diff --git a/Rules/Languages/ru/SharedRules/calculus.yaml b/Rules/Languages/ru/SharedRules/calculus.yaml
index e6288aec2..8fcbadccc 100644
--- a/Rules/Languages/ru/SharedRules/calculus.yaml
+++ b/Rules/Languages/ru/SharedRules/calculus.yaml
@@ -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
diff --git a/Rules/Languages/ru/SharedRules/default.yaml b/Rules/Languages/ru/SharedRules/default.yaml
index ad8a44f7d..709a57c60 100644
--- a/Rules/Languages/ru/SharedRules/default.yaml
+++ b/Rules/Languages/ru/SharedRules/default.yaml
@@ -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:
diff --git a/Rules/Languages/ru/SharedRules/general.yaml b/Rules/Languages/ru/SharedRules/general.yaml
index f2964d2b9..c20cd1fa3 100644
--- a/Rules/Languages/ru/SharedRules/general.yaml
+++ b/Rules/Languages/ru/SharedRules/general.yaml
@@ -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]
@@ -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"
@@ -181,7 +354,7 @@
- x: "*[2]"
- name: binomial
- tag: binomial
+ tag: [binomial, binomial-coefficient]
match: "count(*)=2"
replace:
- T: "число сочетаний из"
@@ -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]"
@@ -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
@@ -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
diff --git a/Rules/Languages/ru/SharedRules/geometry.yaml b/Rules/Languages/ru/SharedRules/geometry.yaml
index d16ae3f69..eef4d2b1b 100644
--- a/Rules/Languages/ru/SharedRules/geometry.yaml
+++ b/Rules/Languages/ru/SharedRules/geometry.yaml
@@ -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"
diff --git a/Rules/Languages/ru/definitions.yaml b/Rules/Languages/ru/definitions.yaml
index b3509614e..d9ab453f8 100644
--- a/Rules/Languages/ru/definitions.yaml
+++ b/Rules/Languages/ru/definitions.yaml
@@ -108,17 +108,211 @@
# "ratio": "function=ratio : to | the ratio : to | the ratio : to" # verbosity of name:glue pairs
#
- IntentMappings: {
+ # W3C core concept names; explicit intent does not change inferred notation.
+ "adjugate": "function=присоединённая матрица",
+ "and": "infix=и",
+ "angle": "prefix=угол",
+ "angle-measure": "prefix=мера угла",
+ "annotation": "infix=с пояснением",
+ "applied-to": "infix=от",
+ "approximately": "infix=приблизительно равно",
+ "arc-hyperbolic-cosecant": "function=обратная функция гиперболического косеканса",
+ "arc-hyperbolic-cosine": "function=обратная функция гиперболического косинуса",
+ "arc-hyperbolic-cotangent": "function=обратная функция гиперболического котангенса",
+ "arc-hyperbolic-secant": "function=обратная функция гиперболического секанса",
+ "arc-hyperbolic-sine": "function=обратная функция гиперболического синуса",
+ "arc-hyperbolic-tangent": "function=обратная функция гиперболического тангенса",
+ "arccosecant": "function=арккосеканс",
+ "arccosine": "function=арккосинус",
+ "arccotangent": "function=арккотангенс",
+ "arcsecant": "function=арксеканс",
+ "arcsine": "function=арксинус",
+ "arctangent": "function=арктангенс",
+ "area": "function=площадь",
+ "binomial-coefficient": "infix=число сочетаний из; по; конец числа сочетаний",
+ "braced-group": "prefix=; группа; конец группы",
+ "cardinality": "function=мощность",
+ "cartesian-coordinate": "function=декартовы координаты",
+ "cartesian-product": "infix=декартово произведение",
+ "ceiling": "function=округление вверх",
+ "change": "prefix=изменение",
+ "complement": "function=дополнение",
+ "complex-arg": "function=аргумент",
+ "complex-conjugate": "function=комплексное сопряжение",
+ "composed-with": "infix=композиция с",
+ "conditional-probability": "function=вероятность: при условии",
+ "congruent": "infix=конгруэнтно",
+ "constraint": "infix=при условии",
+ "cosecant": "function=косеканс",
+ "cosine": "function=косинус",
+ "cotangent": "function=котангенс",
+ "defined-as": "infix=определяется как",
+ "diameter": "nofix=диаметр || function=диаметр",
+ "differential-d": "nofix=дэ",
+ "dimensional-product": "infix=на",
+ "direct-product": "infix=прямое произведение",
+ "directed-line-segment": "prefix=направленный отрезок",
+ "distance": "nofix=расстояние || function=расстояние",
+ "divided-by": "infix=разделить на",
+ "divides": "infix=делит",
+ "does-not-belong-to": "infix=не принадлежит",
+ "does-not-divide": "infix=не делит",
+ "downwards-diagonal-ellipsis": "infix=диагональное многоточие вниз",
+ "element-of": "infix=принадлежит",
+ "ellipsis": "infix=многоточие",
+ "embellished-name": "infix=с обозначением",
+ "empty-set": "nofix=пустое множество",
+ "equals": "infix=равно",
+ "equivalent-to": "infix=эквивалентно",
+ "evaluated-at": "infix=вычисленное при",
+ "evaluates-to": "infix=вычисляется как",
+ "exponential": "function=экспонента",
+ "exponential-e": "nofix=число е",
+ "factorial": "postfix=факториал",
+ "fenced-group": "prefix=; выражение в скобках; конец выражения в скобках",
+ "floor": "function=округление вниз",
+ "for-all": "prefix=для всех",
+ "fractional-part": "function=дробная часть",
+ "given": "infix=при условии",
+ "golden-ratio": "nofix=золотое сечение",
+ "greater-than": "infix=больше",
+ "greater-than-or-equal-to": "infix=больше или равно",
+ "highlight": "postfix=выделено",
+ "hyperbolic-cosecant": "function=гиперболический косеканс",
+ "hyperbolic-cosine": "function=гиперболический косинус",
+ "hyperbolic-cotangent": "function=гиперболический котангенс",
+ "hyperbolic-secant": "function=гиперболический секанс",
+ "hyperbolic-sine": "function=гиперболический синус",
+ "hyperbolic-tangent": "function=гиперболический тангенс",
+ "identically-equals": "infix=тождественно равно",
+ "identity-matrix": "nofix=единичная матрица",
+ "if-and-only-if": "infix=тогда и только тогда когда",
+ "imaginary-i": "nofix=мнимая единица",
+ "implies": "infix=влечёт",
+ "inner-product": "infix=скалярное произведение",
+ "intersection": "infix=пересечение",
+ "inverse": "function=обратный к || postfix=обратный",
+ "least-common-denominator": "function=наименьший общий знаменатель",
+ "length": "function=длина",
+ "less-than": "infix=меньше",
+ "less-than-or-equal-to": "infix=меньше или равно",
+ "line": "prefix=прямая",
+ "list": "nofix=список || function=список",
+ "list-separator": "infix=запятая",
+ "logarithm": "function=логарифм",
+ "maps-to": "infix=отображается в",
+ "max": "function=максимум",
+ "mean": "function=среднее",
+ "measured-angle": "prefix=измеренный угол",
+ "median": "function=медиана",
+ "member-of": "infix=принадлежит",
+ "min": "function=минимум",
+ "minus-or-plus": "infix=минус плюс",
+ "mixed-fraction": "infix=и",
+ "mode": "function=мода",
+ "not": "prefix=не",
+ "not-equal-to": "infix=не равно",
+ "not-member-of": "infix=не принадлежит",
+ "not-parallel-to": "infix=не параллельно",
+ "not-subset": "infix=не является подмножеством",
+ "not-superset": "infix=не является надмножеством",
+ "number-of": "prefix=число",
+ "obtained-from": "infix=получено из",
+ "or": "infix=или",
+ "ordered-pair": "function=упорядоченная пара: и",
+ "outer-product": "infix=внешнее произведение",
+ "parallel-to": "infix=параллельно",
+ # Speech rules defined elsewhere: SharedRules/calculus.yaml (core-partial-derivative).
+ # "partial-derivative": "other=частная производная",
+ "percent": "postfix=процентов",
+ "permutation-cycle": "function=цикл перестановки",
+ "plus-or-minus": "infix=плюс минус",
+ "polar-coordinate": "function=полярные координаты",
+ "precedes": "infix=предшествует",
+ "probability": "nofix=вероятность || function=вероятность",
+ "product": "function=; произведение; конец произведения",
+ "proportional": "infix=пропорционально",
+ "quotient": "function=целая часть частного",
+ "radius": "nofix=радиус || function=радиус",
+ "range-separator": "infix=до",
+ "rate": "infix=на",
+ "ratio": "function=отношение: к",
+ "remainder": "function=остаток",
+ "right-angle": "prefix=прямой угол",
+ "round": "function=округлённое значение",
+ "secant": "function=секанс",
+ "set-difference": "function=разность множеств: и || infix=минус",
+ "set-of-complex-numbers": "nofix=комплексные числа",
+ "set-of-integers": "nofix=целые числа",
+ "set-of-natural-numbers": "nofix=натуральные числа",
+ "set-of-primes": "nofix=простые числа",
+ "set-of-rationals": "nofix=рациональные числа",
+ "set-of-reals": "nofix=действительные числа",
+ "similar": "infix=подобно",
+ "sine": "function=синус",
+ "span": "function=линейная оболочка",
+ "spherical-coordinate": "function=сферические координаты",
+ "square-root-of": "prefix=квадратный корень из",
+ "standard-deviation": "function=стандартное отклонение",
+ "subset": "infix=является подмножеством",
+ "subset-or-equal": "infix=является подмножеством или равно",
+ "succeeds": "infix=следует за",
+ "such-that": "infix=таких что",
+ "sum": "function=; сумма; конец суммы",
+ "superset": "infix=является надмножеством",
+ "superset-or-equal": "infix=является надмножеством или равно",
+ "tangent": "function=тангенс",
+ "tends-to": "infix=стремится к",
+ "tends-to-from-above": "infix=стремится сверху к",
+ "tends-to-from-below": "infix=стремится снизу к",
+ "there-does-not-exist": "prefix=не существует",
+ "there-exists": "prefix=существует",
+ "tilde": "infix=тильда",
+ "time-separator": "infix=",
+ "times": "infix=умножить на",
+ "translation": "function=перенос на",
+ "tuple": "nofix=кортеж || function=кортеж",
+ "union": "infix=объединение",
+ "unit-vector": "prefix=единичный вектор",
+ "upwards-diagonal-ellipsis": "infix=диагональное многоточие вверх",
+ "variance": "function=дисперсия",
+ "vertical-ellipsis": "infix=вертикальное многоточие",
+ "volume": "nofix=объём || function=объём",
+ "xor": "infix=исключающее или",
+ # Speech rules defined elsewhere: SharedRules/general.yaml (blank-intent).
+ # "blank": "nofix=пустое место",
+ # Speech rules defined elsewhere: SharedRules/calculus.yaml (definite-integral-intent, derivative-intent).
+ # "definite-integral": "other=интеграл",
+ # "derivative": "other=производная",
+ # Speech rules defined elsewhere: SharedRules/general.yaml (invisible-operator-intent).
+ # "invisible-separator": "silent=",
+ # "invisible-times": "silent=",
+ # Speech rules defined elsewhere: SharedRules/general.yaml (default-point).
+ # "point": "other=точка",
+ # Speech rules defined elsewhere: SharedRules/general.yaml (permutation).
+ # Keep this mapping to supply the default function fixity required by that rule.
+ "pochhammer": "function=число размещений",
"indexed-by": "infix= ; с индексом; конец индекса| с индексом| с индексом",
"modified-variable": "silent= ",
"say-super": "infix=верхний индекс| верхний индекс| верхний индекс", # used with 'mo' for superscripts (e.g, "<")
"skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*")
"absolute-value": "function= ; модуль| модуль| модуль; конец модуля",
+ "domain": "function=область определения",
+ "codomain": "function=целевое множество",
+ "image": "function=образ",
"binomial": "infix=число сочетаний из; по; конец числа сочетаний",
+ # Speech rules for open-interval, open-closed-interval, closed-interval, and closed-open-interval
+ # are defined elsewhere: SharedRules/general.yaml (intervals, numeric-half-open-interval).
# "closed-interval": "other=closed-interval; от,до; end closed-interval",
+ # Speech rules defined elsewhere: ClearSpeak_Rules.yaml and SimpleSpeak_Rules.yaml.
+ # "fraction": "function=дробь; делить на; конец дроби",
+ # Speech rules defined elsewhere: SharedRules/general.yaml (repeating-decimal).
+ # "repeating-decimal": "function=период",
"greatest-common-divisor": "function=нод| нод| наибольший общий делитель",
"imaginary-part": "function=мнимая часть",
"least-common-multiple": "function=нок|нок|наименьшее общее кратное",
+ # Speech rules defined elsewhere: SharedRules/general.yaml (bigop-both, bigop-under).
# "large-op": "infix=над || other=от,до",
"limit": "prefix=предел при| предел при| предел при",
"lim-sup": "prefix=верхний предел при| верхний предел при| верхний предел при",
@@ -127,7 +321,6 @@
"natural-logarithm": "function=эл эн| натуральный логарифм| натуральный логарифм",
"minus": "infix=минус || prefix=минус",
"plus": "infix=плюс || prefix=плюс",
- # "pochhammer": "infix=permutations of", # arguments are in reverse order, so can't work here
"real-part": "function=действительная часть",
"transpose": "postfix=транспонирование || function=транспонированная",
@@ -153,6 +346,60 @@
}
# Names of functions that in terse mode don't say "of" (or it's equivalent in other languages)
+- RussianGenitiveFunctionSets: {
+ "image": "образа",
+ "domain": "области определения",
+ "codomain": "целевого множества",
+ }
+
+- RussianCoreGenitiveNames: {
+ "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": "объёма",
+ "list": "списка",
+ "tuple": "кортежа",
+ "permutation-cycle": "цикла перестановки",
+ "cartesian-coordinate": "декартовых координат",
+ "polar-coordinate": "полярных координат",
+ "spherical-coordinate": "сферических координат",
+ }
+
+# Case of a capital-letter right operand of a named relation or operation.
+- RussianGenitiveRightOperandIntents: {
+ "applied-to", "approximately", "composed-with", "congruent", "does-not-belong-to",
+ "element-of", "equals", "equivalent-to", "given", "greater-than", "greater-than-or-equal-to",
+ "identically-equals", "less-than", "less-than-or-equal-to", "member-of", "not-equal-to",
+ "not-member-of", "not-parallel-to", "not-subset", "not-superset", "obtained-from",
+ "parallel-to", "precedes", "proportional", "range-separator", "similar", "subset",
+ "subset-or-equal", "succeeds", "superset", "superset-or-equal", "tends-to",
+ "tends-to-from-above", "tends-to-from-below",
+ }
+- RussianAccusativeRightOperandIntents: {
+ "divided-by", "implies", "maps-to", "rate", "times",
+ }
+
- TerseFunctionNames: {
"divergence", "gradient", "curl"
}
diff --git a/tests/Languages/ru/intent.rs b/tests/Languages/ru/intent.rs
index 40dd2e1c5..9b1f28bef 100644
--- a/tests/Languages/ru/intent.rs
+++ b/tests/Languages/ru/intent.rs
@@ -1,9 +1,113 @@
/// Тесты для правил, общих для различных стилей речи:
-/// * здесь собраны тесты, посвящённые различным алфавитам
+/// * явный intent, русская локализация и грамматика аргументов
use crate::common::*;
use anyhow::Result;
+fn all_russian_speech_modes(expr: &str, expected: &str) -> Result<()> {
+ russian_speech_verbosities(expr, expected, expected)
+}
+
+fn russian_speech_verbosities(expr: &str, terse: &str, normal: &str) -> Result<()> {
+ for style in ["ClearSpeak", "SimpleSpeak"] {
+ for verbosity in ["Terse", "Medium", "Verbose"] {
+ let expected = if verbosity == "Terse" { terse } else { normal };
+ test_prefs("ru", style, vec![("Verbosity", verbosity), ("IntentErrorRecovery", "Error")], expr, expected)?;
+ }
+ }
+ Ok(())
+}
+
+#[test]
+fn w3c_point_dimensions() -> Result<()> {
+ // W3C permits one or more coordinates; retain the established two-coordinate reading.
+ all_russian_speech_modes("", "точка 1")?;
+ all_russian_speech_modes("", "точка 1 запятая 2")?;
+ all_russian_speech_modes("", "точка 1 запятая 2 запятая 3")
+}
+
+#[test]
+fn w3c_point_compound_coordinate() -> Result<()> {
+ // A coordinate expression remains a single coordinate, with the separator after the whole expression.
+ all_russian_speech_modes("", "точка 1 плюс 2 запятая 3")
+}
+
+#[test]
+fn w3c_pochhammer_function() -> Result<()> {
+ // W3C's default function form keeps n=5 and k=2 in the Russian 'из n по k' order.
+ all_russian_speech_modes("", "число размещений из 5 по 2")?;
+ all_russian_speech_modes("", "число размещений из 5 по 2")
+}
+
+#[test]
+fn w3c_pochhammer_infix_compatibility() -> Result<()> {
+ // Existing inferred intents use infix fixity; their wording and argument order must remain unchanged.
+ all_russian_speech_modes("", "число размещений из 5 по 2")
+}
+
+#[test]
+fn function_set_image() -> Result<()> {
+ // An explicit image intent names the image, with a genitive capital-letter operand.
+ all_russian_speech_modes("", "образ заглавной эр")
+}
+
+#[test]
+fn function_set_domain() -> Result<()> {
+ // The domain is the set of allowed inputs, not an ordinary function applied with "от".
+ all_russian_speech_modes("", "область определения заглавной эф")
+}
+
+#[test]
+fn function_set_codomain() -> Result<()> {
+ // The codomain is the target set; it must remain distinct from the image.
+ all_russian_speech_modes("", "целевое множество заглавной эф")
+}
+
+#[test]
+fn function_set_nested_genitive() -> Result<()> {
+ // Nested concept names themselves take the genitive, without an extra expression cue.
+ all_russian_speech_modes("", "образ области определения заглавной эф")?;
+ all_russian_speech_modes("", "область определения целевого множества образа заглавной эф")
+}
+
+#[test]
+fn function_set_compound_operand() -> Result<()> {
+ // A compound operand is introduced with genitive "выражения"; its internal letters stay nominative.
+ all_russian_speech_modes("", "образ выражения заглавная эф плюс заглавная гэ")
+}
+
+#[test]
+fn function_set_name_only() -> Result<()> {
+ // A standalone operator name has no operand to inflect and needs no connector.
+ all_russian_speech_modes("", "образ")?;
+ all_russian_speech_modes("", "область определения")?;
+ all_russian_speech_modes("", "целевое множество")
+}
+
+#[test]
+fn complex_parts_with_style_wrappers() -> Result<()> {
+ // TeX4ht splits upright function names into mi children of mstyle; neither name may disappear.
+ let expr = "";
+ test("ru", "ClearSpeak", expr, "а равно действительная часть от зэт запятая, бэ равно мнимая часть от зэт")?;
+ test("ru", "SimpleSpeak", expr, "а равно действительная часть от зэт запятая, бэ равно мнимая часть от зэт")
+}
+
+#[test]
+fn complex_parts_without_style_wrappers() -> Result<()> {
+ // Access8Math removes mstyle wrappers; split Re and Im still denote functions of z.
+ let expr = "";
+ test("ru", "ClearSpeak", expr, "а равно действительная часть от зэт запятая, бэ равно мнимая часть от зэт")?;
+ test("ru", "SimpleSpeak", expr, "а равно действительная часть от зэт запятая, бэ равно мнимая часть от зэт")
+}
+
+#[test]
+fn complex_parts_lowercase() -> Result<()> {
+ // Lowercase re/im must be recognized just like Re/Im, without an explicit apply operator.
+ let expr = "";
+ test("ru", "ClearSpeak", expr, "действительная часть от зэт запятая, мнимая часть от зэт")?;
+ test("ru", "SimpleSpeak", expr, "действительная часть от зэт запятая, мнимая часть от зэт")
+}
+
#[test]
fn imaginary_part_name() -> Result<()> {
// The imaginary part is a real component of a complex number, not a "complex part".
@@ -135,6 +239,1298 @@ fn intent_prob_x() -> Result<()> {
x
P
";
- test("ru", "ClearSpeak", expr, "probability от икс")?;
+ // An indirectly referenced W3C name keeps its Russian noun grammar in every speech mode.
+ all_russian_speech_modes(expr, "вероятность икс")?;
return Ok(());
}
+
+// Reviewed W3C names and argument-grammar regressions.
+// W3C Core Concept List, reviewed 2026-10-30: https://w3c.github.io/mathml-docs/intent-core-concepts/
+#[test]
+fn w3c_core_adjugate() -> Result<()> {
+ // W3C adjugate: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "присоединённая матрица икс")
+}
+
+#[test]
+fn w3c_core_and() -> Result<()> {
+ // W3C and: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс и игрек")
+}
+
+#[test]
+fn w3c_core_angle() -> Result<()> {
+ // W3C angle: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "угол икс")
+}
+
+#[test]
+fn w3c_core_angle_measure() -> Result<()> {
+ // W3C angle-measure: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "мера угла икс")
+}
+
+#[test]
+fn w3c_core_annotation() -> Result<()> {
+ // W3C annotation: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс с пояснением, игрек")
+}
+
+#[test]
+fn w3c_core_applied_to() -> Result<()> {
+ // W3C applied-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс от игрек")
+}
+
+#[test]
+fn w3c_core_approximately() -> Result<()> {
+ // W3C approximately: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс приблизительно равно, игрек")
+}
+
+#[test]
+fn w3c_core_arc_hyperbolic_cosecant() -> Result<()> {
+ // W3C arc-hyperbolic-cosecant: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "обратная функция гиперболического косеканса икс", "обратная функция гиперболического косеканса от икс")
+}
+
+#[test]
+fn w3c_core_arc_hyperbolic_cosine() -> Result<()> {
+ // W3C arc-hyperbolic-cosine: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "обратная функция гиперболического косинуса икс", "обратная функция гиперболического косинуса от икс")
+}
+
+#[test]
+fn w3c_core_arc_hyperbolic_cotangent() -> Result<()> {
+ // W3C arc-hyperbolic-cotangent: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "обратная функция гиперболического котангенса икс", "обратная функция гиперболического котангенса от икс")
+}
+
+#[test]
+fn w3c_core_arc_hyperbolic_secant() -> Result<()> {
+ // W3C arc-hyperbolic-secant: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "обратная функция гиперболического секанса икс", "обратная функция гиперболического секанса от икс")
+}
+
+#[test]
+fn w3c_core_arc_hyperbolic_sine() -> Result<()> {
+ // W3C arc-hyperbolic-sine: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "обратная функция гиперболического синуса икс", "обратная функция гиперболического синуса от икс")
+}
+
+#[test]
+fn w3c_core_arc_hyperbolic_tangent() -> Result<()> {
+ // W3C arc-hyperbolic-tangent: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "обратная функция гиперболического тангенса икс", "обратная функция гиперболического тангенса от икс")
+}
+
+#[test]
+fn w3c_core_arccosecant() -> Result<()> {
+ // W3C arccosecant: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "арккосеканс икс", "арккосеканс от икс")
+}
+
+#[test]
+fn w3c_core_arccosine() -> Result<()> {
+ // W3C arccosine: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "арккосинус икс", "арккосинус от икс")
+}
+
+#[test]
+fn w3c_core_arccotangent() -> Result<()> {
+ // W3C arccotangent: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "арккотангенс икс", "арккотангенс от икс")
+}
+
+#[test]
+fn w3c_core_arcsecant() -> Result<()> {
+ // W3C arcsecant: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "арксеканс икс", "арксеканс от икс")
+}
+
+#[test]
+fn w3c_core_arcsine() -> Result<()> {
+ // W3C arcsine: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "арксинус икс", "арксинус от икс")
+}
+
+#[test]
+fn w3c_core_arctangent() -> Result<()> {
+ // W3C arctangent: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "арктангенс икс", "арктангенс от икс")
+}
+
+#[test]
+fn w3c_core_area() -> Result<()> {
+ // W3C area: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "площадь икс")
+}
+
+#[test]
+fn w3c_core_binomial_coefficient() -> Result<()> {
+ // W3C binomial-coefficient: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "число сочетаний из икс по игрек")
+}
+
+#[test]
+fn w3c_core_braced_group() -> Result<()> {
+ // W3C braced-group: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "группа икс")
+}
+
+#[test]
+fn w3c_core_cardinality() -> Result<()> {
+ // W3C cardinality: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "мощность икс")
+}
+
+#[test]
+fn w3c_core_cartesian_coordinate() -> Result<()> {
+ // W3C cartesian-coordinate: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "декартовы координаты икс запятая игрек")
+}
+
+#[test]
+fn w3c_core_cartesian_product() -> Result<()> {
+ // W3C cartesian-product: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс декартово произведение; игрек")
+}
+
+#[test]
+fn w3c_core_ceiling() -> Result<()> {
+ // W3C ceiling: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "округление вверх икс")
+}
+
+#[test]
+fn w3c_core_change() -> Result<()> {
+ // W3C change: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "изменение икс")
+}
+
+#[test]
+fn w3c_core_complement() -> Result<()> {
+ // W3C complement: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "дополнение икс")
+}
+
+#[test]
+fn w3c_core_complex_arg() -> Result<()> {
+ // W3C complex-arg: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "аргумент икс")
+}
+
+#[test]
+fn w3c_core_complex_conjugate() -> Result<()> {
+ // W3C complex-conjugate: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "комплексное сопряжение икс")
+}
+
+#[test]
+fn w3c_core_composed_with() -> Result<()> {
+ // W3C composed-with: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс композиция с, игрек")
+}
+
+#[test]
+fn w3c_core_conditional_probability() -> Result<()> {
+ // W3C conditional-probability: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "вероятность икс при условии игрек")
+}
+
+#[test]
+fn w3c_core_congruent() -> Result<()> {
+ // W3C congruent: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс конгруэнтно, игрек")
+}
+
+#[test]
+fn w3c_core_constraint() -> Result<()> {
+ // W3C constraint: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс при условии, игрек")
+}
+
+#[test]
+fn w3c_core_cosecant() -> Result<()> {
+ // W3C cosecant: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "косеканс икс", "косеканс от икс")
+}
+
+#[test]
+fn w3c_core_cosine() -> Result<()> {
+ // W3C cosine: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "косинус икс", "косинус от икс")
+}
+
+#[test]
+fn w3c_core_cotangent() -> Result<()> {
+ // W3C cotangent: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "котангенс икс", "котангенс от икс")
+}
+
+#[test]
+fn w3c_core_defined_as() -> Result<()> {
+ // W3C defined-as: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс определяется как, игрек")
+}
+
+#[test]
+fn w3c_core_diameter() -> Result<()> {
+ // W3C diameter: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "диаметр икс")
+}
+
+#[test]
+fn w3c_core_differential_d() -> Result<()> {
+ // W3C differential-d: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "дэ")
+}
+
+#[test]
+fn w3c_core_dimensional_product() -> Result<()> {
+ // W3C dimensional-product: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс на игрек")
+}
+
+#[test]
+fn w3c_core_direct_product() -> Result<()> {
+ // W3C direct-product: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс прямое произведение, игрек")
+}
+
+#[test]
+fn w3c_core_directed_line_segment() -> Result<()> {
+ // W3C directed-line-segment: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "направленный отрезок икс игрек")
+}
+
+#[test]
+fn w3c_core_distance() -> Result<()> {
+ // W3C distance: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "расстояние икс")
+}
+
+#[test]
+fn w3c_core_divided_by() -> Result<()> {
+ // W3C divided-by: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс разделить на, игрек")
+}
+
+#[test]
+fn w3c_core_divides() -> Result<()> {
+ // W3C divides: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс делит игрек")
+}
+
+#[test]
+fn w3c_core_does_not_belong_to() -> Result<()> {
+ // W3C does-not-belong-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс не принадлежит, игрек")
+}
+
+#[test]
+fn w3c_core_does_not_divide() -> Result<()> {
+ // W3C does-not-divide: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс не делит игрек")
+}
+
+#[test]
+fn w3c_core_downwards_diagonal_ellipsis() -> Result<()> {
+ // W3C downwards-diagonal-ellipsis: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс диагональное многоточие вниз; игрек")
+}
+
+#[test]
+fn w3c_core_element_of() -> Result<()> {
+ // W3C element-of: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс принадлежит, игрек")
+}
+
+#[test]
+fn w3c_core_ellipsis() -> Result<()> {
+ // W3C ellipsis: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс многоточие, игрек")
+}
+
+#[test]
+fn w3c_core_embellished_name() -> Result<()> {
+ // W3C embellished-name: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс с обозначением, игрек")
+}
+
+#[test]
+fn w3c_core_empty_set() -> Result<()> {
+ // W3C empty-set: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "пустое множество")
+}
+
+#[test]
+fn w3c_core_equals() -> Result<()> {
+ // W3C equals: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс равно игрек")
+}
+
+#[test]
+fn w3c_core_equivalent_to() -> Result<()> {
+ // W3C equivalent-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс эквивалентно, игрек")
+}
+
+#[test]
+fn w3c_core_evaluated_at() -> Result<()> {
+ // W3C evaluated-at: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс вычисленное при, игрек")
+}
+
+#[test]
+fn w3c_core_evaluates_to() -> Result<()> {
+ // W3C evaluates-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс вычисляется как, игрек")
+}
+
+#[test]
+fn w3c_core_exponential() -> Result<()> {
+ // W3C exponential: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "экспонента икс", "экспонента от икс")
+}
+
+#[test]
+fn w3c_core_exponential_e() -> Result<()> {
+ // W3C exponential-e: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "число е")
+}
+
+#[test]
+fn w3c_core_factorial() -> Result<()> {
+ // W3C factorial: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс факториал")
+}
+
+#[test]
+fn w3c_core_fenced_group() -> Result<()> {
+ // W3C fenced-group: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "выражение в скобках икс")
+}
+
+#[test]
+fn w3c_core_floor() -> Result<()> {
+ // W3C floor: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "округление вниз икс")
+}
+
+#[test]
+fn w3c_core_for_all() -> Result<()> {
+ // W3C for-all: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "для всех икс")
+}
+
+#[test]
+fn w3c_core_fractional_part() -> Result<()> {
+ // W3C fractional-part: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "дробная часть икс")
+}
+
+#[test]
+fn w3c_core_given() -> Result<()> {
+ // W3C given: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс при условии, игрек")
+}
+
+#[test]
+fn w3c_core_golden_ratio() -> Result<()> {
+ // W3C golden-ratio: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "золотое сечение")
+}
+
+#[test]
+fn w3c_core_greater_than() -> Result<()> {
+ // W3C greater-than: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс больше игрек")
+}
+
+#[test]
+fn w3c_core_greater_than_or_equal_to() -> Result<()> {
+ // W3C greater-than-or-equal-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс больше или равно, игрек")
+}
+
+#[test]
+fn w3c_core_highlight() -> Result<()> {
+ // W3C highlight: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс выделено")
+}
+
+#[test]
+fn w3c_core_hyperbolic_cosecant() -> Result<()> {
+ // W3C hyperbolic-cosecant: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "гиперболический косеканс икс", "гиперболический косеканс от икс")
+}
+
+#[test]
+fn w3c_core_hyperbolic_cosine() -> Result<()> {
+ // W3C hyperbolic-cosine: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "гиперболический косинус икс", "гиперболический косинус от икс")
+}
+
+#[test]
+fn w3c_core_hyperbolic_cotangent() -> Result<()> {
+ // W3C hyperbolic-cotangent: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "гиперболический котангенс икс", "гиперболический котангенс от икс")
+}
+
+#[test]
+fn w3c_core_hyperbolic_secant() -> Result<()> {
+ // W3C hyperbolic-secant: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "гиперболический секанс икс", "гиперболический секанс от икс")
+}
+
+#[test]
+fn w3c_core_hyperbolic_sine() -> Result<()> {
+ // W3C hyperbolic-sine: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "гиперболический синус икс", "гиперболический синус от икс")
+}
+
+#[test]
+fn w3c_core_hyperbolic_tangent() -> Result<()> {
+ // W3C hyperbolic-tangent: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "гиперболический тангенс икс", "гиперболический тангенс от икс")
+}
+
+#[test]
+fn w3c_core_identically_equals() -> Result<()> {
+ // W3C identically-equals: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс тождественно равно, игрек")
+}
+
+#[test]
+fn w3c_core_identity_matrix() -> Result<()> {
+ // W3C identity-matrix: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "единичная матрица")
+}
+
+#[test]
+fn w3c_core_if_and_only_if() -> Result<()> {
+ // W3C if-and-only-if: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс тогда и только тогда когда; игрек")
+}
+
+#[test]
+fn w3c_core_imaginary_i() -> Result<()> {
+ // W3C imaginary-i: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "мнимая единица")
+}
+
+#[test]
+fn w3c_core_implies() -> Result<()> {
+ // W3C implies: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс влечёт игрек")
+}
+
+#[test]
+fn w3c_core_inner_product() -> Result<()> {
+ // W3C inner-product: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс скалярное произведение; игрек")
+}
+
+#[test]
+fn w3c_core_intersection() -> Result<()> {
+ // W3C intersection: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс пересечение, игрек")
+}
+
+#[test]
+fn w3c_core_inverse() -> Result<()> {
+ // W3C inverse: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "обратный к икс")
+}
+
+#[test]
+fn w3c_core_least_common_denominator() -> Result<()> {
+ // W3C least-common-denominator: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "наименьший общий знаменатель икс и игрек")
+}
+
+#[test]
+fn w3c_core_length() -> Result<()> {
+ // W3C length: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "длина икс")
+}
+
+#[test]
+fn w3c_core_less_than() -> Result<()> {
+ // W3C less-than: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс меньше игрек")
+}
+
+#[test]
+fn w3c_core_less_than_or_equal_to() -> Result<()> {
+ // W3C less-than-or-equal-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс меньше или равно, игрек")
+}
+
+#[test]
+fn w3c_core_line() -> Result<()> {
+ // W3C line: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "прямая икс игрек")
+}
+
+#[test]
+fn w3c_core_list() -> Result<()> {
+ // W3C list: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "список")
+}
+
+#[test]
+fn w3c_core_list_separator() -> Result<()> {
+ // W3C list-separator: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс запятая игрек")
+}
+
+#[test]
+fn w3c_core_logarithm() -> Result<()> {
+ // W3C logarithm: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "логарифм по основанию игрек от икс")
+}
+
+#[test]
+fn w3c_core_maps_to() -> Result<()> {
+ // W3C maps-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс отображается в, игрек")
+}
+
+#[test]
+fn w3c_core_max() -> Result<()> {
+ // W3C max: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "максимум икс")
+}
+
+#[test]
+fn w3c_core_mean() -> Result<()> {
+ // W3C mean: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "среднее икс")
+}
+
+#[test]
+fn w3c_core_measured_angle() -> Result<()> {
+ // W3C measured-angle: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "измеренный угол икс")
+}
+
+#[test]
+fn w3c_core_median() -> Result<()> {
+ // W3C median: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "медиана икс")
+}
+
+#[test]
+fn w3c_core_member_of() -> Result<()> {
+ // W3C member-of: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс принадлежит, игрек")
+}
+
+#[test]
+fn w3c_core_min() -> Result<()> {
+ // W3C min: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "минимум икс")
+}
+
+#[test]
+fn w3c_core_minus_or_plus() -> Result<()> {
+ // W3C minus-or-plus: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс минус плюс, игрек")
+}
+
+#[test]
+fn w3c_core_mixed_fraction() -> Result<()> {
+ // W3C mixed-fraction: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс и игрек")
+}
+
+#[test]
+fn w3c_core_mode() -> Result<()> {
+ // W3C mode: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "мода икс")
+}
+
+#[test]
+fn w3c_core_not() -> Result<()> {
+ // W3C not: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "не икс")
+}
+
+#[test]
+fn w3c_core_not_equal_to() -> Result<()> {
+ // W3C not-equal-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс не равно игрек")
+}
+
+#[test]
+fn w3c_core_not_member_of() -> Result<()> {
+ // W3C not-member-of: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс не принадлежит, игрек")
+}
+
+#[test]
+fn w3c_core_not_parallel_to() -> Result<()> {
+ // W3C not-parallel-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс не параллельно, игрек")
+}
+
+#[test]
+fn w3c_core_not_subset() -> Result<()> {
+ // W3C not-subset: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс не является подмножеством; игрек")
+}
+
+#[test]
+fn w3c_core_not_superset() -> Result<()> {
+ // W3C not-superset: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс не является надмножеством; игрек")
+}
+
+#[test]
+fn w3c_core_number_of() -> Result<()> {
+ // W3C number-of: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "число икс")
+}
+
+#[test]
+fn w3c_core_obtained_from() -> Result<()> {
+ // W3C obtained-from: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс получено из, игрек")
+}
+
+#[test]
+fn w3c_core_or() -> Result<()> {
+ // W3C or: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс или игрек")
+}
+
+#[test]
+fn w3c_core_ordered_pair() -> Result<()> {
+ // W3C ordered-pair: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "упорядоченная пара икс и игрек")
+}
+
+#[test]
+fn w3c_core_outer_product() -> Result<()> {
+ // W3C outer-product: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс внешнее произведение, игрек")
+}
+
+#[test]
+fn w3c_core_parallel_to() -> Result<()> {
+ // W3C parallel-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс параллельно, игрек")
+}
+
+#[test]
+fn w3c_core_partial_derivative() -> Result<()> {
+ // W3C partial-derivative: localizes the concept and retains all 3 arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "частная производная икс по игрек порядка зэт")
+}
+
+#[test]
+fn w3c_core_percent() -> Result<()> {
+ // W3C percent: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс процентов")
+}
+
+#[test]
+fn w3c_core_permutation_cycle() -> Result<()> {
+ // W3C permutation-cycle: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "цикл перестановки икс запятая игрек")
+}
+
+#[test]
+fn w3c_core_plus_or_minus() -> Result<()> {
+ // W3C plus-or-minus: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс плюс минус, игрек")
+}
+
+#[test]
+fn w3c_core_polar_coordinate() -> Result<()> {
+ // W3C polar-coordinate: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "полярные координаты икс запятая игрек")
+}
+
+#[test]
+fn w3c_core_precedes() -> Result<()> {
+ // W3C precedes: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс предшествует, игрек")
+}
+
+#[test]
+fn w3c_core_probability() -> Result<()> {
+ // W3C probability: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "вероятность икс")
+}
+
+#[test]
+fn w3c_core_product() -> Result<()> {
+ // W3C product: localizes the concept and retains all 3 arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "произведение от икс до игрек выражения зэт")
+}
+
+#[test]
+fn w3c_core_proportional() -> Result<()> {
+ // W3C proportional: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс пропорционально, игрек")
+}
+
+#[test]
+fn w3c_core_quotient() -> Result<()> {
+ // W3C quotient: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "целая часть результата деления икс на игрек")
+}
+
+#[test]
+fn w3c_core_radius() -> Result<()> {
+ // W3C radius: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "радиус икс")
+}
+
+#[test]
+fn w3c_core_range_separator() -> Result<()> {
+ // W3C range-separator: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс до игрек")
+}
+
+#[test]
+fn w3c_core_rate() -> Result<()> {
+ // W3C rate: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс на игрек")
+}
+
+#[test]
+fn w3c_core_ratio() -> Result<()> {
+ // W3C ratio: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "отношение икс к игрек")
+}
+
+#[test]
+fn w3c_core_remainder() -> Result<()> {
+ // W3C remainder: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "остаток от деления икс на игрек")
+}
+
+#[test]
+fn w3c_core_right_angle() -> Result<()> {
+ // W3C right-angle: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "прямой угол икс")
+}
+
+#[test]
+fn w3c_core_round() -> Result<()> {
+ // W3C round: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "округлённое значение икс")
+}
+
+#[test]
+fn w3c_core_secant() -> Result<()> {
+ // W3C secant: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "секанс икс", "секанс от икс")
+}
+
+#[test]
+fn w3c_core_set_difference() -> Result<()> {
+ // W3C set-difference: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "разность множеств икс и игрек")
+}
+
+#[test]
+fn w3c_core_set_of_complex_numbers() -> Result<()> {
+ // W3C set-of-complex-numbers: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "комплексные числа")
+}
+
+#[test]
+fn w3c_core_set_of_integers() -> Result<()> {
+ // W3C set-of-integers: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "целые числа")
+}
+
+#[test]
+fn w3c_core_set_of_natural_numbers() -> Result<()> {
+ // W3C set-of-natural-numbers: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "натуральные числа")
+}
+
+#[test]
+fn w3c_core_set_of_primes() -> Result<()> {
+ // W3C set-of-primes: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "простые числа")
+}
+
+#[test]
+fn w3c_core_set_of_rationals() -> Result<()> {
+ // W3C set-of-rationals: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "рациональные числа")
+}
+
+#[test]
+fn w3c_core_set_of_reals() -> Result<()> {
+ // W3C set-of-reals: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "действительные числа")
+}
+
+#[test]
+fn w3c_core_similar() -> Result<()> {
+ // W3C similar: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс подобно игрек")
+}
+
+#[test]
+fn w3c_core_sine() -> Result<()> {
+ // W3C sine: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "синус икс", "синус от икс")
+}
+
+#[test]
+fn w3c_core_span() -> Result<()> {
+ // W3C span: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "линейная оболочка икс")
+}
+
+#[test]
+fn w3c_core_spherical_coordinate() -> Result<()> {
+ // W3C spherical-coordinate: localizes the concept and retains all 3 arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "сферические координаты икс запятая игрек запятая зэт")
+}
+
+#[test]
+fn w3c_core_square_root_of() -> Result<()> {
+ // W3C square-root-of: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "квадратный корень из икс")
+}
+
+#[test]
+fn w3c_core_standard_deviation() -> Result<()> {
+ // W3C standard-deviation: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "стандартное отклонение икс")
+}
+
+#[test]
+fn w3c_core_subset() -> Result<()> {
+ // W3C subset: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс является подмножеством; игрек")
+}
+
+#[test]
+fn w3c_core_subset_or_equal() -> Result<()> {
+ // W3C subset-or-equal: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс является подмножеством или равно; игрек")
+}
+
+#[test]
+fn w3c_core_succeeds() -> Result<()> {
+ // W3C succeeds: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс следует за, игрек")
+}
+
+#[test]
+fn w3c_core_such_that() -> Result<()> {
+ // W3C such-that: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс таких что игрек")
+}
+
+#[test]
+fn w3c_core_sum() -> Result<()> {
+ // W3C sum: localizes the concept and retains all 3 arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "сумма от икс до игрек выражения зэт")
+}
+
+#[test]
+fn w3c_core_superset() -> Result<()> {
+ // W3C superset: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс является надмножеством; игрек")
+}
+
+#[test]
+fn w3c_core_superset_or_equal() -> Result<()> {
+ // W3C superset-or-equal: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс является надмножеством или равно; игрек")
+}
+
+#[test]
+fn w3c_core_tangent() -> Result<()> {
+ // W3C tangent: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ russian_speech_verbosities(expr, "тангенс икс", "тангенс от икс")
+}
+
+#[test]
+fn w3c_core_tends_to() -> Result<()> {
+ // W3C tends-to: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс стремится к, игрек")
+}
+
+#[test]
+fn w3c_core_tends_to_from_above() -> Result<()> {
+ // W3C tends-to-from-above: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс стремится сверху к, игрек")
+}
+
+#[test]
+fn w3c_core_tends_to_from_below() -> Result<()> {
+ // W3C tends-to-from-below: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс стремится снизу к, игрек")
+}
+
+#[test]
+fn w3c_core_there_does_not_exist() -> Result<()> {
+ // W3C there-does-not-exist: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "не существует икс")
+}
+
+#[test]
+fn w3c_core_there_exists() -> Result<()> {
+ // W3C there-exists: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "существует икс")
+}
+
+#[test]
+fn w3c_core_tilde() -> Result<()> {
+ // W3C tilde: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс тильда игрек")
+}
+
+#[test]
+fn w3c_core_time_separator() -> Result<()> {
+ // W3C time-separator: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс игрек")
+}
+
+#[test]
+fn w3c_core_times() -> Result<()> {
+ // W3C times: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс умножить на, игрек")
+}
+
+#[test]
+fn w3c_core_translation() -> Result<()> {
+ // W3C translation: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "перенос на икс запятая игрек")
+}
+
+#[test]
+fn w3c_core_tuple() -> Result<()> {
+ // W3C tuple: localizes the standalone concept name, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "кортеж")
+}
+
+#[test]
+fn w3c_core_union() -> Result<()> {
+ // W3C union: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс объединение, игрек")
+}
+
+#[test]
+fn w3c_core_unit_vector() -> Result<()> {
+ // W3C unit-vector: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "единичный вектор икс")
+}
+
+#[test]
+fn w3c_core_upwards_diagonal_ellipsis() -> Result<()> {
+ // W3C upwards-diagonal-ellipsis: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс диагональное многоточие вверх; игрек")
+}
+
+#[test]
+fn w3c_core_variance() -> Result<()> {
+ // W3C variance: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "дисперсия икс")
+}
+
+#[test]
+fn w3c_core_vertical_ellipsis() -> Result<()> {
+ // W3C vertical-ellipsis: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс вертикальное многоточие; игрек")
+}
+
+#[test]
+fn w3c_core_volume() -> Result<()> {
+ // W3C volume: localizes the concept and retains its argument, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "объём икс")
+}
+
+#[test]
+fn w3c_core_xor() -> Result<()> {
+ // W3C xor: localizes the concept and retains both arguments, in both styles and all verbosities.
+ let expr = "";
+ all_russian_speech_modes(expr, "икс исключающее или, игрек")
+}
+
+#[test]
+fn w3c_logarithm_argument_and_base() -> Result<()> {
+ // W3C orders arguments as value, base; Russian speech says 'по основанию base от value'.
+ all_russian_speech_modes("","логарифм по основанию 2 от 8")?;
+ for style in ["ClearSpeak", "SimpleSpeak"] {
+ for verbosity in ["Terse", "Medium", "Verbose"] {
+ let expected=if verbosity=="Terse" {"логарифм 8"} else {"логарифм от 8"};
+ test_prefs("ru",style,vec![("Verbosity",verbosity)],"",expected)?;
+ }
+ }
+ Ok(())
+}
+
+#[test]
+fn w3c_sum_arities() -> Result<()> {
+ // Domain/bound arguments precede the summand in the two- and three-argument W3C forms.
+ all_russian_speech_modes("","сумма 2")?;
+ all_russian_speech_modes("","сумма по 2 выражения 3")?;
+ all_russian_speech_modes("","сумма от 2 до 3 выражения 5")
+}
+
+#[test]
+fn w3c_product_arities() -> Result<()> {
+ // The last argument is the factor expression, never an upper bound or an extra factor.
+ all_russian_speech_modes("","произведение 2")?;
+ all_russian_speech_modes("","произведение по 2 выражения 3")?;
+ all_russian_speech_modes("","произведение от 2 до 3 выражения 5")
+}
+
+#[test]
+fn w3c_partial_derivative_mixed_orders() -> Result<()> {
+ // Every variable stays paired with its own order, including an implicit first-order variable.
+ all_russian_speech_modes("","частная производная эф по икс порядка 2 и по игрек")?;
+ all_russian_speech_modes("","частная производная эф по икс порядка эн и по игрек порядка 3")
+}
+
+#[test]
+fn w3c_variadic_lists_and_coordinates() -> Result<()> {
+ // Every entry/coordinate of a longer list must be spoken once; arity-zero names are in the inventory test.
+ all_russian_speech_modes("","список 1 запятая 2 запятая 3")?;
+ all_russian_speech_modes("","кортеж 1 запятая 2 запятая 3")?;
+ all_russian_speech_modes("","декартовы координаты 1 запятая 2 запятая 3 запятая 4")
+}
+
+#[test]
+fn w3c_variadic_extrema() -> Result<()> {
+ // max/min accept more than one value and must not drop the final value.
+ all_russian_speech_modes("","максимум из 1 запятая 2 запятая 3")?;
+ all_russian_speech_modes("","минимум из 1 запятая 2 запятая 3")
+}
+
+#[test]
+fn w3c_nested_noun_cases() -> Result<()> {
+ // Nested noun heads take genitive forms, in either order of old and newly supported concepts.
+ all_russian_speech_modes("","мощность образа заглавной эр")?;
+ all_russian_speech_modes("","образ мощности заглавной эр")?;
+ all_russian_speech_modes("","среднее списка 1 запятая 2 запятая 3")
+}
+
+#[test]
+fn w3c_division_and_condition_argument_order() -> Result<()> {
+ // Non-symmetric numeric operands expose accidental reversal of dividend/divisor or event/condition.
+ all_russian_speech_modes("","целая часть результата деления 7 на 3")?;
+ all_russian_speech_modes("","остаток от деления 7 на 3")?;
+ all_russian_speech_modes("","отношение 7 к 3")?;
+ all_russian_speech_modes("","вероятность 7 при условии 3")
+}
+
+#[test]
+fn w3c_relation_and_operation_cases() -> Result<()> {
+ // Check grammatical words independently of automatically generated pauses.
+ for style in ["ClearSpeak","SimpleSpeak"] {
+ for (name,operator,expected) in [
+ ("equals","=","заглавная ку равно заглавной эр"),
+ ("element-of","∈","заглавная ку принадлежит заглавной эр"),
+ ("times","×","заглавная ку умножить на заглавную эр"),
+ ("implies","⇒","заглавная ку влечёт заглавную эр"),
+ ] {
+ let mathml=format!("");
+ init_nav("ru",&mathml)?;
+ set_preference("SpeechStyle",style)?;
+ set_preference("SpeechOverrides_CapitalLetters","")?;
+ set_preference("Impairment","Blindness")?;
+ let actual=get_spoken_text()?.replace([',',';'],"").split_whitespace().collect::>().join(" ");
+ assert_eq!(actual,expected,"{style}/{name}");
+ }
+ }
+ Ok(())
+}
+
+#[test]
+fn w3c_read_named_logarithm_and_relation() -> Result<()> {
+ // Semantic ReadCurrent must retain both argument order and Russian relation wording.
+ for style in ["ClearSpeak","SimpleSpeak"] {
+ init_nav("ru","")?;
+ set_preference("SpeechStyle",style)?;
+ let speech=do_navigate_command("ReadCurrent")?.split_whitespace().collect::>().join(" ");
+ assert!(speech.contains("логарифм по основанию 2 от 8"),"{style}: {speech}");
+ init_nav("ru","")?;
+ set_preference("SpeechStyle",style)?;
+ let speech=do_navigate_command("ReadCurrent")?.split_whitespace().collect::>().join(" ");
+ assert!(speech.contains("2 равно 3"),"{style}: {speech}");
+ }
+ Ok(())
+}
diff --git a/tests/Languages/ru/navigate.rs b/tests/Languages/ru/navigate.rs
index 1d83e6dc7..74ff26e0b 100644
--- a/tests/Languages/ru/navigate.rs
+++ b/tests/Languages/ru/navigate.rs
@@ -17,6 +17,42 @@ fn overview_modes(expr: &str, expected: [&str; 3]) -> Result<()> {
Ok(())
}
+#[test]
+fn read_function_set_intents() -> Result<()> {
+ // Semantic modes read the explicit image intent; Character mode keeps its literal notation.
+ for style in ["ClearSpeak", "SimpleSpeak"] {
+ for mode in ["Enhanced", "Simple", "Character"] {
+ init_nav("ru", "")?;
+ set_preference("SpeechStyle", style)?;
+ set_preference("NavMode", mode)?;
+ let speech = do_navigate_command("ReadCurrent")?.split_whitespace().collect::>().join(" ");
+ let expected = if mode == "Character" {"Im заглавной эр"} else {"образ заглавной эр"};
+ assert!(speech.contains(expected), "{style}/{mode}: {speech}");
+ }
+ }
+ Ok(())
+}
+
+#[test]
+fn read_w3c_point_and_pochhammer() -> Result<()> {
+ // Semantic navigation must retain all coordinates and the asymmetric permutation arguments.
+ for style in ["ClearSpeak", "SimpleSpeak"] {
+ for mode in ["Enhanced", "Simple"] {
+ init_nav("ru", "")?;
+ set_preference("SpeechStyle", style)?;
+ set_preference("NavMode", mode)?;
+ let speech=do_navigate_command("ReadCurrent")?.split_whitespace().collect::>().join(" ");
+ assert!(speech.contains("точка 1 запятая 2 запятая 3"), "{style}/{mode}: {speech}");
+ init_nav("ru", "")?;
+ set_preference("SpeechStyle", style)?;
+ set_preference("NavMode", mode)?;
+ let speech=do_navigate_command("ReadCurrent")?.split_whitespace().collect::>().join(" ");
+ assert!(speech.contains("число размещений из 5 по 2"), "{style}/{mode}: {speech}");
+ }
+ }
+ Ok(())
+}
+
#[test]
fn overview_labeled_table() -> Result<()> {
// A row label is not a data column; both rows have two data cells.