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", "точка 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("ImR", "образ заглавной эр") +} + +#[test] +fn function_set_domain() -> Result<()> { + // The domain is the set of allowed inputs, not an ordinary function applied with "от". + all_russian_speech_modes("DomF", "область определения заглавной эф") +} + +#[test] +fn function_set_codomain() -> Result<()> { + // The codomain is the target set; it must remain distinct from the image. + all_russian_speech_modes("CodF", "целевое множество заглавной эф") +} + +#[test] +fn function_set_nested_genitive() -> Result<()> { + // Nested concept names themselves take the genitive, without an extra expression cue. + all_russian_speech_modes("ImF", "образ области определения заглавной эф")?; + all_russian_speech_modes("DomF", "область определения целевого множества образа заглавной эф") +} + +#[test] +fn function_set_compound_operand() -> Result<()> { + // A compound operand is introduced with genitive "выражения"; its internal letters stay nominative. + all_russian_speech_modes("ImF+G", "образ выражения заглавная эф плюс заглавная гэ") +} + +#[test] +fn function_set_name_only() -> Result<()> { + // A standalone operator name has no operand to inflect and needs no connector. + all_russian_speech_modes("Im", "образ")?; + all_russian_speech_modes("Dom", "область определения")?; + all_russian_speech_modes("Cod", "целевое множество") +} + +#[test] +fn complex_parts_with_style_wrappers() -> Result<()> { + // TeX4ht splits upright function names into mi children of mstyle; neither name may disappear. + let expr = "a=Rez,b=Imz"; + 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 = "a=Rez,b=Imz"; + 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 = "rez,imz"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xyz"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "xyz"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "xyz"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xyz"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "x"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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 = "x"; + 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 = "xy"; + 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("log28","логарифм по основанию 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("fxy","частная производная эф по икс порядка 2 и по игрек")?; + all_russian_speech_modes("fn","частная производная эф по икс порядка эн и по игрек порядка 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("ImR","мощность образа заглавной эр")?; + all_russian_speech_modes("ImR","образ мощности заглавной эр")?; + 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!("Q{operator}R"); + 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", "ImR")?; + 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.