Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions Rules/Languages/ru/SharedRules/calculus.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,96 @@
---

# W3C definite-integral arguments are the integration domain or the two bounds, not the sign.
- name: definite-integral-intent
tag: definite-integral
match: "(count(*)=1 or count(*)=2) and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- T: "интеграл"
- test:
if: "count(*)=1"
then: [T: "по", x: "*[1]"]
else:
- T: "от"
- test:
- if: "*[1][self::m:minus and count(*)=1 and *[1][.='∞']]"
then: [T: "минус бесконечности"]
- else_if: "*[1][self::m:plus and count(*)=1 and *[1][.='∞']]"
then: [T: "плюс бесконечности"]
- else_if: "*[1][.='∞']"
then: [T: "бесконечности"]
else: [x: "*[1]"]
- T: "до"
- test:
- if: "*[2][self::m:minus and count(*)=1 and *[1][.='∞']]"
then: [T: "минус бесконечности"]
- else_if: "*[2][self::m:plus and count(*)=1 and *[1][.='∞']]"
then: [T: "плюс бесконечности"]
- else_if: "*[2][.='∞']"
then: [T: "бесконечности"]
else: [x: "*[2]"]

# A semantic reading also works for prime notation; the numeric-order phrase avoids case-dependent ordinals.
- name: derivative-intent
tag: derivative
match: "count(*)=3 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- T: "производная"
- test:
if: "not(*[3][self::m:mn and .='1'])"
then: [T: "порядка", x: "*[3]"]
- test:
if: "not(IsNode(*[1], 'simple'))"
then: [T: "выражения"]
- x: "*[1]"
- T: "по"
- x: "*[2]"

- name: core-sum-product
tag: [sum, product]
match: "count(*)>=1 and count(*)<=3 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- x: "SpeakIntentName(name(.), $Verbosity, 'function')"
- test:
- if: "count(*)=2"
then: [T: "по", x: "*[1]"]
- else_if: "count(*)=3"
then: [T: "от", x: "*[1]", T: "до", x: "*[2]"]
- test:
if: "count(*)>1 or not(IsNode(*[last()], 'simple'))"
then: [T: "выражения"]
- x: "*[last()]"
- test:
if: "$Impairment='Blindness' and not(IsNode(*[last()], 'simple') or IsBracketed(*[last()], '', ''))"
then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'function', 'end')"]

# Pair each variable with its following order. InsertIndex is supplied by insert;
# the previous variable's order is at 2*InsertIndex-1 in the full child list.

- name: core-partial-derivative
tag: partial-derivative
match: "count(*)>=3 and count(*) mod 2=1 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- T: "частная производная"
- test:
if: "not(IsNode(*[1], 'simple'))"
then: [T: "выражения"]
- x: "*[1]"
- T: "по"
- insert:
nodes: "*[position() mod 2=0]"
replace:
- test:
if: "not(*[2*$InsertIndex - 1][self::m:mn and .='1'])"
then: [T: "порядка", x: "*[2*$InsertIndex - 1]"]
- T: "и по"
- test:
if: "not(*[last()][self::m:mn and .='1'])"
then: [T: "порядка", x: "*[last()]"]

