From 2894695fa248f96cb81fd4f24266372d4412ed69 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Thu, 23 Apr 2026 20:19:54 -0400 Subject: [PATCH 01/31] added missing rules from en to default.yaml --- Rules/Languages/fr/SharedRules/default.yaml | 198 ++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/Rules/Languages/fr/SharedRules/default.yaml b/Rules/Languages/fr/SharedRules/default.yaml index 7f38a389c..d3547e592 100644 --- a/Rules/Languages/fr/SharedRules/default.yaml +++ b/Rules/Languages/fr/SharedRules/default.yaml @@ -315,6 +315,204 @@ - x: "$PostSuperscript" - x: "$Postscripts[2]" +- name: default + tag: mtable + variables: + - IsColumnSilent: "false()" + - NumColumns: "count(*[1]/*) - IfThenElse(*/self::m:mlabeledtr, 1, 0)" + match: "." + replace: + - t: "table avec" # phrase(the 'table with' 3 rows) + - x: count(*) + - test: + if: count(*)=1 + then: [t: "rangée"] # phrase(the table with 1 'row') + else: [t: "rangées"] # phrase(the table with 3 'rows') + - t: "et" # phrase(the table with 3 rows 'and' 4 columns) + - x: "$NumColumns" + - test: + if: "NumColumns=1" + then: [t: "colonne"] # phrase(the table with 3 rows and 1 'column') + else: [t: "colonnes"] # phrase(the table with 3 rows and 4 'columns') + - pause: long + - x: "*" + +- name: default + # callers/context should do that. + # this may get called from navigation -- in that case, there is no context to speak the row #, so don't do it + tag: [mtr, mlabeledtr] + match: "." + replace: + - pause: medium + - t: "rangée" # phrase(the first 'row' of a matrix) + - x: "count(preceding-sibling::*)+1" + - test: + if: "self::m:mlabeledtr" + then: + - t: "avec nom" # phrase(the line 'with label' first equation) + - x: "*[1]/*" + - pause: short + - pause: medium + - test: + if: "self::m:mlabeledtr" + then: [x: "*[position()>1]"] + else: [x: "*"] + +- name: default + tag: mtd + match: "." + replace: + - test: + # ClearSpeak normally speaks "column 1" even though it says the row number, which is a waste... + # The following is commented out but the count(...)!=0 probably belongs in other rule sets + # if: not($IsColumnSilent) and ($ClearSpeak_Matrix = 'SpeakColNum' or count(preceding-sibling::*) != 0) + if: "not($IsColumnSilent)" + then: + - t: "colonne" # phrase(the first 'column' of the matrix) + - x: "count(preceding-sibling::*)+IfThenElse(parent::m:mlabeledtr, 0, 1)" + - pause: medium + - x: "*" + - test: + # short pause after each element; medium pause if last element in a row; long pause for last element in matrix + - if: count(following-sibling::*) > 0 + then: [pause: short] + - else_if: count(../following-sibling::*) > 0 + then: [pause: medium] + else: [pause: long] + +- name: empty-box + # The ordering below is the order in which words come out when there is more than one value + # Note: @notation can contain more than one value + tag: menclose + match: "@notation='box' and *[self::m:mtext and .=' ']" + replace: + - t: "Case vide" # phrase(the 'empty box' contains no values) + +- name: default + # The ordering below is the order in which words come out when there is more than one value + # Note: @notation can contain more than one value + tag: menclose + match: "." + replace: + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' box ')]" + then: [t: "case", pause: short] # phrase(the 'box' around the expression) + - test: + if: ".[contains(@notation,'roundedbox')]" + then: [t: "case arrondie", pause: short] # phrase(the 'round box' around the expression) + - test: + if: ".[contains(@notation,'circle')]" + then: [t: "rond", pause: short] # phrase(the 'circle' around the expression) + - test: + if: ".[ contains(concat(' ', normalize-space(@notation), ' '), ' left ') or contains(concat(' ', normalize-space(@notation), ' '), ' right ') or contains(@notation,'top') or contains(@notation,'bottom') ]" + then: + - t: "line on" # phrase(draw a straight 'line' on the page) + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]" + then: [t: "gauche", pause: short] # phrase(line on 'left' of the expression) + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]" + then: [t: "droite", pause: short] # phrase(line on 'right' of the expression) + - test: + if: ".[contains(@notation,'top')]" + then: [t: "dessus", pause: short] # phrase(line on 'top' of the expression) + - test: + if: ".[contains(@notation,'bottom')]" + then: [t: "dessous", pause: short] # phrase(line on the 'bottom' of the expression) + - test: + if: ".[ contains(@notation,'updiagonalstrike') or contains(@notation,'downdiagonalstrike') or contains(@notation,'verticalstrike') or contains(@notation,'horizontalstrike') ]" + then: + - test: + if: ".[contains(@notation,'updiagonalstrike') and contains(@notation,'downdiagonalstrike')]" + then: [spell: "'x'", pause: short] # seems better to say 'x cross out' than 'up diagonal, down diagonal cross out' + else: + - test: + if: ".[contains(@notation,'updiagonalstrike')]" + then: [t: "diagonale vers le haut", pause: short] # phrase(the line runs 'up diagonal') + - test: + if: ".[contains(@notation,'downdiagonalstrike')]" + then: [t: "diagonale vers le bas", pause: short] # phrase(the line runs 'down diagonal') + - test: + if: ".[contains(@notation,'verticalstrike')]" + then: [t: "verticale", pause: short] # phrase(the line is 'vertical') + - test: + if: ".[contains(@notation,'horizontalstrike')]" + then: [t: "horizontale", pause: short] # phrase(the line is 'horizontal') + - t: "cross out" # phrase(please 'cross out' the incorrect answer) + - pause: short + - test: + if: ".[contains(@notation,'uparrow')]" + then: [t: "flèche vers le haut", pause: short] # phrase(direction is shown by the 'up arrow') + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]" + then: [t: "flèche vers le bas", pause: short] # phrase(the trend is shown by the 'down arrow') + - test: + if: ".[contains(@notation,'leftarrow')]" + then: [t: "flèche vers la gauche", pause: short] # phrase(the 'left arrow' indicates going back) + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')]" + then: [t: "flèche vers la droite", pause: short] # phrase(the 'right arrow' indicates moving forward) + - test: + if: ".[contains(@notation,'northeastarrow')]" + then: [t: "flèche nord-est", pause: short] # phrase(direction is indicated by the 'northeast arrow') + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')]" + then: [t: "flèche sud-est", pause: short] # phrase(direction is shown by the 'southeast arrow') + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')]" + then: [t: "flèche sud-ouest", pause: short] # phrase(direction is shown by the 'southwest arrow') + - test: + if: ".[contains(@notation,'northwestarrow')]" + then: [t: "flèche nord-ouest", pause: short] # phrase(direction is shown by the 'northwest arrow') + - test: + if: ".[contains(@notation,'updownarrow')]" + then: [t: "flèche verticale à double extrémité", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') + - test: + if: ".[contains(@notation,'leftrightarrow')]" + then: [t: "flèche horizontale à double extrémité", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') + - test: + if: ".[contains(@notation,'northeastsouthwestarrow')]" + then: [t: "flèche diagonale vers le haut à double extrémité", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') + - test: + if: ".[contains(@notation,'northwestsoutheastarrow')]" + then: [t: "flèche diagonale vers le bas à double extrémité", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') + - test: + if: ".[contains(@notation,'actuarial')]" + then: [t: "symbole actuariel", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) + - test: + if: ".[contains(@notation,'madrub')]" + then: [t: "symbole factoriel arabe", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) + - test: + if: ".[contains(@notation,'phasorangle')]" + then: [t: "angle de phaseur", pause: short] # phrase(the 'phasor angle' is used to measure electrical current) + - test: + if: ".[contains(@notation,'longdiv') or not(@notation) or normalize-space(@notation) ='']" # default + then: [t: "symbole de division longue", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) + - test: + if: ".[contains(@notation,'radical')]" + then: [t: "racine carrée", pause: short] # phrase(5 is the 'square root' of 25) + - t: "enclosing" # phrase(parentheses are 'enclosing' part of the equation) + - test: + if: "*[self::m:mtext and .=' ']" + then: [t: "espace"] # otherwise there is complete silence # phrase(there is a 'space' between the words) + else: [x: "*"] + - test: + if: "$Impairment = 'Blindness' and ( $SpeechStyle != 'SimpleSpeak' or not(IsNode(*[1], 'leaf')) )" + then: [t: "fin d'encadrement"] # phrase(reached the 'end enclosure' point) + - pause: short + +- name: semantics + tag: "semantics" + match: "*[@encoding='MathML-Presentation']" + replace: + - x: "*[@encoding='MathML-Presentation']/*[1]" + +- name: semantics-default + tag: "semantics" + match: . + replace: + - x: "*[1]" + - name: apply-function tag: "apply-function" match: . From 5060b1b36ed8cd6413366396a3330e0b7f3f56b3 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Thu, 23 Apr 2026 21:17:15 -0400 Subject: [PATCH 02/31] added missing rules from en to general.yaml --- Rules/Languages/fr/SharedRules/general.yaml | 934 ++++++++++++++++++++ 1 file changed, 934 insertions(+) diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml index 1c2e155f7..244c0a376 100644 --- a/Rules/Languages/fr/SharedRules/general.yaml +++ b/Rules/Languages/fr/SharedRules/general.yaml @@ -1,4 +1,343 @@ --- + +# number-sets are a little messy in that the base was converted to a number-set, so we have to match that (simple) case last +- name: pos-neg-number-sets + tag: number-sets + match: "count(*)=2 and *[2][.='+' or .='-']" + replace: + - test: + if: "$Verbosity!='Terse'" + then: + - t: "la" # phrase('the' square root of 25 equals 5) + - bookmark: "*[2]/@id" + - test: + - if: "*[2][.='+']" + then: [t: "positive"] # phrase(set of all 'positive' integers less than 10) + else: [t: "negative"] # phrase(set of all 'negative' integers less than minus 10) + - bookmark: "*[1]/@id" + - test: + - if: "*[1][.='ℂ']" + then: [t: "nombre complexe"] # phrase('complex numbers' consist of two parts) + - else_if: "*[1][.='ℕ']" + then: [t: "nombre naturel"] # phrase('natural numbers' are numbers from 1 to infinity) + - else_if: "*[1][.='ℚ']" + then: [t: "nombre rationel"] # phrase('rational numbers' are the fraction of 2 integers) + - else_if: "*[1][.='ℝ']" + then: [t: "nombre réel"] # phrase('real numbers' can be both positive and negative) + - else_if: "*[1][.='ℤ']" + then: [t: "nombre entier"] # phrase(positive 'integers' are natural numbers above 0) + else: [x: "*[1][text()]"] # shouldn't happen + +- name: dimension-number-sets + # should be single digit integer at this point (e.g, R^3) + tag: number-sets + match: "count(*)=2" + replace: + - bookmark: "*[1]/@id" + - test: + - if: "*[1][.='ℂ']" + then: [t: "C"] # phrase(the letter 'C' used to represent complex number) + - else_if: "*[1][.='ℕ']" + then: [t: "N"] # phrase(the letter 'N' may represent natural numbers) + - else_if: "*[1][.='ℚ']" + then: [t: "Q"] # phrase(the letter 'Q' may represent rational numbers) + - else_if: "*[1][.='ℝ']" + then: [t: "R"] # phrase(the letter 'R' may represent real numbers) + - else_if: "*[1][.='ℤ']" + then: [t: "Z"] # phrase(the letter 'Z' may represent integers) + else: [x: "*[1][text()]"] # shouldn't happen + - bookmark: "*[2]/@id" + - x: "*[2]" + +- name: simple-number-sets + tag: number-sets + match: "count(*)=0" + replace: + - bookmark: "@id" + - test: + - if: ".='ℂ'" + then: [t: "les nombres complexes"] # phrase('the complex numbers' include 2 parts) + - else_if: ".='ℕ'" + then: [t: "les nombres naturels"] # phrase('the natural numbers' begin at 1) + - else_if: ".='ℚ'" + then: [t: "les nombres rationels"] # phrase('the rational numbers' are the fraction of 2 integers) + - else_if: ".='ℝ'" + then: [t: "les nombres réels"] # phrase('the real numbers' can be both positive and negative) + - else_if: ".='ℤ'" + then: [t: "les nombres entiers"] # phrase('the integers' are natural numbers above 0) + else: [x: "text()"] # shouldn't happen + +- name: real-part + tag: real-part + match: "." + replace: + - bookmark: "@id" + - t: "la partie réelle" # phrase('the real part' of a complex number does not include the imaginary part) + +- name: imaginary-part + tag: imaginary-part + match: "." + replace: + - bookmark: "@id" + - t: "la partie imaginaire" # phrase('the imaginary part' is part of a complex number) + +# rules on scripted vertical bars ('evaluated at') +- name: evaluated-at-2 + tag: evaluate + match: "count(*)=2" + replace: + - x: "*[1]" + - pause: auto + - t: "évalués à" # phrase(results were 'evaluated at' a given point) + - pause: auto + - x: "*[2]" + +- name: evaluated-at-3 + tag: evaluate + match: "count(*)=3" + replace: + - x: "*[1]" + - pause: auto + - t: "évalués à" # phrase(results were 'evaluated at' this point) + - pause: auto + - x: "*[3]" + - t: "moins la même expression évaluée à" # phrase(this result is 'minus the same expression evaluated at' an earlier point) + - x: "*[2]" + +- name: permutation + # Not a default because the order of the args is reversed + tag: pochhammer + match: "count(*)=2 and contains(@data-intent-property, ':infix:')" + replace: + - x: "*[2]" + - t: "permutations de" # phrase(the solution involves several 'permutations of' values) + - x: "*[1]" + +- name: intervals + tag: [open-interval, open-closed-interval, closed-interval, closed-open-interval] + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then: + - t: "la" # phrase('the' square root of 25 equals 5) + - x: "translate(name(.),'-', ' ')" + - test: + if: "$Verbosity!='Terse'" + then: + - t: "de" # phrase(subtracting 5 'from' 10 gives 5) + - x: "*[1]" + - t: "à" # phrase(adding 6 'to' 6 equals 12) + - x: "*[2]" + else: + - x: "*[1]" + - t: "virgule" # phrase(use a 'comma' to divide large numbers or as a decimal point) + - x: "*[2]" + +- name: default-point + tag: point + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then: + - t: "la" # phrase('the' square root of 25 equals 5) + - t: "point" # phrase(a decimal 'point' indicates the fraction component of a number) + - x: "*[1]" + - t: "virgule" # phrase(use a 'comma' to divide large numbers or as a decimal point) + - x: "*[2]" + +- name: bigop-both + tag: large-op + match: "count(*) = 3" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [t: "la"] # phrase('the' square root of 25 equals 5) + - x: "*[1]" + - t: "de" # phrase(subtracting 5 'from' 10 gives 5) + - x: "*[2]" + - pause: short + - t: "à" # phrase(adding 6 'to' 6 equals 12) + - x: "*[3]" + - test: + if: "following-sibling::*" + then: [t: "de"] # phrase(the square root 'of' 25 equals 5) + +- name: bigop-under + tag: large-op + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [t: "la"] # phrase('the' square root of 25 equals 5) + - x: "*[1]" + - t: "sur" # phrase(2 'over' 3 equals two thirds) + - x: "*[2]" + - test: + if: "following-sibling::*" + then: [t: "de"] # phrase(the square root 'of' 25 equals 5) + +- name: largeop + tag: mrow + match: "count(*)=2 and IsInDefinition(*[1], 'LargeOperators')" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [t: "la"] # phrase('the' square root of 25 equals 5) + - x: "*[1]" + - t: "de" # phrase(the square root 'of' 25 equals 5) + - x: "*[2]" + +- name: repeating-decimal + tag: repeating-decimal + match: "." + replace: + - x: "*[1]" + - t: "avec des chiffres répétitifs" # phrase('with repeating digits') + - spell: "*[2]" + +- name: msubsup-skip-super + # handles single, double, etc., prime + tag: [skip-super, say-super] + match: "count(*)=3" + replace: + - x: "*[1]" + - test: + if: "$Verbosity='Verbose'" + then: [t: "indice"] # phrase(a 'subscript' may be used to indicate an index) + else: [t: "sous"] # phrase(the result is 'sub' optimal) + - x: "*[2]" + - test: + if: "not(IsNode(*[2],'leaf') and $Impairment = 'Blindness')" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "fin de l'indice"] # phrase(this is the 'end subscript' position) + else: [t: "fin d'indice"] # phrase(this is the 'end sub' position) + - pause: short + else_test: + if: "*[2][self::m:mi]" # need a pause in "x sub k prime" so the prime is not associated with the 'k' + then: [pause: short] + - test: + if: "name(.)='say-super'" + then_test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(a 'superscript' number indicates raised to a power) + else: [t: "super"] # phrase(this is a 'super' set of numbers) + - x: "*[3]" + - pause: short + +# in terse mode, we just say "m" or "s", etc., not meters or seconds +- name: unit-terse + tag: unit + match: "$Verbosity = 'Terse' and string-length(.)=1" + replace: + - bookmark: "@id" + - spell: "text()" + + +# the order of matching is +# 1. does it match the base of an SI unit +# 2. does it match an English unit (if in an English language) +# 3. does it match an SI prefix followed by an SI that accepts SI prefixes +# Due to this order, some things like "ft" and "cd" mean "feet" vs "femto-tonnes" and "pints" vs "pico-tonnes" +- name: unit + tag: unit + match: "." + variables: + # If the coefficient is singular, we don't add the plural ending. Finding the coefficient is tricky + # Normal case (A) "3m" (parents is mrow), but could also be (B) "3 m^2" (etc.) (parent is power/mrow) + # But it might be in a fraction as (C) "3 m/s" (parent is fraction/mrow) or (D) "3 m^2/s^2" (parent is power/fraction/mrow) + # or even (E) {3 m^2}/s (parent is power/mrow) + # If in a fraction, only look in the numerator to find the coefficient + # Note: we have a special case for pseudo-scripts like "°" (degrees) which are not powers -- they are essentially "1^°" + # The following "IfThenElse" logic returns the mrow that potentially contains the coefficient, if it exists + # The tests are in the order A, B & E, C, D + - MRowForCoefficient: "IfThenElse(parent::m:mrow, parent::m:mrow, + IfThenElse(parent::m:power, ancestor::*[2][self::m:mrow], + IfThenElse(parent::m:fraction and not(preceding-sibling::*), ancestor::*[2][self::m:mrow], + IfThenElse(parent::m:power[parent::m:fraction and not(preceding-sibling::*)], ancestor::*[3][self::m:mrow], false()) ) ) )" + - IsSingular: "(not($MRowForCoefficient) and parent::*[name(.)!='skip-super' or *[1][.=1]]) or + ($MRowForCoefficient and $MRowForCoefficient[(count(*) = 3 and *[1][self::m:mn and .=1] and *[2]='\u2062')])" + - Prefix: "''" + - Word: "''" + replace: + - bookmark: "@id" + - test: + # is the whole string match a SI Unit without a prefix? + - if: "DefinitionValue(., 'Speech', 'SIUnits') != ''" + then: + - set_variables: [Word: "DefinitionValue(., 'Speech', 'SIUnits')"] + - else_if: "DefinitionValue(., 'Speech', 'UnitsWithoutPrefixes') != ''" + then: + - set_variables: [Word: "DefinitionValue(., 'Speech', 'UnitsWithoutPrefixes')"] + - else_if: "DefinitionValue(., 'Speech', 'EnglishUnits') != ''" + then: + - set_variables: [Word: "DefinitionValue(., 'Speech', 'EnglishUnits')"] + + # do the first two chars match "da" and the remainder match an SIUnit + - else_if: "string-length(.) >= 3 and + substring(., 1, 2) = 'da' and + DefinitionValue(substring(., 3), 'Speech', 'SIUnits') != ''" + then: + - set_variables: + - Prefix: "DefinitionValue('da', 'Speech', 'SIPrefixes')" + - Word: "DefinitionValue(substring(., 3), 'Speech', 'SIUnits')" + + # does the first char match a prefix and the remainder match an SIUnit + - else_if: "string-length(.) >= 2 and + DefinitionValue(substring(., 1, 1), 'Speech', 'SIPrefixes') != '' and + DefinitionValue(substring(., 2), 'Speech', 'SIUnits') != ''" + then: + - set_variables: + - Prefix: "DefinitionValue(substring(., 1, 1), 'Speech', 'SIPrefixes')" + - Word: "DefinitionValue(substring(., 2), 'Speech', 'SIUnits')" + + # not a known unit -- just speak the text, possibly as a plural + - else: + - set_variables: + - Word: "text()" + + # somewhat complicated logic to avoid spaces around "-" as in "centi-grams" vs "centi - grams" -- probably doesn't matter + - test: + if: "$Prefix = ''" + then: + - test: + - if: "$IsSingular" + # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatenated to the base + then: [x: "$Word"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + then: [x: "DefinitionValue($Word, 'Speech', 'PluralForms')"] + else: [x: "$Word", ct: "s"] + else: + - x: "$Prefix" + - ct: "-" + - test: + - if: "$IsSingular" + # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatenated to the base + then: [x: "concat('\uF8FE', $Word)"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralForms'))"] + else: [x: "concat('\uF8FE', $Word)", ct: "s"] + +# need to reverse the order of speech: $ 3 -> 3 dollars +- name: currency + tag: mrow + match: "count(*)=3 and DefinitionValue(*[1], 'Speech', 'CurrencySymbols') != ''" + variables: + # If the amount is singular, we don't add the plural ending. + - IsSingular: "*[3][self::m:mn and .=1] and *[2]='\u2062'" + replace: + - bookmark: "*[3]/@id" + - x: "*[3]" + - test: + - if: "$IsSingular" + then: [x: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')"] + - else_if: "DefinitionValue(*[1], 'Speech', 'PluralForms') != ''" + then: [x: "DefinitionValue(*[1], 'Speech', 'PluralForms')"] + else: [x: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')", ct: "s"] + - name: sin tag: mi match: ".='sin'" @@ -150,3 +489,598 @@ - else_if: "$Verbosity='Terse'" then: [spell: "'ln'"] else: [t: "logarithme naturel"] + +- name: multi-line + # that eliminates the need for the if: else_if: ... + # IDEA: set a variable with the word to say for the row (e.g., RowLabel = Row/Case/Line/...) + tag: [piecewise, system-of-equations, lines] + match: "." + variables: + # Wikipedia has some tables where all the entire first column is empty (e.g., https://en.wikipedia.org/wiki/List_of_trigonometric_identities) + - LineCount: "count(*[not(contains(@data-intent-property, ':continued-row:'))])" + - NextLineIsContinuedRow: "false()" # default value + - IsColumnSilent: true() + replace: + - x: "$LineCount" + - test: + - if: "self::m:piecewise" + then: [t: "case"] # phrase(this is the first 'case' of three cases) + - else_if: "self::m:system-of-equations" + then: [t: "équation"] # phrase(this is the first 'equation' of three equations) + else: [t: "ligne"] # phrase(this is the first 'line' of three lines) + - test: + - if: "$LineCount != 1" + then: [ct: "s"] # plural + - pause: short + - x: "*" + - pause: long + +- name: default-multiline + tag: [mtr, mlabeledtr] + match: "parent::m:piecewise or parent::m:system-of-equations or parent::m:lines" + variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] + replace: + - test: + if: "not($LineCount=1 or contains(@data-intent-property, ':continued-row:'))" + then: + - pause: medium + - test: + - if: "parent::m:piecewise" + then: [t: "case"] # phrase('case' 1 of 10 cases) + - else_if: "parent::m:system-of-equations" + then: [t: "équation"] # phrase('equation' 1 of 10 equations) + else: [t: "ligne"] # phrase('line 1 of 10 lines) + - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" + - test: + if: "self::m:mlabeledtr" + then: + - t: "avec étiquette" # phrase(the diagram is complete 'with label') + - x: "*[1]/*" + - test: + if: "not(contains(@data-intent-property, ':continued-row:'))" + then: [pause: medium] + - test: + if: "self::m:mlabeledtr" + then: [x: "*[position()>1]"] + else: [x: "*"] + +- name: default-multiline + tag: mtd + match: "parent::*[parent::m:piecewise or parent::m:system-of-equations or parent::m:lines]" + variables: [LongPause: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultiLinePausesBetweenColumns = 'Long'"] + replace: + - test: + if: "IsInDefinition(*[1], 'ComparisonOperators')" + then: [pause: short] + - test: + if: "*[1][@data-added!='missing-content']" + then: [x: "*"] + - test: + # no pause after each element; medium pause if last element in a row; long pause for last element in matrix unless ClearSpeak override + - if: "count(following-sibling::*) = 0 and not($NextLineIsContinuedRow)" + then_test: + if: "count(../following-sibling::*) > 0" + then_test: + if: "$LongPause" + then: [pause: long] + else: [pause: medium] + else_test: + if: "IsInDefinition(*[1], 'ComparisonOperators')" + then: [pause: short] + else: [pause: auto] + +# Matrix/Determinant rules +# matrix and determinant are the same other than "matrix"/"determinant" based on the bracketing chars +# the pausing logic is pushed down to the +# the rules either speak the s (to get "row n") or the s. "column n" spoken if $IsColumnSilent is false +- name: 1x1-matrix + tag: [matrix, determinant] + variables: [IsColumnSilent: true()] + match: "count(*)=1 and *[self::m:mtr][count(*) = 1]" + replace: + - ot: "the" # phrase('the' 1 by 1 matrix M) + - t: "une par une" # phrase(the '1 by 1' matrix) + - test: + if: "self::m:determinant" # just need to check the first bracket since we know it must be (, [, or | + then: [t: "déterminant"] # phrase(the 2 by 2 'determinant')) + else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + + - t: "avec entrée" # phrase(the 2 by 2 matrix 'with entry' x) + - x: "*[1]/*" + +# simpler reading methods for special case matrices +- name: zero-matrix + tag: matrix + # select all the non-zero entries -- if there are none of them, then it is a zero matrix + match: "not( */*/*[not(self::m:mn and .= 0)] )" + replace: + - t: "la" # phrase('the' 1 by 2 matrix M) + - x: count(*) + - t: "par" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - t: "matrice zéro" # phrase(the 2 by 2 'zero matrix') + - pause: long + +- name: identity-matrix + tag: matrix + # every diagonal entry must be a literal 1, and every off-diagonal entry must be a literal 0 + match: + - "count(*) = count(*[1]/*) and " # matrix is square + - "not( */*[count(preceding-sibling::*) = count(../preceding-sibling::*)]/*[not(self::m:mn and .= 1)] ) and " # on-diagonal + - "not( */*[count(preceding-sibling::*) != count(../preceding-sibling::*)]/*[not(self::m:mn and .= 0)] )" # off-diagonal + replace: + - t: "la" # phrase('the' 1 by 2 matrix M) + - x: count(*) + - t: "par" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - t: "matrice identitée" # phrase(the 2 by 2 'identity matrix') + - pause: long + +- name: diagonal-matrix + tag: matrix + # select all the non-zero entries...if they are not on the diagonal + # if there are any of them, then this isn't an identity matrix + match: + - "count(*) = count(*[1]/*) and " + - "not( */*/*[not(self::m:mn and .= 0)]" + - " [count(../preceding-sibling::*)!=count(../../preceding-sibling::*)]" + - " )" + replace: + - t: "la" # phrase('the' 1 by 2 matrix) + - x: count(*) + - t: "par" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - t: "matrice diagonale" # phrase(the 2 by 2 'diagonal matrix') + - pause: long + - insert: + # this lists the diagonal 'mtd's to be read, and they say "column nnn" before reading the contents + # there seems to be an xpath bug -- without the parens, the match fails for the + # test Languages::en::mtable::diagonal_matrix due to match failure (the third matching element seems to be missing) + nodes: "(*/*/*[not(self::m:mn and .= 0)]/..)" + replace: [pause: auto] + - pause: long + +# simpler reading methods for smaller matrices if the entries are simple +- name: 2-or-3x1-matrix + tag: matrix + variables: [IsColumnSilent: true()] + match: + - "$ClearSpeak_Matrix != 'SpeakColNum' and " # "simple" isn't used for this preference + - "*[self::m:mtr][count(*) = 1] and " # one column + - count(*)<=3 and # at least two rows + - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple + replace: + - t: "la" # phrase('the' 2 by 2 matrix M) + - x: count(*) + - t: "par une colonne" # phrase(the 2 'by 1 column' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [t: "vecteur"] # phrase(the 2 by 2 'vector') + else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - t: "fin" # phrase('end' of matrix) + - test: + if: $ClearSpeak_Matrix = 'EndVector' + then: [t: "vecteur"] # phrase(the 2 column 'vector') + else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + +- name: default-column-matrix + tag: matrix + variables: [IsColumnSilent: true()] + match: "*[self::m:mtr][count(*) = 1]" + replace: + - t: "la" # phrase('the' 2 by 2 matrix M) + - x: "count(*)" + - t: "par 1 colonne" # phrase(the 2 'by 1 column' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [t: "vecteur"] # phrase(the 2 column 'vector') + else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*" # select the rows (mtr) + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: [t: "fin de la matrice"] # phrase(the 'end of matrix' has been reached) + +- name: 1x2-or-3-matrix + tag: matrix + variables: [IsColumnSilent: "$SpeechStyle = 'SimpleSpeak' or ($SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix != 'SpeakColNum')"] + match: + - "$ClearSpeak_Matrix != 'SpeakColNum' and " # "simple" isn't used for this preference + - count(*)=1 and # one row + - count(*[1]/*)<=3 and # at least two cols + - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple + replace: + - t: "la 1 par" # phrase('the 1 by' 2 matrix) + - x: count(*/*) + - t: "rangée" # phrase(the 1 by 4 'row' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [t: "vecteur"] # phrase('the 1 by' 2 row 'vector') + else: [t: "matrice"] # phrase('the 1 by' 2 'matrix') + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - t: "fin" # phrase(the 'end' of matrix has been reached) + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [t: "matrice"] # phrase(the 2 by 2 'matrix') + else: [t: "vecteur"] # phrase(the 2 by 1 'vector') + +- name: default-row-matrix + tag: matrix + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] + match: "count(*)=1" # one row + replace: + - t: "la 1 par" # phrase('the 1 by' 2 matrix) + - x: "count(*/*)" + - t: "rangée" # phrase(the 1 by 2 'row' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [t: "vecteur"] # phrase(the 2 by 1 'vector') + else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + - pause: long + - pause: medium + - x: "*/*" # select the cols (mtd) + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - t: "fin" # phrase(the 'end' of matrix has been reached) + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [t: "matrice"] # phrase(the 2 by 2 'matrix') + else: [t: "vecteur"] # phrase(the 2 by 1 'vector') + +- name: simple-small-matrix + tag: [matrix, determinant] + match: + - "$ClearSpeak_Matrix != 'SpeakColNum' and " # "simple" isn't used for this preference + - (count(*)<=3 and count(*[1]/*)<=3) and # no bigger than a 3x3 matrix + - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple + variables: [IsColumnSilent: "$SpeechStyle = 'SimpleSpeak' or ($SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix != 'SpeakColNum')"] + replace: + - t: "la" # phrase('the' 1 by 2 matrix M) + - x: count(*) + - t: "par" # phrase(the 1 'by' 2 matrix) + - x: count(*[self::m:mtr][1]/*) + - test: + if: "self::m:determinant" + then: [t: "determinant"] # phrase(the 2 by 2 'determinant') + else: [t: "matrix"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - t: "fin" # phrase(the 'end' of matrix has been reached) + - test: + if: "self::m:determinant" + then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') + else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + +- name: default-matrix + tag: [matrix, determinant] + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] + match: "." + replace: + - t: "the" # phrase('the' 1 by 2 matrix M) + - x: "count(*)" + - t: "par" # phrase(the 1 'by' 2 matrix) + - x: "count(*[self::m:mtr][1]/*)" + - test: + if: "self::m:determinant" + then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') + else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - t: "fin" # phrase(the 'end' of matrix has been reached) + - test: + if: "self::m:determinant" + then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') + else: [t: "matrice"] # phrase(the 2 by 2 'matrix's) + +- name: chemistry-msub + tag: [chemical-formula] + match: "*[1][.='msub']" + replace: + - x: "*[2]" + - test: + if: "$Verbosity='Verbose'" + then: [t: "indice"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "sous"] # phrase(H 'sub' 2) + - x: "*[3]" + +- name: dimension-by + tag: mrow + match: dimension-product + replace: + - insert: + nodes: "*" + replace: [t: "par", pause: auto] # phrase(3 'by' 5 matrix) + +- name: chemistry-msup + tag: [chemical-formula] + match: "count(*)=3 and *[1][.='msup']" + replace: + - x: "*[2]" + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "super"] # phrase(H 'super' 2) + - x: "*[3]" + - test: + if: "following-sibling::*[1][.='+' or .='-']" # a little lazy -- assumes chemistry superscripts end with + or - + then: [pause: medium] + +- + # There currently is no way to do sub/super for n-ary number of args + # Instead, we just deal with up to two prescripts and up to four postscripts (repeating blocks of similar code [UGLY!]) + # This hopefully covers all reasonable cases... + name: chemistry-scripts + tag: [chemical-formula, chemical-nuclide] + variables: + # computing the number of postscripts is messy because of being optionally present -- we use "mod" to get the count right + - Prescripts: "m:mprescripts/following-sibling::*" + - NumChildren: "count(*)" # need to stash this since the count is wrong inside '*[...]' below + - Postscripts: "*[position()>1 and position() < (last() + ($NumChildren mod 2) -count($Prescripts))]" + match: . # should only be msubsup or mmultiscripts at this point + replace: + - test: + if: "$Prescripts" # we have at least one pre sub/super + then: + # nuclide: speak the superscript first + - test: + if: "not($Prescripts[2][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "super"] # phrase(H 'super' 2) + - x: "$Prescripts[2]" + - pause: "short" + - test: + if: "not($Prescripts[1][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(a 'subscript' may be used to indicate an index) + else_test: + if: "$Verbosity='Medium'" + then: [t: "sous"] # phrase(here is a 'sub' total) + - x: "$Prescripts[1]" + - pause: "short" + - test: + if: "count($Prescripts) > 2" # can this happen for chemistry??? we allow for one *extra* pre sub/super pair + then: + - test: + if: "not($Prescripts[4][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "super"] # phrase(H 'super' 2) + - x: "$Prescripts[4]" + - pause: "short" + - test: + if: "not($Prescripts[3][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "indice"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "sous"] # phrase(H 'sub' 2) + - x: "$Prescripts[3]" + - pause: "short" + - x: "*[1]" # base + - test: + if: "$Postscripts" + then: + - test: + if: "not($Postscripts[1][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "subscript"] # phrase(phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "sous"] # phrase(phrase(H 'sub' 2) + - x: "$Postscripts[1]" + - pause: "short" + - test: + if: "not($Postscripts[2][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "super"] # phrase(H 'super' 2) + - x: "$Postscripts[2]" + - pause: "short" + - test: + if: "count($Postscripts) > 2" + then: + - test: + if: "not($Postscripts[3][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "sous"] # phrase(H 'sub' 2) + - x: "$Postscripts[3]" + - pause: "short" + - test: + if: "not($Postscripts[4][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "super"] # phrase(H 'super' 2) + - x: "$Postscripts[4]" + - pause: "short" + - test: + if: "count($Postscripts) > 4" + then: + - test: + if: "not($Postscripts[5][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "sous"] # phrase(H 'sub' 2) + - x: "$Postscripts[5]" + - pause: "short" + - test: + if: "not($Postscripts[6][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "sous"] # phrase(H 'super' 2) + - x: "$Postscripts[6]" + - pause: "short" + - test: + if: "count($Postscripts) > 6" + then: + - test: + if: "not($Postscripts[7][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'subscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "sous"] # phrase(H 'sub' 2) + - x: "$Postscripts[7]" + - pause: "short" + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [t: "exposant"] # phrase(H 'superscript' 2) + else_test: + if: "$Verbosity='Medium'" + then: [t: "sous"] # phrase(H 'super' 2) + - x: "$Postscripts[8]" + - pause: "short" + - test: + if: "$Postscripts[last()][not(self::m:none)] and following-sibling::*[1][.='+' or .='-']" + then: [pause: medium] + +- name: chemistry + tag: chemical-equation + match: "." + replace: + - x: "*" + +- name: chemical-element + tag: chemical-element + match: "." + replace: + - bookmark: "@id" + - spell: text() + - pause: short + +- name: chemical-state + tag: chemical-state + match: "count(*)=1" + replace: + - bookmark: "*[1]/@id" + - test: + - if: ".='s'" + then: [t: "solide"] # phrase(Boron is a 'solid' in its natural state) + - else_if: ".='l'" + then: [t: "liquide"] # phrase(water is a 'liquid') + - else_if: ".='g'" + then: [t: "gaz"] # phrase(hydrogen is a 'gas' ) + else: [t: "acqueuse"] # phrase(an 'aqueous' solution is contained in water) + - pause: short + +- name: chemical-formula-operator-bond + tag: chemical-formula-operator + match: "@data-chemical-bond" + replace: + # FIX: this might be better/more efficient if in unicode.yaml + - bookmark: "@id" + - test: + - if: ".='-' or .=':'" + then: [t: "liaison simple"] # phrase(a 'single bond' is formed when two atoms share one pair of electrons) + - else_if: ".='=' or .='∷'" + then: [t: "liaison double"] # phrase(a 'double bond' may occur when two atoms share two pairs of electrons) + - else_if: ".='≡'" + then: [t: "liaison triple"] # phrase(a 'triple bond' occurs when two atoms share three pairs of electrons) + - else_if: ".='≣'" + then: [t: "liaison quadruple"] # phrase(a 'quadruple bond' occurs when two atoms share four pairs of electrons) + else: [x: "text()"] + +- name: chemical-formula-operator + tag: chemical-formula-operator + match: "." + replace: + x: "text()" + +- name: chemical-arrow-operator + tag: chemical-arrow-operator + match: "." + replace: + # FIX: this might be better/more efficient if in unicode.yaml + - bookmark: "@id" + - test: + - if: ".='→' or .='⟶'" + then_test: + if: "$Verbosity='Terse'" + then: [t: "forment"] # phrase(hydrogen and oxygen 'forms' water ) + else: [t: "réagissent pour former"] # phrase(hydrogen and oxygen 'reacts to form' water) + - else_if: ".='⇌' or .='🣑'" # U+01F8D1 + then: [t: "est en équilibre avec"] # phrase(a reactant 'is in equilibrium with' a product) + - else_if: ".='🣓'" # U+1F8D3 + then: [t: "est en équilibre biaisé vers la gauche avec"] # phrase(the reactant 'is in equilibrium biased to the left with' the product) + - else_if: ".='🣒'" # U+1F8D2 + then: [t: "est en équilibre biaisé vers la droite avec"] # phrase(the reactant 'is in equilibrium biased to the right with' the product) + else: [x: "*"] + +- name: chemical-equation-operator + tag: chemical-equation-operator + match: "." + replace: + - bookmark: "@id" + - x: "text()" + +- name: none + tag: none + match: "../../*[self::m:chemical-formula or self::m:chemical-nuclide]" + replace: + - t: "" # don't say anything + +- name: ignore-intent-wrapper + tag: intent-wrapper + match: "." + replace: + - x: "*" \ No newline at end of file From 4c9fc2b4ef38b80648651019161af40bf06237fb Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Sat, 25 Apr 2026 09:56:56 -0400 Subject: [PATCH 03/31] minor corrections to definitions.yaml --- Rules/Languages/fr/definitions.yaml | 68 ++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/Rules/Languages/fr/definitions.yaml b/Rules/Languages/fr/definitions.yaml index 8feea1791..8be98268f 100644 --- a/Rules/Languages/fr/definitions.yaml +++ b/Rules/Languages/fr/definitions.yaml @@ -4,6 +4,15 @@ # French overrides for language-dependent speech definitions. Anything omitted # here continues to fall back to the shared English defaults. +# If an "intent" is used, the 'terse:medium:verbose' speech for the intent name is given here for a prefix||infix||postfix||function fixity +# If only one ":" is used, the first part is used for 'terse' and the second part is used for 'medium' and 'verbose' +# If no ":"s are used, the same speech is used for all forms +# If bracketing words make sense, they are separated with ";"s +# Intent mappings must specify whether they are "prefix", "infix", "postfix", or "function" with an "=" sign +# If there are multiple fixities (e.g., see transpose), they are separated with "||" +# for readability, spaces can be used around any of the delimiter characters +# Note: if there are multiple fixities, the first one is used if the fixity is not given in the intent + - IntentMappings: { "indexed-by": "infix= ; indice; fin d'indice: fin d'indice: fin d'indice", "modified-variable": "silent= ", @@ -43,10 +52,12 @@ "chemistry-concentration": "function= ; concentration: concentration de: la concentration de; fin de concentration", } +# Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) - TerseFunctionNames: { "divergence", "gradient", "curl" } +# These are the parts of a formula that can be navigated to - NavigationParts: { "large-op": "base; borne inférieure; borne supérieure", "mfrac": "numérateur; dénominateur", @@ -68,6 +79,8 @@ "mover": "base; borne supérieure", "munderover": "base; borne inférieure; borne supérieure", + # words for moving into and out of one of the parts (e.g., "move right 'out of' numerator, 'in' denominator") + # it's a hack to put them here, but at least they are grouped with the other navigation parts "in": "dans", "out": "hors de", } @@ -78,7 +91,12 @@ "n": "nano", "p": "pico", "f": "femto", "a": "atto", "z": "zepto", "y": "yocto", "r": "ronto", "q": "quecto" } +# this is a list of all units that accept SIPrefixes +# from www.bipm.org/documents/20126/41483022/SI-Brochure-9-EN.pdf +# Prefixes may be used with any of the 29 SI units with special names +# The SI prefixes can be used with several of accepted units, but not, for example, with the non-SI units of time. - SIUnits: { + # base units "A": "ampère", "cd": "candela", "K": "kelvin", "K": "kelvin", @@ -87,6 +105,7 @@ "mol": "mole", "s": "seconde", "sec": "seconde", + # derived units "Bq": "becquerel", "C": "coulomb", "°C": "degré Celsius", "℃": "degré Celsius", @@ -108,6 +127,7 @@ "W": "watt", "Wb": "weber", + # accepted (plus a few variants) that take SI prefixes "l": "litre", "L": "litre", "ℓ": "litre", "t": "tonne métrique", "Da": "dalton", @@ -117,9 +137,11 @@ "rad": "radian", "sr": "stéradian", + # others that take a prefix "a": "année", "as": "seconde d'arc", + # technically wrong, but used in practice with SI Units "b": "bit", "B": "octet", "Bd": "baud", @@ -170,6 +192,7 @@ - EnglishUnits: { "in": "pouce", "ft": "pied", + "yd": verge, "mi": "mille", "rd": "perche", "li": "chaînon", @@ -177,19 +200,19 @@ "sq in": "pouce carré", "sq. in": "pouce carré", "sq. in.": "pouce carré", "sq ft": "pied carré", "sq. ft": "pied carré", "sq. ft.": "pied carré", - "sq yd": "yard carré", "sq. yd": "yard carré", "sq. yd.": "yard carré", + "sq yd": "verge carré", "sq. yd": "verge carré", "sq. yd.": "verge carré", "sq mi": "mille carré", "sq. mi": "mille carré", "sq. mi.": "mille carré", "ac": "acre", "FBM": "board foot", "cu in": "pouce cube", "cu. in": "pouce cube", "cu. in.": "pouce cube", "cu ft": "pied cube", "cu. ft": "pied cube", "cu. ft.": "pied cube", - "cu yd": "yard cube", "cu. yd": "yard cube", "cu. yd.": "yard cube", + "cu yd": "verge cube", "cu. yd": "verge cube", "cu. yd.": "verge cube", "bbl": "baril", "BBL": "baril", "pk": "peck", "bu": "boisseau", "tsp": "cuillère à café", - "tbl": "cuillère à soupe", + "tbl": "cuillère à table", "fl dr": "dram liquide", "fl oz": "once liquide", @@ -203,7 +226,7 @@ "dr": "dram", "oz": "once", "℥": "once", "lb": "livre", - "cwt": "hundredweight", + "cwt": "quintal", "dwt": "pennyweight", "oz t": "once troy", "lb t": "livre troy", @@ -235,35 +258,59 @@ "tour par minute": "tours par minute", "pouce carré": "pouces carrés", "pied carré": "pieds carrés", - "yard carré": "yards carrés", + "yard carré": "verges carrés", "mille carré": "milles carrés", "pouce cube": "pouces cubes", "pied cube": "pieds cubes", - "yard cube": "yards cubes", + "yard cube": "verges cubes", "once liquide": "onces liquides", "cuillère à café": "cuillères à café", - "cuillère à soupe": "cuillères à soupe", + "cuillère à soupe": "cuillères à table", "degré": "degrés", "mille par heure": "milles par heure", "mille par gallon": "milles par gallon" } +# ---------------- Cardinal and Ordinal Numbers -------------------------- +# The following definitions are used to convert numbers to words +# The are mainly used for ordinals, of which there are two cases: +# 1. Regular ordinals: first, second, third, ... +# 2. Ordinals used in the denominator of fractions (e.g, one half, one third) +# When used in the denominator of fractions, a plural version might be +# used (e.g., two halves, two thirds) +# Although a lot of languages are regular after a few entries, for generality, +# the following lists should be filled out even though they are the same +# or easily derived from others in many languages (e.g, an 's' is added for plurals). +# The larger ordinal numbers (e.g, millionth) is used when there are only +# '0's after that decimal place (e.g., 23000000).:w + +# All definitions start 0, 10, 100, etc. + +# TODO: does that belong here? (vingt-et-un, trente-et-un, etc.) - NumbersOnes: [ "zéro", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", "dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", - "dix-sept", "dix-huit", "dix-neuf" + "dix-sept", "dix-huit", "dix-neuf", + "vingt-et-un", "trente-et-un", "quarante-et-un", "cinquante-et-un", "soixante-et-un", + "soixante-et-onze", "quatre-vingt-un", "quatre-vingt-onze" ] +# TODO: does that belong here? (vingt-et-unième, trente-et-unième, etc.) - NumbersOrdinalOnes: [ "zéroième", "premier", "deuxième", "troisième", "quatrième", "cinquième", "sixième", "septième", "huitième", "neuvième", "dixième", "onzième", "douzième", "treizième", "quatorzième", "quinzième", "seizième", - "dix-septième", "dix-huitième", "dix-neuvième" + "dix-septième", "dix-huitième", "dix-neuvième", + "vingt-et-unième", "trente-et-unième", "quarante-et-unième", "cinquante-et-unième", "soixante-et-unième", + "soixante-et-onzième", "quatre-vingt-unième", "quatre-vingt-onzième" ] +# TODO: does that belong here? (vingt-et-unièmes, trente-et-unièmes, etc.) - NumbersOrdinalPluralOnes: [ "zéroièmes", "premiers", "deuxièmes", "troisièmes", "quatrièmes", "cinquièmes", "sixièmes", "septièmes", "huitièmes", "neuvièmes", "dixièmes", "onzièmes", "douzièmes", "treizièmes", "quatorzièmes", "quinzièmes", "seizièmes", - "dix-septièmes", "dix-huitièmes", "dix-neuvièmes" + "dix-septièmes", "dix-huitièmes", "dix-neuvièmes", + "vingt-et-unièmes", "trente-et-unièmes", "quarante-et-unièmes", "cinquante-et-unièmes", "soixante-et-unièmes", + "soixante-et-onzièmes", "quatre-vingt-unièmes", "quatre-vingt-onzièmes" ] - NumbersOrdinalFractionalOnes: [ @@ -274,6 +321,7 @@ "zéros", "premiers", "demis", "tiers", "quarts", "cinquièmes", "sixièmes", "septièmes", "huitièmes", "neuvièmes", "dixièmes" ] +# TODO: make a special case for belgian french (fr-BE) where soixante-dix -> septante, quatre-vingt -> octante, quatre-vingt-dix -> nonante - NumbersTens: [ "", "dix", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante-dix", "quatre-vingt", "quatre-vingt-dix" ] From b80ce11d9b244ee127ea5e16fd861161b4e3941a Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Sat, 25 Apr 2026 10:05:19 -0400 Subject: [PATCH 04/31] added comment to overview.yaml --- Rules/Languages/fr/overview.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Rules/Languages/fr/overview.yaml b/Rules/Languages/fr/overview.yaml index 306b74f27..b077f447a 100644 --- a/Rules/Languages/fr/overview.yaml +++ b/Rules/Languages/fr/overview.yaml @@ -1,5 +1,18 @@ --- +# Provide an overview/outline/description of the math +# MathPlayer just tried to shorten things like "mfrac" by just saying "fraction" +# For mrow, it say up to 5 operands and just say "and n more things" for the rest +# This results in strings of varying length. Given human memory is about 7 words long, +# it would be better to aim for 7 words (maybe aim for a range of 6-10 words). +# Idea: +# Start by generating a terse form of the speech +# At every step when the strings are being joined +# a) if the #words <= 7, return the joined string +# b) otherwise, set verbosity to 'overview' and regenerate the expression and use that +# There is a balance that you want to maximize the info given, so 10 words is likely better then 3. +# That might mean that at the top level, we may want to allow the first few children to expand + - name: overview-default tag: [mfrac, fraction] match: "." From 1ee0736071f6360dce047f9effc2a2e8cce1571a Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Wed, 6 May 2026 22:05:33 -0400 Subject: [PATCH 05/31] first pass in unicode.yaml --- Rules/Languages/fr/unicode.yaml | 66 ++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Rules/Languages/fr/unicode.yaml b/Rules/Languages/fr/unicode.yaml index 807078568..46374ffff 100644 --- a/Rules/Languages/fr/unicode.yaml +++ b/Rules/Languages/fr/unicode.yaml @@ -42,12 +42,12 @@ then_test: if: "$Verbosity = 'Terse'" then: [t: "bang"] # 0x21 (DeepL translation) - else: [t: "factorielle"] # 0x21 (en: 'exclamation point') + else: [t: "point d'exclamation"] # 0x21 (en: 'exclamation point') else: [t: "factorielle"] # 0x21 (en: 'factorial') - - "\"": [t: "barre oblique inversée"] # 0x22 (en: 'quotation mark') + - "\"": [t: "guillemet"] # 0x22 (en: 'quotation mark') - "#": [t: "dièse"] # 0x23 (en: 'number') - - "$": [t: "dollars"] # 0x24 + - "$": [t: "dollar"] # 0x24 - "%": [t: "pourcent"] # 0x25 (en: 'percent') - "&": [t: "esperluette"] # 0x26 (en: 'ampersand') - "'": [t: "apostrophe"] # 0x27 (SRE: 'prime') @@ -71,8 +71,8 @@ - "*": # 0x2a test: if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [t: "étoile"] # 0x2a (en: 'star', DeepL translation) - else: [t: "astérisque"] # 0x2a (en: 'times') + then: [t: "astérisque"] # 0x2a (en: 'star', DeepL translation) + else: [t: "fois"] # 0x2a (en: 'times') - "+": [t: "plus"] # 0x2b (MathPlayer: 'pluce') - ",": # 0x2c # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent @@ -86,7 +86,7 @@ # except if expression starts with '…' - "../*[1][.='…'] " then: - - T: "comma" # (en: 'comma', google translation) + - t: "virgule" # (en: 'comma') - test: if: "$Verbosity != Terse" then: [pause: short] @@ -102,7 +102,7 @@ - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" then: [t: "barre oblique"] # 0x2f (en: 'slash', DeepL translation) - else: [t: "barre oblique"] # 0x2f (en: 'divided by') + else: [t: "divisé par"] # 0x2f (en: 'divided by') - ":": [t: "deux points"] # 0x3a (en: 'colon') - ";": [t: "point virgule"] # 0x3b (en: 'semicolon') @@ -127,19 +127,19 @@ - "[": # 0x5b - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "parenthèse ouverte"] # (en: 'open bracket', DeepL translation) + then: [t: "crochet ouvrant"] # (en: 'open bracket') else: [t: "crochet gauche"] # (en: 'left bracket', MathPlayer: 'crochet ouvrant', DeepL: 'parenthèse gauche') - "\\": [t: "crochet gauche"] # 0x5c (en: 'back slash', MathPlayer: 'crochet ouvrant', DeepL: 'barre oblique arrière') - "]": # 0x5d - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "parenthèse fermée"] # (en: 'close bracket', DeepL translation) + then: [t: "crochet fermant"] # (en: 'close bracket') else: [t: "crochet droit"] # (en: 'right bracket', MathPlayer: 'crochet fermant', DeepL: 'parenthèse droite') - "^": # 0x5e - test: if: "parent::m:modified-variable or parent::m:mover" - then: [t: "chapeau"] # (en: 'hat', DeepL translation) - else: [t: "circonflexe"] # (en: 'caret') + then: [t: "accent circonflexe"] # (en: 'hat') + else: [t: "accent circonflexe"] # (en: 'caret') - "_": [t: "tiret bas"] # 0x5f (en: 'under bar') - "`": [t: "accent grave"] # 0x60 (en: 'grave') - "{": # 0x7b @@ -162,19 +162,19 @@ - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" then: [t: "divise"] # (en: 'divides', DeepL translation) - else: [t: "barre verticale"] # (en: 'vertical line') + else: [t: "ligne verticale"] # (en: 'vertical line') - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" then: [t: "ligne verticale"] # (en: 'vertical line', DeepL translation) - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" then: [t: "tel que"] # (en: 'such that', DeepL translation) - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" then: [t: "donné"] # (en: 'given', DeepL translation) - - else: [t: "barre verticale"] # (en: 'divides') + - else: [t: "divise"] # (en: 'divides') - "}": # 0x7d - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "accolade"] # (en: 'close brace', DeepL translation) + then: [t: "accolade fermée"] # (en: 'close brace') else: [t: "accolade droite"] # (en: 'right brace', MathPlayer: 'accolade fermante') - "~": [t: "tilde"] # 0x7e @@ -185,7 +185,7 @@ then: [t: "vide"] # want to say something for fraction (etc) with empty child (en: 'empty', DeepL translation) else: [t: ""] - - "¬": [t: "négation"] # 0xac (en: 'not') + - "¬": [t: "non"] # 0xac (en: 'not') - "°": [t: "degrés"] # 0xb0 (en: 'degrees') - "±": [t: "plus ou moins"] # 0xb1 (en: 'plus or minus') - "´": [t: "accent aigu"] # 0xb4 (en: 'acute') @@ -193,7 +193,7 @@ - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" then: [t: "point"] # (en: 'dot', DeepL translation) - else: [t: "point médian"] # (en: 'times') + else: [t: "fois"] # (en: 'times') - "×": # 0xd7 - test: if: "$SpeechStyle = 'ClearSpeak'" @@ -205,7 +205,7 @@ else: [t: "multiplié par"] # (en: 'cross') else_test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "croix"] # (en: 'cross', DeepL translation) + then: [t: "multiplié par"] # (en: 'cross', DeepL translation) else: [t: "multiplié par"] # (en: 'times') - "÷": [t: "divisé par"] # 0xf7 (en: 'divided by') @@ -255,7 +255,7 @@ - "ξ": [t: "xi"] # 0x3be (en: 'zai', DeepL: 'zai') - "ο": [t: "omicron"] # 0x3bf - "π": [t: "pi"] # 0x3c0 - - "ρ": [t: "rho"] # 0x3c1 + - "ρ": [t: "rhô"] # 0x3c1 - "ς": [t: "sigma final"] # 0x3c2 (en: 'final sigma') - "σ": [t: "sigma"] # 0x3c3 - "τ": [t: "tau"] # 0x3c4 @@ -264,13 +264,13 @@ - "χ": [t: "chi"] # 0x3c7 - "ψ": [t: "psi"] # 0x3c8 - "ω": [t: "oméga"] # 0x3c9 (en: 'omega') - - "ϕ": [t: "phi droit"] # 0x3d5 (en: 'phi', DeepL: 'phi') - - "ϖ": [t: "pi cursif"] # 0x3d6 (en: 'pi', DeepL: 'pi') + - "ϕ": [t: "phi"] # 0x3d5 (en: 'phi', DeepL: 'phi') + - "ϖ": [t: "pi"] # 0x3d6 (en: 'pi', DeepL: 'pi') - "ϵ": [t: "epsilon"] # 0x3f5 - - "϶": [t: "epsilon lunaire réfléchi"] # 0x3f6 (en: 'reversed epsilon') + - "϶": [t: "epsilon inversé"] # 0x3f6 (en: 'reversed epsilon') - - "–": [t: "trait d'union insécable"] # 0x2013 (en: 'en dash') - - "—": [t: "tiret numérique"] # 0x2014 (en: 'em dash') + - "–": [t: "tirait demi-cadratin"] # 0x2013 (en: 'en dash') + - "—": [t: "tiret cadratin"] # 0x2014 (en: 'em dash') - "―": [t: "barre horizontalle"] # 0x2015 (en: 'horizontal bar') - "‖": [t: "double ligne verticale"] # 0x2016 (en: 'double vertical line') - "…": # 0x2026 @@ -298,13 +298,13 @@ preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) )" - then: [t: "de"] # (en: 'of', DeepL translation) + then: [t: "de"] # (en: 'of', DeepL translation) - "⁢": [t: ""] # 0x2062 - "⁣": [t: ""] # 0x2063 - - "⁤": [t: "plus"] # 0x2064 (en: 'and', DeepL: 'et') - - "′": [t: "prime"] # 0x2032 - - "″": [t: "double prime"] # 0x2033 - - "‴": [t: "triple prime"] # 0x2034 + - "⁤": [t: "et"] # 0x2064 (en: 'and', DeepL: 'et') + - "′": [t: "prime"] # 0x2032 + - "″": [t: "double prime"] # 0x2033 + - "‴": [t: "triple prime"] # 0x2034 - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - t: "triple prime" # (en: 'double-struck') @@ -313,7 +313,7 @@ - "℃": [t: "degré celsius"] # 0x2103 (en: 'degrees celsius', DeepL: 'degrés celsius') - "℉": [t: "degré fahrenheit"] # 0x2109 (en: 'degrees fahrenheit', DeepL: 'degrés fahrenheit') - "ℋℛℓ": # 0x210b - - t: "degré fahrenheit" # (en: 'script', DeepL: 'script') + - t: "script" # (en: 'script', DeepL: 'script') - spell: "translate('.', 'ℋℛℓ', 'HRl')" - "ℎ": [t: "constante de planck"] # 0x210e (en: 'planck constant') - "ℜ": # 0x211c @@ -332,11 +332,11 @@ - "→": # 0x2192 - test: if: "ancestor::*[2][self::m:limit]" - then: [t: "approche"] # (en: 'approaches', DeepL translation) - else: [t: "flèche droite"] # (en: 'right arrow', MathPlayer: 'flèche vers la droite') + then: [t: "approches"] # (en: 'approaches', DeepL translation) + else: [t: "flèche vers la droite"] # (en: 'right arrow', MathPlayer: 'flèche vers la droite') - "↓": [t: "flèche vers le bas"] # 0x2193 (en: 'downwards arrow') - - "⇒": [t: "double flèche vers la droite"] # 0x21d2 (en: 'rightwards double arrow', SRE: 'double flèche droite') + - "⇒": [t: "double flèche vers la droite"] # 0x21d2 (en: 'rightwards double arrow', SRE: 'double flèche droite') - "∀": [t: "pour tous"] # 0x2200 (en: 'for all') - "∂": # 0x2202 - test: @@ -350,7 +350,7 @@ - test: if: "$Verbosity!='Terse'" then: [t: "le"] # (en: 'the', DeepL translation) - - t: "incrément" # (en: 'laplacian of') + - t: "laplacien de" # (en: 'laplacian of') - "∈": # 0x2208 - test: if: "$SpeechStyle != 'ClearSpeak'" From 788a748f5ee3a854d1e817f1463fdfb166dbfc01 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Fri, 8 May 2026 11:02:11 -0400 Subject: [PATCH 06/31] modifications to unicode.yaml --- Rules/Languages/fr/unicode.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Rules/Languages/fr/unicode.yaml b/Rules/Languages/fr/unicode.yaml index 46374ffff..c940095bc 100644 --- a/Rules/Languages/fr/unicode.yaml +++ b/Rules/Languages/fr/unicode.yaml @@ -438,12 +438,12 @@ - "∑": [t: "sommation"] # 0x2211 (en: 'sum') - "−": [t: "moins"] # 0x2212 (en: 'minus') - "∓": [t: "moins ou plus"] # 0x2213 (en: 'minus or plus', MathPlayer: 'moins-ou-plus') - - "∗": [t: "opérateur astérisque"] # 0x2217 (en: 'times') - - "∘": [t: "opérateur rond"] # 0x2218 (en: 'composed with') + - "∗": [t: "fois"] # 0x2217 (en: 'times') + - "∘": [t: "composé avec"] # 0x2218 (en: 'composed with') - "√": # 0x221a - test: if: "$Verbosity!='Terse'" - then: [t: "le"] # (en: 'the', DeepL translation) + then: [t: "la"] # (en: 'the', DeepL translation) - t: "racine carrée" # (en: 'square root of') - "∝": # 0x221d - test: @@ -468,8 +468,8 @@ - "∦": # 0x2226 - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "non parallèle à" # (en: 'not parallel to') + then: [t: "n'est"] # (en: 'is', DeepL translation) + - t: "pas parallèle à" # (en: 'not parallel to') - "∧": [t: "et logique"] # 0x2227 (en: 'and') - "∨": [t: "ou logique"] # 0x2228 (en: 'or') - "∩": [t: "intersection"] # 0x2229 @@ -484,8 +484,8 @@ then: [t: "est"] # (en: 'is', DeepL translation) - t: "rapport" # (en: 'to') - "∷": [t: "proportion"] # 0x2237 (en: 'as') - - "∼": [t: "opérateur tilde"] # 0x223c (en: 'varies with') - - "∽": [t: "opérateur tilde renversé"] # 0x223d (en: 'reversed tilde') + - "∼": [t: "varie avec"] # 0x223c (en: 'varies with') + - "∽": [t: "tilde renversé"] # 0x223d (en: 'reversed tilde') - "∾": # 0x223e - test: if: "$Verbosity!='Terse'" @@ -495,7 +495,7 @@ - "≠": # 0x2260 - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) + then: [t: "n'est"] # (en: 'is', DeepL translation) - t: "pas égal à" # (en: 'not equal to') - "≡": # 0x2261 - test: @@ -512,8 +512,8 @@ if: "$Verbosity!='Terse'" then: [t: "est"] # (en: 'is', DeepL translation) - t: "plus grand ou égal à" # (en: 'greater than or equal to') - - "≦": [t: "plus petit que par dessus égal à"] # 0x2266 (en: 'less than over equal to', MathPlayer: 'plus petit que par-dessus égal à', DeepL: 'inférieur à supérieur à égal à') - - "≧": [t: "plus grand que par dessus égal à"] # 0x2267 (en: 'greater than over equal to', MathPlayer: 'plus grand que par-dessus égal à', DeepL: 'supérieur à égal à') + - "≦": [t: "plus petit que par-dessus égal à"] # 0x2266 (en: 'less than over equal to', MathPlayer: 'plus petit que par-dessus égal à', DeepL: 'inférieur à supérieur à égal à') + - "≧": [t: "plus grand que par-dessus égal à"] # 0x2267 (en: 'greater than over equal to', MathPlayer: 'plus grand que par-dessus égal à', DeepL: 'supérieur à égal à') - "≺": [t: "précède"] # 0x227a (en: 'precedes') - "≻": [t: "suit"] # 0x227b (en: 'succeeds') - "⊂": # 0x2282 @@ -529,12 +529,12 @@ - "⊄": # 0x2284 - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) + then: [t: "n'est"] # (en: 'is', DeepL translation) - t: "pas un sous-ensemble de" # (en: 'not a subset of', SRE: 'pas un sous ensemble de') - "⊅": # 0x2285 - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) + then: [t: "n'est"] # (en: 'is', DeepL translation) - t: "pas un sur ensemble de" # (en: 'not a superset of', MathPlayer: 'pas un sur-ensemble de', DeepL: 'n'est pas un super-ensemble de') - "⊆": # 0x2286 - test: From fb34d78ee9a0977ef6663d0e4172205f74547bbf Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Fri, 8 May 2026 12:44:58 -0400 Subject: [PATCH 07/31] started test adjustments for functions.rs --- Rules/Languages/fr/definitions.yaml | 2 +- tests/Languages/fr/SimpleSpeak/functions.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Rules/Languages/fr/definitions.yaml b/Rules/Languages/fr/definitions.yaml index 8be98268f..2f0584875 100644 --- a/Rules/Languages/fr/definitions.yaml +++ b/Rules/Languages/fr/definitions.yaml @@ -30,7 +30,7 @@ "lim-inf": "prefix=lim inf quand: la limite inférieure quand: la limite inférieure quand", "logarithm-with-base": "prefix=log en base: le log en base: le log en base", "natural-logarithm": "function=l n: logarithme naturel: logarithme naturel", - "minus": "infix=moins || prefix=négatif", + "minus": "infix=moins || prefix=moins", "plus": "infix=plus || prefix=positif", "real-part": "function=la partie réelle", diff --git a/tests/Languages/fr/SimpleSpeak/functions.rs b/tests/Languages/fr/SimpleSpeak/functions.rs index a2c821b05..fb48592c8 100644 --- a/tests/Languages/fr/SimpleSpeak/functions.rs +++ b/tests/Languages/fr/SimpleSpeak/functions.rs @@ -17,7 +17,7 @@ fn trig_names() -> Result<()> { cscϕ+ cotφ "; - test("fr", "SimpleSpeak", expr, "sinus de x plus cosinus de y plus tangente de z plus sécante de alpha, plus cosécante de phi droit, plus cotangente de phi")?; + test("fr", "SimpleSpeak", expr, "sinus de x plus cosinus de y plus tangente de z plus sécante de alpha, plus cosécante de phi, plus cotangente de phi")?; Ok(()) } @@ -32,7 +32,7 @@ fn hyperbolic_trig_names() -> Result<()> { cschϕ+ cothφ "; - test("fr", "SimpleSpeak", expr, "sinus hyperbolique de x, plus cosinus hyperbolique de y, plus tangente hyperbolique de z, plus, sécante hyperbolique de alpha, plus, cosécante hyperbolique de phi droit; plus, cotangente hyperbolique de phi")?; + test("fr", "SimpleSpeak", expr, "sinus hyperbolique de x, plus cosinus hyperbolique de y, plus tangente hyperbolique de z, plus, sécante hyperbolique de alpha, plus, cosécante hyperbolique de phi, plus, cotangente hyperbolique de phi")?; Ok(()) } @@ -261,7 +261,7 @@ fn no_times_sqrt() -> Result<()> { 2 ) "; - test("fr", "SimpleSpeak", expr, "2 plus négatif 2")?; + test("fr", "SimpleSpeak", expr, "2 plus moins 2")?; Ok(()) } @@ -275,7 +275,7 @@ fn no_times_sqrt() -> Result<()> { ) +1 "; - test("fr", "SimpleSpeak", expr, "négatif 2 x, plus 1")?; + test("fr", "SimpleSpeak", expr, "moins 2 x, plus 1")?; Ok(()) } @@ -322,7 +322,7 @@ fn no_times_sqrt() -> Result<()> { (c,d) ) "; - test("fr", "SimpleSpeak", expr, "open interval de c comma, d")?; + test("fr", "SimpleSpeak", expr, "l'interval ouvert de c à d")?; Ok(()) } From 70d9289a13dd958bbd412a8006944bacb744d7a7 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Mon, 11 May 2026 17:27:51 -0400 Subject: [PATCH 08/31] added ClearSpeak_Rules.yaml --- Rules/Languages/fr/ClearSpeak_Rules.yaml | 766 +++++++++++++++++++++++ 1 file changed, 766 insertions(+) create mode 100644 Rules/Languages/fr/ClearSpeak_Rules.yaml diff --git a/Rules/Languages/fr/ClearSpeak_Rules.yaml b/Rules/Languages/fr/ClearSpeak_Rules.yaml new file mode 100644 index 000000000..133fce420 --- /dev/null +++ b/Rules/Languages/fr/ClearSpeak_Rules.yaml @@ -0,0 +1,766 @@ +--- +- name: pause + tag: "!*" + match: "not(self::m:math) and not($MatchingPause) and @data-intent-property[contains(., ':pause')]" + replace: + - with: + variables: [MatchingPause: "true()"] + replace: + - test: + - if: "contains(@data-intent-property, ':pause-long')" + then: [pause: long] + - else_if: "contains(@data-intent-property, ':pause-short')" + then: [pause: short] + else: [pause: medium] + - x: "." + +- name: intent-literal-silent + tag: [mi, mo, mn] + match: "contains(@data-intent-property, ':silent:')" + # say nothing + replace: [] + +# handling of negative numbers that come from 'intent' is hard -- we do something that is close to right here +- name: intent-literal-negative-number + tag: mn + match: "starts-with(text(), '-')" + replace: + - t: "moins" # phrase(10 'minus' 4 equals 6) + - x: "translate(text(), '-_', '')" + +- name: default + tag: square-root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [t: "la"] # phrase('the' square root of 25) + - test: + if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - bookmark: "*[1]/@id" + - test: + if: "parent::*[self::m:minus and count(*)=1]" + then: [t: "négatif"] # phrase(minus 4 is a 'negative' number) + else: [t: "positif"] # phrase(10 is a 'positive' number) + - t: "racine carrée" # phrase(8 is the 'square root' of 64) + - test: + if: "$Verbosity!='Terse'" + then: [t: "de"] # phrase(the square root 'of' 5) + else: [pause: short] + - x: "*[1]" + - test: + - if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - pause: short + - t: "fin de racine" # phrase(the square root of x 'end root') + - pause: medium + - else_if: "IsNode(*[1], 'simple')" + then: [pause: short] + else: [pause: long] + +- name: default + tag: root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [t: "la"] # phrase(6 is 'the' square root of 36) + - test: + if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - test: + if: "parent::*[(self::m:minus or self::m:plus) and count(*)=1]" + then: [bookmark: "parent/@id"] + - test: + if: "parent::m:minus" + then: [t: "négatif"] # phrase(minus 6 is a 'negative' number) + else: [t: "positif"] # phrase(10 is a 'positive' number) + - test: + if: "*[2][self::m:mn and not(contains(., '.'))]" + then_test: + - if: "*[2][.='2']" + then: [t: "racine carrée"] # phrase(5 is the 'square root' of 25) + - else_if: "*[2][.='3']" + then: [t: "racine cubique"] # phrase(5 is the 'cube root' of 625) + - else: [x: "ToOrdinal(*[2])", t: "racine"] # phrase(the square 'root' of 25) + else: + - test: + if: "*[2][self::m:mi][string-length(.)=1]" + then: + - x: "*[2]" + - pronounce: [text: "-ième", ipa: "jɛm", sapi5: "ieme", eloquence: "ieme"] + else: [x: "*[2]"] + - t: "racine" # phrase(the square 'root' of 36) + - test: + if: "$Verbosity!='Terse'" + then: [t: "de"] # phrase(the square root 'of' 36) + - x: "*[1]" + - test: + if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - pause: short + - t: "fin de racine" # phrase(start the fifth root of x 'end root') + - pause: medium + else_test: + if: "IsNode(*[1], 'simple')" + then: [pause: short] + else: [pause: long] + +# The 'negative' rule interacts with the msqrt/mroot rules as those might pick off this case ("the negative square root of x") +- name: negative_and_positive + tag: [plus, minus] + match: "count(*)=1 and contains(@data-intent-property, ':prefix:')" + replace: + - test: + if: + - "*[1][self::m:square-root or self::m:root] and" + - "($ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd')" + then: [t: ""] + else: + - bookmark: "@id" + - test: + if: "self::m:minus" + then: [t: "négatif"] # phrase(minus 5 is a 'negative' number) + else: [t: "positif"] # phrase(7 is a 'positive' number) + - x: "*[1]" + +# Fraction rules +# Mixed numbers mostly "just work" because the invisible char reads as "and" and other parts read properly on their own + +# Units (e.g., meters per second) +- name: per-fraction + tag: fraction + match: + - "$ClearSpeak_Fractions='Per' or" + - "(BaseNode(*[1])[contains(@data-intent-property, ':unit') or" + - " ( self::m:mrow and count(*)=3 and" # maybe a bit paranoid checking the structure... + - " *[1][self::m:mn] and *[2][.='\u2062'] and BaseNode(*[3])[contains(@data-intent-property, ':unit')] ) ] and" + - " BaseNode(*[2])[contains(@data-intent-property, ':unit')] )" + replace: + - x: "*[1]" + - t: "par" # phrase('5 meters 'per' second) + - x: "*[2]" + +- name: common-fraction + tag: fraction + match: + - "($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and" + - "*[1][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and" + - "*[2][self::m:mn][not(contains(., $DecimalSeparators)) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))]" + variables: [IsPlural: "*[1]!=1"] + replace: + - x: "*[1]" + - x: "ToOrdinal(*[2], true(), $IsPlural)" # extra args specify fractional ordinal and whether it is plural + +- name: fraction-over-simple + tag: fraction + match: + - "($ClearSpeak_Fractions='Over' or $ClearSpeak_Fractions='FracOver' or $ClearSpeak_Fractions='OverEndFrac') or" + - "( not($ClearSpeak_Fractions='General' or $ClearSpeak_Fractions='GeneralEndFrac') and" + - " (IsNode(*[1],'simple') and IsNode(*[2],'simple')) )" # simple fraction in ClearSpeak spec + replace: + - test: + if: "$ClearSpeak_Fractions='FracOver'" + then: + - test: + if: "$Verbosity!='Terse'" + then: [ot: "la"] + - t: "fraction" # phrase(the 'fraction' with 3 over 4) + - x: "*[1]" + - t: "sur" # phrase(the fraction 3 'over' 4) + - x: "*[2]" + - test: + # very ugly!!! -- replicate nested ordinal fraction as they are an exception + if: "$ClearSpeak_Fractions='OverEndFrac' or ($ClearSpeak_Fractions='EndFrac' and not( ($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and *[1][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] and *[2][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] ) )" + then: + - pause: short + - t: "fin de fraction" # phrase(7 over 8 'end fraction') + - pause: short + +- # fraction with text or numbers followed by text in both numerator and denominator + name: fraction-over-text + tag: fraction + match: + - "not($ClearSpeak_Fractions='General' or $ClearSpeak_Fractions='GeneralEndFrac') and" + - "( " + - " ((*[1][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text + - " (*[1][self::m:mrow][count(*)=3][ " + - " *[1][self::m:mn] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) ) and" + - " ((*[2][self::m:mi or self::m:mtext][string-length(.)>1]) or " # fractions with text + - " (*[2][self::m:mrow][count(*)=3][ " + - " *[1][self::m:mn] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[3][self::m:mi or self::m:mtext][string-length(.)>1] ]) )" + - ")" + replace: + - x: "*[1]" + - t: "sur" # phrase(the fraction 3 'over' 4) + - x: "*[2]" + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='OverEndFrac'" + then: + - pause: short + - t: "fin de fraction" # phrase(7 over 8 'end fraction') + - pause: short + +- name: default + tag: fraction + match: "." + replace: + - ot: "la" # phrase(5 is 'the' square root of 25) + - t: "fraction avec numérateur" # phrase(the 'fraction with numerator' 6) + - test: + if: "not(IsNode(*[1], 'simple'))" + then: [pause: medium] + - x: "*[1]" + - pause: medium + - t: "et dénominateur" # phrase(the fraction with numerator 5 'and denominator' 8) + - x: "*[2]" + - pause: long + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='GeneralEndFrac'" + then: + - pause: short + - t: "fin de fraction" # phrase(the fraction with 3 over 4 'end fraction') + - pause: short + +# rules for functions raised to a power +# these could have been written on 'mrow' but putting them on msup seems more specific +# to see if it is a function, we look right to see if the following sibling is apply-function +- name: ClearSpeak-function-inverse + tag: inverse-function + match: "." + replace: + - test: + if: "$ClearSpeak_Trig = 'TrigInverse'" + then: [x: "*[1]", bookmark: "*[2]/@id", t: "l'inverse"] # phrase(8 over 5 is the 'inverse' of 5 over 8) + else_test: + if: "$ClearSpeak_Trig = 'ArcTrig'" + then: [bookmark: "*[2]/@id", t: "arc", x: "*[1]"] # phrase(the 'arc' of a circle) + else: [bookmark: "*[2]/@id", t: "l'inverse", x: "*[1]"] # default/Auto # phrase(8 over 5 is the 'inverse' of 5 over 8) + +- name: function-squared-or-cubed + tag: power + match: + - "*[2][self::m:mn][.='2' or .='3'] and" + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - test: + if: "*[2][.='2']" + then: [t: "au carré"] # phrase(25 equals 5 'squared') + else: [t: "au cube"] # phrase(625 equals 5 'cubed') + +- name: function-power + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - test: + if: "$Verbosity!='Terse'" + then: [t: "la"] # phrase('the' third power of 2) + - bookmark: "*[2]/@id" + - test: + if: "*[2][self::m:mn][not(contains(., '.'))]" + then: [x: "ToOrdinal(*[2])"] + else: [x: "*[2]"] + - t: "puissance de" # phrase(the third 'power of' 6) + - pause: short + - x: "*[1]" + +- name: AfterPower-nested + tag: power + match: # directly a superscript or an mrow that contains a superscript + - "$ClearSpeak_Exponents = 'AfterPower' and" + - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" + replace: + - x: "*[1]" + - t: "à la puissance de" # phrase(5 'raised to the exponent' x plus 1) + - pause: short + - x: "*[2]" + - pause: short + - t: "fin de l'exposant" # phrase(5 raised to the exponent x plus 1 'end exponent') + +- name: AfterPower-default + tag: power + match: "$ClearSpeak_Exponents = 'AfterPower'" + replace: + - x: "*[1]" + - t: "à la puissance de" # phrase(x is 'raised to the power' 4) + - x: "*[2]" + - pause: short + +- name: squared + tag: power + match: "*[2][self::m:mn][.='2'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - t: "au carré" # phrase(7 'squared' equals 49) + +- name: cubed + tag: power + match: "*[2][self::m:mn][.='3'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - t: "au cube" # phrase(5 'cubed' equals 125) + +- name: simple-integer + tag: power + match: "*[2][self::m:mn][not(contains(., '.'))]" + replace: + - x: "*[1]" + - t: "à la" # phrase(2 raised 'to the' power 7) + - test: + if: "*[2][.>0]" + then: [x: "ToOrdinal(*[2])"] + else: [x: "*[2]"] + - test: + if: "$ClearSpeak_Exponents != 'Ordinal'" + then: [t: "puissance"] # phrase(2 raised to the 'power' 7) + +- name: simple-negative-integer + tag: power + match: + - "*[2][self::m:minus and count(*)=1 and " + - " *[1][self::m:mn][not(contains(., '.'))]" + - " ]" + replace: + - x: "*[1]" + - t: "à la" # phrase(2 raised 'to the' power 7) + - x: "*[2]" + - test: + if: "$ClearSpeak_Exponents != 'Ordinal'" + then: [t: "puissance"] # phrase(2 raised to the 'power' 7) + +- name: simple-var + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + - x: "*[1]" + - t: "à la" # phrase(3 raised 'to the' power 7) + - x: "*[2]" + - pronounce: [text: "-ième", ipa: "jɛm", sapi5: "ieme", eloquence: "ieme"] + - test: + if: "$ClearSpeak_Exponents != 'Ordinal'" + then: [t: "puissance"] # phrase(2 raised to the 'power' 7) + +# match nested exponent, where the nested exponent is has the power 2 or 3 (n below) +# [xxx]^n, - [xxx]^n, [xxx] var^n, -[xxx] var^n +# where xxx is a number or common fraction (or a var in the first two forms) +# short of creating a specialized built-in function, I don't see a way to eliminate a lot of repetition in the matches +# also really bad is that the test of a common fraction is replicated here (four times!) +# Note: the ClearSpeak doc doesn't say these only apply when the pref is "Auto", +# but the test cases all fall back to "raised to the exponent" when not "Auto" +# If these are allowed for non-Auto values, then you end up with "...power power...". +- # [xxx]^n + name: nested-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - "*[2][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 + # base is mn, mi, common fraction ([xxx] case) + - " *[1][self::m:mn or self::m:mi or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - t: "élevé à la" # phrase(x 'raised to the' second power) + - x: "*[2]" + - t: "puissance" # phrase(x raised to the second 'power') + +- # - [xxx]^n + name: nested-negative-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - " *[2][self::m:minus and count(*)=1 and " + - " *[1]/*[1][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3" + # base is mn, mi, common fraction ([xxx] case) + - " *[1][self::m:mn or self::m:mi or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - t: "élevé à la" # phrase(x 'raised to the' second power) + - x: "*[2]" + - t: "puissance" # phrase(x raised to the second 'power') + +- # [xxx] var^n + name: nested-var-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - " *[2][self::m:mrow][count(*)=3][ " + - " *[3][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 + - " *[1][self::m:mi]" + - " ] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + # base is mn, or common fraction ([xxx] case) + - " *[1][self::m:mn or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - t: "élevé à la" # phrase(x 'raised to the' second power) + - x: "*[2]" + - t: "puissance" # phrase(x raised to the second 'power') + +- # -[xxx] var^n + name: nested-negative-var-squared-or-cubed + tag: power + match: + - "$ClearSpeak_Exponents = 'Auto' and" + - " *[2][self::m:mrow][count(*)=3][ " + - " *[3][self::m:power][" + - " *[2][self::m:mn][.='2' or .='3'] and " # exp is 2 or 3 + - " *[1][self::m:mi]" + - " ] and " + - " *[2][self::m:mo][.='⁢'] and " # invisible times + - " *[1][self::m:minus and count(*)=1 and " + # base is mn, or common fraction ([xxx] case) + - " *[1][self::m:mn or " + - " self::m:fraction[*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - " *[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]]" + - " ]" + - " ]" + - " ]" + replace: + - x: "*[1]" + - t: "élevé à la" # phrase(x 'raised to the' second power) + - x: "*[2]" + - t: "puissance" # phrase(x raised to the second 'power') + +- name: default-exponent-power + tag: power + match: # directly a superscript or an mrow that contains a superscript + - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" + replace: + - x: "*[1]" + - t: "élevé à l'exposant" # phrase(x is 'raised to the exponent') + - pause: short + - x: "*[2]" + - pause: short + - t: "fin de l'exposant" # phrase(and now 'end exponent' has been reached) + +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + - t: "élevé à la" # phrase(x 'raised to the' second power) + - x: "*[2]" + - t: "puissance" # phrase(x raised to the second 'power') + +# +# Some rules on mrows +# +- # the inference rules lump absolute value and cardinality together, so those rules are implemented here + name: ClearSpeak-absolute-value + tag: absolute-value + match: "." + variables: [WordToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'cardinality', 'absolute value')"] + replace: + - test: + if: "$Verbosity!='Terse'" + then: [t: "la"] # phrase('the' absolute value of 25) + - x: "$WordToSay" + - t: "de" # phrase(the absolute value 'of' 25) + - x: "*[1]" + - test: + if: "$ClearSpeak_AbsoluteValue = 'AbsEnd'" + then: + - pause: short + - t: "fin" # phrase('end' absolute value) + - x: "$WordToSay" + - pause: short + +- name: set + tag: set + match: "." + replace: + - test: + - if: "count(*)=0" + then: [t: "l'ensemble vide"] # phrase('the empty set') + - else_if: "count(*)=2" + then: + - test: + if: "$Verbosity!='Terse'" + then: [t: "l'"] # phrase('the' empty set) + - t: "ensemble vide" # phrase(the 'empty set') + - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" + then: + - test: + if: "$Verbosity!='Terse'" + then: [t: "l'"] # phrase('the' set of all integers) + - t: "ensemble de" # phrase(this is a 'set of' numbers) + - test: + if: "$ClearSpeak_Sets != 'woAll'" + then: [t: "tous"] # phrase(the set of 'all' integers) + - x: "*[1]/*[1]" + - t: "tel que" # phrase(the set S 'such that' x is less than y) + - x: "*[1]/*[3]" + else: + - test: + if: "$ClearSpeak_Sets != 'SilentBracket'" + then: + - test: + if: "$Verbosity!='Terse'" + then: [t: "l'"] # phrase('the' set of integers) + - t: "ensemble" # phrase(this is a 'set' of integers) + - x: "*[1]" + +- # intervals are controlled by a ClearSpeak Preference -- parens/brackets don't have to match, so we avoid IsBracketed + # alternatively, we could have four (or ten) rules, but there is a lot of duplication if we do that + # this one rule handles all ten cases listed as part $ClearSpeak_Paren = 'Interval' + # note that *[2] is an mrow with X, ",", Y, so getting X or Y is a double index + name: ClearSpeak-intervals # avoid overriding with default "intervals" name + variables: + - is_intervals_start_infinity: "*[1][self::m:minus and count(*)=1 and *[1][.='∞']]" + - is_intervals_end_infinity: "*[2][.='∞'or (self::m:plus and count(*)=1 and *[1][.='∞'])]" + tag: [open-interval, open-closed-interval, closed-interval, closed-open-interval] + match: "." + replace: + - t: "l'invervalle de" # phrase('the interval from' a to b) + - x: "*[1]" + - t: "à" # phrase(the interval from a 'to' b) + - x: "*[2]" + - pause: short + - test: + if: "not($is_intervals_start_infinity)" + then: + - test: + if: "starts-with(name(.), 'open')" + then: [t: "sans"] # phrase(the interval from a to b 'not' including b) + - t: "inclure" # phrase(the interval from a to b not 'including' b) + - x: "*[1]" + # logic to deal with [not] arg #1 + - test: + if: "not($is_intervals_start_infinity or $is_intervals_end_infinity)" + then_test: + - if: "name(.)='open-interval'" + then: [t: "ou"] # phrase(the interval including a 'or' b ) + - else_if: "name(.)='closed-interval'" + then: [t: "et"] # phrase(the interval including a 'and' b) + else: [t: "mais"] # phrase(the interval including a 'but' not b) + # some ugly logic dealing with connectives: or, but, but, and (cleaner to be part of next clause?) + - test: + if: "not($is_intervals_end_infinity)" + then: + - test: + # there is some asymmetry to the test because of the and/or/but logic above + if: "not( name(.)='open-interval' or name(.)='closed-interval' ) or $is_intervals_start_infinity" + then: + - test: + if: "name(.) = 'open-interval' or name(.) = 'closed-open-interval'" + then: [t: "n'"] # phrase(the interval 'not' including a) + - t: "incluant pas" # phrase(the interval not 'including' a) + - x: "*[2]" + + # onto the [not] [including]... part +- name: binomial-frac-vector + tag: matrix + match: + - "$ClearSpeak_Matrix = 'Combinatorics' and " + - "count(*[1]/*)=1 and count(*)=2" + replace: + - x: "*[1]/*[1]/*" # mtable/mtr/mtd + - t: "parmi" # phrase(the binomial coefficient n 'choose' m) + - x: "*[2]/*[1]/*" + +- name: ClearSpeak-default + tag: [mtr, mlabeledtr] + match: "parent::m:matrix or parent::m:determinant" + variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] + replace: + - pause: medium + - t: "rangée" # phrase(the first 'row' of a matrix) + - x: "count(preceding-sibling::*)+1" + - test: + if: ".[self::m:mlabeledtr]" + then: + - t: "avec l'étiquette" # phrase(the line 'with label' first equation) + - x: "*[1]/*" + - pause: short + - pause: medium + - test: + if: ".[self::m:mlabeledtr]" + then: [x: "*[position()>1]"] + else: [x: "*"] + +- # handle both log and ln + name: ClearSpeak-log + tag: mi + match: ".='log' or .='ln'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity!='Terse' and not(IsNode(following-sibling::*[2],'simple'))" + then: [t: "la"] # phrase('the' square root of 25) + - test: + - if: ".='log'" + then: [t: "logarithme"] + - else_if: "$ClearSpeak_Log = 'LnAsNaturalLog'" + then: [t: "logarithme naturel"] # phrase(the 'natural log' of x) + else: [spell: "'ln'"] + +- name: ClearSpeak-multi-line + tag: [piecewise, system-of-equations, lines] # these are ignored in favor of the ClearSpeak prefs + match: "." + variables: + # Wikipedia has some tables where all the entire first column is empty (e.g., https://en.wikipedia.org/wiki/List_of_trigonometric_identities) + - LineCount: "count(*[not(contains(@data-intent-property, ':continued-row:'))])" + - NextLineIsContinuedRow: "false()" # default value + - IsColumnSilent: true() + replace: + - test: + - if: "$ClearSpeak_MultiLineOverview = 'Auto'" + then: + - x: "$LineCount" + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and self::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [t: "cas"] # phrase(this is the first 'case' of three cases) + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line' or $ClearSpeak_MultiLineLabel = 'None'" # already dealt with Auto/Case + then: [t: "ligne"] # phrase(this is the first 'line' of three lines) + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [t: "contrainte"] # phrase(this is the first 'constraint' of three constraints) + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [t: "équation"] # phrase(this is the first 'equation' of three equations) + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [t: "rangée"] # phrase(this is the first 'row' of three rows) + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [t: "étape"] # phrase(this is the first 'step' of three steps) + # else 'None -- don't say anything' + - test: + - if: "$LineCount != 1" + then: [ct: "s"] # plural # phrase(shown by the letter 's') + - pause: short + - x: "*" + - pause: long + +- name: ClearSpeak-default-multiline + tag: [mtr, mlabeledtr] + match: "parent::m:piecewise or parent::m:system-of-equations or parent::m:lines" + variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] + replace: + - test: + if: "not($LineCount=1 or $ClearSpeak_MultiLineLabel='None' or contains(@data-intent-property, ':continued-row:'))" + then: + - pause: medium + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and parent::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [t: "cas"] # phrase(in this 'case' x is not equal to y) + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" # already dealt with Auto/Case + then: [t: "ligne"] # phrase(the straight 'line' between x and y) + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [t: "contrainte"] # phrase(there is a 'constraint' on possible values) + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [t: "équation"] # phrase(the 'equation' pi r squared gives the area of a circle) + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [t: "rangée"] # phrase(the values on the top 'row' are relevant) + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [t: "étape"] # phrase(this is a 'step' by step process) + # else 'None -- don't say anything' + - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" + - test: + if: "self::m:mlabeledtr" + then: + - t: "avec étiquette" # phrase(the diagram is complete 'with label') + - x: "*[1]/*" + - test: + - if: "$ClearSpeak_MultiLineLabel='None'" + then: [pause: xlong] # need a very long pause with no line labels + - else_if: "not(contains(@data-intent-property, ':continued-row:'))" + then: [pause: medium] + - test: + if: "self::m:mlabeledtr" + then: [x: "*[position()>1]"] + else: [x: "*"] + +- name: ClearSpeak_Functions_None + tag: mo + match: + - ".='⁡' and $ClearSpeak_Functions = 'None' and" + - "not(preceding-sibling::*[1][IsInDefinition(., 'TrigFunctionNames')])" # Functions=None does not apply to "trig" functions + replace: + test: + if: "$ClearSpeak_ImpliedTimes = 'None'" + then: [t: ""] + else: [t: "fois"] # phrase(5 'times' 3 equals 15) + +- name: no-times + tag: mo + match: + # Note: this rule is also part of the paren rule so that the parens speak + - ".='⁢' and $ClearSpeak_ImpliedTimes = 'None'" + replace: + - t: "" + +- name: ClearSpeak-times + tag: mo + match: + # say "times" when invisible times is followed by parens or a superscript that has a base with parens or "|"s + # if we aren't sure if it is times or not, don't say anything + - ".='⁢' and (not(@data-function-guess) or $ClearSpeak_Functions = 'None') and" + - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) and (" + - " $ClearSpeak_ImpliedTimes = 'MoreImpliedTimes'" + - " or " + - " following-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|') or " + # most of these aren't mentioned in ClearSpeak spec, but are (I think) expected uses of "times" + - " self::m:matrix or self::m:determinant or self::m:binomial or" # followed by parens + - " self::m:square-root or self::m:msqrt or self::m:root or self::m:mroot or" + - " (self::m:msub or self::m:msubsup or" + - " ((self::m:msup or self::m:power) and not(IsNode(*[1], 'leaf') and *[2][self::m:mn and (.=2 or '.=3')]))) and " # followed by msup, etc. + - " (*[1][self::m:mrow[IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')] or " + - " self::m:matrix or self::m:determinant] or" # base has parens + - " not(IsNode(*[2], 'simple')) or " + - " (self::m:msubsup and not(IsNode(*[3], 'simple')))" + - " )" + - " ]" + # other possibility is the preceding element has parens (but not the following) + # this is not mentioned in the ClearSpeak rules or examples but seems like it should say "times". E.g, |x| y + - " or " + - " preceding-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" # followed by parens + - " )" + replace: + - t: "fois" # phrase(5 'times' 3 equals 15) + +- name: no-say-parens + tag: mrow + match: + - "parent::*[not(self::m:msup) and not(self::m:msub) and not(self::m:msubsup) and not(self::m:power) and" + - " not(self::m:math) ] and " # rule out [x] standing alone + - "( IsBracketed(., '(', ')') or IsBracketed(., '[', ']') ) and " + - "not( $ClearSpeak_Functions = 'None' and " + - " (preceding-sibling::*[1][.='⁡'] or following-sibling::*[1][.='⁡']) ) and " + - "not( $ClearSpeak_ImpliedTimes = 'None' and " + - " (preceding-sibling::*[1][.='⁢'] or following-sibling::*[1][.='⁢']) ) and " + - "IsNode(*[2], 'simple') and" + - "not(preceding-sibling::*[1][.='\u2062' and @data-function-guess]) and" + - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')])" + # missing clause: 'a positive fraction that is spoken as an ordinal + # (either by the Ordinal preference or by the default rules)' + replace: + - x: "*[2]" + +- include: "SharedRules/geometry.yaml" +- include: "SharedRules/linear-algebra.yaml" +- include: "SharedRules/general.yaml" +- include: "SharedRules/default.yaml" From 5889a023f9f6e5579f0dadb678acd642a54a5c4b Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Mon, 11 May 2026 18:38:06 -0400 Subject: [PATCH 09/31] fixed rules and tests for intervals --- Rules/Languages/fr/SharedRules/general.yaml | 38 +++++++++++++-------- tests/Languages/fr/SimpleSpeak/functions.rs | 16 ++++----- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml index 244c0a376..d0170f7e4 100644 --- a/Rules/Languages/fr/SharedRules/general.yaml +++ b/Rules/Languages/fr/SharedRules/general.yaml @@ -118,21 +118,29 @@ match: "count(*)=2" replace: - test: - if: "$Verbosity!='Terse'" - then: - - t: "la" # phrase('the' square root of 25 equals 5) - - x: "translate(name(.),'-', ' ')" - - test: - if: "$Verbosity!='Terse'" - then: - - t: "de" # phrase(subtracting 5 'from' 10 gives 5) - - x: "*[1]" - - t: "à" # phrase(adding 6 'to' 6 equals 12) - - x: "*[2]" - else: - - x: "*[1]" - - t: "virgule" # phrase(use a 'comma' to divide large numbers or as a decimal point) - - x: "*[2]" + - if: "self::m:open-interval" + then_test: + if: "$Verbosity!='Terse'" + then: [t: "l'intervalle ouvert"] + else: [t: "intervalle ouvert"] + - else_if: "self::m:open-closed-interval" + then_test: + if: "$Verbosity!='Terse'" + then: [t: "l'intervalle ouvert fermé"] + else: [t: "intervalle ouvert fermé"] + - else_if: "self::m:closed-interval" + then_test: + if: "$Verbosity!='Terse'" + then: [t: "l'intervalle fermé"] + else: [t: "intervalle fermé"] + else_test: + if: "$Verbosity!='Terse'" + then: [t: "l'intervalle fermé ouvert"] # closed-open-interval + else: [t: "intervalle fermé ouvert"] + - t: "de" # phrase(the interval 'from' c to d) + - x: "*[1]" + - t: "à" # phrase(the interval from c 'to' d) + - x: "*[2]" - name: default-point tag: point diff --git a/tests/Languages/fr/SimpleSpeak/functions.rs b/tests/Languages/fr/SimpleSpeak/functions.rs index fb48592c8..cd7d6cbc8 100644 --- a/tests/Languages/fr/SimpleSpeak/functions.rs +++ b/tests/Languages/fr/SimpleSpeak/functions.rs @@ -312,7 +312,6 @@ fn no_times_sqrt() -> Result<()> { Ok(()) } - // Tests for the four types of intervals in SimpleSpeak // AI generated #[test] @@ -322,8 +321,9 @@ fn no_times_sqrt() -> Result<()> { (c,d) ) "; - test("fr", "SimpleSpeak", expr, "l'interval ouvert de c à d")?; - Ok(()) + test("fr", "SimpleSpeak",expr, "l'intervalle ouvert de c à d")?; + return Ok(()); + } // AI generated @@ -334,7 +334,7 @@ fn no_times_sqrt() -> Result<()> { [(]c,d) ) "; - test("fr", "SimpleSpeak", expr, "closed open interval de c comma, d")?; + test("fr", "SimpleSpeak", expr, "l'invervalle fermé ouvert fermé de c à d")?; Ok(()) } @@ -347,7 +347,7 @@ fn parens_interval_open_closed() -> Result<()> { (c,d] ] "; - test("fr", "SimpleSpeak", expr, "open closed interval de c comma, d")?; + test("fr", "SimpleSpeak", expr, "l'intervalle ouvert fermé de c à d")?; Ok(()) } @@ -360,7 +360,7 @@ fn parens_interval_closed_closed() -> Result<()> { [(]c,d] ] "; - test("fr", "SimpleSpeak", expr, "closed interval de c comma, d")?; + test("fr", "SimpleSpeak", expr, "l'intervalle fermé de c à d")?; Ok(()) } @@ -372,7 +372,7 @@ fn parens_interval_closed_closed() -> Result<()> { - ,d) ) "; - test("fr", "SimpleSpeak", expr, "open interval de négatif infini comma, d")?; + test("fr", "SimpleSpeak", expr, "l'intervalle ouvert de moins infini à d")?; Ok(()) } @@ -384,7 +384,7 @@ fn parens_interval_closed_closed() -> Result<()> { - ,d] ] "; - test("fr", "SimpleSpeak", expr, "open closed interval de négatif infini comma, d")?; + test("fr", "SimpleSpeak", expr, "l'intervalle ouvert fermé de moins infini à d")?; Ok(()) } From ba7088d1fb93649d192141c7965d31c447039ddc Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Wed, 13 May 2026 21:11:30 -0400 Subject: [PATCH 10/31] added SimpleSpeak/geometry.rs tests --- tests/Languages/fr.rs | 1 + tests/Languages/fr/SimpleSpeak/geometry.rs | 36 ++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 tests/Languages/fr/SimpleSpeak/geometry.rs diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index e63ef8f88..3c67646bb 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -2,6 +2,7 @@ mod SimpleSpeak { mod functions; + mod geometry; } mod shared; diff --git a/tests/Languages/fr/SimpleSpeak/geometry.rs b/tests/Languages/fr/SimpleSpeak/geometry.rs new file mode 100644 index 000000000..e841df9c9 --- /dev/null +++ b/tests/Languages/fr/SimpleSpeak/geometry.rs @@ -0,0 +1,36 @@ +/// Tests for geometry listed in intent +/// ABC as mtext and as separated letters +use crate::common::*; +use anyhow::Result; + +#[test] +fn arc() -> Result<()> { + let expr = " BC "; + test("fr", "SimpleSpeak", expr, "arc majuscule b majuscule c")?; + return Ok(()); + +} + +#[test] +fn ray() -> Result<()> { + let expr = " XY¯ "; + test("fr", "SimpleSpeak", expr, "segment majuscule x majuscule y")?; + return Ok(()); + +} + +#[test] +fn arc_mtext() -> Result<()> { + let expr = " BC "; + test("fr", "SimpleSpeak", expr, "arc majuscule b majuscule c")?; + return Ok(()); + +} + +#[test] +fn ray_mtext() -> Result<()> { + let expr = " XY "; + test("fr", "SimpleSpeak", expr, "demi-droite majuscule x majuscule y")?; + return Ok(()); + +} From af3ea0604c80995f7c735ad9c65610f25f5d685c Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Thu, 14 May 2026 18:02:45 -0400 Subject: [PATCH 11/31] completed changes and tests for large_ops --- Rules/Languages/fr/SharedRules/general.yaml | 21 +- Rules/Languages/fr/unicode-full.yaml | 32 +-- Rules/Languages/fr/unicode.yaml | 10 +- tests/Languages/fr.rs | 1 + tests/Languages/fr/SimpleSpeak/large_ops.rs | 235 ++++++++++++++++++++ 5 files changed, 275 insertions(+), 24 deletions(-) create mode 100644 tests/Languages/fr/SimpleSpeak/large_ops.rs diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml index d0170f7e4..7a249a35c 100644 --- a/Rules/Languages/fr/SharedRules/general.yaml +++ b/Rules/Languages/fr/SharedRules/general.yaml @@ -161,7 +161,12 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "la"] # phrase('the' square root of 25 equals 5) + then_test: + - if: "*[1][.='∏']" + then: [t: "le"] # phrase('the' product) - masculine starting with consonant + - else_if: "*[1][contains('⋂∩⋃∪∫∬∭∮∯∰∱∲∳', .)]" # phrase('the' union/intersection/integral) - starting with vowel + then: [t: "l'"] + - else: [t: "la"] # phrase('the' sum) - feminine starting with consonant - x: "*[1]" - t: "de" # phrase(subtracting 5 'from' 10 gives 5) - x: "*[2]" @@ -178,7 +183,12 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "la"] # phrase('the' square root of 25 equals 5) + then_test: + - if: "*[1][.='∏']" + then: [t: "le"] # phrase('the' product) - masculine starting with consonant + - else_if: "*[1][contains('⋂∩⋃∪∫∬∭∮∯∰∱∲∳', .)]" # phrase('the' union/intersection/integral) - starting with vowel + then: [t: "l'"] + - else: [t: "la"] # phrase('the' sum) - feminine starting with consonant - x: "*[1]" - t: "sur" # phrase(2 'over' 3 equals two thirds) - x: "*[2]" @@ -192,7 +202,12 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "la"] # phrase('the' square root of 25 equals 5) + then_test: + - if: "*[1][.='∏']" + then: [t: "le"] # phrase('the' product) - masculine starting with consonant + - else_if: "*[1][contains('⋂∩⋃∪∫∬∭∮∯∰∱∲∳', .)]" # phrase('the' union/intersection/integral) - starting with vowel + then: [t: "l'"] + - else: [t: "la"] # phrase('the' sum) - feminine starting with consonant - x: "*[1]" - t: "de" # phrase(the square root 'of' 25 equals 5) - x: "*[2]" diff --git a/Rules/Languages/fr/unicode-full.yaml b/Rules/Languages/fr/unicode-full.yaml index 569463afa..8eb936fbd 100644 --- a/Rules/Languages/fr/unicode-full.yaml +++ b/Rules/Languages/fr/unicode-full.yaml @@ -498,7 +498,7 @@ - "ℸ": [t: "dalèt"] # 0x2138 (en: 'fourth transfinite cardinal') - "ℼ": [t: "pi ajouré"] # 0x213c (en: 'double struck pi', DeepL: 'double pi frappé') - "ℽ": [t: "gamma ajouré"] # 0x213d (en: 'double struck gamma', DeepL: 'double gamma frappé') - - "⅀": [t: "sommation de la famille ajouré"] # 0x2140 (en: 'double struck n-ary summation', DeepL: 'somme n-aire doublement frappée') + - "⅀": [t: "sommation"] # 0x2140 (en: 'double struck n-ary summation', DeepL: 'somme n-aire doublement frappée') - "⅋": [t: "perluète culbutée"] # 0x214b (en: 'turned ampersand', DeepL: 'esperluette tournée') - "⅌": [t: "symbole per"] # 0x214c (en: 'per', DeepL: 'per') - "ⅎ": [t: "minuscule f culbuté"] # 0x214e (en: 'turned F', DeepL: 'tourné f') @@ -800,17 +800,17 @@ - "∤": [t: "n'est pas un diviseur de"] # 0x2224 (en: 'does not divide') - "∧": [t: "et logique"] # 0x2227 (en: 'and') - "∨": [t: "ou logique"] # 0x2228 (en: 'or') - - "∩": [t: "intersection"] # 0x2229 - - "∪": [t: "union"] # 0x222a - - "∫": [t: "intégrale"] # 0x222b (en: 'integral') - - "∬": [t: "intégrale double"] # 0x222c (en: 'double integral') - - "∭": [t: "intégrale triple"] # 0x222d (en: 'triple integral') - - "∮": [t: "intégrale de contour"] # 0x222e (en: 'contour integral') - - "∯": [t: "intégrale de surface"] # 0x222f (en: 'surface integral') - - "∰": [t: "intégrale de volume"] # 0x2230 (en: 'volume integral') - - "∱": [t: "intégrale en sens négatif"] # 0x2231 (en: 'clockwise integral') - - "∲": [t: "intégrale de contour en sens négatif"] # 0x2232 (en: 'clockwise contour integral') - - "∳": [t: "intégrale de contour en sens positif"] # 0x2233 (en: 'anticlockwise contour integral') + - "∩": [t: "\uF8FEintersection"] # 0x2229 + - "∪": [t: "\uF8FEunion"] # 0x222a + - "∫": [t: "\uF8FEintégrale"] # 0x222b (en: 'integral') + - "∬": [t: "\uF8FEintégrale double"] # 0x222c (en: 'double integral') + - "∭": [t: "\uF8FEintégrale triple"] # 0x222d (en: 'triple integral') + - "∮": [t: "\uF8FEintégrale de contour"] # 0x222e (en: 'contour integral') + - "∯": [t: "\uF8FEintégrale de surface"] # 0x222f (en: 'surface integral') + - "∰": [t: "\uF8FEintégrale de volume"] # 0x2230 (en: 'volume integral') + - "∱": [t: "\uF8FEintégrale en sens négatif"] # 0x2231 (en: 'clockwise integral') + - "∲": [t: "\uF8FEintégrale de contour en sens négatif"] # 0x2232 (en: 'clockwise contour integral') + - "∳": [t: "\uF8FEintégrale de contour en sens positif"] # 0x2233 (en: 'anticlockwise contour integral') - "∴": [t: "par conséquent"] # 0x2234 (en: 'therefore') - "∵": [t: "parce que"] # 0x2235 (en: 'because') - "∶": # 0x2236 @@ -1181,10 +1181,10 @@ - "⊽": [t: "non ou"] # 0x22bd (en: 'nor') - "⊾": [t: "angle droit avec arc"] # 0x22be (en: 'right angle with arc') - "⊿": [t: "triangle rectangle"] # 0x22bf (en: 'right triangle') - - "⋀": [t: "et logique de la famille"] # 0x22c0 (en: 'logical and') - - "⋁": [t: "ou logique de la famille"] # 0x22c1 (en: 'logical or') - - "⋂": [t: "intersection de la famille"] # 0x22c2 (en: 'intersection') - - "⋃": [t: "réunion de la famille"] # 0x22c3 (en: 'union') + - "⋀": [t: "et logique"] # 0x22c0 (en: 'logical and') + - "⋁": [t: "ou logique"] # 0x22c1 (en: 'logical or') + - "⋂": [t: "\uF8FEintersection"] # 0x22c2 (en: 'intersection') + - "⋃": [t: "\uF8FEunion"] # 0x22c3 (en: 'union') - "⋄": [t: "opérateur losange"] # 0x22c4 (en: 'diamond operator') - "⋅": # 0x22c5 - test: diff --git a/Rules/Languages/fr/unicode.yaml b/Rules/Languages/fr/unicode.yaml index c940095bc..1d1120670 100644 --- a/Rules/Languages/fr/unicode.yaml +++ b/Rules/Languages/fr/unicode.yaml @@ -473,11 +473,11 @@ - "∧": [t: "et logique"] # 0x2227 (en: 'and') - "∨": [t: "ou logique"] # 0x2228 (en: 'or') - "∩": [t: "intersection"] # 0x2229 - - "∪": [t: "union"] # 0x222a - - "∫": [t: "intégrale"] # 0x222b (en: 'integral') - - "∬": [t: "intégrale double"] # 0x222c (en: 'double integral') - - "∭": [t: "intégrale triple"] # 0x222d (en: 'triple integral') - - "∮": [t: "intégrale de contour"] # 0x222e (en: 'contour integral') + - "∪": [t: "\uF8FEunion"] # 0x222a + - "∫": [t: "\uF8FEintégrale"] # 0x222b (en: 'integral') + - "∬": [t: "\uF8FEintégrale double"] # 0x222c (en: 'double integral') + - "∭": [t: "\uF8FEintégrale triple"] # 0x222d (en: 'triple integral') + - "∮": [t: "\uF8FEintégrale de contour"] # 0x222e (en: 'contour integral') - "∶": # 0x2236 - test: if: "$Verbosity!='Terse'" diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 3c67646bb..36c17d88c 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -3,6 +3,7 @@ mod SimpleSpeak { mod functions; mod geometry; + mod large_ops; } mod shared; diff --git a/tests/Languages/fr/SimpleSpeak/large_ops.rs b/tests/Languages/fr/SimpleSpeak/large_ops.rs new file mode 100644 index 000000000..948c8c49f --- /dev/null +++ b/tests/Languages/fr/SimpleSpeak/large_ops.rs @@ -0,0 +1,235 @@ +use crate::common::*; +use anyhow::Result; + +#[test] +fn sum_both() -> Result<()> { + let expr = " + + + n=1 + 10 + + n + "; + test("fr", "SimpleSpeak", expr, "la sommation de n est égal à 1, à 10 de n")?; + return Ok(()); + +} + +#[test] +fn sum_under() -> Result<()> { + let expr = " + + + S + + i + "; + test("fr", "SimpleSpeak", expr, "la sommation sur majuscule s de i")?; + return Ok(()); + +} +#[test] +fn sum_both_msubsup() -> Result<()> { + let expr = " + + + n=1 + 10 + + n + "; + test("fr", "SimpleSpeak", expr, "la sommation de n est égal à 1, à 10 de n")?; + return Ok(()); + +} + +#[test] +fn sum_sub() -> Result<()> { + let expr = " + + + S + + i + "; + test("fr", "SimpleSpeak", expr, "la sommation sur majuscule s de i")?; + return Ok(()); + +} + +#[test] +fn sum() -> Result<()> { + let expr = " + + ai + "; + test("fr", "SimpleSpeak", expr, "la sommation de a indice i")?; + return Ok(()); + +} + +#[test] +fn product_both() -> Result<()> { + let expr = " + + + n=1 + 10 + + n + "; + test("fr", "SimpleSpeak", expr, "le produit de n est égal à 1, à 10 de n")?; + return Ok(()); + +} + +#[test] +fn product_under() -> Result<()> { + let expr = " + + + S + + i + "; + test("fr", "SimpleSpeak", expr, "le produit sur majuscule s de i")?; + return Ok(()); + +} + +#[test] +fn product() -> Result<()> { + let expr = " + + ai + "; + test("fr", "SimpleSpeak", expr, "le produit de a indice i")?; + return Ok(()); + +} + +#[test] +fn intersection_both() -> Result<()> { + let expr = " + + + i=1 + 10 + + Si + "; + test("fr", "SimpleSpeak", expr, "l'intersection de i est égal à 1, à 10 de; majuscule s indice i")?; + return Ok(()); + +} + +#[test] +fn intersection_under() -> Result<()> { + let expr = " + + + C + + Si + "; + test("fr", "SimpleSpeak", expr, "l'intersection sur majuscule c de; majuscule s indice i")?; + return Ok(()); + +} + +#[test] +fn intersection() -> Result<()> { + let expr = " + + Si + "; + test("fr", "SimpleSpeak", expr, "l'intersection de majuscule s indice i")?; + return Ok(()); + +} + +#[test] +fn union_both() -> Result<()> { + let expr = " + + + i=1 + 10 + + Si + "; + test("fr", "SimpleSpeak", expr, "l'union de i est égal à 1, à 10 de; majuscule s indice i")?; + return Ok(()); + +} + +#[test] +fn union_under() -> Result<()> { + let expr = " + + + C + + Si + "; + test("fr", "SimpleSpeak", expr, "l'union sur majuscule c de, majuscule s indice i")?; + return Ok(()); + +} + +#[test] +fn union() -> Result<()> { + let expr = " + + Si + "; + test("fr", "SimpleSpeak", expr, "l'union de majuscule s indice i")?; + return Ok(()); + +} + +#[test] +fn integral_both() -> Result<()> { + let expr = " + + + + 0 + 1 + + f(x ) + + dx + "; + test("fr", "SimpleSpeak", expr, "l'intégrale de 0, à 1 de, f de x; d x")?; + return Ok(()); + +} + +#[test] +fn integral_under() -> Result<()> { + let expr = " + + + + + f(x ) + dx + "; + test("fr", "SimpleSpeak", expr, "l'intégrale sur les nombres réels de; f de x d x")?; + return Ok(()); + +} + +#[test] +fn integral() -> Result<()> { + let expr = " + + f(x ) + dx + "; + test("fr", "SimpleSpeak", expr, "l'intégrale de f de x d x")?; + return Ok(()); + +} \ No newline at end of file From d00ec64cc4a612640b760aa7efd188a175fac82e Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Thu, 14 May 2026 18:26:07 -0400 Subject: [PATCH 12/31] fixed grammar rule, majuscule a -> a majuscule --- Rules/Languages/fr/unicode-full.yaml | 42 +++---- Rules/Languages/fr/unicode.yaml | 20 ++-- tests/Languages/fr.rs | 1 + tests/Languages/fr/SimpleSpeak/geometry.rs | 8 +- tests/Languages/fr/SimpleSpeak/large_ops.rs | 18 +-- .../fr/SimpleSpeak/linear_algebra.rs | 111 ++++++++++++++++++ 6 files changed, 156 insertions(+), 44 deletions(-) create mode 100644 tests/Languages/fr/SimpleSpeak/linear_algebra.rs diff --git a/Rules/Languages/fr/unicode-full.yaml b/Rules/Languages/fr/unicode-full.yaml index 8eb936fbd..264e56aef 100644 --- a/Rules/Languages/fr/unicode-full.yaml +++ b/Rules/Languages/fr/unicode-full.yaml @@ -199,6 +199,10 @@ - audio: value: "beep.mp4" replace: [] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] + - t: "avec dialytika" # (en: 'with dialytika', DeepL translation) - test: if: "$CapitalLetters_UseWord" then_test: @@ -206,11 +210,7 @@ then_test: if: "$Impairment = 'Blindness'" then: [t: "majuscule"] # (en: 'cap', DeepL translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] - - t: "avec dialytika" # (en: 'with dialytika', DeepL translation) + else: [x: "$SpeechOverrides_CapitalLetters"] - "ϊ": [t: "iota tréma"] # 0x3ca (en: 'iota with dialytika') - "ϋ": [t: "upsilon tréma"] # 0x3cb (en: 'upsilon with dialytika') - "ό": [t: "omicron accent"] # 0x3cc (en: 'omicron with tonos') @@ -235,6 +235,9 @@ - audio: value: "beep.mp4" replace: [] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] - test: if: "$CapitalLetters_UseWord" then_test: @@ -242,10 +245,7 @@ then_test: if: "$Impairment = 'Blindness'" then: [t: "majuscule"] # (en: 'cap', DeepL translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] + else: [x: "$SpeechOverrides_CapitalLetters"] - "а": [t: "a"] # 0x430 (DeepL: 'а') - "б": [t: "bé"] # 0x431 (en: 'be', DeepL: 'être') - "в": [t: "vé"] # 0x432 (en: 've', DeepL: 've') @@ -3246,6 +3246,9 @@ - audio: value: "beep.mp4" replace: [] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [t: "ligature ae"] # (DeepL translation) - test: if: "$CapitalLetters_UseWord" then_test: @@ -3253,10 +3256,7 @@ then_test: if: "$Impairment = 'Blindness'" then: [t: "majuscule"] # (en: 'cap', DeepL translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [t: "ligature ae"] # (DeepL translation) + else: [x: "$SpeechOverrides_CapitalLetters"] - "": # 0xf19b - test: if: "$CapitalLetters_Beep" @@ -3264,6 +3264,9 @@ - audio: value: "beep.mp4" replace: [] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [t: "s pointu"] # (en: 'sharp s', DeepL translation) - test: if: "$CapitalLetters_UseWord" then_test: @@ -3271,10 +3274,7 @@ then_test: if: "$Impairment = 'Blindness'" then: [t: "majuscule"] # (en: 'cap', DeepL translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [t: "s pointu"] # (en: 'sharp s', DeepL translation) + else: [x: "$SpeechOverrides_CapitalLetters"] - "": # 0xf19c - test: if: "$CapitalLetters_Beep" @@ -3282,6 +3282,9 @@ - audio: value: "beep.mp4" replace: [] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [t: "o avec trait"] # (en: 'o with stroke', DeepL translation) - test: if: "$CapitalLetters_UseWord" then_test: @@ -3289,10 +3292,7 @@ then_test: if: "$Impairment = 'Blindness'" then: [t: "majuscule"] # (en: 'cap', DeepL translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - replace: [t: "o avec trait"] # (en: 'o with stroke', DeepL translation) + else: [x: "$SpeechOverrides_CapitalLetters"] # MathType only has a few of the cap Greek letters in PUA - "": # 0xf201 - 0xf209 diff --git a/Rules/Languages/fr/unicode.yaml b/Rules/Languages/fr/unicode.yaml index 1d1120670..4bd31653b 100644 --- a/Rules/Languages/fr/unicode.yaml +++ b/Rules/Languages/fr/unicode.yaml @@ -19,6 +19,10 @@ - audio: value: "beep.mp4" replace: [] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] - test: if: "$CapitalLetters_UseWord" then_test: @@ -26,11 +30,7 @@ then_test: if: "$Impairment = 'Blindness'" then: [t: "majuscule"] # (en: 'cap', DeepL translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + else: [x: "$SpeechOverrides_CapitalLetters"] - "0-9": [t: "."] # (en: '.', DeepL: 'A') @@ -226,6 +226,10 @@ - audio: value: "beep.mp4" replace: [] + - pitch: + value: "$CapitalLetters_Pitch" + # note: processing of ranges converts '.' into the character, so it needs to be in quotes below + replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - test: if: "$CapitalLetters_UseWord" then_test: @@ -233,11 +237,7 @@ then_test: if: "$Impairment = 'Blindness'" then: [t: "majuscule"] # (en: 'cap', DeepL translation) - else: [x: "$SpeechOverrides_CapitalLetters"] - - pitch: - value: "$CapitalLetters_Pitch" - # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + else: [x: "$SpeechOverrides_CapitalLetters"] - "α": [t: "alpha"] # 0x3b1 - "β": [t: "bêta"] # 0x3b2 (en: 'beta') diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 36c17d88c..d5398a4cb 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -4,6 +4,7 @@ mod SimpleSpeak { mod functions; mod geometry; mod large_ops; + mod linear_algebra; } mod shared; diff --git a/tests/Languages/fr/SimpleSpeak/geometry.rs b/tests/Languages/fr/SimpleSpeak/geometry.rs index e841df9c9..911a70c35 100644 --- a/tests/Languages/fr/SimpleSpeak/geometry.rs +++ b/tests/Languages/fr/SimpleSpeak/geometry.rs @@ -6,7 +6,7 @@ use anyhow::Result; #[test] fn arc() -> Result<()> { let expr = " BC "; - test("fr", "SimpleSpeak", expr, "arc majuscule b majuscule c")?; + test("fr", "SimpleSpeak", expr, "arc b majuscule c majuscule")?; return Ok(()); } @@ -14,7 +14,7 @@ fn arc() -> Result<()> { #[test] fn ray() -> Result<()> { let expr = " XY¯ "; - test("fr", "SimpleSpeak", expr, "segment majuscule x majuscule y")?; + test("fr", "SimpleSpeak", expr, "segment x majuscule y majuscule")?; return Ok(()); } @@ -22,7 +22,7 @@ fn ray() -> Result<()> { #[test] fn arc_mtext() -> Result<()> { let expr = " BC "; - test("fr", "SimpleSpeak", expr, "arc majuscule b majuscule c")?; + test("fr", "SimpleSpeak", expr, "arc b majuscule c majuscule")?; return Ok(()); } @@ -30,7 +30,7 @@ fn arc_mtext() -> Result<()> { #[test] fn ray_mtext() -> Result<()> { let expr = " XY "; - test("fr", "SimpleSpeak", expr, "demi-droite majuscule x majuscule y")?; + test("fr", "SimpleSpeak", expr, "demi-droite x majuscule y majuscule")?; return Ok(()); } diff --git a/tests/Languages/fr/SimpleSpeak/large_ops.rs b/tests/Languages/fr/SimpleSpeak/large_ops.rs index 948c8c49f..ff978a8ae 100644 --- a/tests/Languages/fr/SimpleSpeak/large_ops.rs +++ b/tests/Languages/fr/SimpleSpeak/large_ops.rs @@ -25,7 +25,7 @@ fn sum_under() -> Result<()> { i "; - test("fr", "SimpleSpeak", expr, "la sommation sur majuscule s de i")?; + test("fr", "SimpleSpeak", expr, "la sommation sur s majuscule de i")?; return Ok(()); } @@ -53,7 +53,7 @@ fn sum_sub() -> Result<()> { i "; - test("fr", "SimpleSpeak", expr, "la sommation sur majuscule s de i")?; + test("fr", "SimpleSpeak", expr, "la sommation sur s majuscule de i")?; return Ok(()); } @@ -93,7 +93,7 @@ fn product_under() -> Result<()> { i "; - test("fr", "SimpleSpeak", expr, "le produit sur majuscule s de i")?; + test("fr", "SimpleSpeak", expr, "le produit sur s majuscule de i")?; return Ok(()); } @@ -119,7 +119,7 @@ fn intersection_both() -> Result<()> { Si "; - test("fr", "SimpleSpeak", expr, "l'intersection de i est égal à 1, à 10 de; majuscule s indice i")?; + test("fr", "SimpleSpeak", expr, "l'intersection de i est égal à 1, à 10 de; s majuscule indice i")?; return Ok(()); } @@ -133,7 +133,7 @@ fn intersection_under() -> Result<()> { Si "; - test("fr", "SimpleSpeak", expr, "l'intersection sur majuscule c de; majuscule s indice i")?; + test("fr", "SimpleSpeak", expr, "l'intersection sur c majuscule de; s majuscule indice i")?; return Ok(()); } @@ -144,7 +144,7 @@ fn intersection() -> Result<()> { Si "; - test("fr", "SimpleSpeak", expr, "l'intersection de majuscule s indice i")?; + test("fr", "SimpleSpeak", expr, "l'intersection de s majuscule indice i")?; return Ok(()); } @@ -159,7 +159,7 @@ fn union_both() -> Result<()> { Si "; - test("fr", "SimpleSpeak", expr, "l'union de i est égal à 1, à 10 de; majuscule s indice i")?; + test("fr", "SimpleSpeak", expr, "l'union de i est égal à 1, à 10 de; s majuscule indice i")?; return Ok(()); } @@ -173,7 +173,7 @@ fn union_under() -> Result<()> { Si "; - test("fr", "SimpleSpeak", expr, "l'union sur majuscule c de, majuscule s indice i")?; + test("fr", "SimpleSpeak", expr, "l'union sur c majuscule de, s majuscule indice i")?; return Ok(()); } @@ -184,7 +184,7 @@ fn union() -> Result<()> { Si "; - test("fr", "SimpleSpeak", expr, "l'union de majuscule s indice i")?; + test("fr", "SimpleSpeak", expr, "l'union de s majuscule indice i")?; return Ok(()); } diff --git a/tests/Languages/fr/SimpleSpeak/linear_algebra.rs b/tests/Languages/fr/SimpleSpeak/linear_algebra.rs new file mode 100644 index 000000000..026564c7b --- /dev/null +++ b/tests/Languages/fr/SimpleSpeak/linear_algebra.rs @@ -0,0 +1,111 @@ +use crate::common::*; +use anyhow::Result; + +#[test] +fn transpose() -> Result<()> { + let expr = " MT "; + test("fr", "SimpleSpeak", expr, "m majuscule transposée")?; + return Ok(()); + +} + +#[test] +fn trace() -> Result<()> { + let expr = " TrM "; + test("fr", "SimpleSpeak", expr, "trace of cap m")?; + return Ok(()); + +} + +#[test] +fn dimension() -> Result<()> { + let expr = " DimM "; + test("fr", "SimpleSpeak", expr, "dimension of cap m")?; + return Ok(()); + +} + +#[test] +fn homomorphism() -> Result<()> { + let expr = " Hom(M) "; + test("fr", "SimpleSpeak", expr, "homomorphism of cap m")?; + return Ok(()); + +} + +#[test] +fn kernel() -> Result<()> { + let expr = " ker(L) "; + test("fr", "SimpleSpeak", expr, "kernel of cap l")?; + return Ok(()); + +} + +#[test] +fn norm() -> Result<()> { + let expr = " + + + f + + + +"; + test("fr", "SimpleSpeak", expr, "norm of f")?; + return Ok(()); + +} + +#[test] +fn norm_non_simple() -> Result<()> { + let expr = " + + + x + + + y + + + +"; + test("fr", "SimpleSpeak", expr, "norm of x plus y end norm")?; + return Ok(()); + +} + +#[test] +fn norm_subscripted() -> Result<()> { + let expr = " + + + + f + + + p + + +"; + test("fr", "SimpleSpeak", expr, "p norm of f")?; + return Ok(()); + +} + +#[test] +fn not_gradient() -> Result<()> { + // the nabla is at the end, so it can't be gradient because it doesn't operate on anything + let expr = r#" + ( + b + + + + + ) + a + +"#; + test("fr", "SimpleSpeak", expr, "open paren, b times nahblah, close paren; times eigh")?; + return Ok(()); + +} \ No newline at end of file From 5663cd61d5c105653b4f737044ab0a02399f33ab Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Thu, 14 May 2026 18:42:30 -0400 Subject: [PATCH 13/31] completed changes and tests for linear_algebra --- Rules/Languages/fr/definitions.yaml | 10 +++++----- Rules/Languages/fr/unicode-full.yaml | 2 +- tests/Languages/fr/SimpleSpeak/linear_algebra.rs | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Rules/Languages/fr/definitions.yaml b/Rules/Languages/fr/definitions.yaml index 2f0584875..6859b7ca6 100644 --- a/Rules/Languages/fr/definitions.yaml +++ b/Rules/Languages/fr/definitions.yaml @@ -35,11 +35,11 @@ "real-part": "function=la partie réelle", "transpose": "postfix=transposée || function=transposée", - "norm": "function= ; norme: norme de: la norme de; fin de norme", - "trace": "function= ; trace : trace de: la trace de; fin de trace", - "dimension": "function= ; dimension : dimension de: la dimension de; fin de dimension", - "homomorphism": "function= ; homomorphisme : homomorphisme de: l'homomorphisme de; fin de l'homomorphisme", - "kernel": "function= ; noyau : noyau de: le noyau de; fin du noyau", + "norm": "function= ; norme: norme: la norme de; fin de norme", + "trace": "function= ; trace : trace: la trace de; fin de trace", + "dimension": "function= ; dimension : dimension: la dimension de; fin de dimension", + "homomorphism": "function= ; homomorphisme : homomorphisme: l'homomorphisme de; fin de l'homomorphisme", + "kernel": "function= ; noyau : noyau: le noyau de; fin du noyau", "vector": "function= ; vecteur || prefix=vecteur", "cross-product": "infix=croix: produit vectoriel: produit vectoriel", "dot-product": "infix=point: produit scalaire: point: produit scalaire", diff --git a/Rules/Languages/fr/unicode-full.yaml b/Rules/Languages/fr/unicode-full.yaml index 264e56aef..19499693d 100644 --- a/Rules/Languages/fr/unicode-full.yaml +++ b/Rules/Languages/fr/unicode-full.yaml @@ -1190,7 +1190,7 @@ - test: if: "@data-chem-formula-op" then: [t: "point"] # (en: 'dot', DeepL translation) - else: [t: "opérateur point"] # (en: 'times') + else: [t: "fois"] # (en: 'times') - "⋆": [t: "opérateur étoile"] # 0x22c6 (en: 'times') - "⋇": [t: "divisé multiplié"] # 0x22c7 (en: 'division times') diff --git a/tests/Languages/fr/SimpleSpeak/linear_algebra.rs b/tests/Languages/fr/SimpleSpeak/linear_algebra.rs index 026564c7b..36260ccfc 100644 --- a/tests/Languages/fr/SimpleSpeak/linear_algebra.rs +++ b/tests/Languages/fr/SimpleSpeak/linear_algebra.rs @@ -12,7 +12,7 @@ fn transpose() -> Result<()> { #[test] fn trace() -> Result<()> { let expr = " TrM "; - test("fr", "SimpleSpeak", expr, "trace of cap m")?; + test("fr", "SimpleSpeak", expr, "trace de m majuscule")?; return Ok(()); } @@ -20,7 +20,7 @@ fn trace() -> Result<()> { #[test] fn dimension() -> Result<()> { let expr = " DimM "; - test("fr", "SimpleSpeak", expr, "dimension of cap m")?; + test("fr", "SimpleSpeak", expr, "dimension de m majuscule")?; return Ok(()); } @@ -28,7 +28,7 @@ fn dimension() -> Result<()> { #[test] fn homomorphism() -> Result<()> { let expr = " Hom(M) "; - test("fr", "SimpleSpeak", expr, "homomorphism of cap m")?; + test("fr", "SimpleSpeak", expr, "homomorphisme de m majuscule")?; return Ok(()); } @@ -36,7 +36,7 @@ fn homomorphism() -> Result<()> { #[test] fn kernel() -> Result<()> { let expr = " ker(L) "; - test("fr", "SimpleSpeak", expr, "kernel of cap l")?; + test("fr", "SimpleSpeak", expr, "noyau de l majuscule")?; return Ok(()); } @@ -51,7 +51,7 @@ fn norm() -> Result<()> { "; - test("fr", "SimpleSpeak", expr, "norm of f")?; + test("fr", "SimpleSpeak", expr, "norme de f")?; return Ok(()); } @@ -68,7 +68,7 @@ fn norm_non_simple() -> Result<()> { "; - test("fr", "SimpleSpeak", expr, "norm of x plus y end norm")?; + test("fr", "SimpleSpeak", expr, "norme de x plus y fin de norme")?; return Ok(()); } @@ -86,7 +86,7 @@ fn norm_subscripted() -> Result<()> { "; - test("fr", "SimpleSpeak", expr, "p norm of f")?; + test("fr", "SimpleSpeak", expr, "p norme de f")?; return Ok(()); } @@ -105,7 +105,7 @@ fn not_gradient() -> Result<()> { a "#; - test("fr", "SimpleSpeak", expr, "open paren, b times nahblah, close paren; times eigh")?; + test("fr", "SimpleSpeak", expr, "parenthèse gauche, b fois nabla, parenthèse droite; fois a")?; return Ok(()); } \ No newline at end of file From 15ec99768afb9e6abe2a7f55281d6bbdacfcf69d Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Fri, 15 May 2026 14:49:01 -0400 Subject: [PATCH 14/31] added tests mfrac.rs --- tests/Languages/fr.rs | 1 + tests/Languages/fr/SimpleSpeak/mfrac.rs | 356 ++++++++++++++++++++++++ 2 files changed, 357 insertions(+) create mode 100644 tests/Languages/fr/SimpleSpeak/mfrac.rs diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index d5398a4cb..29d1a4e27 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -5,6 +5,7 @@ mod SimpleSpeak { mod geometry; mod large_ops; mod linear_algebra; + mod mfrac; } mod shared; diff --git a/tests/Languages/fr/SimpleSpeak/mfrac.rs b/tests/Languages/fr/SimpleSpeak/mfrac.rs new file mode 100644 index 000000000..a2856f338 --- /dev/null +++ b/tests/Languages/fr/SimpleSpeak/mfrac.rs @@ -0,0 +1,356 @@ +/// Tests for fractions +/// includes simple fractions and more complex fractions +/// also tests mixed fractions (implicit and explicit) +use crate::common::*; +use anyhow::Result; + +#[test] +fn common_fraction_half() -> Result<()> { + let expr = " + 1 2 + "; + test("fr", "SimpleSpeak", expr, "1 demi")?; + return Ok(()); + +} + +#[test] +fn common_fraction_thirds() -> Result<()> { + let expr = " + 2 3 + "; + test("fr", "SimpleSpeak", expr, "2 tiers")?; + return Ok(()); + +} + +#[test] +fn common_fraction_tenths() -> Result<()> { + let expr = " + 17 10 + "; + test("fr", "SimpleSpeak", expr, "17 dixièmes")?; + return Ok(()); + +} + +#[test] +#[allow(non_snake_case)] +fn not_SimpleSpeak_common_fraction_tenths() -> Result<()> { + let expr = " + 89 10 + "; + test("fr", "SimpleSpeak", expr, "89 sur 10")?; + return Ok(()); + +} + +#[test] +fn non_simple_fraction() -> Result<()> { + let expr = " + + + + x+y + + x-y + + + + "; + test("fr", "SimpleSpeak", expr, "fraction, x plus y, sur, x moins y, fin de fraction")?; + return Ok(()); + +} + +#[test] +fn nested_fraction() -> Result<()> { + let expr = " + + + + x+ 1y + + x-y + + + + "; + test("fr", "SimpleSpeak", expr, "fraction, x plus, fraction, 1 sur y, fin de fraction; sur, x moins y, fin de fraction")?; + return Ok(()); + +} + + +#[test] +fn deeply_nested_fraction_msqrt() -> Result<()> { + let expr = " + + + + x+ 1y + + x-y + + + + "; + test("fr", "SimpleSpeak", expr, "fraction, x plus, la racine carrée de 1 sur y; fin de racine; sur, x moins y, fin de fraction")?; + return Ok(()); + +} + +#[test] +fn deeply_nested_fraction_mrow_msqrt() -> Result<()> { + let expr = " + + + + x+ 2+1y + + x-y + + + + "; + test("fr", "SimpleSpeak", expr, "fraction, x plus, la racine carrée de 2 plus 1 sur y; fin de racine; sur, x moins y, fin de fraction")?; + return Ok(()); + +} + +#[test] +fn numerator_simple_fraction() -> Result<()> { + let expr = " + + + + x + + x-y + + + + "; + test("fr", "SimpleSpeak", expr, "fraction, x sur, x moins y, fin de fraction")?; + return Ok(()); + +} + +#[test] +fn denominator_simple_fraction() -> Result<()> { + let expr = " + + + x-y + x + + + "; + test("fr", "SimpleSpeak", expr, "fraction, x moins y, sur x, fin de fraction")?; + return Ok(()); + +} + + +#[test] +fn frac_with_units() -> Result<()> { + let expr = " + + + 62 + + mi + hr + + + "; + test("fr", "SimpleSpeak", expr, "62 milles par heure")?; + return Ok(()); + +} + +#[test] +fn singular_frac_with_units() -> Result<()> { + let expr = " + + + 1 + + gal + mi + + + "; + test("fr", "SimpleSpeak", expr, "1 gallon par mille")?; + return Ok(()); + +} + +#[test] +fn number_in_numerator_with_units() -> Result<()> { + let expr = " + + + + 3 + gal + + mi + + "; + test("fr", "SimpleSpeak", expr, "3 gallons par mille")?; + return Ok(()); + +} + +#[test] +fn units_with_powers() -> Result<()> { + let expr = " + + + 3 m + s2 + + "; + test("fr", "SimpleSpeak", expr, "3 mètres par seconde au carré")?; + return Ok(()); + +} + + +#[test] +fn mixed_number() -> Result<()> { + let expr = " + 3 + 1 2 + "; + test("fr", "SimpleSpeak", expr, "3 et 1 demi")?; + return Ok(()); + +} + +#[test] +fn explicit_mixed_number() -> Result<()> { + let expr = " + 3 + + 1 8 + "; + test("fr", "SimpleSpeak", expr, "3 et 1 huitième")?; + return Ok(()); + +} + +#[test] +fn mixed_number_big() -> Result<()> { + let expr = " + 3 + 7 83 + "; + test("fr", "SimpleSpeak", expr, "3 et 7 quatre-vingt troisièmes")?; + return Ok(()); + +} + +#[test] +fn simple_text() -> Result<()> { + let expr = " + rise run + "; + test("fr", "SimpleSpeak", expr, "rise sur run")?; + return Ok(()); + +} + +#[test] +fn number_and_text() -> Result<()> { + let expr = " + + + 2milles + + 3gallons + + "; + test("fr", "SimpleSpeak", expr, "fraction, 2 milles, sur, 3 gallons, fin de fraction")?; + return Ok(()); + +} + + +#[test] +fn nested_simple_fractions() -> Result<()> { + let expr = " + + + + + 1 + 2 + + + + + 2 + 3 + + + + + "; + test("fr", "SimpleSpeak", expr, "fraction, 1 demi, sur, 2 tiers, fin de fraction")?; + return Ok(()); + +} + +#[test] +fn binomial() -> Result<()> { + let expr = " + 2 + ( + 7 3 + ) + "; + test("fr", "SimpleSpeak", expr, "2 fois 7 parmi 3")?; + return Ok(()); + +} + +#[test] +fn binomial_non_simple_top() -> Result<()> { + let expr = " + 2 + ( + n+7 3 + ) + "; + test("fr", "SimpleSpeak", expr, "2 fois, binôme n plus 7 parmi 3")?; + return Ok(()); + +} + +#[test] +fn binomial_non_simple_bottom() -> Result<()> { + let expr = " + 2 + ( + 7 k+3 + ) + "; + test("fr", "SimpleSpeak", expr, "2 fois, 7 parmi k plus 3 fin du binôme")?; + return Ok(()); + +} + +#[test] +fn binomial_non_simple_top_and_bottom() -> Result<()> { + let expr = " + 2 + ( + n+7 k+3 + ) + "; + test("fr", "SimpleSpeak", expr, "2 fois, binôme n plus 7 parmi k plus 3 fin du binôme")?; + return Ok(()); + +} From 7fea11a60c33bf5e54400ce10304f23362522b85 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Fri, 15 May 2026 15:28:36 -0400 Subject: [PATCH 15/31] added tests and corrections for msup.rs --- Rules/Languages/fr/SimpleSpeak_Rules.yaml | 4 +- tests/Languages/fr.rs | 1 + tests/Languages/fr/SimpleSpeak/msup.rs | 379 ++++++++++++++++++++++ 3 files changed, 381 insertions(+), 3 deletions(-) create mode 100644 tests/Languages/fr/SimpleSpeak/msup.rs diff --git a/Rules/Languages/fr/SimpleSpeak_Rules.yaml b/Rules/Languages/fr/SimpleSpeak_Rules.yaml index 59a8ec542..0bc84e0c9 100644 --- a/Rules/Languages/fr/SimpleSpeak_Rules.yaml +++ b/Rules/Languages/fr/SimpleSpeak_Rules.yaml @@ -242,10 +242,8 @@ match: "." replace: - x: "*[1]" - - t: "élevé à la" + - t: "élevé à la puissance" - x: "*[2]" - - t: "puissance" - - pause: short - name: set tag: set diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 29d1a4e27..958651cf5 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -6,6 +6,7 @@ mod SimpleSpeak { mod large_ops; mod linear_algebra; mod mfrac; + mod msup; } mod shared; diff --git a/tests/Languages/fr/SimpleSpeak/msup.rs b/tests/Languages/fr/SimpleSpeak/msup.rs new file mode 100644 index 000000000..41d35c314 --- /dev/null +++ b/tests/Languages/fr/SimpleSpeak/msup.rs @@ -0,0 +1,379 @@ +/// Tests for superscripts +/// simple superscripts +/// complex/nested superscripts +use crate::common::*; +use anyhow::Result; + +#[test] +fn squared() -> Result<()> { + let expr = " + x 2 + "; + test("fr", "SimpleSpeak", expr, "x au carré")?; + return Ok(()); + +} + +#[test] +fn cubed() -> Result<()> { + let expr = " + x 3 + "; + test("fr", "SimpleSpeak", expr, "x au cube")?; + return Ok(()); + +} + +#[test] + fn ordinal_power() -> Result<()> { + let expr = " + x 4 + "; + test("fr", "SimpleSpeak", expr, "x à la 4")?; + return Ok(()); + + } + +#[test] +fn simple_mi_power() -> Result<()> { + let expr = " + x n + "; + test("fr", "SimpleSpeak", expr, "x à la n-ième")?; + return Ok(()); + +} + +#[test] +fn zero_power() -> Result<()> { + let expr = " + x 0 + "; + test("fr", "SimpleSpeak", expr, "x à la 0")?; + return Ok(()); + +} + + +#[test] +fn decimal_power() -> Result<()> { + let expr = " + x 2,0 + "; + test("fr", "SimpleSpeak", expr, "x à la 2,0")?; + return Ok(()); + +} + +#[test] +fn non_simple_power() -> Result<()> { + let expr = " + + + 3 + + y+2 + + + "; + test("fr", "SimpleSpeak", expr, "3 élevé à la puissance y plus 2")?; + return Ok(()); + +} + +#[test] +fn negative_power() -> Result<()> { + let expr = " + + x + - 2 + + "; + test("fr", "SimpleSpeak", expr, "x à la moins 2")?; + return Ok(()); + +} + +#[test] +fn simple_fraction_power() -> Result<()> { + let expr = " + + x + 13 + + "; + test("fr", "SimpleSpeak", expr, "x élevé à la puissance 1 tiers")?; + return Ok(()); + +} + +#[test] +fn nested_squared_power_with_coef() -> Result<()> { + let expr = " + + + 3 + + 2 + + x + 2 + + + + + "; + test("fr", "SimpleSpeak", expr, "3 élevé à la puissance 2 x au carré")?; + return Ok(()); + +} + +#[test] +fn nested_squared_power_with_neg_coef() -> Result<()> { + let expr = " + + + 3 + + - + 2 + + x + 2 + + + + + "; + test("fr", "SimpleSpeak", expr, "3 élevé à la puissance moins 2 x au carré")?; + return Ok(()); + +} + + +#[test] +fn nested_cubed_power() -> Result<()> { + let expr = " + + y + + 45 + 3 + + + "; + test("fr", "SimpleSpeak", expr, "y élevé à la puissance 4 cinquièmes au cube")?; + return Ok(()); + +} + +#[test] +fn nested_cubed_power_with_neg_base() -> Result<()> { + let expr = " + + y + + - + + 45 + 3 + + + + "; + test("fr", "SimpleSpeak", expr, "y élevé à la puissance moins 4 cinquièmes au cube")?; + return Ok(()); + +} + +#[test] +fn nested_number_times_squared() -> Result<()> { + let expr = " + + + e + + + 1 + 2 + + + x + 2 + + + + + "; + test("fr", "SimpleSpeak", expr, "e élevé à la puissance 1 demi x au carré")?; + return Ok(()); + +} + +#[test] +fn nested_negative_number_times_squared() -> Result<()> { + let expr = " + + + e + + + 1 + 2 + + + x + 2 + + + + + "; + test("fr", "SimpleSpeak", expr, "e élevé à la puissance moins 1 demi x au carré")?; + return Ok(()); + +} + +#[test] +fn nested_expr_to_tenth() -> Result<()> { + let expr = " + + + 3 + + + 3 + + 10 + + + + + "; + test("fr", "SimpleSpeak", expr, "3 élevé à la puissance 3 à la 10")?; + return Ok(()); + +} + +#[test] +fn nested_non_simple_squared_exp() -> Result<()> { + let expr = " + + + 3 + + + + ( + + x+1 + ) + 2 + + + + + "; + test("fr", "SimpleSpeak", expr, "3 élevé à la puissance parenthèse gauche, x plus 1, parenthèse droite au carré")?; + return Ok(()); + +} + +#[test] +fn nested_simple_power() -> Result<()> { + let expr = " + + t + + 45 + n + + + "; + test("fr", "SimpleSpeak", expr, "t élevé à la puissance 4 cinquièmes à la n-ième")?; + return Ok(()); + +} + +#[test] +fn nested_end_exponent_power() -> Result<()> { + let expr = " + + t + + 45 + n+1 + + + "; + test("fr", "SimpleSpeak", expr, "t élevé à la 4 cinquièmes élevé à la puissance n plus 1, fin d'exposant")?; + test_prefs("fr", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, + "t élevé à la 4 cinquièmes élevé à la puissance n plus 1")?; + return Ok(()); + +} + +#[test] +fn nested_end_exponent_neg_power() -> Result<()> { + let expr = " + + t + + 45 + -3 + + + "; + test("fr", "SimpleSpeak", expr, "t élevé à la 4 cinquièmes à la moins 3, fin d'exposant")?; + return Ok(()); + +} + +#[test] +fn nested_complex_power() -> Result<()> { + let expr = " + + + e + + + 1 + 2 + + + + ( + + + + xμ + σ + + + ) + 2 + + + + + "; + test("fr", "SimpleSpeak", expr, "e élevé à la puissance moins 1 demi fois; parenthèse gauche; fraction, x moins mû, sur sigma, fin de fraction; parenthèse droite au carré")?; + return Ok(()); + +} + +#[test] +fn default_power() -> Result<()> { + let expr = " + + t + + b+1 + 3 + + + "; + test("fr", "SimpleSpeak", expr, "t élevé à la puissance fraction, b plus 1, sur 3, fin de fraction")?; + return Ok(()); + +} From 8f990a575540b5bf9f8b9d90e19d52885c6d7911 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Fri, 15 May 2026 15:46:29 -0400 Subject: [PATCH 16/31] added tests and corrections for multiline.rs --- Rules/Languages/fr/SharedRules/general.yaml | 8 +-- tests/Languages/fr.rs | 1 + tests/Languages/fr/SimpleSpeak/multiline.rs | 78 +++++++++++++++++++++ 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 tests/Languages/fr/SimpleSpeak/multiline.rs diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml index 7a249a35c..a3a60efed 100644 --- a/Rules/Languages/fr/SharedRules/general.yaml +++ b/Rules/Languages/fr/SharedRules/general.yaml @@ -527,13 +527,13 @@ - x: "$LineCount" - test: - if: "self::m:piecewise" - then: [t: "case"] # phrase(this is the first 'case' of three cases) + then: [t: "cas"] # phrase(this is the first 'case' of three cases) - else_if: "self::m:system-of-equations" then: [t: "équation"] # phrase(this is the first 'equation' of three equations) else: [t: "ligne"] # phrase(this is the first 'line' of three lines) - test: - - if: "$LineCount != 1" - then: [ct: "s"] # plural + - if: "$LineCount != 1 and not(self::m:piecewise)" # 'cas' already ends with an 's', no need to add one when plural + then: [ct: "s"] # plural (not for 'cas' which is invariant) - pause: short - x: "*" - pause: long @@ -549,7 +549,7 @@ - pause: medium - test: - if: "parent::m:piecewise" - then: [t: "case"] # phrase('case' 1 of 10 cases) + then: [t: "cas"] # phrase('case' 1 of 10 cases) - else_if: "parent::m:system-of-equations" then: [t: "équation"] # phrase('equation' 1 of 10 equations) else: [t: "ligne"] # phrase('line 1 of 10 lines) diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 958651cf5..7669464e3 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -7,6 +7,7 @@ mod SimpleSpeak { mod linear_algebra; mod mfrac; mod msup; + mod multiline; } mod shared; diff --git a/tests/Languages/fr/SimpleSpeak/multiline.rs b/tests/Languages/fr/SimpleSpeak/multiline.rs new file mode 100644 index 000000000..ef85e1531 --- /dev/null +++ b/tests/Languages/fr/SimpleSpeak/multiline.rs @@ -0,0 +1,78 @@ +use crate::common::*; +use anyhow::Result; + +#[test] +fn case_1() -> Result<()> { + let expr = " + + f( + x + )={ + + + + + 1 si x<0 + + + + + + 0 si x=0 + + + + + + 1 si x>0 + + + + + "; + test("fr", "SimpleSpeak", expr, "f de x est égal à; 3 cas; \ + cas 1; moins 1 si x; est inférieur à 0; \ + cas 2; 0 si x, est égal à 0; \ + cas 3; 1 si x, est supérieur à 0")?; + return Ok(()); +} + +#[test] +fn equation_1() -> Result<()> { + let expr = " + + + + + + x+y + + + = + + + 7 + + + + + + 2x+3y + + + = + + + + 17 + + + + + + "; + test("fr", "SimpleSpeak", expr, "2 équations; \ + équation 1; x plus y, est égal à 7; \ + équation 2; 2 x plus 3 y; est égal à 17")?; + return Ok(()); +} From 61f6db0000e88194a54efeae1c46f9dcdc338ccd Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Fri, 15 May 2026 17:07:49 -0400 Subject: [PATCH 17/31] draft sets.rs --- Rules/Languages/fr/SharedRules/general.yaml | 24 +- Rules/Languages/fr/unicode.yaml | 8 +- tests/Languages/fr.rs | 1 + tests/Languages/fr/SimpleSpeak/sets.rs | 285 ++++++++++++++++++++ 4 files changed, 302 insertions(+), 16 deletions(-) create mode 100644 tests/Languages/fr/SimpleSpeak/sets.rs diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml index a3a60efed..3aa8bf124 100644 --- a/Rules/Languages/fr/SharedRules/general.yaml +++ b/Rules/Languages/fr/SharedRules/general.yaml @@ -8,25 +8,25 @@ - test: if: "$Verbosity!='Terse'" then: - - t: "la" # phrase('the' square root of 25 equals 5) - - bookmark: "*[2]/@id" - - test: - - if: "*[2][.='+']" - then: [t: "positive"] # phrase(set of all 'positive' integers less than 10) - else: [t: "negative"] # phrase(set of all 'negative' integers less than minus 10) + - t: "les" # phrase('the' real numbers) - bookmark: "*[1]/@id" - test: - if: "*[1][.='ℂ']" - then: [t: "nombre complexe"] # phrase('complex numbers' consist of two parts) + then: [t: "nombres complexes"] # phrase('complex numbers' consist of two parts) - else_if: "*[1][.='ℕ']" - then: [t: "nombre naturel"] # phrase('natural numbers' are numbers from 1 to infinity) + then: [t: "nombres naturels"] # phrase('natural numbers' are numbers from 1 to infinity) - else_if: "*[1][.='ℚ']" - then: [t: "nombre rationel"] # phrase('rational numbers' are the fraction of 2 integers) + then: [t: "nombres rationnels"] # phrase('rational numbers' are the fraction of 2 integers) - else_if: "*[1][.='ℝ']" - then: [t: "nombre réel"] # phrase('real numbers' can be both positive and negative) + then: [t: "nombres réels"] # phrase('real numbers' can be both positive and negative) - else_if: "*[1][.='ℤ']" - then: [t: "nombre entier"] # phrase(positive 'integers' are natural numbers above 0) + then: [t: "nombres entiers"] # phrase(positive 'integers' are natural numbers above 0) else: [x: "*[1][text()]"] # shouldn't happen + - bookmark: "*[2]/@id" + - test: + - if: "*[2][.='+']" + then: [t: "positifs"] # phrase(set of all 'positive' integers less than 10) + else: [t: "négatifs"] # phrase(set of all 'negative' integers less than minus 10) - name: dimension-number-sets # should be single digit integer at this point (e.g, R^3) @@ -60,7 +60,7 @@ - else_if: ".='ℕ'" then: [t: "les nombres naturels"] # phrase('the natural numbers' begin at 1) - else_if: ".='ℚ'" - then: [t: "les nombres rationels"] # phrase('the rational numbers' are the fraction of 2 integers) + then: [t: "les nombres rationnels"] # phrase('the rational numbers' are the fraction of 2 integers) - else_if: ".='ℝ'" then: [t: "les nombres réels"] # phrase('the real numbers' can be both positive and negative) - else_if: ".='ℤ'" diff --git a/Rules/Languages/fr/unicode.yaml b/Rules/Languages/fr/unicode.yaml index 4bd31653b..631150fd0 100644 --- a/Rules/Languages/fr/unicode.yaml +++ b/Rules/Languages/fr/unicode.yaml @@ -358,7 +358,7 @@ - test: if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" then: [t: "est"] # (en: 'is', DeepL translation) - - t: "appartient à" # (en: 'an element of') + - t: "appartenant à" # (en: 'an element of') # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set @@ -383,9 +383,9 @@ - test: if: "$SpeechStyle != 'ClearSpeak'" then: - - test: - if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) + # - test: + # if: "$Verbosity!='Terse'" + # then: [t: "est"] # (en: 'is', DeepL translation) - t: "n'appartient pas à" # (en: 'not an element of') # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 7669464e3..0ecbf66fb 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -8,6 +8,7 @@ mod SimpleSpeak { mod mfrac; mod msup; mod multiline; + mod sets; } mod shared; diff --git a/tests/Languages/fr/SimpleSpeak/sets.rs b/tests/Languages/fr/SimpleSpeak/sets.rs new file mode 100644 index 000000000..ee51b5739 --- /dev/null +++ b/tests/Languages/fr/SimpleSpeak/sets.rs @@ -0,0 +1,285 @@ +use crate::common::*; +use anyhow::Result; + +#[test] +fn complex() -> Result<()> { + let expr = " + + "; + test("fr", "SimpleSpeak", expr, "les nombres complexes")?; + return Ok(()); + +} + +#[test] +fn natural() -> Result<()> { + let expr = " + + "; + test("fr", "SimpleSpeak", expr, "les nombres naturels")?; + return Ok(()); + +} + +#[test] +fn rationals() -> Result<()> { + let expr = " + + "; + test("fr", "SimpleSpeak", expr, "les nombres rationnels")?; + return Ok(()); + +} + +#[test] +fn reals() -> Result<()> { + let expr = " + + "; + test("fr", "SimpleSpeak", expr, "les nombres réels")?; + return Ok(()); + +} + +#[test] +fn integers() -> Result<()> { + let expr = " + + "; + test("fr", "SimpleSpeak", expr, "les nombres entiers")?; + return Ok(()); + +} + + + +#[test] +fn msup_complex() -> Result<()> { + let expr = " + + + 2 + + "; + test("fr", "SimpleSpeak", expr, "C 2")?; + return Ok(()); + +} + +#[test] +fn msup_natural() -> Result<()> { + let expr = " + + + 2 + + "; + test("fr", "SimpleSpeak", expr, "N 2")?; + return Ok(()); + +} + +#[test] +fn msup_rationals() -> Result<()> { + let expr = " + + + 2 + + "; + test("fr", "SimpleSpeak", expr, "Q 2")?; + return Ok(()); + +} + +#[test] +fn msup_reals() -> Result<()> { + let expr = " + + + 3 + + "; + test("fr", "SimpleSpeak", expr, "R 3")?; + return Ok(()); + +} + +#[test] +fn msup_integers() -> Result<()> { + let expr = " + + + 4 + + "; + test("fr", "SimpleSpeak", expr, "Z 4")?; + return Ok(()); + +} + +#[test] +fn msup_positive_integers() -> Result<()> { + let expr = " + + + + + + "; + test("fr", "SimpleSpeak", expr, "les nombres entiers positifs")?; + return Ok(()); + +} + +#[test] +fn msup_negative_integers() -> Result<()> { + let expr = " + + + - + + "; + test("fr", "SimpleSpeak", expr, "les nombres entiers négatifs")?; + return Ok(()); + +} + +#[test] +fn msup_positive_rationals() -> Result<()> { + let expr = " + + + + + + "; + test("fr", "SimpleSpeak", expr, "les nombres rationnels positifs")?; + return Ok(()); + +} + +#[test] +fn msup_negative_rationals() -> Result<()> { + let expr = " + + + - + + "; + test("fr", "SimpleSpeak", expr, "les nombres rationnels négatifs")?; + return Ok(()); + +} + +#[test] +fn empty_set() -> Result<()> { + let expr = " + { } + "; + test("fr", "SimpleSpeak", expr, "ensemble vide")?; + return Ok(()); + +} + +#[test] +fn single_element_set() -> Result<()> { + let expr = " + { 12} + "; + test("fr", "SimpleSpeak", expr, "ensemble 12")?; + return Ok(()); + +} + +#[test] +fn multiple_element_set() -> Result<()> { + let expr = " + { 5 , 10 , 15 } + "; + test("fr", "SimpleSpeak", expr, "ensemble 5 virgule, 10 virgule, 15")?; + return Ok(()); + +} + +#[test] +fn set_with_colon() -> Result<()> { + let expr = " + { x:x>2 } + "; + test("fr", "SimpleSpeak", expr, "l'ensemble de tous les x tel que x est supérieur à 2")?; + return Ok(()); + +} + +#[test] +fn set_with_bar() -> Result<()> { + let expr = " + { x|x>2 } + "; + test("fr", "SimpleSpeak", expr, "l'ensemble de tous les x tel que x est supérieur à 2")?; + return Ok(()); + +} + +#[test] +fn element_alone() -> Result<()> { + let expr = " + 3+2i + "; + test("fr", "SimpleSpeak", expr, "3 plus 2 i, n'appartient pas à, les nombres réels")?; + return Ok(()); + +} + +#[test] +fn element_under_sum() -> Result<()> { + let expr = " + + + i + + + 1 + i 2 + + "; + test("fr", "SimpleSpeak", expr, + "the sum over i is an element of the integers of; fraction, 1 over, i squared, end fraction")?; + return Ok(()); + +} + +#[test] +fn complicated_set_with_colon() -> Result<()> { + let expr = " + { + x + + + : + 2 + < + x + < + 7 + } + "; + test("fr", "SimpleSpeak", expr, "ensemble de tous les x appartenant aux nombres entiers tel que 2 est inférieur à x est inférieur à 7")?; + return Ok(()); + +} + +#[test] +fn complicated_set_with_mtext() -> Result<()> { + // as of 8/5/21, parsing of "|" is problematic an element of the example, so are needed for this test + let expr = " + { + x + | + x  est un nombre pair + } + "; + test("fr", "SimpleSpeak", expr, + "ensemble de tous les x appartenant à, les nombres naturels tel que x est un nombre pair")?; + return Ok(()); + +} From 1f732763c00617850ee0017ae50d310c34bbe055 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Wed, 20 May 2026 16:53:54 -0400 Subject: [PATCH 18/31] completed sets.rs --- Rules/Languages/fr/unicode.yaml | 4 ++-- tests/Languages/fr/SimpleSpeak/sets.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Rules/Languages/fr/unicode.yaml b/Rules/Languages/fr/unicode.yaml index 631150fd0..b12a50781 100644 --- a/Rules/Languages/fr/unicode.yaml +++ b/Rules/Languages/fr/unicode.yaml @@ -358,7 +358,7 @@ - test: if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" then: [t: "est"] # (en: 'is', DeepL translation) - - t: "appartenant à" # (en: 'an element of') + - t: "un élément de" # (en: 'an element of') # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set @@ -396,7 +396,7 @@ - else_if: $ClearSpeak_SetMemberSymbol = 'Member' then: [t: "n'est pas membre de"] # (en: 'not member of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "pas un élément de"] # (en: 'not element of', DeepL translation) + then: [t: "n'est pas un élément de"] # (en: 'not element of', DeepL translation) - else: [t: "n'appartient pas à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' diff --git a/tests/Languages/fr/SimpleSpeak/sets.rs b/tests/Languages/fr/SimpleSpeak/sets.rs index ee51b5739..0d26de76e 100644 --- a/tests/Languages/fr/SimpleSpeak/sets.rs +++ b/tests/Languages/fr/SimpleSpeak/sets.rs @@ -205,7 +205,7 @@ fn set_with_colon() -> Result<()> { let expr = " { x:x>2 } "; - test("fr", "SimpleSpeak", expr, "l'ensemble de tous les x tel que x est supérieur à 2")?; + test("fr", "SimpleSpeak", expr, "ensemble de tous les x tel que x est supérieur à 2")?; return Ok(()); } @@ -215,7 +215,7 @@ fn set_with_bar() -> Result<()> { let expr = " { x|x>2 } "; - test("fr", "SimpleSpeak", expr, "l'ensemble de tous les x tel que x est supérieur à 2")?; + test("fr", "SimpleSpeak", expr, "ensemble de tous les x tel que x est supérieur à 2")?; return Ok(()); } @@ -243,7 +243,7 @@ fn element_under_sum() -> Result<()> { "; test("fr", "SimpleSpeak", expr, - "the sum over i is an element of the integers of; fraction, 1 over, i squared, end fraction")?; + "la sommation sur i est un élément de, les nombres entiers de; fraction, 1 sur, i au carré, fin de fraction")?; return Ok(()); } @@ -263,7 +263,7 @@ fn complicated_set_with_colon() -> Result<()> { 7 } "; - test("fr", "SimpleSpeak", expr, "ensemble de tous les x appartenant aux nombres entiers tel que 2 est inférieur à x est inférieur à 7")?; + test("fr", "SimpleSpeak", expr, "ensemble de tous les x un élément de, les nombres entiers tel que 2 est inférieur à x est inférieur à 7")?; return Ok(()); } @@ -279,7 +279,7 @@ fn complicated_set_with_mtext() -> Result<()> { } "; test("fr", "SimpleSpeak", expr, - "ensemble de tous les x appartenant à, les nombres naturels tel que x est un nombre pair")?; + "ensemble de tous les x un élément de, les nombres naturels tel que x est un nombre pair")?; return Ok(()); } From 2093e984b69beb02faded5f3e5527cc7aafff2f3 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Wed, 20 May 2026 17:03:14 -0400 Subject: [PATCH 19/31] added subscripts.rs tests --- tests/Languages/fr.rs | 1 + tests/Languages/fr/SimpleSpeak/subscripts.rs | 64 ++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 tests/Languages/fr/SimpleSpeak/subscripts.rs diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 0ecbf66fb..9dcdafd9a 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -9,6 +9,7 @@ mod SimpleSpeak { mod msup; mod multiline; mod sets; + mod subscripts; } mod shared; diff --git a/tests/Languages/fr/SimpleSpeak/subscripts.rs b/tests/Languages/fr/SimpleSpeak/subscripts.rs new file mode 100644 index 000000000..10ff0e0e0 --- /dev/null +++ b/tests/Languages/fr/SimpleSpeak/subscripts.rs @@ -0,0 +1,64 @@ +use crate::common::*; +use anyhow::Result; + +#[test] +fn msub_simple() -> Result<()> { + let expr = " x 1 "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "x indice 1")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x indice 1")?; + return Ok(()); + + } + +#[test] +fn msub_not_simple() -> Result<()> { + let expr = " x 1,2 "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x indice 1,2")?; + return Ok(()); + + } + +#[test] +fn msubsup_not_simple() -> Result<()> { + let expr = " x 1,2 3 "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x indice 1,2, au cube")?; + return Ok(()); + + } + +#[test] +fn msub_simple_mi() -> Result<()> { + let expr = " x i "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x indice i")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x indice i")?; + return Ok(()); + +} + +#[test] +fn msub_simple_number_follows() -> Result<()> { + let expr = " x 1 102 "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1, 10 au carré")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x indice 1, 10 au carré")?; + return Ok(()); + +} + +#[test] +fn msub_simple_non_number_follows() -> Result<()> { + let expr = " x 1 2 "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1, au carré")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x indice 1, au carré")?; + return Ok(()); + +} + +#[test] +fn msubsup_simple() -> Result<()> { + let expr = " x 1 x,2 "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "x 1, x au carré")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "x indice 1, x au carré")?; + return Ok(()); + +} \ No newline at end of file From 83cda50ffcbe768186d1df7b39eaa155c9d1abf5 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Wed, 20 May 2026 18:36:01 -0400 Subject: [PATCH 20/31] added test file and modifs for alphabets.rs --- Rules/Languages/fr/unicode-full.yaml | 302 +++++++++++++++------------ tests/Languages/fr/alphabets.rs | 258 ++++++++++++----------- 2 files changed, 297 insertions(+), 263 deletions(-) diff --git a/Rules/Languages/fr/unicode-full.yaml b/Rules/Languages/fr/unicode-full.yaml index 19499693d..0d02115d3 100644 --- a/Rules/Languages/fr/unicode-full.yaml +++ b/Rules/Languages/fr/unicode-full.yaml @@ -48,8 +48,9 @@ - "ʴ": [t: "modificateur petit tourné vers la droite"] # 0x2b4 (en: 'modifier small turned r', DeepL translation) - "ʵ": [t: "modificateur petit r tourné avec crochet"] # 0x2b5 (en: 'modifier small turned r with hook', DeepL translation) - "ʶ": # 0x2b6 - - t: "modificateur petit inversé" # (en: 'modifier small inverted', DeepL translation) - spell: "translate('R', 'R', 'R')" + - t: "modificateur petit inversé" # (en: 'modifier small inverted', DeepL translation) + - "ʷ": [t: "modificateur petit w"] # 0x2b7 (en: 'modifier small w', DeepL translation) - "ʸ": [t: "modificateur petit y"] # 0x2b8 (en: 'modifier small y', DeepL translation) @@ -454,19 +455,20 @@ - "℉": [t: "degré fahrenheit"] # 0x2109 (en: 'degrees fahrenheit', DeepL: 'degrés fahrenheit') - "ℊ": [t: "g ronde minuscule"] # 0x210a (en: 'script g', DeepL: 'script g') - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d - - t: "g ronde minuscule" # (en: 'fraktur', DeepL: 'fraktur') - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" + - t: "gothique" # (en: 'fraktur', DeepL: 'fraktur') - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f - - t: "g ronde minuscule" # (en: 'double struck', DeepL: 'double frappé') - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" + - t: "double barre" # (en: 'double struck', DeepL: 'double barre') + - "ℎ": [t: "constante de planck"] # 0x210e (en: 'planck constant') - "ℏ": [t: "constante de planck sur deux pi"] # 0x210f (en: 'h bar') - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 - - t: "constante de planck sur deux pi" # (en: 'script') - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + - t: "script" # (en: 'script') - "ℓ": [t: "l minuscule en script"] # 0x2113 (en: 'script l', MathPlayer: 'l ronde minuscule', DeepL: 'script l') - "℔": [t: "symbole l b barré"] # 0x2114 (en: 'pounds', DeepL: 'livres') @@ -481,15 +483,15 @@ # coalesced some chars that use cap letters - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 + - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" - test: - if: "'.' = '℺'" then: [t: "tourné"] # (en: 'rotated', DeepL translation) - else_if: "'.' = 'Ⅎ'" then: [t: "tourné"] # (en: 'turned', DeepL translation) - else_if: "'.' = '⅃'" - then: [t: "sans-serif inversé"] # (en: 'reversed sans-serif', DeepL translation) - else: [t: "e ronde minuscule"] # (en: 'turned sans-serif', DeepL: 'tourné sans empattement') - - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" + then: [t: "tourné sans-serif"] # (en: 'reversed sans-serif', DeepL translation) + else: [t: "tourné sans-serif"] # (en: 'turned sans-serif', DeepL: 'tourné sans empattement') - "ℴ": [t: "o ronde minuscule"] # 0x2134 (en: 'script o', DeepL: 'script o') - "ℵ": [t: "alef"] # 0x2135 (en: 'first transfinite cardinal') @@ -1415,8 +1417,8 @@ - t: "courant" # (en: 'current', DeepL translation) - "⏧": [t: "intersection électrique"] # 0x23e7 (en: 'electrical intersection', DeepL translation) - "①-⑨": # 0x2460 - 0x2469 - - t: "encerclé" # (en: 'circled', DeepL translation) - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - t: "encerclé" # (en: 'circled', DeepL translation) - "⑩": [t: "encerclé dix"] # 0x2469 (en: 'circled ten', DeepL translation) - "⑪": [t: "encerclé onze"] # 0x246a (en: 'circled eleven', DeepL translation) - "⑫": [t: "encerclé douze"] # 0x246b (en: 'circled twelve', DeepL translation) @@ -1428,8 +1430,8 @@ - "⑱": [t: "ateen encerclé"] # 0x2471 (en: 'circled eighteen', DeepL translation) - "⑳": [t: "encerclé vingt"] # 0x2473 (en: 'circled twenty', DeepL translation) - "⑴-⑼": # 0x2474 - 0x247d - - t: "entre parenthèses" # (en: 'parenthesized', DeepL translation) - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - t: "entre parenthèses" # (en: 'parenthesized', DeepL translation) - "⑽": [t: "dix entre parenthèses"] # 0x247d (en: 'parenthesized ten', DeepL translation) - "⑾": [t: "onze entre parenthèses"] # 0x247e (en: 'parenthesized eleven', DeepL translation) - "⑿": [t: "parenthèse-histhésée douze"] # 0x247f (en: 'parenthesized twelve', DeepL translation) @@ -1456,34 +1458,39 @@ - "⒚": [t: "dix-neuf avec point"] # 0x249a (en: 'nineteen with period', DeepL translation) - "⒛": [t: "vingt avec point"] # 0x249b (en: 'twenty with period', DeepL translation) - "⒜-⒵": # 0x249c - 0x24b5 - - t: "entre parenthèses" # (en: 'parenthesized', DeepL translation) - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + - t: "entre parenthèses" # (en: 'parenthesized', DeepL translation) + - "Ⓐ-ⓩ": # 0x24b6 - 0x24cf - - t: "encerclé" # (en: 'circled', DeepL translation) - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "encerclé" # (en: 'circled', DeepL translation) + - "🅐-🅩": # 0x1f150 - 0x1f169 - - t: "encerclé de noir" # (en: 'black circled', DeepL translation) - spell: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "encerclé de noir" # (en: 'black circled', DeepL translation) + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - t: "encerclé" # (en: 'circled', DeepL translation) - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - "⓪": [t: "encerclé zéro"] # 0x24ea (en: 'circled zero', DeepL translation) + - t: "encerclé" # (en: 'circled', DeepL translation) + + - "⓪": [t: "zéro encerclé"] # 0x24ea (en: 'circled zero', DeepL translation) - "⓫": [t: "onze encerclé de noir"] # 0x24eb (en: 'black circled eleven', DeepL translation) - - "⓬": [t: "noir encerclé douze"] # 0x24ec (en: 'black circled twelve', DeepL translation) - - "⓭": [t: "noir encerclé treize"] # 0x24ed (en: 'black circled thirteen', DeepL translation) - - "⓮": [t: "quatorze entouré de noir"] # 0x24ee (en: 'black circled fourteen', DeepL translation) - - "⓯": [t: "quinze encerclés noirs"] # 0x24ef (en: 'black circled fifteen', DeepL translation) - - "⓰": [t: "noir encerclé seize"] # 0x24f0 (en: 'black circled sixteen', DeepL translation) - - "⓱": [t: "dix-sept encerclé noir"] # 0x24f1 (en: 'black circled seventeen', DeepL translation) - - "⓲": [t: "atéroïde noir encerclé"] # 0x24f2 (en: 'black circled eighteen', DeepL translation) - - "⓳": [t: "noir encerclé dix-neuf"] # 0x24f3 (en: 'black circled nineteen', DeepL translation) - - "⓴": [t: "vingt encerclés de noir"] # 0x24f4 (en: 'black circled twenty', DeepL translation) + - "⓬": [t: "douze encerclé de noir"] # 0x24ec (en: 'black circled twelve', DeepL translation) + - "⓭": [t: "treize encerclé de noir"] # 0x24ed (en: 'black circled thirteen', DeepL translation) + - "⓮": [t: "quatorze encerclé de noir"] # 0x24ee (en: 'black circled fourteen', DeepL translation) + - "⓯": [t: "quinze encerclé de noir"] # 0x24ef (en: 'black circled fifteen', DeepL translation) + - "⓰": [t: "seize encerclé de noir"] # 0x24f0 (en: 'black circled sixteen', DeepL translation) + - "⓱": [t: "dix-sept encerclé de noir"] # 0x24f1 (en: 'black circled seventeen', DeepL translation) + - "⓲": [t: "atéroïde encerclé de noir"] # 0x24f2 (en: 'black circled eighteen', DeepL translation) + - "⓳": [t: "dix-neuf encerclé de noir"] # 0x24f3 (en: 'black circled nineteen', DeepL translation) + - "⓴": [t: "vingt encerclé de noir"] # 0x24f4 (en: 'black circled twenty', DeepL translation) - "⓵-⓽": # 0x24f5 - 0x24fe - - t: "double encerclé" # (en: 'double circled', DeepL translation) - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" + - t: "double encerclé" # (en: 'double circled', DeepL translation) + - "⓾": [t: "double cercle de dix"] # 0x24fe (en: 'double circled ten', DeepL translation) - "⓿": [t: "zéro encerclé de noir"] # 0x24ff (en: 'black circled zero', DeepL translation) - "■": [t: "petit carré noir"] # 0x25a0 (en: 'black square') @@ -1644,36 +1651,36 @@ - "❳": [t: "crochet de fantaisie droit maigre en écaille"] # 0x2773 (en: 'light right tortoise shell bracket ornament', DeepL: 'ornement de support en écaille de tortue léger et droit') - "❴": [t: "accolade de fantaisie gauche moyenne"] # 0x2774 (en: 'medium left brace ornament', DeepL: 'ornement d'accolade moyen gauche') - "❵": [t: "accolade de fantaisie droite moyenne"] # 0x2775 (en: 'medium right brace ornament', DeepL: 'accolade moyenne droite ornement') - - "❶": [t: "noir encerclé un"] # 0x2776 (en: 'black circled one', DeepL translation) - - "❷": [t: "deux encerclés de noir"] # 0x2777 (en: 'black circled two', DeepL translation) - - "❸": [t: "noir encerclé trois"] # 0x2778 (en: 'black circled three', DeepL translation) - - "❹": [t: "quatre encerclé noir"] # 0x2779 (en: 'black circled four', DeepL translation) - - "❺": [t: "cinq noir encerclé"] # 0x277a (en: 'black circled five', DeepL translation) - - "❻": [t: "noir encerclé six"] # 0x277b (en: 'black circled six', DeepL translation) - - "❼": [t: "sept encerclé en noir"] # 0x277c (en: 'black circled seven', DeepL translation) - - "❽": [t: "cercle noir avec flèche vers le bas"] # 0x277d (en: 'black circled eight', DeepL translation) - - "❾": [t: "noir encerclé neuf"] # 0x277e (en: 'black circled nine', DeepL translation) - - "❿": [t: "dix encerclé en noir"] # 0x277f (en: 'black circled ten', DeepL translation) - - "➀": [t: "un sans serif encerclé"] # 0x2780 (en: 'circled sans serif one', DeepL translation) - - "➁": [t: "encerclé sans serif deux"] # 0x2781 (en: 'circled sans serif two', DeepL translation) - - "➂": [t: "encerclé sans serif trois"] # 0x2782 (en: 'circled sans serif three', DeepL translation) - - "➃": [t: "quatre sans serif encerclé"] # 0x2783 (en: 'circled sans serif four', DeepL translation) - - "➄": [t: "encerclé sans serif cinq"] # 0x2784 (en: 'circled sans serif five', DeepL translation) - - "➅": [t: "encerclé sans serif six"] # 0x2785 (en: 'circled sans serif six', DeepL translation) - - "➆": [t: "encerclé sans empattement sept"] # 0x2786 (en: 'circled sans serif seven', DeepL translation) - - "➇": [t: "encerclé sans serif à"] # 0x2787 (en: 'circled sans serif eight', DeepL translation) - - "➈": [t: "encerclé sans serif neuf"] # 0x2788 (en: 'circled sans serif nine', DeepL translation) - - "➉": [t: "encerclé sans serif dix"] # 0x2789 (en: 'circled sans serif ten', DeepL translation) - - "➊": [t: "noir encerclé sans serif un"] # 0x278a (en: 'black circled sans serif one', DeepL translation) - - "➋": [t: "noir encerclé sans serif deux"] # 0x278b (en: 'black circled sans serif two', DeepL translation) - - "➌": [t: "noir encerclé sans serif trois"] # 0x278c (en: 'black circled sans serif three', DeepL translation) - - "➍": [t: "noir encerclé sans serif quatre"] # 0x278d (en: 'black circled sans serif four', DeepL translation) - - "➎": [t: "noir encerclé sans serif cinq"] # 0x278e (en: 'black circled sans serif five', DeepL translation) - - "➏": [t: "noir encerclé sans serif six"] # 0x278f (en: 'black circled sans serif six', DeepL translation) - - "➐": [t: "noir encerclé sans serif sept"] # 0x2790 (en: 'black circled sans serif seven', DeepL translation) - - "➑": [t: "sans serif noir encerclé at"] # 0x2791 (en: 'black circled sans serif eight', DeepL translation) - - "➒": [t: "noir encerclé sans empattement neuf"] # 0x2792 (en: 'black circled sans serif nine', DeepL translation) - - "➓": [t: "dix sans empattement cerclé de noir"] # 0x2793 (en: 'black circled sans serif ten', DeepL translation) + - "❶": [t: "un encerclé de noir"] # 0x2776 (en: 'black circled one', DeepL translation) + - "❷": [t: "deux encerclé de noir"] # 0x2777 (en: 'black circled two', DeepL translation) + - "❸": [t: "trois encerclé de noir"] # 0x2778 (en: 'black circled three', DeepL translation) + - "❹": [t: "quatre encerclé de noir"] # 0x2779 (en: 'black circled four', DeepL translation) + - "❺": [t: "cinq encerclé de noir"] # 0x277a (en: 'black circled five', DeepL translation) + - "❻": [t: "six encerclé de noir"] # 0x277b (en: 'black circled six', DeepL translation) + - "❼": [t: "sept encerclé de noir"] # 0x277c (en: 'black circled seven', DeepL translation) + - "❽": [t: "huit encerclé de noir"] # 0x277d (en: 'black circled eight', DeepL translation) + - "❾": [t: "neuf encerclé de noir"] # 0x277e (en: 'black circled nine', DeepL translation) + - "❿": [t: "dix encerclé de noir"] # 0x277f (en: 'black circled ten', DeepL translation) + - "➀": [t: "un encerclé sans serif"] # 0x2780 (en: 'circled sans serif one', DeepL translation) + - "➁": [t: "deux encerclé sans serif"] # 0x2781 (en: 'circled sans serif two', DeepL translation) + - "➂": [t: "trois encerclé sans serif"] # 0x2782 (en: 'circled sans serif three', DeepL translation) + - "➃": [t: "quatre encerclé sans serif"] # 0x2783 (en: 'circled sans serif four', DeepL translation) + - "➄": [t: "cinq encerclé sans serif"] # 0x2784 (en: 'circled sans serif five', DeepL translation) + - "➅": [t: "six encerclé sans serif"] # 0x2785 (en: 'circled sans serif six', DeepL translation) + - "➆": [t: "sept encerclé sans serif"] # 0x2786 (en: 'circled sans serif seven', DeepL translation) + - "➇": [t: "huit encerclé sans serif"] # 0x2787 (en: 'circled sans serif eight', DeepL translation) + - "➈": [t: "neuf encerclé sans serif"] # 0x2788 (en: 'circled sans serif nine', DeepL translation) + - "➉": [t: "dix encerclé sans serif"] # 0x2789 (en: 'circled sans serif ten', DeepL translation) + - "➊": [t: "un encerclé de noir sans serif"] # 0x278a (en: 'black circled sans serif one', DeepL translation) + - "➋": [t: "deux encerclé de nori sans serif"] # 0x278b (en: 'black circled sans serif two', DeepL translation) + - "➌": [t: "trois encerclé de noir sans serif"] # 0x278c (en: 'black circled sans serif three', DeepL translation) + - "➍": [t: "quatre encerclé de noir sans serif"] # 0x278d (en: 'black circled sans serif four', DeepL translation) + - "➎": [t: "cinq encerclé de noir sans serif"] # 0x278e (en: 'black circled sans serif five', DeepL translation) + - "➏": [t: "six encerclé de noir sans serif"] # 0x278f (en: 'black circled sans serif six', DeepL translation) + - "➐": [t: "sept encerclé de noir sans serif"] # 0x2790 (en: 'black circled sans serif seven', DeepL translation) + - "➑": [t: "huit encerclé de noir sans serif"] # 0x2791 (en: 'black circled sans serif eight', DeepL translation) + - "➒": [t: "neuf encerclé de noir sans serif"] # 0x2792 (en: 'black circled sans serif nine', DeepL translation) + - "➓": [t: "dix encerclé de noir sans serif"] # 0x2793 (en: 'black circled sans serif ten', DeepL translation) - "➔": [t: "flèche grasse vers la droite à pointe large"] # 0x2794 (en: 'heavy wide-headed rightwards arrow', DeepL: 'flèche lourde à tête large vers la droite') - "➕": [t: "plus gras"] # 0x2795 (en: 'heavy plus sign', DeepL: 'signe plus lourd') - "➖": [t: "moins gras"] # 0x2796 (en: 'heavy minus sign', DeepL: 'signe moins lourd') @@ -3125,116 +3132,123 @@ # fraktur chars in math alphabetic block and also MathType private use area # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) - - t: "fraktur" # (DeepL translation) - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + - t: "gothique" # (DeepL translation) - "-": # 0xf000 - 0xf018 - - t: "fraktur" # (DeepL translation) - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + - t: "gothique" # (DeepL translation) - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - t: "fraktur" # (DeepL translation) - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + - t: "gothique" # (DeepL translation) + - "-": # 0xf01a - 0xf033 - - t: "fraktur" # (DeepL translation) - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "gothique" # (DeepL translation) - "𝕬-𝖅": # 0x1D56C - 0x1D585 - - t: "fraktur" # (DeepL translation) + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "gothique" # (DeepL translation) - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf040 - 0xf059 - - t: "fraktur" # (DeepL translation) + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "gothique" # (DeepL translation) - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - t: "fraktur" # (DeepL translation) + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - t: "gothique" # (DeepL translation) - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf05a - 0xf073 - - t: "fraktur" # (DeepL translation) + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "gothique" # (DeepL translation) - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + # double struck (blackboard bold) chars in math alphabetic block and also MathType private use area # Some of these are reserved because they were used in Plane 0 -- that shouldn't be an issue other than causing the other chars to not display - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) - - t: "double frappé" # (en: 'double struck', DeepL translation) - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - + - t: "double barre" # (en: 'double struck', DeepL translation) - "-": # 0xf080 - 0xf098 - - t: "double frappé" # (en: 'double struck', DeepL translation) - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - t: "double frappé" # (en: 'double struck', DeepL translation) + - t: "double barre" # (en: 'double struck', DeepL translation) + - "𝕒-𝕫": # 0x1d552 - 0x1d56b - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + - t: "double barre" # (en: 'double struck', DeepL translation) - "-": # 0xf09a - 0xf0b3 - - t: "double frappé" # (en: 'double struck', DeepL translation) - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "double barre" # (en: 'double struck', DeepL translation) - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - t: "double frappé" # (en: 'double struck', DeepL translation) - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - t: "double barre" # (en: 'double struck', DeepL translation) - "-": # 0xf0c0 - 0xf0c9 - - t: "double frappé" # (en: 'double struck', DeepL translation) - spell: "translate('.', '', '0123456789')" + - t: "double barre" # (en: 'double struck', DeepL translation) - - "": [t: "double frappé nahblah"] # 0xf0ca (en: 'double struck nahblah', DeepL translation) + - "": [t: "double barre nahblah"] # 0xf0ca (en: 'double struck nahblah', DeepL translation) - "": [t: "constante d'euler doublement frappée"] # 0xf0cb (en: 'double struck euler constant', DeepL translation) # script chars in math alphabetic block and also MathType private use area - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - t: "script" # (DeepL translation) - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "-": # 0xf100 - 0xf119 - t: "script" # (DeepL translation) + - "-": # 0xf100 - 0xf119 - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - t: "script" # (DeepL translation) + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" - - "-": # 0xf11a - 0xf133 - t: "script" # (DeepL translation) + - "-": # 0xf11a - 0xf133 - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "script" # (DeepL translation) # bold script chars in math alphabetic block and also MathType private use area - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - t: "script" # (DeepL translation) + - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": # 0xf140 - 0xf159 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - t: "script" # (DeepL translation) + - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - t: "script" # (DeepL translation) + - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf15a - 0xf173 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - t: "script" # (DeepL translation) + - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "-": # 0xf180 - 0xf199 - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" @@ -3296,39 +3310,41 @@ # MathType only has a few of the cap Greek letters in PUA - "": # 0xf201 - 0xf209 - - t: "double frappé" # (en: 'double struck', DeepL translation) - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" + - t: "double barre" # (en: 'double struck', DeepL translation) - "-": # 0xf220 - 0xf236 - - t: "double frappé" # (en: 'double struck', DeepL translation) - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - t: "double barre" # (en: 'double struck', DeepL translation) - - "": [t: "double frappé final sigma"] # 0xf237 (en: 'double struck final sigma', DeepL translation) + - "": [t: "double barre final sigma"] # 0xf237 (en: 'double struck final sigma', DeepL translation) - "": [t: "double rho frappé"] # 0xf250 (en: 'double struck rho', DeepL translation) - "": [t: "phi doublement frappé"] # 0xf251 (en: 'double struck phi', DeepL translation) - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf260 - 0xf279 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf27a - 0xf293 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝐴-𝑍": # 0x1d434 - 0x1d44d - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" @@ -3344,31 +3360,33 @@ - "𝑨-𝒁": # 0x1d468 - 0x1d481 # - t: "bold italic" + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf2c8 - 0xf2e1 # - t: "bold italic" + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝒂-𝒛": # 0x1d482 - 0x1d49b # - t: "bold italic" + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf2e2 - 0xf2fb # - t: "bold italic" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" @@ -3383,28 +3401,30 @@ - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf334 - 0xf34d + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf34e - 0xf367 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": # 0x1d608 - 0x1d621 # - t: "italic" - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" @@ -3422,31 +3442,33 @@ - "𝘼-𝙕": # 0x1d63c - 0x1d655 # - t: "bold italic" + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf39c - 0xf3b5 # - t: "bold italic" + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝙖-𝙯": # 0x1d656 - 0x1d66f # - t: "bold italic" + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf3b6 - 0xf3cf # - t: "bold italic" + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝙰-𝚉": # 0x1d670 - 0x1d689 - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" @@ -3465,43 +3487,46 @@ - "𝚥": [t: "dotless j"] # 0x1d6a5 - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf408 - 0xf420 + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf422 - 0xf43a + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "": [t: "gras nahblah"] # 0xf421 (en: 'bold nahblah', DeepL translation) - "𝛁": [t: "symbole mathématique gras nabla"] # 0x1d6c1 (en: 'bold nahblah', DeepL: 'gras nahblah') - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 + - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - "": # 0xF43C - 0xF441 + - spell: "translate('.', '', '∂εθκφρπ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', '∂εθκφρπ')" + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa # - t: "italic" @@ -3532,155 +3557,166 @@ - "𝜜-𝜴": # 0x1d71c - 0x1d734 # - t: "bold italic" + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf47c - 0xf494 # - t: "bold italic" + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝜶-𝝎": # 0x1d736 - 0x1d74e # - t: "bold italic" + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf496 - 0xf4ae # - t: "bold italic" + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 # - t: "bold italic" + - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" - "": # 0xf422 - 0xf43a # - t: "bold italic" + - spell: "translate('.', '', '∂εθκφρπ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', '∂εθκφρπ')" + - "𝜵": [t: "symbole mathématique gras italique nabla"] # 0x1d735 (en: 'bold italic nahblah', DeepL: 'gras italique nahblah') - "": [t: "gras italique nahblah"] # 0xf495 (en: 'bold italic nahblah', DeepL translation) - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf4b6 - 0xf4ce + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝝰-𝞈": # 0x1d770 - 0x1d788 + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf4d0 - 0xf4e8 + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f + - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" - "": # 0xf4e9 - 0xf4ef + - spell: "translate('.', '', '∂εθκφρπ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', '∂εθκφρπ')" + - "": [t: "gras nahblah"] # 0xf4cf (en: 'bold nahblah', DeepL translation) - "𝝯": [t: "symbole mathématique gras sans empattement nabla"] # 0x1d76f (en: 'bold nahblah', DeepL: 'gras nahblah') - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 # - t: "bold italic" + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf4f0 - 0xf508 # - t: "bold italic" + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 # - t: "bold italic" + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf50a - 0xf522 # - t: "bold italic" + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 # - t: "bold italic" + - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" - "": # 0xf523 - 0xf529 # - t: "bold italic" + - spell: "translate('.', '', '∂εθκφρπ')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', '∂εθκφρπ')" + - "": [t: "gras nahblah"] # 0xf509 (en: 'bold nahblah', DeepL translation) - "𝞩": [t: "symbole mathématique sans empattement italique gras nabla"] # 0x1d7a9 (en: 'bold nahblah', DeepL: 'gras nahblah') - "-": # 0xf52e - 0xf537 (old MathType) + - spell: "translate('.', '', '0123456789')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', '0123456789')" + - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 + - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - "-": # 0xf52e - 0xf537 (old MathType) + - spell: "translate('.', '', '0123456789')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '', '0123456789')" + - "𝟬-𝟵": # 0x1D7EC - 0x1D7F5 + - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - test: if: "not($IgnoreBold)" then: [t: "gras"] # (en: 'bold', DeepL translation) - - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - "-": # 0xf556 - 0xf55f (old MathType) - spell: "translate('.', '', '0123456789')" diff --git a/tests/Languages/fr/alphabets.rs b/tests/Languages/fr/alphabets.rs index 810cedaa4..b14926fc8 100644 --- a/tests/Languages/fr/alphabets.rs +++ b/tests/Languages/fr/alphabets.rs @@ -4,394 +4,392 @@ use crate::common::*; use anyhow::Result; -// AI generated #[test] fn special_alphabet_chars() -> Result<()> { let expr = " ,"; - test("fr", "SimpleSpeak", expr, "g ronde minuscule majuscule h, comma; g ronde minuscule majuscule c")?; + test("fr", "SimpleSpeak", expr, "h majuscule gothique, virgule, c majuscule gothique")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "g ronde minuscule majuscule h, comma; g ronde minuscule majuscule pi")?; + test("fr", "SimpleSpeak", expr, "h majuscule double barre, virgule; pi majuscule double barre")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "constante de planck sur deux pi majuscule i; comma; constante de planck sur deux pi majuscule m")?; + test("fr", "SimpleSpeak", expr, "i majuscule script, virgule, m majuscule script")?; Ok(()) } -// AI generated + #[test] fn greek() -> Result<()> { let expr = " Α,Ω"; - test("fr", "SimpleSpeak", expr, "majuscule alpha comma, majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule virgule, oméga majuscule")?; let expr = " α,ω"; - test("fr", "SimpleSpeak", expr, "alpha comma, oméga")?; + test("fr", "SimpleSpeak", expr, "alpha virgule, oméga")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "double frappé majuscule delta, comma; double frappé majuscule upsilon")?; + test("fr", "SimpleSpeak", expr, "delta majuscule double barre, virgule; upsilon majuscule double barre")?; let expr = " α,ω"; - test("fr", "SimpleSpeak", expr, "alpha comma, oméga")?; + test("fr", "SimpleSpeak", expr, "alpha virgule, oméga")?; Ok(()) } -// AI generated + #[test] fn cap_cyrillic() -> Result<()> { let expr = " А,Я"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule ya")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, ya majuscule")?; Ok(()) } -// AI generated + #[test] fn parenthesized() -> Result<()> { let expr = " ,"; - test("fr", "SimpleSpeak", expr, "entre parenthèses a, comma, entre parenthèses z")?; + test("fr", "SimpleSpeak", expr, "a entre parenthèses, virgule, z entre parenthèses")?; Ok(()) } -// AI generated + #[test] fn circled() -> Result<()> { let expr = " ,"; - test("fr", "SimpleSpeak", expr, "encerclé majuscule a, comma, encerclé majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule encerclé, virgule, z majuscule encerclé")?; let expr = " 🅐,🅩"; - test("fr", "SimpleSpeak", expr, "encerclé de noir majuscule a, comma; encerclé de noir majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule encerclé de noir, virgule; z majuscule encerclé de noir")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "encerclé a comma, encerclé z")?; + test("fr", "SimpleSpeak", expr, "a encerclé virgule, z encerclé")?; Ok(()) } -// AI generated + #[test] fn fraktur() -> Result<()> { let expr = " 𝔄,𝔜"; - test("fr", "SimpleSpeak", expr, "fraktur majuscule a, comma, fraktur majuscule y")?; + test("fr", "SimpleSpeak", expr, "a majuscule gothique, virgule, y majuscule gothique")?; let expr = " 𝔞,𝔷"; - test("fr", "SimpleSpeak", expr, "fraktur a comma, fraktur z")?; + test("fr", "SimpleSpeak", expr, "a gothique virgule, z gothique")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "fraktur majuscule a, comma, fraktur majuscule y")?; + test("fr", "SimpleSpeak", expr, "a majuscule gothique, virgule, y majuscule gothique")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "fraktur a comma, fraktur z")?; + test("fr", "SimpleSpeak", expr, "a gothique virgule, z gothique")?; Ok(()) } -// AI generated + #[test] fn bold_fraktur() -> Result<()> { let expr = " 𝕬,𝖅"; - test("fr", "SimpleSpeak", expr, "fraktur gras majuscule a, comma, fraktur gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule gothique gras, virgule; z majuscule gothique gras")?; let expr = " 𝖆,𝖟"; - test("fr", "SimpleSpeak", expr, "fraktur gras a comma, fraktur gras z")?; + test("fr", "SimpleSpeak", expr, "a gothique gras virgule, z gothique gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "fraktur gras majuscule a, comma, fraktur gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule gothique gras, virgule; z majuscule gothique gras")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "fraktur gras a comma, fraktur gras z")?; + test("fr", "SimpleSpeak", expr, "a gothique gras virgule, z gothique gras")?; Ok(()) } -// AI generated + #[test] fn double_struck() -> Result<()> { let expr = " 𝔸,𝕐"; - test("fr", "SimpleSpeak", expr, "double frappé majuscule a, comma, double frappé majuscule y")?; + test("fr", "SimpleSpeak", expr, "a majuscule double barre, virgule; y majuscule double barre")?; let expr = " 𝕒,𝕫"; - test("fr", "SimpleSpeak", expr, "double frappé a comma, double frappé z")?; + test("fr", "SimpleSpeak", expr, "a double barre virgule, z double barre")?; let expr = " 𝟘,𝟡"; - test("fr", "SimpleSpeak", expr, "double frappé 0 comma, double frappé 9")?; + test("fr", "SimpleSpeak", expr, "0 double barre virgule, 9 double barre")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "double frappé majuscule a, comma, double frappé majuscule y")?; + test("fr", "SimpleSpeak", expr, "a majuscule double barre, virgule; y majuscule double barre")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "double frappé a comma, double frappé z")?; + test("fr", "SimpleSpeak", expr, "a double barre virgule, z double barre")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "double frappé 0 comma, double frappé 9")?; + test("fr", "SimpleSpeak", expr, "0 double barre virgule, 9 double barre")?; Ok(()) } -// AI generated + #[test] fn script() -> Result<()> { let expr = " 𝒜,𝒵"; - test("fr", "SimpleSpeak", expr, "script majuscule a, comma, script majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule script, virgule, z majuscule script")?; let expr = " 𝒶,𝓏"; - test("fr", "SimpleSpeak", expr, "script a comma, script z")?; + test("fr", "SimpleSpeak", expr, "a script virgule, z script")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "script majuscule a, comma, script majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule script, virgule, z majuscule script")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "script a comma, script z")?; + test("fr", "SimpleSpeak", expr, "a script virgule, z script")?; Ok(()) } -// AI generated + #[test] fn bold_script() -> Result<()> { let expr = " 𝓐,𝓩"; - test("fr", "SimpleSpeak", expr, "script gras majuscule a, comma, script gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule script gras, virgule; z majuscule script gras")?; let expr = " 𝓪,𝔃"; - test("fr", "SimpleSpeak", expr, "script gras a comma, script gras z")?; + test("fr", "SimpleSpeak", expr, "a script gras virgule, z script gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "script gras majuscule a, comma, script gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule script gras, virgule; z majuscule script gras")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "script gras a comma, script gras z")?; + test("fr", "SimpleSpeak", expr, "a script gras virgule, z script gras")?; Ok(()) } -// AI generated + #[test] fn bold() -> Result<()> { let expr = " 𝐀,𝐙"; - test("fr", "SimpleSpeak", expr, "gras majuscule a comma, gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule gras virgule, z majuscule gras")?; let expr = " 𝐚,𝐳"; - test("fr", "SimpleSpeak", expr, "gras a comma, gras z")?; + test("fr", "SimpleSpeak", expr, "a gras virgule, z gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras majuscule a comma, gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule gras virgule, z majuscule gras")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras a comma, gras z")?; + test("fr", "SimpleSpeak", expr, "a gras virgule, z gras")?; Ok(()) } -// AI generated + #[test] fn italic() -> Result<()> { let expr = " 𝐴,𝑍"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, z majuscule")?; let expr = " 𝑎,𝑧"; - test("fr", "SimpleSpeak", expr, "a comma, z")?; + test("fr", "SimpleSpeak", expr, "a virgule, z")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, z majuscule")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "a comma, z")?; + test("fr", "SimpleSpeak", expr, "a virgule, z")?; Ok(()) } -// AI generated + #[test] fn sans_serif() -> Result<()> { let expr = " 𝖠,𝖹"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, z majuscule")?; let expr = " 𝖺,𝗓"; - test("fr", "SimpleSpeak", expr, "a comma, z")?; + test("fr", "SimpleSpeak", expr, "a virgule, z")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, z majuscule")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "a comma, z")?; + test("fr", "SimpleSpeak", expr, "a virgule, z")?; Ok(()) } -// AI generated + #[test] fn sans_serif_bold() -> Result<()> { let expr = " 𝗔,𝗭"; - test("fr", "SimpleSpeak", expr, "gras majuscule a comma, gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule gras virgule, z majuscule gras")?; let expr = " 𝗮,𝘇"; - test("fr", "SimpleSpeak", expr, "gras a comma, gras z")?; + test("fr", "SimpleSpeak", expr, "a gras virgule, z gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras majuscule a comma, gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule gras virgule, z majuscule gras")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras a comma, gras z")?; + test("fr", "SimpleSpeak", expr, "a gras virgule, z gras")?; Ok(()) } -// AI generated + #[test] fn sans_serif_italic() -> Result<()> { let expr = " 𝘈,𝘡"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, z majuscule")?; let expr = " 𝘢,𝘻"; - test("fr", "SimpleSpeak", expr, "a comma, z")?; + test("fr", "SimpleSpeak", expr, "a virgule, z")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, z majuscule")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "a comma, z")?; + test("fr", "SimpleSpeak", expr, "a virgule, z")?; Ok(()) } -// AI generated + #[test] fn sans_serif_bold_italic() -> Result<()> { let expr = " 𝘼,𝙕"; - test("fr", "SimpleSpeak", expr, "gras majuscule a comma, gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule gras virgule, z majuscule gras")?; let expr = " 𝙖,𝙯"; - test("fr", "SimpleSpeak", expr, "gras a comma, gras z")?; + test("fr", "SimpleSpeak", expr, "a gras virgule, z gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras majuscule a comma, gras majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule gras virgule, z majuscule gras")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras a comma, gras z")?; + test("fr", "SimpleSpeak", expr, "a gras virgule, z gras")?; Ok(()) } -// AI generated + #[test] fn monospace() -> Result<()> { let expr = " 𝙰,𝚉"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, z majuscule")?; let expr = " 𝚊,𝚣"; - test("fr", "SimpleSpeak", expr, "a comma, z")?; + test("fr", "SimpleSpeak", expr, "a virgule, z")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, z majuscule")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "a comma, z")?; + test("fr", "SimpleSpeak", expr, "a virgule, z")?; Ok(()) } -// AI generated + #[test] fn bold_greek() -> Result<()> { let expr = " 𝚨,𝛀"; - test("fr", "SimpleSpeak", expr, "gras majuscule alpha, comma, gras majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule gras, virgule, oméga majuscule gras")?; let expr = " 𝛂,𝛚"; - test("fr", "SimpleSpeak", expr, "gras alpha comma, gras oméga")?; + test("fr", "SimpleSpeak", expr, "alpha gras virgule, oméga gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras majuscule alpha, comma, gras majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule gras, virgule, oméga majuscule gras")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras alpha comma, gras oméga")?; + test("fr", "SimpleSpeak", expr, "alpha gras virgule, oméga gras")?; Ok(()) } -// AI generated + #[test] fn bold_greek_others() -> Result<()> { let expr = " 𝛛,𝛡"; - test("fr", "SimpleSpeak", expr, "gras dérivée partielle, comma, gras pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle gras, virgule, pi gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras dérivée partielle, comma, gras pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle gras, virgule, pi gras")?; Ok(()) } -// AI generated #[test] fn italic_greek() -> Result<()> { let expr = " 𝛢,𝛺"; - test("fr", "SimpleSpeak", expr, "majuscule alpha comma, majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule virgule, oméga majuscule")?; let expr = " 𝛼,𝜔"; - test("fr", "SimpleSpeak", expr, "alpha comma, oméga")?; + test("fr", "SimpleSpeak", expr, "alpha virgule, oméga")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "majuscule alpha comma, majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule virgule, oméga majuscule")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "alpha comma, oméga")?; + test("fr", "SimpleSpeak", expr, "alpha virgule, oméga")?; Ok(()) } -// AI generated + #[test] fn italic_greek_others() -> Result<()> { let expr = " 𝜕,𝜛"; - test("fr", "SimpleSpeak", expr, "dérivée partielle, comma, pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle, virgule, pi")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "dérivée partielle, comma, pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle, virgule, pi")?; Ok(()) } -// AI generated + #[test] fn bold_italic_greek() -> Result<()> { let expr = " 𝜜,𝜴"; - test("fr", "SimpleSpeak", expr, "gras majuscule alpha, comma, gras majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule gras, virgule, oméga majuscule gras")?; let expr = " 𝜶,𝝎"; - test("fr", "SimpleSpeak", expr, "gras alpha comma, gras oméga")?; + test("fr", "SimpleSpeak", expr, "alpha gras virgule, oméga gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras majuscule alpha, comma, gras majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule gras, virgule, oméga majuscule gras")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras alpha comma, gras oméga")?; + test("fr", "SimpleSpeak", expr, "alpha gras virgule, oméga gras")?; Ok(()) } -// AI generated + #[test] fn bold_italic_greek_others() -> Result<()> { let expr = " 𝝏,𝝕"; - test("fr", "SimpleSpeak", expr, "gras dérivée partielle, comma, gras pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle gras, virgule, pi gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras dérivée partielle, comma, gras pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle gras, virgule, pi gras")?; Ok(()) } -// AI generated + #[test] fn sans_serif_bold_greek() -> Result<()> { let expr = " 𝝖,𝝮"; - test("fr", "SimpleSpeak", expr, "gras majuscule alpha, comma, gras majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule gras, virgule, oméga majuscule gras")?; let expr = " 𝝰,𝞈"; - test("fr", "SimpleSpeak", expr, "gras alpha comma, gras oméga")?; + test("fr", "SimpleSpeak", expr, "alpha gras virgule, oméga gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras majuscule alpha, comma, gras majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule gras, virgule, oméga majuscule gras")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras alpha comma, gras oméga")?; + test("fr", "SimpleSpeak", expr, "alpha gras virgule, oméga gras")?; Ok(()) } -// AI generated + #[test] fn sans_serif_bold_greek_others() -> Result<()> { let expr = " 𝞉,𝞏"; - test("fr", "SimpleSpeak", expr, "gras dérivée partielle, comma, gras pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle gras, virgule, pi gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras dérivée partielle, comma, gras pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle gras, virgule, pi gras")?; Ok(()) } -// AI generated + #[test] fn sans_serif_bold_italic_greek() -> Result<()> { let expr = " 𝞐,𝞨"; - test("fr", "SimpleSpeak", expr, "gras majuscule alpha, comma, gras majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule gras, virgule, oméga majuscule gras")?; let expr = " 𝞪,𝟂"; - test("fr", "SimpleSpeak", expr, "gras alpha comma, gras oméga")?; + test("fr", "SimpleSpeak", expr, "alpha gras virgule, oméga gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras majuscule alpha, comma, gras majuscule oméga")?; + test("fr", "SimpleSpeak", expr, "alpha majuscule gras, virgule, oméga majuscule gras")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras alpha comma, gras oméga")?; + test("fr", "SimpleSpeak", expr, "alpha gras virgule, oméga gras")?; Ok(()) } -// AI generated + #[test] fn sans_serif_bold_italic_greek_others() -> Result<()> { let expr = " 𝟃,𝟉"; - test("fr", "SimpleSpeak", expr, "gras dérivée partielle, comma, gras pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle gras, virgule, pi gras")?; // MathType private space versions let expr = " ,"; - test("fr", "SimpleSpeak", expr, "gras dérivée partielle, comma, gras pi")?; + test("fr", "SimpleSpeak", expr, "dérivée partielle gras, virgule, pi gras")?; Ok(()) } -// AI generated + #[test] fn pua_regular() -> Result<()> { let expr = " ,"; - test("fr", "SimpleSpeak", expr, "majuscule a comma, majuscule z")?; + test("fr", "SimpleSpeak", expr, "a majuscule virgule, z majuscule")?; Ok(()) } -// AI generated + #[test] fn turned() -> Result<()> { let expr = " ,"; - test("fr", "SimpleSpeak", expr, "tourné majuscule f, comma; e ronde minuscule majuscule y")?; + test("fr", "SimpleSpeak", expr, "f majuscule tourné, virgule; y majuscule tourné sans-serif")?; Ok(()) } -// AI generated + #[test] fn unicode_typo_regressions() -> Result<()> { test("fr", "SimpleSpeak", "", "exposant i")?; @@ -399,18 +397,18 @@ fn unicode_typo_regressions() -> Result<()> { Ok(()) } -// AI generated + #[test] fn enclosed_numbers() -> Result<()> { let expr = " ,"; - test("fr", "SimpleSpeak", expr, "encerclé 1 comma, encerclé 9")?; + test("fr", "SimpleSpeak", expr, "1 encerclé virgule, 9 encerclé")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "noir encerclé un comma, numéro cinquante encerclé")?; + test("fr", "SimpleSpeak", expr, "un encerclé de noir, virgule; numéro cinquante encerclé")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "entre parenthèses 1, comma, entre parenthèses 9")?; + test("fr", "SimpleSpeak", expr, "1 entre parenthèses, virgule, 9 entre parenthèses")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "1 avec point comma, 9 avec point")?; + test("fr", "SimpleSpeak", expr, "1 avec point virgule, 9 avec point")?; let expr = " ,"; - test("fr", "SimpleSpeak", expr, "double encerclé 1 comma, double encerclé 9")?; + test("fr", "SimpleSpeak", expr, "1 double encerclé, virgule, 9 double encerclé")?; Ok(()) } From 41f7d3d7b95c93d509a7daec2df9f2980666ca13 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Wed, 20 May 2026 22:13:30 -0400 Subject: [PATCH 21/31] wip chemistry.rs --- Rules/Languages/fr/SharedRules/general.yaml | 15 +- tests/Languages/fr.rs | 1 + tests/Languages/fr/chemistry.rs | 769 ++++++++++++++++++++ 3 files changed, 776 insertions(+), 9 deletions(-) create mode 100644 tests/Languages/fr/chemistry.rs diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml index 3aa8bf124..3c65077aa 100644 --- a/Rules/Languages/fr/SharedRules/general.yaml +++ b/Rules/Languages/fr/SharedRules/general.yaml @@ -817,11 +817,8 @@ replace: - x: "*[2]" - test: - if: "$Verbosity='Verbose'" + if: "$Verbosity='Verbose' or $Verbosity='Medium'" then: [t: "indice"] # phrase(H 'subscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "sous"] # phrase(H 'sub' 2) - x: "*[3]" - name: dimension-by @@ -838,11 +835,11 @@ replace: - x: "*[2]" - test: - if: "$Verbosity='Verbose'" + if: "$Verbosity='Verbose' or $Verbosity='Medium'" then: [t: "exposant"] # phrase(H 'superscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "super"] # phrase(H 'super' 2) + # else_test: + # if: "$Verbosity='Medium'" + # then: [t: "super"] # phrase(H 'super' 2) - x: "*[3]" - test: if: "following-sibling::*[1][.='+' or .='-']" # a little lazy -- assumes chemistry superscripts end with + or - @@ -1043,7 +1040,7 @@ then: [t: "liquide"] # phrase(water is a 'liquid') - else_if: ".='g'" then: [t: "gaz"] # phrase(hydrogen is a 'gas' ) - else: [t: "acqueuse"] # phrase(an 'aqueous' solution is contained in water) + else: [t: "aqueux"] # phrase(an 'aqueous' solution is contained in water) - pause: short - name: chemical-formula-operator-bond diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 9dcdafd9a..73ed530b6 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -14,3 +14,4 @@ mod SimpleSpeak { mod shared; mod alphabets; +mod chemistry; diff --git a/tests/Languages/fr/chemistry.rs b/tests/Languages/fr/chemistry.rs new file mode 100644 index 000000000..e007095f5 --- /dev/null +++ b/tests/Languages/fr/chemistry.rs @@ -0,0 +1,769 @@ +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; +use anyhow::Result; + +#[test] +fn salt() -> Result<()> { + let expr = "NaCl"; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "n majuscule a, c majuscule l")?; + return Ok(()); + +} + +#[test] +fn water() -> Result<()> { + let expr = "H2O"; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "h majuscule, 2 o majuscule")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "h majuscule, indice 2, o majuscule")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "h majuscule, indice 2, o majuscule")?; + return Ok(()); + +} + +#[test] +fn carbon() -> Result<()> { + let expr = "C"; // not enough to trigger recognition + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "c majuscule")?; + return Ok(()); + +} + +#[test] +fn sulfate() -> Result<()> { + let expr = " + [SO4] + 2 + "; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "crochet ouvrant, s majuscule, o majuscule, indice 4; crochet fermant exposant 2 moins")?; + return Ok(()); + +} + +#[test] +fn aluminum_sulfate() -> Result<()> { + let expr = "Al2 + (SO4)3"; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "a majuscule l, 2; ouvert, s majuscule, o majuscule, 4; fermer 3")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "a majuscule l, indice 2; parenthèse gauche, s majuscule, o majuscule, indice 4; parenthèse droite indice 3")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "a majuscule l, indice 2; parenthèse gauche, s majuscule, o majuscule, indice 4; parenthèse droite indice 3")?; + return Ok(()); + +} + +#[test] +fn ethanol_bonds() -> Result<()> { + let expr = " + + C + H 3 + + C + H 2 + + O + H + + "; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "c majuscule, h majuscule, 3, liaison simple c majuscule, h majuscule, 2, liaison simple o majuscule, h majuscule")?; + + return Ok(()); + +} + +#[test] +fn dichlorine_hexoxide() -> Result<()> { + let expr = " + + [ClO2] + + + + + [ClO4] + - + + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "crochet ouvrant, c majuscule l, o majuscule, 2; crochet fermant plus; \ + crochet ouvrant, c majuscule l, o majuscule, 4; crochet fermant moins")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "crochet ouvrant, c majuscule l, o majuscule, indice 2; crochet fermant exposant plus; \ + crochet ouvrant, c majuscule l, o majuscule, indice 4; crochet fermant exposant moins")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], + expr, "crochet ouvrant, c majuscule l, o majuscule, indice 2; crochet fermant exposant plus; \ + crochet ouvrant, c majuscule l, o majuscule, indice 4; crochet fermant exposant moins")?; + return Ok(()); + +} + + +#[test] +fn ethylene_with_bond() -> Result<()> { + let expr = " + H2C + = + CH2 + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "h majuscule, 2 c majuscule; liaison double c majuscule, h majuscule, 2")?; + return Ok(()); + +} + +#[test] +fn ferric_chloride_aq() -> Result<()> { + let expr = " + Fe + Cl3 + (aq) + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "f majuscule e, c majuscule l, 3, aqueux")?; + return Ok(()); + + } + +#[test] +fn ethylene_with_colon_bond() -> Result<()> { + let expr = " + H2C + :: + CH2 + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "cap h, 2 cap c, double bond cap c, cap h, 2")?; + return Ok(()); + +} + +#[test] +fn beta_decay() -> Result<()> { + let expr = " + + C + + 6 + 14 + + + + N + + 7 + 14 + + + + + e + + + + 1 + + 0 + + "; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, cap c; forms, 14, 7, cap n; plus 0, negative 1, e")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "super 14, sub 6, cap c; reacts to form; super 14, sub 7, cap n; plus super 0, sub negative 1, e")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "superscript 14, subscript 6, cap c; reacts to form; superscript 14, subscript 7, cap n; plus, superscript 0, subscript negative 1, e")?; + return Ok(()); + +} + +#[test] +fn mhchem_beta_decay() -> Result<()> { + let expr = " + + + + + + + A + + + + + + + + + 6 + + + + + + + + + 14 + + + + + + + + + + + + A + + + + + + + + + 2 + + + + + + + + 6 + + + + + + + + + + + + 2 + + + + + + + + 14 + + + + + + C + + + + + + + + + + + + A + + + + + + + + + 7 + + + + + + + + + 14 + + + + + + + + + + + + A + + + + + + + + + 2 + + + + + + + + 7 + + + + + + + + + + + + 2 + + + + + + + + 14 + + + + + + N + + + + + + + + + + + A + + + + + + + + + + 1 + + + + + + + + + 0 + + + + + + + + + + + + A + + + + + + + + + 2 + + + + + + + + + 1 + + + + + + + + + + + + 2 + + + + + + + + 0 + + + + + + e + + + "; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, cap c; forms, 14, 7, cap n; plus 0, negative 1, e")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "super 14, sub 6, cap c; reacts to form; super 14, sub 7, cap n; plus super 0, sub negative 1, e")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "superscript 14, subscript 6, cap c; reacts to form; superscript 14, subscript 7, cap n; plus, superscript 0, subscript negative 1, e")?; + return Ok(()); + +} + +#[test] +fn hcl_na_yields() -> Result<()> { + let expr = " + 2HCl+2Na + + 2NaCl+ + H 2 + + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "2, cap h, cap c l; plus 2 cap n eigh; reacts to form; 2, cap n eigh, cap c l; plus cap h, subscript 2")?; + return Ok(()); + +} + +#[test] +fn mhchem_so4_2plus() -> Result<()> { + let expr = " + + + SO + + + + + + + A + + + + + + + + 4 + + + + + + + + + + A + + + + + + 2 + + + + + + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "cap s; cap o, 4, 2 plus")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "cap s; cap o, sub 4, super 2 plus")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "cap s; cap o, subscript 4, superscript 2 plus")?; + return Ok(()); + +} + + +#[test] +fn mhchem_hcl_aq_etc() -> Result<()> { + let expr = " + + 2 + + + + + HCl + + + ( + + aq + + ) + + + + + 2 + + + + + Na + + + ( + + s + + ) + + + + + + 2 + + + + + NaCl + + + ( + + aq + + ) + + + + + + H + + + + + + + A + + + + + + + + 2 + + + + + + ( + + g + + ) + + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "2, cap h, cap c l, aqueous; plus, 2, cap n eigh, solid; forms; 2, cap n eigh, cap c l, aqueous; plus, cap h, 2, gas")?; + + return Ok(()); + +} + + +#[test] +fn mhchem_barbed_equilibrium() -> Result<()> { + let expr = " + + + + H + 2 + + + + + ( + g + ) + + + + + + + + I + 2 + + + + + ( + g + ) + + + + + + + - + + + - + + + + + 2 + + + H + + I + + + ( + g + ) + + + + + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "cap h, 2, gas; plus; cap i, 2, gas; is in equilibrium with, 2, cap h, cap i, gas")?; + return Ok(()); + +} + + + +#[test] +fn mhchem_roman_in_superscript() -> Result<()> { + let expr = " + + + Fe + + II + + + + Fe + + III + + + + O + 4 + + + + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "cap f e, 2; cap f e, 3; cap o, 4")?; + return Ok(()); + +} + + +#[test] +fn dropped_msubsup_bug_358() -> Result<()> { + let expr = r#" + + + 2 + + + SO + + 2 + + + + + + + + + O + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + SO + + 3 + + + + + + + + "#; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "2, cap s, cap o, 2; plus; cap o, 2 is in equilibrium with, 2, cap s, cap o, 3")?; + return Ok(()); + +} + + From 4f0d7f72dcdb505137f80eb78e3992f5cb156591 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Thu, 21 May 2026 18:47:40 -0400 Subject: [PATCH 22/31] completed corrections for chemistry.rs --- Rules/Languages/fr/SharedRules/default.yaml | 18 ++--- Rules/Languages/fr/SharedRules/general.yaml | 76 ++++++--------------- tests/Languages/fr/chemistry.rs | 30 ++++---- 3 files changed, 44 insertions(+), 80 deletions(-) diff --git a/Rules/Languages/fr/SharedRules/default.yaml b/Rules/Languages/fr/SharedRules/default.yaml index d3547e592..28b737496 100644 --- a/Rules/Languages/fr/SharedRules/default.yaml +++ b/Rules/Languages/fr/SharedRules/default.yaml @@ -191,15 +191,17 @@ if: "not(IsNode(*[last()], 'simple')) or $Impairment = 'Blindness'" then: [t: "fin d'exposant"] else: - - test: - if: "$Verbosity='Verbose'" - then: [t: "exposant"] - else: [t: "super"] + - t: "exposant" + # - test: + # if: "$Verbosity='Verbose'" + # then: [t: "exposant"] + # else: [t: "super"] - x: "*[last()]" - - test: - if: "$Verbosity='Verbose'" - then: [t: "fin d'exposant"] - else: [t: "fin de super"] + - t: "fin d'exposant" + # - test: + # if: "$Verbosity='Verbose'" + # then: [t: "fin d'exposant"] + # else: [t: "fin de super"] - name: default tag: munder diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml index 3c65077aa..00f30dd1e 100644 --- a/Rules/Languages/fr/SharedRules/general.yaml +++ b/Rules/Languages/fr/SharedRules/general.yaml @@ -244,10 +244,8 @@ then: [pause: short] - test: if: "name(.)='say-super'" - then_test: - if: "$Verbosity='Verbose'" - then: [t: "exposant"] # phrase(a 'superscript' number indicates raised to a power) - else: [t: "super"] # phrase(this is a 'super' set of numbers) + then: + - t: "exposant" - x: "*[3]" - pause: short @@ -866,22 +864,16 @@ if: "not($Prescripts[2][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" + if: "$Verbosity='Medium' or $Verbosity='Verbose'" then: [t: "exposant"] # phrase(H 'superscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "super"] # phrase(H 'super' 2) - x: "$Prescripts[2]" - pause: "short" - test: if: "not($Prescripts[1][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" - then: [t: "exposant"] # phrase(a 'subscript' may be used to indicate an index) - else_test: - if: "$Verbosity='Medium'" - then: [t: "sous"] # phrase(here is a 'sub' total) + if: "$Verbosity='Medium' or $Verbosity='Verbose'" + then: [t: "indice"] # phrase(a 'subscript' may be used to indicate an index) - x: "$Prescripts[1]" - pause: "short" - test: @@ -891,22 +883,16 @@ if: "not($Prescripts[4][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" + if: "$Verbosity='Medium' or $Verbosity='Verbose'" then: [t: "exposant"] # phrase(H 'superscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "super"] # phrase(H 'super' 2) - x: "$Prescripts[4]" - pause: "short" - test: if: "not($Prescripts[3][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" + if: "$Verbosity='Medium' or $Verbosity='Verbose'" then: [t: "indice"] # phrase(H 'subscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "sous"] # phrase(H 'sub' 2) - x: "$Prescripts[3]" - pause: "short" - x: "*[1]" # base @@ -917,22 +903,16 @@ if: "not($Postscripts[1][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" - then: [t: "subscript"] # phrase(phrase(H 'subscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "sous"] # phrase(phrase(H 'sub' 2) + if: "$Verbosity='Medium' or $Verbosity='Verbose'" + then: [t: "indice"] # phrase(phrase(H 'subscript' 2) - x: "$Postscripts[1]" - pause: "short" - test: if: "not($Postscripts[2][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" + if: "$Verbosity='Medium' or $Verbosity='Verbose'" then: [t: "exposant"] # phrase(H 'superscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "super"] # phrase(H 'super' 2) - x: "$Postscripts[2]" - pause: "short" - test: @@ -942,22 +922,16 @@ if: "not($Postscripts[3][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" - then: [t: "exposant"] # phrase(H 'subscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "sous"] # phrase(H 'sub' 2) + if: "$Verbosity='Medium' or $Verbosity='Verbose'" + then: [t: "indice"] # phrase(H 'subscript' 2) - x: "$Postscripts[3]" - pause: "short" - test: if: "not($Postscripts[4][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" + if: "$Verbosity='Medium' or $Verbosity='Verbose'" then: [t: "exposant"] # phrase(H 'superscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "super"] # phrase(H 'super' 2) - x: "$Postscripts[4]" - pause: "short" - test: @@ -967,22 +941,16 @@ if: "not($Postscripts[5][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" - then: [t: "exposant"] # phrase(H 'subscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "sous"] # phrase(H 'sub' 2) + if: "$Verbosity='Medium' or $Verbosity='Verbose'" + then: [t: "indice"] # phrase(H 'subscript' 2) - x: "$Postscripts[5]" - pause: "short" - test: if: "not($Postscripts[6][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" + if: "$Verbosity='Medium' or $Verbosity='Verbose'" then: [t: "exposant"] # phrase(H 'superscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "sous"] # phrase(H 'super' 2) - x: "$Postscripts[6]" - pause: "short" - test: @@ -992,22 +960,16 @@ if: "not($Postscripts[7][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" - then: [t: "exposant"] # phrase(H 'subscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "sous"] # phrase(H 'sub' 2) + if: "$Verbosity='Medium' or $Verbosity='Verbose'" + then: [t: "indice"] # phrase(H 'subscript' 2) - x: "$Postscripts[7]" - pause: "short" - test: if: "not($Postscripts[8][self::m:none])" then: - test: - if: "$Verbosity='Verbose'" + if: "$Verbosity='Medium' or $Verbosity='Verbose'" then: [t: "exposant"] # phrase(H 'superscript' 2) - else_test: - if: "$Verbosity='Medium'" - then: [t: "sous"] # phrase(H 'super' 2) - x: "$Postscripts[8]" - pause: "short" - test: diff --git a/tests/Languages/fr/chemistry.rs b/tests/Languages/fr/chemistry.rs index e007095f5..401858180 100644 --- a/tests/Languages/fr/chemistry.rs +++ b/tests/Languages/fr/chemistry.rs @@ -128,7 +128,7 @@ fn ethylene_with_colon_bond() -> Result<()> { :: CH2 "; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "cap h, 2 cap c, double bond cap c, cap h, 2")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "h majuscule, 2 c majuscule; liaison double c majuscule, h majuscule, 2")?; return Ok(()); } @@ -161,11 +161,11 @@ fn beta_decay() -> Result<()> { "; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], expr, - "14, 6, cap c; forms, 14, 7, cap n; plus 0, negative 1, e")?; + "14, 6, c majuscule; forment; 14, 7, n majuscule; plus 0, négatif 1, e")?; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "super 14, sub 6, cap c; reacts to form; super 14, sub 7, cap n; plus super 0, sub negative 1, e")?; + "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice négatif 1, e")?; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, - "superscript 14, subscript 6, cap c; reacts to form; superscript 14, subscript 7, cap n; plus, superscript 0, subscript negative 1, e")?; + "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice négatif 1, e")?; return Ok(()); } @@ -427,11 +427,11 @@ fn mhchem_beta_decay() -> Result<()> { "; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], expr, - "14, 6, cap c; forms, 14, 7, cap n; plus 0, negative 1, e")?; + "14, 6, c majuscule; forment; 14, 7, n majuscule; plus 0, négatif 1, e")?; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "super 14, sub 6, cap c; reacts to form; super 14, sub 7, cap n; plus super 0, sub negative 1, e")?; + "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice négatif 1, e")?; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, - "superscript 14, subscript 6, cap c; reacts to form; superscript 14, subscript 7, cap n; plus, superscript 0, subscript negative 1, e")?; + "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice négatif 1, e")?; return Ok(()); } @@ -446,7 +446,7 @@ fn hcl_na_yields() -> Result<()> { "; test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, - "2, cap h, cap c l; plus 2 cap n eigh; reacts to form; 2, cap n eigh, cap c l; plus cap h, subscript 2")?; + "2, h majuscule, c majuscule l; plus 2 n majuscule a; réagissent pour former; 2, n majuscule a, c majuscule l; plus h majuscule, indice 2")?; return Ok(()); } @@ -493,9 +493,9 @@ fn mhchem_so4_2plus() -> Result<()> { "; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "cap s; cap o, 4, 2 plus")?; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "cap s; cap o, sub 4, super 2 plus")?; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "cap s; cap o, subscript 4, superscript 2 plus")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "s majuscule; o majuscule, 4, 2 plus")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "s majuscule; o majuscule, indice 4, exposant 2 plus")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "s majuscule; o majuscule, indice 4, exposant 2 plus")?; return Ok(()); } @@ -585,7 +585,7 @@ fn mhchem_hcl_aq_etc() -> Result<()> { "; test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], - expr, "2, cap h, cap c l, aqueous; plus, 2, cap n eigh, solid; forms; 2, cap n eigh, cap c l, aqueous; plus, cap h, 2, gas")?; + expr, "2, h majuscule, c majuscule l, aqueux; plus, 2, n majuscule a, solide; forment; 2, n majuscule a, c majuscule l, aqueux; plus, h majuscule, 2; gaz")?; return Ok(()); @@ -653,7 +653,7 @@ fn mhchem_barbed_equilibrium() -> Result<()> { "; test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], - expr, "cap h, 2, gas; plus; cap i, 2, gas; is in equilibrium with, 2, cap h, cap i, gas")?; + expr, "h majuscule, 2; gaz; plus; i majuscule, 2; gaz; est en équilibre avec, 2, h majuscule, i majuscule, gaz")?; return Ok(()); } @@ -684,7 +684,7 @@ fn mhchem_roman_in_superscript() -> Result<()> { "; test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], - expr, "cap f e, 2; cap f e, 3; cap o, 4")?; + expr, "f majuscule e, 2; f majuscule e, 3; o majuscule, 4")?; return Ok(()); } @@ -761,7 +761,7 @@ fn dropped_msubsup_bug_358() -> Result<()> { "#; test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], - expr, "2, cap s, cap o, 2; plus; cap o, 2 is in equilibrium with, 2, cap s, cap o, 3")?; + expr, "2, s majuscule, o majuscule, 2; plus; o majuscule, 2 est en équilibre avec, 2, s majuscule, o majuscule, 3")?; return Ok(()); } From 1f45cc0c49f3f4eb1f93c33c9f30b6af9b73ca03 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Thu, 21 May 2026 19:01:29 -0400 Subject: [PATCH 23/31] added tests intent.rs --- tests/Languages/fr.rs | 1 + tests/Languages/fr/intent.rs | 144 +++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 tests/Languages/fr/intent.rs diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 73ed530b6..0124f33f3 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -15,3 +15,4 @@ mod SimpleSpeak { mod shared; mod alphabets; mod chemistry; +mod intent; diff --git a/tests/Languages/fr/intent.rs b/tests/Languages/fr/intent.rs new file mode 100644 index 000000000..caf2abd10 --- /dev/null +++ b/tests/Languages/fr/intent.rs @@ -0,0 +1,144 @@ +/// Tests for rules shared between various speech styles: +/// * this has tests focused on the various alphabets +use crate::common::*; +use anyhow::Result; + + +#[test] +fn silent_intent() -> Result<()> { + let expr = " 2 x "; + test("fr", "SimpleSpeak", expr, "2 x")?; + test("fr", "LiteralSpeak", expr, "2 x")?; + return Ok(()); + +} + +#[test] +fn prefix_intent() -> Result<()> { + let expr = r#" x T "#; + test("fr", "SimpleSpeak", expr, "teste x")?; + return Ok(()); + +} + +#[test] +fn postfix_intent() -> Result<()> { + let expr = r#" x T "#; + test("fr", "SimpleSpeak", expr, "x teste")?; + return Ok(()); + +} + +#[test] +fn infix_intent() -> Result<()> { + let expr = r#" + x + y + z + "#; + test("fr", "SimpleSpeak", expr, "x teste y teste z teste 2")?; + return Ok(()); + +} + +#[test] +fn infix_intent_no_args() -> Result<()> { + // this is illegal intent, so it is just an mrow with one child + let expr = r#" + x + "#; + test("fr", "SimpleSpeak", expr, "x")?; + return Ok(()); + +} + +#[test] +fn infix_intent_one_arg() -> Result<()> { + let expr = r#" + x + "#; + // Note: we say the intent name because there are infix plus/minus with a single arg due to continued rows or combined columns + test("fr", "SimpleSpeak", expr, "teste x")?; + return Ok(()); + +} + +#[test] +fn function_intent() -> Result<()> { + let expr = r#" + x + y + z + "#; + test("fr", "SimpleSpeak", expr, "teste de x virgule, y virgule, z virgule, 2")?; + return Ok(()); + +} + +#[test] +fn function_no_args_intent() -> Result<()> { + // this is illegal intent, so it is just an mrow with one child + let expr = r#" + x + "#; + test("fr", "SimpleSpeak", expr, "x")?; + return Ok(()); + +} + +#[test] +fn function_one_arg_intent() -> Result<()> { + let expr = r#" + x + "#; + test("fr", "SimpleSpeak", expr, "teste de x")?; + return Ok(()); + +} + +#[test] +fn silent_intent_mi() -> Result<()> { + let expr = " 2 x"; + test("fr", "SimpleSpeak", expr, "2")?; + test("fr", "ClearSpeak", expr, "2")?; + return Ok(()); + +} + +#[test] +fn silent_intent_msup() -> Result<()> { + let expr = " + + H + 2 + "; + test("fr", "SimpleSpeak", expr, "h majuscule 2")?; + test("fr", "ClearSpeak", expr, "h majuscule 2")?; + return Ok(()); + +} + +#[test] +fn silent_intent_underscore() -> Result<()> { + let expr = " + + H + 2 + "; + test("fr", "SimpleSpeak", expr, "h majuscule 2")?; + test("fr", "ClearSpeak", expr, "h majuscule 2")?; + return Ok(()); + +} + +#[test] +fn intent_prob_x() -> Result<()> { + let expr = " + + x + P + "; + test("fr", "ClearSpeak", expr, "probabilité de x")?; + return Ok(()); + +} From 42b2c7dcf96f9b681d7b3b15306eb57563abc0e7 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Mon, 25 May 2026 16:07:09 -0400 Subject: [PATCH 24/31] modified rules and completed tests for mtable.rs --- Rules/Languages/fr/ClearSpeak_Rules.yaml | 6 +- Rules/Languages/fr/SharedRules/default.yaml | 8 - Rules/Languages/fr/SharedRules/general.yaml | 80 +- Rules/Languages/fr/definitions.yaml | 2 +- tests/Languages/fr.rs | 1 + tests/Languages/fr/mtable.rs | 1191 +++++++++++++++++++ 6 files changed, 1247 insertions(+), 41 deletions(-) create mode 100644 tests/Languages/fr/mtable.rs diff --git a/Rules/Languages/fr/ClearSpeak_Rules.yaml b/Rules/Languages/fr/ClearSpeak_Rules.yaml index 133fce420..6dc24be3f 100644 --- a/Rules/Languages/fr/ClearSpeak_Rules.yaml +++ b/Rules/Languages/fr/ClearSpeak_Rules.yaml @@ -121,8 +121,8 @@ - bookmark: "@id" - test: if: "self::m:minus" - then: [t: "négatif"] # phrase(minus 5 is a 'negative' number) - else: [t: "positif"] # phrase(7 is a 'positive' number) + then: [t: "moins"] + else: [t: "plus"] - x: "*[1]" # Fraction rules @@ -474,7 +474,7 @@ name: ClearSpeak-absolute-value tag: absolute-value match: "." - variables: [WordToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'cardinality', 'absolute value')"] + variables: [WordToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'cardinalité', 'valeur absolue')"] replace: - test: if: "$Verbosity!='Terse'" diff --git a/Rules/Languages/fr/SharedRules/default.yaml b/Rules/Languages/fr/SharedRules/default.yaml index 28b737496..374e36dc1 100644 --- a/Rules/Languages/fr/SharedRules/default.yaml +++ b/Rules/Languages/fr/SharedRules/default.yaml @@ -192,16 +192,8 @@ then: [t: "fin d'exposant"] else: - t: "exposant" - # - test: - # if: "$Verbosity='Verbose'" - # then: [t: "exposant"] - # else: [t: "super"] - x: "*[last()]" - t: "fin d'exposant" - # - test: - # if: "$Verbosity='Verbose'" - # then: [t: "fin d'exposant"] - # else: [t: "fin de super"] - name: default tag: munder diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml index 00f30dd1e..989957617 100644 --- a/Rules/Languages/fr/SharedRules/general.yaml +++ b/Rules/Languages/fr/SharedRules/general.yaml @@ -599,14 +599,16 @@ variables: [IsColumnSilent: true()] match: "count(*)=1 and *[self::m:mtr][count(*) = 1]" replace: - - ot: "the" # phrase('the' 1 by 1 matrix M) - - t: "une par une" # phrase(the '1 by 1' matrix) - test: if: "self::m:determinant" # just need to check the first bracket since we know it must be (, [, or | - then: [t: "déterminant"] # phrase(the 2 by 2 'determinant')) + then: [t: "le"] # phrase('the' 1 by 1 determinant) + else: [t: "la"] # phrase('the' 1 by 1 matrix M) + - test: + if: "self::m:determinant" + then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') else: [t: "matrice"] # phrase(the 2 by 2 'matrix') - - - t: "avec entrée" # phrase(the 2 by 2 matrix 'with entry' x) + - t: "1 par 1" # phrase(the '1 by 1' matrix) + - t: "avec l'élément" # phrase(the 2 by 2 matrix 'containing the element' x) - x: "*[1]/*" # simpler reading methods for special case matrices @@ -616,10 +618,10 @@ match: "not( */*/*[not(self::m:mn and .= 0)] )" replace: - t: "la" # phrase('the' 1 by 2 matrix M) + - t: "matrice zéro" # phrase(the 2 by 2 'zero matrix') - x: count(*) - t: "par" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - t: "matrice zéro" # phrase(the 2 by 2 'zero matrix') - pause: long - name: identity-matrix @@ -631,10 +633,10 @@ - "not( */*[count(preceding-sibling::*) != count(../preceding-sibling::*)]/*[not(self::m:mn and .= 0)] )" # off-diagonal replace: - t: "la" # phrase('the' 1 by 2 matrix M) + - t: "matrice identité" # phrase(the 2 by 2 'identity matrix') - x: count(*) - t: "par" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - t: "matrice identitée" # phrase(the 2 by 2 'identity matrix') - pause: long - name: diagonal-matrix @@ -648,10 +650,10 @@ - " )" replace: - t: "la" # phrase('the' 1 by 2 matrix) + - t: "matrice diagonale" # phrase(the 2 by 2 'diagonal matrix') - x: count(*) - t: "par" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - t: "matrice diagonale" # phrase(the 2 by 2 'diagonal matrix') - pause: long - insert: # this lists the diagonal 'mtd's to be read, and they say "column nnn" before reading the contents @@ -671,13 +673,16 @@ - count(*)<=3 and # at least two rows - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple replace: - - t: "la" # phrase('the' 2 by 2 matrix M) - - x: count(*) - - t: "par une colonne" # phrase(the 2 'by 1 column' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [t: "le"] # phrase('the' 2 by 2 vector) - masculine + else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" then: [t: "vecteur"] # phrase(the 2 by 2 'vector') else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + - x: count(*) + - t: "par 1 colonne" # phrase(the 2 'by 1 column' matrix) - pause: long - x: "*/*" - test: @@ -694,13 +699,16 @@ variables: [IsColumnSilent: true()] match: "*[self::m:mtr][count(*) = 1]" replace: - - t: "la" # phrase('the' 2 by 2 matrix M) - - x: "count(*)" - - t: "par 1 colonne" # phrase(the 2 'by 1 column' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [t: "le"] # phrase('the' 2 by 2 vector) - masculine + else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" then: [t: "vecteur"] # phrase(the 2 column 'vector') else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + - x: "count(*)" + - t: "par 1 colonne" # phrase(the 2 'by 1 column' matrix) - pause: long - x: "*" # select the rows (mtr) - test: @@ -716,13 +724,17 @@ - count(*[1]/*)<=3 and # at least two cols - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple replace: - - t: "la 1 par" # phrase('the 1 by' 2 matrix) - - x: count(*/*) - - t: "rangée" # phrase(the 1 by 4 'row' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [t: "le"] # phrase('the' 2 by 2 vector) - masculine + else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" then: [t: "vecteur"] # phrase('the 1 by' 2 row 'vector') else: [t: "matrice"] # phrase('the 1 by' 2 'matrix') + - t: "1 par" # phrase('the 1 by' 2 matrix) + - x: count(*/*) + - t: "rangée" # phrase(the 1 by 4 'row' matrix) - pause: long - x: "*/*" - test: @@ -739,13 +751,17 @@ variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] match: "count(*)=1" # one row replace: - - t: "la 1 par" # phrase('the 1 by' 2 matrix) - - x: "count(*/*)" - - t: "rangée" # phrase(the 1 by 2 'row' matrix) + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [t: "le"] # phrase('the' 2 by 2 vector) - masculine + else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" then: [t: "vecteur"] # phrase(the 2 by 1 'vector') else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + - t: "1 par" # phrase('the 1 by' 2 matrix) + - x: "count(*/*)" + - t: "rangée" # phrase(the 1 by 2 'row' matrix) - pause: long - pause: medium - x: "*/*" # select the cols (mtd) @@ -766,14 +782,17 @@ - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple variables: [IsColumnSilent: "$SpeechStyle = 'SimpleSpeak' or ($SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix != 'SpeakColNum')"] replace: - - t: "la" # phrase('the' 1 by 2 matrix M) + - test: + if: "self::m:determinant" + then: [t: "le"] # phrase('the' 2 by 2 determinant) - masculine + else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine + - test: + if: "self::m:determinant" + then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') + else: [t: "matrice"] # phrase(the 2 by 2 'matrix') - x: count(*) - t: "par" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - test: - if: "self::m:determinant" - then: [t: "determinant"] # phrase(the 2 by 2 'determinant') - else: [t: "matrix"] # phrase(the 2 by 2 'matrix') - pause: long - x: "*" - test: @@ -790,14 +809,17 @@ variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] match: "." replace: - - t: "the" # phrase('the' 1 by 2 matrix M) - - x: "count(*)" - - t: "par" # phrase(the 1 'by' 2 matrix) - - x: "count(*[self::m:mtr][1]/*)" + - test: + if: "self::m:determinant" + then: [t: "le"] # phrase('the' 2 by 2 determinant) - masculine + else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "self::m:determinant" then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + - x: "count(*)" + - t: "par" # phrase(the 1 'by' 2 matrix) + - x: "count(*[self::m:mtr][1]/*)" - pause: long - x: "*" - test: diff --git a/Rules/Languages/fr/definitions.yaml b/Rules/Languages/fr/definitions.yaml index 6859b7ca6..4708dcee0 100644 --- a/Rules/Languages/fr/definitions.yaml +++ b/Rules/Languages/fr/definitions.yaml @@ -19,7 +19,7 @@ "say-super": "infix=super: exposant: exposant", "skip-super": "silent=", - "absolute-value": "function= ; valeur absolue: la valeur absolue de: la valeur absolue de; fin de valeur absolue", + "absolute-value": "function= ; valeur absolue: la valeur absolue: la valeur absolue; fin de valeur absolue", "binomial": "infix=binôme; parmi; fin du binôme", "dimension-product": "infix=par", "greatest-common-divisor": "function=pgcd: le pgcd: le plus grand commun diviseur", diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 0124f33f3..3ba3cdfd4 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -16,3 +16,4 @@ mod shared; mod alphabets; mod chemistry; mod intent; +mod mtable; diff --git a/tests/Languages/fr/mtable.rs b/tests/Languages/fr/mtable.rs new file mode 100644 index 000000000..7d618cebb --- /dev/null +++ b/tests/Languages/fr/mtable.rs @@ -0,0 +1,1191 @@ +use crate::common::*; +use anyhow::Result; + +#[test] +fn matrix_1x1() -> Result<()> { + let expr = " + + + ( + + 3 + + ) + + "; + test("fr", "ClearSpeak", expr, "la matrice 1 par 1 avec l'élément 3")?; + test("fr", "SimpleSpeak", expr, "la matrice 1 par 1 avec l'élément 3")?; + return Ok(()); + +} + +#[test] +fn determinant_1x1() -> Result<()> { + let expr = " + + + | + + 3 + + | + + "; + test("fr", "ClearSpeak", expr, "le déterminant 1 par 1 avec l'élément 3")?; + test("fr", "SimpleSpeak", expr, "le déterminant 1 par 1 avec l'élément 3")?; + return Ok(()); + +} + + +#[test] +fn matrix_1x2() -> Result<()> { + let expr = " + + + ( + + + + 3 + + + 5 + + + + ) + + "; + test("fr", "ClearSpeak", expr, "la matrice 1 par 2 rangée; 3, 5")?; + test("fr", "SimpleSpeak", expr, "la matrice 1 par 2 rangée; 3, 5")?; + return Ok(()); + +} + + +#[test] +fn matrix_1x3() -> Result<()> { + let expr = " + + + ( + + + + -x + + + 5 + + + 12 + + + + ) + + "; + test("fr", "ClearSpeak", expr, "la matrice 1 par 3 rangée; moins x, 5, 12")?; + test("fr", "SimpleSpeak", expr, "la matrice 1 par 3 rangée; moins x, 5, 12")?; + return Ok(()); + +} + +#[test] +fn matrix_2x1_not_simple() -> Result<()> { + let expr = " + + + ( + + + + + x+1 + + + + + + + x-1 + + + + ) + + "; + test("fr", "ClearSpeak", expr, "la matrice 2 par 1 colonne; rangée 1; x plus 1; rangée 2; x moins 1")?; + test("fr", "SimpleSpeak", expr, "la matrice 2 par 1 colonne; rangée 1; x plus 1; rangée 2; x moins 1")?; + return Ok(()); + +} +#[test] +fn matrix_3x1_not_simple() -> Result<()> { + let expr = " + + + ( + + + + + x + + + + + + + a + + + + + + + x + + x+1 + + + + + + ) + "; + test("fr", "SimpleSpeak", expr, "la matrice 3 par 1 colonne; \ + rangée 1; x; \ + rangée 2; a; \ + rangée 3; fraction, x sur, x plus 1, fin de fraction")?; + test("fr", "ClearSpeak", expr, "la matrice 3 par 1 colonne; \ + rangée 1; x; \ + rangée 2; a; \ + rangée 3; la fraction avec numérateur x; et dénominateur x plus 1")?; + return Ok(()); + +} + +#[test] +fn determinant_2x2() -> Result<()> { + let expr = " + + | + + + + 2 + + + 1 + + + + + 7 + + + 5 + + + + + | + "; + test("fr", "ClearSpeak", expr, "le déterminant 2 par 2; rangée 1; 2, 1; rangée 2; 7, 5")?; + test("fr", "SimpleSpeak", expr, "le déterminant 2 par 2; rangée 1; 2, 1; rangée 2; 7, 5")?; + return Ok(()); + +} + +#[test] +fn matrix_2x3() -> Result<()> { + let expr = " + + + [ + + + + 3 + + + 1 + + + 4 + + + + + 0 + + + 2 + + + 6 + + + + ] + + "; + test("fr", "ClearSpeak", expr, "la matrice 2 par 3; rangée 1; 3, 1, 4; rangée 2; 0, 2, 6")?; + test("fr", "SimpleSpeak", expr, "la matrice 2 par 3; rangée 1; 3, 1, 4; rangée 2; 0, 2, 6")?; + return Ok(()); + +} + +#[test] +fn matrix_2x3_labeled() -> Result<()> { + let expr = " + + + [ + + + + (3.1) + + + 3 + + + 1 + + + 4 + + + + + 0 + + + 2 + + + 6 + + + + ] + + "; + test("fr", "ClearSpeak", expr, + "la matrice 2 par 3; rangée 1 avec l'étiquette (3.1); colonne 1; 3, colonne 2; 1, colonne 3; 4; \ + rangée 2; colonne 1; 0, colonne 2; 2, colonne 3; 6")?; + test("fr", "SimpleSpeak", expr, + "la matrice 2 par 3; rangée 1 avec nom (3.1); colonne 1; 3, colonne 2; 1, colonne 3; 4; \ + rangée 2; colonne 1; 0, colonne 2; 2, colonne 3; 6")?; + return Ok(()); + +} + +#[test] +fn matrix_3x1() -> Result<()> { + let expr = " + + + [ + + + + 1 + + + + + 2 + + + + + 3 + + + ] + + "; + test("fr", "ClearSpeak", expr, "la matrice 3 par 1 colonne; 1; 2; 3")?; + test("fr", "SimpleSpeak", expr, "la matrice 3 par 1 colonne; 1; 2; 3")?; + return Ok(()); + +} + +#[test] +fn matrix_4x1() -> Result<()> { + let expr = " + + + ( + + + + 3 + + + + + 6 + + + + + 1 + + + + + 2 + + + + ) + + "; + test("fr", "ClearSpeak", expr, "la matrice 4 par 1 colonne; rangée 1; 3; rangée 2; 6; rangée 3; 1; rangée 4; 2")?; + test("fr", "SimpleSpeak", expr, "la matrice 4 par 1 colonne; rangée 1; 3; rangée 2; 6; rangée 3; 1; rangée 4; 2")?; + return Ok(()); + +} + +#[test] +fn matrix_4x1_labeled() -> Result<()> { + let expr = " + + + ( + + + + 3 + + + + + 6 + + + + + 1 + + + + + (3.1) + + + 2 + + + + ) + + "; + test("fr", "ClearSpeak", expr, + "la matrice 4 par 1 colonne; rangée 1; 3; rangée 2; 6; rangée 3; 1; rangée 4 avec l'étiquette (3.1); 2")?; + test("fr", "SimpleSpeak", expr, + "la matrice 4 par 1 colonne; rangée 1; 3; rangée 2; 6; rangée 3; 1; rangée 4 avec nom (3.1); 2")?; + return Ok(()); + +} + +#[test] +fn matrix_1x4() -> Result<()> { + let expr = " + + + ( + + + + 3 + + + 6 + + + 1 + + + 2 + + + + ) + + "; + test("fr", "ClearSpeak", expr, "la matrice 1 par 4 rangée; colonne 1; 3, colonne 2; 6, colonne 3; 1, colonne 4; 2")?; + test("fr", "SimpleSpeak", expr, "la matrice 1 par 4 rangée; colonne 1; 3, colonne 2; 6, colonne 3; 1, colonne 4; 2")?; + return Ok(()); + +} + +#[test] +fn matrix_4x4() -> Result<()> { + let expr = " + + + ( + + + + 0 + + + 3 + + + 4 + + + 3 + + + + + 2 + + + 1 + + + 0 + + + 9 + + + + + 3 + + + 0 + + + 2 + + + 1 + + + + + 6 + + + 2 + + + 9 + + + 0 + + + + ) + + "; + test("fr", "ClearSpeak", expr, "la matrice 4 par 4; \ + rangée 1; colonne 1; 0, colonne 2; 3, colonne 3; 4, colonne 4; 3; \ + rangée 2; colonne 1; 2, colonne 2; 1, colonne 3; 0, colonne 4; 9; \ + rangée 3; colonne 1; 3, colonne 2; 0, colonne 3; 2, colonne 4; 1; \ + rangée 4; colonne 1; 6, colonne 2; 2, colonne 3; 9, colonne 4; 0")?; + test("fr", "SimpleSpeak", expr, "la matrice 4 par 4; \ + rangée 1; colonne 1; 0, colonne 2; 3, colonne 3; 4, colonne 4; 3; \ + rangée 2; colonne 1; 2, colonne 2; 1, colonne 3; 0, colonne 4; 9; \ + rangée 3; colonne 1; 3, colonne 2; 0, colonne 3; 2, colonne 4; 1; \ + rangée 4; colonne 1; 6, colonne 2; 2, colonne 3; 9, colonne 4; 0")?; + return Ok(()); +} + +#[test] +fn matrix_4x2() -> Result<()> { + let expr = " + + + ( + + + + 1 + + + 3 + + + + + 4 + + + 2 + + + + + 2 + + + 1 + + + + + 0 + + + 5 + + + + + ) + + "; + test("fr", "ClearSpeak", expr, "la matrice 4 par 2; \ + rangée 1; colonne 1; 1, colonne 2; 3; \ + rangée 2; colonne 1; 4, colonne 2; 2; \ + rangée 3; colonne 1; 2, colonne 2; 1; \ + rangée 4; colonne 1; 0, colonne 2; 5\ + ")?; + test("fr", "SimpleSpeak", expr, "la matrice 4 par 2; \ + rangée 1; colonne 1; 1, colonne 2; 3; \ + rangée 2; colonne 1; 4, colonne 2; 2; \ + rangée 3; colonne 1; 2, colonne 2; 1; \ + rangée 4; colonne 1; 0, colonne 2; 5\ + ")?; + return Ok(()); +} + +// put absolue value test here since it is related to determinate and is small for its own file +#[test] +fn simple_absolute_value() -> Result<()> { + let expr = " + | x | + "; + test("fr", "SimpleSpeak", expr, "la valeur absolue de x")?; + test("fr", "ClearSpeak", expr, "la valeur absolue de x")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse"), ("ClearSpeak_AbsoluteValue", "Auto")], expr, "valeur absolue de x")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_AbsoluteValue", "AbsEnd")], + expr, "la valeur absolue de x, fin valeur absolue")?; + return Ok(()); +} + +#[test] +fn absolute_value_plus_1() -> Result<()> { +let expr = " + | + x+1 + | + "; + test("fr", "ClearSpeak", expr, "la valeur absolue de x plus 1")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse"), ("ClearSpeak_AbsoluteValue", "AbsEnd")], + expr, "valeur absolue de x plus 1, fin valeur absolue")?; + return Ok(()); +} + +#[test] +fn simple_cardinality_value() -> Result<()> { + let expr = " + | S | + "; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_AbsoluteValue", "Cardinality")], expr, + "la cardinalité de s majuscule")?; + return Ok(()); +} + +// Test preferences +#[test] +fn simple_matrix_speak_col_num() -> Result<()> { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("fr", "ClearSpeak_Matrix", "SpeakColNum", + expr, "la matrice 2 par 2; rangée 1; colonne 1; 2, colonne 2; 1; rangée 2; colonne 1; 7, colonne 2; 5")?; + return Ok(()); +} + +#[test] +fn col_matrix_3x1_speak_col_num() -> Result<()> { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "SpeakColNum", + expr, "la matrice 3 par 1 colonne; rangée 1; 1; rangée 2; 2; rangée 3; 3")?; + return Ok(()); +} + +#[test] +fn row_matrix_1x2_speak_col_num() -> Result<()> { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "SpeakColNum", + expr, "la matrice 1 par 2 rangée; colonne 1; 1, colonne 2; 2")?; + return Ok(()); +} + +#[test] +fn matrix_2x2_speak_col_num() -> Result<()> { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "SpeakColNum", + expr, "la matrice 2 par 2; rangée 1; colonne 1; b indice 1 1; colonne 2; b indice 1 2; \ + rangée 2; colonne 1; b indice 2 1; colonne 2; b indice 2 2")?; + return Ok(()); +} + + +#[test] +fn simple_matrix_silent_col_num() -> Result<()> { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("fr", "ClearSpeak_Matrix", "SilentColNum", + expr, "la matrice 2 par 2; rangée 1; 2, 1; rangée 2; 7, 5")?; + return Ok(()); +} + +#[test] +fn col_matrix_3x1_silent_col_num() -> Result<()> { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "SilentColNum", + expr, "la matrice 3 par 1 colonne; 1; 2; 3")?; + return Ok(()); +} + +#[test] +fn row_matrix_1x2_silent_col_num() -> Result<()> { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "SilentColNum", + expr, "la matrice 1 par 2 rangée; 1, 2")?; + return Ok(()); +} + +#[test] +fn matrix_2x2_silent_col_num() -> Result<()> { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "SilentColNum", + expr, "la matrice 2 par 2; rangée 1; b indice 1 1; b indice 1 2; \ + rangée 2; b indice 2 1; b indice 2 2")?; + return Ok(()); + } + + +#[test] +fn simple_matrix_end_matrix() -> Result<()> { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("fr", "ClearSpeak_Matrix", "EndMatrix", + expr, "la matrice 2 par 2; rangée 1; 2, 1; rangée 2; 7, 5; fin matrice")?; + return Ok(()); + } + +#[test] +fn col_matrix_3x1_end_matrix() -> Result<()> { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "EndMatrix", + expr, "la matrice 3 par 1 colonne; 1; 2; 3; fin matrice")?; + return Ok(()); + } + +#[test] +fn row_matrix_1x2_end_matrix() -> Result<()> { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "EndMatrix", + expr, "la matrice 1 par 2 rangée; 1, 2; fin matrice")?; + return Ok(()); + } + +#[test] +fn matrix_2x2_end_matrix() -> Result<()> { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "EndMatrix", + expr, "la matrice 2 par 2; rangée 1; colonne 1; b indice 1 1; colonne 2; b indice 1 2; \ + rangée 2; colonne 1; b indice 2 1; colonne 2; b indice 2 2; fin matrice")?; + return Ok(()); + } + + +#[test] +fn simple_matrix_vector() -> Result<()> { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("fr", "ClearSpeak_Matrix", "Vector", + expr, "la matrice 2 par 2; rangée 1; 2, 1; rangée 2; 7, 5")?; + return Ok(()); + } + +#[test] +fn col_matrix_3x1_vector() -> Result<()> { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "Vector", + expr, "le vecteur 3 par 1 colonne; 1; 2; 3")?; + return Ok(()); + } + +#[test] +fn row_matrix_1x2_vector() -> Result<()> { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "Vector", + expr, "le vecteur 1 par 2 rangée; 1, 2")?; + return Ok(()); + } + +#[test] +fn matrix_2x2_vector() -> Result<()> { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "Vector", + expr, "la matrice 2 par 2; rangée 1; colonne 1; b indice 1 1; colonne 2; b indice 1 2; \ + rangée 2; colonne 1; b indice 2 1; colonne 2; b indice 2 2")?; + return Ok(()); + } + + +#[test] +fn simple_matrix_end_vector() -> Result<()> { +let expr = " + + ( + + + + 2 + 1 + + + 7 + 5 + + + ) + "; + test_ClearSpeak("fr", "ClearSpeak_Matrix", "EndVector", + expr, "la matrice 2 par 2; rangée 1; 2, 1; rangée 2; 7, 5; fin matrice")?; + return Ok(()); + } + +#[test] +fn col_matrix_3x1_end_vector() -> Result<()> { +let expr = " + + ( + + + + 1 + + + 2 + + + 3 + + + ) + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "EndVector", + expr, "le vecteur 3 par 1 colonne; 1; 2; 3; fin vecteur")?; + return Ok(()); + } + +#[test] +fn row_matrix_1x2_end_vector() -> Result<()> { +let expr = " + + [ + + + + 1 2 + + + ] + "; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "EndVector", + expr, "le vecteur 1 par 2 rangée; 1, 2; fin vecteur")?; + return Ok(()); + } + +#[test] +fn matrix_2x2_end_vector() -> Result<()> { +let expr = "( + + + b11 + b12 + + + b21 + b22 + + + )"; +test_ClearSpeak("fr", "ClearSpeak_Matrix", "EndVector", + expr, "la matrice 2 par 2; rangée 1; colonne 1; b indice 1 1; colonne 2; b indice 1 2; \ + rangée 2; colonne 1; b indice 2 1; colonne 2; b indice 2 2; fin matrice")?; + return Ok(()); + } + + + +#[test] +fn matrix_binomial() -> Result<()> { + let expr = " + ( + 32 + ) + "; + test_ClearSpeak("fr", "ClearSpeak_Matrix", "Combinatorics", expr, "3 parmi 2")?; + return Ok(()); + } + +#[test] +fn matrix_times() -> Result<()> { + let expr = " + 1234 + abcd + "; + test("fr", "SimpleSpeak", expr, + "la matrice 2 par 2; rangée 1; 1, 2; rangée 2; 3, 4; fois; la matrice 2 par 2; rangée 1; a, b; rangée 2; c, d")?; + return Ok(()); + } + +#[test] +fn unknown_mtable_property() -> Result<()> { + let expr = " + + + + a + + + = + + + + b + + + c + + d + + + + + + + + + + e + + f + + + + "; + test("fr", "ClearSpeak", expr, + "2 lignes; ligne 1; a est égal à, b plus c moins d; ligne 2; plus e moins f")?; + return Ok(()); + } + + +#[test] +fn zero_matrix() -> Result<()> { + let expr = " + [ + + 00 + 00 + + ] + "; + test("fr", "SimpleSpeak", expr, + "la matrice zéro 2 par 2")?; + return Ok(()); + } + +#[test] +fn identity_matrix() -> Result<()> { + let expr = " + ( + + 100 + 010 + 001 + + ) + "; + test("fr", "SimpleSpeak", expr, + "la matrice identité 3 par 3")?; + return Ok(()); + } + +#[test] +fn identity_matrix_false_positive_negative_one() -> Result<()> { + let expr = " + [ + + 10 + 0-1 + + ] + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "la matrice diagonale 2 par 2; colonne 1; 1; colonne 2; moins 1")?; + Ok(()) +} + +#[test] +fn identity_matrix_false_positive_zero_diagonal() -> Result<()> { + let expr = " + [ + + 10 + 00 + + ] + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "la matrice diagonale 2 par 2; colonne 1; 1")?; + Ok(()) +} + +#[test] +fn diagonal_matrix() -> Result<()> { + let expr = " + ( + + 200 + 010 + 00x2 + + ) + "; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "la matrice diagonale 3 par 3; colonne 1; 2; colonne 2; 1; colonne 3; x au carré")?; + // test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], + // expr, "the 3 par 3 diagonal matrice; rangée 1, colonne 1, 2; rangée 2, colonne 2, 1; rangée 3, colonne 3, x squared"); + return Ok(()); + } + +#[test] +fn single_line_with_label() -> Result<()> { + let expr = r#" + + + (2) + 𝑏 = 2 + + + "#; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], + expr, "1 ligne, avec étiquette 2; b égale 2")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "1 équation, avec étiquette 2; b égale 2")?; + return Ok(()); + } From 85b6ed8a7c52ad92ce7dd2dba5daff464e3c9d07 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Mon, 25 May 2026 17:13:14 -0400 Subject: [PATCH 25/31] corrections for tests shared.rs --- Rules/Languages/fr/SharedRules/calculus.yaml | 2 +- Rules/Languages/fr/SharedRules/default.yaml | 77 ++++++++++++++++++++ Rules/Languages/fr/definitions.yaml | 2 +- Rules/Languages/fr/unicode-full.yaml | 4 +- Rules/Languages/fr/unicode.yaml | 8 +- tests/Languages/fr/shared.rs | 70 +++++++++--------- 6 files changed, 121 insertions(+), 42 deletions(-) diff --git a/Rules/Languages/fr/SharedRules/calculus.yaml b/Rules/Languages/fr/SharedRules/calculus.yaml index 0ee458987..894d9481b 100644 --- a/Rules/Languages/fr/SharedRules/calculus.yaml +++ b/Rules/Languages/fr/SharedRules/calculus.yaml @@ -49,7 +49,7 @@ - test: if: "$Verbosity!='Terse'" then: [t: "gradient de"] - else: [t: "del"] + else: [t: "grad"] - test: if: "not(IsNode(*[1], 'leaf'))" then: [pause: short] diff --git a/Rules/Languages/fr/SharedRules/default.yaml b/Rules/Languages/fr/SharedRules/default.yaml index 374e36dc1..0b2cf89e8 100644 --- a/Rules/Languages/fr/SharedRules/default.yaml +++ b/Rules/Languages/fr/SharedRules/default.yaml @@ -277,6 +277,29 @@ then: - x: "$PreSuperscript" - x: "$Prescripts[2]" + - pause: short + - test: + if: "count($Prescripts) > 2" + then: + - test: + if: "not($Prescripts[3][self::m:none])" + then: + - x: "$PreSubscript" + - x: "$Prescripts[3]" + - test: + if: "not($Prescripts[3][self::m:none] or $Prescripts[4][self::m:none])" + then: [t: "et"] + - test: + if: "not($Prescripts[4][self::m:none])" + then: + - x: "$PreSuperscript" + - x: "$Prescripts[4]" + - test: + if: "count($Prescripts) > 4" + then: + - t: "et préscripts alternés" + - x: "$Prescripts[position() > 4]" + - t: "fin préscripts" - test: if: "$Postscripts" then: @@ -308,6 +331,60 @@ then: - x: "$PostSuperscript" - x: "$Postscripts[2]" + - test: + if: "count($Postscripts) > 2" + then: + - test: + if: "not($Postscripts[3][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[3]" + - test: + if: "not($Postscripts[3][self::m:none] or $Postscripts[4][self::m:none])" + then: [t: "et"] + - test: + if: "not($Postscripts[4][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[4]" + - test: + if: "count($Postscripts) > 4" + then: + - test: + if: "not($Postscripts[5][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[5]" + - test: + if: "not($Postscripts[5][self::m:none] or $Postscripts[6][self::m:none])" + then: [t: "et"] + - test: + if: "not($Postscripts[6][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[6]" + - test: + if: "count($Postscripts) > 6" + then: + - test: + if: "not($Postscripts[7][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[7]" + - test: + if: "not($Postscripts[7][self::m:none] or $Postscripts[8][self::m:none])" + then: [t: "et"] + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[8]" + - test: + if: "count($Postscripts) > 8" + then: + - t: "et scripts alternés" + - x: "$Postscripts[position() > 8]" + - t: "fin scripts" - name: default tag: mtable diff --git a/Rules/Languages/fr/definitions.yaml b/Rules/Languages/fr/definitions.yaml index 4708dcee0..39fd461ec 100644 --- a/Rules/Languages/fr/definitions.yaml +++ b/Rules/Languages/fr/definitions.yaml @@ -46,7 +46,7 @@ "divergence": "function= ; div: divergence: divergence; fin de divergence", "curl": "function= ; rotationnel: rotationnel: rotationnel; fin du rotationnel", - "gradient": "function= ; del: gradient: gradient; fin de gradient", + "gradient": "function= ; grad: gradient: gradient; fin de gradient", "laplacian": "function=laplacien", "chemistry-concentration": "function= ; concentration: concentration de: la concentration de; fin de concentration", diff --git a/Rules/Languages/fr/unicode-full.yaml b/Rules/Languages/fr/unicode-full.yaml index 0d02115d3..d0f65adb5 100644 --- a/Rules/Languages/fr/unicode-full.yaml +++ b/Rules/Languages/fr/unicode-full.yaml @@ -3801,14 +3801,14 @@ - if: "$SpeechStyle != 'ClearSpeak'" then_test: if: "$DefaultToGiven" - then: [t: "donné"] # (en: 'given', DeepL translation) + then: [t: "sachant"] # (en: 'given', DeepL translation) else: [t: "barre verticale"] # (en: 'vertical line', DeepL: 'ligne verticale') - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" then: [t: "ligne verticale"] # (en: 'vertical line', DeepL translation) - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" then: [t: "tel que"] # (en: 'such that', DeepL translation) - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [t: "donné"] # (en: 'given', DeepL translation) + then: [t: "sachant"] # (en: 'given', DeepL translation) - else: [t: "barre verticale"] # (en: 'divides', DeepL: 'divise') - "~": [t: "tilde"] # 0xff5e - "¬": [t: "négation"] # 0xffe2 (en: 'not', DeepL: 'non') diff --git a/Rules/Languages/fr/unicode.yaml b/Rules/Languages/fr/unicode.yaml index b12a50781..d305de42a 100644 --- a/Rules/Languages/fr/unicode.yaml +++ b/Rules/Languages/fr/unicode.yaml @@ -158,7 +158,7 @@ - else_if: "$SpeechStyle != 'ClearSpeak'" then_test: - if: "$DefaultToGiven" - then: [t: "donné"] # (en: 'given', DeepL translation) + then: [t: "sachant"] # (en: 'given', DeepL translation) - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" then: [t: "divise"] # (en: 'divides', DeepL translation) @@ -168,7 +168,7 @@ - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" then: [t: "tel que"] # (en: 'such that', DeepL translation) - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [t: "donné"] # (en: 'given', DeepL translation) + then: [t: "sachant"] # (en: 'given', DeepL translation) - else: [t: "divise"] # (en: 'divides') - "}": # 0x7d @@ -205,7 +205,7 @@ else: [t: "multiplié par"] # (en: 'cross') else_test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "multiplié par"] # (en: 'cross', DeepL translation) + then: [t: "croix"] # (en: 'cross', DeepL translation) else: [t: "multiplié par"] # (en: 'times') - "÷": [t: "divisé par"] # 0xf7 (en: 'divided by') @@ -332,7 +332,7 @@ - "→": # 0x2192 - test: if: "ancestor::*[2][self::m:limit]" - then: [t: "approches"] # (en: 'approaches', DeepL translation) + then: [t: "approche"] # (en: 'approaches', DeepL translation) else: [t: "flèche vers la droite"] # (en: 'right arrow', MathPlayer: 'flèche vers la droite') - "↓": [t: "flèche vers le bas"] # 0x2193 (en: 'downwards arrow') diff --git a/tests/Languages/fr/shared.rs b/tests/Languages/fr/shared.rs index ca0c79066..204c00494 100644 --- a/tests/Languages/fr/shared.rs +++ b/tests/Languages/fr/shared.rs @@ -21,7 +21,7 @@ fn modified_vars() -> Result<()> { x ^ + t "; - test("fr", "SimpleSpeak", expr, "a accent grave, b tilde, c diacritique brève; b diacritique caron; c accent grave; plus r caron plus; x point, y point en chef; z tréma; u V diacritique trois points en chef; v W diacritique quatre points en chef; plus x chapeau, plus vecteur t")?; + test("fr", "SimpleSpeak", expr, "a accent grave, b tilde, c diacritique brève; b diacritique caron; c accent grave; plus r caron plus; x point, y point en chef; z tréma; u V diacritique trois points en chef; v W diacritique quatre points en chef; plus x accent circonflexe; plus vecteur t")?; Ok(()) } @@ -90,7 +90,7 @@ fn binomial_subscript() -> Result<()> { // C_{n,k} #[test] fn permutation_mmultiscripts() -> Result<()> { let expr = "Pkn"; - test("fr", "SimpleSpeak", expr, "n pochhammer k")?; + test("fr", "SimpleSpeak", expr, "k permutations de n")?; Ok(()) } @@ -98,7 +98,7 @@ fn permutation_mmultiscripts() -> Result<()> { #[test] fn permutation_mmultiscripts_sup() -> Result<()> { let expr = "Pkn"; - test("fr", "SimpleSpeak", expr, "n pochhammer k")?; + test("fr", "SimpleSpeak", expr, "k permutations de n")?; Ok(()) } @@ -106,7 +106,7 @@ fn permutation_mmultiscripts_sup() -> Result<()> { #[test] fn permutation_msubsup() -> Result<()> { let expr = "Pkn"; - test("fr", "SimpleSpeak", expr, "n pochhammer k")?; + test("fr", "SimpleSpeak", expr, "k permutations de n")?; Ok(()) } @@ -116,8 +116,8 @@ fn tensor_mmultiscripts() -> Result<()> { let expr = " R i j k l "; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "majuscule r avec 4 postscripts, indice i")?; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "majuscule r avec 4 postscripts, indice i")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "r majuscule avec 4 postscripts, indice i exposant j indice k indice l")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "r majuscule avec 4 postscripts, indice i exposant j indice k indice l")?; Ok(()) } @@ -128,7 +128,8 @@ fn huge_num_mmultiscripts() -> Result<()> { R i j k l m I J K L "; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "majuscule r avec 4 préscripts, pré-indice majuscule i et avec 5 postscripts, indice i")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "r majuscule avec 4 préscripts, pré-indice i majuscule, pré-exposant j majuscule et préscripts alternés k majuscule none l majuscule none fin préscripts et avec 5 postscripts, indice i exposant j indice k indice l et scripts alternés m none fin scripts")?; Ok(()) } @@ -144,8 +145,8 @@ fn prime() -> Result<()> { #[test] fn given() -> Result<()> { let expr = "P(A|B)"; - test("fr", "SimpleSpeak", expr, "majuscule p; parenthèse gauche, majuscule a donné majuscule b; parenthèse droite")?; - test("fr", "ClearSpeak", expr, "majuscule p; parenthèse gauche, majuscule a donné majuscule b; parenthèse droite")?; // not good, but follows the spec + test("fr", "SimpleSpeak", expr, "p majuscule; parenthèse gauche, a majuscule sachant b majuscule; parenthèse droite")?; + test("fr", "ClearSpeak", expr, "p majuscule; parenthèse gauche, a majuscule sachant b majuscule; parenthèse droite")?; // not good, but follows the spec Ok(()) } @@ -165,7 +166,7 @@ fn simple_msubsup() -> Result<()> { "; - test("fr", "ClearSpeak", expr, "x indice k, à la i-ième")?; + test("fr", "ClearSpeak", expr, "x indice k, à la i-ième puissance")?; Ok(()) } @@ -174,7 +175,7 @@ fn simple_msubsup() -> Result<()> { fn non_simple_msubsup() -> Result<()> { let expr = "ij2k"; test("fr", "SimpleSpeak", expr, "i indice j moins 2 fin d'indice, à la k-ième")?; - test("fr", "ClearSpeak", expr, "i indice j moins 2 fin d'indice, à la k-ième")?; + test("fr", "ClearSpeak", expr, "i indice j moins 2 fin d'indice, à la k-ième puissance")?; test_prefs("fr", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr, "i indice j moins 2, à la k-ième")?; Ok(()) } @@ -198,7 +199,7 @@ fn presentation_mathml_in_semantics() -> Result<()> { "; - test("fr", "ClearSpeak", expr, "x indice k, à la i-ième")?; + test("fr", "ClearSpeak", expr, "x indice k, à la i-ième puissance")?; Ok(()) } @@ -217,7 +218,7 @@ fn ignore_period() -> Result<()> { A -  and  +  et  B @@ -244,7 +245,8 @@ fn ignore_period() -> Result<()> { "; - test("fr", "SimpleSpeak", expr, "majuscule p; parenthèse gauche, majuscule a and majuscule b; parenthèse droite; est égal à; majuscule p; parenthèse gauche, majuscule a intersection majuscule b; parenthèse droite; est égal à; majuscule p de majuscule a; majuscule p de majuscule b")?; + test("fr", "SimpleSpeak", expr, + "p majuscule; parenthèse gauche, a majuscule et b majuscule; parenthèse droite; est égal à; p majuscule; parenthèse gauche, a majuscule intersection b majuscule; parenthèse droite; est égal à; p majuscule de a majuscule; p majuscule de b majuscule")?; Ok(()) } @@ -291,7 +293,7 @@ fn ignore_comma() -> Result<()> { "; - test("fr", "SimpleSpeak", expr, "phi droit de x, est égal à; c fois, e élevé à la négatif h au carré, x au carré puissance")?; + test("fr", "SimpleSpeak", expr, "phi de x est égal à; c fois, e élevé à la puissance moins h au carré, x au carré")?; Ok(()) } @@ -355,7 +357,7 @@ fn bug_199_2pi() -> Result<()> { ) "; - test("fr", "SimpleSpeak", expr, "closed open interval de 0 comma, 2 pi")?; + test("fr", "SimpleSpeak", expr, "l'intervalle fermé ouvert de 0 à 2 pi")?; Ok(()) } @@ -363,7 +365,7 @@ fn bug_199_2pi() -> Result<()> { #[test] fn caret_and_hat() -> Result<()> { let expr = "x^2+y^"; - test("fr", "SimpleSpeak", expr, "x circonflexe 2, plus y chapeau")?; + test("fr", "SimpleSpeak", expr, "x accent circonflexe 2, plus y accent circonflexe")?; Ok(()) } @@ -390,7 +392,7 @@ fn ignore_bold() -> Result<()> { - 1 "#; - test_prefs("fr", "SimpleSpeak", vec![("IgnoreBold", "false")], expr, "gras x est égal à, 2 sinus de gras t, moins 1")?; + test_prefs("fr", "SimpleSpeak", vec![("IgnoreBold", "false")], expr, "x gras est égal à, 2 sinus de t gras, moins 1")?; test_prefs("fr", "SimpleSpeak", vec![("IgnoreBold", "true")], expr, "x est égal à, 2 sinus de t, moins 1")?; Ok(()) } @@ -407,8 +409,8 @@ fn mn_with_block_and_decimal_separators() -> Result<()> { #[test] fn divergence() -> Result<()> { let expr = "·F"; // may want to change this for another language - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "div majuscule f")?; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "divergence de majuscule f")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "div f majuscule")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "divergence de f majuscule")?; Ok(()) } @@ -417,8 +419,8 @@ fn divergence() -> Result<()> { fn curl() -> Result<()> { let expr = "×F"; // may want to change this for another language - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "rotationnel majuscule f")?; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "rotationnel de majuscule f")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "rotationnel f majuscule")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "rotationnel de f majuscule")?; Ok(()) } @@ -427,8 +429,8 @@ fn curl() -> Result<()> { fn gradient() -> Result<()> { let expr = "F"; // may want to change this for another language - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "del majuscule f")?; - test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "gradient de majuscule f")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "grad f majuscule")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "gradient de f majuscule")?; Ok(()) } @@ -441,14 +443,14 @@ fn literal_speak_perpendicular() -> Result<()> { A - + B "#; - test("fr", "LiteralSpeak", expr, "majuscule a flèche droite, perpendicular to, majuscule b flèche droite")?; + test("fr", "LiteralSpeak", expr, "a majuscule flèche vers la droite, perpendiculaire à, b majuscule flèche vers la droite")?; Ok(()) } @@ -468,14 +470,14 @@ fn literal_speak_chars() -> Result<()> { "#; - test("fr", "LiteralSpeak", expr, "ligne verticale; x croix, y point z barre oblique 2; plus a; double ligne verticale, b plus x factorielle; ligne verticale")?; + test("fr", "LiteralSpeak", expr, "ligne verticale; x croix, y point z barre oblique 2; plus a; double ligne verticale, b plus x point d'exclamation; ligne verticale")?; Ok(()) } // AI generated #[test] fn literal_speak_with_name() -> Result<()> { - let expr = r#" + let expr = r#" f @@ -489,7 +491,7 @@ fn literal_speak_with_name() -> Result<()> { "#; - test("fr", "LiteralSpeak", expr, "forced f, parenthèse gauche, x factorielle, parenthèse droite")?; + test("fr", "LiteralSpeak", expr, "forcé f, parenthèse gauche, x point d'exclamation, parenthèse droite")?; Ok(()) } @@ -510,7 +512,7 @@ fn literal_speak_with_property() -> Result<()> { "#; - test("fr", "LiteralSpeak", expr, "f, parenthèse gauche, x factorielle, parenthèse droite")?; + test("fr", "LiteralSpeak", expr, "f, parenthèse gauche, x point d'exclamation, parenthèse droite")?; Ok(()) } @@ -523,21 +525,21 @@ fn literal_intent_property() -> Result<()> { A - + B "#; - test("fr", "SimpleSpeak", expr, "majuscule a flèche droite, perpendicular to, majuscule b flèche droite")?; + test("fr", "SimpleSpeak", expr, "a majuscule flèche vers la droite, perpendiculaire à, b majuscule flèche vers la droite")?; Ok(()) } // AI generated #[test] fn literal_intent_property_with_name() -> Result<()> { - let expr = r#" + let expr = r#" f @@ -551,6 +553,6 @@ fn literal_intent_property_with_name() -> Result<()> { "#; - test("fr", "SimpleSpeak", expr, "forced f, parenthèse gauche, x factorielle, parenthèse droite")?; + test("fr", "SimpleSpeak", expr, "forcé f, parenthèse gauche, x point d'exclamation, parenthèse droite")?; Ok(()) } From c7aaa5b7250ceaecaddc4412836fc8286f96b233 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Mon, 25 May 2026 18:08:53 -0400 Subject: [PATCH 26/31] corrections to units.rs --- tests/Languages/fr.rs | 1 + tests/Languages/fr/units.rs | 549 ++++++++++++++++++++++++++++++++++++ 2 files changed, 550 insertions(+) create mode 100644 tests/Languages/fr/units.rs diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs index 3ba3cdfd4..eadb0d419 100644 --- a/tests/Languages/fr.rs +++ b/tests/Languages/fr.rs @@ -17,3 +17,4 @@ mod alphabets; mod chemistry; mod intent; mod mtable; +mod units; diff --git a/tests/Languages/fr/units.rs b/tests/Languages/fr/units.rs new file mode 100644 index 000000000..cb22e6002 --- /dev/null +++ b/tests/Languages/fr/units.rs @@ -0,0 +1,549 @@ +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; +use anyhow::Result; + +// The basic layout of the tests is: +// 1. Sweep through all the SI prefixes +// 2. Sweep through each group of SI units +// a) with both singular and plural without prefixes +// b) with both singular and plural with one prefix +// 3. Sweep through each group of units that don't take SI prefixes +// These are broken into chunks so it is easier to see errors, when there are errors + +#[test] +fn prefix_sweep() -> Result<()> { + let expr = r#" + Qg, + Rg, + Yg, + Zg, + Eg, + Pg, + Tg, + Gg, + Mg, + kg, + hg, + dag, + dg, + cg, + mg, + µg, + ng, + pg, + fg, + ag, + zg, + yg, + rg, + qg + "#; + test("fr", "SimpleSpeak", expr, + "quetta-grammes, virgule; \ + ronna-grammes, virgule; \ + yotta-grammes, virgule; \ + zetta-grammes, virgule, \ + exa-grammes, virgule; \ + peta-grammes, virgule; \ + tera-grammes, virgule; \ + giga-grammes, virgule; \ + mega-grammes, virgule; \ + kilo-grammes, virgule; \ + hecto-grammes, virgule; \ + déca-grammes, virgule; \ + déci-grammes, virgule; \ + centi-grammes, virgule; \ + milli-grammes, virgule; \ + micro-grammes, virgule; \ + nano-grammes, virgule; \ + pico-grammes, virgule; \ + femto-grammes, virgule; \ + atto-grammes, virgule; \ + zepto-grammes, virgule; \ + yocto-grammes, virgule; \ + ronto-grammes, virgule; \ + quecto-grammes")?; + return Ok(()); + +} + +#[test] +fn si_base() -> Result<()> { + let expr = r#" + 1A,2A, + 1cd,2cd, + 1K,2K, + 1,2, + 1g,2g, + 1m,2m, + 1mol,2mol, + 1s,2s, + 1,2, + 1",2", + 1sec,2sec + "#; + test("fr", "SimpleSpeak", expr, + "1 ampère, virgule; 2 ampères, virgule, \ + 1 candela, virgule; 2 candelas, virgule, \ + 1 kelvin, virgule; 2 kelvins, virgule, \ + 1 kelvin, virgule; 2 kelvins, virgule, \ + 1 gramme, virgule; 2 grammes, virgule, \ + 1 mètre, virgule; 2 mètres, virgule, \ + 1 mole, virgule; 2 moles, virgule, \ + 1 seconde, virgule; 2 secondes, virgule, \ + 1 seconde, virgule; 2 secondes, virgule, \ + 1 seconde, virgule; 2 secondes, virgule, \ + 1 seconde, virgule; 2 secondes")?; + return Ok(()); + +} + +#[test] +fn si_base_with_prefixes() -> Result<()> { + let expr = r#" + 1QA,2RA, + 1Ycd,2Zcd, + 1EK,2PK, + 1TK,2GK, + 1Mg,2kg, + 1hm,2dam, + 1dmol,2cmol, + 1ms,2µs, + 1nsec,2psec + "#; + test("fr", "SimpleSpeak", expr, + "1 quetta-ampère, virgule; 2 ronna-ampères; virgule; \ + 1 yotta-candela, virgule; 2 zetta-candelas; virgule; \ + 1 exa-kelvin, virgule; 2 peta-kelvins, virgule; \ + 1 tera-kelvin, virgule; 2 giga-kelvins, virgule; \ + 1 mega-gramme, virgule; 2 kilo-grammes, virgule; \ + 1 hecto-mètre, virgule; 2 déca-mètres, virgule; \ + 1 déci-mole, virgule; 2 centi-moles, virgule; \ + 1 milli-seconde, virgule; 2 micro-secondes; virgule; \ + 1 nano-seconde, virgule; 2 pico-secondes")?; + return Ok(()); + +} + + +#[test] +fn si_derived_1() -> Result<()> { + let expr = r#" + 1Bq,2Bq, + 1C,2C, + 1°C,2°C, + 1,2, + 1F,2F, + 1Gy,2Gy, + 1H,2H, + 1Hz,2Hz, + 1J,2J, + 1kat,2kat, + 1lm,2lm, + 1lx,2lx + "#; + test("fr", "SimpleSpeak", expr, + "1 becquerel, virgule; 2 becquerels, virgule, \ + 1 coulomb, virgule; 2 coulombs, virgule; \ + 1 degré Celsius, virgule; 2 degrés Celsius, virgule; \ + 1 degré Celsius, virgule; 2 degrés Celsius, virgule, \ + 1 farad, virgule; 2 farads, virgule, \ + 1 gray, virgule; 2 grays, virgule, \ + 1 henry, virgule; 2 henrys, virgule, \ + 1 hertz, virgule, 2 hertz, virgule, \ + 1 joule, virgule; 2 joules, virgule, \ + 1 katal, virgule; 2 katals, virgule, \ + 1 lumen, virgule; 2 lumens, virgule, \ + 1 lux, virgule, 2 lux")?; + return Ok(()); + +} + +#[test] +fn si_derived_1_with_prefixes() -> Result<()> { + let expr = r#" + 1QBq,2RBq, + 1YC,2ZC, + 1EF,2PF, + 1TGy,2GGy, + 1MH,2kH, + 1daHz,2dHz, + 1cJ,2mJ, + 1µkat,2nkat, + 1plm,2flm, + 1alx,2zlx, + 1m°C,2µ°C, + 1p℃,2n℃ + "#; + test("fr", "SimpleSpeak", expr, + "1 quetta-becquerel, virgule; 2 ronna-becquerels; virgule; \ + 1 yotta-coulomb, virgule; 2 zetta-coulombs; virgule; \ + 1 exa-farad, virgule; 2 peta-farads, virgule; \ + 1 tera-gray, virgule; 2 giga-grays, virgule; \ + 1 mega-henry, virgule; 2 kilo-henrys, virgule; \ + 1 déca-hertz, virgule; 2 déci-hertz, virgule; \ + 1 centi-joule, virgule; 2 milli-joules, virgule; \ + 1 micro-katal, virgule; 2 nano-katals, virgule; \ + 1 pico-lumen, virgule; 2 femto-lumens, virgule; \ + 1 atto-lux, virgule; 2 zepto-lux, virgule; \ + 1 milli-degré Celsius; virgule; 2 micro-degrés Celsius; virgule; \ + 1 pico-degré Celsius; virgule; 2 nano-degrés Celsius")?; + return Ok(()); + +} + +#[test] +fn si_derived_2() -> Result<()> { + let expr = r#" + 1N,2N, + 1Ω,2Ω, + 1,2, + 1Pa,2Pa, + 1S,2S, + 1Sv,2Sv, + 1T,2T, + 1V,2V, + 1W,2W, + 1Wb,2Wb + "#; + test("fr", "SimpleSpeak", expr, + "1 newton, virgule; 2 newtons, virgule, \ + 1 ohm, virgule; 2 ohms, virgule, \ + 1 ohm, virgule; 2 ohms, virgule, \ + 1 pascal, virgule; 2 pascals, virgule, \ + 1 siemens, virgule, 2 siemens, virgule, \ + 1 sievert, virgule; 2 sieverts, virgule, \ + 1 tesla, virgule; 2 teslas, virgule, \ + 1 volt, virgule; 2 volts, virgule, \ + 1 watt, virgule; 2 watts, virgule, \ + 1 weber, virgule; 2 webers")?; + return Ok(()); + +} + +#[test] +fn si_derived_2_with_prefixes() -> Result<()> { + let expr = r#" + 1qN,2rN, + 1,2, + 1aΩ,2fΩ, + 1pPa,2nPa, + 1µS,2mS, + 1cSv,2dSv, + 1daT,2hT, + 1kV,2MV, + 1GW,2TW, + 1PWb,2EWb + "#; + test("fr", "SimpleSpeak", expr, + "1 quecto-newton, virgule; 2 ronto-newtons, virgule; \ + 1 yocto-ohm, virgule; 2 zepto-ohms, virgule; \ + 1 atto-ohm, virgule; 2 femto-ohms, virgule; \ + 1 pico-pascal, virgule; 2 nano-pascals, virgule; \ + 1 micro-siemens, virgule; 2 milli-siemens, virgule; \ + 1 centi-sievert, virgule; 2 déci-sieverts; virgule; \ + 1 déca-tesla, virgule; 2 hecto-teslas, virgule; \ + 1 kilo-volt, virgule; 2 mega-volts, virgule; \ + 1 giga-watt, virgule; 2 tera-watts, virgule; \ + 1 peta-weber, virgule; 2 exa-webers")?; + return Ok(()); + +} + + +#[test] +fn si_accepted() -> Result<()> { + let expr = r#" + 1l,2l, + 1L,2L, + 1,2, + 1t,2t, + 1Da,2Da, + 1Np,2Np, + 1u,2u, + 1eV,2eV, + 1rad,2rad, + 1sr,2sr, + 1a,2a, + 1as,2as, + 1b,2b, + 1B,2B, + 1Bd,2Bd + "#; + test("fr", "SimpleSpeak", expr, + "1 litre, virgule; 2 litres, virgule, \ + 1 litre, virgule; 2 litres, virgule, \ + 1 litre, virgule; 2 litres, virgule; \ + 1 tonne métrique, virgule; 2 tonne métriques, virgule, \ + 1 dalton, virgule; 2 daltons, virgule, \ + 1 néper, virgule; 2 népers, virgule; \ + 1 unité de masse atomique, virgule; 2 unités de masse atomique, virgule; \ + 1 électronvolt, virgule; 2 électronvolts, virgule, \ + 1 radian, virgule; 2 radians, virgule; \ + 1 stéradian, virgule; 2 stéradians, virgule, \ + 1 année, virgule; 2 années, virgule; \ + 1 seconde d'arc, virgule; 2 secondes d'arc, virgule, \ + 1 bit, virgule; 2 bits, virgule, \ + 1 octet, virgule; 2 octets, virgule, \ + 1 baud, virgule; 2 bauds")?; + return Ok(()); + +} + +#[test] +fn si_accepted_with_prefixes() -> Result<()> { + let expr = r#" + 1Ql,2Rl, + 1YL,2ZL, + 1Eℓ,2Pℓ, + 1Tt,2Gt, + 1MDa,2kDa, + 1dNp,2cNp, + 1hu,2dau, + 1meV,2µeV, + 1nrad,2prad, + 1fsr,2asr, + 1Ga,2Ma, + 1zas,2yas, + 1kb,2Mb, + 1GB,2TB, + 1TBd,2EBd + "#; + test("fr", "SimpleSpeak", expr, + "1 quetta-litre, virgule; 2 ronna-litres, virgule; \ + 1 yotta-litre, virgule; 2 zetta-litres, virgule; \ + 1 exa-litre, virgule; 2 peta-litres, virgule; \ + 1 tera-tonne métrique; virgule; 2 giga-tonne métriques; virgule; \ + 1 mega-dalton, virgule; 2 kilo-daltons, virgule; \ + 1 déci-néper, virgule; 2 centi-népers, virgule; \ + 1, hecto-unité de masse atomique; virgule; 2, déca-unités de masse atomique; virgule; \ + 1 milli-électronvolt; virgule; 2 micro-électronvolts; virgule; \ + 1 nano-radian, virgule; 2 pico-radians, virgule; \ + 1 femto-stéradian, virgule; 2 atto-stéradians; virgule; \ + 1 giga-année, virgule; 2 mega-années, virgule; \ + 1 zepto-seconde d'arc; virgule; 2 yocto-secondes d'arc; virgule; \ + 1 kilo-bit, virgule; 2 mega-bits, virgule; \ + 1 giga-octet, virgule; 2 tera-octets, virgule; \ + 1 tera-baud, virgule; 2 exa-bauds")?; + return Ok(()); + +} + +#[test] +fn without_prefix_time() -> Result<()> { + let expr = r#" + 1,2, + 1",2", + 1,2, + 1',2', + 1min,2min, + 1h,2h, + 1hr,2hr, + 1Hr,2Hr, + 1d,2d, + 1dy,2dy, + 1w,2w, + 1wk,2wk, + 1y,2y, + 1yr,2yr + "#; + test("fr", "SimpleSpeak", expr, + "1 seconde, virgule; 2 secondes, virgule, \ + 1 seconde, virgule; 2 secondes, virgule, \ + 1 minute, virgule; 2 minutes, virgule, \ + 1 minute, virgule; 2 minutes, virgule, \ + 1 minute, virgule; 2 minutes, virgule, \ + 1 heure, virgule; 2 heures, virgule, \ + 1 heure, virgule; 2 heures, virgule, \ + 1 heure, virgule; 2 heures, virgule, \ + 1 jour, virgule; 2 jours, virgule, \ + 1 jour, virgule; 2 jours, virgule, \ + 1 semaine, virgule; 2 semaines, virgule, \ + 1 semaine, virgule; 2 semaines, virgule, \ + 1 année, virgule; 2 années, virgule, \ + 1 année, virgule; 2 années")?; + return Ok(()); + +} + +#[test] +fn without_prefix_angles() -> Result<()> { + let expr = r#" + 1°,2°, + 1deg,2deg, + 1arcmin,2arcmin, + 1amin,2amin, + 1am,2am, + 1MOA,2MOA, + 1arcsec,2arcsec, + 1asec,2asec + "#; + test("fr", "SimpleSpeak", expr, + "1 degré, virgule, 2 degrés, virgule, \ + 1 degré, virgule, 2 degrés, virgule; \ + 1 minute d'arc, virgule; 2 minutes d'arc, virgule; \ + 1 minute d'arc, virgule; 2 minutes d'arc, virgule; \ + 1 minute d'arc, virgule; 2 minutes d'arc, virgule; \ + 1 minute d'arc, virgule; 2 minutes d'arc, virgule; \ + 1 seconde d'arc, virgule; 2 secondes d'arc, virgule; \ + 1 seconde d'arc, virgule; 2 secondes d'arc")?; + return Ok(()); + +} + +#[test] +fn without_prefix_distance() -> Result<()> { + let expr = r#" + 1au,2au, + 1ltyr,2ltyr, + 1pc,2pc, + 1Å,2Å, + 1,2, + 1fm,2fm + "#; + test("fr", "SimpleSpeak", expr, + "1 unité astronomique, virgule; 2 unités astronomiques, virgule; \ + 1 année-lumière, virgule; 2 années-lumière, virgule, \ + 1 parsec, virgule; 2 parsecs, virgule; \ + 1 ångström, virgule; 2 ångströms, virgule; \ + 1 ångström, virgule; 2 ångströms, virgule, \ + 1 fermi, virgule; 2 fermis")?; + return Ok(()); + +} + +#[test] +fn without_prefix_other() -> Result<()> { + let expr = r#" + 1ha,2ha, + 1dB,2dB, + 1atm,2atm, + 1amu,2amu, + 1bar,2bar, + 1cal,2cal, + 1Ci,2Ci, + 1grad,2grad, + 1M,2M, + 1R,2R, + 1rpm,2rpm, + 1fl dr,2fl dr, + 1,2, + 1dyn,2dyn, + 1erg,2erg + "#; + test("fr", "SimpleSpeak", expr, + "1 hectare, virgule; 2 hectares, virgule; \ + 1 décibel, virgule; 2 décibels, virgule; \ + 1 atmosphère, virgule; 2 atmosphères, virgule; \ + 1 unité de masse atomique, virgule; 2 unités de masse atomique, virgule, \ + 1 bar, virgule; 2 bars, virgule, \ + 1 calorie, virgule; 2 calories, virgule, \ + 1 curie, virgule; 2 curies, virgule, \ + 1 gradian, virgule; 2 gradians, virgule, \ + 1 molaire, virgule; 2 molaires, virgule; \ + 1 roentgen, virgule; 2 roentgens, virgule; \ + 1 tour par minute, virgule; 2 tours par minute, virgule; \ + 1 dram liquide, virgule; 2 dram liquides, virgule, \ + 1 mho, virgule; 2 mhos, virgule, \ + 1 dyne, virgule; 2 dynes, virgule, \ + 1 erg, virgule; 2 ergs")?; + return Ok(()); + +} + +#[test] +fn without_prefix_powers_of_2() -> Result<()> { + let expr = r#" + 1Kib,2Kib, + 1Mib,2Mib, + 1Gib,2Gib, + 1Tib,2Tib, + 1Pib,2Pib, + 1Eib,2Eib, + 1Zib,2Zib, + 1Yib,2Yib, + 1KiB,2KiB, + 1MiB,2MiB, + 1GiB,2GiB, + 1TiB,2TiB, + 1PiB,2PiB, + 1EiB,2EiB, + 1ZiB,2ZiB, + 1YiB,2YiB + "#; + test("fr", "SimpleSpeak", expr, + "1 kibi-bit, virgule; 2 kibi-bits, virgule; \ + 1 mebi-bit, virgule; 2 mebi-bits, virgule; \ + 1 gibi-bit, virgule; 2 gibi-bits, virgule; \ + 1 tebi-bit, virgule; 2 tebi-bits, virgule; \ + 1 pebi-bit, virgule; 2 pebi-bits, virgule; \ + 1 exbi-bit, virgule; 2 exbi-bits, virgule; \ + 1 zebi-bit, virgule; 2 zebi-bits, virgule; \ + 1 yobi-bit, virgule; 2 yobi-bits, virgule; \ + 1 kibi-octet, virgule; 2 kibi-octets, virgule; \ + 1 mebi-octet, virgule; 2 mebi-octets, virgule; \ + 1 gibi-octet, virgule; 2 gibi-octets, virgule; \ + 1 tebi-octet, virgule; 2 tebi-octets, virgule; \ + 1 pebi-octet, virgule; 2 pebi-octets, virgule; \ + 1 exbi-octet, virgule; 2 exbi-octets, virgule; \ + 1 zebi-octet, virgule; 2 zebi-octets, virgule; \ + 1 yobi-octet, virgule; 2 yobi-octets")?; + return Ok(()); + +} + + +#[test] +fn si_other_numbers() -> Result<()> { + let expr = r#"1,0l, + 2,0 m, + x ms, + yµs, + dag, + 1235daN, + 2,5µsec, + 32,34mol"#; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, + "1,0 l virgule, 2,0 m virgule; x milli-secondes; virgule; y micro-secondes; virgule; déca-grammes, virgule; \ + 1235 déca-newtons; virgule; 2,5 micro-secondes; virgule; 32,34 moles")?; + test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "1,0 litres, virgule; 2,0 mètres, virgule; x milli-secondes; virgule; y micro-secondes; virgule; déca-grammes, virgule; \ + 1235 déca-newtons; virgule; 2,5 micro-secondes; virgule; 32,34 moles")?; + test_prefs("fr", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "1,0 litres, virgule; 2,0 mètres, virgule; x milli-secondes; virgule; y micro-secondes; virgule; déca-grammes, virgule; \ + 1235 déca-newtons; virgule; 2,5 micro-secondes; virgule; 32,34 moles")?; + return Ok(()); + +} + + +#[test] +fn test_mtext_inference() -> Result<()> { + let expr = r#"[ + 1t, + 2PA, + 3Pa, + 4.5mT + ]"#; + test("fr", "SimpleSpeak", expr, + "crochet ouvrant; 1 tonne métrique, virgule; 2 peta-ampères, virgule; \ + 3 pascals, virgule; 45 milli-teslas; crochet fermant")?; + return Ok(()); + +} + + #[test] + fn infer_unit() -> Result<()> { + let expr = r#" + 3m, + 1km, + 3m, + 310F, + mmin + "#; + test("fr", "SimpleSpeak", expr, + "3 mètres, virgule; 1 kilo-mètre, virgule; 3 mètres, virgule; 3 dixièmes farads, virgule; m indice min fin d'indice")?; + return Ok(()); + + } From 14e4fccf218b81ab42795abe60d0c09077231742 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Wed, 3 Jun 2026 09:13:09 -0400 Subject: [PATCH 27/31] fixed all unit tests --- tests/Languages/fr/SimpleSpeak/functions.rs | 2 +- tests/Languages/fr/chemistry.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/Languages/fr/SimpleSpeak/functions.rs b/tests/Languages/fr/SimpleSpeak/functions.rs index cd7d6cbc8..7e816f2c6 100644 --- a/tests/Languages/fr/SimpleSpeak/functions.rs +++ b/tests/Languages/fr/SimpleSpeak/functions.rs @@ -334,7 +334,7 @@ fn no_times_sqrt() -> Result<()> { [(]c,d) ) "; - test("fr", "SimpleSpeak", expr, "l'invervalle fermé ouvert fermé de c à d")?; + test("fr", "SimpleSpeak", expr, "l'intervalle fermé ouvert de c à d")?; Ok(()) } diff --git a/tests/Languages/fr/chemistry.rs b/tests/Languages/fr/chemistry.rs index 401858180..191d274d4 100644 --- a/tests/Languages/fr/chemistry.rs +++ b/tests/Languages/fr/chemistry.rs @@ -161,11 +161,11 @@ fn beta_decay() -> Result<()> { "; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], expr, - "14, 6, c majuscule; forment; 14, 7, n majuscule; plus 0, négatif 1, e")?; + "14, 6, c majuscule; forment, 14, 7, n majuscule; plus 0, moins 1, e")?; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice négatif 1, e")?; + "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice moins 1, e")?; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, - "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice négatif 1, e")?; + "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice moins 1, e")?; return Ok(()); } @@ -427,11 +427,11 @@ fn mhchem_beta_decay() -> Result<()> { "; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Terse")], expr, - "14, 6, c majuscule; forment; 14, 7, n majuscule; plus 0, négatif 1, e")?; + "14, 6, c majuscule; forment, 14, 7, n majuscule; plus 0, moins 1, e")?; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice négatif 1, e")?; + "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice moins 1, e")?; test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, - "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice négatif 1, e")?; + "exposant 14, indice 6, c majuscule; réagissent pour former; exposant 14, indice 7, n majuscule; plus, exposant 0, indice moins 1, e")?; return Ok(()); } From 730285b44fc8e903a1fdd9fa3a0b575c658b235a Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Wed, 3 Jun 2026 09:26:12 -0400 Subject: [PATCH 28/31] cleanup --- Rules/Languages/fr/definitions.yaml | 15 +++------------ tests/Languages/fr/intent.rs | 13 +++++++++++++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Rules/Languages/fr/definitions.yaml b/Rules/Languages/fr/definitions.yaml index 39fd461ec..a7f9558eb 100644 --- a/Rules/Languages/fr/definitions.yaml +++ b/Rules/Languages/fr/definitions.yaml @@ -286,31 +286,22 @@ # All definitions start 0, 10, 100, etc. -# TODO: does that belong here? (vingt-et-un, trente-et-un, etc.) - NumbersOnes: [ "zéro", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", "dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", - "dix-sept", "dix-huit", "dix-neuf", - "vingt-et-un", "trente-et-un", "quarante-et-un", "cinquante-et-un", "soixante-et-un", - "soixante-et-onze", "quatre-vingt-un", "quatre-vingt-onze" + "dix-sept", "dix-huit", "dix-neuf" ] -# TODO: does that belong here? (vingt-et-unième, trente-et-unième, etc.) - NumbersOrdinalOnes: [ "zéroième", "premier", "deuxième", "troisième", "quatrième", "cinquième", "sixième", "septième", "huitième", "neuvième", "dixième", "onzième", "douzième", "treizième", "quatorzième", "quinzième", "seizième", - "dix-septième", "dix-huitième", "dix-neuvième", - "vingt-et-unième", "trente-et-unième", "quarante-et-unième", "cinquante-et-unième", "soixante-et-unième", - "soixante-et-onzième", "quatre-vingt-unième", "quatre-vingt-onzième" + "dix-septième", "dix-huitième", "dix-neuvième" ] -# TODO: does that belong here? (vingt-et-unièmes, trente-et-unièmes, etc.) - NumbersOrdinalPluralOnes: [ "zéroièmes", "premiers", "deuxièmes", "troisièmes", "quatrièmes", "cinquièmes", "sixièmes", "septièmes", "huitièmes", "neuvièmes", "dixièmes", "onzièmes", "douzièmes", "treizièmes", "quatorzièmes", "quinzièmes", "seizièmes", - "dix-septièmes", "dix-huitièmes", "dix-neuvièmes", - "vingt-et-unièmes", "trente-et-unièmes", "quarante-et-unièmes", "cinquante-et-unièmes", "soixante-et-unièmes", - "soixante-et-onzièmes", "quatre-vingt-unièmes", "quatre-vingt-onzièmes" + "dix-septièmes", "dix-huitièmes", "dix-neuvièmes" ] - NumbersOrdinalFractionalOnes: [ diff --git a/tests/Languages/fr/intent.rs b/tests/Languages/fr/intent.rs index caf2abd10..e73fa4222 100644 --- a/tests/Languages/fr/intent.rs +++ b/tests/Languages/fr/intent.rs @@ -142,3 +142,16 @@ fn intent_prob_x() -> Result<()> { return Ok(()); } + +#[test] +fn do_some_stuff_71() -> Result<()> { + let expr = " + + 41 + + + 71 + + "; + test("fr", "SimpleSpeak", expr, "quarante et un plus soixante et onze") + +} From 16ddbc5b169d55e7ab04442532ced574e8b4254f Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Wed, 3 Jun 2026 09:27:15 -0400 Subject: [PATCH 29/31] more cleanup --- tests/Languages/fr/intent.rs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/tests/Languages/fr/intent.rs b/tests/Languages/fr/intent.rs index e73fa4222..1fa7bcb4b 100644 --- a/tests/Languages/fr/intent.rs +++ b/tests/Languages/fr/intent.rs @@ -141,17 +141,4 @@ fn intent_prob_x() -> Result<()> { test("fr", "ClearSpeak", expr, "probabilité de x")?; return Ok(()); -} - -#[test] -fn do_some_stuff_71() -> Result<()> { - let expr = " - - 41 - + - 71 - - "; - test("fr", "SimpleSpeak", expr, "quarante et un plus soixante et onze") - -} +} \ No newline at end of file From 8be4ab15f724e8bf672d99601c7a44088f9500c0 Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Thu, 4 Jun 2026 10:16:01 -0400 Subject: [PATCH 30/31] finalized rules, replaced t: -> T:, ct: -> CT:, ot: -> OT, spell: -> SPELL: --- Rules/Languages/fr/ClearSpeak_Rules.yaml | 212 ++++---- Rules/Languages/fr/SharedRules/calculus.yaml | 16 +- Rules/Languages/fr/SharedRules/default.yaml | 184 +++---- Rules/Languages/fr/SharedRules/general.yaml | 394 +++++++------- Rules/Languages/fr/SharedRules/geometry.yaml | 30 +- .../fr/SharedRules/linear-algebra.yaml | 14 +- Rules/Languages/fr/SimpleSpeak_Rules.yaml | 70 +-- Rules/Languages/fr/overview.yaml | 34 +- Rules/Languages/fr/unicode.yaml | 498 +++++++++--------- 9 files changed, 726 insertions(+), 726 deletions(-) diff --git a/Rules/Languages/fr/ClearSpeak_Rules.yaml b/Rules/Languages/fr/ClearSpeak_Rules.yaml index 6dc24be3f..18e9cd916 100644 --- a/Rules/Languages/fr/ClearSpeak_Rules.yaml +++ b/Rules/Languages/fr/ClearSpeak_Rules.yaml @@ -25,7 +25,7 @@ tag: mn match: "starts-with(text(), '-')" replace: - - t: "moins" # phrase(10 'minus' 4 equals 6) + - T: "moins" # phrase(10 'minus' 4 equals 6) - x: "translate(text(), '-_', '')" - name: default @@ -34,26 +34,26 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "la"] # phrase('the' square root of 25) + then: [T: "la"] # phrase('the' square root of 25) - test: if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" then: - bookmark: "*[1]/@id" - test: if: "parent::*[self::m:minus and count(*)=1]" - then: [t: "négatif"] # phrase(minus 4 is a 'negative' number) - else: [t: "positif"] # phrase(10 is a 'positive' number) - - t: "racine carrée" # phrase(8 is the 'square root' of 64) + then: [T: "négatif"] # phrase(minus 4 is a 'negative' number) + else: [T: "positif"] # phrase(10 is a 'positive' number) + - T: "racine carrée" # phrase(8 is the 'square root' of 64) - test: if: "$Verbosity!='Terse'" - then: [t: "de"] # phrase(the square root 'of' 5) + then: [T: "de"] # phrase(the square root 'of' 5) else: [pause: short] - x: "*[1]" - test: - if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" then: - pause: short - - t: "fin de racine" # phrase(the square root of x 'end root') + - T: "fin de racine" # phrase(the square root of x 'end root') - pause: medium - else_if: "IsNode(*[1], 'simple')" then: [pause: short] @@ -65,7 +65,7 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "la"] # phrase(6 is 'the' square root of 36) + then: [T: "la"] # phrase(6 is 'the' square root of 36) - test: if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" then: @@ -74,16 +74,16 @@ then: [bookmark: "parent/@id"] - test: if: "parent::m:minus" - then: [t: "négatif"] # phrase(minus 6 is a 'negative' number) - else: [t: "positif"] # phrase(10 is a 'positive' number) + then: [T: "négatif"] # phrase(minus 6 is a 'negative' number) + else: [T: "positif"] # phrase(10 is a 'positive' number) - test: if: "*[2][self::m:mn and not(contains(., '.'))]" then_test: - if: "*[2][.='2']" - then: [t: "racine carrée"] # phrase(5 is the 'square root' of 25) + then: [T: "racine carrée"] # phrase(5 is the 'square root' of 25) - else_if: "*[2][.='3']" - then: [t: "racine cubique"] # phrase(5 is the 'cube root' of 625) - - else: [x: "ToOrdinal(*[2])", t: "racine"] # phrase(the square 'root' of 25) + then: [T: "racine cubique"] # phrase(5 is the 'cube root' of 625) + - else: [x: "ToOrdinal(*[2])", T: "racine"] # phrase(the square 'root' of 25) else: - test: if: "*[2][self::m:mi][string-length(.)=1]" @@ -91,16 +91,16 @@ - x: "*[2]" - pronounce: [text: "-ième", ipa: "jɛm", sapi5: "ieme", eloquence: "ieme"] else: [x: "*[2]"] - - t: "racine" # phrase(the square 'root' of 36) + - T: "racine" # phrase(the square 'root' of 36) - test: if: "$Verbosity!='Terse'" - then: [t: "de"] # phrase(the square root 'of' 36) + then: [T: "de"] # phrase(the square root 'of' 36) - x: "*[1]" - test: if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" then: - pause: short - - t: "fin de racine" # phrase(start the fifth root of x 'end root') + - T: "fin de racine" # phrase(start the fifth root of x 'end root') - pause: medium else_test: if: "IsNode(*[1], 'simple')" @@ -116,13 +116,13 @@ if: - "*[1][self::m:square-root or self::m:root] and" - "($ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd')" - then: [t: ""] + then: [T: ""] else: - bookmark: "@id" - test: if: "self::m:minus" - then: [t: "moins"] - else: [t: "plus"] + then: [T: "moins"] + else: [T: "plus"] - x: "*[1]" # Fraction rules @@ -139,7 +139,7 @@ - " BaseNode(*[2])[contains(@data-intent-property, ':unit')] )" replace: - x: "*[1]" - - t: "par" # phrase('5 meters 'per' second) + - T: "par" # phrase('5 meters 'per' second) - x: "*[2]" - name: common-fraction @@ -165,17 +165,17 @@ then: - test: if: "$Verbosity!='Terse'" - then: [ot: "la"] - - t: "fraction" # phrase(the 'fraction' with 3 over 4) + then: [OT: "la"] + - T: "fraction" # phrase(the 'fraction' with 3 over 4) - x: "*[1]" - - t: "sur" # phrase(the fraction 3 'over' 4) + - T: "sur" # phrase(the fraction 3 'over' 4) - x: "*[2]" - test: # very ugly!!! -- replicate nested ordinal fraction as they are an exception if: "$ClearSpeak_Fractions='OverEndFrac' or ($ClearSpeak_Fractions='EndFrac' and not( ($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and *[1][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] and *[2][*[1][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and *[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))] ] ) )" then: - pause: short - - t: "fin de fraction" # phrase(7 over 8 'end fraction') + - T: "fin de fraction" # phrase(7 over 8 'end fraction') - pause: short - # fraction with text or numbers followed by text in both numerator and denominator @@ -197,34 +197,34 @@ - ")" replace: - x: "*[1]" - - t: "sur" # phrase(the fraction 3 'over' 4) + - T: "sur" # phrase(the fraction 3 'over' 4) - x: "*[2]" - test: if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='OverEndFrac'" then: - pause: short - - t: "fin de fraction" # phrase(7 over 8 'end fraction') + - T: "fin de fraction" # phrase(7 over 8 'end fraction') - pause: short - name: default tag: fraction match: "." replace: - - ot: "la" # phrase(5 is 'the' square root of 25) - - t: "fraction avec numérateur" # phrase(the 'fraction with numerator' 6) + - OT: "la" # phrase(5 is 'the' square root of 25) + - T: "fraction avec numérateur" # phrase(the 'fraction with numerator' 6) - test: if: "not(IsNode(*[1], 'simple'))" then: [pause: medium] - x: "*[1]" - pause: medium - - t: "et dénominateur" # phrase(the fraction with numerator 5 'and denominator' 8) + - T: "et dénominateur" # phrase(the fraction with numerator 5 'and denominator' 8) - x: "*[2]" - pause: long - test: if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='GeneralEndFrac'" then: - pause: short - - t: "fin de fraction" # phrase(the fraction with 3 over 4 'end fraction') + - T: "fin de fraction" # phrase(the fraction with 3 over 4 'end fraction') - pause: short # rules for functions raised to a power @@ -236,11 +236,11 @@ replace: - test: if: "$ClearSpeak_Trig = 'TrigInverse'" - then: [x: "*[1]", bookmark: "*[2]/@id", t: "l'inverse"] # phrase(8 over 5 is the 'inverse' of 5 over 8) + then: [x: "*[1]", bookmark: "*[2]/@id", T: "l'inverse"] # phrase(8 over 5 is the 'inverse' of 5 over 8) else_test: if: "$ClearSpeak_Trig = 'ArcTrig'" - then: [bookmark: "*[2]/@id", t: "arc", x: "*[1]"] # phrase(the 'arc' of a circle) - else: [bookmark: "*[2]/@id", t: "l'inverse", x: "*[1]"] # default/Auto # phrase(8 over 5 is the 'inverse' of 5 over 8) + then: [bookmark: "*[2]/@id", T: "arc", x: "*[1]"] # phrase(the 'arc' of a circle) + else: [bookmark: "*[2]/@id", T: "l'inverse", x: "*[1]"] # default/Auto # phrase(8 over 5 is the 'inverse' of 5 over 8) - name: function-squared-or-cubed tag: power @@ -252,8 +252,8 @@ - bookmark: "*[2]/@id" - test: if: "*[2][.='2']" - then: [t: "au carré"] # phrase(25 equals 5 'squared') - else: [t: "au cube"] # phrase(625 equals 5 'cubed') + then: [T: "au carré"] # phrase(25 equals 5 'squared') + else: [T: "au cube"] # phrase(625 equals 5 'cubed') - name: function-power tag: power @@ -262,13 +262,13 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "la"] # phrase('the' third power of 2) + then: [T: "la"] # phrase('the' third power of 2) - bookmark: "*[2]/@id" - test: if: "*[2][self::m:mn][not(contains(., '.'))]" then: [x: "ToOrdinal(*[2])"] else: [x: "*[2]"] - - t: "puissance de" # phrase(the third 'power of' 6) + - T: "puissance de" # phrase(the third 'power of' 6) - pause: short - x: "*[1]" @@ -279,18 +279,18 @@ - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" replace: - x: "*[1]" - - t: "à la puissance de" # phrase(5 'raised to the exponent' x plus 1) + - T: "à la puissance de" # phrase(5 'raised to the exponent' x plus 1) - pause: short - x: "*[2]" - pause: short - - t: "fin de l'exposant" # phrase(5 raised to the exponent x plus 1 'end exponent') + - T: "fin de l'exposant" # phrase(5 raised to the exponent x plus 1 'end exponent') - name: AfterPower-default tag: power match: "$ClearSpeak_Exponents = 'AfterPower'" replace: - x: "*[1]" - - t: "à la puissance de" # phrase(x is 'raised to the power' 4) + - T: "à la puissance de" # phrase(x is 'raised to the power' 4) - x: "*[2]" - pause: short @@ -300,7 +300,7 @@ replace: - x: "*[1]" - bookmark: "*[2]/@id" - - t: "au carré" # phrase(7 'squared' equals 49) + - T: "au carré" # phrase(7 'squared' equals 49) - name: cubed tag: power @@ -308,21 +308,21 @@ replace: - x: "*[1]" - bookmark: "*[2]/@id" - - t: "au cube" # phrase(5 'cubed' equals 125) + - T: "au cube" # phrase(5 'cubed' equals 125) - name: simple-integer tag: power match: "*[2][self::m:mn][not(contains(., '.'))]" replace: - x: "*[1]" - - t: "à la" # phrase(2 raised 'to the' power 7) + - T: "à la" # phrase(2 raised 'to the' power 7) - test: if: "*[2][.>0]" then: [x: "ToOrdinal(*[2])"] else: [x: "*[2]"] - test: if: "$ClearSpeak_Exponents != 'Ordinal'" - then: [t: "puissance"] # phrase(2 raised to the 'power' 7) + then: [T: "puissance"] # phrase(2 raised to the 'power' 7) - name: simple-negative-integer tag: power @@ -332,23 +332,23 @@ - " ]" replace: - x: "*[1]" - - t: "à la" # phrase(2 raised 'to the' power 7) + - T: "à la" # phrase(2 raised 'to the' power 7) - x: "*[2]" - test: if: "$ClearSpeak_Exponents != 'Ordinal'" - then: [t: "puissance"] # phrase(2 raised to the 'power' 7) + then: [T: "puissance"] # phrase(2 raised to the 'power' 7) - name: simple-var tag: power match: "*[2][self::m:mi][string-length(.)=1]" replace: - x: "*[1]" - - t: "à la" # phrase(3 raised 'to the' power 7) + - T: "à la" # phrase(3 raised 'to the' power 7) - x: "*[2]" - pronounce: [text: "-ième", ipa: "jɛm", sapi5: "ieme", eloquence: "ieme"] - test: if: "$ClearSpeak_Exponents != 'Ordinal'" - then: [t: "puissance"] # phrase(2 raised to the 'power' 7) + then: [T: "puissance"] # phrase(2 raised to the 'power' 7) # match nested exponent, where the nested exponent is has the power 2 or 3 (n below) # [xxx]^n, - [xxx]^n, [xxx] var^n, -[xxx] var^n @@ -373,9 +373,9 @@ - " ]" replace: - x: "*[1]" - - t: "élevé à la" # phrase(x 'raised to the' second power) + - T: "élevé à la" # phrase(x 'raised to the' second power) - x: "*[2]" - - t: "puissance" # phrase(x raised to the second 'power') + - T: "puissance" # phrase(x raised to the second 'power') - # - [xxx]^n name: nested-negative-squared-or-cubed @@ -394,9 +394,9 @@ - " ]" replace: - x: "*[1]" - - t: "élevé à la" # phrase(x 'raised to the' second power) + - T: "élevé à la" # phrase(x 'raised to the' second power) - x: "*[2]" - - t: "puissance" # phrase(x raised to the second 'power') + - T: "puissance" # phrase(x raised to the second 'power') - # [xxx] var^n name: nested-var-squared-or-cubed @@ -417,9 +417,9 @@ - " ]" replace: - x: "*[1]" - - t: "élevé à la" # phrase(x 'raised to the' second power) + - T: "élevé à la" # phrase(x 'raised to the' second power) - x: "*[2]" - - t: "puissance" # phrase(x raised to the second 'power') + - T: "puissance" # phrase(x raised to the second 'power') - # -[xxx] var^n name: nested-negative-var-squared-or-cubed @@ -442,9 +442,9 @@ - " ]" replace: - x: "*[1]" - - t: "élevé à la" # phrase(x 'raised to the' second power) + - T: "élevé à la" # phrase(x 'raised to the' second power) - x: "*[2]" - - t: "puissance" # phrase(x raised to the second 'power') + - T: "puissance" # phrase(x raised to the second 'power') - name: default-exponent-power tag: power @@ -452,20 +452,20 @@ - "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]" replace: - x: "*[1]" - - t: "élevé à l'exposant" # phrase(x is 'raised to the exponent') + - T: "élevé à l'exposant" # phrase(x is 'raised to the exponent') - pause: short - x: "*[2]" - pause: short - - t: "fin de l'exposant" # phrase(and now 'end exponent' has been reached) + - T: "fin de l'exposant" # phrase(and now 'end exponent' has been reached) - name: default tag: power match: "." replace: - x: "*[1]" - - t: "élevé à la" # phrase(x 'raised to the' second power) + - T: "élevé à la" # phrase(x 'raised to the' second power) - x: "*[2]" - - t: "puissance" # phrase(x raised to the second 'power') + - T: "puissance" # phrase(x raised to the second 'power') # # Some rules on mrows @@ -478,15 +478,15 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "la"] # phrase('the' absolute value of 25) + then: [T: "la"] # phrase('the' absolute value of 25) - x: "$WordToSay" - - t: "de" # phrase(the absolute value 'of' 25) + - T: "de" # phrase(the absolute value 'of' 25) - x: "*[1]" - test: if: "$ClearSpeak_AbsoluteValue = 'AbsEnd'" then: - pause: short - - t: "fin" # phrase('end' absolute value) + - T: "fin" # phrase('end' absolute value) - x: "$WordToSay" - pause: short @@ -496,24 +496,24 @@ replace: - test: - if: "count(*)=0" - then: [t: "l'ensemble vide"] # phrase('the empty set') + then: [T: "l'ensemble vide"] # phrase('the empty set') - else_if: "count(*)=2" then: - test: if: "$Verbosity!='Terse'" - then: [t: "l'"] # phrase('the' empty set) - - t: "ensemble vide" # phrase(the 'empty set') + then: [T: "l'"] # phrase('the' empty set) + - T: "ensemble vide" # phrase(the 'empty set') - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" then: - test: if: "$Verbosity!='Terse'" - then: [t: "l'"] # phrase('the' set of all integers) - - t: "ensemble de" # phrase(this is a 'set of' numbers) + then: [T: "l'"] # phrase('the' set of all integers) + - T: "ensemble de" # phrase(this is a 'set of' numbers) - test: if: "$ClearSpeak_Sets != 'woAll'" - then: [t: "tous"] # phrase(the set of 'all' integers) + then: [T: "tous"] # phrase(the set of 'all' integers) - x: "*[1]/*[1]" - - t: "tel que" # phrase(the set S 'such that' x is less than y) + - T: "tel que" # phrase(the set S 'such that' x is less than y) - x: "*[1]/*[3]" else: - test: @@ -521,8 +521,8 @@ then: - test: if: "$Verbosity!='Terse'" - then: [t: "l'"] # phrase('the' set of integers) - - t: "ensemble" # phrase(this is a 'set' of integers) + then: [T: "l'"] # phrase('the' set of integers) + - T: "ensemble" # phrase(this is a 'set' of integers) - x: "*[1]" - # intervals are controlled by a ClearSpeak Preference -- parens/brackets don't have to match, so we avoid IsBracketed @@ -536,9 +536,9 @@ tag: [open-interval, open-closed-interval, closed-interval, closed-open-interval] match: "." replace: - - t: "l'invervalle de" # phrase('the interval from' a to b) + - T: "l'invervalle de" # phrase('the interval from' a to b) - x: "*[1]" - - t: "à" # phrase(the interval from a 'to' b) + - T: "à" # phrase(the interval from a 'to' b) - x: "*[2]" - pause: short - test: @@ -546,18 +546,18 @@ then: - test: if: "starts-with(name(.), 'open')" - then: [t: "sans"] # phrase(the interval from a to b 'not' including b) - - t: "inclure" # phrase(the interval from a to b not 'including' b) + then: [T: "sans"] # phrase(the interval from a to b 'not' including b) + - T: "inclure" # phrase(the interval from a to b not 'including' b) - x: "*[1]" # logic to deal with [not] arg #1 - test: if: "not($is_intervals_start_infinity or $is_intervals_end_infinity)" then_test: - if: "name(.)='open-interval'" - then: [t: "ou"] # phrase(the interval including a 'or' b ) + then: [T: "ou"] # phrase(the interval including a 'or' b ) - else_if: "name(.)='closed-interval'" - then: [t: "et"] # phrase(the interval including a 'and' b) - else: [t: "mais"] # phrase(the interval including a 'but' not b) + then: [T: "et"] # phrase(the interval including a 'and' b) + else: [T: "mais"] # phrase(the interval including a 'but' not b) # some ugly logic dealing with connectives: or, but, but, and (cleaner to be part of next clause?) - test: if: "not($is_intervals_end_infinity)" @@ -568,8 +568,8 @@ then: - test: if: "name(.) = 'open-interval' or name(.) = 'closed-open-interval'" - then: [t: "n'"] # phrase(the interval 'not' including a) - - t: "incluant pas" # phrase(the interval not 'including' a) + then: [T: "n'"] # phrase(the interval 'not' including a) + - T: "incluant pas" # phrase(the interval not 'including' a) - x: "*[2]" # onto the [not] [including]... part @@ -580,7 +580,7 @@ - "count(*[1]/*)=1 and count(*)=2" replace: - x: "*[1]/*[1]/*" # mtable/mtr/mtd - - t: "parmi" # phrase(the binomial coefficient n 'choose' m) + - T: "parmi" # phrase(the binomial coefficient n 'choose' m) - x: "*[2]/*[1]/*" - name: ClearSpeak-default @@ -589,12 +589,12 @@ variables: [NextLineIsContinuedRow: "following-sibling::*[1][contains(@data-intent-property, ':continued-row:')]"] replace: - pause: medium - - t: "rangée" # phrase(the first 'row' of a matrix) + - T: "rangée" # phrase(the first 'row' of a matrix) - x: "count(preceding-sibling::*)+1" - test: if: ".[self::m:mlabeledtr]" then: - - t: "avec l'étiquette" # phrase(the line 'with label' first equation) + - T: "avec l'étiquette" # phrase(the line 'with label' first equation) - x: "*[1]/*" - pause: short - pause: medium @@ -611,13 +611,13 @@ - bookmark: "@id" - test: if: "$Verbosity!='Terse' and not(IsNode(following-sibling::*[2],'simple'))" - then: [t: "la"] # phrase('the' square root of 25) + then: [T: "la"] # phrase('the' square root of 25) - test: - if: ".='log'" - then: [t: "logarithme"] + then: [T: "logarithme"] - else_if: "$ClearSpeak_Log = 'LnAsNaturalLog'" - then: [t: "logarithme naturel"] # phrase(the 'natural log' of x) - else: [spell: "'ln'"] + then: [T: "logarithme naturel"] # phrase(the 'natural log' of x) + else: [SPELL: "'ln'"] - name: ClearSpeak-multi-line tag: [piecewise, system-of-equations, lines] # these are ignored in favor of the ClearSpeak prefs @@ -634,21 +634,21 @@ - x: "$LineCount" - test: - if: "($ClearSpeak_MultiLineLabel = 'Auto' and self::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" - then: [t: "cas"] # phrase(this is the first 'case' of three cases) + then: [T: "cas"] # phrase(this is the first 'case' of three cases) - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line' or $ClearSpeak_MultiLineLabel = 'None'" # already dealt with Auto/Case - then: [t: "ligne"] # phrase(this is the first 'line' of three lines) + then: [T: "ligne"] # phrase(this is the first 'line' of three lines) - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" - then: [t: "contrainte"] # phrase(this is the first 'constraint' of three constraints) + then: [T: "contrainte"] # phrase(this is the first 'constraint' of three constraints) - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" - then: [t: "équation"] # phrase(this is the first 'equation' of three equations) + then: [T: "équation"] # phrase(this is the first 'equation' of three equations) - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" - then: [t: "rangée"] # phrase(this is the first 'row' of three rows) + then: [T: "rangée"] # phrase(this is the first 'row' of three rows) - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" - then: [t: "étape"] # phrase(this is the first 'step' of three steps) + then: [T: "étape"] # phrase(this is the first 'step' of three steps) # else 'None -- don't say anything' - test: - if: "$LineCount != 1" - then: [ct: "s"] # plural # phrase(shown by the letter 's') + then: [CT: "s"] # plural # phrase(shown by the letter 's') - pause: short - x: "*" - pause: long @@ -664,23 +664,23 @@ - pause: medium - test: - if: "($ClearSpeak_MultiLineLabel = 'Auto' and parent::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" - then: [t: "cas"] # phrase(in this 'case' x is not equal to y) + then: [T: "cas"] # phrase(in this 'case' x is not equal to y) - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" # already dealt with Auto/Case - then: [t: "ligne"] # phrase(the straight 'line' between x and y) + then: [T: "ligne"] # phrase(the straight 'line' between x and y) - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" - then: [t: "contrainte"] # phrase(there is a 'constraint' on possible values) + then: [T: "contrainte"] # phrase(there is a 'constraint' on possible values) - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" - then: [t: "équation"] # phrase(the 'equation' pi r squared gives the area of a circle) + then: [T: "équation"] # phrase(the 'equation' pi r squared gives the area of a circle) - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" - then: [t: "rangée"] # phrase(the values on the top 'row' are relevant) + then: [T: "rangée"] # phrase(the values on the top 'row' are relevant) - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" - then: [t: "étape"] # phrase(this is a 'step' by step process) + then: [T: "étape"] # phrase(this is a 'step' by step process) # else 'None -- don't say anything' - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" - test: if: "self::m:mlabeledtr" then: - - t: "avec étiquette" # phrase(the diagram is complete 'with label') + - T: "avec étiquette" # phrase(the diagram is complete 'with label') - x: "*[1]/*" - test: - if: "$ClearSpeak_MultiLineLabel='None'" @@ -700,8 +700,8 @@ replace: test: if: "$ClearSpeak_ImpliedTimes = 'None'" - then: [t: ""] - else: [t: "fois"] # phrase(5 'times' 3 equals 15) + then: [T: ""] + else: [T: "fois"] # phrase(5 'times' 3 equals 15) - name: no-times tag: mo @@ -709,7 +709,7 @@ # Note: this rule is also part of the paren rule so that the parens speak - ".='⁢' and $ClearSpeak_ImpliedTimes = 'None'" replace: - - t: "" + - T: "" - name: ClearSpeak-times tag: mo @@ -740,7 +740,7 @@ - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" # followed by parens - " )" replace: - - t: "fois" # phrase(5 'times' 3 equals 15) + - T: "fois" # phrase(5 'times' 3 equals 15) - name: no-say-parens tag: mrow diff --git a/Rules/Languages/fr/SharedRules/calculus.yaml b/Rules/Languages/fr/SharedRules/calculus.yaml index 894d9481b..db33ff687 100644 --- a/Rules/Languages/fr/SharedRules/calculus.yaml +++ b/Rules/Languages/fr/SharedRules/calculus.yaml @@ -4,13 +4,13 @@ tag: laplacian match: "count(*) <= 1" replace: - - t: "laplacien" + - T: "laplacien" - test: if: "count(*) = 1" then: - test: if: "$Verbosity!='Terse'" - then: [t: "de"] + then: [T: "de"] - test: if: "not(IsNode(*[1], 'leaf'))" then: [pause: short] @@ -22,8 +22,8 @@ replace: - test: if: "$Verbosity='Terse'" - then: [t: "div"] - else: [t: "divergence de"] + then: [T: "div"] + else: [T: "divergence de"] - test: if: "not(IsNode(*[1], 'leaf'))" then: [pause: short] @@ -33,10 +33,10 @@ tag: curl match: "count(*) = 1" replace: - - t: "rotationnel" + - T: "rotationnel" - test: if: "$Verbosity!='Terse'" - then: [t: "de"] + then: [T: "de"] - test: if: "not(IsNode(*[1], 'leaf'))" then: [pause: short] @@ -48,8 +48,8 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "gradient de"] - else: [t: "grad"] + then: [T: "gradient de"] + else: [T: "grad"] - test: if: "not(IsNode(*[1], 'leaf'))" then: [pause: short] diff --git a/Rules/Languages/fr/SharedRules/default.yaml b/Rules/Languages/fr/SharedRules/default.yaml index 0b2cf89e8..f365c0d35 100644 --- a/Rules/Languages/fr/SharedRules/default.yaml +++ b/Rules/Languages/fr/SharedRules/default.yaml @@ -24,7 +24,7 @@ tag: mrow match: "not(*)" replace: - - t: " " + - T: " " - name: default tag: mrow @@ -57,14 +57,14 @@ - if: "string-length(.) = 1 and text() != '_'" then: [x: "text()"] - else_if: "@data-chem-element" - then: [spell: "text()", pause: "short"] + then: [SPELL: "text()", pause: "short"] else: [x: "translate(., '-_\u00A0', ' ')"] - name: default tag: ms match: "." replace: - - t: "la chaîne" + - T: "la chaîne" - pause: short - x: "text()" @@ -80,7 +80,7 @@ - "not(ancestor::*[name() != 'mrow'][1]/self::m:fraction)" replace: - x: "*[1]" - - t: "sur" + - T: "sur" - x: "*[2]" - pause: short @@ -88,13 +88,13 @@ tag: mfrac match: "." replace: - - t: "début" + - T: "début" - pause: short - x: "*[1]" - test: if: "not(IsNode(*[1],'leaf'))" then: [pause: short] - - t: "sur" + - T: "sur" - test: if: "not(IsNode(*[2],'leaf'))" then: [pause: short] @@ -102,36 +102,36 @@ - pause: short - test: if: "$Impairment = 'Blindness'" - then: [t: "fin"] + then: [T: "fin"] - pause: medium - name: literal-default tag: msqrt match: "." replace: - - t: "racine" + - T: "racine" - test: if: "$Verbosity!='Terse'" - then: [t: "de"] + then: [T: "de"] - x: "*[1]" - pause: short - test: if: "not(IsNode(*[1],'leaf')) or $Impairment = 'Blindness'" - then: [t: "fin de racine", pause: medium] + then: [T: "fin de racine", pause: medium] - name: literal-default tag: mroot match: "." replace: - - t: "racine d'indice" + - T: "racine d'indice" - x: "*[2]" - pause: short - - t: "de" + - T: "de" - x: "*[1]" - pause: short - test: if: "not(IsNode(*[2],'leaf'))" - then: [t: "fin de racine"] + then: [T: "fin de racine"] - name: simple-sub tag: indexed-by @@ -146,7 +146,7 @@ match: "count(*)=2 and *[2][self::m:mrow and *[2][.='⁣']]" replace: - x: "*[1]" - - t: "indice" + - T: "indice" - x: "*[2]" - pause: short @@ -155,7 +155,7 @@ match: "." replace: - x: "*[1]" - - t: "indice" + - T: "indice" - x: "*[2]" - pause: short @@ -166,7 +166,7 @@ - x: "*[1]" - test: if: "not($Verbosity='Terse' and *[2][self::m:mn and not(translate(., '.,', '')!=.)])" - then: [t: "indice"] + then: [T: "indice"] - x: "*[2]" - name: literal @@ -177,7 +177,7 @@ - test: if: "name(.)='msubsup'" then: - - t: "indice" + - T: "indice" - x: "*[2]" - test: if: "*[last()][translate(., '′″‴⁗†‡°*', '')='']" @@ -185,15 +185,15 @@ else_test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" then: - - t: "exposant" + - T: "exposant" - x: "*[last()]" - test: if: "not(IsNode(*[last()], 'simple')) or $Impairment = 'Blindness'" - then: [t: "fin d'exposant"] + then: [T: "fin d'exposant"] else: - - t: "exposant" + - T: "exposant" - x: "*[last()]" - - t: "fin d'exposant" + - T: "fin d'exposant" - name: default tag: munder @@ -201,11 +201,11 @@ replace: - test: if: "not(IsNode(*[1], 'leaf'))" - then: [t: "quantité"] + then: [T: "quantité"] - x: "*[1]" - - t: "avec" + - T: "avec" - x: "*[2]" - - t: "en dessous" + - T: "en dessous" - name: diacriticals tag: mover @@ -220,11 +220,11 @@ replace: - test: if: "not(IsNode(*[1], 'leaf'))" - then: [t: "quantité"] + then: [T: "quantité"] - x: "*[1]" - - t: "avec" + - T: "avec" - x: "*[2]" - - t: "au-dessus" + - T: "au-dessus" - name: default tag: munderover @@ -232,13 +232,13 @@ replace: - test: if: "not(IsNode(*[1], 'leaf'))" - then: [t: "quantité"] + then: [T: "quantité"] - x: "*[1]" - - t: "avec" + - T: "avec" - x: "*[2]" - - t: "en dessous et" + - T: "en dessous et" - x: "*[3]" - - t: "au-dessus" + - T: "au-dessus" - name: default tag: mmultiscripts @@ -260,9 +260,9 @@ - test: if: "count($Prescripts) > 2" then: - - t: "avec" + - T: "avec" - x: "count($Prescripts) div 2" - - t: "préscripts" + - T: "préscripts" - pause: short - test: if: "not($Prescripts[1][self::m:none])" @@ -271,7 +271,7 @@ - x: "$Prescripts[1]" - test: if: "not($Prescripts[1][self::m:none] or $Prescripts[2][self::m:none])" - then: [t: "et"] + then: [T: "et"] - test: if: "not($Prescripts[2][self::m:none])" then: @@ -288,7 +288,7 @@ - x: "$Prescripts[3]" - test: if: "not($Prescripts[3][self::m:none] or $Prescripts[4][self::m:none])" - then: [t: "et"] + then: [T: "et"] - test: if: "not($Prescripts[4][self::m:none])" then: @@ -297,9 +297,9 @@ - test: if: "count($Prescripts) > 4" then: - - t: "et préscripts alternés" + - T: "et préscripts alternés" - x: "$Prescripts[position() > 4]" - - t: "fin préscripts" + - T: "fin préscripts" - test: if: "$Postscripts" then: @@ -313,10 +313,10 @@ then: - test: if: "$Prescripts" - then: [t: "et"] - - t: "avec" + then: [T: "et"] + - T: "avec" - x: "count($Postscripts) div 2" - - t: "postscripts" + - T: "postscripts" - pause: short - test: if: "not($Postscripts[1][self::m:none])" @@ -325,7 +325,7 @@ - x: "$Postscripts[1]" - test: if: "not($Postscripts[1][self::m:none] or $Postscripts[2][self::m:none])" - then: [t: "et"] + then: [T: "et"] - test: if: "not($Postscripts[2][self::m:none])" then: @@ -341,7 +341,7 @@ - x: "$Postscripts[3]" - test: if: "not($Postscripts[3][self::m:none] or $Postscripts[4][self::m:none])" - then: [t: "et"] + then: [T: "et"] - test: if: "not($Postscripts[4][self::m:none])" then: @@ -357,7 +357,7 @@ - x: "$Postscripts[5]" - test: if: "not($Postscripts[5][self::m:none] or $Postscripts[6][self::m:none])" - then: [t: "et"] + then: [T: "et"] - test: if: "not($Postscripts[6][self::m:none])" then: @@ -373,7 +373,7 @@ - x: "$Postscripts[7]" - test: if: "not($Postscripts[7][self::m:none] or $Postscripts[8][self::m:none])" - then: [t: "et"] + then: [T: "et"] - test: if: "not($Postscripts[8][self::m:none])" then: @@ -382,9 +382,9 @@ - test: if: "count($Postscripts) > 8" then: - - t: "et scripts alternés" + - T: "et scripts alternés" - x: "$Postscripts[position() > 8]" - - t: "fin scripts" + - T: "fin scripts" - name: default tag: mtable @@ -393,18 +393,18 @@ - NumColumns: "count(*[1]/*) - IfThenElse(*/self::m:mlabeledtr, 1, 0)" match: "." replace: - - t: "table avec" # phrase(the 'table with' 3 rows) + - T: "table avec" # phrase(the 'table with' 3 rows) - x: count(*) - test: if: count(*)=1 - then: [t: "rangée"] # phrase(the table with 1 'row') - else: [t: "rangées"] # phrase(the table with 3 'rows') - - t: "et" # phrase(the table with 3 rows 'and' 4 columns) + then: [T: "rangée"] # phrase(the table with 1 'row') + else: [T: "rangées"] # phrase(the table with 3 'rows') + - T: "et" # phrase(the table with 3 rows 'and' 4 columns) - x: "$NumColumns" - test: if: "NumColumns=1" - then: [t: "colonne"] # phrase(the table with 3 rows and 1 'column') - else: [t: "colonnes"] # phrase(the table with 3 rows and 4 'columns') + then: [T: "colonne"] # phrase(the table with 3 rows and 1 'column') + else: [T: "colonnes"] # phrase(the table with 3 rows and 4 'columns') - pause: long - x: "*" @@ -415,12 +415,12 @@ match: "." replace: - pause: medium - - t: "rangée" # phrase(the first 'row' of a matrix) + - T: "rangée" # phrase(the first 'row' of a matrix) - x: "count(preceding-sibling::*)+1" - test: if: "self::m:mlabeledtr" then: - - t: "avec nom" # phrase(the line 'with label' first equation) + - T: "avec nom" # phrase(the line 'with label' first equation) - x: "*[1]/*" - pause: short - pause: medium @@ -439,7 +439,7 @@ # if: not($IsColumnSilent) and ($ClearSpeak_Matrix = 'SpeakColNum' or count(preceding-sibling::*) != 0) if: "not($IsColumnSilent)" then: - - t: "colonne" # phrase(the first 'column' of the matrix) + - T: "colonne" # phrase(the first 'column' of the matrix) - x: "count(preceding-sibling::*)+IfThenElse(parent::m:mlabeledtr, 0, 1)" - pause: medium - x: "*" @@ -457,7 +457,7 @@ tag: menclose match: "@notation='box' and *[self::m:mtext and .=' ']" replace: - - t: "Case vide" # phrase(the 'empty box' contains no values) + - T: "Case vide" # phrase(the 'empty box' contains no values) - name: default # The ordering below is the order in which words come out when there is more than one value @@ -467,109 +467,109 @@ replace: - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' box ')]" - then: [t: "case", pause: short] # phrase(the 'box' around the expression) + then: [T: "case", pause: short] # phrase(the 'box' around the expression) - test: if: ".[contains(@notation,'roundedbox')]" - then: [t: "case arrondie", pause: short] # phrase(the 'round box' around the expression) + then: [T: "case arrondie", pause: short] # phrase(the 'round box' around the expression) - test: if: ".[contains(@notation,'circle')]" - then: [t: "rond", pause: short] # phrase(the 'circle' around the expression) + then: [T: "rond", pause: short] # phrase(the 'circle' around the expression) - test: if: ".[ contains(concat(' ', normalize-space(@notation), ' '), ' left ') or contains(concat(' ', normalize-space(@notation), ' '), ' right ') or contains(@notation,'top') or contains(@notation,'bottom') ]" then: - - t: "line on" # phrase(draw a straight 'line' on the page) + - T: "line on" # phrase(draw a straight 'line' on the page) - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]" - then: [t: "gauche", pause: short] # phrase(line on 'left' of the expression) + then: [T: "gauche", pause: short] # phrase(line on 'left' of the expression) - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]" - then: [t: "droite", pause: short] # phrase(line on 'right' of the expression) + then: [T: "droite", pause: short] # phrase(line on 'right' of the expression) - test: if: ".[contains(@notation,'top')]" - then: [t: "dessus", pause: short] # phrase(line on 'top' of the expression) + then: [T: "dessus", pause: short] # phrase(line on 'top' of the expression) - test: if: ".[contains(@notation,'bottom')]" - then: [t: "dessous", pause: short] # phrase(line on the 'bottom' of the expression) + then: [T: "dessous", pause: short] # phrase(line on the 'bottom' of the expression) - test: if: ".[ contains(@notation,'updiagonalstrike') or contains(@notation,'downdiagonalstrike') or contains(@notation,'verticalstrike') or contains(@notation,'horizontalstrike') ]" then: - test: if: ".[contains(@notation,'updiagonalstrike') and contains(@notation,'downdiagonalstrike')]" - then: [spell: "'x'", pause: short] # seems better to say 'x cross out' than 'up diagonal, down diagonal cross out' + then: [SPELL: "'x'", pause: short] # seems better to say 'x cross out' than 'up diagonal, down diagonal cross out' else: - test: if: ".[contains(@notation,'updiagonalstrike')]" - then: [t: "diagonale vers le haut", pause: short] # phrase(the line runs 'up diagonal') + then: [T: "diagonale vers le haut", pause: short] # phrase(the line runs 'up diagonal') - test: if: ".[contains(@notation,'downdiagonalstrike')]" - then: [t: "diagonale vers le bas", pause: short] # phrase(the line runs 'down diagonal') + then: [T: "diagonale vers le bas", pause: short] # phrase(the line runs 'down diagonal') - test: if: ".[contains(@notation,'verticalstrike')]" - then: [t: "verticale", pause: short] # phrase(the line is 'vertical') + then: [T: "verticale", pause: short] # phrase(the line is 'vertical') - test: if: ".[contains(@notation,'horizontalstrike')]" - then: [t: "horizontale", pause: short] # phrase(the line is 'horizontal') - - t: "cross out" # phrase(please 'cross out' the incorrect answer) + then: [T: "horizontale", pause: short] # phrase(the line is 'horizontal') + - T: "cross out" # phrase(please 'cross out' the incorrect answer) - pause: short - test: if: ".[contains(@notation,'uparrow')]" - then: [t: "flèche vers le haut", pause: short] # phrase(direction is shown by the 'up arrow') + then: [T: "flèche vers le haut", pause: short] # phrase(direction is shown by the 'up arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]" - then: [t: "flèche vers le bas", pause: short] # phrase(the trend is shown by the 'down arrow') + then: [T: "flèche vers le bas", pause: short] # phrase(the trend is shown by the 'down arrow') - test: if: ".[contains(@notation,'leftarrow')]" - then: [t: "flèche vers la gauche", pause: short] # phrase(the 'left arrow' indicates going back) + then: [T: "flèche vers la gauche", pause: short] # phrase(the 'left arrow' indicates going back) - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')]" - then: [t: "flèche vers la droite", pause: short] # phrase(the 'right arrow' indicates moving forward) + then: [T: "flèche vers la droite", pause: short] # phrase(the 'right arrow' indicates moving forward) - test: if: ".[contains(@notation,'northeastarrow')]" - then: [t: "flèche nord-est", pause: short] # phrase(direction is indicated by the 'northeast arrow') + then: [T: "flèche nord-est", pause: short] # phrase(direction is indicated by the 'northeast arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')]" - then: [t: "flèche sud-est", pause: short] # phrase(direction is shown by the 'southeast arrow') + then: [T: "flèche sud-est", pause: short] # phrase(direction is shown by the 'southeast arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')]" - then: [t: "flèche sud-ouest", pause: short] # phrase(direction is shown by the 'southwest arrow') + then: [T: "flèche sud-ouest", pause: short] # phrase(direction is shown by the 'southwest arrow') - test: if: ".[contains(@notation,'northwestarrow')]" - then: [t: "flèche nord-ouest", pause: short] # phrase(direction is shown by the 'northwest arrow') + then: [T: "flèche nord-ouest", pause: short] # phrase(direction is shown by the 'northwest arrow') - test: if: ".[contains(@notation,'updownarrow')]" - then: [t: "flèche verticale à double extrémité", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') + then: [T: "flèche verticale à double extrémité", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') - test: if: ".[contains(@notation,'leftrightarrow')]" - then: [t: "flèche horizontale à double extrémité", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') + then: [T: "flèche horizontale à double extrémité", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') - test: if: ".[contains(@notation,'northeastsouthwestarrow')]" - then: [t: "flèche diagonale vers le haut à double extrémité", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') + then: [T: "flèche diagonale vers le haut à double extrémité", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') - test: if: ".[contains(@notation,'northwestsoutheastarrow')]" - then: [t: "flèche diagonale vers le bas à double extrémité", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') + then: [T: "flèche diagonale vers le bas à double extrémité", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') - test: if: ".[contains(@notation,'actuarial')]" - then: [t: "symbole actuariel", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) + then: [T: "symbole actuariel", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) - test: if: ".[contains(@notation,'madrub')]" - then: [t: "symbole factoriel arabe", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) + then: [T: "symbole factoriel arabe", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) - test: if: ".[contains(@notation,'phasorangle')]" - then: [t: "angle de phaseur", pause: short] # phrase(the 'phasor angle' is used to measure electrical current) + then: [T: "angle de phaseur", pause: short] # phrase(the 'phasor angle' is used to measure electrical current) - test: if: ".[contains(@notation,'longdiv') or not(@notation) or normalize-space(@notation) ='']" # default - then: [t: "symbole de division longue", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) + then: [T: "symbole de division longue", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) - test: if: ".[contains(@notation,'radical')]" - then: [t: "racine carrée", pause: short] # phrase(5 is the 'square root' of 25) - - t: "enclosing" # phrase(parentheses are 'enclosing' part of the equation) + then: [T: "racine carrée", pause: short] # phrase(5 is the 'square root' of 25) + - T: "enclosing" # phrase(parentheses are 'enclosing' part of the equation) - test: if: "*[self::m:mtext and .=' ']" - then: [t: "espace"] # otherwise there is complete silence # phrase(there is a 'space' between the words) + then: [T: "espace"] # otherwise there is complete silence # phrase(there is a 'space' between the words) else: [x: "*"] - test: if: "$Impairment = 'Blindness' and ( $SpeechStyle != 'SimpleSpeak' or not(IsNode(*[1], 'leaf')) )" - then: [t: "fin d'encadrement"] # phrase(reached the 'end enclosure' point) + then: [T: "fin d'encadrement"] # phrase(reached the 'end enclosure' point) - pause: short - name: semantics @@ -589,7 +589,7 @@ match: . replace: - x: "*[1]" - - t: "de" + - T: "de" - pause: auto - x: "*[position() > 1]" @@ -660,7 +660,7 @@ - test: if: "$Verbosity != 'Terse' and not(contains(@data-intent-property, ':literal:')) and not(count(*)=2 and (IsInDefinition(*[1], 'TrigFunctionNames') or IsInDefinition(name(.), 'TerseFunctionNames')) and IsNode(*[2], 'simple'))" - then: [t: "de", pause: auto] + then: [T: "de", pause: auto] - insert: nodes: "*" replace: diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml index 989957617..ac4bf5b7e 100644 --- a/Rules/Languages/fr/SharedRules/general.yaml +++ b/Rules/Languages/fr/SharedRules/general.yaml @@ -8,25 +8,25 @@ - test: if: "$Verbosity!='Terse'" then: - - t: "les" # phrase('the' real numbers) + - T: "les" # phrase('the' real numbers) - bookmark: "*[1]/@id" - test: - if: "*[1][.='ℂ']" - then: [t: "nombres complexes"] # phrase('complex numbers' consist of two parts) + then: [T: "nombres complexes"] # phrase('complex numbers' consist of two parts) - else_if: "*[1][.='ℕ']" - then: [t: "nombres naturels"] # phrase('natural numbers' are numbers from 1 to infinity) + then: [T: "nombres naturels"] # phrase('natural numbers' are numbers from 1 to infinity) - else_if: "*[1][.='ℚ']" - then: [t: "nombres rationnels"] # phrase('rational numbers' are the fraction of 2 integers) + then: [T: "nombres rationnels"] # phrase('rational numbers' are the fraction of 2 integers) - else_if: "*[1][.='ℝ']" - then: [t: "nombres réels"] # phrase('real numbers' can be both positive and negative) + then: [T: "nombres réels"] # phrase('real numbers' can be both positive and negative) - else_if: "*[1][.='ℤ']" - then: [t: "nombres entiers"] # phrase(positive 'integers' are natural numbers above 0) + then: [T: "nombres entiers"] # phrase(positive 'integers' are natural numbers above 0) else: [x: "*[1][text()]"] # shouldn't happen - bookmark: "*[2]/@id" - test: - if: "*[2][.='+']" - then: [t: "positifs"] # phrase(set of all 'positive' integers less than 10) - else: [t: "négatifs"] # phrase(set of all 'negative' integers less than minus 10) + then: [T: "positifs"] # phrase(set of all 'positive' integers less than 10) + else: [T: "négatifs"] # phrase(set of all 'negative' integers less than minus 10) - name: dimension-number-sets # should be single digit integer at this point (e.g, R^3) @@ -36,15 +36,15 @@ - bookmark: "*[1]/@id" - test: - if: "*[1][.='ℂ']" - then: [t: "C"] # phrase(the letter 'C' used to represent complex number) + then: [T: "C"] # phrase(the letter 'C' used to represent complex number) - else_if: "*[1][.='ℕ']" - then: [t: "N"] # phrase(the letter 'N' may represent natural numbers) + then: [T: "N"] # phrase(the letter 'N' may represent natural numbers) - else_if: "*[1][.='ℚ']" - then: [t: "Q"] # phrase(the letter 'Q' may represent rational numbers) + then: [T: "Q"] # phrase(the letter 'Q' may represent rational numbers) - else_if: "*[1][.='ℝ']" - then: [t: "R"] # phrase(the letter 'R' may represent real numbers) + then: [T: "R"] # phrase(the letter 'R' may represent real numbers) - else_if: "*[1][.='ℤ']" - then: [t: "Z"] # phrase(the letter 'Z' may represent integers) + then: [T: "Z"] # phrase(the letter 'Z' may represent integers) else: [x: "*[1][text()]"] # shouldn't happen - bookmark: "*[2]/@id" - x: "*[2]" @@ -56,15 +56,15 @@ - bookmark: "@id" - test: - if: ".='ℂ'" - then: [t: "les nombres complexes"] # phrase('the complex numbers' include 2 parts) + then: [T: "les nombres complexes"] # phrase('the complex numbers' include 2 parts) - else_if: ".='ℕ'" - then: [t: "les nombres naturels"] # phrase('the natural numbers' begin at 1) + then: [T: "les nombres naturels"] # phrase('the natural numbers' begin at 1) - else_if: ".='ℚ'" - then: [t: "les nombres rationnels"] # phrase('the rational numbers' are the fraction of 2 integers) + then: [T: "les nombres rationnels"] # phrase('the rational numbers' are the fraction of 2 integers) - else_if: ".='ℝ'" - then: [t: "les nombres réels"] # phrase('the real numbers' can be both positive and negative) + then: [T: "les nombres réels"] # phrase('the real numbers' can be both positive and negative) - else_if: ".='ℤ'" - then: [t: "les nombres entiers"] # phrase('the integers' are natural numbers above 0) + then: [T: "les nombres entiers"] # phrase('the integers' are natural numbers above 0) else: [x: "text()"] # shouldn't happen - name: real-part @@ -72,14 +72,14 @@ match: "." replace: - bookmark: "@id" - - t: "la partie réelle" # phrase('the real part' of a complex number does not include the imaginary part) + - T: "la partie réelle" # phrase('the real part' of a complex number does not include the imaginary part) - name: imaginary-part tag: imaginary-part match: "." replace: - bookmark: "@id" - - t: "la partie imaginaire" # phrase('the imaginary part' is part of a complex number) + - T: "la partie imaginaire" # phrase('the imaginary part' is part of a complex number) # rules on scripted vertical bars ('evaluated at') - name: evaluated-at-2 @@ -88,7 +88,7 @@ replace: - x: "*[1]" - pause: auto - - t: "évalués à" # phrase(results were 'evaluated at' a given point) + - T: "évalués à" # phrase(results were 'evaluated at' a given point) - pause: auto - x: "*[2]" @@ -98,10 +98,10 @@ replace: - x: "*[1]" - pause: auto - - t: "évalués à" # phrase(results were 'evaluated at' this point) + - T: "évalués à" # phrase(results were 'evaluated at' this point) - pause: auto - x: "*[3]" - - t: "moins la même expression évaluée à" # phrase(this result is 'minus the same expression evaluated at' an earlier point) + - T: "moins la même expression évaluée à" # phrase(this result is 'minus the same expression evaluated at' an earlier point) - x: "*[2]" - name: permutation @@ -110,7 +110,7 @@ match: "count(*)=2 and contains(@data-intent-property, ':infix:')" replace: - x: "*[2]" - - t: "permutations de" # phrase(the solution involves several 'permutations of' values) + - T: "permutations de" # phrase(the solution involves several 'permutations of' values) - x: "*[1]" - name: intervals @@ -121,25 +121,25 @@ - if: "self::m:open-interval" then_test: if: "$Verbosity!='Terse'" - then: [t: "l'intervalle ouvert"] - else: [t: "intervalle ouvert"] + then: [T: "l'intervalle ouvert"] + else: [T: "intervalle ouvert"] - else_if: "self::m:open-closed-interval" then_test: if: "$Verbosity!='Terse'" - then: [t: "l'intervalle ouvert fermé"] - else: [t: "intervalle ouvert fermé"] + then: [T: "l'intervalle ouvert fermé"] + else: [T: "intervalle ouvert fermé"] - else_if: "self::m:closed-interval" then_test: if: "$Verbosity!='Terse'" - then: [t: "l'intervalle fermé"] - else: [t: "intervalle fermé"] + then: [T: "l'intervalle fermé"] + else: [T: "intervalle fermé"] else_test: if: "$Verbosity!='Terse'" - then: [t: "l'intervalle fermé ouvert"] # closed-open-interval - else: [t: "intervalle fermé ouvert"] - - t: "de" # phrase(the interval 'from' c to d) + then: [T: "l'intervalle fermé ouvert"] # closed-open-interval + else: [T: "intervalle fermé ouvert"] + - T: "de" # phrase(the interval 'from' c to d) - x: "*[1]" - - t: "à" # phrase(the interval from c 'to' d) + - T: "à" # phrase(the interval from c 'to' d) - x: "*[2]" - name: default-point @@ -149,10 +149,10 @@ - test: if: "$Verbosity!='Terse'" then: - - t: "la" # phrase('the' square root of 25 equals 5) - - t: "point" # phrase(a decimal 'point' indicates the fraction component of a number) + - T: "la" # phrase('the' square root of 25 equals 5) + - T: "point" # phrase(a decimal 'point' indicates the fraction component of a number) - x: "*[1]" - - t: "virgule" # phrase(use a 'comma' to divide large numbers or as a decimal point) + - T: "virgule" # phrase(use a 'comma' to divide large numbers or as a decimal point) - x: "*[2]" - name: bigop-both @@ -163,19 +163,19 @@ if: "$Verbosity!='Terse'" then_test: - if: "*[1][.='∏']" - then: [t: "le"] # phrase('the' product) - masculine starting with consonant + then: [T: "le"] # phrase('the' product) - masculine starting with consonant - else_if: "*[1][contains('⋂∩⋃∪∫∬∭∮∯∰∱∲∳', .)]" # phrase('the' union/intersection/integral) - starting with vowel - then: [t: "l'"] - - else: [t: "la"] # phrase('the' sum) - feminine starting with consonant + then: [T: "l'"] + - else: [T: "la"] # phrase('the' sum) - feminine starting with consonant - x: "*[1]" - - t: "de" # phrase(subtracting 5 'from' 10 gives 5) + - T: "de" # phrase(subtracting 5 'from' 10 gives 5) - x: "*[2]" - pause: short - - t: "à" # phrase(adding 6 'to' 6 equals 12) + - T: "à" # phrase(adding 6 'to' 6 equals 12) - x: "*[3]" - test: if: "following-sibling::*" - then: [t: "de"] # phrase(the square root 'of' 25 equals 5) + then: [T: "de"] # phrase(the square root 'of' 25 equals 5) - name: bigop-under tag: large-op @@ -185,16 +185,16 @@ if: "$Verbosity!='Terse'" then_test: - if: "*[1][.='∏']" - then: [t: "le"] # phrase('the' product) - masculine starting with consonant + then: [T: "le"] # phrase('the' product) - masculine starting with consonant - else_if: "*[1][contains('⋂∩⋃∪∫∬∭∮∯∰∱∲∳', .)]" # phrase('the' union/intersection/integral) - starting with vowel - then: [t: "l'"] - - else: [t: "la"] # phrase('the' sum) - feminine starting with consonant + then: [T: "l'"] + - else: [T: "la"] # phrase('the' sum) - feminine starting with consonant - x: "*[1]" - - t: "sur" # phrase(2 'over' 3 equals two thirds) + - T: "sur" # phrase(2 'over' 3 equals two thirds) - x: "*[2]" - test: if: "following-sibling::*" - then: [t: "de"] # phrase(the square root 'of' 25 equals 5) + then: [T: "de"] # phrase(the square root 'of' 25 equals 5) - name: largeop tag: mrow @@ -204,12 +204,12 @@ if: "$Verbosity!='Terse'" then_test: - if: "*[1][.='∏']" - then: [t: "le"] # phrase('the' product) - masculine starting with consonant + then: [T: "le"] # phrase('the' product) - masculine starting with consonant - else_if: "*[1][contains('⋂∩⋃∪∫∬∭∮∯∰∱∲∳', .)]" # phrase('the' union/intersection/integral) - starting with vowel - then: [t: "l'"] - - else: [t: "la"] # phrase('the' sum) - feminine starting with consonant + then: [T: "l'"] + - else: [T: "la"] # phrase('the' sum) - feminine starting with consonant - x: "*[1]" - - t: "de" # phrase(the square root 'of' 25 equals 5) + - T: "de" # phrase(the square root 'of' 25 equals 5) - x: "*[2]" - name: repeating-decimal @@ -217,8 +217,8 @@ match: "." replace: - x: "*[1]" - - t: "avec des chiffres répétitifs" # phrase('with repeating digits') - - spell: "*[2]" + - T: "avec des chiffres répétitifs" # phrase('with repeating digits') + - SPELL: "*[2]" - name: msubsup-skip-super # handles single, double, etc., prime @@ -228,16 +228,16 @@ - x: "*[1]" - test: if: "$Verbosity='Verbose'" - then: [t: "indice"] # phrase(a 'subscript' may be used to indicate an index) - else: [t: "sous"] # phrase(the result is 'sub' optimal) + then: [T: "indice"] # phrase(a 'subscript' may be used to indicate an index) + else: [T: "sous"] # phrase(the result is 'sub' optimal) - x: "*[2]" - test: if: "not(IsNode(*[2],'leaf') and $Impairment = 'Blindness')" then: - test: if: "$Verbosity='Verbose'" - then: [t: "fin de l'indice"] # phrase(this is the 'end subscript' position) - else: [t: "fin d'indice"] # phrase(this is the 'end sub' position) + then: [T: "fin de l'indice"] # phrase(this is the 'end subscript' position) + else: [T: "fin d'indice"] # phrase(this is the 'end sub' position) - pause: short else_test: if: "*[2][self::m:mi]" # need a pause in "x sub k prime" so the prime is not associated with the 'k' @@ -245,7 +245,7 @@ - test: if: "name(.)='say-super'" then: - - t: "exposant" + - T: "exposant" - x: "*[3]" - pause: short @@ -255,7 +255,7 @@ match: "$Verbosity = 'Terse' and string-length(.)=1" replace: - bookmark: "@id" - - spell: "text()" + - SPELL: "text()" # the order of matching is @@ -330,17 +330,17 @@ then: [x: "$Word"] - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" then: [x: "DefinitionValue($Word, 'Speech', 'PluralForms')"] - else: [x: "$Word", ct: "s"] + else: [x: "$Word", CT: "s"] else: - x: "$Prefix" - - ct: "-" + - CT: "-" - test: - if: "$IsSingular" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatenated to the base then: [x: "concat('\uF8FE', $Word)"] - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralForms'))"] - else: [x: "concat('\uF8FE', $Word)", ct: "s"] + else: [x: "concat('\uF8FE', $Word)", CT: "s"] # need to reverse the order of speech: $ 3 -> 3 dollars - name: currency @@ -357,14 +357,14 @@ then: [x: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')"] - else_if: "DefinitionValue(*[1], 'Speech', 'PluralForms') != ''" then: [x: "DefinitionValue(*[1], 'Speech', 'PluralForms')"] - else: [x: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')", ct: "s"] + else: [x: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')", CT: "s"] - name: sin tag: mi match: ".='sin'" replace: - bookmark: "@id" - - t: "sinus" + - T: "sinus" - name: cos tag: mi @@ -373,8 +373,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cos"] - else: [t: "cosinus"] + then: [T: "cos"] + else: [T: "cosinus"] - name: tan tag: mi @@ -383,8 +383,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "tan"] - else: [t: "tangente"] + then: [T: "tan"] + else: [T: "tangente"] - name: sec tag: mi @@ -393,8 +393,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "sec"] - else: [t: "sécante"] + then: [T: "sec"] + else: [T: "sécante"] - name: csc tag: mi @@ -403,8 +403,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "csc"] - else: [t: "cosécante"] + then: [T: "csc"] + else: [T: "cosécante"] - name: cot tag: mi @@ -413,8 +413,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cot"] - else: [t: "cotangente"] + then: [T: "cot"] + else: [T: "cotangente"] - name: sinh tag: mi @@ -423,8 +423,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "sinh"] - else: [t: "sinus hyperbolique"] + then: [T: "sinh"] + else: [T: "sinus hyperbolique"] - name: cosh tag: mi @@ -433,8 +433,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cosh"] - else: [t: "cosinus hyperbolique"] + then: [T: "cosh"] + else: [T: "cosinus hyperbolique"] - name: tanh tag: mi @@ -443,8 +443,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "tanh"] - else: [t: "tangente hyperbolique"] + then: [T: "tanh"] + else: [T: "tangente hyperbolique"] - name: sech tag: mi @@ -453,8 +453,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "sech"] - else: [t: "sécante hyperbolique"] + then: [T: "sech"] + else: [T: "sécante hyperbolique"] - name: csch tag: mi @@ -463,8 +463,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "csch"] - else: [t: "cosécante hyperbolique"] + then: [T: "csch"] + else: [T: "cosécante hyperbolique"] - name: coth tag: mi @@ -473,8 +473,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "coth"] - else: [t: "cotangente hyperbolique"] + then: [T: "coth"] + else: [T: "cotangente hyperbolique"] - name: exponential tag: mi @@ -483,8 +483,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "exp"] - else: [t: "exponentielle"] + then: [T: "exp"] + else: [T: "exponentielle"] - name: covariance tag: mi @@ -493,8 +493,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "Cov"] - else: [t: "covariance"] + then: [T: "Cov"] + else: [T: "covariance"] - name: log tag: mi @@ -503,13 +503,13 @@ - bookmark: "@id" - test: - if: "$Verbosity!='Terse'" - then: [t: "le"] + then: [T: "le"] - test: - if: ".= 'log'" - then: [t: "log"] + then: [T: "log"] - else_if: "$Verbosity='Terse'" - then: [spell: "'ln'"] - else: [t: "logarithme naturel"] + then: [SPELL: "'ln'"] + else: [T: "logarithme naturel"] - name: multi-line # that eliminates the need for the if: else_if: ... @@ -525,13 +525,13 @@ - x: "$LineCount" - test: - if: "self::m:piecewise" - then: [t: "cas"] # phrase(this is the first 'case' of three cases) + then: [T: "cas"] # phrase(this is the first 'case' of three cases) - else_if: "self::m:system-of-equations" - then: [t: "équation"] # phrase(this is the first 'equation' of three equations) - else: [t: "ligne"] # phrase(this is the first 'line' of three lines) + then: [T: "équation"] # phrase(this is the first 'equation' of three equations) + else: [T: "ligne"] # phrase(this is the first 'line' of three lines) - test: - if: "$LineCount != 1 and not(self::m:piecewise)" # 'cas' already ends with an 's', no need to add one when plural - then: [ct: "s"] # plural (not for 'cas' which is invariant) + then: [CT: "s"] # plural (not for 'cas' which is invariant) - pause: short - x: "*" - pause: long @@ -547,15 +547,15 @@ - pause: medium - test: - if: "parent::m:piecewise" - then: [t: "cas"] # phrase('case' 1 of 10 cases) + then: [T: "cas"] # phrase('case' 1 of 10 cases) - else_if: "parent::m:system-of-equations" - then: [t: "équation"] # phrase('equation' 1 of 10 equations) - else: [t: "ligne"] # phrase('line 1 of 10 lines) + then: [T: "équation"] # phrase('equation' 1 of 10 equations) + else: [T: "ligne"] # phrase('line 1 of 10 lines) - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" - test: if: "self::m:mlabeledtr" then: - - t: "avec étiquette" # phrase(the diagram is complete 'with label') + - T: "avec étiquette" # phrase(the diagram is complete 'with label') - x: "*[1]/*" - test: if: "not(contains(@data-intent-property, ':continued-row:'))" @@ -601,14 +601,14 @@ replace: - test: if: "self::m:determinant" # just need to check the first bracket since we know it must be (, [, or | - then: [t: "le"] # phrase('the' 1 by 1 determinant) - else: [t: "la"] # phrase('the' 1 by 1 matrix M) + then: [T: "le"] # phrase('the' 1 by 1 determinant) + else: [T: "la"] # phrase('the' 1 by 1 matrix M) - test: if: "self::m:determinant" - then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') - else: [t: "matrice"] # phrase(the 2 by 2 'matrix') - - t: "1 par 1" # phrase(the '1 by 1' matrix) - - t: "avec l'élément" # phrase(the 2 by 2 matrix 'containing the element' x) + then: [T: "déterminant"] # phrase(the 2 by 2 'determinant') + else: [T: "matrice"] # phrase(the 2 by 2 'matrix') + - T: "1 par 1" # phrase(the '1 by 1' matrix) + - T: "avec l'élément" # phrase(the 2 by 2 matrix 'containing the element' x) - x: "*[1]/*" # simpler reading methods for special case matrices @@ -617,10 +617,10 @@ # select all the non-zero entries -- if there are none of them, then it is a zero matrix match: "not( */*/*[not(self::m:mn and .= 0)] )" replace: - - t: "la" # phrase('the' 1 by 2 matrix M) - - t: "matrice zéro" # phrase(the 2 by 2 'zero matrix') + - T: "la" # phrase('the' 1 by 2 matrix M) + - T: "matrice zéro" # phrase(the 2 by 2 'zero matrix') - x: count(*) - - t: "par" # phrase(the 1 'by' 2 matrix) + - T: "par" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - pause: long @@ -632,10 +632,10 @@ - "not( */*[count(preceding-sibling::*) = count(../preceding-sibling::*)]/*[not(self::m:mn and .= 1)] ) and " # on-diagonal - "not( */*[count(preceding-sibling::*) != count(../preceding-sibling::*)]/*[not(self::m:mn and .= 0)] )" # off-diagonal replace: - - t: "la" # phrase('the' 1 by 2 matrix M) - - t: "matrice identité" # phrase(the 2 by 2 'identity matrix') + - T: "la" # phrase('the' 1 by 2 matrix M) + - T: "matrice identité" # phrase(the 2 by 2 'identity matrix') - x: count(*) - - t: "par" # phrase(the 1 'by' 2 matrix) + - T: "par" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - pause: long @@ -649,10 +649,10 @@ - " [count(../preceding-sibling::*)!=count(../../preceding-sibling::*)]" - " )" replace: - - t: "la" # phrase('the' 1 by 2 matrix) - - t: "matrice diagonale" # phrase(the 2 by 2 'diagonal matrix') + - T: "la" # phrase('the' 1 by 2 matrix) + - T: "matrice diagonale" # phrase(the 2 by 2 'diagonal matrix') - x: count(*) - - t: "par" # phrase(the 1 'by' 2 matrix) + - T: "par" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - pause: long - insert: @@ -675,24 +675,24 @@ replace: - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "le"] # phrase('the' 2 by 2 vector) - masculine - else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine + then: [T: "le"] # phrase('the' 2 by 2 vector) - masculine + else: [T: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "vecteur"] # phrase(the 2 by 2 'vector') - else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + then: [T: "vecteur"] # phrase(the 2 by 2 'vector') + else: [T: "matrice"] # phrase(the 2 by 2 'matrix') - x: count(*) - - t: "par 1 colonne" # phrase(the 2 'by 1 column' matrix) + - T: "par 1 colonne" # phrase(the 2 'by 1 column' matrix) - pause: long - x: "*/*" - test: if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" then: - - t: "fin" # phrase('end' of matrix) + - T: "fin" # phrase('end' of matrix) - test: if: $ClearSpeak_Matrix = 'EndVector' - then: [t: "vecteur"] # phrase(the 2 column 'vector') - else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + then: [T: "vecteur"] # phrase(the 2 column 'vector') + else: [T: "matrice"] # phrase(the 2 by 2 'matrix') - name: default-column-matrix tag: matrix @@ -701,19 +701,19 @@ replace: - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "le"] # phrase('the' 2 by 2 vector) - masculine - else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine + then: [T: "le"] # phrase('the' 2 by 2 vector) - masculine + else: [T: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "vecteur"] # phrase(the 2 column 'vector') - else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + then: [T: "vecteur"] # phrase(the 2 column 'vector') + else: [T: "matrice"] # phrase(the 2 by 2 'matrix') - x: "count(*)" - - t: "par 1 colonne" # phrase(the 2 'by 1 column' matrix) + - T: "par 1 colonne" # phrase(the 2 'by 1 column' matrix) - pause: long - x: "*" # select the rows (mtr) - test: if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "fin de la matrice"] # phrase(the 'end of matrix' has been reached) + then: [T: "fin de la matrice"] # phrase(the 'end of matrix' has been reached) - name: 1x2-or-3-matrix tag: matrix @@ -726,25 +726,25 @@ replace: - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "le"] # phrase('the' 2 by 2 vector) - masculine - else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine + then: [T: "le"] # phrase('the' 2 by 2 vector) - masculine + else: [T: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "vecteur"] # phrase('the 1 by' 2 row 'vector') - else: [t: "matrice"] # phrase('the 1 by' 2 'matrix') - - t: "1 par" # phrase('the 1 by' 2 matrix) + then: [T: "vecteur"] # phrase('the 1 by' 2 row 'vector') + else: [T: "matrice"] # phrase('the 1 by' 2 'matrix') + - T: "1 par" # phrase('the 1 by' 2 matrix) - x: count(*/*) - - t: "rangée" # phrase(the 1 by 4 'row' matrix) + - T: "rangée" # phrase(the 1 by 4 'row' matrix) - pause: long - x: "*/*" - test: if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" then: - - t: "fin" # phrase(the 'end' of matrix has been reached) + - T: "fin" # phrase(the 'end' of matrix has been reached) - test: if: $ClearSpeak_Matrix = 'EndMatrix' - then: [t: "matrice"] # phrase(the 2 by 2 'matrix') - else: [t: "vecteur"] # phrase(the 2 by 1 'vector') + then: [T: "matrice"] # phrase(the 2 by 2 'matrix') + else: [T: "vecteur"] # phrase(the 2 by 1 'vector') - name: default-row-matrix tag: matrix @@ -753,26 +753,26 @@ replace: - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "le"] # phrase('the' 2 by 2 vector) - masculine - else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine + then: [T: "le"] # phrase('the' 2 by 2 vector) - masculine + else: [T: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "vecteur"] # phrase(the 2 by 1 'vector') - else: [t: "matrice"] # phrase(the 2 by 2 'matrix') - - t: "1 par" # phrase('the 1 by' 2 matrix) + then: [T: "vecteur"] # phrase(the 2 by 1 'vector') + else: [T: "matrice"] # phrase(the 2 by 2 'matrix') + - T: "1 par" # phrase('the 1 by' 2 matrix) - x: "count(*/*)" - - t: "rangée" # phrase(the 1 by 2 'row' matrix) + - T: "rangée" # phrase(the 1 by 2 'row' matrix) - pause: long - pause: medium - x: "*/*" # select the cols (mtd) - test: if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" then: - - t: "fin" # phrase(the 'end' of matrix has been reached) + - T: "fin" # phrase(the 'end' of matrix has been reached) - test: if: $ClearSpeak_Matrix = 'EndMatrix' - then: [t: "matrice"] # phrase(the 2 by 2 'matrix') - else: [t: "vecteur"] # phrase(the 2 by 1 'vector') + then: [T: "matrice"] # phrase(the 2 by 2 'matrix') + else: [T: "vecteur"] # phrase(the 2 by 1 'vector') - name: simple-small-matrix tag: [matrix, determinant] @@ -784,25 +784,25 @@ replace: - test: if: "self::m:determinant" - then: [t: "le"] # phrase('the' 2 by 2 determinant) - masculine - else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine + then: [T: "le"] # phrase('the' 2 by 2 determinant) - masculine + else: [T: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "self::m:determinant" - then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') - else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + then: [T: "déterminant"] # phrase(the 2 by 2 'determinant') + else: [T: "matrice"] # phrase(the 2 by 2 'matrix') - x: count(*) - - t: "par" # phrase(the 1 'by' 2 matrix) + - T: "par" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - pause: long - x: "*" - test: if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" then: - - t: "fin" # phrase(the 'end' of matrix has been reached) + - T: "fin" # phrase(the 'end' of matrix has been reached) - test: if: "self::m:determinant" - then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') - else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + then: [T: "déterminant"] # phrase(the 2 by 2 'determinant') + else: [T: "matrice"] # phrase(the 2 by 2 'matrix') - name: default-matrix tag: [matrix, determinant] @@ -811,25 +811,25 @@ replace: - test: if: "self::m:determinant" - then: [t: "le"] # phrase('the' 2 by 2 determinant) - masculine - else: [t: "la"] # phrase('the' 2 by 2 matrix) - feminine + then: [T: "le"] # phrase('the' 2 by 2 determinant) - masculine + else: [T: "la"] # phrase('the' 2 by 2 matrix) - feminine - test: if: "self::m:determinant" - then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') - else: [t: "matrice"] # phrase(the 2 by 2 'matrix') + then: [T: "déterminant"] # phrase(the 2 by 2 'determinant') + else: [T: "matrice"] # phrase(the 2 by 2 'matrix') - x: "count(*)" - - t: "par" # phrase(the 1 'by' 2 matrix) + - T: "par" # phrase(the 1 'by' 2 matrix) - x: "count(*[self::m:mtr][1]/*)" - pause: long - x: "*" - test: if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" then: - - t: "fin" # phrase(the 'end' of matrix has been reached) + - T: "fin" # phrase(the 'end' of matrix has been reached) - test: if: "self::m:determinant" - then: [t: "déterminant"] # phrase(the 2 by 2 'determinant') - else: [t: "matrice"] # phrase(the 2 by 2 'matrix's) + then: [T: "déterminant"] # phrase(the 2 by 2 'determinant') + else: [T: "matrice"] # phrase(the 2 by 2 'matrix's) - name: chemistry-msub tag: [chemical-formula] @@ -838,7 +838,7 @@ - x: "*[2]" - test: if: "$Verbosity='Verbose' or $Verbosity='Medium'" - then: [t: "indice"] # phrase(H 'subscript' 2) + then: [T: "indice"] # phrase(H 'subscript' 2) - x: "*[3]" - name: dimension-by @@ -847,7 +847,7 @@ replace: - insert: nodes: "*" - replace: [t: "par", pause: auto] # phrase(3 'by' 5 matrix) + replace: [T: "par", pause: auto] # phrase(3 'by' 5 matrix) - name: chemistry-msup tag: [chemical-formula] @@ -856,10 +856,10 @@ - x: "*[2]" - test: if: "$Verbosity='Verbose' or $Verbosity='Medium'" - then: [t: "exposant"] # phrase(H 'superscript' 2) + then: [T: "exposant"] # phrase(H 'superscript' 2) # else_test: # if: "$Verbosity='Medium'" - # then: [t: "super"] # phrase(H 'super' 2) + # then: [T: "super"] # phrase(H 'super' 2) - x: "*[3]" - test: if: "following-sibling::*[1][.='+' or .='-']" # a little lazy -- assumes chemistry superscripts end with + or - @@ -887,7 +887,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "exposant"] # phrase(H 'superscript' 2) + then: [T: "exposant"] # phrase(H 'superscript' 2) - x: "$Prescripts[2]" - pause: "short" - test: @@ -895,7 +895,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "indice"] # phrase(a 'subscript' may be used to indicate an index) + then: [T: "indice"] # phrase(a 'subscript' may be used to indicate an index) - x: "$Prescripts[1]" - pause: "short" - test: @@ -906,7 +906,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "exposant"] # phrase(H 'superscript' 2) + then: [T: "exposant"] # phrase(H 'superscript' 2) - x: "$Prescripts[4]" - pause: "short" - test: @@ -914,7 +914,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "indice"] # phrase(H 'subscript' 2) + then: [T: "indice"] # phrase(H 'subscript' 2) - x: "$Prescripts[3]" - pause: "short" - x: "*[1]" # base @@ -926,7 +926,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "indice"] # phrase(phrase(H 'subscript' 2) + then: [T: "indice"] # phrase(phrase(H 'subscript' 2) - x: "$Postscripts[1]" - pause: "short" - test: @@ -934,7 +934,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "exposant"] # phrase(H 'superscript' 2) + then: [T: "exposant"] # phrase(H 'superscript' 2) - x: "$Postscripts[2]" - pause: "short" - test: @@ -945,7 +945,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "indice"] # phrase(H 'subscript' 2) + then: [T: "indice"] # phrase(H 'subscript' 2) - x: "$Postscripts[3]" - pause: "short" - test: @@ -953,7 +953,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "exposant"] # phrase(H 'superscript' 2) + then: [T: "exposant"] # phrase(H 'superscript' 2) - x: "$Postscripts[4]" - pause: "short" - test: @@ -964,7 +964,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "indice"] # phrase(H 'subscript' 2) + then: [T: "indice"] # phrase(H 'subscript' 2) - x: "$Postscripts[5]" - pause: "short" - test: @@ -972,7 +972,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "exposant"] # phrase(H 'superscript' 2) + then: [T: "exposant"] # phrase(H 'superscript' 2) - x: "$Postscripts[6]" - pause: "short" - test: @@ -983,7 +983,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "indice"] # phrase(H 'subscript' 2) + then: [T: "indice"] # phrase(H 'subscript' 2) - x: "$Postscripts[7]" - pause: "short" - test: @@ -991,7 +991,7 @@ then: - test: if: "$Verbosity='Medium' or $Verbosity='Verbose'" - then: [t: "exposant"] # phrase(H 'superscript' 2) + then: [T: "exposant"] # phrase(H 'superscript' 2) - x: "$Postscripts[8]" - pause: "short" - test: @@ -1009,7 +1009,7 @@ match: "." replace: - bookmark: "@id" - - spell: text() + - SPELL: text() - pause: short - name: chemical-state @@ -1019,12 +1019,12 @@ - bookmark: "*[1]/@id" - test: - if: ".='s'" - then: [t: "solide"] # phrase(Boron is a 'solid' in its natural state) + then: [T: "solide"] # phrase(Boron is a 'solid' in its natural state) - else_if: ".='l'" - then: [t: "liquide"] # phrase(water is a 'liquid') + then: [T: "liquide"] # phrase(water is a 'liquid') - else_if: ".='g'" - then: [t: "gaz"] # phrase(hydrogen is a 'gas' ) - else: [t: "aqueux"] # phrase(an 'aqueous' solution is contained in water) + then: [T: "gaz"] # phrase(hydrogen is a 'gas' ) + else: [T: "aqueux"] # phrase(an 'aqueous' solution is contained in water) - pause: short - name: chemical-formula-operator-bond @@ -1035,13 +1035,13 @@ - bookmark: "@id" - test: - if: ".='-' or .=':'" - then: [t: "liaison simple"] # phrase(a 'single bond' is formed when two atoms share one pair of electrons) + then: [T: "liaison simple"] # phrase(a 'single bond' is formed when two atoms share one pair of electrons) - else_if: ".='=' or .='∷'" - then: [t: "liaison double"] # phrase(a 'double bond' may occur when two atoms share two pairs of electrons) + then: [T: "liaison double"] # phrase(a 'double bond' may occur when two atoms share two pairs of electrons) - else_if: ".='≡'" - then: [t: "liaison triple"] # phrase(a 'triple bond' occurs when two atoms share three pairs of electrons) + then: [T: "liaison triple"] # phrase(a 'triple bond' occurs when two atoms share three pairs of electrons) - else_if: ".='≣'" - then: [t: "liaison quadruple"] # phrase(a 'quadruple bond' occurs when two atoms share four pairs of electrons) + then: [T: "liaison quadruple"] # phrase(a 'quadruple bond' occurs when two atoms share four pairs of electrons) else: [x: "text()"] - name: chemical-formula-operator @@ -1060,14 +1060,14 @@ - if: ".='→' or .='⟶'" then_test: if: "$Verbosity='Terse'" - then: [t: "forment"] # phrase(hydrogen and oxygen 'forms' water ) - else: [t: "réagissent pour former"] # phrase(hydrogen and oxygen 'reacts to form' water) + then: [T: "forment"] # phrase(hydrogen and oxygen 'forms' water ) + else: [T: "réagissent pour former"] # phrase(hydrogen and oxygen 'reacts to form' water) - else_if: ".='⇌' or .='🣑'" # U+01F8D1 - then: [t: "est en équilibre avec"] # phrase(a reactant 'is in equilibrium with' a product) + then: [T: "est en équilibre avec"] # phrase(a reactant 'is in equilibrium with' a product) - else_if: ".='🣓'" # U+1F8D3 - then: [t: "est en équilibre biaisé vers la gauche avec"] # phrase(the reactant 'is in equilibrium biased to the left with' the product) + then: [T: "est en équilibre biaisé vers la gauche avec"] # phrase(the reactant 'is in equilibrium biased to the left with' the product) - else_if: ".='🣒'" # U+1F8D2 - then: [t: "est en équilibre biaisé vers la droite avec"] # phrase(the reactant 'is in equilibrium biased to the right with' the product) + then: [T: "est en équilibre biaisé vers la droite avec"] # phrase(the reactant 'is in equilibrium biased to the right with' the product) else: [x: "*"] - name: chemical-equation-operator @@ -1081,7 +1081,7 @@ tag: none match: "../../*[self::m:chemical-formula or self::m:chemical-nuclide]" replace: - - t: "" # don't say anything + - T: "" # don't say anything - name: ignore-intent-wrapper tag: intent-wrapper diff --git a/Rules/Languages/fr/SharedRules/geometry.yaml b/Rules/Languages/fr/SharedRules/geometry.yaml index b5ab22a7e..636fc214d 100644 --- a/Rules/Languages/fr/SharedRules/geometry.yaml +++ b/Rules/Languages/fr/SharedRules/geometry.yaml @@ -7,12 +7,12 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "le segment de droite de" + - T: "le segment de droite de" - x: "*[1]" - - t: "à" + - T: "à" - x: "*[2]" else: - - t: "segment" + - T: "segment" - x: "*[1]" - x: "*[2]" @@ -23,12 +23,12 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "la demi-droite de" + - T: "la demi-droite de" - x: "*[1]" - - t: "à" + - T: "à" - x: "*[2]" else: - - t: "demi-droite" + - T: "demi-droite" - x: "*[1]" - x: "*[2]" @@ -38,8 +38,8 @@ replace: - test: if: "$Verbosity='Verbose'" - then: [t: "l'"] - - t: "arc" + then: [T: "l'"] + - T: "arc" - x: "*[1]" - x: "*[2]" @@ -50,9 +50,9 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "la mesure de l'angle" + - T: "la mesure de l'angle" else: - - t: "mesure de l'angle" + - T: "mesure de l'angle" - x: "*[1]" - x: "*[2]" - x: "*[3]" @@ -63,16 +63,16 @@ replace: - test: if: "$Verbosity='Verbose'" - then: [t: "le"] - - t: "point" + then: [T: "le"] + - T: "point" - test: if: "$Verbosity='Verbose'" - then: [t: "de coordonnées"] + then: [T: "de coordonnées"] - pause: short - insert: nodes: "*" - replace: [t: "virgule", pause: auto] + replace: [T: "virgule", pause: auto] - pause: short - test: if: "($SpeechStyle='ClearSpeak' and $Verbosity='Verbose') or not(IsNode(*[last()],'leaf'))" - then: [t: "fin du point"] + then: [T: "fin du point"] diff --git a/Rules/Languages/fr/SharedRules/linear-algebra.yaml b/Rules/Languages/fr/SharedRules/linear-algebra.yaml index ce8a03dcd..71a8ca747 100644 --- a/Rules/Languages/fr/SharedRules/linear-algebra.yaml +++ b/Rules/Languages/fr/SharedRules/linear-algebra.yaml @@ -7,16 +7,16 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "le" - - t: "déterminant" + - T: "le" + - T: "déterminant" - test: if: "$Verbosity!='Terse'" then: - - t: "de" + - T: "de" - x: "*[1]" - test: if: "not(IsNode(*[1], 'simple')) and $Impairment = 'Blindness'" - then: [t: "fin du déterminant"] + then: [T: "fin du déterminant"] - name: subscripted-norm tag: subscripted-norm @@ -25,11 +25,11 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "la" + - T: "la" - x: "*[2]" - - t: "norme" + - T: "norme" - test: if: "$Verbosity!='Terse'" then: - - t: "de" + - T: "de" - x: "*[1]" diff --git a/Rules/Languages/fr/SimpleSpeak_Rules.yaml b/Rules/Languages/fr/SimpleSpeak_Rules.yaml index 0bc84e0c9..160b8e954 100644 --- a/Rules/Languages/fr/SimpleSpeak_Rules.yaml +++ b/Rules/Languages/fr/SimpleSpeak_Rules.yaml @@ -23,7 +23,7 @@ tag: mn match: "starts-with(text(), '-')" replace: - - t: "moins" + - T: "moins" - x: "translate(text(), '-_', '')" - name: default @@ -32,17 +32,17 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "la"] - - t: "racine carrée" + then: [T: "la"] + - T: "racine carrée" - test: if: "$Verbosity!='Terse'" - then: [t: "de"] + then: [T: "de"] else: [pause: short] - x: "*[1]" - pause: short - test: if: "not(IsNode(*[1], 'leaf')) and $Impairment = 'Blindness'" - then: [t: "fin de racine", pause: medium] + then: [T: "fin de racine", pause: medium] - name: default tag: root @@ -50,28 +50,28 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "la"] + then: [T: "la"] - test: if: "*[2][self::m:mn and not(contains(., '.'))]" then_test: - if: "*[2][.='2']" - then: [t: "racine carrée"] + then: [T: "racine carrée"] - else_if: "*[2][.='3']" - then: [t: "racine cubique"] + then: [T: "racine cubique"] - else: - x: "*[2]" - - t: "ième racine" + - T: "ième racine" else: - x: "*[2]" - - t: "racine" + - T: "racine" - test: if: "$Verbosity!='Terse'" - then: [t: "de"] + then: [T: "de"] - x: "*[1]" - pause: short - test: if: "not(IsNode(*[1], 'leaf')) and $Impairment = 'Blindness'" - then: [t: "fin de racine", pause: medium] + then: [T: "fin de racine", pause: medium] - name: common-fraction tag: fraction @@ -103,7 +103,7 @@ - "BaseNode(*[2])[contains(@data-intent-property, ':unit')] " replace: - x: "*[1]" - - t: "par" + - T: "par" - x: "*[2]" - name: simple @@ -113,7 +113,7 @@ - "not(ancestor::*[name() != 'mrow'][1]/self::m:fraction)" replace: - x: "*[1]" - - t: "sur" + - T: "sur" - x: "*[2]" - pause: short @@ -123,13 +123,13 @@ replace: - test: if: "$Impairment = 'Blindness'" - then: [t: "fraction"] + then: [T: "fraction"] - pause: short - x: "*[1]" - test: if: "not(IsNode(*[1],'leaf'))" then: [pause: short] - - t: "sur" + - T: "sur" - test: if: "not(IsNode(*[2],'leaf'))" then: [pause: short] @@ -137,14 +137,14 @@ - pause: short - test: if: "$Impairment = 'Blindness'" - then: [t: "fin de fraction"] + then: [T: "fin de fraction"] - pause: medium - name: inverse-function tag: inverse-function match: "." replace: - - t: "inverse" + - T: "inverse" - x: "*[1]" - name: function-squared-or-cubed @@ -157,8 +157,8 @@ - bookmark: "*[2]/@id" - test: if: "*[2][.=2]" - then: [t: "au carré"] - else: [t: "au cube"] + then: [T: "au carré"] + else: [T: "au cube"] - name: function-power tag: power @@ -167,7 +167,7 @@ replace: - bookmark: "*[2]/@id" - x: "*[2]" - - t: "puissance de" + - T: "puissance de" - pause: short - x: "*[1]" @@ -179,15 +179,15 @@ - bookmark: "*[2]/@id" - test: if: "*[2][.=2]" - then: [t: "au carré"] - else: [t: "au cube"] + then: [T: "au carré"] + else: [T: "au cube"] - name: simple-integer tag: power match: "*[2][self::m:mn][not(contains(., '.'))]" replace: - x: "*[1]" - - t: "à la" + - T: "à la" - x: "*[2]" - name: simple-negative-integer @@ -197,7 +197,7 @@ - " *[1][self::m:mn][not(contains(., '.'))]]" replace: - x: "*[1]" - - t: "à la" + - T: "à la" - x: "*[2]" - name: simple-var @@ -205,7 +205,7 @@ match: "*[2][self::m:mi][string-length(.)=1]" replace: - x: "*[1]" - - t: "à la" + - T: "à la" - x: "*[2]" - pronounce: [text: "-ième", ipa: "jɛm", sapi5: "ième", eloquence: "ième"] @@ -214,7 +214,7 @@ match: "IsNode(*[2], 'leaf')" replace: - x: "*[1]" - - t: "à la" + - T: "à la" - x: "*[2]" - name: nested @@ -226,13 +226,13 @@ - " ]" replace: - x: "*[1]" - - t: "élevé à la" + - T: "élevé à la" - x: "*[2]" - pause: short - test: if: "$Impairment = 'Blindness'" then: - - t: "fin d'exposant" + - T: "fin d'exposant" - pause: short else: - pause: medium @@ -242,7 +242,7 @@ match: "." replace: - x: "*[1]" - - t: "élevé à la puissance" + - T: "élevé à la puissance" - x: "*[2]" - name: set @@ -252,15 +252,15 @@ - test: - if: "count(*)=0" then: - - t: "ensemble vide" + - T: "ensemble vide" - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" then: - - t: "ensemble de tous les" + - T: "ensemble de tous les" - x: "*[1]/*[1]" - - t: "tel que" + - T: "tel que" - x: "*[1]/*[3]" else: - - t: "ensemble" + - T: "ensemble" - x: "*[1]" - name: times @@ -286,7 +286,7 @@ - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" - " )" replace: - - t: "fois" + - T: "fois" - name: no-say-parens tag: mrow diff --git a/Rules/Languages/fr/overview.yaml b/Rules/Languages/fr/overview.yaml index b077f447a..96bbc366c 100644 --- a/Rules/Languages/fr/overview.yaml +++ b/Rules/Languages/fr/overview.yaml @@ -21,22 +21,22 @@ if: "IsNode(*[1], 'simple') and IsNode(*[2], 'simple')" then: - x: "*[1]" - - t: "sur" + - T: "sur" - x: "*[2]" else: - - t: "fraction" + - T: "fraction" - name: overview-default tag: [msqrt, "square-root"] match: "." replace: - - t: "racine carrée" + - T: "racine carrée" - test: if: "IsNode(*[1], 'simple')" then: - test: if: "$Verbosity!='Terse'" - then: [t: "de"] + then: [T: "de"] - x: "*[1]" - name: overview-default @@ -47,21 +47,21 @@ if: "*[2][self::m:mn]" then_test: - if: "*[2][.='2']" - then: [t: "racine carrée"] + then: [T: "racine carrée"] - else_if: "*[2][.='3']" - then: [t: "racine cubique"] + then: [T: "racine cubique"] - else: - x: "*[2]" - - t: "ième racine" + - T: "ième racine" else: - x: "*[2]" - - t: "racine" + - T: "racine" - test: if: "IsNode(*[1], 'simple')" then: - test: if: "$Verbosity!='Terse'" - then: [t: "de"] + then: [T: "de"] - x: "*[1]" - name: matrix-override @@ -70,24 +70,24 @@ - "*[2][self::m:mtable] and" - "(IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|'))" replace: - - t: "la" + - T: "la" - x: count(*[2]/*) - - t: "par" + - T: "par" - x: count(*[2]/*[self::m:mtr][1]/*) - test: if: "*[1][.='|']" - then: [t: "déterminant"] - else: [t: "matrice"] + then: [T: "déterminant"] + else: [T: "matrice"] - name: overview-default tag: mtable match: "." replace: - - t: "la" + - T: "la" - x: count(*[2]/*) - - t: "par" + - T: "par" - x: count(*[2]/*[self::m:mtr][1]/*) - - t: "table" + - T: "table" - name: short-mrow tag: mrow @@ -111,6 +111,6 @@ - pause: auto - x: "*[5]" - pause: auto - - t: "et ainsi de suite" + - T: "et ainsi de suite" - include: "SimpleSpeak_Rules.yaml" diff --git a/Rules/Languages/fr/unicode.yaml b/Rules/Languages/fr/unicode.yaml index d305de42a..b1542a694 100644 --- a/Rules/Languages/fr/unicode.yaml +++ b/Rules/Languages/fr/unicode.yaml @@ -5,8 +5,8 @@ - "a-z": - test: if: "$TTS='none'" - then: [t: "."] # (en: '.', DeepL translation) - else: [spell: "'.'"] + then: [T: "."] # (en: '.', DeepL translation) + else: [SPELL: "'.'"] # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and # screen readers have options to use pitch changes or beeps instead of or in addition to say "cap" @@ -22,58 +22,58 @@ - pitch: value: "$CapitalLetters_Pitch" # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] + replace: [SPELL: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"] - test: if: "$CapitalLetters_UseWord" then_test: if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "majuscule"] # (en: 'cap', DeepL translation) + then: [T: "majuscule"] # (en: 'cap', DeepL translation) else: [x: "$SpeechOverrides_CapitalLetters"] - - "0-9": [t: "."] # (en: '.', DeepL: 'A') + - "0-9": [T: "."] # (en: '.', DeepL: 'A') - - " ": [t: " "] # 0x20 (en: ' ', DeepL: ' ') + - " ": [T: " "] # 0x20 (en: ' ', DeepL: ' ') - "!": # 0x21 - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" then_test: if: "$Verbosity = 'Terse'" - then: [t: "bang"] # 0x21 (DeepL translation) - else: [t: "point d'exclamation"] # 0x21 (en: 'exclamation point') - else: [t: "factorielle"] # 0x21 (en: 'factorial') + then: [T: "bang"] # 0x21 (DeepL translation) + else: [T: "point d'exclamation"] # 0x21 (en: 'exclamation point') + else: [T: "factorielle"] # 0x21 (en: 'factorial') - - "\"": [t: "guillemet"] # 0x22 (en: 'quotation mark') - - "#": [t: "dièse"] # 0x23 (en: 'number') - - "$": [t: "dollar"] # 0x24 - - "%": [t: "pourcent"] # 0x25 (en: 'percent') - - "&": [t: "esperluette"] # 0x26 (en: 'ampersand') - - "'": [t: "apostrophe"] # 0x27 (SRE: 'prime') + - "\"": [T: "guillemet"] # 0x22 (en: 'quotation mark') + - "#": [T: "dièse"] # 0x23 (en: 'number') + - "$": [T: "dollar"] # 0x24 + - "%": [T: "pourcent"] # 0x25 (en: 'percent') + - "&": [T: "esperluette"] # 0x26 (en: 'ampersand') + - "'": [T: "apostrophe"] # 0x27 (SRE: 'prime') - "(": # 0x28 - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' then_test: if: "$Verbosity='Terse'" - then: [t: "ouvert"] # 0x28 (en: 'open', DeepL translation) - else: [t: "parenthèse gauche"] # 0x28 (en: 'open paren', MathPlayer: 'parenthèse ouvrante', DeepL: 'parenthèse ouverte') - else: [t: "parenthèse gauche"] # 0x28 (en: 'left paren', MathPlayer: 'parenthèse ouvrante') + then: [T: "ouvert"] # 0x28 (en: 'open', DeepL translation) + else: [T: "parenthèse gauche"] # 0x28 (en: 'open paren', MathPlayer: 'parenthèse ouvrante', DeepL: 'parenthèse ouverte') + else: [T: "parenthèse gauche"] # 0x28 (en: 'left paren', MathPlayer: 'parenthèse ouvrante') - ")": # 0x29 - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' then_test: if: "$Verbosity='Terse'" - then: [t: "fermer"] # 0x29 (en: 'close', DeepL translation) - else: [t: "parenthèse droite"] # 0x29 (en: 'close paren', MathPlayer: 'parenthèse fermante', DeepL: 'parenthèse fermée') - else: [t: "parenthèse droite"] # 0x29 (en: 'right paren', MathPlayer: 'parenthèse fermante') + then: [T: "fermer"] # 0x29 (en: 'close', DeepL translation) + else: [T: "parenthèse droite"] # 0x29 (en: 'close paren', MathPlayer: 'parenthèse fermante', DeepL: 'parenthèse fermée') + else: [T: "parenthèse droite"] # 0x29 (en: 'right paren', MathPlayer: 'parenthèse fermante') - "*": # 0x2a test: if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [t: "astérisque"] # 0x2a (en: 'star', DeepL translation) - else: [t: "fois"] # 0x2a (en: 'times') - - "+": [t: "plus"] # 0x2b (MathPlayer: 'pluce') + then: [T: "astérisque"] # 0x2a (en: 'star', DeepL translation) + else: [T: "fois"] # 0x2a (en: 'times') + - "+": [T: "plus"] # 0x2b (MathPlayer: 'pluce') - ",": # 0x2c # the following deals with the interaction of "," with "…" which sometimes wants the ',' to be silent # that this test is here and not with "…" is not ideal, but seems simplest @@ -86,67 +86,67 @@ # except if expression starts with '…' - "../*[1][.='…'] " then: - - t: "virgule" # (en: 'comma') + - T: "virgule" # (en: 'comma') - test: if: "$Verbosity != Terse" then: [pause: short] # else silent - - "-": [t: "moins"] # 0x2d (en: 'minus') + - "-": [T: "moins"] # 0x2d (en: 'minus') - ".": # 0x2e - test: if: "parent::*[1][self::m:mn]" - then: [t: "point"] # (DeepL translation) - else: [t: "point"] # (en: 'dot') + then: [T: "point"] # (DeepL translation) + else: [T: "point"] # (en: 'dot') - "/": # 0x2f - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "barre oblique"] # 0x2f (en: 'slash', DeepL translation) - else: [t: "divisé par"] # 0x2f (en: 'divided by') + then: [T: "barre oblique"] # 0x2f (en: 'slash', DeepL translation) + else: [T: "divisé par"] # 0x2f (en: 'divided by') - - ":": [t: "deux points"] # 0x3a (en: 'colon') - - ";": [t: "point virgule"] # 0x3b (en: 'semicolon') + - ":": [T: "deux points"] # 0x3a (en: 'colon') + - ";": [T: "point virgule"] # 0x3b (en: 'semicolon') - "<": # 0x3c - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "inférieur à" # (en: 'less than') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "inférieur à" # (en: 'less than') - "=": # 0x3d - test: if: "$Verbosity!='Terse'" - then: [t: "est égal à"] # (en: 'is equal to', DeepL translation) - else: [t: "égale"] # (en: 'equals') + then: [T: "est égal à"] # (en: 'is equal to', DeepL translation) + else: [T: "égale"] # (en: 'equals') - ">": # 0x3e - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "supérieur à" # (en: 'greater than') - - "?": [t: "point d'interrogation"] # 0x3f (en: 'question mark') - - "@": [t: "arobase"] # 0x40 (en: 'at sign') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "supérieur à" # (en: 'greater than') + - "?": [T: "point d'interrogation"] # 0x3f (en: 'question mark') + - "@": [T: "arobase"] # 0x40 (en: 'at sign') - "[": # 0x5b - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "crochet ouvrant"] # (en: 'open bracket') - else: [t: "crochet gauche"] # (en: 'left bracket', MathPlayer: 'crochet ouvrant', DeepL: 'parenthèse gauche') - - "\\": [t: "crochet gauche"] # 0x5c (en: 'back slash', MathPlayer: 'crochet ouvrant', DeepL: 'barre oblique arrière') + then: [T: "crochet ouvrant"] # (en: 'open bracket') + else: [T: "crochet gauche"] # (en: 'left bracket', MathPlayer: 'crochet ouvrant', DeepL: 'parenthèse gauche') + - "\\": [T: "crochet gauche"] # 0x5c (en: 'back slash', MathPlayer: 'crochet ouvrant', DeepL: 'barre oblique arrière') - "]": # 0x5d - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "crochet fermant"] # (en: 'close bracket') - else: [t: "crochet droit"] # (en: 'right bracket', MathPlayer: 'crochet fermant', DeepL: 'parenthèse droite') + then: [T: "crochet fermant"] # (en: 'close bracket') + else: [T: "crochet droit"] # (en: 'right bracket', MathPlayer: 'crochet fermant', DeepL: 'parenthèse droite') - "^": # 0x5e - test: if: "parent::m:modified-variable or parent::m:mover" - then: [t: "accent circonflexe"] # (en: 'hat') - else: [t: "accent circonflexe"] # (en: 'caret') - - "_": [t: "tiret bas"] # 0x5f (en: 'under bar') - - "`": [t: "accent grave"] # 0x60 (en: 'grave') + then: [T: "accent circonflexe"] # (en: 'hat') + else: [T: "accent circonflexe"] # (en: 'caret') + - "_": [T: "tiret bas"] # 0x5f (en: 'under bar') + - "`": [T: "accent grave"] # 0x60 (en: 'grave') - "{": # 0x7b - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "accolade ouverte"] # (en: 'open brace', DeepL translation) - else: [t: "accolade gauche"] # (en: 'left brace', MathPlayer: 'accolade ouvrante') + then: [T: "accolade ouverte"] # (en: 'open brace', DeepL translation) + else: [T: "accolade gauche"] # (en: 'left brace', MathPlayer: 'accolade ouvrante') - "|": # 0x7c # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' - with: @@ -154,69 +154,69 @@ replace: - test: - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "ligne verticale"] # (en: 'vertical line', DeepL translation) + then: [T: "ligne verticale"] # (en: 'vertical line', DeepL translation) - else_if: "$SpeechStyle != 'ClearSpeak'" then_test: - if: "$DefaultToGiven" - then: [t: "sachant"] # (en: 'given', DeepL translation) + then: [T: "sachant"] # (en: 'given', DeepL translation) - else_if: "preceding-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))] and following-sibling::*[1][self::m:mn and not(contains(., $DecimalSeparators))]" - then: [t: "divise"] # (en: 'divides', DeepL translation) - else: [t: "ligne verticale"] # (en: 'vertical line') + then: [T: "divise"] # (en: 'divides', DeepL translation) + else: [T: "ligne verticale"] # (en: 'vertical line') - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" - then: [t: "ligne verticale"] # (en: 'vertical line', DeepL translation) + then: [T: "ligne verticale"] # (en: 'vertical line', DeepL translation) - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [t: "tel que"] # (en: 'such that', DeepL translation) + then: [T: "tel que"] # (en: 'such that', DeepL translation) - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [t: "sachant"] # (en: 'given', DeepL translation) - - else: [t: "divise"] # (en: 'divides') + then: [T: "sachant"] # (en: 'given', DeepL translation) + - else: [T: "divise"] # (en: 'divides') - "}": # 0x7d - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' - then: [t: "accolade fermée"] # (en: 'close brace') - else: [t: "accolade droite"] # (en: 'right brace', MathPlayer: 'accolade fermante') + then: [T: "accolade fermée"] # (en: 'close brace') + else: [T: "accolade droite"] # (en: 'right brace', MathPlayer: 'accolade fermante') - - "~": [t: "tilde"] # 0x7e + - "~": [T: "tilde"] # 0x7e - " ": # 0xa0 - test: # could be mtext in mtd or mtext in an mrow that is a concatenation of mtd's. Is there a better solution? if: "@data-empty-in-2D and not(ancestor::*[self::m:piecewise or self::m:system-of-equations or self::m:lines])" - then: [t: "vide"] # want to say something for fraction (etc) with empty child (en: 'empty', DeepL translation) - else: [t: ""] + then: [T: "vide"] # want to say something for fraction (etc) with empty child (en: 'empty', DeepL translation) + else: [T: ""] - - "¬": [t: "non"] # 0xac (en: 'not') - - "°": [t: "degrés"] # 0xb0 (en: 'degrees') - - "±": [t: "plus ou moins"] # 0xb1 (en: 'plus or minus') - - "´": [t: "accent aigu"] # 0xb4 (en: 'acute') + - "¬": [T: "non"] # 0xac (en: 'not') + - "°": [T: "degrés"] # 0xb0 (en: 'degrees') + - "±": [T: "plus ou moins"] # 0xb1 (en: 'plus or minus') + - "´": [T: "accent aigu"] # 0xb4 (en: 'acute') - "·": # 0xB7 - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" - then: [t: "point"] # (en: 'dot', DeepL translation) - else: [t: "fois"] # (en: 'times') + then: [T: "point"] # (en: 'dot', DeepL translation) + else: [T: "fois"] # (en: 'times') - "×": # 0xd7 - test: if: "$SpeechStyle = 'ClearSpeak'" then_test: - if: "$ClearSpeak_MultSymbolX = 'Auto'" - then: [t: "fois"] # (en: 'times', DeepL translation) + then: [T: "fois"] # (en: 'times', DeepL translation) - else_if: "$ClearSpeak_MultSymbolX = 'By'" - then: [t: "par"] # (en: 'by', DeepL translation) - else: [t: "multiplié par"] # (en: 'cross') + then: [T: "par"] # (en: 'by', DeepL translation) + else: [T: "multiplié par"] # (en: 'cross') else_test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "croix"] # (en: 'cross', DeepL translation) - else: [t: "multiplié par"] # (en: 'times') + then: [T: "croix"] # (en: 'cross', DeepL translation) + else: [T: "multiplié par"] # (en: 'times') - - "÷": [t: "divisé par"] # 0xf7 (en: 'divided by') - - "̀": [t: "diacritique accent grave"] # 0x300 (en: 'grave accent embellishment', DeepL: 'accent grave embellissement') - - "́": [t: "diacritique accent aigu"] # 0x301 (en: 'acute accent embellishment', DeepL: 'accent aigu') - - "̂": [t: "diacritique accent circonflexe"] # 0x302 (en: 'circumflex accent embellishment', DeepL: 'accent circonflexe fioriture') - - "̃": [t: "diacritique tilde"] # 0x303 (en: 'tilde embellishment', DeepL: 'tilde embellissement') - - "̄": [t: "diacritique macron"] # 0x304 (en: 'macron embellishment', DeepL: 'emblème macron') - - "̅": [t: "diacritique tiret haut"] # 0x305 (en: 'overbar embellishment', DeepL: 'embellissement de la barre supérieure') - - "̆": [t: "diacritique brève"] # 0x306 (en: 'breve', DeepL: 'breve') - - "̇": [t: "diacritique point en chef"] # 0x307 (en: 'dot above embellishment', DeepL: 'point au-dessus de la fioriture') + - "÷": [T: "divisé par"] # 0xf7 (en: 'divided by') + - "̀": [T: "diacritique accent grave"] # 0x300 (en: 'grave accent embellishment', DeepL: 'accent grave embellissement') + - "́": [T: "diacritique accent aigu"] # 0x301 (en: 'acute accent embellishment', DeepL: 'accent aigu') + - "̂": [T: "diacritique accent circonflexe"] # 0x302 (en: 'circumflex accent embellishment', DeepL: 'accent circonflexe fioriture') + - "̃": [T: "diacritique tilde"] # 0x303 (en: 'tilde embellishment', DeepL: 'tilde embellissement') + - "̄": [T: "diacritique macron"] # 0x304 (en: 'macron embellishment', DeepL: 'emblème macron') + - "̅": [T: "diacritique tiret haut"] # 0x305 (en: 'overbar embellishment', DeepL: 'embellissement de la barre supérieure') + - "̆": [T: "diacritique brève"] # 0x306 (en: 'breve', DeepL: 'breve') + - "̇": [T: "diacritique point en chef"] # 0x307 (en: 'dot above embellishment', DeepL: 'point au-dessus de la fioriture') # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - "Α-Ω": @@ -229,50 +229,50 @@ - pitch: value: "$CapitalLetters_Pitch" # note: processing of ranges converts '.' into the character, so it needs to be in quotes below - replace: [spell: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + replace: [SPELL: "translate('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - test: if: "$CapitalLetters_UseWord" then_test: if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "majuscule"] # (en: 'cap', DeepL translation) + then: [T: "majuscule"] # (en: 'cap', DeepL translation) else: [x: "$SpeechOverrides_CapitalLetters"] - - "α": [t: "alpha"] # 0x3b1 - - "β": [t: "bêta"] # 0x3b2 (en: 'beta') - - "γ": [t: "gamma"] # 0x3b3 - - "δ": [t: "delta"] # 0x3b4 - - "ε": [t: "epsilon"] # 0x3b5 - - "ζ": [t: "zêta"] # 0x3b6 (en: 'zeta') - - "η": [t: "êta"] # 0x3b7 (en: 'eta', DeepL: 'eta') - - "θ": [t: "thêta"] # 0x3b8 (en: 'theta') - - "ι": [t: "iota"] # 0x3b9 - - "κ": [t: "kappa"] # 0x3ba - - "λ": [t: "lambda"] # 0x3bb - - "μ": [t: "mû"] # 0x3bc (en: 'mu', DeepL: 'mu') - - "ν": [t: "nû"] # 0x3bd (en: 'nu', DeepL: 'nu') - - "ξ": [t: "xi"] # 0x3be (en: 'zai', DeepL: 'zai') - - "ο": [t: "omicron"] # 0x3bf - - "π": [t: "pi"] # 0x3c0 - - "ρ": [t: "rhô"] # 0x3c1 - - "ς": [t: "sigma final"] # 0x3c2 (en: 'final sigma') - - "σ": [t: "sigma"] # 0x3c3 - - "τ": [t: "tau"] # 0x3c4 - - "υ": [t: "upsilon"] # 0x3c5 - - "φ": [t: "phi"] # 0x3c6 - - "χ": [t: "chi"] # 0x3c7 - - "ψ": [t: "psi"] # 0x3c8 - - "ω": [t: "oméga"] # 0x3c9 (en: 'omega') - - "ϕ": [t: "phi"] # 0x3d5 (en: 'phi', DeepL: 'phi') - - "ϖ": [t: "pi"] # 0x3d6 (en: 'pi', DeepL: 'pi') - - "ϵ": [t: "epsilon"] # 0x3f5 - - "϶": [t: "epsilon inversé"] # 0x3f6 (en: 'reversed epsilon') + - "α": [T: "alpha"] # 0x3b1 + - "β": [T: "bêta"] # 0x3b2 (en: 'beta') + - "γ": [T: "gamma"] # 0x3b3 + - "δ": [T: "delta"] # 0x3b4 + - "ε": [T: "epsilon"] # 0x3b5 + - "ζ": [T: "zêta"] # 0x3b6 (en: 'zeta') + - "η": [T: "êta"] # 0x3b7 (en: 'eta', DeepL: 'eta') + - "θ": [T: "thêta"] # 0x3b8 (en: 'theta') + - "ι": [T: "iota"] # 0x3b9 + - "κ": [T: "kappa"] # 0x3ba + - "λ": [T: "lambda"] # 0x3bb + - "μ": [T: "mû"] # 0x3bc (en: 'mu', DeepL: 'mu') + - "ν": [T: "nû"] # 0x3bd (en: 'nu', DeepL: 'nu') + - "ξ": [T: "xi"] # 0x3be (en: 'zai', DeepL: 'zai') + - "ο": [T: "omicron"] # 0x3bf + - "π": [T: "pi"] # 0x3c0 + - "ρ": [T: "rhô"] # 0x3c1 + - "ς": [T: "sigma final"] # 0x3c2 (en: 'final sigma') + - "σ": [T: "sigma"] # 0x3c3 + - "τ": [T: "tau"] # 0x3c4 + - "υ": [T: "upsilon"] # 0x3c5 + - "φ": [T: "phi"] # 0x3c6 + - "χ": [T: "chi"] # 0x3c7 + - "ψ": [T: "psi"] # 0x3c8 + - "ω": [T: "oméga"] # 0x3c9 (en: 'omega') + - "ϕ": [T: "phi"] # 0x3d5 (en: 'phi', DeepL: 'phi') + - "ϖ": [T: "pi"] # 0x3d6 (en: 'pi', DeepL: 'pi') + - "ϵ": [T: "epsilon"] # 0x3f5 + - "϶": [T: "epsilon inversé"] # 0x3f6 (en: 'reversed epsilon') - - "–": [t: "tirait demi-cadratin"] # 0x2013 (en: 'en dash') - - "—": [t: "tiret cadratin"] # 0x2014 (en: 'em dash') - - "―": [t: "barre horizontalle"] # 0x2015 (en: 'horizontal bar') - - "‖": [t: "double ligne verticale"] # 0x2016 (en: 'double vertical line') + - "–": [T: "tirait demi-cadratin"] # 0x2013 (en: 'en dash') + - "—": [T: "tiret cadratin"] # 0x2014 (en: 'em dash') + - "―": [T: "barre horizontalle"] # 0x2015 (en: 'horizontal bar') + - "‖": [T: "double ligne verticale"] # 0x2016 (en: 'double vertical line') - "…": # 0x2026 test: if: @@ -280,11 +280,11 @@ # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' # speak '…' as 'and so on...' unless expr starts with '…' - "../*[1][.='…']" - then: [t: "point point point"] # (en: 'dot dot dot', DeepL translation) + then: [T: "point point point"] # (en: 'dot dot dot', DeepL translation) else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' if: "count(following-sibling::*) = 0" - then: [t: "et ainsi de suite"] # (en: 'and so on', DeepL translation) - else: [t: "points de suspension"] # (en: 'and so on up to') + then: [T: "et ainsi de suite"] # (en: 'and so on', DeepL translation) + else: [T: "points de suspension"] # (en: 'and so on up to') - "⁡": # 0x2061 - test: @@ -298,86 +298,86 @@ preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) )" - then: [t: "de"] # (en: 'of', DeepL translation) - - "⁢": [t: ""] # 0x2062 - - "⁣": [t: ""] # 0x2063 - - "⁤": [t: "et"] # 0x2064 (en: 'and', DeepL: 'et') - - "′": [t: "prime"] # 0x2032 - - "″": [t: "double prime"] # 0x2033 - - "‴": [t: "triple prime"] # 0x2034 + then: [T: "de"] # (en: 'of', DeepL translation) + - "⁢": [T: ""] # 0x2062 + - "⁣": [T: ""] # 0x2063 + - "⁤": [T: "et"] # 0x2064 (en: 'and', DeepL: 'et') + - "′": [T: "prime"] # 0x2032 + - "″": [T: "double prime"] # 0x2033 + - "‴": [T: "triple prime"] # 0x2034 - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - t: "triple prime" # (en: 'double-struck') - - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + - T: "triple prime" # (en: 'double-struck') + - SPELL: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - "℃": [t: "degré celsius"] # 0x2103 (en: 'degrees celsius', DeepL: 'degrés celsius') - - "℉": [t: "degré fahrenheit"] # 0x2109 (en: 'degrees fahrenheit', DeepL: 'degrés fahrenheit') + - "℃": [T: "degré celsius"] # 0x2103 (en: 'degrees celsius', DeepL: 'degrés celsius') + - "℉": [T: "degré fahrenheit"] # 0x2109 (en: 'degrees fahrenheit', DeepL: 'degrés fahrenheit') - "ℋℛℓ": # 0x210b - - t: "script" # (en: 'script', DeepL: 'script') - - spell: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℎ": [t: "constante de planck"] # 0x210e (en: 'planck constant') + - T: "script" # (en: 'script', DeepL: 'script') + - SPELL: "translate('.', 'ℋℛℓ', 'HRl')" + - "ℎ": [T: "constante de planck"] # 0x210e (en: 'planck constant') - "ℜ": # 0x211c - - t: "r gothique majuscule" # (en: 'fraktur', DeepL: 'fraktur') - - spell: "'R'" + - T: "r gothique majuscule" # (en: 'fraktur', DeepL: 'fraktur') + - SPELL: "'R'" - - "Ω": [t: "ohm"] # 0x2126 (en: 'ohms') - - "K": [t: "degré kelvin"] # 0x212a (en: 'kelvin') - - "Å": [t: "angstroms"] # 0x212b + - "Ω": [T: "ohm"] # 0x2126 (en: 'ohms') + - "K": [T: "degré kelvin"] # 0x212a (en: 'kelvin') + - "Å": [T: "angstroms"] # 0x212b - "ⅆⅇⅈⅉ": # 0x2146-9 - - t: "angstroms" # (en: 'double-struck italic') - - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + - T: "angstroms" # (en: 'double-struck italic') + - SPELL: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - "←": [t: "flèche vers la gauche"] # 0x2190 (en: 'leftwards arrow', SRE: 'flèche gauche') - - "↑": [t: "flèche vers le haut"] # 0x2191 (en: 'upwards arrow') + - "←": [T: "flèche vers la gauche"] # 0x2190 (en: 'leftwards arrow', SRE: 'flèche gauche') + - "↑": [T: "flèche vers le haut"] # 0x2191 (en: 'upwards arrow') - "→": # 0x2192 - test: if: "ancestor::*[2][self::m:limit]" - then: [t: "approche"] # (en: 'approaches', DeepL translation) - else: [t: "flèche vers la droite"] # (en: 'right arrow', MathPlayer: 'flèche vers la droite') + then: [T: "approche"] # (en: 'approaches', DeepL translation) + else: [T: "flèche vers la droite"] # (en: 'right arrow', MathPlayer: 'flèche vers la droite') - - "↓": [t: "flèche vers le bas"] # 0x2193 (en: 'downwards arrow') - - "⇒": [t: "double flèche vers la droite"] # 0x21d2 (en: 'rightwards double arrow', SRE: 'double flèche droite') - - "∀": [t: "pour tous"] # 0x2200 (en: 'for all') + - "↓": [T: "flèche vers le bas"] # 0x2193 (en: 'downwards arrow') + - "⇒": [T: "double flèche vers la droite"] # 0x21d2 (en: 'rightwards double arrow', SRE: 'double flèche droite') + - "∀": [T: "pour tous"] # 0x2200 (en: 'for all') - "∂": # 0x2202 - test: if: "$Verbosity='Terse'" - then: [t: "partiel"] # (en: 'partial', DeepL translation) - else: [t: "dérivée partielle"] # (en: 'partial derivative') - - "∃": [t: "il existe"] # 0x2203 (en: 'there exists') - - "∄": [t: "il n'existe pas"] # 0x2204 (en: 'there does not exist') - - "∅": [t: "ensemble vide"] # 0x2205 (en: 'empty set') + then: [T: "partiel"] # (en: 'partial', DeepL translation) + else: [T: "dérivée partielle"] # (en: 'partial derivative') + - "∃": [T: "il existe"] # 0x2203 (en: 'there exists') + - "∄": [T: "il n'existe pas"] # 0x2204 (en: 'there does not exist') + - "∅": [T: "ensemble vide"] # 0x2205 (en: 'empty set') - "∆": # 0x2206 - test: if: "$Verbosity!='Terse'" - then: [t: "le"] # (en: 'the', DeepL translation) - - t: "laplacien de" # (en: 'laplacian of') + then: [T: "le"] # (en: 'the', DeepL translation) + - T: "laplacien de" # (en: 'laplacian of') - "∈": # 0x2208 - test: if: "$SpeechStyle != 'ClearSpeak'" then: - test: if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "un élément de" # (en: 'an element of') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "un élément de" # (en: 'an element of') # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set then_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "en"] # (en: 'in', DeepL translation) + then: [T: "en"] # (en: 'in', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "membre de"] # (en: 'member of', DeepL translation) + then: [T: "membre de"] # (en: 'member of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "élément de"] # (en: 'element of', DeepL translation) - - else: [t: "appartient à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + then: [T: "élément de"] # (en: 'element of', DeepL translation) + - else: [T: "appartient à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "est membre de"] # (en: 'is a member of', DeepL translation) + then: [T: "est membre de"] # (en: 'is a member of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "est un élément de"] # (en: 'is an element of', DeepL translation) + then: [T: "est un élément de"] # (en: 'is an element of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "est dans"] # (en: 'is in', DeepL translation) - - else: [t: "appartient à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + then: [T: "est dans"] # (en: 'is in', DeepL translation) + - else: [T: "appartient à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - "∉": # 0x2209 # rule is identical to 0x2208 - test: @@ -385,164 +385,164 @@ then: # - test: # if: "$Verbosity!='Terse'" - # then: [t: "est"] # (en: 'is', DeepL translation) - - t: "n'appartient pas à" # (en: 'not an element of') + # then: [T: "est"] # (en: 'is', DeepL translation) + - T: "n'appartient pas à" # (en: 'not an element of') # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set then_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "pas dans"] # (en: 'not in', DeepL translation) + then: [T: "pas dans"] # (en: 'not in', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "n'est pas membre de"] # (en: 'not member of', DeepL translation) + then: [T: "n'est pas membre de"] # (en: 'not member of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "n'est pas un élément de"] # (en: 'not element of', DeepL translation) - - else: [t: "n'appartient pas à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + then: [T: "n'est pas un élément de"] # (en: 'not element of', DeepL translation) + - else: [T: "n'appartient pas à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "n'est pas membre de"] # (en: 'is not a member of', DeepL translation) + then: [T: "n'est pas membre de"] # (en: 'is not a member of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "n'est pas un élément de"] # (en: 'is not an element of', DeepL translation) + then: [T: "n'est pas un élément de"] # (en: 'is not an element of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "n'est pas dans"] # (en: 'is not in', DeepL translation) - - else: [t: "n'appartient pas à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + then: [T: "n'est pas dans"] # (en: 'is not in', DeepL translation) + - else: [T: "n'appartient pas à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') - "∊": # 0x220a - test: if: "$SpeechStyle != 'ClearSpeak'" then: - test: if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "appartient à" # (en: 'an element of') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "appartient à" # (en: 'an element of') # Several options for speaking elements in ClearSpeak -- they split between being inside a set or not and then the option else_test: if: "../../self::m:set or ../../../self::m:set" # inside a set then_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "en"] # (en: 'in', DeepL translation) + then: [T: "en"] # (en: 'in', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "membre de"] # (en: 'member of', DeepL translation) + then: [T: "membre de"] # (en: 'member of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "élément de"] # (en: 'element of', DeepL translation) - - else: [t: "appartient à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + then: [T: "élément de"] # (en: 'element of', DeepL translation) + - else: [T: "appartient à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "est membre de"] # (en: 'is a member of', DeepL translation) + then: [T: "est membre de"] # (en: 'is a member of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "est un élément de"] # (en: 'is an element of', DeepL translation) + then: [T: "est un élément de"] # (en: 'is an element of', DeepL translation) - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "est dans"] # (en: 'is in', DeepL translation) - - else: [t: "appartient à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') - - "∏": [t: "produit"] # 0x220f (en: 'product') - - "∐": [t: "coproduit"] # 0x2210 (en: 'co-product') - - "∑": [t: "sommation"] # 0x2211 (en: 'sum') - - "−": [t: "moins"] # 0x2212 (en: 'minus') - - "∓": [t: "moins ou plus"] # 0x2213 (en: 'minus or plus', MathPlayer: 'moins-ou-plus') - - "∗": [t: "fois"] # 0x2217 (en: 'times') - - "∘": [t: "composé avec"] # 0x2218 (en: 'composed with') + then: [T: "est dans"] # (en: 'is in', DeepL translation) + - else: [T: "appartient à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∏": [T: "produit"] # 0x220f (en: 'product') + - "∐": [T: "coproduit"] # 0x2210 (en: 'co-product') + - "∑": [T: "sommation"] # 0x2211 (en: 'sum') + - "−": [T: "moins"] # 0x2212 (en: 'minus') + - "∓": [T: "moins ou plus"] # 0x2213 (en: 'minus or plus', MathPlayer: 'moins-ou-plus') + - "∗": [T: "fois"] # 0x2217 (en: 'times') + - "∘": [T: "composé avec"] # 0x2218 (en: 'composed with') - "√": # 0x221a - test: if: "$Verbosity!='Terse'" - then: [t: "la"] # (en: 'the', DeepL translation) - - t: "racine carrée" # (en: 'square root of') + then: [T: "la"] # (en: 'the', DeepL translation) + - T: "racine carrée" # (en: 'square root of') - "∝": # 0x221d - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "proportionnel à" # (en: 'proportional to') - - "∞": [t: "infini"] # 0x221e (en: 'infinity') - - "∟": [t: "angle droit"] # 0x221f (en: 'right angle') - - "∠": [t: "angle"] # 0x2220 - - "∡": [t: "angle mesuré"] # 0x2221 (en: 'measured angle') - - "∣": [t: "est un diviseur de"] # 0x2223 (en: 'divides') - - "∤": [t: "n'est pas un diviseur de"] # 0x2224 (en: 'does not divide') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "proportionnel à" # (en: 'proportional to') + - "∞": [T: "infini"] # 0x221e (en: 'infinity') + - "∟": [T: "angle droit"] # 0x221f (en: 'right angle') + - "∠": [T: "angle"] # 0x2220 + - "∡": [T: "angle mesuré"] # 0x2221 (en: 'measured angle') + - "∣": [T: "est un diviseur de"] # 0x2223 (en: 'divides') + - "∤": [T: "n'est pas un diviseur de"] # 0x2224 (en: 'does not divide') - "∥": # 0x2225 - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "double ligne verticale"] # (en: 'double vertical line', DeepL translation) + then: [T: "double ligne verticale"] # (en: 'double vertical line', DeepL translation) else: - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "parallèle à" # (en: 'parallel to') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "parallèle à" # (en: 'parallel to') - "∦": # 0x2226 - test: if: "$Verbosity!='Terse'" - then: [t: "n'est"] # (en: 'is', DeepL translation) - - t: "pas parallèle à" # (en: 'not parallel to') - - "∧": [t: "et logique"] # 0x2227 (en: 'and') - - "∨": [t: "ou logique"] # 0x2228 (en: 'or') - - "∩": [t: "intersection"] # 0x2229 - - "∪": [t: "\uF8FEunion"] # 0x222a - - "∫": [t: "\uF8FEintégrale"] # 0x222b (en: 'integral') - - "∬": [t: "\uF8FEintégrale double"] # 0x222c (en: 'double integral') - - "∭": [t: "\uF8FEintégrale triple"] # 0x222d (en: 'triple integral') - - "∮": [t: "\uF8FEintégrale de contour"] # 0x222e (en: 'contour integral') + then: [T: "n'est"] # (en: 'is', DeepL translation) + - T: "pas parallèle à" # (en: 'not parallel to') + - "∧": [T: "et logique"] # 0x2227 (en: 'and') + - "∨": [T: "ou logique"] # 0x2228 (en: 'or') + - "∩": [T: "intersection"] # 0x2229 + - "∪": [T: "\uF8FEunion"] # 0x222a + - "∫": [T: "\uF8FEintégrale"] # 0x222b (en: 'integral') + - "∬": [T: "\uF8FEintégrale double"] # 0x222c (en: 'double integral') + - "∭": [T: "\uF8FEintégrale triple"] # 0x222d (en: 'triple integral') + - "∮": [T: "\uF8FEintégrale de contour"] # 0x222e (en: 'contour integral') - "∶": # 0x2236 - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "rapport" # (en: 'to') - - "∷": [t: "proportion"] # 0x2237 (en: 'as') - - "∼": [t: "varie avec"] # 0x223c (en: 'varies with') - - "∽": [t: "tilde renversé"] # 0x223d (en: 'reversed tilde') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "rapport" # (en: 'to') + - "∷": [T: "proportion"] # 0x2237 (en: 'as') + - "∼": [T: "varie avec"] # 0x223c (en: 'varies with') + - "∽": [T: "tilde renversé"] # 0x223d (en: 'reversed tilde') - "∾": # 0x223e - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "s couché renversé" # (en: 'most positive') - - "∿": [t: "sinusoïde"] # 0x223f (en: 'sine wave') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "s couché renversé" # (en: 'most positive') + - "∿": [T: "sinusoïde"] # 0x223f (en: 'sine wave') - "≠": # 0x2260 - test: if: "$Verbosity!='Terse'" - then: [t: "n'est"] # (en: 'is', DeepL translation) - - t: "pas égal à" # (en: 'not equal to') + then: [T: "n'est"] # (en: 'is', DeepL translation) + - T: "pas égal à" # (en: 'not equal to') - "≡": # 0x2261 - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "identique à" # (en: 'identical to') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "identique à" # (en: 'identical to') - "≤": # 0x2264 - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "plus petit ou égal à" # (en: 'less than or equal to') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "plus petit ou égal à" # (en: 'less than or equal to') - "≥": # 0x2265 - test: if: "$Verbosity!='Terse'" - then: [t: "est"] # (en: 'is', DeepL translation) - - t: "plus grand ou égal à" # (en: 'greater than or equal to') - - "≦": [t: "plus petit que par-dessus égal à"] # 0x2266 (en: 'less than over equal to', MathPlayer: 'plus petit que par-dessus égal à', DeepL: 'inférieur à supérieur à égal à') - - "≧": [t: "plus grand que par-dessus égal à"] # 0x2267 (en: 'greater than over equal to', MathPlayer: 'plus grand que par-dessus égal à', DeepL: 'supérieur à égal à') - - "≺": [t: "précède"] # 0x227a (en: 'precedes') - - "≻": [t: "suit"] # 0x227b (en: 'succeeds') + then: [T: "est"] # (en: 'is', DeepL translation) + - T: "plus grand ou égal à" # (en: 'greater than or equal to') + - "≦": [T: "plus petit que par-dessus égal à"] # 0x2266 (en: 'less than over equal to', MathPlayer: 'plus petit que par-dessus égal à', DeepL: 'inférieur à supérieur à égal à') + - "≧": [T: "plus grand que par-dessus égal à"] # 0x2267 (en: 'greater than over equal to', MathPlayer: 'plus grand que par-dessus égal à', DeepL: 'supérieur à égal à') + - "≺": [T: "précède"] # 0x227a (en: 'precedes') + - "≻": [T: "suit"] # 0x227b (en: 'succeeds') - "⊂": # 0x2282 - test: if: "$Verbosity!='Terse'" - then: [t: "est un"] # (en: 'is a', DeepL translation) - - t: "sous-ensemble de" # (en: 'subset of', SRE: 'sous ensemble de') + then: [T: "est un"] # (en: 'is a', DeepL translation) + - T: "sous-ensemble de" # (en: 'subset of', SRE: 'sous ensemble de') - "⊃": # 0x2283 - test: if: "$Verbosity!='Terse'" - then: [t: "est un"] # (en: 'is a', DeepL translation) - - t: "sur-ensemble de" # (en: 'superset of', SRE: 'sur ensemble de') + then: [T: "est un"] # (en: 'is a', DeepL translation) + - T: "sur-ensemble de" # (en: 'superset of', SRE: 'sur ensemble de') - "⊄": # 0x2284 - test: if: "$Verbosity!='Terse'" - then: [t: "n'est"] # (en: 'is', DeepL translation) - - t: "pas un sous-ensemble de" # (en: 'not a subset of', SRE: 'pas un sous ensemble de') + then: [T: "n'est"] # (en: 'is', DeepL translation) + - T: "pas un sous-ensemble de" # (en: 'not a subset of', SRE: 'pas un sous ensemble de') - "⊅": # 0x2285 - test: if: "$Verbosity!='Terse'" - then: [t: "n'est"] # (en: 'is', DeepL translation) - - t: "pas un sur ensemble de" # (en: 'not a superset of', MathPlayer: 'pas un sur-ensemble de', DeepL: 'n'est pas un super-ensemble de') + then: [T: "n'est"] # (en: 'is', DeepL translation) + - T: "pas un sur ensemble de" # (en: 'not a superset of', MathPlayer: 'pas un sur-ensemble de', DeepL: 'n'est pas un super-ensemble de') - "⊆": # 0x2286 - test: if: "$Verbosity!='Terse'" - then: [t: "est un"] # (en: 'is a', DeepL translation) - - t: "sous ensemble ou égal à" # (en: 'subset of or equal to', MathPlayer: 'sous-ensemble ou égal à', DeepL: 'sous-ensemble de ou égal à') + then: [T: "est un"] # (en: 'is a', DeepL translation) + - T: "sous ensemble ou égal à" # (en: 'subset of or equal to', MathPlayer: 'sous-ensemble ou égal à', DeepL: 'sous-ensemble de ou égal à') - "⊇": # 0x2287 - test: if: "$Verbosity!='Terse'" - then: [t: "est un"] # (en: 'is a', DeepL translation) - - t: "sur ensemble ou égal à" # (en: 'superset of or equal to', MathPlayer: 'sur-ensemble ou égal à', DeepL: 'sur-ensemble de ou égal à') + then: [T: "est un"] # (en: 'is a', DeepL translation) + - T: "sur ensemble ou égal à" # (en: 'superset of or equal to', MathPlayer: 'sur-ensemble ou égal à', DeepL: 'sur-ensemble de ou égal à') From b268810cb5f487c546320549f3bdc376c0cd464b Mon Sep 17 00:00:00 2001 From: "olivier.thiffault" Date: Thu, 4 Jun 2026 14:29:06 -0400 Subject: [PATCH 31/31] removed AI generated comments --- tests/Languages/fr/SimpleSpeak/functions.rs | 68 ++++++++++----------- tests/Languages/fr/shared.rs | 68 ++++++++++----------- 2 files changed, 68 insertions(+), 68 deletions(-) diff --git a/tests/Languages/fr/SimpleSpeak/functions.rs b/tests/Languages/fr/SimpleSpeak/functions.rs index 7e816f2c6..ca403f898 100644 --- a/tests/Languages/fr/SimpleSpeak/functions.rs +++ b/tests/Languages/fr/SimpleSpeak/functions.rs @@ -6,7 +6,7 @@ use crate::common::*; use anyhow::Result; -// AI generated + #[test] fn trig_names() -> Result<()> { let expr = " @@ -21,7 +21,7 @@ fn trig_names() -> Result<()> { Ok(()) } -// AI generated + #[test] fn hyperbolic_trig_names() -> Result<()> { let expr = " @@ -37,7 +37,7 @@ fn hyperbolic_trig_names() -> Result<()> { } -// AI generated + #[test] fn inverse_trig() -> Result<()> { let expr = "sin-1x"; @@ -45,7 +45,7 @@ fn inverse_trig() -> Result<()> { Ok(()) } -// AI generated + #[test] fn trig_squared() -> Result<()> { let expr = "sin2x"; @@ -53,7 +53,7 @@ fn trig_squared() -> Result<()> { Ok(()) } -// AI generated + #[test] fn trig_cubed() -> Result<()> { let expr = "tan3x"; @@ -61,7 +61,7 @@ fn trig_cubed() -> Result<()> { Ok(()) } -// AI generated + #[test] fn trig_fourth() -> Result<()> { let expr = "sec4x"; @@ -70,7 +70,7 @@ fn trig_fourth() -> Result<()> { } -// AI generated + #[test] fn trig_power_other() -> Result<()> { let expr = "sinh>n-1x"; @@ -78,7 +78,7 @@ fn trig_power_other() -> Result<()> { Ok(()) } -// AI generated + #[test] fn simple_log() -> Result<()> { let expr = " logx "; @@ -86,7 +86,7 @@ fn simple_log() -> Result<()> { Ok(()) } -// AI generated + #[test] fn normal_log() -> Result<()> { let expr = "log(x+y)"; @@ -94,7 +94,7 @@ fn normal_log() -> Result<()> { Ok(()) } -// AI generated + #[test] fn simple_log_with_base() -> Result<()> { let expr = " logbx "; @@ -102,7 +102,7 @@ fn simple_log_with_base() -> Result<()> { Ok(()) } -// AI generated + #[test] fn normal_log_with_base() -> Result<()> { let expr = "logb(x+y)"; @@ -110,7 +110,7 @@ fn normal_log_with_base() -> Result<()> { Ok(()) } -// AI generated + #[test] fn normal_ln() -> Result<()> { let expr = "ln(x+y)"; @@ -120,7 +120,7 @@ fn normal_ln() -> Result<()> { Ok(()) } -// AI generated + #[test] fn simple_ln() -> Result<()> { let expr = " lnx "; @@ -130,7 +130,7 @@ fn simple_ln() -> Result<()> { Ok(()) } -// AI generated + #[test] fn other_names() -> Result<()> { let expr = " Covx "; @@ -142,7 +142,7 @@ fn other_names() -> Result<()> { Ok(()) } -// AI generated + #[test] fn explicit_function_call_with_parens() -> Result<()> { let expr = "t(x)"; @@ -151,7 +151,7 @@ fn explicit_function_call_with_parens() -> Result<()> { } -// AI generated + #[test] fn explicit_times_with_parens() -> Result<()> { let expr = "t(x)"; @@ -159,7 +159,7 @@ fn explicit_times_with_parens() -> Result<()> { Ok(()) } -// AI generated + #[test] fn explicit_function_call() -> Result<()> { let expr = "tx"; @@ -167,7 +167,7 @@ fn explicit_function_call() -> Result<()> { Ok(()) } -// AI generated + #[test] fn explicit_times() -> Result<()> { let expr = "tx"; @@ -179,7 +179,7 @@ fn explicit_times() -> Result<()> { /* * Tests for times */ -// AI generated + #[test] fn no_times_binomial() -> Result<()> { let expr = "x y"; @@ -187,7 +187,7 @@ fn no_times_binomial() -> Result<()> { Ok(()) } -// AI generated + #[test] fn times_following_paren() -> Result<()> { let expr = " @@ -198,7 +198,7 @@ fn times_following_paren() -> Result<()> { Ok(()) } -// AI generated + #[test] fn times_preceding_paren() -> Result<()> { let expr = " @@ -209,7 +209,7 @@ fn times_preceding_paren() -> Result<()> { Ok(()) } -// AI generated + #[test] fn no_times_sqrt() -> Result<()> { let expr = " @@ -226,7 +226,7 @@ fn no_times_sqrt() -> Result<()> { /* * Tests for parens */ - // AI generated + #[test] fn no_parens_number() -> Result<()> { let expr = " @@ -239,7 +239,7 @@ fn no_times_sqrt() -> Result<()> { Ok(()) } - // AI generated + #[test] fn no_parens_monomial() -> Result<()> { let expr = " @@ -252,7 +252,7 @@ fn no_times_sqrt() -> Result<()> { Ok(()) } - // AI generated + #[test] fn no_parens_negative_number() -> Result<()> { let expr = " @@ -266,7 +266,7 @@ fn no_times_sqrt() -> Result<()> { } - // AI generated + #[test] fn no_parens_negative_number_with_var() -> Result<()> { let expr = " @@ -279,7 +279,7 @@ fn no_times_sqrt() -> Result<()> { Ok(()) } - // AI generated + #[test] fn parens_superscript() -> Result<()> { let expr = " @@ -297,7 +297,7 @@ fn no_times_sqrt() -> Result<()> { Ok(()) } - // AI generated + #[test] fn no_parens_fraction() -> Result<()> { let expr = " @@ -313,7 +313,7 @@ fn no_times_sqrt() -> Result<()> { } // Tests for the four types of intervals in SimpleSpeak - // AI generated + #[test] fn parens_interval_open_open() -> Result<()> { let expr = " @@ -326,7 +326,7 @@ fn no_times_sqrt() -> Result<()> { } -// AI generated + #[test] fn parens_interval_closed_open() -> Result<()> { let expr = " @@ -339,7 +339,7 @@ fn no_times_sqrt() -> Result<()> { } -// AI generated + #[test] fn parens_interval_open_closed() -> Result<()> { let expr = " @@ -352,7 +352,7 @@ fn parens_interval_open_closed() -> Result<()> { } -// AI generated + #[test] fn parens_interval_closed_closed() -> Result<()> { let expr = " @@ -364,7 +364,7 @@ fn parens_interval_closed_closed() -> Result<()> { Ok(()) } - // AI generated + #[test] fn parens_interval_neg_infinity_open_open() -> Result<()> { let expr = " @@ -376,7 +376,7 @@ fn parens_interval_closed_closed() -> Result<()> { Ok(()) } - // AI generated + #[test] fn parens_interval_neg_infinity_open_closed() -> Result<()> { let expr = " diff --git a/tests/Languages/fr/shared.rs b/tests/Languages/fr/shared.rs index 204c00494..b63588b52 100644 --- a/tests/Languages/fr/shared.rs +++ b/tests/Languages/fr/shared.rs @@ -3,7 +3,7 @@ use crate::common::*; use anyhow::Result; -// AI generated + #[test] fn modified_vars() -> Result<()> { let expr = " @@ -25,7 +25,7 @@ fn modified_vars() -> Result<()> { Ok(()) } -// AI generated + #[test] fn limit() -> Result<()> { let expr = " @@ -45,7 +45,7 @@ fn limit() -> Result<()> { Ok(()) } -// AI generated + #[test] fn limit_from_below() -> Result<()> { let expr = " @@ -62,7 +62,7 @@ fn limit_from_below() -> Result<()> { } -// AI generated + #[test] fn binomial_mmultiscripts() -> Result<()> { let expr = "Cmn"; @@ -70,7 +70,7 @@ fn binomial_mmultiscripts() -> Result<()> { Ok(()) } -// AI generated + #[test] fn binomial_mmultiscripts_other() -> Result<()> { let expr = "Cmn"; @@ -78,7 +78,7 @@ fn binomial_mmultiscripts_other() -> Result<()> { Ok(()) } -// AI generated + #[test] fn binomial_subscript() -> Result<()> { // C_{n,k} let expr = "Cn,m"; @@ -86,7 +86,7 @@ fn binomial_subscript() -> Result<()> { // C_{n,k} Ok(()) } -// AI generated + #[test] fn permutation_mmultiscripts() -> Result<()> { let expr = "Pkn"; @@ -94,7 +94,7 @@ fn permutation_mmultiscripts() -> Result<()> { Ok(()) } -// AI generated + #[test] fn permutation_mmultiscripts_sup() -> Result<()> { let expr = "Pkn"; @@ -102,7 +102,7 @@ fn permutation_mmultiscripts_sup() -> Result<()> { Ok(()) } -// AI generated + #[test] fn permutation_msubsup() -> Result<()> { let expr = "Pkn"; @@ -110,7 +110,7 @@ fn permutation_msubsup() -> Result<()> { Ok(()) } -// AI generated + #[test] fn tensor_mmultiscripts() -> Result<()> { let expr = " @@ -121,7 +121,7 @@ fn tensor_mmultiscripts() -> Result<()> { Ok(()) } -// AI generated + #[test] fn huge_num_mmultiscripts() -> Result<()> { let expr = " @@ -133,7 +133,7 @@ fn huge_num_mmultiscripts() -> Result<()> { Ok(()) } -// AI generated + #[test] fn prime() -> Result<()> { let expr = " x "; @@ -141,7 +141,7 @@ fn prime() -> Result<()> { Ok(()) } -// AI generated + #[test] fn given() -> Result<()> { let expr = "P(A|B)"; @@ -150,7 +150,7 @@ fn given() -> Result<()> { Ok(()) } -// AI generated + #[test] fn simple_msubsup() -> Result<()> { let expr = " @@ -170,7 +170,7 @@ fn simple_msubsup() -> Result<()> { Ok(()) } -// AI generated + #[test] fn non_simple_msubsup() -> Result<()> { let expr = "ij2k"; @@ -180,7 +180,7 @@ fn non_simple_msubsup() -> Result<()> { Ok(()) } -// AI generated + #[test] fn presentation_mathml_in_semantics() -> Result<()> { let expr = " @@ -203,7 +203,7 @@ fn presentation_mathml_in_semantics() -> Result<()> { Ok(()) } -// AI generated + #[test] fn ignore_period() -> Result<()> { // from https://en.wikipedia.org/wiki/Probability @@ -250,7 +250,7 @@ fn ignore_period() -> Result<()> { Ok(()) } -// AI generated + #[test] fn ignore_mtext_period() -> Result<()> { let expr = "{2}."; @@ -258,7 +258,7 @@ fn ignore_mtext_period() -> Result<()> { Ok(()) } -// AI generated + #[test] fn ignore_comma() -> Result<()> { // from https://en.wikipedia.org/wiki/Probability @@ -297,7 +297,7 @@ fn ignore_comma() -> Result<()> { Ok(()) } -// AI generated + #[test] #[ignore] // issue #14 fn ignore_period_and_space() -> Result<()> { @@ -340,7 +340,7 @@ fn ignore_period_and_space() -> Result<()> { } -// AI generated + #[test] fn bug_199_2pi() -> Result<()> { let expr = " @@ -361,7 +361,7 @@ fn bug_199_2pi() -> Result<()> { Ok(()) } -// AI generated + #[test] fn caret_and_hat() -> Result<()> { let expr = "x^2+y^"; @@ -369,7 +369,7 @@ fn caret_and_hat() -> Result<()> { Ok(()) } -// AI generated + #[test] fn mn_with_space() -> Result<()> { let expr = "1 234 567"; @@ -377,7 +377,7 @@ fn mn_with_space() -> Result<()> { Ok(()) } -// AI generated + #[test] fn ignore_bold() -> Result<()> { let expr = r#" @@ -397,7 +397,7 @@ fn ignore_bold() -> Result<()> { Ok(()) } -// AI generated + #[test] fn mn_with_block_and_decimal_separators() -> Result<()> { let expr = "1,234.56"; // may want to change this for another language @@ -405,7 +405,7 @@ fn mn_with_block_and_decimal_separators() -> Result<()> { Ok(()) } -// AI generated + #[test] fn divergence() -> Result<()> { let expr = "·F"; // may want to change this for another language @@ -414,7 +414,7 @@ fn divergence() -> Result<()> { Ok(()) } -// AI generated + #[test] fn curl() -> Result<()> { let expr = "×F"; @@ -424,7 +424,7 @@ fn curl() -> Result<()> { Ok(()) } -// AI generated + #[test] fn gradient() -> Result<()> { let expr = "F"; @@ -434,7 +434,7 @@ fn gradient() -> Result<()> { Ok(()) } -// AI generated + #[test] fn literal_speak_perpendicular() -> Result<()> { let expr = r#" @@ -454,7 +454,7 @@ fn literal_speak_perpendicular() -> Result<()> { Ok(()) } -// AI generated + #[test] fn literal_speak_chars() -> Result<()> { let expr = r#" @@ -474,7 +474,7 @@ fn literal_speak_chars() -> Result<()> { Ok(()) } -// AI generated + #[test] fn literal_speak_with_name() -> Result<()> { let expr = r#" @@ -495,7 +495,7 @@ fn literal_speak_with_name() -> Result<()> { Ok(()) } -// AI generated + #[test] fn literal_speak_with_property() -> Result<()> { let expr = r#" @@ -516,7 +516,7 @@ fn literal_speak_with_property() -> Result<()> { Ok(()) } -// AI generated + #[test] fn literal_intent_property() -> Result<()> { let expr = r#" @@ -536,7 +536,7 @@ fn literal_intent_property() -> Result<()> { Ok(()) } -// AI generated + #[test] fn literal_intent_property_with_name() -> Result<()> { let expr = r#"