diff --git a/Rules/Languages/pl/SharedRules/default.yaml b/Rules/Languages/pl/SharedRules/default.yaml index ae139ebd6..531f57a5d 100644 --- a/Rules/Languages/pl/SharedRules/default.yaml +++ b/Rules/Languages/pl/SharedRules/default.yaml @@ -513,6 +513,18 @@ - x: "count(preceding-sibling::*)+IfThenElse(parent::m:mlabeledtr, 0, 1)" - pause: medium - x: "*" + - test: + if: "HasVisibleColumnLine(../.., count(preceding-sibling::*) + 1)" + then: + - pause: short + - T: "separator" + - test: + # Separator wiersza zapowiadamy tylko po ostatniej komórce wiersza, żeby + # wybrzmiał raz na każdą granicę poziomą. + if: "count(following-sibling::*) = 0 and HasVisibleRowLine(../.., count(../preceding-sibling::*) + 1)" + then: + - pause: short + - T: "separator wiersza" - 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 @@ -737,21 +749,38 @@ - name: function-intent # uncaught intent -- speak as foo of arg1 comma arg2 .... The MathML spec requires arguments to functions + # IntentMappings mogą dodać po nazwie opcje spoiwa "| ...": + # * jedna opcja bez przecinka: separator dwuargumentowy po "z" + # (np. "| podzielone przez" daje "część całkowita z x podzielone przez y") + # * wiele opcji albo opcja z przecinkami: szablony arności; k słów spoiwa + # opisuje k+1 argumentów (np. "| po | od,do") + # * gdy arność nie pasuje, argumenty rozdziela przecinek tag: "*" match: "count(*)>0" replace: - x: "SpeakIntentName(name(.), $Verbosity, 'function')" - 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: "z", pause: auto] # phrase(sine 'of' 5) - - insert: - nodes: "*" - replace: - - test: - if: "not(contains(@data-intent-property, ':literal:'))" - then: [x: "','"] + - if: "IntentFunctionUseArityPath(name(.), 'function', count(*))" + then: + - x: "IntentFunctionGlueBefore(name(.), 'function', 1, count(*))" - pause: auto + - insert: + nodes: "*" + replace: + - x: "IntentFunctionGlueBefore(name(.), 'function', $InsertIndex, count(*))" + - pause: auto + else: + - 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: "z", pause: auto] # phrase(sine 'of' 5) + - insert: + nodes: "*" + replace: + - test: + if: "not(contains(@data-intent-property, ':literal:'))" + then: [x: "IntentFunctionArgSeparator(name(.), 'function', count(*))"] + - pause: auto - test: # speak "end ..." if not bracketed or last child is not simple and not last node if: "$Impairment = 'Blindness' and not(*[last()][IsBracketed(., '', '') or IsNode(., 'simple')] )" diff --git a/Rules/Languages/pl/SharedRules/geometry.yaml b/Rules/Languages/pl/SharedRules/geometry.yaml index 37155f79c..f110a71ed 100644 --- a/Rules/Languages/pl/SharedRules/geometry.yaml +++ b/Rules/Languages/pl/SharedRules/geometry.yaml @@ -57,12 +57,16 @@ - name: coordinate tag: coordinate - match: "." + # Intencje postaci coordinate($x,...) mają @arg i spadają do function-intent / IntentMappings + match: "not(*[@arg])" replace: - - T: "przecinek" # phrase(the 'point' at 1, 2) - test: if: "$Verbosity='Verbose'" - then: [t: "w"] # phrase('the' point at 1, 2) + then: [OT: "ten"] # phrase('the' point at 1, 2) + - T: "punkt" # phrase(the 'point' at 1, 2) + - test: + if: "$Verbosity='Verbose'" + then: [T: "w"] # phrase('the' point at 1, 2) - pause: short - insert: nodes: "*" diff --git a/Rules/Languages/pl/definitions.yaml b/Rules/Languages/pl/definitions.yaml index 6dda0ebe0..9c4c6e69c 100644 --- a/Rules/Languages/pl/definitions.yaml +++ b/Rules/Languages/pl/definitions.yaml @@ -13,9 +13,9 @@ "image":"function=obraz", "mixed-fraction":"infix=i", - "quotient":"function=część całkowita; podzielone przez", + "quotient":"function=część całkowita | podzielone przez", "evaluated-at":"infix=obliczone w", - "remainder":"function=reszta; podzielone przez", + "remainder":"function=reszta | podzielone przez", "max":"function=maksimum", "min":"function=minimum", @@ -32,10 +32,10 @@ "real-part": "function=część rzeczywista", "imaginary-part": "function=część urojona: część urojona: część urojona", - "polar-coordinate":"function=współrzędna biegunowa; przecinek", - "spherical-coordinate":"function=współrzędna sferyczna; przecinek; przecinek", - "cartesian-coordinate":"function=współrzędna kartezjańska; przecinek", - "coordinate":"function=współrzędna; przecinek", + "polar-coordinate":"function=współrzędna biegunowa", + "spherical-coordinate":"function=współrzędna sferyczna", + "cartesian-coordinate":"function=współrzędna kartezjańska", + "coordinate":"function=współrzędna", "floor":"function=podłoga", "ceiling":"function=sufit", "round":"function=zaokrąglenie", @@ -51,16 +51,23 @@ ### Sets "set": "function=; zbiór: zbiór", - "set-difference":"function=różnica zbiorów; i || infix=minus", # NOTE: not tested + "set-difference":"function=różnica zbiorów | i || infix=minus", "complement":"function=dopełnienie", + "empty-set":"nofix=zbiór pusty", "cardinality":"function=moc zbioru", "list":"function=lista", "tuple": "function=; krotka: krotka", ### Sequence and Series - "sum":"function=; suma po: suma; ", - "product":"function=iloczyn || function=iloczyn po || function=iloczyn od; do", + # UWAGA: NIE używamy tu szablonów arności ("| po | od,do"), choć angielski je ma. + # Powód (zmierzone 31.08.2026): intent_function_glue_before w src/infer_intent.rs + # zwraca dla ostatniego argumentu ZASZYTE W KODZIE angielskie "of", więc polskie + # wyjście brzmiałoby "suma po i of x". To defekt rdzenia dotyczący każdego języka + # poza angielskim; węgierski uniknął go tak samo, zostawiając prostą postać. + # Separator binarny (jedna opcja "| słowo") działa poprawnie i jest używany niżej. + "sum":"function=suma", + "product":"function=iloczyn", ### Elementary classical functions @@ -104,7 +111,7 @@ "median":"function=mediana", "mode":"function=dominanta", - "conditional-probability":"function=prawdopodobieństwo; pod warunkiem", # NOTE: Check test + "conditional-probability":"function=prawdopodobieństwo | pod warunkiem", ### Linear Algebra @@ -120,7 +127,7 @@ "unit-vector":"prefix=wektor jednostkowy", "identity-matrix":"nofix=macierz jednostkowa", # NOTE: no function specified - "transpose":"function=transpozycja || postfix=transponowane", + "transpose":"postfix=transponowane || function=transpozycja", "dimensional-product":"infix=na", # INFIX @@ -150,13 +157,13 @@ ### General Concepts "fenced-group":"function=grupa w nawiasach", - "ordered-pair": "function=; para; i", + "ordered-pair": "function=para | i", "indexed-by": "infix=; indeks dolny; koniec indeksu dolnego", "highlight":"postfix=podświetlone", "least-common-denominator":"function=najmniejszy wspólny mianownik", "rate":"infix=na", - "translation":"function=przesunięcie o; przecinek", + "translation":"function=przesunięcie o", "constraint":"infix=; przy warunku; ", "binomial-coefficient":"infix=po", @@ -264,7 +271,7 @@ ## Default fixity nofix "diameter":"nofix=d: średnica", "distance":"nofix=d; D: odległość", - "probability":"nofix=P: prawdopodobieństwo", + "probability":"nofix=P: prawdopodobieństwo || function=prawdopodobieństwo", "radius":"nofix=r: promień", "volume":"nofix=V: objętość || function=objętość", "exponential-e":"nofix=e", diff --git a/Rules/Languages/pl/navigate.yaml b/Rules/Languages/pl/navigate.yaml index cfdecbcb4..c99b60490 100644 --- a/Rules/Languages/pl/navigate.yaml +++ b/Rules/Languages/pl/navigate.yaml @@ -53,39 +53,46 @@ then: [t: "maksymalnie oddalono", pause: "medium"] else: - test: - - if: "starts-with($NavCommand, 'Zoom')" - then: [set_variables: [Prefix: "'przybliż'"]] # phrase('zoom' in to see more details) + # CommandOffset to 1 + długość ANGIELSKIEGO rdzenia $NavCommand + # (Zoom/Move/Read/Describe), a NIE długość wymawianego $Prefix - + # dzięki temu tłumaczenie może mieć słowo Prefix innej długości. + # Angielskie "zoom" obsługuje oba kierunki, polski ma dwa różne + # czasowniki - "przybliż na zewnątrz" byłoby sprzeczne. + - if: "starts-with($NavCommand, 'ZoomOut')" + then: [set_variables: [Prefix: "'oddal'", CommandOffset: "5"]] # phrase('zoom' out to see less detail) + - else_if: "starts-with($NavCommand, 'Zoom')" + then: [set_variables: [Prefix: "'przybliż'", CommandOffset: "5"]] # phrase('zoom' in to see more details) - else_if: "starts-with($NavCommand, 'Move')" - then: [set_variables: [Prefix: "'przejdź'"]] # phrase('move' to next entry in table) + then: [set_variables: [Prefix: "'przejdź'", CommandOffset: "5"]] # phrase('move' to next entry in table) - else_if: "starts-with($NavCommand, 'Read')" - then: [set_variables: [Prefix: "'odczytaj'"]] # phrase('read' to next entry in table) + then: [set_variables: [Prefix: "'odczytaj'", CommandOffset: "5"]] # phrase('read' to next entry in table) - else_if: "starts-with($NavCommand, 'Describe')" - then: [set_variables: [Prefix: "'opisz'"]] # phrase('describe' to next entry in table) + then: [set_variables: [Prefix: "'opisz'", CommandOffset: "9"]] # phrase('describe' to next entry in table) - test: if: "$Prefix != ''" then: - x: "$Prefix" - test: - - if: "substring($NavCommand, string-length($Prefix)+1) = 'In'" - then: [T: "do"] # phrase(zoom 'in' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'InAll'" + - if: "substring($NavCommand, $CommandOffset) = 'In'" + then: [] # sam czasownik "przybliż" wystarcza + - else_if: "substring($NavCommand, $CommandOffset) = 'InAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" - then: [t: "maksymalnie do środka"] # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Out'" - then: [t: "na zewnątrz"] # phrase(zoom 'out' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'OutAll'" + then: [T: "maksymalnie"] # phrase(zoom 'in all of the way' to see more details) + - else_if: "substring($NavCommand, $CommandOffset) = 'Out'" + then: [] # sam czasownik "oddal" wystarcza + - else_if: "substring($NavCommand, $CommandOffset) = 'OutAll'" # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets "ed" concatenated to "zoom" - then: [t: "maksymalnie na zewnątrz"] # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Next'" - then: [t: "w prawo"] # phrase(move to the 'right') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Previous'" - then: [t: "w lewo"] # phrase(move to the 'left') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Current'" - then: [t: "bieżący"] # phrase(who is the 'current' president) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineStart'" - then: [t: "do początku linii"] # phrase(move 'to start of line') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineEnd'" - then: [t: "do końca linii"] # phrase(move 'to end of line') + then: [T: "maksymalnie"] # phrase(zoom 'out all of the way' to see more details) + - else_if: "substring($NavCommand, $CommandOffset) = 'Next'" + then: [T: "w prawo"] # phrase(move to the 'right') + - else_if: "substring($NavCommand, $CommandOffset) = 'Previous'" + then: [T: "w lewo"] # phrase(move to the 'left') + - else_if: "substring($NavCommand, $CommandOffset) = 'Current'" + then: [T: "bieżący"] # phrase(who is the 'current' president) + - else_if: "substring($NavCommand, $CommandOffset) = 'LineStart'" + then: [T: "do początku linii"] # phrase(move 'to start of line') + - else_if: "substring($NavCommand, $CommandOffset) = 'LineEnd'" + then: [T: "do końca linii"] # phrase(move 'to end of line') - pause: "medium" - set_variables: [MatchCounter: "$MatchCounter + 1"] @@ -96,6 +103,15 @@ (name(.)='mrow' or name(.) = 'mtr' or name(.) = 'mlabeledtr' or @data-from-mathml = 'mtable')" replace: [] +- name: into-or-out-of-prefix-or-silent-without-parts + tag: "*" + # Intencje prefiksowe i ciche bez wpisu w NavigationParts (np. minus unarny, + # x z daszkiem) NIE powinny zapowiadać "do"/"na zewnątrz". + match: "$Move2D != '' and + (contains(@data-intent-property, ':prefix:') or contains(@data-intent-property, ':silent:')) and + GetNavigationPartName(name(.), count($Child2D/preceding-sibling::*)) = ''" + replace: [] + - name: into-or-out-of-mtr tag: [mtr, mlabeledtr] match: "$Move2D = 'in'" @@ -168,6 +184,24 @@ - test: - if: "$PartName != ''" then: [x: "$PartName"] + - else_if: "count(*) = 1" + then_test: + if: "$NavVerbosity = 'Verbose'" + then: # IntentMappings przez SpeakIntentName; w razie braku - nazwa intentu ze spacjami + - test: + - if: "contains(@data-intent-property, ':prefix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'prefix')"] + - else_if: "contains(@data-intent-property, ':postfix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'postfix')"] + - else_if: "contains(@data-intent-property, ':infix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'infix')"] + - else_if: "contains(@data-intent-property, ':function:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'function')"] + - else_if: "contains(@data-intent-property, ':nofix:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'nofix')"] + - else_if: "contains(@data-intent-property, ':silent:')" + then: [x: "SpeakIntentName(name(.), $Verbosity, 'silent')"] + - else: [x: "SpeakIntentName(name(.), $Verbosity, 'other')"] else: - t: "części" # phrase(the 'part' of the expression) - x: "count($Child2D/preceding-sibling::*) + 1" diff --git a/Rules/Languages/pl/unicode-full.yaml b/Rules/Languages/pl/unicode-full.yaml index 0fbeda954..8246f4650 100644 --- a/Rules/Languages/pl/unicode-full.yaml +++ b/Rules/Languages/pl/unicode-full.yaml @@ -291,7 +291,7 @@ - "†": [t: "obelisk"] # 0x2020 - "‡": [t: "podwójny obelisk"] # 0x2021 - - " - ": [t: " "] # 0x2000 - 0x2007 + - " - ": [T: " "] # 0x2000 - 0x2007 - "•": # 0x2022 - test: @@ -344,7 +344,7 @@ - "⁑": [t: "dwie pionowe gwiazdki"] # 0x2051 - "⁒": [t: "handlowy znak minus"] # 0x2052 - "⁗": [t: "poczwórny prim"] # 0x2057 - - "⁠": [t: ""] # 0x2060 + - "⁠": [T: ""] # 0x2060 - "⁰": [t: "do zerowej potęgi"] # 0x2070 - "ⁱ": [t: "do potęgi i"] # 0x2071 - "⁴": [t: "do czwartej potęgi"] # 0x2074 @@ -409,7 +409,7 @@ - "₴": [t: "hrywny"] # 0x20b4 - "₵": [t: "cedi"] # 0x20b5 - "₶": [t: "liwr turoński"] # 0x20b6 - - "₷": [t: "spesmilos"] # 0x20b7 + - "₷": [T: "spesmilos"] # 0x20b7 - "₸": [t: "tenge"] # 0x20b8 - "₹": [t: "rupie indyjskie"] # 0x20b9 - "₺": [t: "liry tureckie"] # 0x20ba @@ -473,7 +473,7 @@ - "№": [t: "numer"] # 0x2116 - "℥": [t: "uncje"] # 0x2125 - "Ω": [t: "omy"] # 0x2126 - - "℧": [t: "mhos"] # 0x2127 + - "℧": [T: "mho"] # 0x2127 - "℩": [t: "odwrócony jota"] # 0x2129 - "K": [t: "kelwin"] # 0x212a - "Å": [t: "angstremy"] # 0x212b @@ -522,37 +522,37 @@ - "⅞": [t: "siedem ósmych"] # 0x215e - "⅟": [t: "jeden przez"] # 0x215f - "Ⅰ": [t: "I"] # 0x2160 - - "Ⅱ": [t: "I I"] # 0x2161 - - "Ⅲ": [t: "I I I"] # 0x2162 - - "Ⅳ": [t: "I V"] # 0x2163 - - "Ⅴ": [t: "V"] # 0x2164 - - "Ⅵ": [t: "V I"] # 0x2165 - - "Ⅶ": [t: "V I I"] # 0x2166 - - "Ⅷ": [t: "V I I I"] # 0x2167 - - "Ⅸ": [t: "I X"] # 0x2168 - - "Ⅹ": [t: "X"] # 0x2169 - - "Ⅺ": [t: "X I"] # 0x216a - - "Ⅻ": [t: "X I I"] # 0x216b - - "Ⅼ": [t: "L"] # 0x216c - - "Ⅽ": [t: "C"] # 0x216d - - "Ⅾ": [t: "D"] # 0x216e - - "Ⅿ": [t: "M"] # 0x216f + - "Ⅱ": [T: "I I"] # 0x2161 + - "Ⅲ": [T: "I I I"] # 0x2162 + - "Ⅳ": [T: "I V"] # 0x2163 + - "Ⅴ": [T: "V"] # 0x2164 + - "Ⅵ": [T: "V I"] # 0x2165 + - "Ⅶ": [T: "V I I"] # 0x2166 + - "Ⅷ": [T: "V I I I"] # 0x2167 + - "Ⅸ": [T: "I X"] # 0x2168 + - "Ⅹ": [T: "X"] # 0x2169 + - "Ⅺ": [T: "X I"] # 0x216a + - "Ⅻ": [T: "X I I"] # 0x216b + - "Ⅼ": [T: "L"] # 0x216c + - "Ⅽ": [T: "C"] # 0x216d + - "Ⅾ": [T: "D"] # 0x216e + - "Ⅿ": [T: "M"] # 0x216f - "ⅰ": [t: "I"] # 0x2170 - - "ⅱ": [t: "I I"] # 0x2171 - - "ⅲ": [t: "I I I"] # 0x2172 - - "ⅳ": [t: "I V"] # 0x2173 - - "ⅴ": [t: "V"] # 0x2174 - - "ⅵ": [t: "V I"] # 0x2175 - - "ⅶ": [t: "V I I"] # 0x2176 - - "ⅷ": [t: "V I I I"] # 0x2177 - - "ⅸ": [t: "I X"] # 0x2178 - - "ⅹ": [t: "X"] # 0x2179 - - "ⅺ": [t: "X I"] # 0x217a - - "ⅻ": [t: "X I I"] # 0x217b - - "ⅼ": [t: "L"] # 0x217c - - "ⅽ": [t: "C"] # 0x217d - - "ⅾ": [t: "D"] # 0x217e - - "ⅿ": [t: "M"] # 0x217f + - "ⅱ": [T: "I I"] # 0x2171 + - "ⅲ": [T: "I I I"] # 0x2172 + - "ⅳ": [T: "I V"] # 0x2173 + - "ⅴ": [T: "V"] # 0x2174 + - "ⅵ": [T: "V I"] # 0x2175 + - "ⅶ": [T: "V I I"] # 0x2176 + - "ⅷ": [T: "V I I I"] # 0x2177 + - "ⅸ": [T: "I X"] # 0x2178 + - "ⅹ": [T: "X"] # 0x2179 + - "ⅺ": [T: "X I"] # 0x217a + - "ⅻ": [T: "X I I"] # 0x217b + - "ⅼ": [T: "L"] # 0x217c + - "ⅽ": [T: "C"] # 0x217d + - "ⅾ": [T: "D"] # 0x217e + - "ⅿ": [T: "M"] # 0x217f - "↉": [t: "zero trzecich"] # 0x2189 - "↔": [t: "lewy strzałka w prawo"] # 0x2194 - "↕": [t: "górny strzałka w dół"] # 0x2195 @@ -1081,11 +1081,6 @@ - "⊢": [t: "dowodzi"] # 0x22a2 - "⊣": [t: "jest dowodzone przez"] # 0x22a3 - "⊤": [t: "góra"] # 0x22a4 - - "⊥": # 0x22a5 - - test: - if: "$Verbosity!='Terse'" - then: [T: "jest"] - - t: "dół" - "⊦": [t: "redukuje się do"] # 0x22a6 - "⊧": [t: "modeluje"] # 0x22a7 - "⊨": # 0x22a8 @@ -1538,7 +1533,7 @@ - "♁": [t: "Ziemia"] # 0x2641 - "♂": [t: "męskie"] # 0x2642 - "♃": [t: "Jowisz"] # 0x2643 - - "♄": [t: "Saturn"] # 0x2644 + - "♄": [T: "Saturn"] # 0x2644 - "♅": [t: "Uran"] # 0x2645 - "♆": [t: "Neptun"] # 0x2646 - "♇": [t: "Pluton"] # 0x2647 @@ -1662,11 +1657,15 @@ - "➾": [t: "otwarta konturowa strzałka w prawo"] # 0x27be - "⟀": [t: "trójwymiarowy kąt"] # 0x27c0 - "⟁": [t: "biały trójkąt zawierający mały biały trójkąt"] # 0x27c1 - - "⟂": # 0x27c2 - - test: - if: "$Verbosity!='Terse'" - then: [T: "jest"] - - t: "prostopadłe do" + - "⟂⊥": # 0x27c2, 22A5 (22A5 wrongly used for perpendicular by most editors) + - test: + - if: "$SpeechStyle = 'LiteralSpeak' and text()='⊥'" # 22A5 (up tack/bottom) + then: [T: "dół"] + - else: + - test: + if: "$Verbosity!='Terse'" + then: [T: "jest"] + - T: "prostopadłe do" - "⟃": # 0x27c3 - test: if: "$Verbosity!='Terse'" @@ -2354,10 +2353,10 @@ - "⸌": [t: "lewy podniesiony pominięcia nawias kwadratowy"] # 0x2e0c - "⸍": [t: "prawy podniesiony pominięcia nawias kwadratowy"] # 0x2e0d - "⸎": [t: "redakcyjny koronis"] # 0x2e0e - - "⸏": [t: "paragraphos"] # 0x2e0f + - "⸏": [T: "paragraphos"] # 0x2e0f - "⸐": [t: "rozwidlony paragrafos"] # 0x2e10 - "⸑": [t: "odwrócony rozwidlony paragrafos"] # 0x2e11 - - "⸒": [t: "hypodiastole"] # 0x2e12 + - "⸒": [T: "hypodiastole"] # 0x2e12 - "⸓": [t: "kropkowany obelos"] # 0x2e13 - "⸔": [t: "dolny ancora"] # 0x2e14 - "⸕": [t: "górny ancora"] # 0x2e15 @@ -2466,7 +2465,7 @@ - "㍲": [t: "daltony"] # 0x3372 - "㍳": [t: "jednostki astronomiczne"] # 0x3373 - "㍴": [t: "bary"] # 0x3374 - - "㍵": [t: "o V"] # 0x3375 + - "㍵": [T: "o V"] # 0x3375 - "㍶": [t: "parseki"] # 0x3376 - "㍷": [t: "decymetry"] # 0x3377 - "㍸": [t: "decymetry do kwadratu"] # 0x3378 @@ -2559,7 +2558,7 @@ - "㏔": [t: "milibarny"] # 0x33d4 - "㏕": [t: "mile"] # 0x33d5 - "㏖": [t: "mole"] # 0x33d6 - - "㏗": [t: "p h"] # 0x33d7 + - "㏗": [T: "p h"] # 0x33d7 - "㏘": [t: "pikometry"] # 0x33d8 - "㏙": [t: "części na milion"] # 0x33d9 - "㏚": [t: "petarentgeny"] # 0x33da @@ -2992,30 +2991,30 @@ - "": [t: "stała Plancka przez dwa pi kreska"] # 0xed00 - "": [t: "lustrzane g"] # 0xed01 - "": [t: "j bez kropki"] # 0xed02 - - "": [t: "digamma"] # 0xed03 - - "ϝ": [t: "digamma"] # 0x3dd - - "": [t: "d"] # 0xed10 - - "ⅆ": [t: "d"] # 0x2146 + - "": [T: "digamma"] # 0xed03 + - "ϝ": [T: "digamma"] # 0x3dd + - "": [T: "d"] # 0xed10 + - "ⅆ": [T: "d"] # 0x2146 - "": [t: "e"] # 0xed11 - "ⅇ": [t: "e"] # 0x2147 - "": [t: "i"] # 0xed12 - "ⅈ": [t: "i"] # 0x2148 - - "": [t: "j"] # 0xed13 + - "": [T: "j"] # 0xed13 - "ⅅ": - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 # The private use chars are from MathType - "": [t: "całka krzywoliniowa z pętlą przeciwnie do ruchu wskazówek zegara"] # 0xee00 - "": [t: "całka krzywoliniowa z pętlą zgodnie z ruchem wskazówek zegara"] # 0xee01 - - "": [t: ""] # 0xee04 - - "": [t: ""] # 0xee05 - - "": [t: ""] # 0xee06 - - "": [t: ""] # 0xee07 - - "": [t: ""] # 0xee08 - - "": [t: ""] # 0xee09 - - "": [t: ""] # 0xee0a - - "": [t: ""] # 0xee0b - - "": [t: ""] # 0xee0c + - "": [T: ""] # 0xee04 + - "": [T: ""] # 0xee05 + - "": [T: ""] # 0xee06 + - "": [T: ""] # 0xee07 + - "": [T: ""] # 0xee08 + - "": [T: ""] # 0xee09 + - "": [T: ""] # 0xee0a + - "": [T: ""] # 0xee0b + - "": [T: ""] # 0xee0c - "": [t: "ozdobnik statusu połączenia"] # 0xee0d - "": [t: "lewy ozdobnik statusu połączenia"] # 0xee0e - "": [t: "prawy ozdobnik statusu połączenia"] # 0xee0f @@ -3040,24 +3039,24 @@ - "": [t: "kreska akcent z zamkniętym okręgiem po prawej"] # 0xee23 - "": [t: "duży kropka nad"] # 0xee24 - "": [t: "znak wyrównania"] # 0xef00 - - "": [t: ""] # 0xef01 - - "​": [t: ""] # 0x200b - - "": [t: ""] # 0xef02 - - " ": [t: ""] # 0x2009 - - "": [t: ""] # 0xef03 - - " ": [t: ""] # 0x205f - - "": [t: ""] # 0xef04 - - "": [t: ""] # 0xef05 - - "": [t: ""] # 0xef06 - - "": [t: ""] # 0xef07 - - "": [t: ""] # 0xef08 - - "": [t: ""] # 0xef09 - - "": [t: ""] # 0xef0a - - " ": [t: ""] # 0x200a - - "": [t: ""] # 0xef22 - - "": [t: ""] # 0xef23 - - "": [t: ""] # 0xef24 - - "": [t: ""] # 0xef29 + - "": [T: ""] # 0xef01 + - "​": [T: ""] # 0x200b + - "": [T: ""] # 0xef02 + - " ": [T: ""] # 0x2009 + - "": [T: ""] # 0xef03 + - " ": [T: ""] # 0x205f + - "": [T: ""] # 0xef04 + - "": [T: ""] # 0xef05 + - "": [T: ""] # 0xef06 + - "": [T: ""] # 0xef07 + - "": [T: ""] # 0xef08 + - "": [T: ""] # 0xef09 + - "": [T: ""] # 0xef0a + - " ": [T: ""] # 0x200a + - "": [T: ""] # 0xef22 + - "": [T: ""] # 0xef23 + - "": [T: ""] # 0xef24 + - "": [T: ""] # 0xef29 - "": [t: "brakujący składnik"] # 0xef41 - "": [t: "całka krzywoliniowa zgodna z ruchem wskazówek zegara ze strzałką po lewej"] # 0xef80 - "": [t: "całka z kwadrat"] # 0xef81 @@ -3564,13 +3563,13 @@ - "": [t: "prawy nawias klamrowy środkowy"] # 0xf8fd - "": [t: "prawy nawias klamrowy dolny"] # 0xf8fe - "": [t: "logo jabłka"] # 0xf8ff - - "ff": [t: "ff"] # 0xfb00 + - "ff": [T: "ff"] # 0xfb00 - "fi": [t: "fi"] # 0xfb01 - - "fl": [t: "fl"] # 0xfb02 - - "ffi": [t: "ffi"] # 0xfb03 - - "ffl": [t: "ffl"] # 0xfb04 - - "ſt": [t: "ft"] # 0xfb05 - - "st": [t: "st"] # 0xfb06 + - "fl": [T: "fl"] # 0xfb02 + - "ffi": [T: "ffi"] # 0xfb03 + - "ffl": [T: "ffl"] # 0xfb04 + - "ſt": [T: "ft"] # 0xfb05 + - "st": [T: "st"] # 0xfb06 - "﬩": [t: "hebrajska litera alternatywny znak plus"] # 0xfb29 - "︠": [t: "lewa połowa ligatury, ozdobnik"] # 0xfe20 - "︡": [t: "prawa połowa ligatury, ozdobnik"] # 0xfe21 diff --git a/Rules/Languages/pl/unicode.yaml b/Rules/Languages/pl/unicode.yaml index 6d90fdcd3..bd3ee353a 100644 --- a/Rules/Languages/pl/unicode.yaml +++ b/Rules/Languages/pl/unicode.yaml @@ -60,9 +60,9 @@ # note: processing of ranges converts '.' into the character, so it needs to be in quotes below replace: [spell: "translate('.', 'BCDEFGHIJKLMNOPQRSTUVWXYZ', 'bcdefghijklmnopqrstuvwxyz')"] - - "0-9": [t: "."] + - "0-9": [T: "."] - - " ": [t: " "] # 0x20 + - " ": [T: " "] # 0x20 - "!": # 0x21 - test: @@ -337,8 +337,8 @@ (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) )" then: [T: "z"] - - "⁢": [t: ""] # 0x2062 - - "⁣": [t: ""] # 0x2063 + - "⁢": [T: ""] # 0x2062 + - "⁣": [T: ""] # 0x2063 - "⁤": [T: "i"] # 0x2064 - "′": [t: "prim"] # 0x2032 - "″": [t: "podwójny prim"] # 0x2033 diff --git a/src/navigate.rs b/src/navigate.rs index f893b3838..95e4c3530 100644 --- a/src/navigate.rs +++ b/src/navigate.rs @@ -1765,6 +1765,59 @@ mod tests { }); } + #[test] + fn zoom_speech_pl() -> Result<()> { + let mathml_str = " + b2 + d + "; + init_prefs(mathml_str, "Enhanced", "pl")?; + return MATHML_INSTANCE.with(|package_instance| { + let package_instance = package_instance.borrow(); + let mathml = get_element(&package_instance); + let speech = test_command("ZoomIn", mathml, "msup")?; + assert_eq!("przybliż; do licznika; b do kwadratu", speech); + let speech = test_command("ZoomIn", mathml, "base")?; + assert_eq!("przybliż; do podstawy; b", speech); + let speech = test_command("ZoomOut", mathml, "msup")?; + assert_eq!("oddal; z podstawy; b do kwadratu", speech); + let speech = test_command("ZoomInAll", mathml, "base")?; + assert_eq!("przybliż maksymalnie; do podstawy; b", speech); + let speech = test_command("ZoomOutAll", mathml, "mfrac")?; + assert_eq!("oddal maksymalnie; z podstawy; z licznika; ułamek, b do kwadratu, przez d, koniec ułamka", speech); + return Ok( () ); + }); + } + + #[test] + fn move_char_speech_pl() -> Result<()> { + let mathml_str = " + + + x + y + + + z + + "; + init_prefs(mathml_str, "Character", "pl")?; + return MATHML_INSTANCE.with(|package_instance| { + let package_instance = package_instance.borrow(); + let mathml = get_element(&package_instance); + test_command("ZoomInAll", mathml, "id-3")?; + let speech = test_command("MoveNext", mathml, "id-4")?; + assert_eq!("przejdź w prawo; do mianownika; y", speech); + let speech = test_command("MoveNext", mathml, "id-7")?; + assert_eq!("przejdź w prawo; z mianownika; do pierwiastka; z", speech); + let speech = test_command("MovePrevious", mathml, "id-4")?; + assert_eq!("przejdź w lewo; z pierwiastka; do mianownika; y", speech); + let speech = test_command("MovePrevious", mathml, "id-3")?; + assert_eq!("przejdź w lewo; do licznika; x", speech); + return Ok( () ); + }); + } + #[test] fn move_char_speech_ru() -> Result<()> { let mathml_str = " diff --git a/tests/Languages/pl/alphabets.rs b/tests/Languages/pl/alphabets.rs index 5c2aef97b..eda0a1ae4 100644 --- a/tests/Languages/pl/alphabets.rs +++ b/tests/Languages/pl/alphabets.rs @@ -391,6 +391,21 @@ fn turned() -> Result<()> { } +#[test] +fn up_tack_330() -> Result<()> { + // Znak prostopadłości i znak "dół" wyglądają identycznie, a edytory + // wstawiają U+22A5 tam, gdzie chodzi o prostopadłość. Dlatego oba znaki + // mówią "prostopadłe do", a osobna reguła LiteralSpeak zachowuje dosłowne + // czytanie U+22A5 jako "dół". + let perp = "ab"; // 0x27c2 + test("pl", "SimpleSpeak", perp, "a jest prostopadłe do b")?; + test("pl", "LiteralSpeak", perp, "a jest prostopadłe do b")?; + let up_tack = "ab"; // 0x22a5 + test("pl", "ClearSpeak", up_tack, "a jest prostopadłe do b")?; + test("pl", "LiteralSpeak", up_tack, "a dół b")?; + return Ok(()); + } + #[test] fn unicode_typo_regressions() -> Result<()> { test("pl", "SimpleSpeak", "", "do potęgi i")?; diff --git a/tests/Languages/pl/definitions.rs b/tests/Languages/pl/definitions.rs index 312075f80..338f7ff95 100644 --- a/tests/Languages/pl/definitions.rs +++ b/tests/Languages/pl/definitions.rs @@ -91,7 +91,14 @@ fn set_difference_basic() -> Result<()> { "#; - test("pl", "ClearSpeak", expr, "i z wielka a przecinek, wielka b")?; + // Separator dwuargumentowy: nazwa funkcji + "z" + argumenty spięte słowem "i". + // Wcześniej nazwa przepadała i zostawało samo spoiwo ("i z wielka a..."). + test( + "pl", + "ClearSpeak", + expr, + "różnica zbiorów z wielka a i wielka b", + )?; Ok(()) } @@ -107,7 +114,9 @@ fn postfix_test() -> Result<()> { T "#, - "transpozycja z x", + // Test postfiksowy: bez jawnej fixity silnik bierze PIERWSZĄ z listy + // w IntentMappings, a tam (jak w EN) postfix jest pierwszy. + "x transponowane", ), ( "highlight", @@ -205,9 +214,11 @@ fn functions_and_inverses_tests() -> Result<()> { //("fraction", "fraction x over y end fraction"), ("mixed-fraction", "x i y"), - ("quotient", "podzielone przez z x przecinek, y"), + // Separator dwuargumentowy z IntentMappings ("| podzielone przez"): + // nazwa funkcji wraca na swoje miejsce, a spoiwo łączy oba argumenty. + ("quotient", "część całkowita z x podzielone przez y"), ("evaluated-at", "x obliczone w y"), - ("remainder", "podzielone przez z x przecinek, y"), + ("remainder", "reszta z x podzielone przez y"), ("max", "maksimum z x przecinek, y przecinek, z"), ("min", "minimum z x przecinek, y przecinek, z"), @@ -228,10 +239,18 @@ fn functions_and_inverses_tests() -> Result<()> { ("real-part", "część rzeczywista"), ("imaginary-part", "część urojona"), - ("polar-coordinate", "przecinek z x przecinek, y"), - ("spherical-coordinate", "przecinek z x przecinek, y przecinek, z"), - ("cartesian-coordinate", "przecinek z x przecinek, y przecinek, z"), - ("coordinate", "przecinek, x przecinek y przecinek z"), + // Współrzędne: po usunięciu zbędnego "; przecinek" z IntentMappings + // nazwa wraca na swoje miejsce (wcześniej wyjście brzmiało "przecinek z x..."). + ("polar-coordinate", "współrzędna biegunowa z x przecinek, y"), + ( + "spherical-coordinate", + "współrzędna sferyczna z x przecinek, y przecinek, z", + ), + ( + "cartesian-coordinate", + "współrzędna kartezjańska z x przecinek, y przecinek, z", + ), + ("coordinate", "współrzędna z x przecinek, y przecinek, z"), ("floor", "podłoga z x"), ("ceiling", "sufit z x"), @@ -598,6 +617,11 @@ fn linear_algebra_tests() -> Result<()> { " .to_string() } + "transpose" => " + + x + + ".to_string(), _ => format!( " diff --git a/tests/Languages/pl/mtable.rs b/tests/Languages/pl/mtable.rs index 8403eeae2..093cb1084 100644 --- a/tests/Languages/pl/mtable.rs +++ b/tests/Languages/pl/mtable.rs @@ -265,8 +265,8 @@ fn augmented_matrix_2x3() -> Result<()> { ] "; - test("pl", "ClearSpeak", expr, "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, 4; wiersz 2; 0, 2, 6")?; - test("pl", "SimpleSpeak", expr, "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, 4; wiersz 2; 0, 2, 6")?; + test("pl", "ClearSpeak", expr, "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, separator, 4; wiersz 2; 0, 2, separator, 6")?; + test("pl", "SimpleSpeak", expr, "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, separator, 4; wiersz 2; 0, 2, separator, 6")?; Ok(()) } @@ -897,9 +897,9 @@ let expr = " "; test_ClearSpeak("pl", "ClearSpeak_Matrix", "EndMatrix", - expr, "3 na 4 macierz rozszerzona; wiersz 1; kolumna 1; 1, kolumna 2; 2, kolumna 3; minus 1, kolumna 4; 3; wiersz 2; kolumna 1; minus 3, kolumna 2; 3, kolumna 3; minus 1, kolumna 4; 2; wiersz 3; kolumna 1; 2, kolumna 2; 3, kolumna 3; 2, kolumna 4; minus 1; koniec macierzy")?; + expr, "3 na 4 macierz rozszerzona; wiersz 1; kolumna 1; 1, kolumna 2; 2, kolumna 3; minus 1, separator, kolumna 4; 3; wiersz 2; kolumna 1; minus 3, kolumna 2; 3, kolumna 3; minus 1, separator, kolumna 4; 2; wiersz 3; kolumna 1; 2, kolumna 2; 3, kolumna 3; 2, separator, kolumna 4; minus 1; koniec macierzy")?; test("pl", "SimpleSpeak", - expr, "3 na 4 macierz rozszerzona; wiersz 1; kolumna 1; 1, kolumna 2; 2, kolumna 3; minus 1, kolumna 4; 3; wiersz 2; kolumna 1; minus 3, kolumna 2; 3, kolumna 3; minus 1, kolumna 4; 2; wiersz 3; kolumna 1; 2, kolumna 2; 3, kolumna 3; 2, kolumna 4; minus 1; koniec macierzy")?; + expr, "3 na 4 macierz rozszerzona; wiersz 1; kolumna 1; 1, kolumna 2; 2, kolumna 3; minus 1, separator, kolumna 4; 3; wiersz 2; kolumna 1; minus 3, kolumna 2; 3, kolumna 3; minus 1, separator, kolumna 4; 2; wiersz 3; kolumna 1; 2, kolumna 2; 3, kolumna 3; 2, separator, kolumna 4; minus 1; koniec macierzy")?; Ok(()) } @@ -1294,3 +1294,42 @@ fn single_line_with_label() -> Result<()> { expr, "1 równanie, z etykietą 2; b równa się 2")?; return Ok(()); } + +/// Linia pionowa w tabeli jest zapowiadana jako separator (upstream #679). +#[test] +fn dashed_augmented_matrix_separator() -> Result<()> { + let expr = " + + [ + + 123 + + ] + "; + test("pl", "ClearSpeak", expr, "jeden na 3 wiersz macierz; 1, separator, 2, separator, 3")?; + test("pl", "SimpleSpeak", expr, "jeden na 3 wiersz macierz; 1, separator, 2, separator, 3")?; + Ok(()) +} + +/// Linia pozioma wybrzmiewa RAZ, po wierszu, ktory oddziela od nastepnego. +#[test] +fn matrix_row_separator() -> Result<()> { + let expr = " + + [ + + + 1 + 2 + + + 3 + 4 + + + ] + "; + test("pl", "ClearSpeak", expr, "2 na 2 macierz; wiersz 1; 1, 2, separator wiersza; wiersz 2; 3, 4")?; + test("pl", "SimpleSpeak", expr, "2 na 2 macierz; wiersz 1; 1, 2, separator wiersza; wiersz 2; 3, 4")?; + Ok(()) +}