- name: laplacian
tag: laplacian
match: "count(*) <= 1" # can be on ∇^2 or on enclosing mrow
Expand Down
4 changes: 2 additions & 2 deletions Rules/Languages/ru/SharedRules/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -569,12 +569,12 @@
tag: mi
match:
- "string-length(.)=1 and"
- "(parent::*[self::m:trace or self::m:dimension or self::m:homomorphism or self::m:kernel or self::m:norm or self::m:determinant or self::m:real-part or self::m:imaginary-part or self::m:laplacian or self::m:divergence or self::m:curl or self::m:gradient or self::m:subscripted-norm or self::m:limit or self::m:line-segment or self::m:ray or self::m:open-interval or self::m:closed-interval or self::m:open-closed-interval or self::m:closed-open-interval or self::m:binomial or self::m:pochhammer or self::m:square-root or self::m:root or self::m:absolute-value] or parent::m:large-op or parent::m:logarithm-with-base or (parent::m:power and preceding-sibling::*) or (parent::m:fraction and preceding-sibling::* and IsNode(../*[1], 'simple') and IsNode(., 'simple')) or (parent::m:apply-function and preceding-sibling::*) or (parent::m:evaluate and preceding-sibling::*) or preceding-sibling::*[1][.='⁡' or .='∈' or .='∉' or .='∊'] or parent::m:mrow[IsBracketed(., '(', ')') and count(*)=3 and parent::*[self::m:kernel or self::m:homomorphism]])"
- "((preceding-sibling::* and (IsInDefinition(name(..), 'RussianGenitiveRightOperandIntents') or IsInDefinition(name(..), 'RussianAccusativeRightOperandIntents'))) or DefinitionValue(name(..), 'Speech', 'RussianCoreGenitiveNames')!='' or parent::*[self::m:partial-derivative or self::m:quotient or self::m:remainder or self::m:ratio or self::m:conditional-probability or self::m:logarithm or self::m:ordered-pair or self::m:inverse or self::m:set-difference or self::m:binomial-coefficient] or parent::*[self::m:definite-integral or self::m:derivative or self::m:image or self::m:domain or self::m:codomain or self::m:trace or self::m:dimension or self::m:homomorphism or self::m:kernel or self::m:norm or self::m:determinant or self::m:real-part or self::m:imaginary-part or self::m:laplacian or self::m:divergence or self::m:curl or self::m:gradient or self::m:subscripted-norm or self::m:limit or self::m:line-segment or self::m:ray or self::m:open-interval or self::m:closed-interval or self::m:open-closed-interval or self::m:closed-open-interval or self::m:binomial or self::m:pochhammer or self::m:square-root or self::m:root or self::m:absolute-value] or parent::m:large-op or parent::m:logarithm-with-base or (parent::m:power and preceding-sibling::*) or (parent::m:fraction and preceding-sibling::* and IsNode(../*[1], 'simple') and IsNode(., 'simple')) or (parent::m:apply-function and preceding-sibling::*) or (parent::m:evaluate and preceding-sibling::*) or preceding-sibling::*[1][.='⁡' or .='∈' or .='∉' or .='∊'] or parent::m:mrow[IsBracketed(., '(', ')') and count(*)=3 and parent::*[self::m:kernel or self::m:homomorphism]])"
replace:
- bookmark: "@id"
- with:
variables:
- RuCapitalWord: "IfThenElse((parent::m:ray or parent::m:fraction) and preceding-sibling::*, 'заглавную', 'заглавной')"
- RuCapitalWord: "IfThenElse(((parent::m:ray or parent::m:fraction or parent::m:quotient or parent::m:remainder) or IsInDefinition(name(..), 'RussianAccusativeRightOperandIntents')) and preceding-sibling::*, 'заглавную', 'заглавной')"
- RuInflectCapital: "not(parent::m:large-op and not(preceding-sibling::*)) and not(parent::m:line-segment and $Verbosity!='Verbose') and not(parent::m:ray and $Verbosity!='Verbose') and not($Verbosity='Terse' and (parent::m:square-root or (parent::m:root and not(preceding-sibling::*))))"
replace:
- with:
Expand Down
200 changes: 188 additions & 12 deletions Rules/Languages/ru/SharedRules/general.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
---

- name: blank-intent
tag: blank
match: "count(*)=0"
replace: [bookmark: "@id", T: "пустое место"]

# Preserve operands while suppressing the default-silent operator, including a bare operator leaf.
- name: invisible-operator-intent
tag: [invisible-times, invisible-separator]
match: "not(@data-intent-property) or contains(@data-intent-property, ':silent:')"
replace:
- test:
if: "*"
then: [x: "*"]
else: [T: ""]
# Names confirmed in Russian mathematical notation. Do not rewrite MathML.
- name: russian-function-alias
tag: [mi, mtext]
Expand Down Expand Up @@ -128,7 +143,165 @@
if: "count(*)>0"
then: [x: "*"]

# Function sets take a genitive operand, without the generic connector "от".
- name: function-set
tag: [image, domain, codomain]
match: "count(*)<=1 and not(contains(@data-intent-property, ':silent:') or contains(@data-intent-property, ':postfix:') or contains(@data-intent-property, ':infix:') or contains(@data-intent-property, ':nofix:'))"
replace:
- bookmark: "@id"
- test:
if: "parent::*[self::m:image or self::m:domain or self::m:codomain][count(*)=1] or DefinitionValue(name(..), 'Speech', 'RussianCoreGenitiveNames')!=''"
then: [x: "DefinitionValue(name(.), 'Speech', 'RussianGenitiveFunctionSets')"]
else: [x: "SpeakIntentName(name(.), $Verbosity, 'function')"]
- test:
if: "count(*)=1"
then:
- test:
if: "not(IsNode(*[1], 'simple')) and not(*[1][self::m:image or self::m:domain or self::m:codomain]) and DefinitionValue(name(*[1]), 'Speech', 'RussianCoreGenitiveNames')=''"
then: [T: "выражения"]
- with:
variables:
- SpeechOverrides_CapitalLetters: "IfThenElse(*[1][self::m:mi and string-length(.)=1 and contains('ABCDEFGHIJKLMNOPQRSTUVWXYZ', .)] and $SpeechOverrides_CapitalLetters='' and $Impairment='Blindness', 'заглавной', $SpeechOverrides_CapitalLetters)"
replace: [x: "*[1]"]

# rules on scripted vertical bars ('evaluated at')
- name: core-noun-function
tag: [adjugate, area, cardinality, ceiling, complement, complex-arg, complex-conjugate, diameter, distance, floor, fractional-part, least-common-denominator, length, max, mean, median, min, mode, probability, radius, round, span, standard-deviation, variance, volume]
match: "count(*)=1 and not(contains(@data-intent-property, ':silent:') or contains(@data-intent-property, ':postfix:') or contains(@data-intent-property, ':infix:'))"
replace:
- bookmark: "@id"
- test:
if: "DefinitionValue(name(..), 'Speech', 'RussianCoreGenitiveNames')!='' or DefinitionValue(name(..), 'Speech', 'RussianGenitiveFunctionSets')!=''"
then: [x: "DefinitionValue(name(.), 'Speech', 'RussianCoreGenitiveNames')"]
else: [x: "SpeakIntentName(name(.), $Verbosity, 'function')"]
- test:
if: "not(IsNode(*[1], 'simple')) and not(DefinitionValue(name(*[1]), 'Speech', 'RussianCoreGenitiveNames')!='' or DefinitionValue(name(*[1]), 'Speech', 'RussianGenitiveFunctionSets')!='')"
then: [T: "выражения"]
- x: "*[1]"

- name: core-coordinate-list
tag: [cartesian-coordinate, polar-coordinate, spherical-coordinate, list, tuple, permutation-cycle]
match: "count(*)>0 and not(contains(@data-intent-property, ':silent:') or contains(@data-intent-property, ':postfix:') or contains(@data-intent-property, ':infix:'))"
replace:
- bookmark: "@id"
- test:
if: "DefinitionValue(name(..), 'Speech', 'RussianCoreGenitiveNames')!='' or DefinitionValue(name(..), 'Speech', 'RussianGenitiveFunctionSets')!=''"
then: [x: "DefinitionValue(name(.), 'Speech', 'RussianCoreGenitiveNames')"]
else: [x: "SpeakIntentName(name(.), $Verbosity, 'function')"]
- test:
if: "*"
then:
- insert:
nodes: "*"
replace: [T: "запятая"]

- name: core-ordered-pair
tag: ordered-pair
match: "count(*)=2 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- T: "упорядоченная пара"
- x: "*[1]"
- T: "и"
- x: "*[2]"

- name: core-conditional-probability
tag: conditional-probability
match: "count(*)=2 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- T: "вероятность"
- x: "*[1]"
- T: "при условии"
- x: "*[2]"

- name: core-logarithm-with-base
tag: logarithm
match: "count(*)=2 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- T: "логарифм по основанию"
- x: "*[2]"
- T: "от"
- x: "*[1]"

- name: core-division-result
tag: [quotient, remainder]
match: "count(*)=2 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- test:
if: "self::m:quotient"
then: [T: "целая часть результата деления"]
else: [T: "остаток от деления"]
- test:
if: "not(IsNode(*[1], 'simple'))"
then: [T: "выражения"]
- x: "*[1]"
- T: "на"
- test:
if: "not(IsNode(*[2], 'simple'))"
then: [T: "выражение"]
- x: "*[2]"

- name: core-common-denominator
tag: least-common-denominator
match: "count(*)>=2 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- T: "наименьший общий знаменатель"
- insert:
nodes: "*"
replace: [T: "и"]

- name: core-extrema
tag: [max, min]
match: "count(*)>=2 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- x: "SpeakIntentName(name(.), $Verbosity, 'function')"
- T: "из"
- insert:
nodes: "*"
replace: [T: "запятая"]

- name: core-set-difference
tag: set-difference
match: "count(*)=2 and not(contains(@data-intent-property, ':silent:') or contains(@data-intent-property, ':infix:'))"
replace:
- bookmark: "@id"
- T: "разность множеств"
- x: "*[1]"
- T: "и"
- x: "*[2]"

- name: core-ratio
tag: ratio
match: "count(*)=2 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- T: "отношение"
- test:
if: "not(IsNode(*[1], 'simple'))"
then: [T: "выражения"]
- x: "*[1]"
- T: "к"
- test:
if: "not(IsNode(*[2], 'simple'))"
then: [T: "выражению"]
- x: "*[2]"

- name: core-inverse
tag: inverse
match: "count(*)=1 and not(contains(@data-intent-property, ':silent:') or contains(@data-intent-property, ':postfix:'))"
replace:
- bookmark: "@id"
- T: "обратный к"
- test:
if: "not(IsNode(*[1], 'simple'))"
then: [T: "выражению"]
- x: "*[1]"

- name: evaluated-at-2
tag: evaluate
match: "count(*)=2"
Expand Down Expand Up @@ -181,7 +354,7 @@
- x: "*[2]"

- name: binomial
tag: binomial
tag: [binomial, binomial-coefficient]
match: "count(*)=2"
replace:
- T: "число сочетаний из"
Expand Down Expand Up @@ -210,11 +383,11 @@
if: "not(IsNode(*[2], 'simple'))"
then: [T: "конец числа сочетаний"]

# Read an infix pochhammer intent as a number of arrangements.
# Accept W3C's default function fixity as well as the inferred infix representation.
- name: permutation
# Use Russian arrangements wording rather than the generic infix intent mapping
tag: pochhammer
match: "count(*)=2 and contains(@data-intent-property, ':infix:')"
match: "count(*)=2 and (contains(@data-intent-property, ':infix:') or contains(@data-intent-property, ':function:'))"
replace:
- T: "число размещений из"
- x: "*[1]"
Expand Down Expand Up @@ -255,15 +428,15 @@
then: [T: "бесконечности"]
else: [x: "*[2]"]

# Read a two-coordinate point with a spoken comma between coordinates.
# W3C points have one or more coordinates, separated by spoken commas.
- name: default-point
tag: point
match: "count(*)=2"
match: "count(*)>=1 and not(contains(@data-intent-property, ':silent:'))"
replace:
- T: "точка" # phrase(the 'point' with coordinates x and y)
- x: "*[1]"
- T: "запятая"
- x: "*[2]"
- insert:
nodes: "*"
replace: [T: "запятая"]

- name: bigop-both
tag: large-op
Expand Down Expand Up @@ -327,13 +500,16 @@
then: [T: "от"] # phrase(the square root 'of' 25 equals 5)
- x: "*[2]"

# W3C supplies the period alone; inferred MathCAT intents also carry a non-repeating prefix.
- name: repeating-decimal
tag: repeating-decimal
match: "."
match: "(count(*)=1 or count(*)=2) and not(contains(@data-intent-property, ':silent:'))"
replace:
- x: "*[1]"
- T: "с повторяющимися цифрами" # phrase('with repeating digits')
- SPELL: "*[2]"
- test:
if: "count(*)=2"
then: [x: "*[1]", T: "с повторяющимися цифрами"]
else: [T: "период"]
- SPELL: "*[last()]"

- name: msubsup-skip-super
# handles single, double, etc., prime
Expand Down
10 changes: 10 additions & 0 deletions Rules/Languages/ru/SharedRules/geometry.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
---

- name: core-translation
tag: translation
match: "count(*)=2 and not(contains(@data-intent-property, ':silent:'))"
replace:
- bookmark: "@id"
- T: "перенос на"
- x: "*[1]"
- T: "запятая"
- x: "*[2]"

- name: line-segment
tag: line-segment
match: "count(*)=2"
Expand Down
Loading
Loading