From 49bb57d0b00d9c46011acf154de136def7fb6b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Arborealis=20L=C3=B6tberg?= <143188129+TimArborealis@users.noreply.github.com> Date: Tue, 1 Sep 2026 11:46:45 +0200 Subject: [PATCH 01/23] Cred to Greek translators --- docs/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index b4283d1d5..9a34a7b71 100644 --- a/docs/index.md +++ b/docs/index.md @@ -173,13 +173,14 @@ Translators: * Finnish -- Sami Määttä (Accessibility Library Celia), and Essi Viippola (freelancer) * French -- Olivier Thiffault (Technologies Humanware) * German -- Nazli Andjic, Robert Graf and Paul Libbrecht (IU International University of Applied Sciences), and Moritz Groß (Math4VIP, Marburg University) +* Greek -- Theodora Antonakopoulou and Paraskevi Riga (National and Kapodistrian University of Athens) * Hungarian -- Attila Hammer (IT Foundation for the Visually Impaired) * Indonesian -- Dr. Pinta Deniyanti Sampoerno, M.Si; Dr. Meiliasari, S.Pd., M.Sc; and Ari Hendarno, S.Pd., M.Kom. -* Norwegian -- Marthe Gjelstad (National Library of Norway), Kvile +* Norwegian -- Marthe Gjelstad (National Library of Norway) and Kvile * Polish -- Michał Dziwisz (Fundacja Instytut Rozwoju Regionalnego) * Russian (both speech and braille) -- Danil Kostenkov * Spanish -- Noelia Ruiz Martínez (also helped with NVDA add-on development) and María Allo Roldán -* Swedish -- Tim Arborealis Lötberg (MTM), and Anders Eklund (SPSM) +* Swedish -- Tim Arborealis Lötberg (MTM) and Anders Eklund (SPSM) * Vietnamese -- Dang Hoai Phúc and Trang Pham * Others??? -- please volunteer so I can list you here... From 0932ffb8f4f0429518b28dd06071316d389a9b0b Mon Sep 17 00:00:00 2001 From: K4itsit Date: Wed, 2 Sep 2026 20:18:10 +0800 Subject: [PATCH 02/23] Fix outdated MathCAT project URLs (#732) Co-authored-by: k4its1t <306379390+k4its1t@users.noreply.github.com> --- Cargo.toml | 6 +++--- README.md | 2 +- Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml | 2 +- Rules/Braille/French/French_Rules.yaml | 2 +- Rules/Braille/LaTeX/LaTeX_Rules.yaml | 2 +- Rules/Braille/Nemeth/Nemeth_Rules.yaml | 4 ++-- Rules/Braille/Swedish/Swedish_Rules.yaml | 2 +- Rules/Braille/UEB/UEB_Rules.yaml | 2 +- Rules/Braille/Vietnam/Vietnam_Rules.yaml | 2 +- Rules/Intent/general.yaml | 2 +- docs/helpers_old.md | 2 +- docs/ru/helpers.md | 2 +- src/canonicalize.rs | 2 +- src/chemistry.rs | 2 +- src/navigate.rs | 2 +- src/speech.rs | 2 +- src/xpath_functions.rs | 2 +- tests/braille/Nemeth/other.rs | 14 +++++++------- tests/braille/Nemeth/rules.rs | 6 +++--- tests/braille/UEB/iceb.rs | 2 +- tests/braille/UEB/other.rs | 10 +++++----- 21 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 67522e0b3..fcf5428d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,9 @@ version = "0.7.7-alpha.1" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" -repository = "https://github.com/NSoiffer/MathCAT" -homepage = "https://nsoiffer.github.io/MathCAT/" -documentation = "https://nsoiffer.github.io/MathCAT/" +repository = "https://github.com/daisy/MathCAT" +homepage = "https://daisy.github.io/MathCAT/" +documentation = "https://daisy.github.io/MathCAT/" edition = "2024" exclude = ["src/main.rs", "docs", "BrailleDocs", "PythonScripts"] # should have "Rules/", but then one can't run build.rs to build the zip file diff --git a/README.md b/README.md index bf974dc3b..0ee92c6fa 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,4 @@ There are four related projects that make use of MathCAT: MathCAT is used in many assistive technologies including NVDA and JAWS. -For more information, see the [full documentation](https://nsoiffer.github.io/MathCAT/). +For more information, see the [full documentation](https://daisy.github.io/MathCAT/). diff --git a/Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml b/Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml index d3cb9d090..edae6abab 100644 --- a/Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml +++ b/Rules/Braille/ASCIIMath/ASCIIMath_Rules.yaml @@ -223,7 +223,7 @@ # FIX: what should be output name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/French/French_Rules.yaml b/Rules/Braille/French/French_Rules.yaml index 46c74a15c..f3514cebf 100644 --- a/Rules/Braille/French/French_Rules.yaml +++ b/Rules/Braille/French/French_Rules.yaml @@ -326,7 +326,7 @@ - name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/LaTeX/LaTeX_Rules.yaml b/Rules/Braille/LaTeX/LaTeX_Rules.yaml index 315192dde..b9237dee0 100644 --- a/Rules/Braille/LaTeX/LaTeX_Rules.yaml +++ b/Rules/Braille/LaTeX/LaTeX_Rules.yaml @@ -235,7 +235,7 @@ # FIX: what should be output name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/Nemeth/Nemeth_Rules.yaml b/Rules/Braille/Nemeth/Nemeth_Rules.yaml index 4fe821d0c..b5f74e562 100644 --- a/Rules/Braille/Nemeth/Nemeth_Rules.yaml +++ b/Rules/Braille/Nemeth/Nemeth_Rules.yaml @@ -164,7 +164,7 @@ replace: - test: if: "preceding-sibling::*" - then: [t: "W⣍"] # github.com/NSoiffer/MathCAT/issues/43#issuecomment-1297048039 + then: [t: "W⣍"] # github.com/daisy/MathCAT/issues/43#issuecomment-1297048039 - test: if: .[self::m:mlabeledtr] then: [x: "*[position()>1]"] @@ -900,7 +900,7 @@ - # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) name: chemistry-mhchem-equilibrium-arrow tag: mover match: diff --git a/Rules/Braille/Swedish/Swedish_Rules.yaml b/Rules/Braille/Swedish/Swedish_Rules.yaml index 7a8504574..94a40bdd6 100644 --- a/Rules/Braille/Swedish/Swedish_Rules.yaml +++ b/Rules/Braille/Swedish/Swedish_Rules.yaml @@ -329,7 +329,7 @@ - name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/UEB/UEB_Rules.yaml b/Rules/Braille/UEB/UEB_Rules.yaml index 4d5b8ca1d..912e03d8a 100644 --- a/Rules/Braille/UEB/UEB_Rules.yaml +++ b/Rules/Braille/UEB/UEB_Rules.yaml @@ -300,7 +300,7 @@ - name: mhchem-hack # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) tag: mover match: - "*[1][substring(., 1, 1)='↽'] and" diff --git a/Rules/Braille/Vietnam/Vietnam_Rules.yaml b/Rules/Braille/Vietnam/Vietnam_Rules.yaml index 85146aeb7..60319160b 100644 --- a/Rules/Braille/Vietnam/Vietnam_Rules.yaml +++ b/Rules/Braille/Vietnam/Vietnam_Rules.yaml @@ -360,7 +360,7 @@ - # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) name: chemistry-mhchem-equilibrium-arrow tag: mover match: diff --git a/Rules/Intent/general.yaml b/Rules/Intent/general.yaml index d5ee239e9..15bd1dc7a 100644 --- a/Rules/Intent/general.yaml +++ b/Rules/Intent/general.yaml @@ -380,7 +380,7 @@ - # this captures the output for the mhchem's "<=>", "<<=>", and "<=>>" output (there are no Unicode arrows for them) - # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/NSoiffer/MathCAT/issues/60) + # this isn't a perfect match, but should be good enough and allows merging all three (see github.com/daisy/MathCAT/issues/60) name: chemistry-mhchem-equilibrium-arrow tag: mover match: diff --git a/docs/helpers_old.md b/docs/helpers_old.md index 5266c8b3e..9292a2557 100644 --- a/docs/helpers_old.md +++ b/docs/helpers_old.md @@ -5,7 +5,7 @@ This page is a work-in-progress. ## Getting Started If you plan to work on MathCAT development, you need to make use of github: -1. Fork the MathCAT repo at `github.com/NSoiffer/MathCAT` +1. Fork the MathCAT repo at `github.com/daisy/MathCAT` 2. Clone the forked copy so you have a local copy to work on. 3. Checkout the branch I create for your work (typically the country code for your translation) and work in that branch. diff --git a/docs/ru/helpers.md b/docs/ru/helpers.md index ebcd6e8c4..fa70fc86f 100644 --- a/docs/ru/helpers.md +++ b/docs/ru/helpers.md @@ -11,7 +11,7 @@ title: Руководство переводчика и разработчика ## Начало работы Если вы планируете участвовать в разработке MathCAT, используйте GitHub: -1. Создайте форк репозитория MathCAT `github.com/NSoiffer/MathCAT`. +1. Создайте форк репозитория MathCAT `github.com/daisy/MathCAT`. 2. Клонируйте форк, чтобы получить локальную копию для работы. 3. Переключитесь на созданную для вашей работы ветку, обычно названную кодом языка перевода, и работайте в ней. diff --git a/src/canonicalize.rs b/src/canonicalize.rs index 47be3ad00..0e0a81447 100644 --- a/src/canonicalize.rs +++ b/src/canonicalize.rs @@ -2083,7 +2083,7 @@ impl CanonicalizeContext { fn merge_number_blocks(context: &CanonicalizeContext, parent_mrow: Element, children: &mut Vec) { // debug!("parent:\n{}", mml_to_string(parent_mrow)); // If we find a comma that is not part of a number, don't form a number - // (see https://github.com/NSoiffer/MathCAT/issues/271) + // (see https://github.com/daisy/MathCAT/issues/271) // Unfortunately, we can't do this in the loop below because we might discover the "not part of a number" after a number has been formed let do_not_merge_comma = is_comma_not_part_of_a_number(children); let mut i = 0; diff --git a/src/chemistry.rs b/src/chemistry.rs index 5bec42313..173c5cccb 100644 --- a/src/chemistry.rs +++ b/src/chemistry.rs @@ -1653,7 +1653,7 @@ fn likely_chem_equation_operator(mathml: Element) -> i32 { return -3; // there is still a chance /// Detects output of mhchem for some equilibrium arrows that currently (11/22) don't have Unicode points - /// See github.com/NSoiffer/MathCAT/issues/60 for the patterns being matched + /// See github.com/daisy/MathCAT/issues/60 for the patterns being matched fn is_hack_for_missing_arrows(mover: Element) -> bool { assert_eq!(name(mover), "mover"); let children = mover.children(); diff --git a/src/navigate.rs b/src/navigate.rs index f893b3838..a3365ef56 100644 --- a/src/navigate.rs +++ b/src/navigate.rs @@ -798,7 +798,7 @@ fn key_press_to_command_and_param( // key press mapping should probably be stored externally (registry) with an app that allows changes // for now, we build in the defaults - // this is a hack to map alt+ctl+arrow to ctl+arrow to change table mappings (github.com/NSoiffer/MathCAT/issues/105) + // this is a hack to map alt+ctl+arrow to ctl+arrow to change table mappings (github.com/daisy/MathCAT/issues/105) // if this change sticks, choose_command() needs to be changed and this hack should go away let mut alt_key = alt_key; if alt_key && control_key && [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN].contains(&key) { diff --git a/src/speech.rs b/src/speech.rs index eaaeff282..100d5ff39 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -152,7 +152,7 @@ fn speak_rules(rules: &'static std::thread::LocalKey>, math // debug!("Speech string: {}", speech_string); // Note: [[...]] is added around a matching child, but if the "id" is on 'mathml', the whole string is used if !rules_with_context.nav_node_id.is_empty() { - // See https://github.com/NSoiffer/MathCAT/issues/174 for why we can just start the speech at the nav node + // See https://github.com/daisy/MathCAT/issues/174 for why we can just start the speech at the nav node let raw_intent_attr = mathml.attribute_value("data-intent-property"); let intent_attr = raw_intent_attr.as_deref().unwrap_or_default(); if let Some(start) = speech_string.find("[[") { diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index 19cf0b6cd..97e1db5ee 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -1945,7 +1945,7 @@ mod tests { test_is_not_simple("-x y z", "-x ⁢y⁢z")?; - test_is_not_simple("C(-2,1,4)", // github.com/NSoiffer/MathCAT/issues/199 + test_is_not_simple("C(-2,1,4)", // github.com/daisy/MathCAT/issues/199 "C(−2,1,4)")?; return Ok( () ); }); diff --git a/tests/braille/Nemeth/other.rs b/tests/braille/Nemeth/other.rs index 102c68096..5efae3d3d 100644 --- a/tests/braille/Nemeth/other.rs +++ b/tests/braille/Nemeth/other.rs @@ -5,7 +5,7 @@ use anyhow::Result; #[test] fn not_number_space_blocks() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "123 ⁣456"; test_braille("Nemeth", expr, "⠼⠂⠆⠒⠀⠼⠲⠢⠖")?; return Ok(()); @@ -14,7 +14,7 @@ fn not_number_space_blocks() -> Result<()> { #[test] fn space_between_digits() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "1 3 5"; test_braille("Nemeth", expr, "⠼⠂⠀⠼⠒⠀⠼⠢")?; return Ok(()); @@ -23,7 +23,7 @@ fn space_between_digits() -> Result<()> { #[test] fn space_hack_between_digits() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "1 ⁣3 ⁣5"; test_braille("Nemeth", expr, "⠼⠂⠀⠼⠒⠀⠼⠢")?; return Ok(()); @@ -32,7 +32,7 @@ fn space_hack_between_digits() -> Result<()> { #[test] fn tilde_prefix_bug_244() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/244 + // https://github.com/daisy/MathCAT/issues/244 let expr = " ~ p "; test_braille("Nemeth", expr, "⠈⠱⠏")?; return Ok(()); @@ -41,7 +41,7 @@ fn tilde_prefix_bug_244() -> Result<()> { #[test] fn double_struck_bug_334() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/334 -- double struck was problem (⠼ was missing); test all of the scripted numbers here + // https://github.com/daisy/MathCAT/issues/334 -- double struck was problem (⠼ was missing); test all of the scripted numbers here let expr = "𝟙,𝟐,𝟯,𝟺"; test_braille("Nemeth", expr, "⠠⠸⠼⠂⠠⠀⠸⠼⠆⠠⠀⠠⠨⠸⠼⠒⠠⠀⠼⠲")?; return Ok(()); @@ -50,7 +50,7 @@ fn double_struck_bug_334() -> Result<()> { #[test] fn extra_indicators_bug_343() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/343 -- extra indicators before baseline indicator due to -x^2, not there for x^2 + // https://github.com/daisy/MathCAT/issues/343 -- extra indicators before baseline indicator due to -x^2, not there for x^2 let expr = " @@ -78,7 +78,7 @@ fn extra_indicators_bug_343() -> Result<()> { #[test] fn find_baseline_indicator_bug_364() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/364 + // https://github.com/daisy/MathCAT/issues/364 let expr = r#" π diff --git a/tests/braille/Nemeth/rules.rs b/tests/braille/Nemeth/rules.rs index 18d31204f..d0cde7248 100644 --- a/tests/braille/Nemeth/rules.rs +++ b/tests/braille/Nemeth/rules.rs @@ -71,7 +71,7 @@ fn test_9_b_4() -> Result<()> { } #[test] fn test_9_c_1_linear() -> Result<()> { - // see https://github.com/NSoiffer/MathCAT/issues/43 for discussion on linear layout + // see https://github.com/daisy/MathCAT/issues/43 for discussion on linear layout let expr = "| 12 -3-4 @@ -1763,7 +1763,7 @@ fn racket_below_121_4() -> Result<()> { #[test] fn identity_matrix_126_linearize() -> Result<()> { - // see https://github.com/NSoiffer/MathCAT/issues/43 for discussion on linear layout + // see https://github.com/daisy/MathCAT/issues/43 for discussion on linear layout let expr = " ( 100 010 @@ -2203,7 +2203,7 @@ fn tensor_from_mathml_spec() -> Result<()> { l "; - // Note: the braille answer was verified to be correct (see https://github.com/NSoiffer/MathCAT/issues/55) + // Note: the braille answer was verified to be correct (see https://github.com/daisy/MathCAT/issues/55) test_braille("Nemeth", expr, "⠠⠗⠰⠊⠐⠘⠚⠐⠰⠅⠐⠰⠇")?; return Ok(()); } diff --git a/tests/braille/UEB/iceb.rs b/tests/braille/UEB/iceb.rs index b7f3a6560..3bd48b19b 100644 --- a/tests/braille/UEB/iceb.rs +++ b/tests/braille/UEB/iceb.rs @@ -522,7 +522,7 @@ fn ratio_3_2_6() -> Result<()> { #[test] fn standing_alone_1() -> Result<()> { - // Tests bug: github.com/NSoiffer/MathCAT/issues/142 + // Tests bug: github.com/daisy/MathCAT/issues/142 let expr = "(n=7)"; test_braille("UEB", expr, "⠐⠣⠰⠝⠀⠐⠶⠀⠼⠛⠐⠜")?; return Ok(()); diff --git a/tests/braille/UEB/other.rs b/tests/braille/UEB/other.rs index f1beb55cc..7dda38f6c 100644 --- a/tests/braille/UEB/other.rs +++ b/tests/braille/UEB/other.rs @@ -72,7 +72,7 @@ fn number_space_before_and_after() -> Result<()> { #[test] fn not_number_space_blocks() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "123 ⁣456"; test_braille("UEB", expr, "⠼⠁⠃⠉⠀⠼⠙⠑⠋")?; return Ok(()); @@ -81,7 +81,7 @@ fn not_number_space_blocks() -> Result<()> { #[test] fn dot_above_bug_204() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/204 + // https://github.com/daisy/MathCAT/issues/204 let expr = " 0. 6 · "; test_braille("UEB", expr, "⠼⠚⠲⠣⠼⠋⠜⠘⠲")?; return Ok(()); @@ -90,7 +90,7 @@ fn dot_above_bug_204() -> Result<()> { #[test] fn tilde_prefix_bug_244() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/244 + // https://github.com/daisy/MathCAT/issues/244 let expr = " ~ p "; test_braille("UEB", expr, "⠈⠔⠏")?; return Ok(()); @@ -109,7 +109,7 @@ fn double_tilde_prefix_bug_244() -> Result<()> { #[test] fn space_hack_between_digits() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "1 ⁣3 ⁣5"; test_braille("UEB", expr, "⠼⠁⠀⠼⠉⠀⠼⠑")?; return Ok(()); @@ -118,7 +118,7 @@ fn space_hack_between_digits() -> Result<()> { #[test] fn space_hack_around_operator() -> Result<()> { - // https://github.com/NSoiffer/MathCAT/issues/144 + // https://github.com/daisy/MathCAT/issues/144 let expr = "y ⁣= ⁣5"; test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠼⠑")?; return Ok(()); From 72e2b1ddf81950d2f12c6fd6cb2aadcdf4df8dac Mon Sep 17 00:00:00 2001 From: natalieac03 Date: Wed, 2 Sep 2026 10:04:44 -0300 Subject: [PATCH 03/23] Add Brazilian Portuguese (pt) translation- #729 (#736) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create test * Traducao das regras pt-BR: unicode, definitions, SimpleSpeak, SharedRules e testes * Versão inicial em português do MathCAT * Corrige bugs da auditoria e traduz unicode-full.yaml (acentos, setas, operadores, formas) * Regras da rodada de testes: probability, ignore_period, unicode-full * Corrige unidades sec/arcsec, remove dot-over espúria, ACHADOS.md * pt: corrige 7 bugs de regra e reconcilia os testes (92/92) cargo test Languages::pt saía de 33 falhas em 91 testes. Agora passa 92/92, e a suíte inteira do repositório continua verde. Nada em src/ foi tocado. Bugs de regra: - SharedRules/general.yaml: a distinção Verbose/Medium tinha desabado na química. 14 pares de ramos diziam "subscrito"/"sobrescrito" nos dois níveis, onde o inglês tem subscript/sub. Um deles (ramo $Prescripts[4]) dizia "subscrito" onde o inglês diz superscript. - SharedRules/general.yaml: ligação dupla escrita "::" não era reconhecida. A regra testava .='::', mas o canonicalizador converte para ∷ (U+2237) antes de as regras rodarem, então H₂C::CH₂ saía "maiúsculo c, como maiúsculo c". - unicode.yaml: a regra de "|" era uma simplificação da inglesa e perdia três casos — P(A|B) ("dado"), a|b entre números ("divide") e o intent literal. Portada a estrutura inglesa inteira. - SharedRules/general.yaml: fora da química caía no default-text, que fala o nome da tag, e saía a palavra inglesa "none". Agora "nenhum". - SharedRules/general.yaml: faltava o Log maiúsculo (valor principal), que saía "Log de x". Marcado t: — a tradução precisa de conferência. - definitions.yaml: "segundo de arco" estava duplicado em PluralForms. O leitor de YAML do Rust aceita, mas audit-translations recusava o arquivo inteiro, ou seja, definitions.yaml não estava sendo auditado de verdade. - definitions.yaml: plurais das formas prefixadas de "segundo de arco", que a regra genérica produzia como "yoctossegundo de arcos". Testes desatualizados: pausas geradas pelo motor (ver ACHADOS.md seção 1), o artigo em "o log de x", "1 meio" em vez de "um meio", "l n x" no modo conciso, e a vírgula do grego (que o teste inglês também tem). Decisão: menos unário fica "menos", não "negativo". Os testes estavam divididos; a regra já dizia "menos" e os três discordantes foram alinhados. Resolve duas pendências do ACHADOS.md: a contradição aparente entre tensor_mmultiscripts e mhchem_so4_2mais (caminhos de código diferentes — só o da química estava quebrado) e a divergência de inverse_trig entre SimpleSpeak e ClearSpeak (as regras já estavam alinhadas; era o teste). ACHADOS.md ganha a seção 6. Corrigidas duas afirmações das seções anteriores: compute_auto_pause conta bytes, não letras; e as regras de química não eram idênticas às inglesas (só as diretivas de pausa eram). Registrado também que trocar bytes por caracteres foi testado e não resolve — piora de 15 para 36 falhas. Co-Authored-By: Claude Opus 5 * Terminologia: maiúscula, romanos por valor, expoente zero cardinal, testes * pt: pertinência sem verbo finito dentro de conjunto; ∉ com In deixa de colidir com ⊄ Duas correções de fala, com varredura e não caso a caso (ACHADOS 7.8/7.9): 1. Dentro de um conjunto ({x ∈ ℤ : x > 5}) a expressão modifica "todos os x" e não pode ter verbo finito nem singular: o verbo grudava em "conjunto" ("o conjunto de todos os x pertence a inteiros"). Seis dos oito ramos estavam errados, não só o Belongs. Agora: em / membros de / elementos de / pertencentes a, e as negações nominais. "fora de" foi rejeitado por trocar pertinência por localização; "não em" por ser truncado. O ramo SimpleSpeak usava uma string só para dentro e fora e passou a bifurcar. 2. ∉ com ClearSpeak_SetMemberSymbol=In fora de conjunto falava "não está contido em", exatamente a fala do ⊄. Passa a "não está em", espelhando o ∈. Também nesta rodada, já em varredura: termo único por família de estilo (fraktur, caligráfico) e adjetivo posposto nos dois arquivos; ∈ ∊ com Auto separado de Member como o ∉; ! volta a distinguir literal/fatorial; ≇ ≚ ≞ ⋕ com termo matemático em vez do nome Unicode; cópula dupla em ∦ ⊈ ⊉. Novo: tests/Languages/pt/ClearSpeak/sets.rs (pt vai de 102 para 142 testes, ∈ e ∊ travados iguais nas cinco preferências e nos dois estilos), PythonScripts/conferir_vocabulario.py (consistência de vocabulário entre unicode.yaml e unicode-full.yaml: 8 -> 4 grupos, restantes benignos) e Rules/Languages/pt/TERMINOLOGIA_PT_BR.md (registro único das leituras). Suíte inteira: 7307 passed, 0 failed. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0134dJm6wzqbquvZrNhPD3Ea * pt: corrige o que o material real do ACESSÍLIA exige; recuo controlado; pacote de escuta Diagnóstico antes de escolher (ACHADOS 9): o MathML do ACESSÍLIA vem do latex2mathml nos dois caminhos (inclusive Docling) e nunca traz intent=, então os 186 IntentMappings ausentes não são prioridade. O que importa é o que o motor infere sozinho e o que sai cru para o sintetizador. Correções, pelo dano ao estudante: - caracteres crus no corpus real: negrito latino e grego (\mathbf, \boldsymbol), ⟨ ⟩, ¯ de \bar{x} (o motor canonicaliza U+0304/U+203E para U+00AF, então a entrada "com mácron" nunca era alcançada), setas longas, µ Ω ℧ Å soltos - "1 terceiro" -> "1 terço": listas fracionárias paravam em "meio" - "o integral" -> "a integral": artigo concorda com o operador grande - "magnitude de x" -> "a norma de x": intent inferido sem mapping pt - "cross product"/"dot product" literais -> "produto vetorial/escalar": o intent inferido vem sem filhos e nenhuma regra casava com count(*)=0 - recuo controlado só em regra (gerar_recuo_en.py): 2091 entradas do en para codepoints sem cobertura, estilo já definido traduzido, resto em t: minúsculo. Antes o caractere saía cru; agora sai em inglês, contado como pendente. Pacote da sessão de escuta (gerar_pacote_escuta.py -> SESSAO_ESCUTA.md): 30 expressões em 6 áreas, fala real nos dois estilos e três verbosidades, roteiro e tabela das decisões que dependem do ouvinte. cargo test: 7307 passed, 0 failed (pt: 142). conferir_vocabulario.py: 4 grupos, todos benignos, antes e depois. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0134dJm6wzqbquvZrNhPD3Ea * pt: P(A ∣ B) fala "dado"; varredura de vazamento nas 593 expressões do en O latex2mathml emite \mid como U+2223, não "|": P(A ∣ B) saía "A divide B". A entrada "∣" ganha a mesma condição de contexto da regra do "|" (dentro de P( · ∣ · ) é "dado"; fora continua "divide"). Em conjunto por compreensão {x ∣ ...} o problema persiste e não é regra: o canonicalizador só trata "|" como cerca (registrado como item de src/ em ACHADOS 9.6). Varredura: as 593 expressões dos testes do inglês faladas em português, à procura de palavras inglesas. Fora dos em inglês dos próprios testes e das letras decoradas, nenhum vazamento em material real. As decorações (circulado, entre parênteses, com ponto, invertido) entraram no mapa de estilo do recuo controlado. cargo test: 7307 passed, 0 failed (pt: 142). conferir_vocabulario.py: 4. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0134dJm6wzqbquvZrNhPD3Ea * pt: recuo marcado # RECUO-EN e separado da tradução pendente; regressão do recuo = 0 As entradas do recuo controlado usavam t: minúsculo, a mesma marca de "traduzido mas não conferido" — 2 mil delas contra 20 pendências reais, que sumiam no meio. Cada entrada do bloco leva agora # RECUO-EN na linha da chave e o conferir_vocabulario.py ganhou a seção 5, que reporta os dois números em separado: 2091 entradas de recuo (1980 strings em inglês) contra 20 strings pendentes de conferência (fraktur x10, caligráfico x10). Verificação de regressão: as 593 expressões dos testes do en faladas em pt sem e com o bloco. 526 iguais; 67 mudaram, todas com caractere cru antes. Nenhuma expressão 100% português mudou de fala. cargo test: 7307 passed, 0 failed (pt: 142). conferir_vocabulario.py: 4. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0134dJm6wzqbquvZrNhPD3Ea * Delete auditar_pt.sh * Delete Rules/Languages/pt/ACHADOS.md * Delete Rules/Languages/pt/SESSAO_ESCUTA.md * Delete Rules/Languages/pt/TERMINOLOGIA_PT_BR.md * Terminologia: maiúscula, romanos por valor, expoente zero cardinal, testes * Restaura arquivos apagados por engano * Delete venv directory * Delete PythonScripts/venv directory * Delete PythonScripts/gerar_recuo_en.py * Delete PythonScripts/gerar_pacote_escuta.py * Delete PythonScripts/conferir_vocabulario.py * Remove translation correction comments from YAML Removed comments regarding translation corrections and pluralization issues. * Clean up comments in ClearSpeak_Rules.yaml Removed comments regarding corrections in Portuguese grammar and terminology for mathematical expressions. * Clean up comments in SimpleSpeak_Rules.yaml Removed comments regarding corrections related to gendered ordinal numbers and unnecessary English suffixes. * Clean up translation notes in definitions.yaml Removed translation notes and comments from definitions.yaml. * Fix tag for overview-default in overview.yaml Corrected the tag for 'overview-default' to include 'fraction' for better intent matching. * Clean up comments in escuta.rs Removed comments and documentation from escuta.rs. * Update expressions in escuta_expressoes.tsv * Clean up comments in intent.rs Removed cautionary comments regarding the Spanish equivalent tests and their historical inaccuracies. * Remove venv from version control * Restringe o PR a Rules/Languages/pt e tests/Languages/pt Reverte o .gitignore à versão do upstream; arquivos locais (venv, saídas de teste, scripts auxiliares e documentos .md) ficam fora do controle de versão via .git/info/exclude. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01VJN43HMwJHeagwCporXvF3 --------- Co-authored-by: Claude Opus 5 --- Rules/Languages/pt/ClearSpeak_Rules.yaml | 801 ++++ Rules/Languages/pt/SharedRules/calculus.yaml | 61 + Rules/Languages/pt/SharedRules/default.yaml | 734 ++++ Rules/Languages/pt/SharedRules/general.yaml | 1121 ++++++ Rules/Languages/pt/SharedRules/geometry.yaml | 80 + .../pt/SharedRules/linear-algebra.yaml | 35 + Rules/Languages/pt/SimpleSpeak_Rules.yaml | 338 ++ Rules/Languages/pt/definitions.yaml | 496 +++ Rules/Languages/pt/navigate.yaml | 1773 +++++++++ Rules/Languages/pt/overview.yaml | 119 + Rules/Languages/pt/unicode-full.yaml | 3431 +++++++++++++++++ Rules/Languages/pt/unicode.yaml | 571 +++ tests/Languages/pt.rs | 17 + tests/Languages/pt/ClearSpeak/sets.rs | 398 ++ tests/Languages/pt/SimpleSpeak/functions.rs | 422 ++ tests/Languages/pt/alphabets.rs | 438 +++ tests/Languages/pt/chemistry.rs | 721 ++++ tests/Languages/pt/escuta.rs | 33 + tests/Languages/pt/escuta_expressoes.tsv | 30 + tests/Languages/pt/intent.rs | 72 + tests/Languages/pt/shared.rs | 346 ++ tests/Languages/pt/unicode_full.rs | 159 + tests/Languages/pt/units.rs | 411 ++ tests/languages.rs | 1 + 24 files changed, 12608 insertions(+) create mode 100644 Rules/Languages/pt/ClearSpeak_Rules.yaml create mode 100644 Rules/Languages/pt/SharedRules/calculus.yaml create mode 100644 Rules/Languages/pt/SharedRules/default.yaml create mode 100644 Rules/Languages/pt/SharedRules/general.yaml create mode 100644 Rules/Languages/pt/SharedRules/geometry.yaml create mode 100644 Rules/Languages/pt/SharedRules/linear-algebra.yaml create mode 100644 Rules/Languages/pt/SimpleSpeak_Rules.yaml create mode 100644 Rules/Languages/pt/definitions.yaml create mode 100644 Rules/Languages/pt/navigate.yaml create mode 100644 Rules/Languages/pt/overview.yaml create mode 100644 Rules/Languages/pt/unicode-full.yaml create mode 100644 Rules/Languages/pt/unicode.yaml create mode 100644 tests/Languages/pt.rs create mode 100644 tests/Languages/pt/ClearSpeak/sets.rs create mode 100644 tests/Languages/pt/SimpleSpeak/functions.rs create mode 100644 tests/Languages/pt/alphabets.rs create mode 100644 tests/Languages/pt/chemistry.rs create mode 100644 tests/Languages/pt/escuta.rs create mode 100644 tests/Languages/pt/escuta_expressoes.tsv create mode 100644 tests/Languages/pt/intent.rs create mode 100644 tests/Languages/pt/shared.rs create mode 100644 tests/Languages/pt/unicode_full.rs create mode 100644 tests/Languages/pt/units.rs diff --git a/Rules/Languages/pt/ClearSpeak_Rules.yaml b/Rules/Languages/pt/ClearSpeak_Rules.yaml new file mode 100644 index 000000000..634aaf0ee --- /dev/null +++ b/Rules/Languages/pt/ClearSpeak_Rules.yaml @@ -0,0 +1,801 @@ +- 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: "menos" + - x: "translate(text(), '-_', '')" + +- name: default + tag: square-root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # "a raiz" (feminino) + - T: "raiz quadrada" + # CORREÇÃO de ordem: o adjetivo vem depois do substantivo em português + # "a raiz quadrada negativa/positiva de x", não "a positiva raiz quadrada". + - test: + if: $ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd' + then: + - bookmark: "*[1]/@id" + - test: + if: parent::*[self::m:minus and count(*)=1] + then: [T: "negativa"] + else: [T: "positiva"] + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + else: [pause: short] + - x: "*[1]" + - test: + - if: "$ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd'" + then: + - pause: short + - T: "fim da raiz" + - pause: medium + - else_if: "IsNode(*[1], 'simple')" + then: [pause: short] + else: [pause: long] + +- name: default + # audit-ignore: divergência deliberada do en — adjetivo positiva/negativa pós-posto (ordem do português) + tag: root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] + - test: + if: "*[2][self::m:mn]" + then_test: + - if: "*[2][.='2']" + then: [T: "raiz quadrada"] + - else_if: "*[2][.='3']" + then: [T: "raiz cúbica"] + - else_if: "*[2][not(contains(., '.'))]" + then: [T: "raiz de índice", x: "*[2]"] + else: + - T: "raiz de índice" + - x: "*[2]" + # adjetivo depois do substantivo: "a raiz cúbica negativa de x" + - 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: "negativa"] + else: [T: "positiva"] + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - x: "*[1]" + - test: + if: $ClearSpeak_Roots = 'RootEnd' or $ClearSpeak_Roots = 'PosNegSqRootEnd' + then: + - pause: short + - T: "fim da raiz" + - 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: "menos"] + else: [T: "positivo"] + - 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: "por" # "cinco metros por segundo" + - 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(., '.')) and ($ClearSpeak_Fractions='Ordinal' or text()<20)] and" + - "*[2][self::m:mn][not(contains(., '.')) and ($ClearSpeak_Fractions='Ordinal' or (2<= text() and text()<=10))]" + replace: [x: ToCommonFraction(.)] + +- name: common-fraction-mixed-number + tag: fraction + match: + - "preceding-sibling::*[1][self::m:mo][.='⁤'] and" # preceding element is invisible plus + - "($ClearSpeak_Fractions='Auto' or $ClearSpeak_Fractions='Ordinal' or $ClearSpeak_Fractions='EndFrac') and" + - "*[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))]" + replace: [x: ToCommonFraction(.)] + +- 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: "a"] + - T: "fração" + - x: "*[1]" + # léxico = fração simples é "a sobre b", não "a partido por b" + - T: "sobre" + - x: "*[2]" + - test: + + 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: "fim da fração" + - 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: "sobre" + - x: "*[2]" + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='OverEndFrac'" + then: + - pause: short + - T: "fim da fração" + - pause: short + +- name: default + tag: fraction + match: "." + replace: + - OT: "a" + - T: "fração com numerador" + - test: + if: not(IsNode(*[1], 'simple')) + then: [pause: medium] + - x: "*[1]" + - pause: medium + - T: "e denominador" + - x: "*[2]" + - pause: long + - test: + if: "$ClearSpeak_Fractions='EndFrac' or $ClearSpeak_Fractions='GeneralEndFrac'" + then: + - pause: short + - T: "fim da fração" + - 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: "inverso"] + else_test: + if: $ClearSpeak_Trig = 'ArcTrig' + then: [bookmark: "*[2]/@id", T: "arco", x: "*[1]"] + else: [bookmark: "*[2]/@id", T: "inversa de", x: "*[1]"] # default/Auto + +- name: function-squared-or-cubed + # audit-ignore: divergência deliberada do en — ao quadrado/ao cubo com par verboso padronizado + 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_test: + if: "$Verbosity='Verbose'" + then: [T: "elevado ao quadrado"] + else: [T: "ao quadrado"] + else: [T: "ao cubo"] +- name: function-power + # audit-ignore: divergência deliberada do en — forma cardinal no lugar de ToOrdinal (sem ordinais femininos no motor) + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] + - bookmark: "*[2]/@id" + - T: "potência" + - x: "*[2]" + - T: "de" + - 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: "elevado ao expoente" + - pause: short + - x: "*[2]" + - pause: short + - T: "fim do expoente" + +- name: AfterPower-default + tag: power + match: "$ClearSpeak_Exponents = 'AfterPower'" + replace: + - x: "*[1]" + - T: "elevado à potência" + - 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: "ao quadrado" + +- name: cubed + tag: power + match: "*[2][self::m:mn][.='3'] and $ClearSpeak_Exponents = 'Auto'" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - T: "ao cubo" + +- name: simple-integer + # audit-ignore: divergência deliberada do en — forma cardinal; preferência Ordinal degrada documentadamente + tag: power + match: "*[2][self::m:mn][not(contains(., '.'))]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +- name: simple-negative-integer + # audit-ignore: divergência deliberada do en — forma cardinal + tag: power + match: + - "*[2][self::m:minus and count(*)=1 and" + - " *[1][self::m:mn][not(contains(., '.'))]" + - " ]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +- name: simple-var + # audit-ignore: divergência deliberada do en — sem o sufixo fonético inglês -th + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + # CORREÇÃO: removido o bloco "pronounce" com o sufixo inglês "-th" (IPA θ), + # que produzia som estrangeiro. "x elevado a n" já está completo. + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +# 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: "elevado à potência" + - x: "*[2]" + +- # - [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: "elevado à potência" + - x: "*[2]" + +- # [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: "elevado à potência" + - x: "*[2]" + +- # -[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: "elevado à potência" + - x: "*[2]" + +- 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: "elevado ao expoente" + - pause: short + - x: "*[2]" + - pause: short + - T: "fim do expoente" + +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + - T: "elevado à potência" + - x: "*[2]" + +# +# Some rules on mrows +# +- # the inference rules lump absolute value and cardinality together, so those rules are implemented here + name: ClearSpeak-absolute-value + # audit-ignore: divergência deliberada do en — três variáveis por causa do gênero (a cardinalidade / o valor absoluto) + tag: absolute-value + match: "." + variables: + - WordToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'cardinalidade', 'valor absoluto')" + - ArticleToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'a', 'o')" + - EndToSay: "IfThenElse($ClearSpeak_AbsoluteValue = 'Cardinality', 'fim da cardinalidade', 'fim do valor absoluto')" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [x: "$ArticleToSay"] + - x: "$WordToSay" + - T: "de" + - x: "*[1]" + - test: + if: "$ClearSpeak_AbsoluteValue = 'AbsEnd'" + then: + - pause: short + - x: "$EndToSay" + - pause: short + +- name: set + # audit-ignore: divergência deliberada do en — conjunto de todos os x tal que (uso brasileiro) + tag: set + match: "." + replace: + - test: + - if: "count(*)=0" + then: [T: "o conjunto vazio"] + - else_if: "count(*)=2" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "o"] + - T: "conjunto vazio" + - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "o"] + # "conjunto de todos os x tal que" o inglês é + # "set of all"; a preferência woAll suprime só o "todos os". + - T: "conjunto de" + - test: + if: $ClearSpeak_Sets != 'woAll' + then: [T: "todos os"] + - x: "*[1]/*[1]" + - T: "tal que" + - x: "*[1]/*[3]" + else: + - test: + if: $ClearSpeak_Sets != 'SilentBracket' + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "o"] + - T: "conjunto" + - 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: "o intervalo de" + - x: "*[1]" + - T: "a" + - x: "*[2]" + - pause: short + - test: + if: "not($is_intervals_start_infinity)" + then: + - test: + if: "starts-with(name(.), 'open')" + # CORREÇÃO: "no" é espanhol; em português, "não" + then: [T: "não"] + - T: "incluindo" + - 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"] + - else_if: "name(.)='closed-interval'" + then: [T: "e"] + else: [T: "mas"] + # 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ão"] + - T: "incluindo" + - 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: "escolhe" + - x: "*[2]/*[1]/*" + +- name: ClearSpeak-default + tag: [mtr, mlabeledtr] + match: "parent::m:matrix or parent::m:determinant" + replace: + - pause: medium + - T: "linha" + - x: "count(preceding-sibling::*)+1" + - test: + if: .[self::m:mlabeledtr] + then: + - T: "com rótulo" + - x: "*[1]/*" + - pause: short + - pause: medium + - test: + if: .[self::m:mlabeledtr] + then: [x: "*[position()>1]"] + else: [x: "*"] + +- name: matrix-default + tag: mtd + match: "parent::*[parent::m:matrix or parent::m:determinant]" + 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: "coluna" + - x: "count(preceding-sibling::*)+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] + +- # 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: "o"] + - test: + - if: ".='log'" + then: [T: "log"] + - else_if: "$ClearSpeak_Log = 'LnAsNaturalLog'" + then: [T: "logaritmo natural"] # phrase(the 'natural log' of x) + else: [spell: "'ln'"] + +- name: ClearSpeak-multi-line + # audit-ignore: divergência deliberada do en — plural por cadeias singular/plural, não por concatenação de s + tag: [piecewise, system-of-equations, lines] # these are ignored in favor of the ClearSpeak prefs + match: "." + variables: [IsColumnSilent: true()] + replace: + - x: "count(*)" + - test: + - if: $ClearSpeak_MultiLineOverview = 'Auto' + then: + - test: + if: "count(*) > 1" + then: + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and self::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [T: "casos"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" + then: [T: "linhas"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [T: "restrições"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [T: "equações"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [T: "linhas"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [T: "passos"] + # else 'None' — não diz nada + else: + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and self::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [T: "caso"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" + then: [T: "linha"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [T: "restrição"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [T: "equação"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [T: "linha"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [T: "passo"] + # else 'None' — não diz nada + - pause: short + - x: "*" + +- name: ClearSpeak-default-multiline + # audit-ignore: divergência deliberada do en — rótulos com plural correto + tag: [mtr, mlabeledtr] + match: "parent::m:piecewise or parent::m:system-of-equations or parent::m:lines" + replace: + - test: + - if: "($ClearSpeak_MultiLineLabel = 'Auto' and parent::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" + then: [T: "caso"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Auto' or $ClearSpeak_MultiLineLabel = 'Line'" + then: [T: "linha"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" + then: [T: "restrição"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" + then: [T: "equação"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" + then: [T: "linha"] + - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" + then: [T: "passo"] + # else 'None' — não diz nada + - test: + if: "$ClearSpeak_MultiLineLabel != 'None'" + then: + - x: "count(preceding-sibling::*)+1" + - test: + if: .[self::m:mlabeledtr] + then: + - T: "com rótulo" + - x: "*[1]/*" + - pause: medium + - test: + if: .[self::m:mlabeledtr] + then: [x: "*[position()>1]"] + else: [x: "*"] + - test: + if: "$ClearSpeak_MultiLineLabel != 'None'" + then: [pause: long] + +- 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: ""] + # léxico = "vezes" é a forma padrão; "multiplicado por" fica + # para o modo verboso + else_test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] + else: [T: "vezes"] + +- 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 + # audit-ignore: divergência deliberada do en — vezes/multiplicado por conforme verbosidade (léxico ACESSÍLIA) + 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 (" + - " $ClearSpeak_ImpliedTimes = 'MoreImpliedTimes'" + - " or " + - " following-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|') or " + - " self::m:matrix or self::m:determinant or self::m:binomial or" # followed by parens + - " ( (self::m:msup or self::m:msub or self::m:msubsup or self::m:power) and " # followed by msup, etc. + - " *[1][self::m:mrow[IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')] or " + - " self::m:matrix or self::m:determinant]" # base has parens + - " )" + - " ]" + # 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: + - test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] + else: [T: "vezes"] + +- name: no-say-parens + # audit-ignore: divergência deliberada do en — idem ClearSpeak-times + 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') )" + # 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/calculus.yaml" +- include: "SharedRules/general.yaml" +- include: "SharedRules/default.yaml" diff --git a/Rules/Languages/pt/SharedRules/calculus.yaml b/Rules/Languages/pt/SharedRules/calculus.yaml new file mode 100644 index 000000000..03b99253a --- /dev/null +++ b/Rules/Languages/pt/SharedRules/calculus.yaml @@ -0,0 +1,61 @@ +--- + +- name: divergence + tag: divergence + match: "count(*) = 1" + replace: + # CORREÇÃO: a polaridade estava invertida — o modo padrão (Medium) ouvia a + # abreviação "div"; o nome completo só saía no Verbose. No inglês, só o + # Terse abrevia. E o "de" era incondicional, contrariando TerseFunctionNames + # (divergence/curl/gradient não dizem "de" no modo conciso). + - test: + if: "$Verbosity='Terse'" + then: [T: "div"] + else: [T: "divergente de"] + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + +- name: curl + tag: curl + match: "count(*) = 1" + replace: + - T: "rotacional" # phrase(the 'curl of' a field) + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + +- name: gradient + tag: gradient + match: "count(*) = 1" + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "gradiente de"] # phrase('divergence' from the mean) + else: [T: "nabla"] # phrase('divergence' from the mean) + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" + + +- name: laplacian + tag: laplacian + match: "count(*) <= 1" # can be on ∇^2 or on enclosing mrow + replace: + - T: "laplaciano" + - test: + if: "count(*) = 1" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [pause: short] + - x: "*[1]" diff --git a/Rules/Languages/pt/SharedRules/default.yaml b/Rules/Languages/pt/SharedRules/default.yaml new file mode 100644 index 000000000..ff8ed2cf8 --- /dev/null +++ b/Rules/Languages/pt/SharedRules/default.yaml @@ -0,0 +1,734 @@ +--- +#default rules shared among several speech rules +- name: default + tag: math + match: "." + replace: + - with: + variables: + - ClearSpeak_Fractions: "IfThenElse($Verbosity='Verbose' and $ClearSpeak_Fractions='Auto', 'EndFrac', $ClearSpeak_Fractions)" + - ClearSpeak_AbsoluteValue: "IfThenElse($Verbosity='Verbose' and $ClearSpeak_AbsoluteValue='Auto', 'AbsEnd', $ClearSpeak_AbsoluteValue)" + - ClearSpeak_Roots: "IfThenElse($Verbosity='Verbose' and $ClearSpeak_Roots='Auto', 'RootEnd', $ClearSpeak_Roots)" + - ClearSpeak_Matrix: "IfThenElse($Verbosity='Verbose' and $ClearSpeak_Matrix='Auto', 'EndMatrix', $ClearSpeak_Matrix)" + # should be set at mtable level, but unknown intents make that impossible to know + - IsColumnSilent: false() + replace: + - test: + if: "$MathRate = 100" + then: [x: "*"] + else: + - rate: + value: "$MathRate" + replace: [x: "*"] + +- name: empty-mrow + tag: mrow + match: "not(*)" + replace: + - t: " " # say nothing -- placeholder + +- name: default + tag: mrow + match: "." + replace: + - insert: + nodes: "*" + replace: [pause: auto] + +- name: default + tag: mn + match: "." + replace: + - bookmark: "@id" + # ACRESCENTADO (en): numerais romanos são soletrados ("XIV" -> letra a + # letra), não lidos como palavra. + - test: + - if: "@data-roman-numeral" + then: [spell: "text()", pause: "short"] + else: [x: "translate(., $BlockSeparators, '')"] # remove digit block separators + +- name: default + tag: [mo, mtext] + match: "." + replace: + - bookmark: "@id" + - x: "text()" + +- name: default + tag: mi + match: "." + replace: + - bookmark: "@id" + - test: + - if: "string-length(.) = 1 and text() != '_'" # need unicode.tdl to kick in for single letter tokens + then: [x: "text()"] + # ACRESCENTADO (en): NavMode=Character precisa disto + - else_if: "@data-chem-element or @data-roman-numeral" + then: [spell: "text()", pause: "short"] + else: [x: "translate(., '-_\u00A0', ' ')"] # from intent literals + +- name: default + tag: ms + match: "." + replace: + - T: "a cadeia" + - pause: short + - x: "text()" + +- name: default + tag: mstyle + match: "." + replace: [x: "*"] + + +- name: literal-simple + # don't include nested fractions. E.g, fraction a plus b over c + 1 end fraction" is ambiguous + # by simplistic SimpleSpeak's rules "b over c" is a fraction, but if we say nested fractions + # are never simple, then any 'over' applies only to enclosing "fraction...end fraction" pair. + tag: mfrac + match: + - "(IsNode(*[1],'leaf') and IsNode(*[2],'leaf')) and" + - "not(ancestor::*[name() != 'mrow'][1]/self::m:fraction)" # FIX: can't test for mrow -- what should be used??? + replace: + - x: "*[1]" + - T: "sobre" + - x: "*[2]" + - pause: short + +- name: literal-default + tag: mfrac + match: "." + replace: + - T: "começar" + - pause: short + - x: "*[1]" + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [pause: short] + - T: "sobre" + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [pause: short] + - x: "*[2]" + - pause: short + # ALINHADO ao en: o marcador de fim é dito apenas para cegueira + - test: + if: "$Impairment = 'Blindness'" + then: [T: "fim da fração"] + - pause: medium + +# ACRESCENTADO: leitura literal de msqrt/mroot sem semântica inferida. +# O inglês evita dizer "quadrada" porque a forma literal não garante índice. +- name: literal-default + tag: msqrt + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "raiz" + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - x: "*[1]" + - pause: short + - test: + if: "not(IsNode(*[1],'leaf')) or $Impairment = 'Blindness'" + then: [T: "fim da raiz", pause: medium] + +- name: literal-default + # audit-ignore: divergência deliberada do en — ordem portuguesa: raiz de índice N de X — o teste final acompanha o último elemento falado + tag: mroot + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "raiz de índice" + - x: "*[2]" + - pause: short + - T: "de" + - x: "*[1]" + - pause: short + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [T: "fim da raiz"] + +- name: simple-sub + tag: indexed-by + # invisible comma -- want "x 1 when subscript is an integer" + match: "count(*)=2 and $Verbosity='Terse' and *[2][self::m:mn and translate(., '.,', '')=.]" + replace: + - x: "*[1]" + - x: "*[2]" + - pause: short + +- name: no-end-sub + tag: indexed-by + # invisible comma -- want "x 1 when subscript is an integer" + match: "count(*)=2 and (IsNode(*[2], 'leaf') or *[2][self::m:mrow][*[2][.='⁣']])" + replace: + - x: "*[1]" + - test: + if: "$Verbosity!='Terse' or not(*[2][self::m:mn])" # just say "x 1" for terse vs "x sub 1" + then: [T: "subscrito"] + - x: "*[2]" + +- name: literal + tag: msub + match: "." + replace: + - x: "*[1]" + - T: "subscrito" + - x: "*[2]" + +- name: literal + tag: [msup, msubsup] + match: "." + replace: + - x: "*[1]" + - test: + if: "name(.)='msubsup'" + then: + - T: "subscrito" + - x: "*[2]" + - test: + if: "*[last()][translate(., '′″‴⁗†‡°*', '')='']" + then: [x: "*[last()]"] + else_test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" # FIX: is this test necessary? + then: + - T: "sobrescrito" + - x: "*[last()]" + - test: + if: "not(IsNode(*[last()], 'simple'))" + then: [T: "fim do sobrescrito"] + else: + - T: "elevado à" + - x: "*[last()]" + - T: "potência" + +- name: default + tag: munder + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "modificado"] + - x: "*[1]" + - T: "com" + - x: "*[2]" + - T: abaixo +# NOTA: aqui existia uma regra "dot-over" que eu havia acrescentado supondo +# ser uma porta do inglês. Ela NÃO existe em en/ — o inglês trata a notação +# de Newton pela regra "diacriticals" abaixo, que apenas fala o caractere. +# A regra inventada encobria a diacriticals e produzia "x com ponto acima" +# no lugar de "x ponto". Removida. + +- name: diacriticals + tag: [mover, modified-variable] + match: "*[1][self::m:mi] and *[2][translate(., '\u0306\u030c.\u00A8\u02D9\u20DB\u20DC`^ˇ~→¯_', '')='']" + replace: + - x: "*[1]" + - x: "*[2]" + - pause: short + +- name: default + tag: mover + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "modificado"] + - x: "*[1]" + - T: "com" + - x: "*[2]" + - T: "acima de" + +- name: default + tag: munderover + match: "." + replace: + - test: + if: "not(IsNode(*[1], 'leaf'))" + then: [T: "modificado"] + - x: "*[1]" + - T: "com" + - x: "*[2]" + - T: "e abaixo" + - x: "*[3]" + - T: "acima de" + +- name: default + # Here we support up to 2 prescripts and up to 4 postscripts -- that should cover all reasonable cases + # If there are more, we just dump them out without regard to sup/super :-( + # FIX: this could use more special cases + # There is (currently) no way in MathCAT to deal with n-ary arguments other than "all" ('*') or an individual entry ('*[1]'). + tag: mmultiscripts + match: "." + 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))]" + replace: + - x: "*[1]" + - test: + if: "$Prescripts" # more common case + then: + - with: + variables: + - PreSubscript: "IfThenElse($Verbosity='Verbose', 'pré-subscrito', 'pré-sub')" + - PreSuperscript: "IfThenElse($Verbosity='Verbose', 'pré-sobrescrito', 'pré-super')" + replace: + - test: # only bother announcing if there is more than one prescript + if: "count($Prescripts) > 2" + then: + - T: "com" + - x: "count($Prescripts) div 2" + - T: "pré-escritos" + - pause: short + - test: + if: "not($Prescripts[1][self::m:none])" + then: + - x: "$PreSubscript" + - x: "$Prescripts[1]" + - test: + if: "not($Prescripts[1][self::m:none] or $Prescripts[2][self::m:none])" + then: [T: "e"] + - test: + if: "not($Prescripts[2][self::m:none])" + then: + - x: "$PreSuperscript" + - x: "$Prescripts[2]" + - pause: short + - test: + if: "count($Prescripts) > 2" # more common case + 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: "e"] + - test: + if: "not($Prescripts[4][self::m:none])" + then: + - x: "$PreSuperscript" + - x: "$Prescripts[4]" + - test: + if: "count($Prescripts) > 4" # give up and just dump them out so at least the content is there + then: + - T: "e pré-escritos alternados" + - x: "$Prescripts[position() > 4]" + - T: "fim dos pré-escritos" + - test: + if: "$Postscripts" + then: + - with: + variables: + - PostSubscript: "IfThenElse($Verbosity='Verbose', 'subscrito', 'sub')" + - PostSuperscript: "IfThenElse($Verbosity='Verbose', 'sobrescrito', 'super')" + replace: + - test: # only bother announcing if there is more than one postscript + if: "count($Postscripts) > 2" + then: + - test: + if: "$Prescripts" + then: [T: "e"] + - T: "com" + - x: "count($Postscripts) div 2" + - T: "pós-escritos" + - pause: short + - test: + if: "not($Postscripts[1][self::m:none])" + then: + - x: "$PostSubscript" + - x: "$Postscripts[1]" + - test: + if: "not($Postscripts[1][self::m:none] or $Postscripts[2][self::m:none])" + then: [T: "e"] + - test: + if: "not($Postscripts[2][self::m:none])" + 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: "e"] + - 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: "e"] + - 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: "e"] + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - x: "$PostSuperscript" + - x: "$Postscripts[8]" + - test: + if: "count($Postscripts) > 8" # give up and just dump them out so at least the content is there + then: + - T: "e índices alternados" + - x: "$Postscripts[position() > 8]" + - T: "fim dos índices" + + +- name: default + tag: [mtable, array] + variables: + - IsColumnSilent: "false()" + - NumColumns: "count(*[1]/*) - IfThenElse(*/self::m:mlabeledtr, 1, 0)" + match: "." + replace: + - T: "tabela com" + - x: count(*) + - test: + if: count(*)=1 + then: [T: "linha"] + else: [T: "linhas"] + - T: e + - x: "$NumColumns" + - test: + if: "$NumColumns" + then: [T: "coluna"] + else: [T: "colunas"] + - pause: long + - x: "*" + +- name: default + # ATUALIZADO para a geração atual do en: anuncia "linha N" e, no + # mlabeledtr, o rótulo — a versão herdada do es só falava os filhos, + # deixando tabelas genéricas sem anúncio de linha. + tag: [mtr, mlabeledtr] + match: "." + replace: + - pause: medium + - T: "linha" + - x: "count(preceding-sibling::*)+1" + - test: + if: "self::m:mlabeledtr" + then: + - T: "com rótulo" + - x: "*[1]/*" + - pause: short + - pause: medium + - test: + if: "self::m:mlabeledtr" + then: [x: "*[position()>1]"] + else: [x: "*"] + +- name: default + tag: mtd + match: "." + replace: + - T: "coluna" + - x: "count(preceding-sibling::*)+IfThenElse(parent::m:mlabeledtr, 0, 1)" + - pause: medium + - x: "*" # speak the entry + - 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: "célula vazia" + +- 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: "célula", pause: short] + - test: + if: ".[contains(@notation,'roundedbox')]" + then: [T: "célula redonda", pause: short] + - test: + if: ".[contains(@notation,'circle')]" + then: [T: "círculo", pause: short] + - 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: linha acima + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]" + then: [T: "esquerda", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]" + then: [T: "direita", pause: short] + - test: + if: ".[contains(@notation,'top')]" + then: [T: "superior", pause: short] + - test: + if: ".[contains(@notation,'bottom')]" + then: [T: "inferior", pause: short] + - 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: "diagonal superior", pause: short] + - test: + if: ".[contains(@notation,'downdiagonalstrike')]" + then: [T: "diagonal inferior", pause: short] + - test: + if: ".[contains(@notation,'verticalstrike')]" + then: [T: "vertical", pause: short] + - test: + if: ".[contains(@notation,'horizontalstrike')]" + then: [T: "horizontal", pause: short] + - T: riscado + - pause: short + - test: + if: ".[contains(@notation,'uparrow')]" + then: [T: "seta para cima", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]" + then: [T: "seta para baixo", pause: short] + - test: + if: ".[contains(@notation,'leftarrow')]" + then: [T: "seta para a esquerda", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')]" + then: [T: "seta para a direita", pause: short] + - test: + if: ".[contains(@notation,'northeastarrow')]" + then: [T: "seta para nordeste", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')]" + then: [T: "seta para sudeste", pause: short] + - test: + if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')]" + then: [T: "seta para sudoeste", pause: short] + - test: + if: ".[contains(@notation,'northwestarrow')]" + then: [T: "seta para noroeste", pause: short] + - test: + if: ".[contains(@notation,'updownarrow')]" + then: [T: "seta vertical de duas pontas", pause: short] + - test: + if: ".[contains(@notation,'leftrightarrow')]" + then: [T: "seta horizontal de duas pontas", pause: short] + - test: + if: ".[contains(@notation,'northeastsouthwestarrow')]" + then: [T: "seta diagonal superior de duas pontas", pause: short] + - test: + if: ".[contains(@notation,'northwestsoutheastarrow')]" + then: [T: "seta diagonal inferior de duas pontas", pause: short] + - test: + if: ".[contains(@notation,'actuarial')]" + then: [T: "símbolo atuarial", pause: short] + - test: + if: ".[contains(@notation,'madrub')]" + then: [T: "símbolo fatorial arábico", pause: short] + - test: + if: ".[contains(@notation,'phasorangle')]" + then: [T: "ângulo fasorial", pause: short] + - test: + if: ".[contains(@notation,'longdiv') or not(@notation) or normalize-space(@notation) ='']" # default + then: [T: "símbolo de divisão longa", pause: short] + - test: + if: ".[contains(@notation,'radical')]" + then: [T: "raiz quadrada", pause: short] + - T: em torno de + - test: + if: "*[self::m:mtext and .=' ']" + then: [T: "espaço"] # otherwise there is complete silence + else: [x: "*"] + - test: + if: "$Impairment = 'Blindness' and ( $SpeechStyle != 'SimpleSpeak' or not(IsNode(*[1], 'leaf')) )" + then: [T: fim do destaque] + - 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: . + replace: + - x: "*[1]" + - T: "de" + - pause: auto + - x: "*[position() > 1]" + +# Here are the intent hints that need to be handled: 'prefix' | 'infix' | 'postfix' | 'function' | 'silent' +- name: produto-vetorial-ou-escalar-sem-filhos + # O motor infere ⃗a × ⃗b e ⃗a ⋅ ⃗b como um elemento / + # SEM filhos (o próprio operador vira o elemento, data-from-mathml='mo'). + # Nenhuma regra de intent casa com count(*)=0, e a regra genérica falava o + # NOME do intent: "cross product", em inglês. Aqui passa pelo IntentMappings + # do pt. Ver ACHADOS 9.4. + tag: [cross-product, dot-product] + match: "count(*)=0" + replace: + - x: "SpeakIntentName(name(.), $Verbosity, 'infix')" + +- name: silent-intent + # uncaught intent -- the args have been inserted in the order of speech + tag: "*" + match: "count(*)>0 and (contains(@data-intent-property, ':silent:') or translate(name(.), '-_', '')='')" + replace: + - x: "*" + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + +# ACRESCENTADO: potência cujo expoente carrega um índice (x^(y_z)). +- name: power-indexed-by + tag: power-indexed-by + match: "." + replace: + - x: "*[1]" + - T: "sub" + - x: "*[2]" + - pause: short + +# ACRESCENTADO: intents com a propriedade :nofix: os argumentos já +# vêm na ordem de fala; basta falar o nome do intent. +- name: nofix-intent + tag: "*" + match: "contains(@data-intent-property, ':nofix:') " + replace: + - x: "SpeakIntentName(name(.), $Verbosity, 'nofix')" + +- name: prefix-intent + # uncaught intent -- the args have been inserted in the order of speech + tag: "*" + match: "count(*)>0 and contains(@data-intent-property, ':prefix:')" + replace: + - x: "SpeakIntentName(name(.), $Verbosity, 'prefix')" + - x: "*" + - test: + if: "not( IsBracketed(., '', '') or IsNode(*[last()], 'simple') )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'prefix', 'end')"] + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + +- name: postfix-intent + # uncaught intent -- the args have been inserted in the order of speech + tag: "*" + match: "count(*)>0 and contains(@data-intent-property, ':postfix:')" + replace: + - test: + if: "$Impairment = 'Blindness' and not( IsBracketed(., '', '') or IsNode(*[1], 'simple') )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'postfix', 'start')"] + - x: "*" + - x: "SpeakIntentName(name(.), $Verbosity, 'postfix')" + +- name: infix-intent + # uncaught intent -- the args have been inserted in the order of speech + tag: "*" + match: "count(*)>0 and contains(@data-intent-property, ':infix:')" + replace: + - test: + if: "$Impairment = 'Blindness' and not( IsBracketed(., '', '') or IsNode(*[1], 'simple') )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'infix', 'start')"] + - test: + if: "count(*) = 1" # in cases such as continued-row, plus/minus might have just one child + then: + - x: "SpeakIntentName(name(.), $Verbosity, 'infix')" + - pause: auto + - x: "*[1]" + else: + - insert: + nodes: "*" + replace: [x: "SpeakIntentName(name(.), $Verbosity, 'infix')", pause: auto] + - test: + if: "$Impairment = 'Blindness' and not( IsBracketed(., '', '') or IsNode(*[last()], 'simple') )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'infix', 'end')"] + - test: + if: "IsNode(., '2D')" # add (probably) a slightly longer pause if this came from a 2D node + then: [pause: short] + else: [pause: auto] + +- name: function-intent + # uncaught intent -- speak as foo of arg1 comma arg2 .... The MathML spec requires arguments to functions + tag: "*" + match: "count(*)>0" + replace: + - x: "SpeakIntentName(name(.), $Verbosity, 'function')" + - test: + if: "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] # phrase(sine 'of' 5) + - insert: + nodes: "*" + replace: + - test: + if: "not(contains(@data-intent-property, ':literal:'))" + then: [x: "','"] + - pause: auto + - test: + if: "$Impairment = 'Blindness' and not(*[last()][IsBracketed(., '', '') or IsNode(., 'simple')] )" + then: [x: "GetBracketingIntentName(name(.), $Verbosity, 'function', 'end')"] + - test: + if: "IsNode(., '2D')" + then: [pause: short] + else: [pause: auto] + + +- name: default-text + # unknown leaf -- just speak the text -- could be a literal intent + tag: "*" + match: "." + replace: + - x: "translate(name(), '-_', ' ')" diff --git a/Rules/Languages/pt/SharedRules/general.yaml b/Rules/Languages/pt/SharedRules/general.yaml new file mode 100644 index 000000000..5b5a69634 --- /dev/null +++ b/Rules/Languages/pt/SharedRules/general.yaml @@ -0,0 +1,1121 @@ +--- + +# 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: "a" + - bookmark: "*[2]/@id" + - test: + - if: "*[2][.='+']" + then: [T: "positivo"] + else: [T: "negativo"] + - bookmark: "*[1]/@id" + - test: + - if: "*[1][.='ℂ']" + then: [T: números complexos] + - else_if: "*[1][.='ℕ']" + then: [T: números naturais] + - else_if: "*[1][.='ℚ']" + then: [T: números racionais] + - else_if: "*[1][.='ℝ']" + then: [T: números reais] + - else_if: "*[1][.='ℤ']" + then: [T: inteiros] + 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"] + - else_if: "*[1][.='ℕ']" + then: [T: "N"] + - else_if: "*[1][.='ℚ']" + then: [T: "Q"] + - else_if: "*[1][.='ℝ']" + then: [T: "R"] + - else_if: "*[1][.='ℤ']" + then: [T: "Z"] + 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: números complexos] + - else_if: ".='ℕ'" + then: [T: números naturais] + - else_if: ".='ℚ'" + then: [T: números racionais] + - else_if: ".='ℝ'" + then: [T: números reais] + - else_if: ".='ℤ'" + then: [T: inteiros] + else: [x: "text()"] # shouldn't happen + +- name: real-part + tag: real-part + match: "." + replace: + - bookmark: "@id" + - T: a parte real +- name: imaginary-part + tag: imaginary-part + match: "." + replace: + - bookmark: "@id" + - T: a parte imaginária# rules on scripted vertical bars ('evaluated at') +- name: evaluated-at-2 + tag: evaluate + match: "count(*)=2" + replace: + - x: "*[1]" + - pause: auto + - T: avaliado em + - pause: auto + - x: "*[2]" + +- name: evaluated-at-3 + tag: evaluate + match: "count(*)=3" + replace: + - x: "*[1]" + - pause: auto + - T: avaliado em + - pause: auto + - x: "*[3]" + - T: "avaliado na mesma expressão" + - x: "*[2]" + +- name: permutation + tag: pochhammer + match: "count(*)=2" + replace: + - x: "*[2]" + - T: permutações de + - 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: "o" + - test: + - if: "self::m:open-interval" + then: [T: "intervalo aberto"] + - else_if: "self::m:closed-interval" + then: [T: "intervalo fechado"] + - else_if: "self::m:open-closed-interval" + then: [T: "intervalo aberto fechado"] + else: [T: "intervalo fechado aberto"] + - test: + if: "$Verbosity!='Terse'" + then: + - T: "de" + - x: "*[1]" + - T: "a" + - x: "*[2]" + else: + - x: "*[1]" + - T: "vírgula" + - x: "*[2]" + +- name: default-point + tag: point + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then: + - T: "o" + - T: "ponto" + - x: "*[1]" + - T: "vírgula" + - x: "*[2]" + +- name: bigop-both + tag: large-op + match: "count(*) = 3" + replace: + - test: + if: "$Verbosity!='Terse'" + then_test: + # "a integral", "o somatório": o artigo concorda com o operador. + if: "*[1][self::m:mo][contains('∫∬∭∮∯∰∱∲∳⨋⨌⨍⨎⨏⨐⨑⨒⨓⨔⨕⨖⨗⨘⨙⨚⨛⨜', .)]" + then: [T: a] + else: [T: o] + - x: "*[1]" + - T: de + - x: "*[2]" + - T: a + - x: "*[3]" + - test: + if: "following-sibling::*" + then: [T: de] + +- name: bigop-under + tag: large-op + match: "count(*)=2" + replace: + - test: + if: "$Verbosity!='Terse'" + then_test: + # "a integral", "o somatório": o artigo concorda com o operador. + if: "*[1][self::m:mo][contains('∫∬∭∮∯∰∱∲∳⨋⨌⨍⨎⨏⨐⨑⨒⨓⨔⨕⨖⨗⨘⨙⨚⨛⨜', .)]" + then: [T: a] + else: [T: o] + - x: "*[1]" + - T: sobre + - x: "*[2]" + - test: + if: "following-sibling::*" + then: [T: de] + +- name: largeop + tag: mrow + match: "count(*)=2 and IsInDefinition(*[1], 'LargeOperators')" + replace: + - test: + if: "$Verbosity!='Terse'" + then_test: + # "a integral", "o somatório": o artigo concorda com o operador. + if: "*[1][self::m:mo][contains('∫∬∭∮∯∰∱∲∳⨋⨌⨍⨎⨏⨐⨑⨒⨓⨔⨕⨖⨗⨘⨙⨚⨛⨜', .)]" + then: [T: a] + else: [T: o] + - x: "*[1]" + - T: de + - x: "*[2]" + +- name: msubsup-skip-super + # handles single, double, etc., prime + tag: [skip-super, say-super] + match: "count(*)=3" + replace: + - x: "*[1]" + # CORREÇÃO: a distinção Verbose/conciso do inglês ("subscript"/"sub") + # tinha colapsado, os dois ramos diziam a mesma coisa. Restaurada, + # coerente com as abreviações de default.yaml ('subscrito'/'sub'). + # Também restaurada a condição $Impairment='Blindness' do match interno, + # presente no inglês e perdida na tradução. + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else: [T: "sub"] + - x: "*[2]" + - test: + if: "not(IsNode(*[2],'leaf') and $Impairment = 'Blindness')" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "fim do subscrito"] + else: [T: "fim do sub"] + - 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: "sobrescrito"] + else: [T: "super"] + - x: "*[3]" + - pause: short + +# 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" +# ACRESCENTADO (en): no modo conciso, unidade de uma letra é soletrada +# ("3 m" -> "3 m" soletrado), em vez de expandida para "metros". +- name: unit-terse + tag: unit + match: "$Verbosity = 'Terse' and string-length(.)=1" + replace: + - bookmark: "@id" + - spell: "text()" + +- 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 msup/mrow) + # But it might be in a fraction as (C) "3 m/s" (parent is mfrac/mrow) or (D) "3 m^2/s^2" (parent is msup/mfrac/mrow) + # or even (E) {3 m^2}/s (parent is msup/mrow) + # If in a fraction, only look in the numerator to find the coefficient + - 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()" + + - with: + variables: + - Word: "IfThenElse(substring($Word, string-length($Word)-2, 3) = 'ián', concat(substring($Word, 1, string-length($Word)-2), ian), $Word)" + - LastChar: "substring($Word, string-length($Word), 1)" + - PluralEnding: "IfThenElse($LastChar = 'r' or $LastChar = 'l', 'es', + IfThenElse(substring($Word, string-length($Word)-2, 3) = 'ian', 'es', 's' )) " + replace: + # 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 concatinated to the base + then: [x: "$Word"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralForms') != ''" + then: [x: "DefinitionValue($Word, 'Speech', 'PluralForms')"] + else: [x: "concat($Word, $PluralEnding)"] + else: + - x: "$Prefix" + - test: + - if: "$IsSingular" + # HACK: '\uF8FE' is used internally for the concatenation char by 'ct' -- this gets the prefix concatinated 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, $PluralEnding)"] + + + +# ACRESCENTADO: valores monetários "R$ 100" -> "100 reais". +# Depende de CurrencySymbols e dos plurais em definitions.yaml. +- name: currency + tag: mrow + match: "count(*)=3 and DefinitionValue(*[1], 'Speech', 'CurrencySymbols') != ''" + variables: + # se o valor é 1, não pluraliza + - IsSingular: "*[3][self::m:mn and .=1] and *[2]='\u2062'" + - CurrencyWord: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')" + replace: + - bookmark: "*[3]/@id" + - x: "*[3]" + - test: + - if: "$IsSingular" + then: [x: "$CurrencyWord"] + - else_if: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms') != ''" + then: [x: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms')"] + else: [x: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')", ct: "s"] + +- name: sin + tag: mi + match: ".='sin' or .='sen'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: sen] + else: [T: seno] +- name: cos + tag: mi + match: ".='cos'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: cos] + else: [T: cosseno] +- name: tan + tag: mi + match: ".='tan' or .='tg'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: tan] + else: [T: tangente] +- name: sec + tag: mi + match: ".='sec'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: sec] + else: [T: secante] +- name: csc + tag: mi + match: ".='csc'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + # CORREÇÃO: dizia "sec", idêntico à regra sec; cossecante e secante + # ficavam indistinguíveis na fala concisa. + then: [T: cossec] + else: [T: cossecante] +- name: cot + tag: mi + match: ".='cot'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: cotan] + else: [T: cotangente] + +- name: sinh + tag: mi + match: ".='sinh'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: seno hiperbólico] + else: [T: seno hiperbólico] +- name: cosh + tag: mi + match: ".='cosh'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: cosseno hiperbólico] + else: [T: cosseno hiperbólico] +- name: tanh + tag: mi + match: ".='tanh'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: tangente hiperbólica] + else: [T: tangente hiperbólica] +- name: sech + tag: mi + match: ".='sech'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: secante hiperbólica] + else: [T: secante hiperbólica] +- name: csch + tag: mi + match: ".='csch'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: cossecante hiperbólica] + else: [T: cossecante hiperbólica] +- name: coth + tag: mi + match: ".='coth'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + + then: [T: cotangente hiperbólica] + else: [T: cotangente hiperbólica] + +- name: exponential + tag: mi + match: ".='exp'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "exp"] + else: [T: "exponencial"] +- name: covariance + tag: mi + match: ".='Cov'" + replace: + - bookmark: "@id" + - test: + if: "$Verbosity='Terse'" + then: [T: "Cov"] + else: [T: "covariância"] + +- + # CORREÇÃO: faltava o 'Log' maiúsculo (valor principal), presente no inglês. + # Sem ele, "Log x" caía na regra genérica de mi e saía "Log de x", perdendo a + # distinção. A tradução de "principal value log" ainda não foi verificada por + # falante nativo -- daí o 't:' minúsculo. + name: log # handle log, principal Log, and ln (if in an mrow, 'intents' are used) + tag: mi + match: ".='log' or .='Log' or .='ln'" + replace: + - bookmark: "@id" + - test: + - if: "$Verbosity!='Terse'" + then: [T: "o"] # phrase('the' logarithm function is used in mathematics) + - test: + - if: ".= 'log'" + then: [T: "log"] # phrase(the 'log' function is used in mathematics) + - else_if: ".= 'Log'" + then: [t: "log do valor principal"] # (en: 'principal value log') + - else_if: "$Verbosity='Terse'" + then: [SPELL: "'ln'"] + else: [T: "logaritmo natural"] # phrase(the 'natural log' function is used in mathematics) + +- name: multi-line + # audit-ignore: divergência deliberada do en — plural por cadeias, não por concatenação de s + # 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: [IsColumnSilent: true()] + replace: + - x: "count(*)" + # CORREÇÃO: o plural era feito concatenando "s" (ct: "s"), o que produzia + # "equaçãos". Substituído por duas cadeias, singular e plural, escolhidas + # pela contagem — mesma correção já aplicada no ClearSpeak. + - test: + if: "count(*) > 1" + then: + - test: + - if: "self::m:piecewise" + then: [T: "casos"] + - else_if: "self::m:system-of-equations" + then: [T: "equações"] + else: [T: "linhas"] + else: + - test: + - if: "self::m:piecewise" + then: [T: "caso"] + - else_if: "self::m:system-of-equations" + then: [T: "equação"] + else: [T: "linha"] + - pause: short + - x: "*" + +- name: default-multiline + tag: [mtr, mlabeledtr] + match: "parent::m:piecewise or parent::m:system-of-equations or parent::m:lines" + replace: + - pause: medium + - test: + - if: "parent::m:piecewise" + then: [T: "caso"] + - else_if: "parent::m:system-of-equations" + then: [T: "equação"] + else: [T: "linha"] + - x: "count(preceding-sibling::*)+1" + - test: + if: .[self::m:mlabeledtr] + then: + - T: rotulada com + - x: "*[1]/*" + - 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: + - x: "*" + - test: + # short 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" + then_test: + if: "$LongPause" + then: [pause: medium] + else: [pause: short] + - else_if: "count(../following-sibling::*) > 0" + then_test: + if: "$LongPause" + then: [pause: long] + else: [pause: medium] + else: [pause: long] + +# 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 +# ACRESCENTADO: regra presente em en/ e ausente em es/ (e portanto em pt). +# Sem ela, dízimas periódicas (0,333...) não eram anunciadas como periódicas. +- name: repeating-decimal + tag: repeating-decimal + match: "." + replace: + - x: "*[1]" + - T: "com dígitos periódicos" + - spell: "*[2]" + +# NOTA: o inglês funde matrix e determinant numa regra só. Em português os +# artigos diferem ("a matriz" / "o determinante"), então a separação é +# deliberada, não é lacuna de paridade. +- name: 1x1-matrix + # audit-ignore: divergência deliberada do en — separada de 1x1-determinant: artigos de gêneros diferentes + tag: matrix + variables: [IsColumnSilent: true()] + match: "count(*)=1 and *[self::m:mtr][count(*) = 1]" + replace: + - OT: "a" + - T: "matriz 1 por 1" + - T: "com o elemento" + - x: "*[1]/*" + +- name: 1x1-determinant + # audit-ignore: divergência deliberada do en — idem + tag: determinant + variables: [IsColumnSilent: true()] + match: "count(*)=1 and *[self::m:mtr][count(*) = 1]" + replace: + - OT: "o" + - T: "determinante 1 por 1" + - T: "com o elemento" + - x: "*[1]/*" + + +- name: zero-matrix + tag: matrix + match: "not( */*/*[not(self::m:mn and .= 0)] )" + replace: + - T: "a matriz nula" + - x: count(*) + - T: "por" + - x: count(*[self::m:mtr][1]/*) + - pause: long + +- name: identity-matrix + tag: matrix + match: + - "count(*) = count(*[1]/*) and " + - "not( */*[count(preceding-sibling::*) = count(../preceding-sibling::*)]/*[not(self::m:mn and .= 1)] ) and " + - "not( */*[count(preceding-sibling::*) != count(../preceding-sibling::*)]/*[not(self::m:mn and .= 0)] )" + replace: + - T: "a matriz identidade" + - x: count(*) + - T: "por" + - x: count(*[self::m:mtr][1]/*) + - pause: long + +- name: diagonal-matrix + tag: matrix + match: + - "count(*) = count(*[1]/*) and " + - "not( */*/*[not(self::m:mn and .= 0)]" + - " [count(../preceding-sibling::*)!=count(../../preceding-sibling::*)]" + - " )" + replace: + - T: "a matriz diagonal" + - x: count(*) + - T: "por" + - x: count(*[self::m:mtr][1]/*) + - pause: long + - insert: + 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: + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "o vetor coluna"] + else: [T: "a matriz coluna"] + - x: count(*) + - T: "por 1 coluna" + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "fim" + - test: + if: $ClearSpeak_Matrix = 'EndVector' + then: [T: vetor] + else: [T: matriz] + +- name: default-column-matrix + tag: matrix + variables: [IsColumnSilent: true()] + match: "*[self::m:mtr][count(*) = 1]" + replace: + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "o vetor"] + else: [T: "a matriz"] + - x: "count(*)" + - T: "por 1 coluna" + - pause: long + - x: "*" # select the rows (mtr) + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "fim da matriz"] + +- name: 1x2-or-3-matrix + tag: matrix + variables: [IsColumnSilent: "$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: + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "o vetor"] + else: [T: "a matriz"] + - T: "1 por" + - x: count(*/*) + - T: "linha" + - pause: long + - x: "*/*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "fim" + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [T: matriz] + else: [T: vetor] + +- name: default-row-matrix + tag: matrix + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] + match: "count(*)=1" # one row + replace: + - test: + if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" + then: [T: "o vetor"] + else: [T: "a matriz"] + - T: "1 por" + - x: "count(*/*)" + - T: "linha" + - pause: long + - x: "*/*" # select the cols (mtd) + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: "fim" + - test: + if: $ClearSpeak_Matrix = 'EndMatrix' + then: [T: matriz] + else: [T: vetor] + +- 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 = 'ClearSpeak' and $ClearSpeak_Matrix != 'SpeakColNum'"] + replace: + - test: + if: "self::m:determinant" + then: [T: "o determinante"] + else: [T: "a matriz"] + - x: count(*) + - T: por + - x: count(*[self::m:mtr][1]/*) + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: fim + - test: + if: "self::m:determinant" + then: [T: "determinante"] + else: [T: "matriz"] + +- name: default-matrix + tag: [matrix, determinant] + variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] + match: "not(@data-intent-property)" + replace: + - test: + if: "self::m:determinant" + then: [T: "o determinante"] + else: [T: "a matriz"] + - x: "count(*)" + - T: por + - x: "count(*[self::m:mtr][1]/*)" + - pause: long + - x: "*" + - test: + if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" + then: + - T: fim + - test: + if: "self::m:determinant" + then: [T: determinante] + else: [T: matriz] + +- name: chemistry-msub + + tag: [chemical-formula] + match: "*[1][.='msub']" + replace: + - x: "*[2]" + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "*[3]" + +# ACRESCENTADO: dimensões de matriz anotadas como dimension-product +# ("3×5" com intent de dimensão) fala "3 por 5". +- name: dimension-by + tag: mrow + match: dimension-product + replace: + - insert: + nodes: "*" + replace: [T: "por", pause: auto] + +- name: chemistry-msup + tag: [chemical-formula] + match: "count(*)=3 and *[1][.='msup']" + replace: + - x: "*[2]" + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - 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: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - x: "$Prescripts[2]" + - pause: "short" + - test: + if: "not($Prescripts[1][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - 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: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - x: "$Prescripts[4]" + - pause: "short" + - test: + if: "not($Prescripts[3][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - 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: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Postscripts[1]" + - pause: "short" + - test: + if: "not($Postscripts[2][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - 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: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Postscripts[3]" + - pause: "short" + - test: + if: "not($Postscripts[4][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - 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: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Postscripts[5]" + - pause: "short" + - test: + if: "not($Postscripts[6][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - 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: "subscrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "sub"] + - x: "$Postscripts[7]" + - pause: "short" + - test: + if: "not($Postscripts[8][self::m:none])" + then: + - test: + if: "$Verbosity='Verbose'" + then: [T: "sobrescrito"] + else_test: + if: "$Verbosity='Medium'" + then: [T: "super"] + - 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: "sólido"] + - else_if: ".='l'" + then: [T: "líquido"] + - else_if: ".='g'" + then: [T: "gasoso"] + else: [T: "aquoso"] # (aq) + - 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: "ligação simples"] + - else_if: ".='=' or .='∷'" # U+2237: o canonicalizador converte '::' nesse caractere + then: [T: "ligação dupla"] + - else_if: ".='≡'" + then: [T: "ligação tripla"] + - else_if: ".='≣'" + then: [T: "ligação quádrupla"] + 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: "forma"] + else: [T: "reage formando"] + - else_if: ".='⇌' or .='🣑'" # U+01F8D1 + then: [T: "está em equilíbrio com"] + - else_if: ".='🣓'" # U+1F8D3 + then: [T: "está em equilíbrio deslocado para a esquerda com"] + - else_if: ".='🣒'" # U+1F8D2 + then: [T: "está em equilíbrio deslocado para a direita com"] + 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 + +# ACRESCENTADO: fora da química, cai na regra 'default-text', que fala o +# nome da tag -- em inglês isso dá "none", que é aceitável lá, mas em português +# saía a palavra inglesa. Aqui traduzimos. +- name: none-default + tag: none + match: "." + replace: + - T: "nenhum" + +- name: ignore-intent-wrapper + tag: intent-wrapper + match: "." + replace: + - x: "*" diff --git a/Rules/Languages/pt/SharedRules/geometry.yaml b/Rules/Languages/pt/SharedRules/geometry.yaml new file mode 100644 index 000000000..24227e81b --- /dev/null +++ b/Rules/Languages/pt/SharedRules/geometry.yaml @@ -0,0 +1,80 @@ + +--- + +- name: line-segment + tag: line-segment + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "o segmento de reta de" + - x: "*[1]" + - T: "a" + - x: "*[2]" + else: + - T: "segmento de reta" + - x: "*[1]" + - x: "*[2]" + +- name: geometry-ray + tag: ray + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "a semirreta de" + - x: "*[1]" + - T: "a" + - x: "*[2]" + else: + - T: "semirreta" + - x: "*[1]" + - x: "*[2]" + +- name: geometry-arc + tag: arc + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: [T: "o"] + - T: "arco" + - x: "*[1]" + - x: "*[2]" + +- name: measure-of-angle + tag: measure-of-angle + match: "count(*)=3" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "a medida do ângulo" + else: + - T: "medida do ângulo" + - x: "*[1]" + - x: "*[2]" + - x: "*[3]" + +# ACRESCENTADO +- name: coordinate + tag: coordinate + match: "." + replace: + - test: + if: "$Verbosity='Verbose'" + then: [OT: "o"] + - T: "ponto" + - test: + if: "$Verbosity='Verbose'" + then: [T: "em"] + - pause: short + - insert: + nodes: "*" + replace: [T: "vírgula", pause: auto] + - pause: short + - test: + if: "($SpeechStyle='ClearSpeak' and $Verbosity='Verbose') or not(IsNode(*[last()],'leaf'))" + then: [T: "fim do ponto"] diff --git a/Rules/Languages/pt/SharedRules/linear-algebra.yaml b/Rules/Languages/pt/SharedRules/linear-algebra.yaml new file mode 100644 index 000000000..72acf26be --- /dev/null +++ b/Rules/Languages/pt/SharedRules/linear-algebra.yaml @@ -0,0 +1,35 @@ +--- + +- name: scalar-determinant + tag: determinant + match: "count(*)=1 and not(*[1][self::m:mtr])" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "o" + - T: "determinante" + - test: + if: "$Verbosity!='Terse'" + then: + - T: "de" + - x: "*[1]" + - test: + if: "not(IsNode(*[1], 'simple'))" + then: [T: "fim do determinante"] + +- name: subscripted-norm + tag: subscripted-norm + match: "count(*)=2" + replace: + - test: + if: "$Verbosity='Verbose'" + then: + - T: "a" + - x: "*[2]" + - T: "norma" + - test: + if: "$Verbosity!='Terse'" + then: + - T: "de" + - x: "*[1]" diff --git a/Rules/Languages/pt/SimpleSpeak_Rules.yaml b/Rules/Languages/pt/SimpleSpeak_Rules.yaml new file mode 100644 index 000000000..7677751f0 --- /dev/null +++ b/Rules/Languages/pt/SimpleSpeak_Rules.yaml @@ -0,0 +1,338 @@ +--- + +- 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: "menos" # phrase(x 'minus' y) + - x: "translate(text(), '-_', '')" + +- name: default + tag: square-root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # phrase('the' square root of x) — "a raiz" (feminino) + - T: "raiz quadrada" # phrase(the 'square root' of x) + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] # phrase(the square root 'of' x) + else: [pause: short] + - x: "*[1]" + - test: + if: IsNode(*[1], 'leaf') + then: [pause: short] + else: [T: "fim da raiz", pause: short] # phrase(the square root of x 'end root') + +- name: default + tag: root + match: "." + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: a] + - test: + if: "*[2][self::m:mn]" + then_test: + - if: "*[2][.='2']" + then: [T: "raiz quadrada"] + - else_if: "*[2][.='3']" + then: [T: "raiz cúbica"] + - else_if: "*[2][not(contains(., '.'))]" + then: [T: "raiz de índice", x: "*[2]"] + else: + # CORREÇÃO: o arquivo em espanhol manteve o bloco "pronounce" com o + # sufixo inglês "-th" , herdado do inglês "n-th root". + # Em português a leitura natural é "raiz de índice n", sem sufixo... + - T: "raiz de índice" + - x: "*[2]" + - test: + if: "$Verbosity!='Terse'" + then: [T: "de"] + - x: "*[1]" + - test: + if: IsNode(*[1], 'leaf') + then: [pause: short] + else: [T: "fim da raiz", pause: short] + +# Fraction rules +# Mixed numbers mostly "just work" because the invisible char reads as "and" and other parts read properly on their own +- name: common-fraction + tag: fraction + match: + - "*[1][self::m:mn][not(contains(., '.')) and text()<20] and" + - "*[2][self::m:mn][not(contains(., '.')) and 2<= text() and text()<=10]" + replace: [x: ToCommonFraction(.)] +- name: common-fraction-mixed-number + tag: fraction + match: + - "preceding-sibling::*[1][self::m:mo][.='⁤'] and" # preceding element is invisible plus + - "*[1][self::m:mn][not(contains(., '.'))] and" + - "*[2][self::m:mn][not(contains(., '.'))]" + replace: [x: ToCommonFraction(.)] + + +# Units (e.g., meters per second, m^2/s^2, (3m^2)/s) +- name: per-fraction + tag: fraction + match: + - "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: "por" # phrase('5 meters 'per' second) — "cinco metros por segundo" + - x: "*[2]" + +- name: simple + # don't include nested fractions. E.g, fraction a plus b over c + 1 end fraction" is ambiguous + # by simplistic SimpleSpeak's rules "b over c" is a fraction, but if we say nested fractions + # are never simple, then any 'over' applies only to enclosing "fraction...end fraction" pair. + tag: fraction + match: + - "(IsNode(*[1],'leaf') and IsNode(*[2],'leaf')) and" + - "not(ancestor::*[name() != 'mrow'][1]/self::m:fraction)" # FIX: can't test for mrow -- what should be used??? + replace: + - x: "*[1]" + - T: "sobre" + - x: "*[2]" + - pause: short + +- name: default + tag: fraction + match: "." + replace: + - T: fração + - pause: short + - x: "*[1]" + - test: + if: "not(IsNode(*[1],'leaf'))" + then: [pause: short] + - T: "sobre" + - test: + if: "not(IsNode(*[2],'leaf'))" + then: [pause: short] + - x: "*[2]" + - pause: short + - T: "fim da fração" + - pause: medium + +# 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: inverse-function + tag: inverse-function + match: "." + replace: + - T: "inversa de" # phrase(the 'inverse' of f) + - x: "*[1]" + +- 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_test: + if: "$Verbosity='Verbose'" + then: [T: "elevado ao quadrado"] + else: [T: "ao quadrado"] + # CORREÇÃO: o espanhol dizia "cúbica" (adjetivo feminino solto), + # incoerente com "al cuadrado" logo acima. O inglês é "cubed". + else: [T: "ao cubo"] +- name: function-power + tag: power + match: + - "following-sibling::*[1][self::m:mo][.='⁡']" #invisible function apply + replace: + - test: + if: "$Verbosity!='Terse'" + then: [T: a] + - bookmark: "*[2]/@id" + - T: "potência" + - x: "*[2]" + - T: "de" + - pause: short + - x: "*[1]" + +# non-function rules for power +- name: squared-or-cubed + tag: power + match: "*[2][self::m:mn][.='2' or .='3']" + replace: + - x: "*[1]" + - bookmark: "*[2]/@id" + - test: + if: "*[2][.=2]" + then_test: + if: "$Verbosity='Verbose'" + then: [T: "elevado ao quadrado"] + else: [T: "ao quadrado"] + else: [T: "ao cubo"] + +- name: simple-integer + tag: power + match: "*[2][self::m:mn][not(contains(., '.'))]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" +- 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: "elevado a" + - x: "*[2]" +- name: simple-var + tag: power + match: "*[2][self::m:mi][string-length(.)=1]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +- name: simple + tag: power + match: "IsNode(*[2], 'leaf')" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + +- name: nested + # it won't end in "power" if the exponent is simple enough + # FIX: not that important, but this misses the case where the nested exp is a negative integer (change test if this is fixed) + # ending nested exponents with "...power power" sounds bad + tag: power + match: + - "*[2][" + - " (self::m:power and not(IsNode(*[2], 'leaf'))) or" # non-simple nested superscript + - " self::m:mrow[*[last()][self::m:power[not(IsNode(*[2], 'leaf'))]]]" # same as above but at the end of an mrow # FIX: need to figure out linear replacement + - " ]" + replace: + - x: "*[1]" + - T: "elevado a" + - x: "*[2]" + - pause: short + # CORREÇÃO: o espanhol escreveu "fin de la exponente" — "exponente" é + # masculino, então já estava errado em espanhol ("fin del exponente"). + - T: "fim do expoente" +- name: default + tag: power + match: "." + replace: + - x: "*[1]" + # CORREÇÃO: a ordem herdada do inglês ("to the n plus 1 power") produzia + # "elevado à n mais 1 potência". Em português o núcleo vem antes do + # complemento: "elevado à potência n mais 1". + - T: "elevado à potência" + - x: "*[2]" + +# +# Some rules on mrows +# +- name: set + tag: set + match: "." + replace: + - test: + - if: "count(*)=0" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: o] + - T: "conjunto vazio" + - else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: o] + - T: "conjunto de todos os" + - x: "*[1]/*[1]" + - T: "tal que" + - x: "*[1]/*[3]" + else: + - test: + if: "$Verbosity!='Terse'" + then: [T: o] + - T: "conjunto" + - x: "*[1]" + +- name: times + tag: mo + match: + # added: say times is the superscript is not simple + # if we aren't sure if it is times or not, don't say anything + - ".='⁢' and" + - "not(@data-function-guess) and (" + - "not(ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) and " + - " following-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|') or " + - " self::m:matrix or self::m:determinant or self::m:binomial or" # followed by parens + - " ( (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) + - " or " + - " preceding-sibling::*[1][" + - " IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|')]" # followed by parens + - " )" + replace: + - test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] # (en: 'times') + else: [T: "vezes"] + +- 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 " + - "( IsNode(*[2], 'simple') )" + # 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/calculus.yaml" +- include: "SharedRules/general.yaml" +- include: "SharedRules/default.yaml" diff --git a/Rules/Languages/pt/definitions.yaml b/Rules/Languages/pt/definitions.yaml new file mode 100644 index 000000000..adf95240a --- /dev/null +++ b/Rules/Languages/pt/definitions.yaml @@ -0,0 +1,496 @@ +--- +- include: "../../definitions.yaml" +# Lines starting with "#" are a comment +# Each definition in this file is of the form +# - name: { "...", "..." "..." } +# For numbers, +# - name: [] "...", "..." "..." ] + + +# 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, it 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= ; índice; fim do índice", + "modified-variable": "silent= ", + "say-super": "infix=sobrescrito", # used with 'mo' for superscripts (e.g, "<") + "skip-super": "silent=", # used with 'mo' for superscripts (e.g, "*") + + "absolute-value": "function= ; valor absoluto: o valor absoluto de: o valor absoluto de; fim do valor absoluto", + "binomial": "infix=binomial; escolhe; fim do binomial", + "limit": "prefix=limite quando", + "lim-sup": "prefix=lim sup quando: o limite superior quando: o limite superior quando", + "lim-inf": "prefix=lim inf quando: o limite inferior quando: o limite inferior quando", + "logarithm-with-base": "prefix=log na base: o log na base: o logaritmo na base", + "minus": "infix=menos || prefix=menos", + "plus": "infix=mais || prefix=positivo", + + "transpose": "postfix=transposta || function=transposta", + "norm": "function=; norma: norma: a norma; fim da norma", + # ‖x‖ é inferido pelo motor como 'magnitude' (não 'norm'); sem esta linha + # vazava "magnitude de x" em inglês. Mesma fala da norma. + "magnitude": "function=; norma: norma: a norma; fim da norma", + "trace": "function=; traço: traço de: o traço de; fim do traço", + "dimension": "function=; dimensão: dimensão de: a dimensão de; fim da dimensão", + "homomorphism": "function= ; homomorfismo: homomorfismo de: o homomorfismo de; fim do homomorfismo", + "kernel": "function= ; núcleo: núcleo de: o núcleo de; fim do núcleo", + "vector": "function= ; vetor || prefix=vetor", + # O motor infere ⃗a × ⃗b como um SEM filhos (o operador vira + # o próprio elemento); aí a fixidade infix não se aplica e ele falava o nome + # literal, "cross product". A fixidade nofix cobre esse caso. Idem dot-product. + "cross-product": "infix=vetorial: produto vetorial: produto vetorial || nofix=vetorial: produto vetorial: produto vetorial", + "dot-product": "infix=escalar: produto escalar: produto escalar || nofix=escalar: produto escalar: produto escalar", + + "divergence": "function= ; div: divergente: divergente; fim do divergente", + "curl": "function= ; rotacional; fim do rotacional", + "gradient": "function= ; grad: gradiente: gradiente; fim do gradiente", + "laplacian": "function=laplaciano", + + "chemistry-concentration": "function= ; concentração: concentração de: a concentração de; fim da concentração", + # CORREÇÃO: o en tem duas fixidades (nofix || function); só com a function + # a fala ganha o "de" ("probabilidade de x"). E o separador de palavras do + # conditional-probability é "|", como no en — ";" não é reconhecido aqui. + "probability": "nofix=P: probabilidade || function=probabilidade", + "conditional-probability": "function=probabilidade | dado", + "intersection": "infix=interseção", + "union": "infix=união", + } + + +# ACRESCENTADO: definição presente em en/ e ausente em es/ (e portanto em pt). +# ATENÇÃO: estes NÃO são textos falados — são nomes de intent (chaves internas +# do motor, sempre em inglês). A regra os consulta com IsInDefinition(name(.), ...). +# Traduzi-los quebraria o casamento. Copiados tal e qual do inglês. +- TerseFunctionNames: { + "divergence", "del:gradient", "curl" + } + +- KnownWords: { + "abs", "adj", "ano", "cel", "dez", "din", "elo", "fim", "lux", "nos" + } + +- NavigationParts: { + "large-op": "base; limite inferior; limite superior", + "mfrac": "numerador;denominador", + "fraction": "numerador;denominador", + "msqrt": "radicando", + "square-root": "radicando", + "mroot": "radicando;índice da raiz", + "root": "radicando;índice da raiz", + "msub": "base;subscrito", + "sub": "base;subscrito", + "msup": "base;sobrescrito", + "say-super": "base;sobrescrito", + "skip-super": "base;sobrescrito", + "power": "base;expoente", + "msubsup": "base;subscrito;sobrescrito", + "munder": "base;limite inferior", + "mover": "base;limite superior", + "munderover": "base;limite inferior;limite superior", + + # 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": "em", + "out": "saindo de", + } + +- SIPrefixes: { + "Q": "quetta", "R": "ronna", "Y": "yotta", "Z": "zetta", "E": "exa", "P": "peta", "T": "tera", "G": "giga", "M": "mega", "k": "quilo", "h": "hecto", "da": "deca", + "d": "deci", "c": "centi", "m": "mili", "µ": "micro", "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/SIBrochure-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", + "g": "grama", + "m": "metro", + "mol": "mol", + "s": "segundo", "sec": "segundo", # "sec" not actually legal + + # derived units + "Bq": "becquerel", + "C": "coulomb", + "°C": "grau Celsius", "℃": "grau Celsius", # should only take negative powers + "F": "farad", + "Gy": "gray", + "H": "henry", + "Hz": "hertz", + "J": "joule", + "kat": "katal", + "lm": "lúmen", + "lx": "lux", + "N": "newton", + "Ω": "ohm", "Ω": "ohm", # Greek Cap letter, U+2126 OHM SIGN + "Pa": "pascal", + "S": "siemens", + "Sv": "sievert", + "T": "tesla", + "V": "volt", + "W": "watt", + "Wb": "weber", + + # accepted (plus a few variants) that take SI prefixes + "l": "litro", "L": "litro", "ℓ": "litro", # Should only take negative powers + "t": "tonelada", # should only take positive powers + "Da": "dalton", + "Np": "neper", # should only take negative powers + "u": "unidade de massa atômica", + "eV": "elétron-volt", + "rad": "radiano", # should only take negative powers + "sr": "esferorradiano", # should only take negative powers + + # others that take a prefix + "a": "ano", # should only take positive powers + "as": "segundo de arco", # see en.wikipedia.org/wiki/Minute_and_second_of_arc + + # technically wrong, but used in practice with SI Units (and only positive powers) + "b": "bit", # should only take positive powers + "B": "byte", # should only take positive powers + "Bd": "baud", # should only take positive powers + } + + +- UnitsWithoutPrefixes: { + # time + "″": "segundo", "\"": "segundo", + "′": "minuto", "'": "minuto","min": "minuto", + "h": "hora", "hr": "hora", "Hr": "hora", + "d": "dia", "dy": "dia", + "w": "semana", "wk": "semana", + "y": "ano", "yr": "ano", + + # angles + "°": "grau", "deg": "grau", # should only take negative powers + "arcmin": "minuto de arco", + "amin": "minuto de arco", + "am": "minuto de arco", + "MOA": "minuto de arco", + "arcsec": "segundo de arco", + "asec": "segundo de arco", + + # distance + "au": "unidade astronômica", "AU": "unidade astronômica", + "ltyr": "ano-luz", "ly": "ano-luz", + "pc": "parsec", + "Å": "angström", "Å": "angström", # U+00C5 and U+212B + "fm": "fermi", + + # others + "ha": "hectare", + # "B": "bel", # "B" more commonly means bytes + "dB": "decibel", # already logarithmic, so not used with SI prefixes + # radiano com prefixo dobra o r (nano+radiano = nanorradiano) + "mrad": "milirradiano", "µrad": "microrradiano", "nrad": "nanorradiano", "prad": "picorradiano", "krad": "quilorradiano", + + + # CORREÇÃO ORTOGRÁFICA pt: prefixo terminado em vogal seguido de + # palavra iniciada por "s" dobra o s ex: milissegundo, microssegundo, + # nanossegundo. É o mesmo caso já tratado para "radiano" acima + # (milirradiano). A regra genérica de composição do MathCAT concatena + # sem dobrar e produziria "milisegundo". + # "as" fica de fora: o símbolo já significa "segundo de arco". + "Qs": "quettassegundo", "Rs": "ronnassegundo", "Ys": "yottassegundo", "Zs": "zettassegundo", "Es": "exassegundo", + "Ps": "petassegundo", "Ts": "terassegundo", "Gs": "gigassegundo", "Ms": "megassegundo", "ks": "quilossegundo", + "hs": "hectossegundo", "das": "decassegundo", "ds": "decissegundo", "cs": "centissegundo", "ms": "milissegundo", + "µs": "microssegundo", "ns": "nanossegundo", "ps": "picossegundo", "fs": "femtossegundo", "zs": "zeptossegundo", + "ys": "yoctossegundo", "rs": "rontossegundo", "qs": "quectossegundo", + + "Qsec": "quettassegundo", "Rsec": "ronnassegundo", "Ysec": "yottassegundo", "Zsec": "zettassegundo", + "Esec": "exassegundo", "Psec": "petassegundo", "Tsec": "terassegundo", "Gsec": "gigassegundo", + "Msec": "megassegundo", "ksec": "quilossegundo", "hsec": "hectossegundo", "dasec": "decassegundo", + "dsec": "decissegundo", "csec": "centissegundo", "msec": "milissegundo", "µsec": "microssegundo", + "μsec": "microssegundo", "nsec": "nanossegundo", "psec": "picossegundo", "fsec": "femtossegundo", + "zsec": "zeptossegundo", "ysec": "yoctossegundo", "rsec": "rontossegundo", "qsec": "quectossegundo", + + + "μs": "microssegundo", + + + "cas": "centissegundo de arco", "mas": "milissegundo de arco", + "µas": "microssegundo de arco", "μas": "microssegundo de arco", "nas": "nanossegundo de arco", + "pas": "picossegundo de arco", "fas": "femtossegundo de arco", "zas": "zeptossegundo de arco", + "yas": "yoctossegundo de arco", "ras": "rontossegundo de arco", "qas": "quectossegundo de arco", + + "QS": "quettassiemens", "RS": "ronnassiemens", "YS": "yottassiemens", "ZS": "zettassiemens", "ES": "exassiemens", + "PS": "petassiemens", "TS": "terassiemens", "GS": "gigassiemens", "MS": "megassiemens", "kS": "quilossiemens", + "hS": "hectossiemens", "daS": "decassiemens", "dS": "decissiemens", "cS": "centissiemens", "mS": "milissiemens", + "µS": "microssiemens", "nS": "nanossiemens", "pS": "picossiemens", "fS": "femtossiemens", "aS": "attossiemens", + "zS": "zeptossiemens", "yS": "yoctossiemens", "rS": "rontossiemens", "qS": "quectossiemens", + + "QSv": "quettassievert", "RSv": "ronnassievert", "YSv": "yottassievert", "ZSv": "zettassievert", "ESv": "exassievert", + "PSv": "petassievert", "TSv": "terassievert", "GSv": "gigassievert", "MSv": "megassievert", "kSv": "quilossievert", + "hSv": "hectossievert", "daSv": "decassievert", "dSv": "decissievert", "cSv": "centissievert", "mSv": "milissievert", + "µSv": "microssievert", "nSv": "nanossievert", "pSv": "picossievert", "fSv": "femtossievert", "aSv": "attossievert", + "zSv": "zeptossievert", "ySv": "yoctossievert", "rSv": "rontossievert", "qSv": "quectossievert", + + "atm": "atmosfera", + "amu": "unidade de massa atômica", + "bar": "bar", + "cal": "caloria", + "Ci": "curie", + "grad": "grado", + "M": "molar", + "R": "roentgen", + "rpm": "rotação por minuto", + "℧": "mho", + "dyn": "dina", + "erg": "erg", + + # special case overrides because prefixes with the base "metro" all get accents + "Qm": "quetâmetro", "Rm": "ronâmetro", "Ym": "yotâmetro", "Zm": "zetâmetro", "Em": "exâmetro", "Pm": "petâmetro", + "Tm": "terâmetro", "Gm": "gigâmetro", "Mm": "megâmetro", "km": "quilômetro", "hm": "hectômetro", "dam": "decâmetro", + "dm": "decímetro", "cm": "centímetro", "mm": "milímetro", "µm": "micrômetro", "nm": "nanômetro", "pm": "picômetro", + # conflicts: "fm": "femtômetro", "am": "attômetro", + "zm": "zeptômetro", "ym": "yoctômetro", "rm": "rontômetro", "qm": "quectômetro", + + # powers of 2 used with bits and bytes + "Kib": "kibibit", "Mib": "mebibit", "Gib": "gibibit", "Tib": "tebibit", "Pib": "pebibit", "Eib": "exbibit", "Zib": "zebibit", "Yib": "yobibit", + "KiB": "kibibyte", "MiB": "mebibyte", "GiB": "gibibyte", "TiB": "tebibyte", "PiB": "pebibyte", "EiB": "exbibyte", "ZiB": "zebibyte", "YiB": "yobibyte", + } + + + # this will only be used if the language is English, so it can be empty for other countries + # Mantida em inglês de propósito: são unidades imperiais, sem uso no Brasil. +- EnglishUnits: { + # length + "in": "inch", + "ft": "foot", + "mi": "mile", + "rd": "rod", + "li": "link", + "ch": "chain", + + # area + "sq in": "square inch", "sq. in": "square inch", "sq. in.": "square inch", + "sq ft": "square foot", "sq. ft": "square foot", "sq. ft.": "square foot", + "sq yd": "square yard", "sq. yd": "square yard", "sq. yd.": "square yard", + "sq mi": "square mile", "sq. mi": "square mile", "sq. mi.": "square mile", + "ac": "acre", + "FBM": "board foot", + + # volume + "cu in": "cubic inch", "cu. in": "cubic inch", "cu. in.": "cubic inch", + "cu ft": "cubic foot", "cu. ft": "cubic foot", "cu. ft.": "cubic foot", + "cu yd": "cubic yard", "cu. yd": "cubic yard", "cu. yd.": "cubic yard", + "bbl": "barrel", "BBL": "barrel", + "pk": "peck", + "bu": "bushel", + "tsp": "teaspoon", + "tbl": "tablespoon", + + # liquid + "fl dr": "fluid drams", + "fl oz": "fluid ounce", + "gi": "gill", + "cp": "cup", "cup": "cup", + "pt": "pint", + "qt": "quart", + "gal": "gallon", + + # weight + "gr": "grain", + "dr": "dram", + "oz": "ounce", "℥": "ounce", + "lb": "pound", + "cwt": "hundredweight", + "dwt": "pennyweight", + "oz t": "troy ounce", + "lb t": "troy pound", + + # energy + "hp": "horsepower", + "BTU": "BTU", + "°F": "degree fahrenheit", "℉": "degree fahrenheit", + + # other + "mph": "mile per hour", + "mpg": "mile per gallon", + } + +# ACRESCENTADO símbolos monetários para a regra currency. +# O inglês não tem R$; acrescentado por ser o caso principal no Brasil. +- CurrencySymbols: { + "R$": "real", + "$": "dólar", "US$": "dólar", "¢": "centavo", "€": "euro", "£": "libra", + "₡": "colón", "₤": "lira", "₨": "rupia", "₩": "won", "₪": "shekel", + "₱": "peso", "₹": "rupia", "₺": "lira", "₿": "bitcoin", + } + +- PluralForms: { + "lúmen": "lúmens", + "kelvin": "kelvins", + "grau Celsius": "graus Celsius", + # O plural genérico acrescenta "s" no FIM da string, o que produziria + # "yoctossegundo de arcos". O "s" tem de ir no substantivo, não na frase. + # (a forma sem prefixo já está mais abaixo, junto de "minuto de arco".) + "centissegundo de arco": "centissegundos de arco", + "milissegundo de arco": "milissegundos de arco", + "microssegundo de arco": "microssegundos de arco", + "nanossegundo de arco": "nanossegundos de arco", + "picossegundo de arco": "picossegundos de arco", + "femtossegundo de arco": "femtossegundos de arco", + "zeptossegundo de arco": "zeptossegundos de arco", + "yoctossegundo de arco": "yoctossegundos de arco", + "rontossegundo de arco": "rontossegundos de arco", + "quectossegundo de arco": "quectossegundos de arco", + "grau Fahrenheit": "graus Fahrenheit", + "hertz": "hertz", + "siemens": "siemens", + "lux": "lux", + "mol": "mols", + # a regra genérica acrescenta "es" a palavras terminadas em l/r, o que + # gera "decibeles"/"molares". Em português o plural de -el é -éis. + "decibel": "decibéis", + "bel": "béis", + + # Unidades invariáveis no plural continuam invariáveis quando prefixadas. + # A regra genérica não consulta o nome composto e produziria + # "milissiemenses", "decahertzes", "attoluxes". + "quettassiemens": "quettassiemens", "ronnassiemens": "ronnassiemens", "yottassiemens": "yottassiemens", "zettassiemens": "zettassiemens", + "exassiemens": "exassiemens", "petassiemens": "petassiemens", "terassiemens": "terassiemens", "gigassiemens": "gigassiemens", + "megassiemens": "megassiemens", "quilossiemens": "quilossiemens", "hectossiemens": "hectossiemens", "decassiemens": "decassiemens", + "decissiemens": "decissiemens", "centissiemens": "centissiemens", "milissiemens": "milissiemens", "microssiemens": "microssiemens", + "nanossiemens": "nanossiemens", "picossiemens": "picossiemens", "femtossiemens": "femtossiemens", "attossiemens": "attossiemens", + "zeptossiemens": "zeptossiemens", "yoctossiemens": "yoctossiemens", "rontossiemens": "rontossiemens", "quectossiemens": "quectossiemens", + "quettahertz": "quettahertz", "ronnahertz": "ronnahertz", "yottahertz": "yottahertz", "zettahertz": "zettahertz", + "exahertz": "exahertz", "petahertz": "petahertz", "terahertz": "terahertz", "gigahertz": "gigahertz", + "megahertz": "megahertz", "quilohertz": "quilohertz", "hectohertz": "hectohertz", "decahertz": "decahertz", + "decihertz": "decihertz", "centihertz": "centihertz", "milihertz": "milihertz", "microhertz": "microhertz", + "nanohertz": "nanohertz", "picohertz": "picohertz", "femtohertz": "femtohertz", "attohertz": "attohertz", + "zeptohertz": "zeptohertz", "yoctohertz": "yoctohertz", "rontohertz": "rontohertz", "quectohertz": "quectohertz", + "quettalux": "quettalux", "ronnalux": "ronnalux", "yottalux": "yottalux", "zettalux": "zettalux", + "exalux": "exalux", "petalux": "petalux", "teralux": "teralux", "gigalux": "gigalux", + "megalux": "megalux", "quilolux": "quilolux", "hectolux": "hectolux", "decalux": "decalux", + "decilux": "decilux", "centilux": "centilux", "mililux": "mililux", "microlux": "microlux", + "nanolux": "nanolux", "picolux": "picolux", "femtolux": "femtolux", "attolux": "attolux", + "zeptolux": "zeptolux", "yoctolux": "yoctolux", "rontolux": "rontolux", "quectolux": "quectolux", + + "mho": "mhos", + "real": "reais", "dólar": "dólares", "colón": "colones", + "pascal": "pascals", + "weber": "webers", + "becquerel": "becquerels", + "katal": "katals", + "rotação por minuto": "rotações por minuto", + "unidade de massa atômica": "unidades de massa atômica", + "unidade astronômica": "unidades astronômicas", + "ano-luz": "anos-luz", + "minuto de arco": "minutos de arco", + "segundo de arco": "segundos de arco", + } + +# ---------------- 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). +# +# NOTA DE TRADUÇÃO -> regra do português para denominador de fração: +# até 1/10 usa-se o ordinal ("um terço", "um décimo"); +# de 1/11 em diante usa-se "avos" ("um onze avos", "três vinte avos"). +# Isso difere do inglês e do espanhol, e está refletido nas listas plurais. + +# All definitions start 0, 10, 100, etc. + +# The definitions for the "ones" should extend until a regular pattern begins +# The minimum length is 10. + +- NumbersOnes: [ + "zero", "um", "dois", "três", "quatro", "cinco", "seis", "sete", "oito", "nove", + "dez", "onze", "doze", "treze", "catorze", "quinze", "dezesseis", + "dezessete", "dezoito", "dezenove" + ] + +- NumbersOrdinalOnes: [ + "zero", "primeiro", "segundo", "terceiro", "quarto", "quinto", "sexto", "sétimo", "oitavo", "nono", + "décimo", "décimo primeiro", "décimo segundo", "décimo terceiro", "décimo quarto", "décimo quinto", "décimo sexto", + "décimo sétimo", "décimo oitavo", "décimo nono" + ] + +- NumbersOrdinalPluralOnes: [ + "zeros", "primeiros", "meios", "terços", "quartos", "quintos", "sextos", "sétimos", "oitavos", "nonos", + "décimos", "onze avos", "doze avos", "treze avos", "catorze avos", "quinze avos", "dezesseis avos", + "dezessete avos", "dezoito avos", "dezenove avos" + ] + + # stop when regularity begins +# A lista parava em "meio": de 1/3 em diante o motor caía nos ordinais +# comuns e falava "1 terceiro". Até 1/10 a forma é a do denominador de +# fração ("um terço", "um décimo"); de 1/11 em diante entra "avos", que já +# está nas listas plurais acima. Ver ACHADOS 9. +- NumbersOrdinalFractionalOnes: [ + "zero", "primeiro", "meio", "terço", "quarto", "quinto", "sexto", "sétimo", "oitavo", "nono", + "décimo" + ] + + # stop when regularity begins +- NumbersOrdinalFractionalPluralOnes: [ + "zeros", "primeiros", "meios", "terços", "quartos", "quintos", "sextos", "sétimos", "oitavos", "nonos", + "décimos" + ] + + + # What to use for multiples of 10 +- NumbersTens: [ + "", "dez", "vinte", "trinta", "quarenta", "cinquenta", "sessenta", "setenta", "oitenta", "noventa" + ] + +- NumbersOrdinalTens: [ + "", "décimo", "vigésimo", "trigésimo", "quadragésimo", "quinquagésimo", "sexagésimo", "septuagésimo", "octogésimo", "nonagésimo" + ] + +- NumbersOrdinalPluralTens: [ + "", "décimos", "vinte avos", "trinta avos", "quarenta avos", "cinquenta avos", "sessenta avos", "setenta avos", "oitenta avos", "noventa avos" + ] + + +- NumbersHundreds: [ + "", "cem", "duzentos", "trezentos", "quatrocentos", "quinhentos", + "seiscentos", "setecentos", "oitocentos", "novecentos" + ] + +- NumbersOrdinalHundreds: [ + "", "centésimo", "ducentésimo", "tricentésimo", "quadringentésimo", "quingentésimo", + "sexcentésimo", "septingentésimo", "octingentésimo", "noningentésimo" + ] + +- NumbersOrdinalPluralHundreds: [ + "", "centésimos", "ducentésimos", "tricentésimos", "quadringentésimos", "quingentésimos", + "sexcentésimos", "septingentésimos", "octingentésimos", "noningentésimos" + ] + + + # At this point, hopefully the language is regular. If not, code needs to be written +- NumbersLarge: [ + "", "mil", "milhão", "bilhão", "trilhão", "quatrilhão", + "quintilhão", "sextilhão", "septilhão", "octilhão", "nonilhão" + ] + +- NumbersOrdinalLarge: [ + "", "milésimo", "milionésimo", "bilionésimo", "trilionésimo", "quatrilionésimo", + "quintilionésimo", "sextilionésimo", "septilionésimo", "octilionésimo", "nonilionésimo" + ] + +- NumbersOrdinalPluralLarge: [ + "", "milésimos", "milionésimos", "bilionésimos", "trilionésimos", "quatrilionésimos", + "quintilionésimos", "sextilionésimos", "septilionésimos", "octilionésimos", "nonilionésimos" + ] diff --git a/Rules/Languages/pt/navigate.yaml b/Rules/Languages/pt/navigate.yaml new file mode 100644 index 000000000..bc7c5fe26 --- /dev/null +++ b/Rules/Languages/pt/navigate.yaml @@ -0,0 +1,1773 @@ +--- +# Documentation: +# +# The general form for many rules is: +# 1. Say the command if this is first rule to fire (MatchCounter) and depending upon "NavVerbosity"s value +# 2. Say info about moving into/out of 2D structures +# 3. Set some variables and possibly recurse. +# If recursing, "MatchCounter" should be incremented. +# If stopping, "NavNode" should be set. +# +# The meaning of NavVerbosity: +# * Verbose -- always echo the command and end points (e.g., "can't move right") +# * Medium -- only echo the command for obscure commands like the placemarker commands; also say end points +# * Terse -- no echo of commands or end points +# +# For the second item, a common set of rules is used. These rules require the variable "Move2D" +# to be set along with "Child2D", where "Move2D" is either 'in' or 'out'. +# +# In addition, the navigation rules make use of two functions: +# +# int DistanceFromLeaf(node, leftSide, treat2DElementsAsTokens) +# Returns the distance (number of children) until a leaf is reached by traversing the leftmost/rightmost child +# If 'treat2DElementsAsTokens' is true, then 2D notations such as fractions are treated like leaves +# A leaf has distance == 0 +# +# EdgeNode(node, "left"/"right", stopNodeName) +# Returns the stopNode if at left/right edge of named ancestor node. 'stopNodeName' can also be "2D" +# If the stopNode isn't found, the original node is returned +# Note: if stopNodeName=="math", then punctuation is taken into account since it isn't really part of the math +# +# A few other variables are of importance to Navigation +# NavMode -- Enhanced, Simple, Character +# ReadZoomLevel -- -1 for Enhanced, otherwise the distance from leaf the rules should maintain +# PlaceMarkerIndex + + +# Rules for speaking what happens when moving into or out of a notation +- name: into-or-out-of + tag: mfrac + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "numerador"] + else: [T: "denominador"] + - pause: "medium" + +- name: into-or-out-of + tag: msqrt + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - T: "raiz quadrada" + - pause: "medium" + +- name: into-or-out-of + tag: mroot + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "radicando"] + else: [T: "índice da raiz"] + - pause: "medium" + +- name: into-or-out-of + tag: msub + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + else: [T: "subscrito"] + - pause: "medium" + +- name: into-or-out-of + tag: msup + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + else: [T: "sobrescrito"] # FIX: it would be better to use the word used when reading (power, exponent, ...) + - pause: "medium" + +- name: into-or-out-of + tag: msubsup + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + - if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + - else_if: "count($Child2D/preceding-sibling::*)=1" + then: [T: "subscrito"] + else: [T: "sobrescrito"] # FIX: it would be better to use the word used when reading (power, exponent, ...) + - pause: "medium" + +- name: into-or-out-of + tag: munder + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + else: [T: "limite inferior"] + - pause: "medium" + +- name: into-or-out-of + tag: mover + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + else: [T: "limite superior"] + - pause: "medium" + +- name: into-or-out-of + tag: munderover + match: "$Move2D != ''" + replace: + - x: "$Move2D" + - test: + - if: "count($Child2D/preceding-sibling::*)=0" + then: [T: "base"] + - else_if: "count($Child2D/preceding-sibling::*)=1" + then: [T: "limite inferior"] + else: [T: "limite superior"] + - pause: "medium" + +- name: into-or-out-of + tag: mmultiscripts + match: "$Move2D != ''" + replace: + - test: + if: "name($Child2D)!='none'" + then: + - with: + variables: + - NumPrecedingSiblings: "count($Child2D/preceding-sibling::*)" + replace: + - x: "$Move2D" + - test: + - if: "$NumPrecedingSiblings=0" + then: [T: "base"] + - else_if: "$Child2D/preceding-sibling::*[self::m:mprescripts]" # are we before mprescripts and hence are postscripts + then: + - test: # in postscripts -- base shifts by one + if: "$NumPrecedingSiblings mod 2 = 0" + then: [T: "subscrito"] + else: [T: "sobrescrito"] + else: + - test: + if: "$NumPrecedingSiblings mod 2 = 0" + then: [T: "sobrescrito"] + else: [T: "subscrito"] + - pause: "medium" + +- name: into-or-out-of + tag: mtd + match: "$Move2D = 'em'" + replace: + - x: "$Move2D" + - T: "coluna" + - x: "count($Child2D/preceding-sibling::*)+1" + - pause: "medium" + +- name: into-or-out-of + tag: [mtr, mlabeledtr] + match: "$Move2D = 'em'" + replace: + - x: "$Move2D" + - x: "count($Child2D/preceding-sibling::*)+1" + - pause: "medium" + +- name: default-move + # nothing to do (not 2D) -- need to catch $Move2D though so rules based on NavCommand don't trigger + tag: "*" + match: "$Move2D != ''" + replace: [] + +# ********* Go back to last position *************** +# This is first since start/end position shouldn't matter +- name: move-last-location + + + tag: "*" + match: "$NavCommand = 'MoveLastLocation'" + replace: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - test: + - if: "$PreviousNavCommand = 'ZoomIn'" + then: [T: "desfazer afastamento"] + - else_if: "$PreviousNavCommand = 'ZoomOut'" + then: [T: "desfazer aproximação"] + - else_if: "$PreviousNavCommand = 'ZoomInAll'" + then: [T: "desfazer afastamento máximo"] + - else_if: "$PreviousNavCommand = 'ZoomOutAll'" + then: [T: "desfazer aproximação máxima"] + - else_if: "$PreviousNavCommand = 'MovePrevious' or $PreviousNavCommand = 'MovePreviousZoom'" + then: [T: "desfazer movimento para a esquerda"] + - else_if: "$PreviousNavCommand = 'MoveNext' or $PreviousNavCommand = 'MoveNextZoom'" + then: [T: "desfazer movimento para a direita"] + - else_if: "$PreviousNavCommand = 'None'" + then: [T: "nenhum comando anterior"] + - pause: "long" + - set_variables: [NavNode: "@id"] + +# many times, for typographic reasons, people include punctuation at the end of a math expr +# these rules detect that and skip speaking it (should be similar regular rule) +- name: skip-punct-at-end-zoom-in + tag: mrow + match: + - "($NavCommand = 'ZoomIn' or $NavCommand = 'ZoomInAll' or $NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom') and" + - " parent::m:math and count(*)=2 and" + - " *[2][translate(.,'.,;:?', '')='']" + replace: + - x: "*[1]" + +# ********* ZoomIn *************** +- name: zoom-in-leaf + + tag: "*" + match: "($NavCommand = 'ZoomIn' or $NavCommand = 'ZoomInAll') and IsNode(., 'leaf')" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: [T: "aproximado ao máximo", pause: "long"] + - test: + if: "$ReadZoomLevel!=-1" + then: + - set_variables: [ReadZoomLevel: "0"] + - set_variables: [NavNode: "@id"] + +# special case of zooming into a matrix or determinant -- move to the first element +- name: zoom-in-matrix + + tag: mrow + match: + - "$NavCommand = 'ZoomIn' and count(*)=3 and " + - "*[2][self::m:mtable and (IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|'))]" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - set_variables: [NavNode: "*[2]/*[1]/@id"] + +# special case of zooming into a table -- move to the first element +- name: zoom-in-table + tag: mtable + match: "$NavCommand = 'ZoomIn'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-mrow-in-math + # Moving to first or last is meaningless the 'math' has only an 'mrow' inside -- dig inside and do it again + tag: math + match: "count(*)=1 and ($NavCommand = 'ZoomIn' or $NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom')" + replace: + - test: + if: "$NavCommand = 'MovePreviousZoom'" + then: [x: "*[last()]"] + else: [x: "*[1]"] + +- # For msqrt and menclose, if the single child isn't an mrow, don't zoom in + name: zoom-in-again + # If there is only one child, this isn't an interesting move -- zoom in again + tag: "*" + match: + - "($NavCommand = 'ZoomIn' or " + - " ($NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom') and $NavMode='Enhanced') and " + - "count(*)=1 and (*[1][self::m:mrow] and not(self::m:msqrt or self::m:menclose))" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "$NavCommand = 'MovePreviousZoom'" + then: [x: "*[last()]"] + else: [x: "*[1]"] + +- name: zoom-in-enhanced + + tag: "*" + match: "$NavCommand = 'ZoomIn' and $NavMode='Enhanced'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - test: + - if: "self::m:mtr or self::m:mlabeledtr" + then: + - with: + variables: [Move2D: "'em'", Child2D: "*[1]/*[1]"] + replace: [x: "."] + - set_variables: [NavNode: "*[1]/*[1]/@id"] # skip mtd + - else_if: "*[1][self::m:mrow and IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false)]" # auto zoom + then: + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - set_variables: [NavNode: "*[1]/*[2]/@id"] # skip parens/brackets + else: + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-2D-not-enhanced + tag: "*" + match: "$NavCommand = 'ZoomIn' and $NavMode!='Enhanced' and IsNode(., '2D')" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]"] + +- name: zoom-in-default + tag: "*" + match: "$NavCommand = 'ZoomIn'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado", pause: "long"] + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "*[1]"] + else_test: + if: "self::m:mtd" + then: [x: "*[1]"] + else: + - test: + if: "$ReadZoomLevel!=-1" + then: + - set_variables: [ReadZoomLevel: "DistanceFromLeaf(*[1], true, $NavMode!='Character')"] + - set_variables: [NavNode: "*[1]/@id"] + +- name: zoom-in-all-default + tag: "*" + match: "$NavCommand = 'ZoomInAll'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "aproximado ao máximo", pause: "medium"] + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "*[1]"] + +- name: zoom-out + tag: math + match: "$NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: [T: "afastado ao máximo", pause: "long"] + - set_variables: [NavNode: "*[1]/@id"] # no-op for $NavCommand = 'ZoomOut' + +- name: zoom-out-top + tag: "*" + match: + - "($NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll') and" + - "parent::m:math " + replace: + - x: ".." # let math rule deal with it + +- name: skip-punct-at-end-zoom-out + tag: mrow + match: + - "($NavCommand = 'ZoomOut' or $NavCommand = 'ZoomOutAll') and" + - " parent::m:math and count(*)=2 and" + - " *[2][translate(.,'.,;:?', '')='']" + replace: + - x: ".." + +- name: zoom-out-all-default + tag: "*" + match: "$NavCommand = 'ZoomOutAll'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: [T: "afastado ao máximo", pause: "medium"] + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: ".."] + +# deal with internal zooming: MoveNextZoom and MovePreviousZoom + +# start with Enhanced mode +- name: move-zoom-enhanced + tag: "*" + match: + - "($NavCommand = 'MoveNextZoom' or $NavCommand = 'MovePreviousZoom') and " + - "$NavMode = 'Enhanced'" + replace: + # don't bother with MatchCounter since we only get here if > 1 + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - test: + - if: "count(*)> 1 or IsNode(., 'leaf') or self::m:msqrt or self::m:menclose" + then: [set_variables: [NavNode: "@id"]] + else: [x: "*[1]"] + +- name: move-next-zoom-not-enhanced + # $ReadZoomLevel must be >= 0 + tag: "*" + match: "$NavCommand = 'MoveNextZoom'" + replace: + #don't bother with MatchCounter since we only get here if > 1 + - test: + if: "$ReadZoomLevel >= DistanceFromLeaf(., false, $NavMode!='Character')" + then: + # - with: + # variables: [Move2D: "'em'", Child2D: "following-sibling::*[1]"] + # replace: [x: ".."] + - set_variables: [NavNode: "@id"] + else: + - with: + variables: [Move2D: "'em'", Child2D: "*[1]"] + replace: [x: "."] + - x: "*[1]" + +- name: move-previous-zoom-not-enhanced + # $ReadZoomLevel must be >= 0 + tag: "*" + match: "$NavCommand = 'MovePreviousZoom'" + replace: + #don't bother with MatchCounter since we only get here if > 1 + - test: + if: "$ReadZoomLevel >= DistanceFromLeaf(., true, $NavMode!='Character')" + then: + # - with: + # variables: [Move2D: "'em'", Child2D: "preceding-sibling::*[1]"] + # replace: [x: ".."] + - set_variables: [NavNode: "@id"] + else: + - with: + variables: [Move2D: "'em'", Child2D: "*[last()]"] + replace: [x: "."] + - x: "*[last()]" + +# ********* ZoomOut *************** +- name: zoom-out-default + + + tag: mtd + match: "$Move2D = '' and ($NavCommand = 'ZoomOut')" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: [T: "afastar", pause: "medium"] + # we need to speak it here + - T: "linha" + # if we let the speech rules speak the row, it is given just the MathML for the row, so the row # will always be '1' + - x: "count(../preceding-sibling::*)+1" + - pause: medium + - set_variables: [NavNode: "../@id"] + +- name: zoom-out + # a row around a single element -- these might duplicate the position/offset, so we jump an extra level here + tag: "*" + match: "$NavCommand = 'ZoomOut'" + replace: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "$MatchCounter = 1 and $NavVerbosity = 'Verbose'" + then: [T: "afastar", pause: "medium"] + - test: + if: "$NavMode='Enhanced' and parent::*[self::m:mrow and IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false)]" + then: [x: ".."] # auto-zoom: move out a level and retry + else: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - test: + if: "parent::m:mtd" + then: [x: ".."] + else: + - test: + if: "$ReadZoomLevel!=-1" + then: [set_variables: [ReadZoomLevel: "DistanceFromLeaf(.., true, $NavMode!='Character')"]] + - set_variables: [NavNode: "../@id"] + +# ********* MoveStart/End *************** +- name: math-move-to-start-or-end + tag: math + match: "$NavCommand = 'MoveStart' or $NavCommand = 'MoveLineStart' or $NavCommand = 'MoveEnd' or $NavCommand = 'MoveLineEnd'" + replace: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveStart'" + then: [T: "início da expressão"] + - else_if: "$NavCommand = 'MoveLineStart'" + then: [T: "mover para o início da linha"] + - else_if: "$NavCommand = 'MoveEnd'" + then: [T: "fim da expressão"] + else: [T: "mover para o fim da linha"] # "$NavCommand = 'MoveLineEnd'" + - pause: "medium" + - test: + if: "$NavCommand = 'MoveStart' or $NavCommand = 'MoveLineStart'" + then: + # move inside of the mrow inside of 'math' or inside the fraction, etc (hence two levels down) + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]/*[1]"] + else: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "*[last()]/*[last()]"] + +# We stop when the parent is 2d (e.g., frac), but not if in leaf base of msub/msup/msubsup/mmultiscripts because that's really on the same line +- name: move-to-start-or-end-2d + tag: "*" + match: + - "($NavCommand = 'MoveLineStart' or $NavCommand = 'MoveLineEnd') and IsNode(.., '2D') and" + - "not( IsNode(., 'leaf') and (parent::m:msub or parent::m:msup or parent::m:msubsup or parent::m:mmultiscripts) )" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + if: "$NavCommand = 'MoveLineStart'" + then: [T: "mover para o início da linha"] + else: [T: "mover para o fim da linha"] # "$NavCommand = 'MoveLineEnd'" + - pause: "medium" + - test: + if: "self::m:mrow" + then_test: + if: "$NavCommand = 'MoveLineStart'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "*[1]"] + else: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "*[last()]"] + else: [set_variables: [NavNode: "@id"]] + +- name: move-to-start-or-end-default + tag: "*" + match: "$NavCommand = 'MoveStart' or $NavCommand = 'MoveLineStart' or $NavCommand = 'MoveEnd' or $NavCommand = 'MoveLineEnd'" + replace: + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: ".."] + +# Table-related movement +# Typically, we need to zoom out to the mtd level, then we move the appropriate direction +- name: not-in-table + + + tag: math + match: + - "$NavCommand='MoveCellPrevious' or $NavCommand='MoveCellNext' or" + - "$NavCommand='MoveCellUp' or $NavCommand='MoveCellDown' or" + - "$NavCommand='MoveColumnStart' or $NavCommand='MoveColumnEnd' or" + - "$NavCommand='ReadCellCurrent'" + replace: + - T: "fora da tabela" + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-cell-previous + tag: mtd + match: "$NavCommand='MoveCellPrevious'" + replace: + - test: + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "mover para a esquerda" + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "coluna" + - x: "count(preceding-sibling::*)" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/*[1]/@id"] + else: + - T: "não há coluna anterior" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-next + tag: mtd + match: "$NavCommand='MoveCellNext'" + replace: + - test: + if: "following-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "mover para a direita" + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "coluna" + - x: "count(preceding-sibling::*)+2" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: + - set_variables: [NavNode: "following-sibling::*[1]/*[1]/@id"] + else: + - T: "não há próxima coluna" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-up + tag: mtd + match: "$NavCommand='MoveCellUp'" + replace: + - test: + if: "../preceding-sibling::*" + then: + - with: + variables: [Column: "count(preceding-sibling::*)+1"] # store this because otherwise the value is used in the wrong context below + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "mover para cima" + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "linha" + - x: "count(../preceding-sibling::*)" + - pause: short + - T: "coluna" + - x: "count(preceding-sibling::*)+1" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "../preceding-sibling::*[1]/*[$Column]"] + else: + - set_variables: [NavNode: "../preceding-sibling::*[1]/*[$Column]/*[1]/@id"] + else: + - T: "não há linha anterior" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-down + tag: mtd + match: "$NavCommand='MoveCellDown'" + replace: + - test: + if: "../following-sibling::*" + then: + - with: + variables: [Column: "count(preceding-sibling::*)+1"] # store this because otherwise the value is used in the wrong context below + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "descer" + - pause: short + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "linha" + - x: "count(../preceding-sibling::*)+2" + - pause: short + - T: "coluna" + - x: "count(preceding-sibling::*)+1" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "../following-sibling::*[1]/*[$Column]"] + else: + - set_variables: [NavNode: "../following-sibling::*[1]/*[$Column]/*[1]/@id"] + else: + - T: "não há próxima linha" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-up + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellUp'" + replace: + - test: + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "subir" + - pause: medium + - T: "linha" + - x: "count(preceding-sibling::*)" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/@id"] + else: + - T: "não há linha anterior" + - set_variables: [SpeakExpression: false()] + +- name: move-cell-down + tag: [mtr, mlabeledtr] + match: "$NavCommand='MoveCellDown'" + replace: + - test: + if: "following-sibling::*" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "descer" + - pause: medium + - T: "linha" + - x: "count(preceding-sibling::*)+2" + - pause: medium + - test: + if: "$NavMode='Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: + - set_variables: [NavNode: "following-sibling::*[1]/@id"] + else: + - T: "não há próxima linha" + - set_variables: [SpeakExpression: false()] + +- name: default-read-cell + tag: "*" + match: "$NavCommand='ReadCellCurrent'" + replace: + - with: + variables: [MTD: "ancestor::m:mtd"] + replace: + - test: + if: "$MTD" + then: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - T: "ler a entrada atual" + - pause: medium + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "linha" + - x: "count($MTD[1]/../preceding-sibling::*)+1" + - T: "coluna" + - x: "count($MTD[1]/preceding-sibling::*)+1" + - pause: short + - set_variables: [NavNode: "$MTD[1]/*[1]/@id"] + else: + - T: "fora da tabela" + - pause: long + - set_variables: [SpeakExpression: false()] + +# mtd ? ( $NavCommand='MoveColumnStart' ) +# => MoveColStart { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^match[0][index(match)][0].dfs; +# ::EndPosition = ^^match[0][index(match)][0].offset; +# }; + +# mtd ? ( $NavCommand='MoveColumnEnd' ) +# => MoveColEnd { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^match[count(^^match)-1][index(match)][0].dfs; +# ::EndPosition = ^^match[count(^^match)-1][index(match)][0].offset; +# }; + + + +# # Rules for columnar math (mstack and mlongdiv) -- each row is an msrow or mscarries except for the start of mlongdiv +# # FIX: not dealing with different number of digits on different lines +# # FIX: not dealing with + (etc) on same line if they are on the right side (Dutch, others) +# # FIX: not dealing with intervening msline (say it and move on??) +# # FIX: not dealing with carries well +# # FIX: not dealing with navigation of first three children of mlongdiv +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# ($NavCommand="MovePrevious" || $NavCommand='MoveCellPrevious') && has_previous(match) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "previous"; +# ::StartPosition = previous(match).dfs; +# ::EndPosition = previous(match).offset; +# }; + +# # no previous child -- in first column -- don't move +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# ($NavCommand="MovePrevious" || $NavCommand='MoveCellPrevious' ) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "previous"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# ($NavCommand="MoveNext" || $NavCommand='MoveCellNext') && has_next(match) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "next"; +# ::StartPosition = next(match).dfs; +# ::EndPosition = next(match).offset; +# }; + +# # no next child -- in first column -- don't move +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# ($NavCommand="MoveNext" || $NavCommand='MoveCellNext' ) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "next"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveCellUp' && has_previous(^^match) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "up"; +# ::StartPosition = ^^^match[index(^^match)-1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[index(^^match)-1][-1][index(match)-count(^match)].offset; +# }; + +# # no previous child -- in first column -- don't move +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveCellUp' ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "up"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveCellDown' && has_next(^^match) ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "down"; +# ::StartPosition = ^^^match[index(^^match)+1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[index(^^match)+1][-1][index(match)-count(^match)].offset; +# }; + +# # no previous child -- in first column -- don't move +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveCellDown' ) +# => MoveCell { +# ruleRef = name(^^match); +# wordRef = "down"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveColumnStart' ) +# => MoveColStart { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^^match[0][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[0][-1][index(match)-count(^match)].offset; +# }; + +# char ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveColumnEnd' ) +# => MoveColEnd { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^^match[count(^^^match)-1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[count(^^^match)-1][-1][index(match)-count(^match)].offset; +# }; + +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# ($NavCommand="MovePrevious" || $NavCommand='MoveCellPrevious') && has_previous(match) ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "previous"; +# ::StartPosition = previous(match).dfs; +# ::EndPosition = previous(match).offset; +# }; + +# # no previous child -- in first column -- don't move +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# ($NavCommand="MovePrevious" || $NavCommand='MoveCellPrevious') ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "previous"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# ($NavCommand="MoveNext" || $NavCommand='MoveCellNext') && has_next(match) ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "next"; +# ::StartPosition = next(match).dfs; +# ::EndPosition = next(match).offset; +# }; + +# # no next child -- in last column -- don't move +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# ($NavCommand="MoveNext" || $NavCommand='MoveCellNext') ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "next"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# $NavCommand='MoveCellUp' && has_previous(^match) ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "up"; +# ::StartPosition = ^^match[index(^match)-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^match[index(^match)-1][index(match)-count(^match)].offset; +# }; + +# # no previous child -- in first row -- don't move +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# $NavCommand='MoveCellUp' ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "up"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# $NavCommand='MoveCellDown' && has_next(^match) ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "down"; +# ::StartPosition = ^^match[index(^match)+1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^match[index(^match)+1][-1][index(match)-count(^match)].offset; +# }; + +# # no next child -- in last row -- don't move +# any ? ( (name(match)=="mn" || name(match)=="none") && +# has_parent(match) && name(^match)=="mscarries" && +# $NavCommand='MoveCellDown' ) +# => MoveCell { +# ruleRef = name(^match); +# wordRef = "down"; +# childIndex = -1; # key to know what to say for each notation +# ::SpeakAfterMove = false; +# }; + +# mn ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveColumnStart' ) +# => MoveColStart { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^^match[0][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[0][-1][index(match)-count(^match)].offset; +# }; + +# mn ? ( has_parent(match, 2) && name(^match)=="mn" && name(^^match)=="msrow" && +# $NavCommand='MoveColumnEnd' ) +# => MoveColEnd { +# ruleRef = name(^^match); +# column = index(match); +# ::StartPosition = ^^^match[count(^^^match)-1][-1][index(match)-count(^match)].dfs; +# ::EndPosition = ^^^match[count(^^^match)-1][-1][index(match)-count(^match)].offset; +# }; + + + +- name: default-cell-move + + tag: "*" + match: + - "$NavCommand='MoveCellPrevious' or $NavCommand='MoveCellNext' or" + - "$NavCommand='MoveCellUp' or $NavCommand='MoveCellDown' or" + - "$NavCommand='MoveColumnStart' or $NavCommand='MoveColumnEnd' or" + - "$NavCommand='ReadCellCurrent'" + replace: + - test: + if: "ancestor::m:mtd" + then: + - x: "ancestor::m:mtd[1]" # try again on an mtd node + else: + - T: "fora da tabela" + - pause: long + - set_variables: [SpeakExpression: false()] + +# ======== Move/Read/Describe Next rules ================= + +# skip 'none' +- name: move-next-none + tag: [none, mprescripts] + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext' or $NavCommand = 'DescribePrevious' or $NavCommand = 'MoveNextZoom') and" + - "parent::*[1][name(.)='mmultiscripts'] and following-sibling::*" + replace: + - with: + variables: [Following: "following-sibling::*[1]"] + replace: + # two 'none's in a row -- move over and try again; one 'none', zoom in on next + - test: + if: "$Following[name(.)='none']" + then: [x: "$Following"] + else: + - with: + variables: [Move2D: "'em'", Child2D: "$Following"] + replace: [x: ".."] + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "$Following"] + +# skip 'none' +- name: move-previous-none + tag: [none, mprescripts] + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious' or $NavCommand = 'MovePreviousZoom') and" + - "parent::*[1][name(.)='mmultiscripts'] and preceding-sibling::*" + replace: + - with: + variables: [Preceding: "preceding-sibling::*[1]"] + replace: + # two 'none's in a row -- move over and try again; one 'none', zoom in on preceding + - test: + if: "$Preceding[name(.)='none']" + then: [x: "$Preceding"] + else: + - with: + variables: [Move2D: "'em'", Child2D: "$Preceding"] + replace: [x: ".."] + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "$Preceding"] + + + +# skip invisible chars except for Enhanced mode when "times" should be read +- name: move-next-invisible + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "following-sibling::*[1][name(.)='mo' and translate(., '\u2061\u2062\u2063\u2064', '')='']" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "ir"] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "following-sibling::*[1][.='\u2062' or .='\u2064'] and $NavMode='Enhanced'" # invisible times and plus + then: [set_variables: [NavNode: "following-sibling::*[1]/@id"]] + else: [x: "following-sibling::*[1]"] + +- name: move-next-no-auto-zoom-at-edge + # at edge of 2D and in a mode where moving right isn't an option + tag: "*" + variables: [EdgeNode: "EdgeNode(., 'right', '2D')"] + match: "$NavCommand = 'MoveNext' and $NavMode!='Character' and not($AutoZoomOut) and $EdgeNode/@id!=@id" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse' and $NavCommand = 'MoveNext'" + then: + - T: "não é possível mover para a direita" + - with: + variables: [Move2D: "'fim de'", Child2D: "$EdgeNode/*[last()]"] + replace: [x: "$EdgeNode"] + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-next-no-auto-zoom-at-edge-math + # at edge of math -- no where to go (must be after we rule out being at the edge of 2D) because we want to speak that + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "(self::m:math or name(EdgeNode(., 'right', 'math'))='math')" # at edge of math + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: + - T: "não é possível" + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "mover"] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita, fim da expressão" + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-next-auto-zoom-up-one-level + # Last child or in auto-zoom'd in-- move up a level and try again + # Note: we've already checked the for the case where we are at an edge and should not AutoZoomOut + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "( not(following-sibling::*) or" + - " ( $NavMode='Enhanced' and " + - " count(following-sibling::*)=1 and (IsBracketed(.., '(', ')') or IsBracketed(.., '[', ']'))" + - " )" + - ")" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: "mover"] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNext'"] + replace: + - test: + if: "following-sibling::*" + then: + - with: + variables: [Move2D: "'em'", Child2D: "."] + replace: [x: ".."] + else: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - test: + if: "following-sibling::*" + then: + - x: ".." # move out of parens + else: + - x: ".." + +# At this point, if XXXNext, then we know there is must be a right sibling +- name: move-next-default + tag: mtd + match: "$Move2D = '' and ($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "following-sibling::*" + then: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "coluna" + - x: "count(preceding-sibling::*)+2" + - pause: short + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: [set_variables: [NavNode: "following-sibling::*[1]/*[1]/@id"]] + else: + - x: ".." # try again at the row level + +- name: move-next-default + tag: [mtr, mlabeledtr] + match: "$Move2D = '' and ($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "following-sibling::*" + then: + - T: "linha" + - x: "count(preceding-sibling::*)+2" + - T: "coluna 1" + - pause: medium + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + else: + - set_variables: [NavNode: "following-sibling::*[1]/*[1]/*[1]/@id"] + else: [x: ".."] # try again for after + +- name: move-next-auto-zoom-parens + # auto-zoom into next child if next child is parenthesized expr + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "$NavMode='Enhanced' and" + - "parent::m:mrow and following-sibling::* and" + - "following-sibling::*[1][self::m:mrow and count(*)=3 and " #exclude empty parens + - " (IsBracketed(., '(', ')') or IsBracketed(., '[', ']'))" + - " ]" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - set_variables: [NavNode: "following-sibling::*[1]/*[2]/@id"] + +# normal cases for MoveNext +- name: move-next-locked-zoom-level + # locked zoom level + tag: "*" + match: + - "($NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext') and" + - "$ReadZoomLevel>=0" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - test: + # if in base (nothing before), we must be moving to a script, so "in" will be said + if: "preceding-sibling::* and following-sibling::*[1][name(.)='none']" + then: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "following-sibling::*[1]"] # skip over 'none' + else: + - with: + variables: [Move2D: "'em'", Child2D: "following-sibling::*[1]"] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNextZoom'"] + replace: [x: "following-sibling::*[1]"] + +- name: move-next-default + tag: "*" + match: "$NavCommand = 'MoveNext' or $NavCommand = 'ReadNext' or $NavCommand = 'DescribeNext'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MoveNext'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadNext'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "direita" + - pause: short + - test: + if: "IsNode(.., '2D')" + then: + - with: + variables: [Move2D: "'em'", Child2D: "following-sibling::*[1]"] + replace: [x: ".."] + - set_variables: [NavNode: "following-sibling::*[1]/@id"] + +# ======== Move/Read/Describe Previous rules ================= + +# skip invisible chars except for Enhanced mode when "times" should be read +- name: move-previous-invisible + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "preceding-sibling::*[1][name(.)='mo' and translate(., '\u2061\u2062\u2063\u2064', '')='']" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: "mover"] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: + - test: + if: "preceding-sibling::*[1][.='\u2062' or .='\u2064'] and $NavMode='Enhanced'" # invisible times and plus + then: [set_variables: [NavNode: "preceding-sibling::*[1]/@id"]] + else: [x: "preceding-sibling::*[1]"] + +# two rules for when can't move right +- name: move-previous-no-auto-zoom-at-edge + # at edge of 2D and in a mode where moving right isn't an option + tag: "*" + variables: [EdgeNode: "EdgeNode(., 'left', '2D')"] + match: "$NavCommand = 'MovePrevious' and $NavMode!='Character' and not($AutoZoomOut) and $EdgeNode/@id!=@id" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse' and $NavCommand = 'MovePrevious'" + then: + - T: "não é possível mover para a esquerda" + - with: + variables: [Move2D: "'fim de'", Child2D: "$EdgeNode/*[1]"] + replace: [x: "$EdgeNode"] + - pause: long + +- name: move-previous-no-auto-zoom-at-edge-of-math + # at edge of math -- no where to go (must be after we rule out being at the edge of 2D) because we want to speak that + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "(self::m:math or name(EdgeNode(., 'left', 'math'))='math')" + replace: + - T: "início da expressão" + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-previous-at-end + + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "EdgeNode(., 'left', 'math')/@id!=@id" # at edge of math + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" + then: + - T: "não é possível mover para a esquerda, início da expressão" + - pause: long + - set_variables: [SpeakExpression: false()] + +- name: move-previous-auto-zoom-up-one-level + # Last child or in auto-zoom'd in-- move up a level and try again + # Note: we've already checked the for the case where we are at an edge and should not AutoZoomOut + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "( not(preceding-sibling::*) or" + - " ( $NavMode='Enhanced' and " + - " count(preceding-sibling::*)=1 and (IsBracketed(.., '(', ')') or IsBracketed(.., '[', ']'))" + - " )" + - ")" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: "mover"] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MovePrevious'"] + replace: + - test: + if: "preceding-sibling::*" + then: + - with: + variables: [Move2D: "'em'", Child2D: "."] + replace: [x: ".."] + else: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - test: + if: "preceding-sibling::*" + then: + - x: .. # move out of parens + else: + - x: ".." + +- name: move-previous-auto-zoom-parens + # auto-zoom into next child if next child is parenthesized expr + # auto-zoom into previous child if previous child is parenthesized expr + # Note: there is an asymmetry here from MoveNext because the base of a scripted might have parens for grouping, but not true for the script + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "$NavMode='Enhanced' and" + - "preceding-sibling::* and" + - "(parent::m:mrow or parent::m:msub or parent::m:msup or" + - " (count(preceding-sibling::*)=1 and (parent::m:msubsup or parent::m:mmultiscripts))" # make sure moving into base + - ") and" + - "preceding-sibling::*[1][self::m:mrow and count(*)=3 and " #exclude empty parens + - " (IsBracketed(., '(', ')') or IsBracketed(., '[', ']'))" + - " ]" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - test: + if: "not(parent::m:mrow)" + then: + - with: + variables: [Move2D: "'em'", Child2D: "preceding-sibling::*[1]"] + replace: [x: ".."] + - set_variables: [NavNode: "preceding-sibling::*[1]/*[2]/@id"] + +# normal cases for MovePrevious + +- name: move-previous-default + tag: mtd + match: "$Move2D = '' and ($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "coluna" + - x: "count(preceding-sibling::*)" + - pause: short + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: [set_variables: [NavNode: "preceding-sibling::*[1]/*[last()]/@id"]] + else: + - x: ".." # try again at the row level + +- name: move-previous-default + tag: [mtr, mlabeledtr] + match: "$Move2D = '' and ($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious')" + replace: + - test: + # can't get here with MatchCounter=0, so no need to echo command + if: "preceding-sibling::*" + then: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "linha" + - x: "count(preceding-sibling::*)" + - T: "coluna" + - x: "count(*)" + - pause: medium + - test: + if: "$NavMode = 'Character'" + then: + - with: + variables: [NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + else: + - set_variables: [NavNode: "preceding-sibling::*[1]/*[last()]/*[last()]/@id"] + else: [x: ".."] # try again for after + +- name: move-previous-locked-zoom-level + # locked zoom level + tag: "*" + match: + - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" + - "$ReadZoomLevel>=0" + replace: + - test: + # if moving into base (nothing before), we must be moving to the base, so "in" will be said + if: "count(preceding-sibling::*) > 2 and preceding-sibling::*[1][name(.)='none']" + then: + - with: + variables: [Move2D: "'fora de'", Child2D: "."] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: "preceding-sibling::*[1]"] # skip over 'none' + else: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - with: + variables: [Move2D: "'em'", Child2D: "preceding-sibling::*[1]"] + replace: [x: ".."] + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MovePreviousZoom'"] + replace: [x: "preceding-sibling::*[1]"] + +- name: move-previous-default + tag: "*" + match: "$NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious'" + replace: + - test: + if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'MovePrevious'" + then: [T: mover] + - else_if: "$NavCommand = 'ReadPrevious'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "esquerda" + - pause: short + - test: + if: "IsNode(.., '2D')" + then: + - with: + variables: [Move2D: "'em'", Child2D: "preceding-sibling::*[1]"] + replace: [x: ".."] + - set_variables: [NavNode: "preceding-sibling::*[1]/@id"] + +# ********* ReadZoomLevel toggle *************** +# These set ::NavMode + +- name: toggle-mode-up + + + tag: "*" + match: "$NavCommand = 'ToggleZoomLockUp'" + replace: + - test: + - if: "$NavMode = 'Enhanced'" + then: + - T: "caractere" + - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] + - else_if: "$NavMode = 'Character'" + then: + - T: "simples" + - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] + - else: + - T: "avançado" + - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] + - T: "modo" + - pause: long + - test: + - if: "$NavMode != 'Enhanced'" # potentially need to zoom to the sibling + then: + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNextZoom'"] + replace: [x: "."] + +- name: toggle-mode-down + tag: "*" + match: "$NavCommand = 'ToggleZoomLockDown'" + replace: + - test: + - if: "$NavMode = 'Enhanced'" + then: + - T: "simples" + - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] + - else_if: "$NavMode = 'Character'" + then: + - T: "avançado" + - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] + - else: + - T: "caractere" + - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] + - T: "modo" + - pause: long + - test: + - if: "$NavMode != 'Enhanced'" # potentially need to zoom to the sibling + then: + - with: + variables: [MatchCounter: "$MatchCounter + 1", NavCommand: "'MoveNextZoom'"] + replace: [x: "."] + +- name: toggle-speech-describe + tag: "*" + match: "$NavCommand = 'ToggleSpeakMode'" + replace: + - test: + if: "$Overview = 'true'" + then: + - T: "falar a expressão após mover" + - set_variables: [Overview: "'false'"] + else: + - T: "resumo da expressão após mover" + - set_variables: [Overview: "'true'"] + - pause: long + +- name: current + tag: "*" + match: "$NavCommand = 'ReadCurrent' or $NavCommand = 'DescribeCurrent'" + replace: + - test: + if: "$NavVerbosity = 'Verbose'" + then: + - test: + - if: "$NavCommand = 'ReadCurrent'" + then: [T: "ler"] + else: [T: "descrever"] + - T: "atual" + - set_variables: [NavNode: "@id"] + - pause: long + +# this needs to be near the end because we only test for 'Describe', "Read", etc., and we don't want to get 'DescribeNext', etc. +- name: placemarker + + tag: "*" + match: + - "starts-with($NavCommand, 'Read') or " + - "starts-with($NavCommand, 'Describe') or " + - "starts-with($NavCommand, 'MoveTo')" + replace: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - test: + - if: "starts-with($NavCommand, 'Read')" + then: [T: "ler"] + - else_if: "starts-with($NavCommand, 'Describe')" + then: [T: "descrever"] + - else_if: "starts-with($NavCommand, 'MoveTo')" + then: [T: "mover para"] + else: [T: "definir"] + - T: "marcador de posição" + - x: "$PlaceMarkerIndex" + - pause: long + - set_variables: [NavNode: "$PlaceMarker"] + +- name: set-placemarker + tag: "*" + match: "starts-with($NavCommand, 'SetPlacemarker')" + replace: + - test: + if: "$NavVerbosity != 'Terse'" + then: + - T: "inserir marcador de posição" + - x: "$PlaceMarkerIndex" + - pause: long + - set_variables: [NavNode: "@id"] + +# ********* WhereAmI *************** + +# FIX: WhereAmI needs support from the Rust code to loop around and do speech at each iteration. +# Alternatively, it could insert a special token that Rust code does a "replace" on with the speech (e.g. SPEECH_AT{id}) +# or a new command "speak" which takes a node id +- name: where-am-i-start + + + tag: "*" + match: "($NavCommand = 'WhereAmI' or $NavCommand = 'WhereAmIAll') and $MatchCounter = 0" + replace: + - translate: "@id" + - pause: long + - with: + variables: [MatchCounter: "$MatchCounter + 1"] + replace: [x: ".."] + +- name: where-am-i-stop + tag: "*" + match: + - "($NavCommand = 'WhereAmI' or $NavCommand = 'WhereAmIAll') and $MatchCounter > 0 and" + # stopping conditions + - "(self::m:math or " + - " parent::*[self::m:math and (count(*)=1 or (count(*)=2 and *[2][.=',' or .='.' or .=';' or .='?']) ) ] " + - ")" + replace: + - test: + if: "$NavCommand = 'WhereAmI'" + then: + - T: "não há mais nada dentro" + - pause: long + - set_variables: [SpeakExpression: false()] + else: + - T: "interior" + - pause: medium + - set_variables: [NavNode: "@id"] + +- name: where-am-i-middle + tag: "*" + match: "$NavCommand = 'WhereAmI' or $NavCommand = 'WhereAmIAll'" + replace: + - T: "interior" + - pause: medium + - test: + - if: "$NavMode='Enhanced' and parent::*[self::m:mrow and IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false)]" + then: [x: ".."] # auto-zoom up + - else_if: "$NavCommand = 'WhereAmI'" + then: [set_variables: [NavNode: "@id"]] + else: + - translate: "@id" + - pause: long + - x: '..' diff --git a/Rules/Languages/pt/overview.yaml b/Rules/Languages/pt/overview.yaml new file mode 100644 index 000000000..f28a44564 --- /dev/null +++ b/Rules/Languages/pt/overview.yaml @@ -0,0 +1,119 @@ +--- +# 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: [fraction, mfrac] + match: "." + replace: + - test: + if: "IsNode(*[1], 'simple') and IsNode(*[2], 'simple')" + then: + - x: "*[1]" + - T: "sobre" + - x: "*[2]" + else: + - T: "fração" + +- name: overview-default + tag: [msqrt, "square-root"] # CORREÇÃO: idem + match: "." + replace: + - T: "raiz quadrada" + - test: + if: "IsNode(*[1], 'simple')" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: de] + - x: "*[1]" + +- name: overview-default + tag: [mroot, root] # CORREÇÃO: idem + match: "." + replace: + - test: + if: "*[2][self::m:mn]" + then_test: + - if: "*[2][.='2']" + then: [T: raiz quadrada] + - else_if: "*[2][.='3']" + then: [T: raiz cúbica] + - else_if: "*[2][not(contains(., '.'))]" + then: [T: raiz, T: de índice, x: "*[2]"] + else: + # índice simbólico (ex.: raiz de índice n) — em português a ordem natural + # é "raiz de índice n", diferente do inglês "n-th root". + - T: raiz + - T: de índice + - x: "*[2]" + - test: + if: "IsNode(*[1], 'simple')" + then: + - test: + if: "$Verbosity!='Terse'" + then: [T: de] + - x: "*[1]" + +- name: matrix-override + tag: mrow + match: + - "*[2][self::m:mtable] and" + - "(IsBracketed(., '(', ')') or IsBracketed(., '[', ']') or IsBracketed(., '|', '|'))" + replace: + # CORREÇÃO: a ordem herdada do inglês ("the 2 by 3 matrix") produzia + # "a 2 por 3 matriz". Em português o substantivo vem antes da dimensão. + - test: + if: "*[1][.='|']" # just need to check the first bracket since we know it must be (, [, or | + then: [T: determinante] + else: [T: matriz] + - x: count(*[2]/*) + - T: por + - x: count(*[2]/*[self::m:mtr][1]/*) + +- name: overview-default + tag: mtable + match: "." + replace: + # CORREÇÃO: mesma inversão de ordem do bloco acima. + - T: "tabela" + - x: count(*[2]/*) + - T: por + - x: count(*[2]/*[self::m:mtr][1]/*) + +- name: short-mrow + tag: mrow + match: "count(*)<6" + replace: + - insert: + nodes: "*" + replace: [pause: auto] + +- name: long-mrow + tag: mrow + match: "." + replace: + - x: "*[1]" + - pause: auto + - x: "*[2]" + - pause: auto + - x: "*[3]" + - pause: auto + - x: "*[4]" + - pause: auto + - x: "*[5]" + - pause: auto + - T: "etc." + +- include: "SimpleSpeak_Rules.yaml" diff --git a/Rules/Languages/pt/unicode-full.yaml b/Rules/Languages/pt/unicode-full.yaml new file mode 100644 index 000000000..21a1e0b71 --- /dev/null +++ b/Rules/Languages/pt/unicode-full.yaml @@ -0,0 +1,3431 @@ + + - "˘": [T: "breve"] # 0x2d8 + - "˚": [T: "anel acima"] # 0x2da + - "˛": [T: "ogonek"] # 0x2db + - "˜": [T: "til pequeno"] # 0x2dc + - "˝": [T: "acento agudo duplo"] # 0x2dd + - "↔": [T: "seta para a esquerda e para a direita"] # 0x2194 + - "↕": [T: "seta para cima e para baixo"] # 0x2195 + - "↖": [T: "seta para noroeste"] # 0x2196 + - "↙": [T: "seta para sudoeste"] # 0x2199 + - "↚": [T: "seta para a esquerda com traço"] # 0x219a + - "↛": [T: "seta para a direita com traço"] # 0x219b + - "↜": [T: "seta ondulada para a esquerda"] # 0x219c + - "↝": [T: "seta ondulada para a direita"] # 0x219d + - "↞": [T: "seta de duas pontas para a esquerda"] # 0x219e + - "↟": [T: "seta de duas pontas para cima"] # 0x219f + - "↠": [T: "seta de duas pontas para a direita"] # 0x21a0 + - "↡": [T: "seta de duas pontas para baixo"] # 0x21a1 + - "↢": [T: "seta para a esquerda com cauda"] # 0x21a2 + - "↣": [T: "seta para a direita com cauda"] # 0x21a3 + - "↤": [T: "seta para a esquerda a partir de barra"] # 0x21a4 + - "↥": [T: "seta para cima a partir de barra"] # 0x21a5 + - "↦": [T: "seta para a direita a partir de barra"] # 0x21a6 + - "↧": [T: "seta para baixo a partir de barra"] # 0x21a7 + - "↨": [T: "seta para cima e para baixo com base"] # 0x21a8 + - "↩": [T: "seta para a esquerda com gancho"] # 0x21a9 + - "↪": [T: "seta para a direita com gancho"] # 0x21aa + - "↫": [T: "seta para a esquerda com laço"] # 0x21ab + - "↬": [T: "seta para a direita com laço"] # 0x21ac + - "↭": [T: "seta ondulada para a esquerda e para a direita"] # 0x21ad + - "↮": [T: "seta para a esquerda e para a direita com traço"] # 0x21ae + - "↯": [T: "seta em zigue-zague para baixo"] # 0x21af + - "↰": [T: "seta para cima com ponta para a esquerda"] # 0x21b0 + - "↱": [T: "seta para cima com ponta para a direita"] # 0x21b1 + - "↲": [T: "seta para baixo com ponta para a esquerda"] # 0x21b2 + - "↳": [T: "seta para baixo com ponta para a direita"] # 0x21b3 + - "↴": [T: "seta para a direita com canto para baixo"] # 0x21b4 + - "↵": [T: "seta para baixo com canto para a esquerda"] # 0x21b5 + - "↶": [T: "seta semicircular superior no sentido anti-horário"] # 0x21b6 + - "↷": [T: "seta semicircular superior no sentido horário"] # 0x21b7 + - "↸": [T: "seta para noroeste até barra longa"] # 0x21b8 + - "↹": [T: "seta para a esquerda até barra sobre seta para a direita até barra"] # 0x21b9 + - "↺": [T: "seta circular aberta no sentido anti-horário"] # 0x21ba + - "↻": [T: "seta circular aberta no sentido horário"] # 0x21bb + - "↼": [T: "arpão para a esquerda com farpa para cima"] # 0x21bc + - "↽": [T: "arpão para a esquerda com farpa para baixo"] # 0x21bd + - "↾": [T: "arpão para cima com farpa para a direita"] # 0x21be + - "↿": [T: "arpão para cima com farpa para a esquerda"] # 0x21bf + - "⇀": [T: "arpão para a direita com farpa para cima"] # 0x21c0 + - "⇁": [T: "arpão para a direita com farpa para baixo"] # 0x21c1 + - "⇂": [T: "arpão para baixo com farpa para a direita"] # 0x21c2 + - "⇃": [T: "arpão para baixo com farpa para a esquerda"] # 0x21c3 + - "⇄": [T: "seta para a direita sobre seta para a esquerda"] # 0x21c4 + - "⇅": [T: "seta para cima à esquerda de seta para baixo"] # 0x21c5 + - "⇆": [T: "seta para a esquerda sobre seta para a direita"] # 0x21c6 + - "⇇": [T: "duas setas para a esquerda"] # 0x21c7 + - "⇈": [T: "duas setas para cima"] # 0x21c8 + - "⇉": [T: "duas setas para a direita"] # 0x21c9 + - "⇊": [T: "duas setas para baixo"] # 0x21ca + - "⇋": [T: "arpão para a esquerda sobre arpão para a direita"] # 0x21cb + - "⇌": [T: "arpão para a direita sobre arpão para a esquerda"] # 0x21cc + - "⇍": [T: "seta dupla para a esquerda com traço"] # 0x21cd + - "⇎": [T: "seta dupla para a esquerda e para a direita com traço"] # 0x21ce + - "⇏": [T: "seta dupla para a direita com traço"] # 0x21cf + - "⇐": [T: "seta dupla para a esquerda"] # 0x21d0 + - "⇑": [T: "seta dupla para cima"] # 0x21d1 + - "⇓": [T: "seta dupla para baixo"] # 0x21d3 + - "⇔": [T: "se e somente se"] # 0x21d4 + - "⇕": [T: "seta dupla para cima e para baixo"] # 0x21d5 + - "⇖": [T: "seta dupla para noroeste"] # 0x21d6 + - "⇗": [T: "seta dupla para nordeste"] # 0x21d7 + - "⇘": [T: "seta dupla para sudeste"] # 0x21d8 + - "⇙": [T: "seta dupla para sudoeste"] # 0x21d9 + - "⇚": [T: "seta tripla para a esquerda"] # 0x21da + - "⇛": [T: "seta tripla para a direita"] # 0x21db + - "⇜": [T: "seta serpenteante para a esquerda"] # 0x21dc + - "⇝": [T: "seta serpenteante para a direita"] # 0x21dd + - "⇞": [T: "seta para cima com traço duplo"] # 0x21de + - "⇟": [T: "seta para baixo com traço duplo"] # 0x21df + - "⇠": [T: "seta tracejada para a esquerda"] # 0x21e0 + - "⇡": [T: "seta tracejada para cima"] # 0x21e1 + - "⇢": [T: "seta tracejada para a direita"] # 0x21e2 + - "⇣": [T: "seta tracejada para baixo"] # 0x21e3 + - "⇤": [T: "seta para a esquerda até barra"] # 0x21e4 + - "⇥": [T: "seta para a direita até barra"] # 0x21e5 + - "⇦": [T: "seta vazada para a esquerda"] # 0x21e6 + - "⇧": [T: "seta vazada para cima"] # 0x21e7 + - "⇨": [T: "seta vazada para a direita"] # 0x21e8 + - "⇩": [T: "seta vazada para baixo"] # 0x21e9 + - "⇪": [T: "seta vazada para cima a partir de barra"] # 0x21ea + - "⇫": [T: "seta vazada para cima sobre pedestal"] # 0x21eb + - "⇬": [T: "seta vazada para cima sobre pedestal com barra horizontal"] # 0x21ec + - "⇭": [T: "seta vazada para cima sobre pedestal com barra vertical"] # 0x21ed + - "⇮": [T: "seta vazada dupla para cima"] # 0x21ee + - "⇯": [T: "seta vazada dupla para cima sobre pedestal"] # 0x21ef + - "⇰": [T: "seta vazada para a direita a partir de parede"] # 0x21f0 + - "⇱": [T: "seta para noroeste até o canto"] # 0x21f1 + - "⇲": [T: "seta para sudeste até o canto"] # 0x21f2 + - "⇳": [T: "seta vazada para cima e para baixo"] # 0x21f3 + - "⇴": [T: "seta para a direita com círculo pequeno"] # 0x21f4 + - "⇵": [T: "seta para baixo à esquerda de seta para cima"] # 0x21f5 + - "⇶": [T: "três setas para a direita"] # 0x21f6 + - "⇷": [T: "seta para a esquerda com traço vertical"] # 0x21f7 + - "⇸": [T: "seta para a direita com traço vertical"] # 0x21f8 + - "⇹": [T: "seta para a esquerda e para a direita com traço vertical"] # 0x21f9 + - "⇺": [T: "seta para a esquerda com traço vertical duplo"] # 0x21fa + - "⇻": [T: "seta para a direita com traço vertical duplo"] # 0x21fb + - "⇼": [T: "seta para a esquerda e para a direita com traço vertical duplo"] # 0x21fc + - "⇽": [T: "seta de ponta aberta para a esquerda"] # 0x21fd + - "⇾": [T: "seta de ponta aberta para a direita"] # 0x21fe + - "⇿": [T: "seta vazada para a esquerda e para a direita"] # 0x21ff + - "∀": [T: "para todo"] # 0x2200 + - "∁": # 0x2201 + - test: + if: "$Verbosity!='Terse'" + then: [OT: "o"] + - T: "complemento de" + - "∃": [T: "existe"] # 0x2203 + - "∄": [T: "não existe"] # 0x2204 + - "∅": [T: "conjunto vazio"] # 0x2205 + - "∇": [T: "nabla"] # 0x2207 + - "∋": [T: "contém o elemento"] # 0x220b + - "∌": [T: "não contém o elemento"] # 0x220c + - "∍": [T: "contém o elemento"] # 0x220d + - "∎": [T: "fim da demonstração"] # 0x220e + - "∏": [T: "produtório"] # 0x220f + - "∑": [T: "somatório"] # 0x2211 + - "−": [T: "menos"] # 0x2212 + - "∓": [T: "menos ou mais"] # 0x2213 + - "∔": [T: "mais com ponto"] # 0x2214 + - "∕": [T: "dividido por"] # 0x2215 + - "∖": [T: "diferença de conjuntos"] # 0x2216 + - "∗": [T: "vezes"] # 0x2217 + - "∙": # 0x2219 + - test: + if: "@data-chem-formula-op" + then: [T: "ponto"] + else: [T: "vezes"] + - "∛": # 0x221b + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "raiz cúbica de" + - "∜": # 0x221c + - test: + if: "$Verbosity!='Terse'" + then: [OT: "a"] + - T: "raiz quarta de" + - "∞": [T: "infinito"] # 0x221e + - "∟": [T: "ângulo reto"] # 0x221f + - "∠": [T: "ângulo"] # 0x2220 + - "∡": [T: "ângulo medido"] # 0x2221 + - "∢": [T: "ângulo esférico"] # 0x2222 + - "∧": [T: "e"] # 0x2227 + - "∨": [T: "ou"] # 0x2228 + - "∩": [T: "interseção"] # 0x2229 + - "∪": [T: "união"] # 0x222a + - "∫": [T: "integral"] # 0x222b + - "∬": [T: "integral dupla"] # 0x222c + - "∭": [T: "integral tripla"] # 0x222d + - "∮": [T: "integral de contorno"] # 0x222e + - "∯": [T: "integral de superfície"] # 0x222f + - "∰": [T: "integral de volume"] # 0x2230 + - "∱": [T: "integral no sentido horário"] # 0x2231 + - "∲": [T: "integral de contorno no sentido horário"] # 0x2232 + - "∳": [T: "integral de contorno no sentido anti-horário"] # 0x2233 + - "∴": [T: "portanto"] # 0x2234 + - "∵": [T: "porque"] # 0x2235 + - "∸": [T: "menos com ponto"] # 0x2238 + - "∹": [T: "tem excesso em relação a"] # 0x2239 + - "∺": # 0x223a + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "geometricamente proporcional a" + - "∻": # 0x223b + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "homotético a" + - "≀": [T: "produto coroa"] # 0x2240 + - "≁": [T: "não é semelhante a"] # 0x2241 + - "≂": [T: "menos til"] # 0x2242 + - "≃": # 0x2243 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "assintoticamente igual a" + - "≄": # 0x2244 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é assintoticamente igual a" + - "≅": # 0x2245 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "congruente a" + - "≆": # 0x2246 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "aproximadamente mas não realmente igual a" + - "≇": # 0x2247 + + - T: "não é congruente a" + - "≈": # 0x2248 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "aproximadamente igual a" + - "≉": # 0x2249 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é aproximadamente igual a" + - "≊": # 0x224a + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "aproximadamente igual ou igual a" + - "≋": [T: "til triplo"] # 0x224b + - "≌": [T: "são todos iguais a"] # 0x224c + - "≍": # 0x224d + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "equivalente a" + - "≎": # 0x224e + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "geometricamente equivalente a" + - "≏": # 0x224f + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "a diferença entre" + - "≐": [T: "aproxima-se do limite"] # 0x2250 + - "≑": # 0x2251 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "geometricamente igual a" + - "≒": # 0x2252 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "aproximadamente igual ou a imagem de" + - "≓": # 0x2253 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "a imagem de ou aproximadamente igual a" + - "≔": [T: "dois pontos igual"] # 0x2254 + - "≕": [T: "igual dois pontos"] # 0x2255 + - "≖": [T: "igual com anel"] # 0x2256 + - "≗": # 0x2257 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual por definição a" + - "≘": [T: "corresponde a"] # 0x2258 + - "≙": [T: "estima"] # 0x2259 + - "≚": # 0x225a + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "equiangular a" # era "igual e inclinado a" (descrição do glifo); en: 'is equiangular to' + - "≛": [T: "igual com estrela"] # 0x225b + - "≜": [T: "igual delta"] # 0x225c + - "≝": [T: "é definido como"] # 0x225d + - "≞": # 0x225e + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "medido por" # era "igual por medida a" (descrição); en: 'is measured by' + - "≟": [T: "tem relação desconhecida com"] # 0x225f + - "≢": # 0x2262 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é idêntico a" + - "≣": # 0x2263 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "estritamente equivalente a" + - "≨": # 0x2268 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor que mas não igual a" + - "≩": # 0x2269 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior que mas não igual a" + - "≬": # 0x226c + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "entre" + - "≭": # 0x226d + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é equivalente a" + - "≮": # 0x226e + # audit-ignore: em português a negação já é frase completa; o "é" do + # inglês (is not less than) não tem par que valha suprimir no Terse + - T: "não é menor que" + - "≯": # 0x226f + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é maior que" + - "≰": # 0x2270 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é menor nem igual a" + - "≱": # 0x2271 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é maior nem igual a" + - "≲": # 0x2272 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor ou equivalente a" + - "≳": # 0x2273 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior ou equivalente a" + - "≴": # 0x2274 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é menor nem equivalente a" + - "≵": # 0x2275 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é maior nem equivalente a" + - "≶": # 0x2276 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor ou maior que" + - "≷": # 0x2277 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior ou menor que" + - "≸": # 0x2278 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "nem menor nem maior que" + - "≹": # 0x2279 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "nem maior nem menor que" + - "≺": [T: "precede"] # 0x227a + - "≻": [T: "sucede"] # 0x227b + - "≼": [T: "precede ou é igual a"] # 0x227c + - "≽": [T: "sucede ou é igual a"] # 0x227d + - "≾": [T: "precede ou é equivalente a"] # 0x227e + - "≿": [T: "sucede ou é equivalente a"] # 0x227f + - "⊀": [T: "não precede"] # 0x2280 + - "⊁": [T: "não sucede"] # 0x2281 + - "⊈": # 0x2288 + # audit-ignore: negação já é frase completa; com o ramo "é" saía + # "é não está contido em nem é igual a". Igual a ≢, ≇ e ∦. + - T: "não está contido em nem é igual a" + - "⊉": # 0x2289 + # audit-ignore: idem ⊈ — saía "é não contém nem é igual a". + - T: "não contém nem é igual a" + - "⊊": [T: "está contido em mas não é igual a"] # 0x228a + - "⊋": [T: "contém mas não é igual a"] # 0x228b + - "⊌": [T: "multiconjunto"] # 0x228c + - "⊍": [T: "multiplicação de multiconjunto"] # 0x228d + - "⊎": [T: "união de multiconjunto"] # 0x228e + - "⊏": [T: "imagem quadrada de"] # 0x228f + - "⊐": [T: "original quadrado de"] # 0x2290 + - "⊑": [T: "imagem quadrada de ou igual a"] # 0x2291 + - "⊒": [T: "original quadrado de ou igual a"] # 0x2292 + - "⊓": [T: "interseção quadrada"] # 0x2293 + - "⊔": [T: "união quadrada"] # 0x2294 + - "⊕": [T: "mais circulado"] # 0x2295 + - "⊖": [T: "menos circulado"] # 0x2296 + - "⊗": [T: "vezes circulado"] # 0x2297 + - "⊘": [T: "barra circulada"] # 0x2298 + - "⊙": [T: "ponto circulado"] # 0x2299 + - "⊚": [T: "anel circulado"] # 0x229a + - "⊛": [T: "asterisco circulado"] # 0x229b + - "⊜": [T: "igual circulado"] # 0x229c + - "⊝": [T: "traço circulado"] # 0x229d + - "⊞": [T: "mais enquadrado"] # 0x229e + - "⊟": [T: "menos enquadrado"] # 0x229f + - "⊠": [T: "vezes enquadrado"] # 0x22a0 + - "⊡": [T: "ponto enquadrado"] # 0x22a1 + - "⊢": [T: "demonstra"] # 0x22a2 + - "⊣": [T: "não produz"] # 0x22a3 + - "⊤": [T: "topo"] # 0x22a4 + - "⊦": [T: "reduz a"] # 0x22a6 + - "⊧": [T: "modela"] # 0x22a7 + - "⊨": # 0x22a8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "verdadeiro" + - "⊩": [T: "força"] # 0x22a9 + - "⊪": [T: "barra vertical tripla com catraca à direita"] # 0x22aa + - "⊫": [T: "barra vertical dupla com catraca dupla à direita"] # 0x22ab + - "⊬": [T: "não demonstra"] # 0x22ac + - "⊭": # 0x22ad + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é verdadeiro" + - "⊮": [T: "não força"] # 0x22ae + - "⊯": [T: "barra vertical dupla com catraca dupla à direita negada"] # 0x22af + - "⊰": [T: "precede sob relação"] # 0x22b0 + - "⊱": [T: "sucede sob relação"] # 0x22b1 + - "⊲": # 0x22b2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "subgrupo normal de" + - "⊳": [T: "contém como subgrupo normal"] # 0x22b3 + - "⊴": # 0x22b4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "subgrupo normal de ou igual a" + - "⊵": [T: "contém como subgrupo normal ou é igual a"] # 0x22b5 + - "⊶": # 0x22b6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "imagem original" + - "⊷": # 0x22b7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "imagem" + - "⊸": [T: "multimapa"] # 0x22b8 + - "⊹": [T: "matriz conjugada hermitiana"] # 0x22b9 + - "⊺": [T: "intercala"] # 0x22ba + - "⊻": [T: "ou exclusivo"] # 0x22bb + - "⊼": [T: "não-e"] # 0x22bc + - "⊽": [T: "não-ou"] # 0x22bd + - "⊾": [T: "ângulo reto com arco"] # 0x22be + - "⊿": [T: "triângulo retângulo"] # 0x22bf + - "⋀": [T: "e lógico"] # 0x22c0 + - "⋁": [T: "ou lógico"] # 0x22c1 + - "⋂": [T: "interseção"] # 0x22c2 + - "⋃": [T: "união"] # 0x22c3 + - "⋄": [T: "operador losango"] # 0x22c4 + - "⋅": # 0x22c5 + - test: + if: "@data-chem-formula-op" + then: [T: "ponto"] + else: [T: "vezes"] + - "⋆": [T: "vezes"] # 0x22c6 + - "⋇": [T: "divisão vezes"] # 0x22c7 + - "⋈": [T: "junção"] # 0x22c8 + - "⋉": # 0x22c9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "produto semidireto à esquerda" + - "⋊": # 0x22ca + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "produto semidireto à direita" + - "⋋": # 0x22cb + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "junção semidireta à esquerda" + - "⋌": # 0x22cc + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "junção semidireta à direita" + - "⋍": [T: "til invertido igual"] # 0x22cd + - "⋎": [T: "ou lógico ondulado"] # 0x22ce + - "⋏": [T: "e lógico ondulado"] # 0x22cf + - "⋐": # 0x22d0 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "contido de forma fechada em" + - "⋑": # 0x22d1 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "contém de forma fechada" + - "⋒": # 0x22d2 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "interseção dupla" + - "⋓": # 0x22d3 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "união dupla" + - "⋔": # 0x22d4 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "transversal a" + - "⋕": # 0x22d5 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual e paralelo a" # era "paralelo forquilhado a" (descreve a forquilha); en: 'is equal to and parallel to' + - "⋖": [T: "menor que com ponto"] # 0x22d6 + - "⋗": [T: "maior que com ponto"] # 0x22d7 + - "⋘": # 0x22d8 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "muito menor que" + - "⋙": # 0x22d9 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "muito maior que" + - "⋚": # 0x22da + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor que, igual ou maior que" + - "⋛": # 0x22db + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior que, igual ou menor que" + - "⋜": # 0x22dc + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual ou menor que" + - "⋝": # 0x22dd + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual ou maior que" + - "⋞": # 0x22de + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual ou precede" + - "⋟": # 0x22df + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "igual ou sucede" + - "⋠": [T: "não precede nem é igual a"] # 0x22e0 + - "⋡": [T: "não sucede nem é igual a"] # 0x22e1 + - "⋢": [T: "não é imagem quadrada de nem igual a"] # 0x22e2 + - "⋣": [T: "não é original quadrado de nem igual a"] # 0x22e3 + - "⋤": [T: "imagem quadrada de ou não igual a"] # 0x22e4 + - "⋥": [T: "original quadrado de ou não igual a"] # 0x22e5 + - "⋦": # 0x22e6 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "menor mas não equivalente a" + - "⋧": # 0x22e7 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "maior mas não equivalente a" + - "⋨": [T: "precede mas não é equivalente a"] # 0x22e8 + - "⋩": [T: "sucede mas não é equivalente a"] # 0x22e9 + - "⋪": # 0x22ea + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é subgrupo normal de" + - "⋫": [T: "não contém como subgrupo normal"] # 0x22eb + - "⋬": # 0x22ec + # audit-ignore: em português a negação já é frase completa; o "is" do inglês não tem par que valha suprimir no Terse + - T: "não é subgrupo normal de nem igual a" + - "⋭": [T: "não contém como subgrupo normal nem é igual a"] # 0x22ed + - "⋮": [T: "reticências verticais"] # 0x22ee + - "⋯": [T: "reticências"] # 0x22ef + - "⋰": [T: "reticências diagonais para cima"] # 0x22f0 + - "⋱": [T: "reticências diagonais"] # 0x22f1 + - "⋲": [T: "pertence a com traço horizontal longo"] # 0x22f2 + - "⋳": [T: "pertence a com barra vertical no fim do traço"] # 0x22f3 + - "⋴": [T: "pertence a com barra vertical no fim do traço"] # 0x22f4 + - "⋵": [T: "pertence a com ponto acima"] # 0x22f5 + - "⋶": [T: "pertence a com barra acima"] # 0x22f6 + - "⋷": [T: "pertence a com barra acima"] # 0x22f7 + - "⋸": [T: "pertence a com barra abaixo"] # 0x22f8 + - "⋹": [T: "pertence a com dois traços horizontais"] # 0x22f9 + - "⋺": [T: "contém com traço horizontal longo"] # 0x22fa + - "⋻": [T: "contém com barra vertical no fim do traço"] # 0x22fb + - "⋼": [T: "contém com barra vertical no fim do traço"] # 0x22fc + - "⋽": [T: "contém com barra acima"] # 0x22fd + - "⋾": [T: "contém com barra acima"] # 0x22fe + - "⋿": [T: "pertinência de multiconjunto da notação z"] # 0x22ff + - "■": [T: "quadrado preto"] # 0x25a0 + - "□": [T: "quadrado branco"] # 0x25a1 + - "▢": [T: "quadrado branco de cantos arredondados"] # 0x25a2 + - "▣": [T: "quadrado branco contendo quadrado preto pequeno"] # 0x25a3 + - "▤": [T: "quadrado com preenchimento horizontal"] # 0x25a4 + - "▥": [T: "quadrado com preenchimento vertical"] # 0x25a5 + - "▦": [T: "quadrado com hachura ortogonal"] # 0x25a6 + - "▧": [T: "quadrado com preenchimento diagonal descendente"] # 0x25a7 + - "▨": [T: "quadrado com preenchimento diagonal ascendente"] # 0x25a8 + - "▩": [T: "quadrado com hachura diagonal"] # 0x25a9 + - "▪": [T: "quadrado preto pequeno"] # 0x25aa + - "▫": [T: "quadrado branco pequeno"] # 0x25ab + - "▬": [T: "retângulo preto"] # 0x25ac + - "▭": [T: "retângulo branco"] # 0x25ad + - "▮": [T: "retângulo preto vertical"] # 0x25ae + - "▯": [T: "retângulo branco vertical"] # 0x25af + - "▰": [T: "paralelogramo preto"] # 0x25b0 + - "▱": [T: "paralelogramo branco"] # 0x25b1 + - "▲": [T: "triângulo preto apontando para cima"] # 0x25b2 + - "△": [T: "triângulo"] # 0x25b3 + - "▴": [T: "triângulo preto pequeno apontando para cima"] # 0x25b4 + - "▵": [T: "triângulo branco pequeno apontando para cima"] # 0x25b5 + - "▶": [T: "triângulo preto apontando para a direita"] # 0x25b6 + - "▷": [T: "triângulo branco apontando para a direita"] # 0x25b7 + - "▸": [T: "triângulo preto pequeno apontando para a direita"] # 0x25b8 + - "▹": [T: "triângulo branco pequeno apontando para a direita"] # 0x25b9 + - "►": [T: "ponteiro preto para a direita"] # 0x25ba + - "▻": [T: "ponteiro branco para a direita"] # 0x25bb + - "▼": [T: "triângulo preto apontando para baixo"] # 0x25bc + - "▽": [T: "triângulo branco apontando para baixo"] # 0x25bd + - "▾": [T: "triângulo preto pequeno apontando para baixo"] # 0x25be + - "▿": [T: "triângulo branco pequeno apontando para baixo"] # 0x25bf + - "◀": [T: "triângulo preto apontando para a esquerda"] # 0x25c0 + - "◁": [T: "triângulo branco apontando para a esquerda"] # 0x25c1 + - "◂": [T: "triângulo preto pequeno apontando para a esquerda"] # 0x25c2 + - "◃": [T: "triângulo branco pequeno apontando para a esquerda"] # 0x25c3 + - "◄": [T: "ponteiro preto para a esquerda"] # 0x25c4 + - "◅": [T: "ponteiro branco para a esquerda"] # 0x25c5 + - "◆": [T: "losango preto"] # 0x25c6 + - "◇": [T: "losango branco"] # 0x25c7 + - "◈": [T: "losango branco contendo losango preto pequeno"] # 0x25c8 + - "◉": [T: "olho de peixe"] # 0x25c9 + - "◊": [T: "losango"] # 0x25ca + - "○": [T: "círculo branco"] # 0x25cb + - "◌": [T: "círculo pontilhado"] # 0x25cc + - "◍": [T: "círculo com preenchimento vertical"] # 0x25cd + - "◎": [T: "alvo"] # 0x25ce + - "●": [T: "círculo preto"] # 0x25cf + - "◐": [T: "círculo com metade esquerda preta"] # 0x25d0 + - "◑": [T: "círculo com metade direita preta"] # 0x25d1 + - "◒": [T: "círculo com metade inferior preta"] # 0x25d2 + - "◓": [T: "círculo com metade superior preta"] # 0x25d3 + - "◔": [T: "círculo com quadrante superior direito preto"] # 0x25d4 + - "◕": [T: "círculo preto exceto o quadrante superior esquerdo"] # 0x25d5 + - "◖": [T: "meio círculo preto esquerdo"] # 0x25d6 + - "◗": [T: "meio círculo preto direito"] # 0x25d7 + - "◘": [T: "marcador inverso"] # 0x25d8 + - "◙": [T: "círculo branco inverso"] # 0x25d9 + - "◚": [T: "metade superior de círculo branco inverso"] # 0x25da + - "◛": [T: "metade inferior de círculo branco inverso"] # 0x25db + - "◜": [T: "arco circular do quadrante superior esquerdo"] # 0x25dc + - "◝": [T: "arco circular do quadrante superior direito"] # 0x25dd + - "◞": [T: "arco circular do quadrante inferior direito"] # 0x25de + - "◟": [T: "arco circular do quadrante inferior esquerdo"] # 0x25df + - "◠": [T: "semicírculo superior"] # 0x25e0 + - "◡": [T: "semicírculo inferior"] # 0x25e1 + - "◢": [T: "triângulo preto inferior direito"] # 0x25e2 + - "◣": [T: "triângulo preto inferior esquerdo"] # 0x25e3 + - "◤": [T: "triângulo preto superior esquerdo"] # 0x25e4 + - "◥": [T: "triângulo preto superior direito"] # 0x25e5 + - "◦": [T: "composição"] # 0x25e6 + - "◧": [T: "quadrado com metade esquerda preta"] # 0x25e7 + - "◨": [T: "quadrado com metade direita preta"] # 0x25e8 + - "◩": [T: "quadrado com metade superior esquerda preta"] # 0x25e9 + - "◪": [T: "quadrado com metade inferior direita preta"] # 0x25ea + - "◫": [T: "quadrado branco com linha divisória"] # 0x25eb + - "◬": [T: "triângulo branco apontando para cima com ponto"] # 0x25ec + - "◭": [T: "triângulo apontando para cima com metade esquerda preta"] # 0x25ed + - "◮": [T: "triângulo apontando para cima com metade direita preta"] # 0x25ee + - "◯": [T: "círculo grande"] # 0x25ef + - "◰": [T: "quadrado branco com quadrante superior esquerdo"] # 0x25f0 + - "◱": [T: "quadrado branco com quadrante inferior esquerdo"] # 0x25f1 + - "◲": [T: "quadrado branco com quadrante inferior direito"] # 0x25f2 + - "◳": [T: "quadrado branco com quadrante superior direito"] # 0x25f3 + - "◴": [T: "círculo branco com quadrante superior esquerdo"] # 0x25f4 + - "◵": [T: "círculo branco com quadrante inferior esquerdo"] # 0x25f5 + - "◶": [T: "círculo branco com quadrante inferior direito"] # 0x25f6 + - "◷": [T: "círculo branco com quadrante superior direito"] # 0x25f7 + - "◸": [T: "triângulo superior esquerdo"] # 0x25f8 + - "◹": [T: "triângulo superior direito"] # 0x25f9 + - "◺": [T: "triângulo inferior esquerdo"] # 0x25fa + - "◻": [T: "quadrado branco médio"] # 0x25fb + - "◼": [T: "quadrado preto médio"] # 0x25fc + - "◽": [T: "quadrado branco pequeno médio"] # 0x25fd + - "◾": [T: "quadrado preto pequeno médio"] # 0x25fe + - "◿": [T: "triângulo inferior direito"] # 0x25ff + + +# Ordem das palavras: ao contrário do inglês, que antepõe o estilo +# ("fraktur cap a"), o português pospõe o adjetivo ("maiúscula a vazado"). +# Por isso o `spell:` vem ANTES da palavra de estilo nos blocos de alfabeto. +# Isso segue a expectativa já registrada em tests/Languages/pt/alphabets.rs +# ("maiúscula delta vazado"). + + +# ---- Frações vulgares (0x00bc-0x00be, 0x2150-0x215f) ---- + - "¼": [T: "um quarto"] # 0x00bc + - "½": [T: "um meio"] # 0x00bd + - "¾": [T: "três quartos"] # 0x00be + - "⅐": [T: "um sétimo"] # 0x2150 + - "⅑": [T: "um nono"] # 0x2151 + - "⅒": [T: "um décimo"] # 0x2152 + - "⅓": [T: "um terço"] # 0x2153 + - "⅔": [T: "dois terços"] # 0x2154 + - "⅕": [T: "um quinto"] # 0x2155 + - "⅖": [T: "dois quintos"] # 0x2156 + - "⅗": [T: "três quintos"] # 0x2157 + - "⅘": [T: "quatro quintos"] # 0x2158 + - "⅙": [T: "um sexto"] # 0x2159 + - "⅚": [T: "cinco sextos"] # 0x215a + - "⅛": [T: "um oitavo"] # 0x215b + - "⅜": [T: "três oitavos"] # 0x215c + - "⅝": [T: "cinco oitavos"] # 0x215d + - "⅞": [T: "sete oitavos"] # 0x215e + - "⅟": [T: "um sobre"] # 0x215f + +# ---- Sobrescritos e subscritos (0x2070-0x209f) ---- + - "⁰": [T: "elevado a zero"] # 0x2070 + - "ⁱ": [T: "elevado a i"] # 0x2071 + - "⁴": [T: "elevado à quarta potência"] # 0x2074 + - "⁵": [T: "elevado à quinta potência"] # 0x2075 + - "⁶": [T: "elevado à sexta potência"] # 0x2076 + - "⁷": [T: "elevado à sétima potência"] # 0x2077 + - "⁸": [T: "elevado à oitava potência"] # 0x2078 + - "⁹": [T: "elevado à nona potência"] # 0x2079 + - "⁺": [T: "sinal de mais sobrescrito"] # 0x207a + - "⁻": [T: "menos sobrescrito"] # 0x207b + - "⁼": [T: "sinal de igual sobrescrito"] # 0x207c + - "⁽": [T: "abre parênteses sobrescrito"] # 0x207d + - "⁾": [T: "fecha parênteses sobrescrito"] # 0x207e + - "ⁿ": [T: "elevado à enésima potência"] # 0x207f + - "₀": [T: "subscrito zero"] # 0x2080 + - "₁": [T: "subscrito um"] # 0x2081 + - "₂": [T: "subscrito dois"] # 0x2082 + - "₃": [T: "subscrito três"] # 0x2083 + - "₄": [T: "subscrito quatro"] # 0x2084 + - "₅": [T: "subscrito cinco"] # 0x2085 + - "₆": [T: "subscrito seis"] # 0x2086 + - "₇": [T: "subscrito sete"] # 0x2087 + - "₈": [T: "subscrito oito"] # 0x2088 + - "₉": [T: "subscrito nove"] # 0x2089 + - "₊": [T: "sinal de mais subscrito"] # 0x208a + - "₋": [T: "sinal de menos subscrito"] # 0x208b + - "₌": [T: "sinal de igual subscrito"] # 0x208c + - "₍": [T: "abre parênteses subscrito"] # 0x208d + - "₎": [T: "fecha parênteses subscrito"] # 0x208e + - "ₐ": [T: "subscrito A"] # 0x2090 + - "ₑ": [T: "subscrito E"] # 0x2091 + - "ₒ": [T: "subscrito O"] # 0x2092 + - "ₓ": [T: "subscrito X"] # 0x2093 + - "ₕ": [T: "subscrito H"] # 0x2095 + - "ₖ": [T: "subscrito K"] # 0x2096 + - "ₗ": [T: "subscrito L"] # 0x2097 + - "ₘ": [T: "subscrito M"] # 0x2098 + - "ₙ": [T: "subscrito N"] # 0x2099 + - "ₚ": [T: "subscrito P"] # 0x209a + - "ₛ": [T: "subscrito S"] # 0x209b + - "ₜ": [T: "subscrito T"] # 0x209c + +# ---- Numerais romanos (0x2160-0x217f) ---- + + - "Ⅰ": [T: "um"] # 0x2160 (valor 1) + - "Ⅱ": [T: "dois"] # 0x2161 (valor 2) + - "Ⅲ": [T: "três"] # 0x2162 (valor 3) + - "Ⅳ": [T: "quatro"] # 0x2163 (valor 4) + - "Ⅴ": [T: "cinco"] # 0x2164 (valor 5) + - "Ⅵ": [T: "seis"] # 0x2165 (valor 6) + - "Ⅶ": [T: "sete"] # 0x2166 (valor 7) + - "Ⅷ": [T: "oito"] # 0x2167 (valor 8) + - "Ⅸ": [T: "nove"] # 0x2168 (valor 9) + - "Ⅹ": [T: "dez"] # 0x2169 (valor 10) + - "Ⅺ": [T: "onze"] # 0x216a (valor 11) + - "Ⅻ": [T: "doze"] # 0x216b (valor 12) + - "Ⅼ": [T: "cinquenta"] # 0x216c (valor 50) + - "Ⅽ": [T: "cem"] # 0x216d (valor 100) + - "Ⅾ": [T: "quinhentos"] # 0x216e (valor 500) + - "Ⅿ": [T: "mil"] # 0x216f (valor 1000) + - "ⅰ": [T: "um"] # 0x2170 (valor 1) + - "ⅱ": [T: "dois"] # 0x2171 (valor 2) + - "ⅲ": [T: "três"] # 0x2172 (valor 3) + - "ⅳ": [T: "quatro"] # 0x2173 (valor 4) + - "ⅴ": [T: "cinco"] # 0x2174 (valor 5) + - "ⅵ": [T: "seis"] # 0x2175 (valor 6) + - "ⅶ": [T: "sete"] # 0x2176 (valor 7) + - "ⅷ": [T: "oito"] # 0x2177 (valor 8) + - "ⅸ": [T: "nove"] # 0x2178 (valor 9) + - "ⅹ": [T: "dez"] # 0x2179 (valor 10) + - "ⅺ": [T: "onze"] # 0x217a (valor 11) + - "ⅻ": [T: "doze"] # 0x217b (valor 12) + - "ⅼ": [T: "cinquenta"] # 0x217c (valor 50) + - "ⅽ": [T: "cem"] # 0x217d (valor 100) + - "ⅾ": [T: "quinhentos"] # 0x217e (valor 500) + - "ⅿ": [T: "mil"] # 0x217f (valor 1000) + +# ---- Alfabetos matemáticos: fraktur, vazado (double-struck) e caligráfico ---- +# Símbolos avulsos do bloco "letterlike" (0x2100-0x214f). + + - "ℊ": [T: "g caligráfico"] # 0x210a + - "ℯ": [T: "e caligráfico"] # 0x212f + - "ℴ": [T: "o caligráfico"] # 0x2134 + - "ℼ": [T: "pi vazado"] # 0x213c + - "ℽ": [T: "gama vazado"] # 0x213d + - "⅀": [T: "somatório n-ário vazado"] # 0x2140 + + - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d + - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" + - t: "fraktur" + + - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f + - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" + - T: "vazado" + + - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 + - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" + - t: "caligráfico" + +# Blocos alfabéticos do plano 1 e as cópias na área de uso privado do +# MathType. Chaves e argumentos de translate() copiados byte a byte do en. + + - "𝔄-𝔜": # 0x1d504 - 0x1d51d ('z' version is reserved) + - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + - t: "fraktur" + + - "-": # 0xf000 - 0xf018 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" + - t: "fraktur" + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + - t: "fraktur" + + - "-": # 0xf01a - 0xf033 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "fraktur" + + - "𝕬-𝖅": # 0x1D56C - 0x1D585 + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "fraktur" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "-": # 0xf040 - 0xf059 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "fraktur" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + - t: "fraktur" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "-": # 0xf05a - 0xf073 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "fraktur" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "𝔸-𝕐": # 0x1d504 - 0x1d51d ('z' version is reserved) + - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "vazado" + + - "-": # 0xf080 - 0xf098 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "vazado" + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + - T: "vazado" + + - "-": # 0xf09a - 0xf0b3 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - T: "vazado" + + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + - T: "vazado" + + - "-": # 0xf0c0 - 0xf0c9 + - spell: "translate('.', '', '0123456789')" + - T: "vazado" + + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "caligráfico" + + - "-": # 0xf100 - 0xf119 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "caligráfico" + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" + - t: "caligráfico" + + - "-": # 0xf11a - 0xf133 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "caligráfico" + + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "caligráfico" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "-": # 0xf140 - 0xf159 + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - t: "caligráfico" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + - t: "caligráfico" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "-": # 0xf15a - 0xf173 + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - t: "caligráfico" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + + - "": [T: "nabla vazado"] # 0xf0ca + - "": [T: "constante de Euler vazada"] # 0xf0cb + +# ---- Rodada 9: caracteres que o corpus real (latex2mathml do ACESSÍLIA) mostrou +# saindo CRUS para o sintetizador. Prioridade pelo dano ao estudante, não pelo +# tamanho da lacuna. Ver ACHADOS 9 e TERMINOLOGIA_PT_BR.md. +# +# Letras negrito: \mathbf{x} (vetores em Álgebra Linear) e \boldsymbol{\alpha}. +# Ordem posposta (8.1): "x negrito". Grego negrito passa de novo pela tabela +# e sai com o nome da letra ("alfa negrito"). + - "𝐀-𝐙": # 0x1d400 - 0x1d419 \mathbf maiúsculas + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝐚-𝐳": # 0x1d41a - 0x1d433 \mathbf minúsculas + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝑨-𝒁": # 0x1d468 - 0x1d481 negrito itálico maiúsculas (o en também fala só "bold") + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝒂-𝒛": # 0x1d482 - 0x1d49b negrito itálico minúsculas + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 grego negrito maiúsculas + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da grego negrito minúsculas + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝜜-𝜴": # 0x1d71c - 0x1d734 grego negrito itálico maiúsculas (\boldsymbol) + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - "𝜶-𝝎": # 0x1d736 - 0x1d74e grego negrito itálico minúsculas (\boldsymbol) + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + +# Produto interno ⟨u, v⟩ e as setas longas (reações químicas, implicação). + - "⟨": [T: "abre colchete angular"] # 0x27e8 (en: 'left angle bracket') + - "⟩": [T: "fecha colchete angular"] # 0x27e9 + - "⟪": [T: "abre colchete angular duplo"] # 0x27ea + - "⟫": [T: "fecha colchete angular duplo"] # 0x27eb + - "⟵": [T: "seta longa para a esquerda"] # 0x27f5 + - "⟶": [T: "seta longa para a direita"] # 0x27f6 (em química a regra de reação fala "reage formando" antes de chegar aqui) + - "⟷": [T: "seta longa para a esquerda e para a direita"] # 0x27f7 + - "⟸": [T: "seta dupla longa para a esquerda"] # 0x27f8 + - "⟹": [T: "implica"] # 0x27f9 (en: 'implies') + - "⟺": [T: "se e somente se"] # 0x27fa (en: 'if and only if') + +# Barra sobre variável: \bar{x}, \overline{x}. O motor canonicaliza U+0304 e +# U+203E para U+00AF, então a entrada "̄" (com mácron) do unicode.yaml nunca +# era alcançada em . "x barra" é a leitura corrente (média amostral). + - "¯": # 0xaf + - test: + if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" + then: [T: "barra"] # (en: 'bar') + else: [T: "linha superior"] # (en: 'line') + +# Sinais "letterlike" que aparecem soltos (fora de unidade, onde definitions.yaml +# já resolve): a leitura é a da letra, não a do prefixo. + - "µ": [T: "mi"] # 0xb5 MICRO SIGN — como letra; "micro" só dentro de unidade + - "Ω": [T: "ômega"] # 0x2126 OHM SIGN — espaço amostral, etc. + - "℧": [T: "mho"] # 0x2127 + - "Å": [T: "angstrom"] # 0xc5 + - "Å": [T: "angstrom"] # 0x212b + + + - "¤": [T: "símbolo de moeda"] + - "¥": [T: "iene"] + - "¦": [T: "barra quebrada"] + - "§": [T: "seção"] + - "©": [T: "direitos autorais"] + - "ª": [T: "feminino ordinal indicador"] + - "«": [T: "apontando para a esquerda duplo aspas angulares"] + - "²": [T: "dois"] + - "³": [T: "três"] + - "¹": [T: "um"] + - "º": [T: "masculino ordinal indicador"] + - "¡": [T: "ponto invertido de exclamação"] + - "¶": [T: "parágrafo marca"] + - "¿": [T: "ponto invertido de interrogação"] + - "ʰ": [T: "modificador pequeno agá"] + - "ʱ": [T: "modificador pequeno agá com gancho"] + - "ʲ": [T: "modificador pequeno jota"] + - "ʳ": [T: "modificador pequeno erre"] + - "ʴ": [T: "modificador pequeno invertido erre"] + - "ʵ": [T: "modificador pequeno invertido erre com gancho"] + - "ʶ": + - spell: "translate('R', 'R', 'R')" + - T: "modificador pequeno invertido" + - "ʷ": [T: "modificador pequeno w"] + - "ʸ": [T: "modificador pequeno y"] + - "ʹ": [T: "modificador linha"] + - "ʺ": [T: "modificador duplo linha"] + - "ʻ": [T: "modificador invertido vírgula"] + - "ʼ": [T: "modificador apóstrofo"] + - "ʽ": [T: "modificador invertido vírgula"] + - "ʾ": [T: "modificador direita metade anel"] + - "ʿ": [T: "modificador esquerda metade anel"] + - "ˀ": [T: "modificador oclusiva glotal"] + - "ˁ": [T: "modificador invertido oclusiva glotal"] + - "˂": [T: "modificador esquerda ponta de seta"] + - "˃": [T: "modificador direita ponta de seta"] + - "˄": [T: "modificador cima ponta de seta"] + - "˅": [T: "modificador baixo ponta de seta"] + - "ˆ": [T: "modificador circunflexo acento"] + - "ˇ": [T: "cáron"] + - "ˈ": [T: "modificador barra vertical"] + - "ˉ": [T: "modificador mácron"] + - "ˊ": [T: "modificador agudo acento"] + - "ˋ": [T: "modificador grave acento"] + - "ˌ": [T: "modificador baixo barra vertical"] + - "ˍ": [T: "modificador baixo mácron"] + - "ˎ": [T: "modificador baixo grave acento"] + - "ˏ": [T: "modificador baixo agudo acento"] + - "ː": [T: "modificador triangular dois pontos"] + - "ˑ": [T: "modificador metade triangular dois pontos"] + - "˒": [T: "modificador centralizado direita metade anel"] + - "˓": [T: "modificador centralizado esquerda metade anel"] + - "˔": [T: "modificador cima taco"] + - "˕": [T: "modificador baixo taco"] + - "˖": [T: "modificador sinal de mais"] + - "˗": [T: "modificador sinal de menos"] + - "˞": [T: "modificador rótico gancho"] + - "˟": [T: "cruzes modificador acento"] + - "ˠ": [T: "modificador pequeno gama"] + - "ˡ": [T: "modificador pequeno l"] + - "ˢ": [T: "modificador pequeno esse"] + - "ˣ": [T: "modificador pequeno xis"] + - "ˤ": [T: "modificador pequeno invertido oclusiva glotal"] + - "˥": [T: "modificador extra-alto tom barra"] + - "˦": [T: "modificador alto tom barra"] + - "˧": [T: "modificador médio tom barra"] + - "˨": [T: "modificador baixo tom barra"] + - "˩": [T: "modificador extra-baixo tom barra"] + - "˪": [T: "modificador yin partindo tom marca"] + - "˫": [T: "modificador yang partindo tom marca"] + - "ˬ": [T: "modificador sonorização"] + - "˭": [T: "modificador não aspirado"] + - "ˮ": [T: "modificador duplo apóstrofo"] + - "˯": [T: "modificador baixo baixo ponta de seta"] + - "˰": [T: "modificador baixo cima ponta de seta"] + - "˱": [T: "modificador baixo esquerda ponta de seta"] + - "˲": [T: "modificador baixo direita ponta de seta"] + - "˳": [T: "modificador baixo anel"] + - "˴": [T: "modificador do meio grave acento"] + - "˵": [T: "modificador do meio duplo grave acento"] + - "˶": [T: "modificador do meio duplo agudo acento"] + - "˷": [T: "modificador baixo til"] + - "˸": [T: "modificador elevado dois pontos"] + - "˹": [T: "modificador início alto tom"] + - "˺": [T: "modificador fim alto tom"] + - "˻": [T: "modificador início baixo tom"] + - "˼": [T: "modificador fim baixo tom"] + - "˽": [T: "modificador prateleira"] + - "˾": [T: "modificador aberto prateleira"] + - "˿": [T: "seta modificador baixo para a esquerda"] + - "̉": [T: "gancho acima de"] + - "̊": [T: "anel acima de"] + - "̋": [T: "duplo agudo acento"] + - "̍": [T: "barra vertical acima de"] + - "̎": [T: "barra dupla vertical acima de"] + - "̏": [T: "duplo grave acento"] + - "̐": [T: "candrabindu"] + - "̑": [T: "invertido breve"] + - "̒": [T: "invertido vírgula acima de"] + - "̓": [T: "vírgula acima de"] + - "̔": [T: "invertido vírgula acima de"] + - "̕": [T: "vírgula acima de direita"] + - "̖": [T: "grave acento abaixo de"] + - "̗": [T: "agudo acento abaixo de"] + - "̘": [T: "taco abaixo de à esquerda"] + - "̙": [T: "taco abaixo de à direita"] + - "̚": [T: "ângulo acima de à esquerda"] + - "̛": [T: "chifre"] + - "̜": [T: "esquerda metade anel abaixo de"] + - "̝": [T: "taco abaixo de para cima"] + - "̞": [T: "taco abaixo de para baixo"] + - "̟": [T: "sinal de mais abaixo de"] + - "̠": [T: "sinal de menos abaixo de"] + - "̡": [T: "palatalizado gancho abaixo de"] + - "̢": [T: "retroflexo gancho abaixo de"] + - "̣": [T: "ponto abaixo de"] + - "̤": [T: "trema abaixo de"] + - "̥": [T: "anel abaixo de"] + - "̦": [T: "vírgula abaixo de"] + - "̧": [T: "cedilha"] + - "̨": [T: "ogonek"] + - "̩": [T: "barra vertical abaixo de"] + - "̪": [T: "ponte abaixo de"] + - "̫": [T: "arco invertido duplo abaixo de"] + - "̬": [T: "cáron abaixo de"] + - "̭": [T: "circunflexo acento abaixo de"] + - "̮": [T: "breve abaixo de"] + - "̯": [T: "invertido breve abaixo de"] + - "̰": [T: "til abaixo de"] + - "̱": [T: "mácron abaixo de"] + - "̲": [T: "linha baixa"] + - "̳": [T: "linha dupla baixa"] + - "̴": [T: "til sobreposto"] + - "̵": [T: "traço curto sobreposto"] + - "̶": [T: "traço longo sobreposto"] + - "̷": [T: "barra curta sobreposto"] + - "̸": [T: "barra longa sobreposto"] + - "̹": [T: "direita metade anel abaixo de"] + - "̺": [T: "ponte invertida abaixo de"] + - "̻": [T: "quadrado abaixo de"] + - "̼": [T: "gaivota abaixo de"] + - "̽": [T: "xis acima de"] + - "̾": [T: "til vertical"] + - "̿": [T: "linha dupla superior"] + - "̀": [T: "grave tom marca"] + - "́": [T: "agudo tom marca"] + - "͆": [T: "ponte acima de"] + - "ΪΫϏ": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] + - T: "com trema" + - "ϊ": [T: "iota com trema"] + - "ϋ": [T: "ípsilon com trema"] + - "ό": [T: "ômicron com tônico"] + - "ύ": [T: "ípsilon com tônico"] + - "ώ": [T: "ômega com tônico"] + - "ϐ": [T: "beta"] + - "ϑ": [T: "teta"] + - "ϒ": [T: "ípsilon com gancho"] + - "ϓ": [T: "ípsilon com agudo e gancho"] + - "ϔ": [T: "ípsilon com trema e gancho"] + - "ϗ": [T: "kai"] + - "Ϙ": [T: "maiúscula arcaico copa"] + - "ϙ": [T: "arcaico copa"] + - "А-Я": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] + - "а": [T: "a"] + - "б": [T: "ser"] + - "в": [T: "vê"] + - "г": [T: "guê"] + - "д": [T: "de"] + - "е": [T: "iê"] + - "ж": [T: "jê"] + - "з": [T: "zê"] + - "и": [T: "i"] + - "й": [T: "curto i"] + - "к": [T: "ka"] + - "л": [T: "ele"] + - "м": [T: "em"] + - "н": [T: "en"] + - "о": [T: "o"] + - "п": [T: "pê"] + - "р": [T: "erre"] + - "с": [T: "esse"] + - "т": [T: "tê"] + - "у": [T: "u"] + - "ф": [T: "efe"] + - "х": [T: "rrá"] + - "ц": [T: "tsê"] + - "ч": [T: "tchê"] + - "ш": [T: "chá"] + - "щ": [T: "chtchá"] + - "ъ": [T: "forte sinal"] + - "ы": [T: "ierí"] + - "ь": [T: "sinal suave"] + - "э": [T: "e"] + - "ю": [T: "iu"] + - "я": [T: "iá"] + - "؆": [T: "arábico-índico raiz cúbica"] + - "؇": [T: "arábico-índico raiz quarta"] + - "؈": [T: "arábico raio"] + - "‐": [T: "hífen"] + - "‑": [T: "hífen"] + - "‒": [T: "algarismo travessão"] + - "―": [T: "barra horizontal"] + - "†": [T: "adaga"] + - "‡": [T: "duplo adaga"] + - " - ": [t: " "] # RECUO-EN + - "•": + - test: + if: "@data-chem-formula-op" + then: [T: "ponto"] + else: [T: "marcador"] + - "‰": [T: "por mil"] + - "‱": [T: "por dez mil"] + - "‸": [T: "a o"] + - "‹": [T: "simples esquerda apontando aspas angulares"] + - "›": [T: "simples direita apontando aspas angulares"] + - "‼": + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "ponto duplo de exclamação"] # 0x203c + else: [T: "duplo fatorial"] # 0x203c + - "⁄": + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "barra grande"] # 0x203c + else: [T: "dividido por"] # 0x203c + - "⁅": [T: "quadrado esquerda colchete com pena"] + - "⁆": [T: "quadrado direita colchete com pena"] + - "※": [T: "marca de referência"] + - "‿": [T: "sob laço"] + - "⁀": [T: "laço"] + - "⁎": [T: "baixo asterisco"] + - "⁏": [T: "ponto invertido e vírgula"] + - "⁐": [T: "fechamento"] + - "⁑": [T: "dois vertical asteriscos"] + - "⁒": [T: "comercial sinal de menos"] + - "⁗": [T: "linha quádrupla"] + - "⁠": [T: ""] + - "₠": [T: "europeia moeda unidades"] + - "₡": [T: "dois pontos"] + - "₢": [T: "cruzeiro"] + - "₣": [T: "franco"] + - "₤": [T: "lira"] + - "₥": [T: "mills"] + - "₦": [T: "naira"] + - "₧": [T: "peseta"] + - "₨": [T: "rupias"] + - "₩": [T: "won"] + - "₪": [T: "novos shequels"] + - "₫": [T: "dong"] + - "€": [T: "euros"] + - "₭": [T: "kip"] + - "₮": [T: "tugrik"] + - "₯": [T: "dracma"] + - "₰": [T: "pfennigs"] + - "₱": [T: "pesos"] + - "₲": [T: "guaranis"] + - "₳": [T: "australes"] + - "₴": [T: "hryvnias"] + - "₵": [T: "cedis"] + - "₶": [T: "livre tournois"] + - "₷": [T: "spesmilos"] + - "₸": [T: "tenges"] + - "₹": [T: "indiano rupias"] + - "₺": [T: "liras turcas"] + - "⃐": [T: "arpão para a esquerda acima de"] + - "⃑": [T: "arpão para a direita acima de"] + - "⃒": [T: "barra longa vertical sobreposto"] + - "⃓": [T: "barra curta vertical sobreposto"] + - "⃔": [T: "seta no sentido anti-horário acima de"] + - "⃕": [T: "seta no sentido horário acima de"] + - "⃖": [T: "seta para a esquerda acima de"] + - "⃗": [T: "seta para a direita acima de"] + - "⃘": [T: "anel sobreposto"] + - "⃙": [T: "no sentido horário anel sobreposto"] + - "⃚": [T: "no sentido anti-horário anel sobreposto"] + - "⃝": [T: "círculo envolvente"] + - "⃞": [T: "quadrado envolvente"] + - "⃟": [T: "losango envolvente"] + - "⃠": [T: "círculo envolvente barra invertida"] + - "⃡": [T: "seta para a esquerda e para a direita acima de"] + - "⃢": [T: "envolvente tela"] + - "⃣": [T: "envolvente tecla"] + - "⃤": [T: "triângulo envolvente para cima apontando"] + - "⃥": [T: "barra invertida sobreposto"] + - "⃦": [T: "traço duplo vertical"] + - "⃧": [T: "anuidade símbolo"] + - "⃨": [T: "ponto triplo abaixo"] + - "⃩": [T: "ponte larga acima de"] + - "⃪": [T: "seta para a esquerda sobreposto"] + - "⃫": [T: "barra longa dupla sobreposto"] + - "⃬": [T: "arpão para a direita com farpa baixo"] + - "⃭": [T: "arpão para a esquerda com farpa baixo"] + - "⃮": [T: "seta para a esquerda abaixo de"] + - "⃯": [T: "seta para a direita abaixo de"] + - "⃰": [T: "asterisco acima de"] + - "℄": [T: "centro linha símbolo"] + - "℅": [T: "aos cuidados de"] + - "℆": [T: "cada uma"] + - "ℇ": [T: "euler'esse constante"] + - "℈": [T: "escrúpulos"] + - "ℏ": [T: "agá barra"] + - "℔": [T: "libras"] + - "№": [T: "número"] + - "℥": [T: "onças"] + - "℩": [T: "invertido iota"] + - "Ⅎ℺⅁⅂⅃⅄": + - test: + - if: "'.' = '℺'" + then: [T: "rotacionado"] + - else_if: "'.' = 'Ⅎ'" + then: [T: "invertido"] + - else_if: "'.' = '⅃'" + then: [T: "invertido sem serifa"] + else: [T: "invertido sem serifa"] + - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" + - "ℵ": [T: "primeiro transfinito cardinal"] + - "ℶ": [T: "segundo transfinito cardinal"] + - "ℷ": [T: "terceiro transfinito cardinal"] + - "ℸ": [T: "quarto transfinito cardinal"] + - "⅋": [T: "invertido e comercial"] + - "⅌": [T: "por"] + - "ⅎ": [T: "invertido efe"] + - "↉": [T: "zero terços"] + - "⌀": [T: "diâmetro"] + - "⌁": [T: "seta elétrico"] + - "⌂": [T: "casa"] + - "⌃": [T: "ponta de seta para cima"] + - "⌄": [T: "ponta de seta para baixo"] + - "⌅": [T: "projetivo"] + - "⌆": [T: "perspectiva"] + - "⌇": [T: "linha ondulada"] + - "⌈": [T: "abre teto"] + - "⌉": [T: "fecha teto"] + - "⌊": [T: "abre piso"] + - "⌋": [T: "fecha piso"] + - "⌌": [T: "inferior direita corte"] + - "⌍": [T: "inferior esquerda corte"] + - "⌎": [T: "superior direita corte"] + - "⌏": [T: "superior esquerda corte"] + - "⌐": [T: "invertido não sinal"] + - "⌑": [T: "quadrado losango"] + - "⌒": [T: "arco"] + - "⌓": [T: "segmento"] + - "⌔": [T: "setor"] + - "⌕": [T: "telefone gravador"] + - "⌖": [T: "posição indicador mira"] + - "⌗": [T: "quadrado viewdata"] + - "⌘": [T: "lugar de interesse sinal"] + - "⌙": [T: "invertido não sinal"] + - "⌚": [T: "relógio"] + - "⌛": [T: "ampulheta"] + - "⌜": [T: "superior esquerda canto"] + - "⌝": [T: "superior direita canto"] + - "⌞": [T: "inferior esquerda canto"] + - "⌟": [T: "inferior direita canto"] + - "⌠": [T: "superior metade integral"] + - "⌡": [T: "inferior metade integral"] + - "⌢": [T: "carranca"] + - "⌣": [T: "sorriso"] + - "⌤": [T: "ponta de seta entre dois barras horizontales para cima"] + - "⌥": [T: "tecla opção"] + - "⌦": [T: "apagar à direita"] + - "⌧": [T: "retângulo xis em a caixa"] + - "⌨": [T: "teclado"] + - "〈": [T: "abre colchete apontando ângulo"] + - "〉": [T: "fecha colchete apontando ângulo"] + - "⌫": [T: "apagar à esquerda"] + - "⌬": [T: "benzeno anel"] + - "⌭": [T: "cilindricidade"] + - "⌮": [T: "tudo ao redor perfil"] + - "⌯": [T: "simetria"] + - "⌰": [T: "total excentricidade"] + - "⌱": [T: "dimensão origem"] + - "⌲": [T: "cone de afunilamento"] + - "⌳": [T: "inclinação"] + - "⌴": [T: "rebaixo"] + - "⌵": [T: "escareado"] + - "⌶": [T: "viga i do apl"] + - "⌽": [T: "círculo apl montante"] + - "⌿": [T: "barra do apl com barra sobreposta"] + - "⍰": [T: "desconhecido caixa"] + - "⍼": [T: "seta ângulo com baixo em zigue-zague para a direita"] + - "⎔": [T: "hexágono"] + - "⎕": [T: "caixa"] + - "⎶": [T: "quadrado inferior colchete sobre superior quadrado colchete"] + - "⏜": [T: "parêntese superior"] + - "⏝": [T: "parêntese inferior"] + - "⏞": [T: "chave superior"] + - "⏟": [T: "chave inferior"] + - "⏠": [T: "concha superior de tartaruga colchete"] + - "⏡": [T: "concha inferior de tartaruga colchete"] + - "⏢": [T: "trapézio branco"] + - "⏣": [T: "círculo benzeno direita com"] + - "⏤": [T: "retilineidade"] + - "⏥": [T: "planicidade"] + - "⏦": + - spell: "ac" + - T: "corrente" + - "⏧": [T: "interseção elétrica"] + - "①-⑨": + - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - T: "circulado" + - "⑩": [T: "dez circulado"] + - "⑪": [T: "onze circulado"] + - "⑫": [T: "doze circulado"] + - "⑬": [T: "treze circulado"] + - "⑭": [T: "quatorze circulado"] + - "⑮": [T: "quinze circulado"] + - "⑯": [T: "dezesseis circulado"] + - "⑰": [T: "dezessete circulado"] + - "⑱": [T: "dezoito circulado"] + - "⑳": [T: "vinte circulado"] + - "⑴-⑼": + - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - T: "entre parênteses" + - "⑽": [T: "dez entre parênteses"] + - "⑾": [T: "onze entre parênteses"] + - "⑿": [T: "doze entre parênteses"] + - "⒀": [T: "treze entre parênteses"] + - "⒁": [T: "quatorze entre parênteses"] + - "⒂": [T: "quinze entre parênteses"] + - "⒃": [T: "dezesseis entre parênteses"] + - "⒄": [T: "dezessete entre parênteses"] + - "⒅": [T: "dezoito entre parênteses"] + - "⒆": [T: "dezenove entre parênteses"] + - "⒇": [T: "vinte entre parênteses"] + - "⒈-⒐": + - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" + - T: "com ponto" + - "⒑": [T: "dez com ponto final"] + - "⒒": [T: "onze com ponto final"] + - "⒓": [T: "doze com ponto final"] + - "⒔": [T: "treze com ponto final"] + - "⒕": [T: "quatorze com ponto final"] + - "⒖": [T: "quinze com ponto final"] + - "⒗": [T: "dezesseis com ponto final"] + - "⒘": [T: "dezessete com ponto final"] + - "⒙": [T: "dezoito com ponto final"] + - "⒚": [T: "dezenove com ponto final"] + - "⒛": [T: "vinte com ponto final"] + - "⒜-⒵": + - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + - T: "entre parênteses" + - "Ⓐ-ⓩ": + - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "circulado" + - "🅐-🅩": + - spell: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - T: "circulado preto" + - "ⓐ-ⓩ": + - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - T: "circulado" + - "⓪": [T: "zero circulado"] + - "⓫": [T: "onze circulado preto"] + - "⓬": [T: "doze circulado preto"] + - "⓭": [T: "treze circulado preto"] + - "⓮": [T: "quatorze circulado preto"] + - "⓯": [T: "quinze circulado preto"] + - "⓰": [T: "dezesseis circulado preto"] + - "⓱": [T: "dezessete circulado preto"] + - "⓲": [T: "dezoito circulado preto"] + - "⓳": [T: "dezenove circulado preto"] + - "⓴": [T: "vinte circulado preto"] + - "⓵-⓽": + - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" + - T: "duplo circulado" + - "⓾": [T: "dez circulado duas vezes"] + - "⓿": [T: "zero circulado preto"] + - "★": [T: "estrela preta"] + - "☆": [T: "estrela branca"] + - "☉": [T: "sol"] + - "☌": [T: "conjunção"] + - "☒": [T: "cédula caixa com xis"] + - "☽": [T: "crescente lua"] + - "☾": [T: "minguante lua"] + - "☿": [T: "mercúrio"] + - "♀": [T: "feminino"] + - "♁": [T: "terra"] + - "♂": [T: "masculino"] + - "♃": [T: "júpiter"] + - "♄": [T: "saturno"] + - "♅": [T: "urano"] + - "♆": [T: "netuno"] + - "♇": [T: "plutão"] + - "♈": [T: "áries"] + - "♉": [T: "touro"] + - "♩": [T: "um quarto nota"] + - "♭": [T: "bemol"] + - "♮": [T: "natural"] + - "♯": [T: "sustenido"] + - "♠": [T: "preto naipe de espadas"] + - "♡": [T: "branco naipe de copas"] + - "♢": [T: "branco naipe de ouros"] + - "♣": [T: "preto naipe de paus"] + - "♤": [T: "branco naipe de espadas"] + - "♥": [T: "preto naipe de copas"] + - "♦": [T: "preto naipe de ouros"] + - "♧": [T: "branco naipe de paus"] + - "⚀": [T: "face de dado 1"] + - "⚁": [T: "face de dado 2"] + - "⚂": [T: "face de dado 3"] + - "⚃": [T: "face de dado 4"] + - "⚄": [T: "face de dado 5"] + - "⚅": [T: "face de dado 6"] + - "⚆": [T: "círculo branco com ponto direita"] + - "⚇": [T: "círculo branco com dois pontos"] + - "⚈": [T: "círculo preto com ponto direita"] + - "⚉": [T: "círculo preto com dois pontos"] + - "⚪": [T: "círculo médio branco"] + - "⚫": [T: "círculo médio preto"] + - "⚬": [T: "círculo médio pequeno branco"] + - "⚲": [T: "neutro"] + - "✓": [T: "verificação marca"] + - "✠": [T: "cruzes de malta"] + - "✪": [T: "branco estrela circulado"] + - "✶": [T: "estrela seis pontuda preta"] + - "❨": [T: "médio parênteses ornamento à esquerda"] + - "❩": [T: "médio parênteses ornamento à direita"] + - "❪": [T: "médio achatado parênteses ornamento à esquerda"] + - "❫": [T: "médio achatado parênteses ornamento à direita"] + - "❬": [T: "médio apontando para a colchete angular ornamento à esquerda"] + - "❭": [T: "médio apontando para a colchete angular ornamento à direita"] + - "❮": [T: "grosso apontando para a esquerda aspas angulares ornamento"] + - "❯": [T: "grosso apontando para a direita aspas angulares ornamento"] + - "❰": [T: "grosso apontando para a colchete angular ornamento à esquerda"] + - "❱": [T: "grosso apontando para a colchete angular ornamento à direita"] + - "❲": [T: "fino concha de tartaruga colchete ornamento à esquerda"] + - "❳": [T: "fino concha de tartaruga colchete ornamento à direita"] + - "❴": [T: "médio chave ornamento à esquerda"] + - "❵": [T: "médio chave ornamento à direita"] + - "❶": [T: "um circulado preto"] + - "❷": [T: "dois circulado preto"] + - "❸": [T: "três circulado preto"] + - "❹": [T: "quatro circulado preto"] + - "❺": [T: "cinco circulado preto"] + - "❻": [T: "seis circulado preto"] + - "❼": [T: "sete circulado preto"] + - "❽": [T: "oito circulado preto"] + - "❾": [T: "nove circulado preto"] + - "❿": [T: "dez circulado preto"] + - "➀": [T: "um circulado sem serifa"] + - "➁": [T: "dois circulado sem serifa"] + - "➂": [T: "três circulado sem serifa"] + - "➃": [T: "quatro circulado sem serifa"] + - "➄": [T: "cinco circulado sem serifa"] + - "➅": [T: "seis circulado sem serifa"] + - "➆": [T: "sete circulado sem serifa"] + - "➇": [T: "oito circulado sem serifa"] + - "➈": [T: "nove circulado sem serifa"] + - "➉": [T: "dez circulado sem serifa"] + - "➊": [T: "um circulado preto sem serifa"] + - "➋": [T: "dois circulado preto sem serifa"] + - "➌": [T: "três circulado preto sem serifa"] + - "➍": [T: "quatro circulado preto sem serifa"] + - "➎": [T: "cinco circulado preto sem serifa"] + - "➏": [T: "seis circulado preto sem serifa"] + - "➐": [T: "sete circulado preto sem serifa"] + - "➑": [T: "oito circulado preto sem serifa"] + - "➒": [T: "nove circulado preto sem serifa"] + - "➓": [T: "dez circulado preto sem serifa"] + - "➔": [T: "seta grossa de cabeça larga para a direita"] + - "➕": [T: "sinal grosso de mais"] + - "➖": [T: "sinal grosso de menos"] + - "➗": [T: "sinal grosso de divisão"] + - "➘": [T: "seta grossa para sudeste"] + - "➙": [T: "seta grossa para a direita"] + - "➚": [T: "seta grossa para nordeste"] + - "➛": [T: "seta desenho técnico ponto para a direita"] + - "➜": [T: "seta grossa de ponta arredondada para a direita"] + - "➝": [T: "seta de ponta triangular para a direita"] + - "➞": [T: "seta grossa de ponta triangular para a direita"] + - "➟": [T: "seta tracejada de ponta triangular para a direita"] + - "➠": [T: "seta grossa tracejada de ponta triangular para a direita"] + - "➡": [T: "seta preta para a direita"] + - "➢": [T: "seta três dê superior aceso para a direita"] + - "➣": [T: "seta três dê inferior aceso para a direita"] + - "➤": [T: "preto ponta de seta à direita"] + - "➥": [T: "seta grossa preta curva baixo e para a direita"] + - "➦": [T: "seta grossa preta curva cima e para a direita"] + - "➧": [T: "seta achatado preta para a direita"] + - "➨": [T: "seta grossa de ponta côncava preta para a direita"] + - "➩": [T: "seta sombreado à direita branca para a direita"] + - "➪": [T: "seta sombreado à esquerda branca para a direita"] + - "➫": [T: "seta inclinado para trás sombreada branca para a direita"] + - "➬": [T: "seta inclinado para a frente sombreada branca para a direita"] + - "➭": [T: "seta grossa inferior com sombra à direita branca para a direita"] + - "➮": [T: "seta grossa superior com sombra à direita branca para a direita"] + - "➯": [T: "seta entalhada inferior com sombra à direita branca para a direita"] + - "➱": [T: "seta entalhada superior com sombra à direita branca para a direita"] + - "➲": [T: "grosso branco direita seta circulado"] + - "➳": [T: "seta de pena branca para a direita"] + - "➴": [T: "seta de pena preta para sudeste"] + - "➵": [T: "seta de pena preta para a direita"] + - "➶": [T: "seta de pena preta para nordeste"] + - "➷": [T: "seta grossa de pena preta para sudeste"] + - "➸": [T: "seta grossa de pena preta para a direita"] + - "➹": [T: "seta grossa de pena preta para nordeste"] + - "➺": [T: "seta de farpa em gota para a direita"] + - "➻": [T: "seta grossa de haste em gota para a direita"] + - "➼": [T: "seta de cauda em cunha para a direita"] + - "➽": [T: "seta grossa de cauda em cunha para a direita"] + - "➾": [T: "seta de contorno aberto para a direita"] + - "⟀": [T: "três dimensional ângulo"] + - "⟁": [T: "triângulo branco contendo pequeno branco triângulo"] + - "⟃": + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "um aberto contido em" + - "⟄": + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] + - T: "um aberto contém" + - "⟅": [T: "esquerda em forma de s saco delimitador"] + - "⟆": [T: "direita em forma de s saco delimitador"] + - "⟇": [T: "ou com ponto dentro de"] + - "⟈": [T: "barra invertida precedente contido"] + - "⟉": [T: "contendo precedente barra"] + - "⟊": [T: "barra vertical com traço horizontal"] + - "⟋": [T: "matemático subindo diagonal"] + - "⟌": [T: "divisão longa"] + - "⟍": [T: "matemático descendo diagonal"] + - "⟎": [T: "e lógico enquadrado"] + - "⟏": [T: "ou lógico enquadrado"] + - "⟐": [T: "losango branco com centralizado ponto"] + - "⟑": [T: "e com ponto"] + - "⟒": [T: "pertence a abrindo cima"] + - "⟓": [T: "inferior direita canto com ponto"] + - "⟔": [T: "superior esquerda canto com ponto"] + - "⟕": [T: "esquerda externo unir"] + - "⟖": [T: "direita externo unir"] + - "⟗": [T: "completo externo unir"] + - "⟘": [T: "grande taco para cima"] + - "⟙": [T: "grande taco para baixo"] + - "⟚": [T: "esquerda e direita catraca dupla"] + - "⟛": [T: "esquerda e taco à direita"] + - "⟜": [T: "esquerda multimapa"] + - "⟝": [T: "longo taco à direita"] + - "⟞": [T: "longo taco à esquerda"] + - "⟟": [T: "círculo cima taco com acima de"] + - "⟠": [T: "losango dividido por horizontal régua"] + - "⟡": [T: "losango branco côncavo lateral"] + - "⟢": [T: "losango branco côncavo lateral com esquerda marca"] + - "⟣": [T: "losango branco côncavo lateral com direita marca"] + - "⟤": [T: "quadrado branco com esquerda marca"] + - "⟥": [T: "quadrado branco com direita marca"] + - "⟦": [T: "abre colchete branco quadrado"] + - "⟧": [T: "fecha colchete branco quadrado"] + - "⟬": [T: "abre colchete branco concha de tartaruga"] + - "⟭": [T: "fecha colchete branco concha de tartaruga"] + - "⟮": [T: "abre parêntese achatado"] + - "⟯": [T: "fecha parêntese achatado"] + - "⟰": [T: "seta quádrupla para cima"] + - "⟱": [T: "seta quádrupla para baixo"] + - "⟲": [T: "seta no sentido anti-horário com falha círculo"] + - "⟳": [T: "seta no sentido horário com falha círculo"] + - "⟴": [T: "seta para a direita com circulado mais"] + - "⟻": [T: "seta longa para a esquerda a partir de barra"] + - "⟼": [T: "seta longa para a direita a partir de barra"] + - "⟽": [T: "seta longa dupla para a esquerda a partir de barra"] + - "⟾": [T: "seta longa dupla para a direita a partir de barra"] + - "⟿": [T: "seta longa serpenteante para a direita"] + - "⤀": [T: "seta de duas pontas para a direita com vertical traço"] + - "⤁": [T: "seta de duas pontas para a direita com duplo vertical traço"] + - "⤂": [T: "seta dupla para a esquerda com vertical traço"] + - "⤃": [T: "seta dupla para a direita com vertical traço"] + - "⤄": [T: "seta dupla para a esquerda e para a direita com vertical traço"] + - "⤅": [T: "seta de duas pontas para a direita a partir de barra"] + - "⤆": [T: "seta dupla para a esquerda a partir de barra"] + - "⤇": [T: "seta dupla para a direita a partir de barra"] + - "⤈": [T: "seta para baixo com horizontal traço"] + - "⤉": [T: "seta para cima com horizontal traço"] + - "⤊": [T: "seta tripla para cima"] + - "⤋": [T: "seta tripla para baixo"] + - "⤌": [T: "seta dupla travessão para a esquerda"] + - "⤍": [T: "seta dupla travessão para a direita"] + - "⤎": [T: "seta de três traços para a esquerda"] + - "⤏": [T: "seta de três traços para a direita"] + - "⤐": [T: "seta de duas pontas de três traços para a direita"] + - "⤑": [T: "seta para a direita com pontilhado haste"] + - "⤒": [T: "seta para cima a barra"] + - "⤓": [T: "seta para baixo a barra"] + - "⤔": [T: "seta para a direita com cauda e vertical traço"] + - "⤕": [T: "seta para a direita com cauda e duplo vertical traço"] + - "⤖": [T: "seta de duas pontas para a direita com cauda"] + - "⤗": [T: "seta de duas pontas para a direita com cauda com vertical traço"] + - "⤘": [T: "seta de duas pontas para a direita com cauda com duplo vertical traço"] + - "⤙": [T: "seta para a esquerda cauda"] + - "⤚": [T: "seta para a direita cauda"] + - "⤛": [T: "seta dupla para a esquerda cauda"] + - "⤜": [T: "seta dupla para a direita cauda"] + - "⤝": [T: "seta para a esquerda a preenchido losango"] + - "⤞": [T: "seta para a direita a preenchido losango"] + - "⤟": [T: "seta para a esquerda a partir de barra a preenchido losango"] + - "⤠": [T: "seta para a direita a partir de barra a preenchido losango"] + - "⤡": [T: "seta e sul leste para noroeste"] + - "⤢": [T: "seta e sul oeste para nordeste"] + - "⤣": [T: "seta para noroeste com gancho"] + - "⤤": [T: "seta para nordeste com gancho"] + - "⤥": [T: "seta para sudeste com gancho"] + - "⤦": [T: "seta para sudoeste com gancho"] + - "⤧": [T: "seta para noroeste e norte leste seta"] + - "⤨": [T: "seta para nordeste e sul leste seta"] + - "⤩": [T: "seta para sudeste e sul oeste seta"] + - "⤪": [T: "seta para sudoeste e norte oeste seta"] + - "⤫": [T: "subindo diagonal cruzando descendo diagonal"] + - "⤬": [T: "descendo diagonal cruzando subindo diagonal"] + - "⤭": [T: "seta para sudeste cruzando norte leste seta"] + - "⤮": [T: "seta para nordeste cruzando sul leste seta"] + - "⤯": [T: "seta descendo diagonal cruzando para nordeste"] + - "⤰": [T: "seta subindo diagonal cruzando para sudeste"] + - "⤱": [T: "seta para nordeste cruzando norte oeste seta"] + - "⤲": [T: "seta para noroeste cruzando norte leste seta"] + - "⤳": [T: "seta ondulada apontando diretamente direita"] + - "⤴": [T: "seta apontando direita depois curvando cima"] + - "⤵": [T: "seta apontando direita depois curvando baixo"] + - "⤶": [T: "seta apontando baixo depois curvando esquerda"] + - "⤷": [T: "seta apontando baixo depois curvando direita"] + - "⤸": [T: "seta lado arco no sentido horário para a direita"] + - "⤹": [T: "seta lado arco no sentido anti-horário para a esquerda"] + - "⤺": [T: "seta superior arco no sentido anti-horário"] + - "⤻": [T: "seta inferior arco no sentido anti-horário"] + - "⤼": [T: "seta superior arco no sentido horário com menos"] + - "⤽": [T: "seta superior arco no sentido anti-horário com mais"] + - "⤾": [T: "seta inferior semicircular no sentido horário para a direita"] + - "⤿": [T: "seta inferior semicircular no sentido anti-horário para a esquerda"] + - "⥀": [T: "seta no sentido anti-horário fechada círculo"] + - "⥁": [T: "seta no sentido horário fechada círculo"] + - "⥂": [T: "seta para a direita acima de curto esquerda seta"] + - "⥃": [T: "seta para a esquerda acima de curto direita seta"] + - "⥄": [T: "seta curta para a direita acima de esquerda seta"] + - "⥅": [T: "seta para a direita com mais abaixo de"] + - "⥆": [T: "seta para a esquerda com mais abaixo de"] + - "⥇": [T: "seta para a direita atravessado por xis"] + - "⥈": [T: "seta para a esquerda e para a direita atravessado por círculo"] + - "⥉": [T: "seta de duas pontas para cima a partir de círculo"] + - "⥊": [T: "arpão farpa cima direita farpa baixo para a esquerda"] + - "⥋": [T: "arpão farpa baixo direita farpa cima para a esquerda"] + - "⥌": [T: "arpão cima farpa direita baixo farpa para a esquerda"] + - "⥍": [T: "arpão cima farpa baixo farpa direita para a esquerda"] + - "⥎": [T: "arpão farpa cima direita farpa cima para a esquerda"] + - "⥏": [T: "arpão cima farpa baixo farpa direita para a direita"] + - "⥐": [T: "arpão farpa baixo direita farpa baixo para a esquerda"] + - "⥑": [T: "arpão cima farpa baixo farpa esquerda para a esquerda"] + - "⥒": [T: "arpão para a esquerda com farpa cima a barra"] + - "⥓": [T: "arpão para a direita com farpa cima a barra"] + - "⥔": [T: "arpão para cima com farpa direita a barra"] + - "⥕": [T: "arpão para baixo com farpa direita a barra"] + - "⥖": [T: "arpão para a esquerda com farpa baixo a barra"] + - "⥗": [T: "arpão para a direita com farpa baixo a barra"] + - "⥘": [T: "arpão para cima com farpa esquerda a barra"] + - "⥙": [T: "arpão para baixo com farpa esquerda a barra"] + - "⥚": [T: "arpão para a esquerda com farpa cima a partir de barra"] + - "⥛": [T: "arpão para a direita com farpa cima a partir de barra"] + - "⥜": [T: "arpão para cima com farpa direita a partir de barra"] + - "⥝": [T: "arpão para baixo com farpa direita a partir de barra"] + - "⥞": [T: "arpão para a esquerda com farpa baixo a partir de barra"] + - "⥟": [T: "arpão para a direita com farpa baixo a partir de barra"] + - "⥠": [T: "arpão para cima com farpa esquerda a partir de barra"] + - "⥡": [T: "arpão para baixo com farpa esquerda a partir de barra"] + - "⥢": [T: "arpão para a esquerda com farpa cima acima de esquerda arpão com farpa baixo"] + - "⥣": [T: "arpão para cima com farpa esquerda ao lado de cima arpão com farpa direita"] + - "⥤": [T: "arpão para a direita com farpa cima acima de direita arpão com farpa baixo"] + - "⥥": [T: "arpão para baixo com farpa esquerda ao lado de baixo arpão com farpa direita"] + - "⥦": [T: "arpão para a esquerda com farpa cima acima de direita arpão com farpa cima"] + - "⥧": [T: "arpão para a esquerda com farpa baixo acima de direita arpão com farpa baixo"] + - "⥨": [T: "arpão para a direita com farpa cima acima de esquerda arpão com farpa cima"] + - "⥩": [T: "arpão para a direita com farpa baixo acima de esquerda arpão com farpa baixo"] + - "⥪": [T: "arpão para a esquerda com farpa cima acima de longo travessão"] + - "⥫": [T: "arpão para a esquerda com farpa baixo abaixo de longo travessão"] + - "⥬": [T: "arpão para a direita com farpa cima acima de longo travessão"] + - "⥭": [T: "arpão para a direita com farpa baixo abaixo de longo travessão"] + - "⥮": [T: "arpão para cima com farpa esquerda ao lado de baixo arpão com farpa direita"] + - "⥯": [T: "arpão para baixo com farpa esquerda ao lado de cima arpão com farpa direita"] + - "⥰": [T: "seta dupla para a direita com ponta arredondada"] + - "⥱": [T: "seta igual acima de para a direita"] + - "⥲": [T: "seta til operador acima de para a direita"] + - "⥳": [T: "seta para a esquerda acima de operador til"] + - "⥴": [T: "seta para a direita acima de operador til"] + - "⥵": [T: "seta para a direita acima de quase igual a"] + - "⥶": [T: "seta menor que acima de para a esquerda"] + - "⥷": [T: "seta para a esquerda atravessado por menor que"] + - "⥸": [T: "seta maior que acima de para a direita"] + - "⥹": [T: "seta contido acima de para a direita"] + - "⥺": [T: "seta para a esquerda atravessado por contido"] + - "⥻": [T: "seta contendo acima de para a esquerda"] + - "⥼": [T: "esquerda peixe cauda"] + - "⥽": [T: "direita peixe cauda"] + - "⥾": [T: "cima peixe cauda"] + - "⥿": [T: "baixo peixe cauda"] + - "⦀": [T: "barra tripla vertical delimitador"] + - "⦁": [T: "da notação z ponto"] + - "⦂": [T: "da notação z tipo dois pontos"] + - "⦃": [T: "abre chave branca"] + - "⦄": [T: "fecha chave branca"] + - "⦅": [T: "abre parêntese branco"] + - "⦆": [T: "fecha parêntese branco"] + - "⦇": [T: "da notação z esquerda imagem colchete"] + - "⦈": [T: "da notação z direita imagem colchete"] + - "⦉": [T: "da notação z esquerda vinculação colchete"] + - "⦊": [T: "da notação z direita vinculação colchete"] + - "⦋": [T: "quadrado esquerda colchete com barra inferior"] + - "⦌": [T: "quadrado direita colchete com barra inferior"] + - "⦍": [T: "quadrado esquerda colchete com marca em superior canto"] + - "⦎": [T: "quadrado direita colchete com marca em inferior canto"] + - "⦏": [T: "quadrado esquerda colchete com marca em inferior canto"] + - "⦐": [T: "quadrado direita colchete com marca em superior canto"] + - "⦑": [T: "colchete angular com ponto à esquerda"] + - "⦒": [T: "colchete angular com ponto à direita"] + - "⦓": [T: "abre colchete arco menor que"] + - "⦔": [T: "fecha colchete arco maior que"] + - "⦕": [T: "arco duplo esquerda maior que colchete"] + - "⦖": [T: "arco duplo direita menor que colchete"] + - "⦗": [T: "abre colchete preto concha de tartaruga"] + - "⦘": [T: "fecha colchete preto concha de tartaruga"] + - "⦙": [T: "cerca pontilhada"] + - "⦚": [T: "linha vertical em zigue-zague"] + - "⦛": [T: "medido ângulo abrindo esquerda"] + - "⦜": [T: "quadrado direita ângulo variante com"] + - "⦝": [T: "medido ângulo com ponto à direita"] + - "⦞": [T: "ângulo com esse dentro de"] + - "⦟": [T: "agudo ângulo"] + - "⦠": [T: "ângulo esférico abrindo esquerda"] + - "⦡": [T: "ângulo esférico abrindo cima"] + - "⦢": [T: "ângulo invertido"] + - "⦣": [T: "ângulo invertido"] + - "⦤": [T: "ângulo com barra inferior"] + - "⦥": [T: "ângulo invertido com barra inferior"] + - "⦦": [T: "ângulo oblíquo abrindo cima"] + - "⦧": [T: "ângulo oblíquo abrindo baixo"] + - "⦨": [T: "seta medido ângulo com aberta braço terminando em apontando cima e à direita"] + - "⦩": [T: "seta medido ângulo com aberta braço terminando em apontando cima e à esquerda"] + - "⦪": [T: "seta medido ângulo com aberta braço terminando em apontando baixo e à direita"] + - "⦫": [T: "seta medido ângulo com aberta braço terminando em apontando baixo e à esquerda"] + - "⦬": [T: "seta medido ângulo com aberta braço terminando em apontando direita e cima"] + - "⦭": [T: "seta medido ângulo com aberta braço terminando em apontando esquerda e cima"] + - "⦮": [T: "seta medido ângulo com aberta braço terminando em apontando direita e baixo"] + - "⦯": [T: "seta medido ângulo com aberta braço terminando em apontando esquerda e baixo"] + - "⦰": [T: "conjunto invertido vazio"] + - "⦱": [T: "conjunto vazio com barra superior"] + - "⦲": [T: "círculo vazio conjunto com pequeno acima de"] + - "⦳": [T: "seta vazio conjunto com para a direita acima de"] + - "⦴": [T: "seta vazio conjunto com para a esquerda acima de"] + - "⦵": [T: "círculo com barra horizontal"] + - "⦶": [T: "barra vertical circulado"] + - "⦷": [T: "paralelo circulado"] + - "⦸": [T: "invertido barra circulado"] + - "⦹": [T: "perpendicular circulado"] + - "⦺": [T: "dividido por barra horizontal e superior metade dividido por barra vertical circulado"] + - "⦻": [T: "círculo com sobreposto xis"] + - "⦼": [T: "no sentido anti-horário rotacionado sinal de divisão circulado"] + - "⦽": [T: "seta para cima atravessado por círculo"] + - "⦾": [T: "branco marcador circulado"] + - "⦿": [T: "marcador circulado"] + - "⧀": [T: "menor que circulado"] + - "⧁": [T: "maior que circulado"] + - "⧂": [T: "círculo com pequeno círculo à direita"] + - "⧃": [T: "círculo com dois horizontal traços à direita"] + - "⧄": [T: "subindo diagonal barra enquadrado"] + - "⧅": [T: "descendo diagonal barra enquadrado"] + - "⧆": [T: "asterisco enquadrado"] + - "⧇": [T: "pequeno círculo enquadrado"] + - "⧈": [T: "quadrado enquadrado"] + - "⧉": [T: "quadrados dois unido"] + - "⧊": [T: "triângulo com ponto acima de"] + - "⧋": [T: "triângulo com barra inferior"] + - "⧌": [T: "triângulo esse em"] + - "⧍": [T: "triângulo com serifas em inferior"] + - "⧎": [T: "triângulo direita acima de esquerda triângulo"] + - "⧏": [T: "triângulo esquerda ao lado de barra vertical"] + - "⧐": [T: "triângulo vertical barra ao lado de direita"] + - "⧑": [T: "laço com esquerda metade preto"] + - "⧒": [T: "laço com direita metade preto"] + - "⧓": [T: "laço preto"] + - "⧔": [T: "vezes com esquerda metade preto"] + - "⧕": [T: "vezes com direita metade preto"] + - "⧖": [T: "ampulheta branco"] + - "⧗": [T: "ampulheta preto"] + - "⧘": [T: "abre cerca ondulada"] + - "⧙": [T: "fecha cerca ondulada"] + - "⧚": [T: "abre cerca dupla ondulada"] + - "⧛": [T: "fecha cerca dupla ondulada"] + - "⧜": [T: "incompleto infinito"] + - "⧝": [T: "laço sobre infinito"] + - "⧞": [T: "infinito negado com barra vertical"] + - "⧟": [T: "de duas pontas multimapa"] + - "⧠": [T: "quadrado com contornado contorno"] + - "⧡": [T: "aumenta como"] + - "⧢": [T: "embaralhamento produto"] + - "⧣": [T: "sinal de igual e inclinado paralelo"] + - "⧤": [T: "sinal de igual e inclinado paralelo com til acima de"] + - "⧥": [T: "idêntico a e inclinado paralelo"] + - "⧦": [T: "igualmente forte"] + - "⧧": [T: "termodinâmico"] + - "⧨": [T: "triângulo baixo apontando com esquerda metade preto"] + - "⧩": [T: "triângulo baixo apontando com direita metade preto"] + - "⧪": [T: "seta preta losango com para baixo"] + - "⧫": [T: "losango preto"] + - "⧬": [T: "seta branca círculo com para baixo"] + - "⧭": [T: "seta preta círculo com para baixo"] + - "⧮": [T: "quadrado com barra de erro branco"] + - "⧯": [T: "quadrado com barra de erro preto"] + - "⧰": [T: "losango com barra de erro branco"] + - "⧱": [T: "losango com barra de erro preto"] + - "⧲": [T: "círculo com barra de erro branco"] + - "⧳": [T: "círculo com barra de erro preto"] + - "⧴": [T: "regra atrasada"] + - "⧵": [T: "barra invertida operador"] + - "⧶": [T: "barra com barra superior"] + - "⧷": [T: "barra invertida com traço horizontal"] + - "⧸": [T: "barra grande"] + - "⧹": [T: "barra grande invertida"] + - "⧺": [T: "duplo mais"] + - "⧻": [T: "triplo mais"] + - "⧼": [T: "abre colchete apontando curvo ângulo"] + - "⧽": [T: "fecha colchete apontando curvo ângulo"] + - "⧾": [T: "minúsculo"] + - "⧿": [T: "miny"] + - "⨀": [T: "ponto circulado"] + - "⨁": [T: "mais operador circulado"] + - "⨂": [T: "vezes operador circulado"] + - "⨃": [T: "união operador com ponto"] + - "⨄": [T: "união operador com mais"] + - "⨅": [T: "quadrado interseção operador"] + - "⨆": [T: "quadrado união operador"] + - "⨇": [T: "dois e lógico operador"] + - "⨈": [T: "dois ou lógico operador"] + - "⨉": [T: "vezes operador"] + - "⨊": [T: "módulo dois soma"] + - "⨋": [T: "somatório com integral"] + - "⨌": [T: "integral quádrupla operador"] + - "⨍": [T: "integral de parte finita"] + - "⨎": [T: "integral com traço duplo"] + - "⨏": [T: "integral média com barra"] + - "⨐": [T: "circulação função"] + - "⨑": [T: "no sentido anti-horário integração"] + - "⨒": [T: "linha integração com retangular caminho ao redor polo"] + - "⨓": [T: "linha integração com semicircular caminho ao redor polo"] + - "⨔": [T: "linha integração não incluindo o polo"] + - "⨕": [T: "integral ao redor a ponto operador"] + - "⨖": [T: "quatérnio integral operador"] + - "⨗": [T: "seta integral com para a esquerda com gancho"] + - "⨘": [T: "integral com vezes sinal"] + - "⨙": [T: "integral com interseção"] + - "⨚": [T: "integral com união"] + - "⨛": [T: "integral com barra superior"] + - "⨜": [T: "integral com barra inferior"] + - "⨝": [T: "unir"] + - "⨞": [T: "triângulo grande esquerda operador"] + - "⨟": [T: "da notação z esquema composição"] + - "⨠": [T: "da notação z esquema encanamento"] + - "⨡": [T: "da notação z esquema projeção"] + - "⨢": [T: "círculo mais sinal com acima de"] + - "⨣": [T: "sinal de mais com circunflexo acento acima de"] + - "⨤": [T: "sinal de mais com til acima de"] + - "⨥": [T: "sinal de mais com ponto abaixo de"] + - "⨦": [T: "sinal de mais com til abaixo de"] + - "⨧": [T: "sinal de mais com subscrito dois"] + - "⨨": [T: "triângulo mais sinal com preto"] + - "⨩": [T: "sinal de menos com vírgula acima de"] + - "⨪": [T: "sinal de menos com ponto abaixo de"] + - "⨫": [T: "sinal de menos com descendo pontos"] + - "⨬": [T: "sinal de menos com subindo pontos"] + - "⨭": [T: "círculo mais sinal em esquerda metade"] + - "⨮": [T: "círculo mais sinal em direita metade"] + - "⨯": + - test: + if: "$Verbosity='Terse'" + then: [T: "cruzes"] + else: [T: "cruzes produto"] + - "⨰": [T: "sinal de multiplicação com ponto acima de"] + - "⨱": [T: "sinal de multiplicação com barra inferior"] + - "⨲": [T: "produto semidireto com inferior fechado"] + - "⨳": [T: "produto esmagado"] + - "⨴": [T: "círculo multiplicação sinal em esquerda metade"] + - "⨵": [T: "círculo multiplicação sinal em direita metade"] + - "⨶": [T: "sinal de multiplicação com circunflexo acento circulado"] + - "⨷": [T: "círculo multiplicação sinal em duplo"] + - "⨸": [T: "sinal de divisão circulado"] + - "⨹": [T: "triângulo mais sinal em"] + - "⨺": [T: "triângulo menos sinal em"] + - "⨻": [T: "triângulo multiplicação sinal em"] + - "⨼": [T: "interior produto"] + - "⨽": [T: "à direita interior produto"] + - "⨾": [T: "da notação z relacional composição"] + - "⨿": [T: "amálgama ou coproduto"] + - "⩀": [T: "interseção com ponto"] + - "⩁": [T: "união com sinal de menos"] + - "⩂": [T: "união com barra superior"] + - "⩃": [T: "interseção com barra superior"] + - "⩄": [T: "interseção com e lógico"] + - "⩅": [T: "união com ou lógico"] + - "⩆": [T: "união acima de interseção"] + - "⩇": [T: "interseção acima de união"] + - "⩈": [T: "união acima de barra acima de interseção"] + - "⩉": [T: "interseção acima de barra acima de união"] + - "⩊": [T: "união ao lado de e unido com união"] + - "⩋": [T: "interseção ao lado de e unido com interseção"] + - "⩌": [T: "união fechada com serifas"] + - "⩍": [T: "interseção fechada com serifas"] + - "⩎": [T: "quadrado duplo interseção"] + - "⩏": [T: "quadrado duplo união"] + - "⩐": [T: "união fechada com serifas e produto esmagado"] + - "⩑": [T: "e lógico com ponto acima de"] + - "⩒": [T: "ou lógico com ponto acima de"] + - "⩓": [T: "duplo e lógico"] + - "⩔": [T: "duplo ou lógico"] + - "⩕": [T: "dois cruzando e lógico"] + - "⩖": [T: "dois cruzando ou lógico"] + - "⩗": [T: "inclinado grande ou"] + - "⩘": [T: "inclinado grande e"] + - "⩙": [T: "ou lógico sobreposto e lógico"] + - "⩚": [T: "e lógico com do meio haste"] + - "⩛": [T: "ou lógico com do meio haste"] + - "⩜": [T: "e lógico com horizontal travessão"] + - "⩝": [T: "ou lógico com horizontal travessão"] + - "⩞": [T: "e lógico com barra dupla superior"] + - "⩟": [T: "e lógico com barra inferior"] + - "⩠": [T: "e lógico com barra dupla inferior"] + - "⩡": [T: "pequeno vê com barra inferior"] + - "⩢": [T: "ou lógico com barra dupla superior"] + - "⩣": [T: "ou lógico com barra dupla inferior"] + - "⩤": [T: "da notação z domínio antirrestrição"] + - "⩥": [T: "da notação z imagem antirrestrição"] + - "⩦": [T: "sinal de igual com ponto abaixo de"] + - "⩧": [T: "idêntico com ponto acima de"] + - "⩨": [T: "barra tripla horizontal com traço duplo vertical"] + - "⩩": [T: "barra tripla horizontal com traço triplo vertical"] + - "⩪": [T: "operador til com ponto acima de"] + - "⩫": [T: "operador til com subindo pontos"] + - "⩬": [T: "semelhante menos semelhante"] + - "⩭": [T: "congruente com ponto acima de"] + - "⩮": [T: "igual com asterisco"] + - "⩯": [T: "quase igual a com circunflexo acento"] + - "⩰": [T: "aproximadamente igual a ou igual a"] + - "⩱": [T: "sinal de igual acima de sinal de mais"] + - "⩲": [T: "sinal de mais acima de sinal de igual"] + - "⩳": [T: "sinal de igual acima de operador til"] + - "⩴": [T: "duplo dois pontos igual"] + - "⩵": [T: "dois consecutivo igual sinais"] + - "⩶": [T: "três consecutivo igual sinais"] + - "⩷": [T: "sinal de igual com dois pontos acima de e dois pontos abaixo de"] + - "⩸": [T: "equivalente com quatro pontos acima de"] + - "⩹": [T: "círculo menor que com dentro de"] + - "⩺": [T: "círculo maior que com dentro de"] + - "⩻": [T: "menor que com ponto de interrogação acima de"] + - "⩼": [T: "maior que com ponto de interrogação acima de"] + - "⩽": [T: "menor que ou inclinado igual a"] + - "⩾": [T: "maior que ou inclinado igual a"] + - "⩿": [T: "menor que ou inclinado igual a com ponto dentro de"] + - "⪀": [T: "maior que ou inclinado igual a com ponto dentro de"] + - "⪁": [T: "menor que ou inclinado igual a com ponto acima de"] + - "⪂": [T: "maior que ou inclinado igual a com ponto acima de"] + - "⪃": [T: "menor que ou inclinado igual a com ponto acima de direita"] + - "⪄": [T: "maior que ou inclinado igual a com ponto acima de esquerda"] + - "⪅": [T: "menor que ou aproximado"] + - "⪆": [T: "maior que ou aproximado"] + - "⪇": [T: "menor que e linha simples não igual a"] + - "⪈": [T: "maior que e linha simples não igual a"] + - "⪉": [T: "menor que e não aproximado"] + - "⪊": [T: "maior que e não aproximado"] + - "⪋": [T: "menor que acima de linha dupla igual acima de maior que"] + - "⪌": [T: "maior que acima de linha dupla igual acima de menor que"] + - "⪍": [T: "menor que acima de semelhante ou igual"] + - "⪎": [T: "maior que acima de semelhante ou igual"] + - "⪏": [T: "menor que acima de semelhante acima de maior que"] + - "⪐": [T: "maior que acima de semelhante acima de menor que"] + - "⪑": [T: "menor que acima de maior que acima de linha dupla igual"] + - "⪒": [T: "maior que acima de menor que acima de linha dupla igual"] + - "⪓": [T: "menor que acima de inclinado igual acima de maior que acima de inclinado igual"] + - "⪔": [T: "maior que acima de inclinado igual acima de menor que acima de inclinado igual"] + - "⪕": [T: "inclinado igual a ou menor que"] + - "⪖": [T: "inclinado igual a ou maior que"] + - "⪗": [T: "inclinado igual a ou menor que com ponto dentro de"] + - "⪘": [T: "inclinado igual a ou maior que com ponto dentro de"] + - "⪙": [T: "linha dupla igual a ou menor que"] + - "⪚": [T: "linha dupla igual a ou maior que"] + - "⪛": [T: "linha dupla inclinado igual a ou menor que"] + - "⪜": [T: "linha dupla inclinado igual a ou maior que"] + - "⪝": [T: "semelhante ou menor que"] + - "⪞": [T: "semelhante ou maior que"] + - "⪟": [T: "semelhante acima de menor que acima de sinal de igual"] + - "⪠": [T: "semelhante acima de maior que acima de sinal de igual"] + - "⪡": [T: "duplo aninhado menor que"] + - "⪢": [T: "duplo aninhado maior que"] + - "⪣": [T: "duplo aninhado menor que com barra inferior"] + - "⪤": [T: "maior que sobreposto menor que"] + - "⪥": [T: "maior que ao lado de menor que"] + - "⪦": [T: "menor que fechado por curva"] + - "⪧": [T: "maior que fechado por curva"] + - "⪨": [T: "menor que fechado por curva acima de inclinado igual"] + - "⪩": [T: "maior que fechado por curva acima de inclinado igual"] + - "⪪": [T: "menor que"] + - "⪫": [T: "maior que"] + - "⪬": [T: "menor que ou igual a"] + - "⪭": [T: "maior que ou igual a"] + - "⪮": [T: "sinal de igual com irregular acima de"] + - "⪯": [T: "precede acima de linha simples sinal de igual"] + - "⪰": [T: "sucede acima de linha simples sinal de igual"] + - "⪱": [T: "precede acima de linha simples não igual a"] + - "⪲": [T: "sucede acima de linha simples não igual a"] + - "⪳": [T: "precede acima de sinal de igual"] + - "⪴": [T: "sucede acima de sinal de igual"] + - "⪵": [T: "precede acima de não igual a"] + - "⪶": [T: "sucede acima de não igual a"] + - "⪷": [T: "precede acima de quase igual a"] + - "⪸": [T: "sucede acima de quase igual a"] + - "⪹": [T: "precede acima de não quase igual a"] + - "⪺": [T: "sucede acima de não quase igual a"] + - "⪻": [T: "duplo precede"] + - "⪼": [T: "duplo sucede"] + - "⪽": [T: "contido com ponto"] + - "⪾": [T: "contendo com ponto"] + - "⪿": [T: "contido com sinal de mais abaixo de"] + - "⫀": [T: "contendo com sinal de mais abaixo de"] + - "⫁": [T: "contido com sinal de multiplicação abaixo de"] + - "⫂": [T: "contendo com sinal de multiplicação abaixo de"] + - "⫃": [T: "contido em ou igual a com ponto acima de"] + - "⫄": [T: "contém ou igual a com ponto acima de"] + - "⫅": [T: "contido em acima de sinal de igual"] + - "⫆": [T: "contém acima de sinal de igual"] + - "⫇": [T: "contido em acima de operador til"] + - "⫈": [T: "contém acima de operador til"] + - "⫉": [T: "contido em acima de quase igual a"] + - "⫊": [T: "contém acima de quase igual a"] + - "⫋": [T: "contido acima de não igual a"] + - "⫌": [T: "contém acima de não igual a"] + - "⫍": [T: "quadrado esquerda aberto caixa operador"] + - "⫎": [T: "quadrado direita aberto caixa operador"] + - "⫏": [T: "fechado contido"] + - "⫐": [T: "fechado contendo"] + - "⫑": [T: "fechado contido ou igual a"] + - "⫒": [T: "fechado contendo ou igual a"] + - "⫓": [T: "contido acima de contendo"] + - "⫔": [T: "contendo acima de contido"] + - "⫕": [T: "contido acima de contido"] + - "⫖": [T: "contendo acima de contendo"] + - "⫗": [T: "contendo ao lado de contido"] + - "⫘": [T: "contendo ao lado de e unido por travessão com contido"] + - "⫙": [T: "pertence a abrindo baixo"] + - "⫚": [T: "forcado com t superior"] + - "⫛": [T: "interseção transversal"] + - "⫝̸": [T: "bifurcando"] + - "⫝": [T: "não bifurcante"] + - "⫞": [T: "curto taco à esquerda"] + - "⫟": [T: "curto taco para baixo"] + - "⫠": [T: "curto taco para cima"] + - "⫡": [T: "perpendicular com esse"] + - "⫢": [T: "barra vertical triplo catraca à direita"] + - "⫣": [T: "barra dupla vertical catraca à esquerda"] + - "⫤": [T: "barra vertical duplo catraca à esquerda"] + - "⫥": [T: "barra dupla vertical duplo catraca à esquerda"] + - "⫦": [T: "longo travessão a partir de esquerda membro de duplo vertical"] + - "⫧": [T: "curto taco com barra superior para baixo"] + - "⫨": [T: "curto taco com barra inferior para cima"] + - "⫩": [T: "curto taco acima de curto taco para baixo para cima"] + - "⫪": [T: "duplo taco para baixo"] + - "⫫": [T: "duplo taco para cima"] + - "⫬": [T: "traço duplo não sinal"] + - "⫭": [T: "traço invertido duplo não sinal"] + - "⫮": [T: "não divide com invertido negação barra"] + - "⫯": [T: "círculo vertical linha com acima de"] + - "⫰": [T: "círculo vertical linha com abaixo de"] + - "⫱": [T: "círculo baixo taco com abaixo de"] + - "⫲": [T: "paralelo com traço horizontal"] + - "⫳": [T: "paralelo com operador til"] + - "⫴": [T: "barra tripla vertical binário relação"] + - "⫵": [T: "barra tripla vertical com traço horizontal"] + - "⫶": [T: "triplo dois pontos operador"] + - "⫷": [T: "triplo aninhado menor que"] + - "⫸": [T: "triplo aninhado maior que"] + - "⫹": [T: "linha dupla inclinado menor ou igual a"] + - "⫺": [T: "linha dupla inclinado maior ou igual a"] + - "⫻": [T: "barra tripla binário relação"] + - "⫼": [T: "barra grande tripla operador vertical"] + - "⫽": [T: "barra dupla operador"] + - "⫾": [T: "barra branca vertical"] + - "⫿": [T: "barra branca vertical"] + - "⬀": [T: "seta branca para nordeste"] + - "⬁": [T: "seta branca para noroeste"] + - "⬂": [T: "seta branca para sudeste"] + - "⬃": [T: "seta branca para sudoeste"] + - "⬄": [T: "seta branca para a esquerda e para a direita"] + - "⬅": [T: "seta preta para a esquerda"] + - "⬆": [T: "seta preta para cima"] + - "⬇": [T: "seta preta para baixo"] + - "⬈": [T: "seta preta para nordeste"] + - "⬉": [T: "seta preta para noroeste"] + - "⬊": [T: "seta preta para sudeste"] + - "⬋": [T: "seta preta para sudoeste"] + - "⬌": [T: "seta preta para a esquerda e para a direita"] + - "⬍": [T: "seta preta para cima e para baixo"] + - "⬎": [T: "seta para a direita com ponta baixo"] + - "⬏": [T: "seta para a direita com ponta cima"] + - "⬐": [T: "seta para a esquerda com ponta baixo"] + - "⬑": [T: "seta para a esquerda com ponta cima"] + - "⬒": [T: "quadrado com superior metade preto"] + - "⬓": [T: "quadrado com inferior metade preto"] + - "⬔": [T: "quadrado com superior direita diagonal metade preto"] + - "⬕": [T: "quadrado com inferior esquerda diagonal metade preto"] + - "⬖": [T: "losango com esquerda metade preto"] + - "⬗": [T: "losango com direita metade preto"] + - "⬘": [T: "losango com superior metade preto"] + - "⬙": [T: "losango com inferior metade preto"] + - "⬚": [T: "caixa"] + - "⬛": [T: "quadrado preto grande"] + - "⬜": [T: "quadrado branco grande"] + - "⬝": [T: "quadrado preto muito pequeno"] + - "⬞": [T: "quadrado branco muito pequeno"] + - "⬟": [T: "pentágono preto"] + - "⬠": [T: "pentágono branco"] + - "⬡": [T: "hexágono branco"] + - "⬢": [T: "hexágono preto"] + - "⬣": [T: "hexágono horizontal preto"] + - "⬤": [T: "círculo preto grande"] + - "⬥": [T: "losango preto médio"] + - "⬦": [T: "losango branco médio"] + - "⬧": [T: "losango preto médio"] + - "⬨": [T: "losango branco médio"] + - "⬩": [T: "losango preto pequeno"] + - "⬪": [T: "losango preto pequeno"] + - "⬫": [T: "losango branco pequeno"] + - "⬬": [T: "elipse preta horizontal"] + - "⬭": [T: "elipse branca horizontal"] + - "⬮": [T: "elipse preta vertical"] + - "⬯": [T: "elipse branca vertical"] + - "⬰": [T: "seta para a esquerda com pequeno círculo"] + - "⬱": [T: "setas três para a esquerda"] + - "⬲": [T: "seta para a esquerda com circulado mais"] + - "⬳": [T: "seta longa serpenteante para a esquerda"] + - "⬴": [T: "seta de duas pontas para a esquerda com vertical traço"] + - "⬵": [T: "seta de duas pontas para a esquerda com duplo vertical traço"] + - "⬶": [T: "seta de duas pontas para a esquerda a partir de barra"] + - "⬷": [T: "seta de duas pontas de três traços para a esquerda"] + - "⬸": [T: "seta para a esquerda com pontilhado haste"] + - "⬹": [T: "seta para a esquerda com cauda com vertical traço"] + - "⬺": [T: "seta para a esquerda com cauda com duplo vertical traço"] + - "⬻": [T: "seta de duas pontas para a esquerda com cauda"] + - "⬼": [T: "seta de duas pontas para a esquerda com cauda com vertical traço"] + - "⬽": [T: "seta de duas pontas para a esquerda com cauda com duplo vertical traço"] + - "⬾": [T: "seta para a esquerda atravessado por xis"] + - "⬿": [T: "seta ondulada apontando diretamente esquerda"] + - "⭀": [T: "seta igual sinal acima de para a esquerda"] + - "⭁": [T: "seta invertida til operador acima de para a esquerda"] + - "⭂": [T: "seta para a esquerda acima de invertido quase igual a"] + - "⭃": [T: "seta para a direita atravessado por maior que"] + - "⭄": [T: "seta para a direita atravessado por contendo"] + - "⭅": [T: "seta quádrupla para a esquerda"] + - "⭆": [T: "seta quádrupla para a direita"] + - "⭇": [T: "seta invertida til operador acima de para a direita"] + - "⭈": [T: "seta para a direita acima de invertido quase igual a"] + - "⭉": [T: "seta til operador acima de para a esquerda"] + - "⭊": [T: "seta para a esquerda acima de quase igual a"] + - "⭋": [T: "seta para a esquerda acima de invertido operador til"] + - "⭌": [T: "seta para a direita acima de invertido operador til"] + - "⭐": [T: "estrela branca média"] + - "⭑": [T: "estrela preta pequena"] + - "⭒": [T: "estrela branca pequena"] + - "⭓": [T: "pentágono preto direita apontando"] + - "⭔": [T: "pentágono branco direita apontando"] + - "⭕": [T: "círculo grosso grande"] + - "⭖": [T: "grosso oval com oval dentro de"] + - "⭗": [T: "círculo grosso com círculo dentro de"] + - "⭘": [T: "círculo grosso"] + - "⭙": [T: "grosso circulado aspa"] + - "⸀": [T: "ângulo substituição marcador à direita"] + - "⸁": [T: "ângulo pontilhado substituição marcador à direita"] + - "⸂": [T: "abre colchete substituição"] + - "⸃": [T: "fecha colchete substituição"] + - "⸄": [T: "abre colchete pontilhado substituição"] + - "⸅": [T: "fecha colchete pontilhado substituição"] + - "⸆": [T: "elevado interpolação marcador"] + - "⸇": [T: "elevado pontilhado interpolação marcador"] + - "⸈": [T: "pontilhado transposição marcador marcador"] + - "⸉": [T: "abre colchete transposição"] + - "⸊": [T: "fecha colchete transposição"] + - "⸋": [T: "quadrado elevado"] + - "⸌": [T: "abre colchete elevado omissão"] + - "⸍": [T: "fecha colchete elevado omissão"] + - "⸎": [T: "editorial corônis"] + - "⸏": [T: "parágrafo"] + - "⸐": [T: "bifurcado parágrafo"] + - "⸑": [T: "invertido bifurcado parágrafo"] + - "⸒": [T: "hipodiástole"] + - "⸓": [T: "pontilhado óbelo"] + - "⸔": [T: "âncora para baixo"] + - "⸕": [T: "âncora para cima"] + - "⸖": [T: "pontilhado direita apontando ângulo"] + - "⸗": [T: "duplo oblíquo hífen"] + - "⸘": [T: "invertido interrobang"] + - "⸙": [T: "ramo de palmeira"] + - "⸚": [T: "hífen com trema"] + - "⸛": [T: "til com anel acima de"] + - "⸜": [T: "abre colchete baixo paráfrase"] + - "⸝": [T: "fecha colchete baixo paráfrase"] + - "⸞": [T: "til com ponto acima de"] + - "⸟": [T: "til com ponto abaixo de"] + - "⸠": [T: "barra vertical com pena à esquerda"] + - "⸡": [T: "barra vertical com pena à direita"] + - "⸢": [T: "superior esquerda metade colchete"] + - "⸣": [T: "superior direita metade colchete"] + - "⸤": [T: "inferior esquerda metade colchete"] + - "⸥": [T: "inferior direita metade colchete"] + - "⸦": [T: "abre colchete de lado u"] + - "⸧": [T: "fecha colchete de lado u"] + - "⸨": [T: "esquerda parênteses duplos"] + - "⸩": [T: "direita parênteses duplos"] + - "⸪": [T: "dois pontos sobre um ponto pontuação"] + - "⸫": [T: "um ponto sobre dois pontos pontuação"] + - "⸬": [T: "quatro ponto pontuação enquadrado"] + - "⸭": [T: "cinco ponto marca"] + - "⸮": [T: "ponto invertido de interrogação"] + - "ⸯ": [T: "til vertical"] + - "⸰": [T: "anel ponto"] + - "⸱": [T: "separador de palavras do meio ponto"] + - "⸲": [T: "invertido vírgula"] + - "⸳": [T: "elevado ponto"] + - "⸴": [T: "elevado vírgula"] + - "⸵": [T: "ponto invertido e vírgula"] + - "⸶": [T: "adaga com esquerda guarda"] + - "⸷": [T: "adaga com direita guarda"] + - "⸸": [T: "invertido adaga"] + - "⸹": [T: "superior metade seção sinal"] + - "⸺": [T: "dois em travessão"] + - "⸻": [T: "três em travessão"] + - "〃": [T: "idem marca"] + - "〈": [T: "abre colchete angular"] + - "〉": [T: "fecha colchete angular"] + - "《": [T: "abre colchete angular duplo"] + - "》": [T: "fecha colchete angular duplo"] + - "「": [T: "abre colchete canto"] + - "」": [T: "fecha colchete canto"] + - "『": [T: "abre colchete branco canto"] + - "』": [T: "fecha colchete branco canto"] + - "【": [T: "abre colchete preto lenticular"] + - "】": [T: "fecha colchete preto lenticular"] + - "〔": [T: "abre colchete concha de tartaruga"] + - "〕": [T: "fecha colchete concha de tartaruga"] + - "〖": [T: "abre colchete branco lenticular"] + - "〗": [T: "fecha colchete branco lenticular"] + - "〘": [T: "abre colchete branco concha de tartaruga"] + - "〙": [T: "fecha colchete branco concha de tartaruga"] + - "〚": [T: "abre colchete branco quadrado"] + - "〛": [T: "fecha colchete branco quadrado"] + - "〜": [T: "ondulado travessão"] + - "〰": [T: "ondulado travessão"] + - "㉈": [T: "dez sobre preto quadrado circulado"] + - "㉉": [T: "vinte sobre preto quadrado circulado"] + - "㉊": [T: "trinta sobre preto quadrado circulado"] + - "㉋": [T: "quarenta sobre pretos quadrado circulado"] + - "㉌": [T: "cinquenta sobre preto quadrado circulado"] + - "㉍": [T: "sessenta sobre preto quadrado circulado"] + - "㉎": [T: "setenta sobre preto quadrado circulado"] + - "㉏": [T: "oitenta sobre preto quadrado circulado"] + - "㉑": [T: "vinte um circulado"] + - "㉒": [T: "vinte dois circulado"] + - "㉓": [T: "vinte três circulado"] + - "㉔": [T: "vinte quatro circulado"] + - "㉕": [T: "vinte cinco circulado"] + - "㉖": [T: "vinte seis circulado"] + - "㉗": [T: "vinte sete circulado"] + - "㉘": [T: "vinte oito circulado"] + - "㉙": [T: "vinte nove circulado"] + - "㉚": [T: "trinta circulado"] + - "㉛": [T: "trinta um circulado"] + - "㉜": [T: "trinta dois circulado"] + - "㉝": [T: "trinta três circulado"] + - "㉞": [T: "trinta quatro circulado"] + - "㉟": [T: "trinta cinco circulado"] + - "㊱": [T: "trinta seis circulado"] + - "㊲": [T: "trinta sete circulado"] + - "㊳": [T: "trinta oito circulado"] + - "㊴": [T: "trinta nove circulado"] + - "㊵": [T: "quarenta circulado"] + - "㊶": [T: "quarenta um circulado"] + - "㊷": [T: "quarenta dois circulado"] + - "㊸": [T: "quarenta três circulado"] + - "㊹": [T: "quarenta quatro circulado"] + - "㊺": [T: "quarenta cinco circulado"] + - "㊻": [T: "quarenta seis circulado"] + - "㊼": [T: "quarenta sete circulado"] + - "㊽": [T: "quarenta oito circulado"] + - "㊾": [T: "quarenta nove circulado"] + - "㊿": [T: "cinquenta circulado"] + - "㋌": [T: "mercúrio"] + - "㋍": [T: "ergs"] + - "㋎": [T: "elétron volts"] + - "㋏": [T: "limitado responsabilidade sinal"] + - "㍱": [T: "hectopascals"] + - "㍲": [T: "daltons"] + - "㍳": [T: "unidades astronômicas"] + - "㍴": [T: "barras"] + - "㍵": [T: "o vê"] + - "㍶": [T: "parsecs"] + - "㍷": [T: "decimetros"] + - "㍸": [T: "decímetros ao quadrado"] + - "㍹": [T: "decímetros ao cubo"] + - "㍺": [T: "instrumental unidades"] + - "㎀": [T: "picoampères"] + - "㎁": [T: "nanoampères"] + - "㎂": [T: "microampères"] + - "㎃": [T: "miliampères"] + - "㎄": [T: "quiloampères"] + - "㎅": [T: "quilobytes"] + - "㎆": [T: "megabytes"] + - "㎇": [T: "gigabytes"] + - "㎈": [T: "calorias"] + - "㎉": [T: "quilocalorias"] + - "㎊": [T: "picofarads"] + - "㎋": [T: "nanofarads"] + - "㎌": [T: "microfarads"] + - "㎍": [T: "microgramas"] + - "㎎": [T: "miligramas"] + - "㎏": [T: "quilogramas"] + - "㎐": [T: "hertz"] + - "㎑": [T: "quilohertz"] + - "㎒": [T: "megahertz"] + - "㎓": [T: "gigahertz"] + - "㎔": [T: "terahertz"] + - "㎕": [T: "microlitros"] + - "㎖": [T: "mililitros"] + - "㎗": [T: "decilitros"] + - "㎘": [T: "quilolitros"] + - "㎙": [T: "femtometros"] + - "㎚": [T: "nanometros"] + - "㎛": [T: "micrometros"] + - "㎜": [T: "milimetros"] + - "㎝": [T: "centimetros"] + - "㎞": [T: "quilometros"] + - "㎟": [T: "milímetros ao quadrado"] + - "㎠": [T: "centímetros ao quadrado"] + - "㎡": [T: "metros ao quadrado"] + - "㎢": [T: "quilômetros ao quadrado"] + - "㎣": [T: "milímetros ao cubo"] + - "㎤": [T: "centímetros ao cubo"] + - "㎥": [T: "metros ao cubo"] + - "㎦": [T: "quilômetros ao cubo"] + - "㎧": [T: "metros por segundo"] + - "㎨": [T: "metros por segundo ao quadrado"] + - "㎩": [T: "pascals"] + - "㎪": [T: "quilopascals"] + - "㎫": [T: "megapascals"] + - "㎬": [T: "gigapascals"] + - "㎭": [T: "radianos"] + - "㎮": [T: "radianos por segundo"] + - "㎯": [T: "radianos por segundo ao quadrado"] + - "㎰": [T: "picosegundos"] + - "㎱": [T: "nanosegundos"] + - "㎲": [T: "microsegundos"] + - "㎳": [T: "milisegundos"] + - "㎴": [T: "picovolts"] + - "㎵": [T: "nanovolts"] + - "㎶": [T: "microvolts"] + - "㎷": [T: "milivolts"] + - "㎸": [T: "quilovolts"] + - "㎹": [T: "megavolts"] + - "㎺": [T: "picowatts"] + - "㎻": [T: "nanowatts"] + - "㎼": [T: "microwatts"] + - "㎽": [T: "miliwatts"] + - "㎾": [T: "quilowatts"] + - "㎿": [T: "megawatts"] + - "㏀": [T: "quiloohms"] + - "㏁": [T: "megaohms"] + - "㏂": [T: "atometros"] + - "㏃": [T: "becquereis"] + - "㏄": [T: "cúbico centímetros"] + - "㏅": [T: "candelas"] + - "㏆": [T: "coulombs por quilograma"] + - "㏇": [T: "maiúscula C, o, ponto final"] + - "㏈": [T: "decibéis"] + - "㏉": [T: "grays"] + - "㏊": [T: "hectares"] + - "㏋": [T: "cavalo-vapor"] + - "㏌": [T: "polegadas"] + - "㏍": [T: "quilokelvins"] + - "㏎": [T: "quilometros"] + - "㏏": [T: "nós"] + - "㏐": [T: "lúmens"] + - "㏑": [T: "logaritmo natural"] + - "㏒": [T: "logaritmo"] + - "㏓": [T: "lux"] + - "㏔": [T: "milibarns"] + - "㏕": [T: "mills"] + - "㏖": [T: "moles"] + - "㏗": [T: "pê agá"] + - "㏘": [T: "picometros"] + - "㏙": [T: "partes por milhão"] + - "㏚": [T: "petaroentgens"] + - "㏛": [T: "esferorradianos"] + - "㏜": [T: "sieverts"] + - "㏝": [T: "webers"] + - "㏞": [T: "volts por metro"] + - "㏟": [T: "ampères por metro"] + - "㏿": [T: "galões"] + - "": [T: "igual com chapéu abaixo de"] + - "": [T: "igual com mais acima de"] + - "": [T: "igual com mais abaixo de"] + - "": [T: "til com mais acima de"] + - "": [T: "til com mais abaixo de"] + - "": [T: "igual duplo sobre maior que"] + - "": [T: "igual duplo sobre menor que"] + - "": [T: "contém ou igual a"] + - "": [T: "contém ou igual a"] + - "": [T: "contido em ou igual a"] + - "": [T: "igual sobre menor que"] + - "": [T: "pertence a ou igual a"] + - "": [T: "igual a ou maior que"] + - "": [T: "aproximado contém"] + - "": [T: "aproximado contido em"] + - "": [T: "contém com ponto inclui como sub relação"] + - "": [T: "contido em com ponto é incluído em como sub relação"] + - "": [T: "igual com ponto abaixo de"] + - "": [T: "ponto sobre menos sobre ponto à direita à esquerda"] + - "": [T: "ponto sobre menos sobre ponto à esquerda à direita"] + - "": [T: "quase igual a menos"] + - "": [T: "quadrado duplo xícara"] + - "": [T: "quadrado duplo maiúscula"] + - "": [T: "menor que igual a ou maior que"] + - "": [T: "til com ponto"] + - "": [T: "til com dois pontos"] + - "": [T: "menor que maior ou igual a"] + - "": [T: "maior que menor ou igual a"] + - "": [T: "equivalente a ou menor que"] + - "": [T: "equivalente a ou maior que"] + - "": [T: "esquerda aberto caixa operador"] + - "": [T: "direita aberto caixa operador"] + - "": [T: "idêntico a com ponto"] + - "": [T: "maior que igual a ou menor que"] + - "": [T: "operador barra"] + - "": [T: "operador duplo barra"] + - "": [T: "operador triplo barra"] + - "": [T: "menor que ou aproximadamente igual a"] + - "": [T: "maior que ou aproximadamente igual a"] + - "": [T: "aninhado menor que"] + - "": [T: "aninhado maior que"] + - "": [T: "precede ou equivalente a"] + - "": [T: "sucede ou equivalente a"] + - "": [T: "precede sobre igual"] + - "": [T: "sucede sobre igual"] + - "": [T: "menor igual inclinado maior"] + - "": [T: "maior igual inclinado menor"] + - "": [T: "satisfeito por"] + - "": [T: "deitado esse"] + - "": [T: "não asserção"] + - "": [T: "duplo igual"] + - "": [T: "triplo igual"] + - "": [T: "régua atrasado"] + - "": [T: "alias delimitador"] + - "": [T: "subgrupo normal de com barra"] + - "": [T: "contém como subgrupo normal com barra"] + - "": [T: "implica arredondado"] + - "": [T: "sorriso barra inferior"] + - "": [T: "carranca barra superior"] + - "": [T: "contém ou quase igual a"] + - "": [T: "contido em ou quase igual a"] + - "": [T: "maior que quase igual a ou menor que"] + - "": [T: "menor que quase igual ou maior que"] + - "": [T: "duplo ou lógico"] + - "": [T: "duplo e lógico"] + - "": [T: "ou lógico com barra dupla abaixo de"] + - "": [T: "ou lógico com barra abaixo de"] + - "": [T: "quase igual sobre igual"] + - "": [T: "triângulo esquerda apontando com bissectando barra"] + - "": [T: "triângulo direita apontando com bissectando barra"] + - "": [T: "igual com linha pontilhada superior"] + - "": [T: "precede com dois pontos"] + - "": [T: "sucede com dois pontos"] + - "": [T: "menor que ou igual inclinado"] + - "": [T: "maior que ou igual inclinado"] + - "": [T: "aninhado muito muito menor que"] + - "": [T: "aninhado muito muito maior que"] + - "": [T: "diferença entre variante"] + - "": [T: "menor que maior que sobreposto"] + - "": [T: "ou lógico e lógico sobreposto"] + - "": [T: "contendo sobre contendo"] + - "": [T: "contido sobre contido"] + - "": [T: "contendo sobre contido"] + - "": [T: "contido sobre contendo"] + - "": [T: "barra tripla vertical"] + - "": [T: "pontos pareados quádruplos verticales"] + - "": [T: "perpendicular barra superior"] + - "": [T: "catraca barra dupla vertical à esquerda"] + - "": [T: "duplo catraca barra dupla vertical à esquerda"] + - "": [T: "perpendicular sobre invertido perpendicular"] + - "": [T: "duplo catraca barra vertical à esquerda"] + - "": [T: "ângulo esférico abrindo cima"] + - "": [T: "barra dupla"] + - "": [T: "ângulo com canto à direita"] + - "": [T: "barra vertical circulado"] + - "": [T: "sinal de divisão circulado"] + - "": [T: "barra tracejada"] + - "": [T: "barra tracejada invertida"] + - "": [T: "linha tracejada média"] + - "": [T: "barra tracejada vertical"] + - "": [T: "perpendicular com esse"] + - "": [T: "ângulo com esse"] + - "": [T: "ângulo esférico abrindo esquerda"] + - "": [T: "ângulo abrindo esquerda"] + - "": [T: "barra vertical com gancho duplo"] + - "": [T: "ponto médio operador radical livre"] + - "": [T: "triângulo branco cima apontando acima de barra"] + - "": [T: "idêntico e paralelo a"] + - "": [T: "produto esmagado"] + - "": [T: "operador triplo barra com barra horizontal"] + - "": [T: "idêntico a com barra dupla"] + - "": [T: "barras triplas cruzadas"] + - "": [T: "círculo vertical barra sobre"] + - "": [T: "vertical proporcional a"] + - "": [T: "preto último um quarto lua"] + - "": [T: "preto primeiro um quarto lua"] + - "": [T: "negativo seno ondulado"] + - "": [T: "ponto entre parênteses"] + - "": [T: "parênteses"] + - "": [T: "branco sorriso"] + - "": [T: "branco carranca"] + - "": [T: "hexágono"] + - "": [T: "equivalente a sobre mais"] + - "": [T: "mais sobre equivalente a"] + - "": [T: "interseção serifas"] + - "": [T: "união serifas"] + - "": [T: "quadrado interseção serifas"] + - "": [T: "quadrado união serifas"] + - "": [T: "precede equivalente a ou sucede"] + - "": [T: "sucede equivalente a ou precede"] + - "": [T: "precede quase igual a ou sucede"] + - "": [T: "sucede quase igual a ou precede"] + - "": [T: "menor que equivalente a ou maior que"] + - "": [T: "maior que equivalente a ou menor que"] + - "": [T: "não vertical muito menor que"] + - "": [T: "não vertical muito maior que"] + - "": [T: "não muito menor que variante"] + - "": [T: "não muito maior que variante"] + - "": [T: "menor vertical não duplo igual"] + - "": [T: "maior que vertical não duplo igual"] + - "": [T: "não menor ou igual a"] + - "": [T: "não maior ou igual a"] + - "": [T: "nem igual a nem menor que"] + - "": [T: "não contém ou igual a"] + - "": [T: "nem contém nem igual a"] + - "": [T: "nem contido em nem igual a"] + - "": [T: "barra invertida contido"] + - "": [T: "nem igual a nem maior que"] + - "": [T: "não menos operador til"] + - "": [T: "nem igual a nem menor que"] + - "": [T: "não operador til"] + - "": [T: "não pertence a ou igual a"] + - "": [T: "nem igual a nem maior que"] + - "": [T: "não quase igual"] + - "": [T: "não sucede semelhante"] + - "": [T: "menor que ou inclinado igual a com barra"] + - "": [T: "maior que ou inclinado igual a com barra"] + - "": [T: "contendo barra"] + - "": [T: "não contém"] + - "": [T: "não menor ou igual a"] + - "": [T: "não maior ou igual a"] + - "": [T: "não quase igual a menos"] + - "": [T: "negado conjunto pertinência ponto acima de"] + - "": [T: "não ângulo vertical"] + - "": [T: "não paralelo inclinado"] + - "": [T: "não operador barra"] + - "": [T: "não operador duplo barra"] + - "": [T: "não operador triplo barra"] + - "": [T: "menor que mas não aproximadamente igual a"] + - "": [T: "maior que mas não aproximadamente igual a"] + - "": [T: "menor que ou não igual a"] + - "": [T: "maior que ou não igual a"] + - "": [T: "não aninhado menor que"] + - "": [T: "não aninhado maior que"] + - "": [T: "não muito menor que"] + - "": [T: "não muito maior que"] + - "": [T: "precede mas não equivalente a"] + - "": [T: "sucede mas não equivalente a"] + - "": [T: "precede mas não igual a"] + - "": [T: "sucede mas não igual a"] + - "": [T: "não igual ou precede"] + - "": [T: "não igual ou sucede"] + - "": [T: "precede mas não igual a"] + - "": [T: "sucede mas não igual a"] + - "": [T: "não contido em nem igual a"] + - "": [T: "não contém nem igual a"] + - "": [T: "contido em ou não igual a"] + - "": [T: "contém ou não igual a"] + - "": [T: "não contido em nem igual a"] + - "": [T: "não contém nem igual a"] + - "": [T: "não triplo menor que"] + - "": [T: "não triplo maior que"] + - "": [T: "não precede igual"] + - "": [T: "não sucede igual"] + - "": [T: "não subgrupo normal de com barra"] + - "": [T: "não contém como subgrupo normal com barra"] + - "": [T: "não diferença entre"] + - "": [T: "não geometricamente equivalente a"] + - "": [T: "não vertical semelhante"] + - "": [T: "não igual ou semelhante"] + - "": [T: "não vertical aproximado"] + - "": [T: "não aproximadamente idêntico a"] + - "": [T: "não irregular igual"] + - "": [T: "não irregular simples igual"] + - "": [T: "não igual ponto"] + - "": [T: "invertido não equivalente"] + - "": [T: "quadrado não contido"] + - "": [T: "quadrado não contendo"] + - "": [T: "não quase igual sobre igual"] + - "": [T: "não estritamente equivalente a"] + - "": [T: "não congruente ponto"] + - "": [T: "invertido não igual"] + - "": [T: "triângulo não vertical esquerda igual"] + - "": [T: "triângulo não vertical direita igual"] + - "": [T: "não parcial"] + - "": [T: "seta extensor"] + - "": [T: "seta para a direita sobre seta esquerda"] + - "": [T: "seta para a direita sobre seta esquerda"] + - "": [T: "arpão para a direita sobre arpão esquerda"] + - "": [T: "arpão para a direita sobre arpão esquerda"] + - "": [T: "seta dupla para nordeste e para sudoeste"] + - "": [T: "seta dupla para noroeste e para sudeste"] + - "": [T: "arpão horizontal extensor"] + - "": [T: "seta no sentido anti-horário arco para a esquerda"] + - "": [T: "seta no sentido anti-horário arco para a direita"] + - "": [T: "seta grande para a direita acento"] + - "": [T: "seta grande para a esquerda acento"] + - "": [T: "ponta de seta à esquerda"] + - "": [T: "ponta de seta à direita"] + - "": [T: "seta grande para a esquerda e para a direita com traço"] + - "": [T: "seta horizontal dupla extensor"] + - "": [T: "seta grande dupla para a esquerda e para a direita com traço"] + - "": [T: "seta para baixo à esquerda de seta para cima"] + - "": [T: "seta para a esquerda com canto baixo"] + - "": [T: "seta para a direita com canto cima"] + - "": [T: "seta para a esquerda com canto cima"] + - "": [T: "seta semicircular superior no sentido anti-horário com mais"] + - "": [T: "seta semicircular superior no sentido horário com menos"] + - "": [T: "seta para a direita com cauda com traço"] + - "": [T: "arpão para a direita com farpa para baixo"] + - "": [T: "arpão para a esquerda com farpa para baixo"] + - "": [T: "arpão para a esquerda e para a direita baixo"] + - "": [T: "arpão para a esquerda e para a direita cima"] + - "": [T: "arpão para cima e para baixo esquerda"] + - "": [T: "arpão para cima e para baixo direita"] + - "": [T: "seta para cima à direita de baixo seta"] + - "": [T: "arpão para a esquerda a barra com farpa cima"] + - "": [T: "arpão para a direita a barra com farpa cima"] + - "": [T: "arpão para a esquerda a barra com farpa baixo"] + - "": [T: "arpão para a direita a barra com farpa baixo"] + - "": [T: "arpão para a esquerda a partir de barra com farpa cima"] + - "": [T: "arpão para a direita a partir de barra com farpa cima"] + - "": [T: "arpão para a esquerda a partir de barra com farpa baixo"] + - "": [T: "arpão para a direita a partir de barra com farpa baixo"] + - "": [T: "arpão para cima a barra com farpa esquerda"] + - "": [T: "arpão para baixo a barra com farpa esquerda"] + - "": [T: "arpão para cima a barra com farpa direita"] + - "": [T: "arpão para baixo a barra com farpa direita"] + - "": [T: "arpão para cima a partir de barra com farpa esquerda"] + - "": [T: "arpão para baixo a partir de barra com farpa esquerda"] + - "": [T: "arpão para cima a partir de barra com farpa direita"] + - "": [T: "arpão para baixo a partir de barra com farpa direita"] + - "": [T: "seta para cima a barra"] + - "": [T: "seta para baixo a barra"] + - "": [T: "arpão para cima à esquerda de baixo arpão"] + - "": [T: "arpão para cima à direita de baixo arpão"] + - "": [T: "ponta de seta para cima"] + - "": [T: "ponta de seta para baixo"] + - "": [T: "arpão duplo com esquerda farpa baixo direita farpa cima"] + - "": [T: "arpão duplo com esquerda farpa cima direita farpa baixo"] + - "": [T: "seta para a esquerda barra superior"] + - "": [T: "seta para a direita barra superior"] + - "": [T: "seta para a esquerda barra inferior"] + - "": [T: "seta para a direita barra inferior"] + - "": [T: "seta tripla para a esquerda e para a direita"] + - "": [T: "seta dupla para nordeste e para sudeste"] + - "": [T: "seta semicircular no sentido anti-horário para a esquerda"] + - "": [T: "seta semicircular no sentido horário para a esquerda"] + - "": [T: "seta esquerda aberta círculo para a esquerda e para a direita"] + - "": [T: "seta para a direita sobre til"] + - "": [T: "seta para a esquerda sobre til"] + - "": [T: "arpão para a esquerda barra superior"] + - "": [T: "arpão para a direita barra superior"] + - "": [T: "arpão para a esquerda barra inferior"] + - "": [T: "arpão para a direita barra inferior"] + - "": [T: "seta achatado preta para a esquerda"] + - "": [T: "seta semicircular no sentido horário para a direita"] + - "": [T: "seta semicircular no sentido anti-horário para a direita"] + - "": [T: "arpão esquerda aberto círculo para a esquerda e para a direita"] + - "": [T: "seta para cima esquerda de barra vertical"] + - "": [T: "seta para baixo esquerda de barra vertical"] + - "": [T: "seta para cima direita de barra vertical"] + - "": [T: "seta para baixo direita de barra vertical"] + - "": [T: "seta para a direita com estendido baixo gancho"] + - "": [T: "seta para a esquerda com estendido gancho"] + - "": [T: "seta para a esquerda com estendido baixo gancho"] + - "": [T: "seta para a direita com estendido gancho"] + - "": [T: "seta não para a direita ondulado"] + - "": [T: "seta não para a direita curvo"] + - "": [T: "arpão para cima esquerda de barra vertical"] + - "": [T: "arpão para baixo esquerda de barra vertical"] + - "": [T: "arpão para cima direita de barra vertical"] + - "": [T: "arpão para baixo direita de barra vertical"] + - "": [T: "seta vertical dupla extensor"] + - "": [T: "arpão vertical com farpa esquerda extensor"] + - "": [T: "arpão vertical com farpa direita extensor"] + - "": [T: "arpão para a direita sobre esquerda arpão direita"] + - "": [T: "arpão para a direita sobre esquerda arpão esquerda"] + - "": [T: "arpão para a esquerda sobre direita arpão direita"] + - "": [T: "arpão para a esquerda sobre direita arpão esquerda"] + - "": [T: "seta para a esquerda a partir de barra ponta de seta"] + - "": [T: "seta para a esquerda e para a direita a partir de barra extensor"] + - "": [T: "seta para a esquerda a partir de barra cauda"] + - "": [T: "seta para a direita a partir de barra cauda"] + - "": [T: "seta para a direita a partir de barra ponta de seta"] + - "": [T: "arpão para cima a partir de barra com farpa esquerda ponta de seta"] + - "": [T: "seta para a direita sobre esquerda seta direita"] + - "": [T: "seta para a direita sobre esquerda seta esquerda"] + - "": [T: "seta para a esquerda sobre direita seta direita"] + - "": [T: "seta para a esquerda sobre direita seta esquerda"] + - "": [T: "seta para cima a partir de barra ponta de seta"] + - "": [T: "seta para cima a partir de barra cauda"] + - "": [T: "seta para baixo a partir de barra cauda"] + - "": [T: "seta para baixo a partir de barra ponta de seta"] + - "": [T: "arpão para baixo a partir de barra com farpa direita ponta de seta"] + - "": [T: "arpão para cima à esquerda de baixo arpão inferior"] + - "": [T: "arpão para cima à esquerda de baixo arpão extensor"] + - "": [T: "arpão para baixo à esquerda de cima arpão superior"] + - "": [T: "arpão para cima à esquerda de baixo arpão superior"] + - "": [T: "arpão para baixo à esquerda de o cima arpão extensor"] + - "": [T: "arpão para baixo à esquerda de o cima arpão inferior"] + - "": [T: "seta para cima esquerda de baixo seta inferior"] + - "": [T: "seta para baixo esquerda de cima seta superior"] + - "": [T: "seta para cima esquerda de baixo seta superior"] + - "": [T: "seta para baixo esquerda de cima seta inferior"] + - "": [T: "setas para a esquerda e para a direita extensor"] + - "": [T: "seta para nordeste extensor"] + - "": [T: "seta para noroeste extensor"] + - "": [T: "baixo apontando chave esquerda"] + - "": [T: "baixo apontando chave médio"] + - "": [T: "baixo apontando chave direita"] + - "": [T: "chave horizontal extensor"] + - "": [T: "cima apontando chave esquerda"] + - "": [T: "cima apontando chave médio"] + - "": [T: "apontando para chave direita para cima"] + - "": [T: "barra vertical à esquerda"] + - "": [T: "barra vertical à direita"] + - "": [T: "esquerda barra dupla vertical"] + - "": [T: "direita barra dupla vertical"] + - "": [T: "colchete horizontal extensor"] + - "": [T: "quadrado sob colchete"] + - "⎵": [T: "quadrado sob colchete"] + - "": [T: "quadrado sobre colchete"] + - "⎴": [T: "quadrado sobre colchete"] + - "": [T: "sob colchete esquerda"] + - "": [T: "sob colchete direita"] + - "": [T: "sobre colchete esquerda"] + - "": [T: "sobre colchete direita"] + - "": [T: "abre parênteses 1"] + - "": [T: "abre parênteses 2"] + - "": [T: "abre parênteses 3"] + - "": [T: "abre parênteses 4"] + - "": [T: "fecha parênteses 1"] + - "": [T: "fecha parênteses 2"] + - "": [T: "fecha parênteses 3"] + - "": [T: "fecha parênteses 4"] + - "": [T: "radical 1"] + - "": [T: "radical 2"] + - "": [T: "radical 3"] + - "": [T: "radical 4"] + - "": [T: "radical 5"] + - "": [T: "radical inferior"] + - "": [T: "radical extensor vertical"] + - "": [T: "radical superior"] + - "": [T: "esquerda colchete branco superior"] + - "": [T: "esquerda colchete branco extensor"] + - "": [T: "esquerda colchete branco inferior"] + - "": [T: "direita colchete branco superior"] + - "": [T: "direita colchete branco extensor"] + - "": [T: "direita colchete branco inferior"] + - "": [T: "abre colchete branco encaracolado"] + - "": [T: "fecha colchete branco encaracolado"] + - "": [T: "sinal longo de divisão"] + - "": [T: "sinal longo de divisão extensor"] + - "": [T: "divisão curta"] + - "": [T: "duplo sudoeste a nordeste ligação em"] + - "": [T: "duplo noroeste a sudeste ligação em"] + - "": [T: "simples horizontal ligação em"] + - "": [T: "duplo horizontal ligação em"] + - "": [T: "triplo horizontal ligação em"] + - "": [T: "simples vertical ligação em"] + - "": [T: "duplo vertical ligação em"] + - "": [T: "triplo vertical ligação em"] + - "": [T: "menor que ligação em"] + - "": [T: "maior que ligação em"] + - "": [T: "simples horizontal ligação en"] + - "": [T: "duplo horizontal ligação en"] + - "": [T: "triplo horizontal ligação en"] + - "": [T: "retângulo superior esquerda"] + - "": [T: "retângulo inferior esquerda"] + - "": [T: "retângulo superior direita"] + - "": [T: "retângulo inferior direita"] + - "": [T: "divisão sintética canto"] + - "": [T: "divisão sintética extensor horizontal"] + - "": [T: "divisão sintética extensor vertical"] + - "": [T: "esquerda teto piso extensor"] + - "": [T: "direita teto piso extensor"] + - "": [T: "sobre colchete extensor"] + - "": [T: "barra extensor vertical"] + - "": [T: "esquerda barra dupla extensor vertical"] + - "": [T: "barra extensor horizontal"] + - "": [T: "sob colchete extensor"] + - "": [T: "baixo apontando parêntese direita"] + - "": [T: "baixo apontando parêntese extensor"] + - "": [T: "baixo apontando parêntese esquerda"] + - "": [T: "cima apontando chave extensor"] + - "": [T: "cima apontando parêntese esquerda"] + - "": [T: "cima apontando parêntese extensor"] + - "": [T: "cima apontando parêntese direita"] + - "": [T: "baixo apontando chave extensor"] + - "": [T: "planck constante sobre dois pi barra"] + - "": [T: "g espelhado"] + - "": [T: "sem ponto jota"] + - "": [T: "digama"] + - "ϝ": [T: "digama"] + - "": [T: "dê"] + - "": [T: "e"] + - "": [T: "i"] + - "": [T: "jota"] + - "ⅅ": + - spell: "translate('.', 'ⅅ', 'DD')" # 0xed16, 0x2145 + - "": [T: "no sentido anti-horário contorno integral laço"] + - "": [T: "no sentido horário contorno integral laço"] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: "junção status"] + - "": [T: "junção status esquerda"] + - "": [T: "junção status direita"] + - "": [T: "junção status extensor"] + - "": [T: "integral laço"] + - "": [T: "integral laço duplo"] + - "": [T: "integral laço triplo"] + - "": [T: "expandindo integral laço duplo"] + - "": [T: "expandindo integral laço triplo"] + - "": [T: "assintoticamente igual a acento"] + - "": [T: "sinal de igual acento"] + - "": [T: "linha quádrupla"] + - "": [T: "círculo barra acento com aberto esquerda"] + - "": [T: "círculo barra acento com fechado esquerda"] + - "": [T: "círculo barra acento com aberto direita"] + - "": [T: "barra acento com sobre ponto"] + - "": [T: "barra acento com sob ponto"] + - "": [T: "barra acento com duplo sobre ponto"] + - "": [T: "barra acento com duplo sob ponto"] + - "": [T: "barra acento com circunflexo"] + - "": [T: "barra espessa acento inferior"] + - "": [T: "círculo barra acento com fechado direita"] + - "": [T: "ponto grande acima de"] + - "": [T: "alinhamento marca"] + - "": [T: ""] + - "​": [T: ""] + - "": [T: ""] + - " ": [T: ""] + - "": [T: ""] + - " ": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - " ": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: ""] + - "": [T: "ausente termo"] + - "": [T: "seta no sentido horário contorno integral sobre esquerda"] + - "": [T: "quadrado integral com"] + - "": [T: "integral com barra"] + - "": [T: "integral invertida"] + - "": [T: "duplo zero sobre duplo zero"] + - "": [T: "zero com barra"] + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "ligadura a e"] + - "": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "sustenido esse"] + - "": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] + else: [x: "$SpeechOverrides_CapitalLetters"] + - pitch: + value: "$CapitalLetters_Pitch" + replace: [T: "o com traço"] + - "": + - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" + - T: "vazado" + - "-": + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - T: "vazado" + - "": [T: "vazado final sigma"] + - "": [T: "vazado rô"] + - "": [T: "vazado fi"] + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝐴-𝑍": + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝑎-𝑧": + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔𝑕𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝖠-𝖹": + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝖺-𝗓": + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝗔-𝗭": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝗮-𝘇": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘈-𝘡": + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝘢-𝘻": + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝘼-𝙕": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝙖-𝙯": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "𝙰-𝚉": + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "-": + - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝚊-𝚣": + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + - "-": + - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" + - "": [T: "sem ponto i"] + - "𝚤": [T: "sem ponto i"] + - "𝚥": [T: "sem ponto jota"] + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "": [T: "em negrito nábela"] + - "𝛁": [T: "em negrito nábela"] + - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" + - "": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '∂εθκφρπ')" + - "𝛢-𝛺": + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝛼-𝜔": + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "-": + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "": [T: "itálico nábela"] + - "𝛻": [T: "itálico nábela"] + - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": + - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" + - "": + - spell: "translate('.', '', '∂εθκφρπ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" + - "": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '∂εθκφρπ')" + - "𝜵": [T: "em negrito itálico nábela"] + - "": [T: "em negrito itálico nábela"] + - "𝝖-𝝮": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝝰-𝞈": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" + - "": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '∂εθκφρπ')" + - "": [T: "em negrito nábela"] + - "𝝯": [T: "em negrito nábela"] + - "𝞐-𝞨": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" + - "𝞪-𝟂": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" + - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" + - "": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '∂εθκφρπ')" + - "": [T: "em negrito nábela"] + - "𝞩": [T: "em negrito nábela"] + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '0123456789')" + - "𝟎-𝟗": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + - "-": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '', '0123456789')" + - "𝟬-𝟵": + - test: + if: "not($IgnoreBold)" + then: [T: "negrito"] + - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" + - "-": + - spell: "translate('.', '', '0123456789')" + - "𝟢-𝟫": + - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" + - "𝟶-𝟿": + - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + - "": [T: "desconhecido caractere"] + - "": [T: "triângulos inferior direita e inferior esquerda"] + - "": [T: "horizontal reticências extensor"] + - "": [T: "linha média horizontal reticências extensor"] + - "": [T: "radical extensor"] + - "": [T: "seta vertical extensor"] + - "": [T: "seta horizontal extensor"] + - "": [T: "registrado sinal sem serifa"] + - "": [T: "direitos autorais sinal sem serifa"] + - "": [T: "marca registrada sinal sem serifa"] + - "": [T: "parêntese superior à esquerda"] + - "": [T: "parêntese extensor à esquerda"] + - "": [T: "parêntese inferior à esquerda"] + - "": [T: "colchete superior à esquerda"] + - "": [T: "colchete extensor à esquerda"] + - "": [T: "colchete inferior à esquerda"] + - "": [T: "chave superior à esquerda"] + - "": [T: "chave médio à esquerda"] + - "": [T: "chave inferior à esquerda"] + - "": [T: "chave extensor"] + - "": [T: "integral extensor"] + - "": [T: "parêntese superior à direita"] + - "": [T: "parêntese extensor à direita"] + - "": [T: "parêntese inferior à direita"] + - "": [T: "colchete superior à direita"] + - "": [T: "colchete extensor à direita"] + - "": [T: "colchete inferior à direita"] + - "": [T: "chave superior à direita"] + - "": [T: "chave médio à direita"] + - "": [T: "chave inferior à direita"] + - "": [T: "logo da apple"] + - "ff": [T: "ligadura ff"] + - "fi": [T: "ligadura fi"] + - "fl": [T: "ligadura fl"] + - "ffi": [T: "ligadura ffi"] + - "ffl": [T: "ligadura ffl"] + - "ſt": [T: "pés"] + - "st": [T: "st"] + - "﬩": [T: "letra hebraica alternativa mais"] + - "︠": [T: "ligadura esquerda metade"] + - "︡": [T: "ligadura direita metade"] + - "︢": [T: "til duplo esquerda metade"] + - "︣": [T: "til duplo direita metade"] + - "︤": [T: "mácron esquerda metade"] + - "︥": [T: "mácron direita metade"] + - "︦": [T: "conjugando mácron"] + - "︵": [T: "sobre parêntese"] + - "︶": [T: "sob parêntese"] + - "︷": [T: "sobre chave"] + - "︸": [T: "sob chave"] + - "︿": [T: "sobre colchete angular"] + - "﹀": [T: "sob colchete angular"] + - "﹡": [T: "pequeno asterisco"] + - "﹢": [T: "pequeno mais"] + - "﹣": [T: "pequeno menos"] + - "﹤": [T: "pequeno menor que"] + - "﹥": [T: "pequeno maior que"] + - "﹦": [T: "pequeno igual"] + - "+": [T: "de largura total sinal de mais"] + - "<": [T: "menor que"] + - "=": [T: "igual"] + - ">": [T: "maior que"] + - "\": [T: "barra invertida"] + - "^": [T: "chapéu"] + - "|": + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "$DefaultToGiven" + then: [T: "dado"] + else: [T: "barra vertical"] + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "barra vertical"] + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "tal que"] + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [T: "dado"] + - else: [T: "divide"] + - "~": [T: "til"] + - "¬": [T: "não"] + - "←": [T: "seta para a esquerda"] + - "↑": [T: "seta para cima"] + - "→": [T: "seta para a direita"] + - "↓": [T: "seta para baixo"] + - "": [T: "desconhecido ou ausente objeto"] + - "�": [T: "ausente caractere"] + - "🣑": [T: "é em equilíbrio com"] + - "🣒": [T: "está em equilíbrio deslocado para a direita com"] + - "🣓": [T: "está em equilíbrio deslocado para a esquerda com"] +# ==== FIM DO RECUO CONTROLADO ==== diff --git a/Rules/Languages/pt/unicode.yaml b/Rules/Languages/pt/unicode.yaml new file mode 100644 index 000000000..64b3fb518 --- /dev/null +++ b/Rules/Languages/pt/unicode.yaml @@ -0,0 +1,571 @@ +--- + # Note to translators: + # most languages don't have two ways to pronounce 'a' -- if not need, remove the rules and change "B-Z" to "A-Z" + # some languages say the word for "uppercase" after the letter. Make sure to change that where appropriate by moving some code around + - "a-z": + - test: + if: "$TTS='none'" + then: [T: "."] + else: [spell: "'.'"] + - "A-Z": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] # (en: 'cap', google 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')"] + + - "0-9": [T: "."] # (en: '.') + + - " ": [t: " "] # 0x20 + + - "!": # 0x21 + # Restaura a ramificação do inglês: dentro de :literal: é pontuação, fora + # é o operador. Sem isto, um ponto de exclamação literal é lido "fatorial". + - test: + if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then_test: + if: "$Verbosity = 'Terse'" + then: [T: "exclamação"] # (en: 'bang') + else: [T: "ponto de exclamação"] # (en: 'exclamation point') + else: [T: "fatorial"] # (en: 'factorial') + - "\"": [T: "aspas"] # 0x22 (en: 'quotation mark') + - "#": [T: "número"] # 0x23 (en: 'number', MathPlayer: 'signo de número', google: 'número') + - "$": [T: "dólares"] # 0x24 (en: 'dollars') + - "%": [T: "por cento"] # 0x25 (en: 'percent') + - "&": [T: "e comercial"] # 0x26 + - "'": [T: "apóstrofo"] # 0x27 (en: 'apostrophe', MathPlayer: 'apóstrofo', google: 'apóstrofe') + - "(": # 0x28 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "abre parênteses"] # (en: 'open', google translation) + else: [T: "abre parênteses"] # (en: 'open paren', MathPlayer: 'paréntesis', google: 'paréntesis abierto') + else: [T: "abre parênteses"] # (en: 'left paren', MathPlayer: 'paréntesis', google: 'paréntesis dejado') + - ")": # 0x29 + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then_test: + if: "$Verbosity='Terse'" + then: [T: "fecha parênteses"] # (en: 'close', google translation) + else: [T: "fecha parênteses"] # (en: 'close paren', MathPlayer: 'cierra paréntesis', google: 'paréntesis cercana') + else: [T: "fecha parênteses"] # (en: 'right paren', MathPlayer: 'cierra paréntesis') + + - "*": # 0x2a + test: + if: "parent::*[name(.)='msup' or name(.)='msubsup']" + then: [T: "asterisco"] # (en: 'star', google translation) + else: [T: "vezes"] # (en: 'times') + - "+": [T: "mais"] # 0x2b (en: 'plus') + - ",": # 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 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or " + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak "comma" when not adjacent to '…' + - "( following-sibling::*[1][text()!= '…'] and preceding-sibling::*[1][text()!='…'] ) or " + # except if expression starts with '…' + - "../*[1][.='…'] " + then: + - T: "vírgula" # (en: 'comma', google translation) + - test: + if: "$Verbosity != Terse" + then: [pause: short] + # else silent + + - "-": [T: "menos"] # 0x2d (en: 'minus') + - ".": # 0x2e + - test: + if: "parent::*[1][self::m:mn]" + then: [T: "ponto"] # (en: 'point', google translation) + else: [T: "ponto"] # (en: 'dot') + - "/": [T: "barra"] # 0x2f (en: 'divided by') + - ":": [T: "dois pontos"] # 0x3a (en: 'colon') + - ";": [T: "ponto e vírgula"] # 0x3b (en: 'semicolon') + - "<": # 0x3c + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "menor que" # (en: 'less than') + - "=": # 0x3d + - test: + if: "$Verbosity!='Terse'" + then: [T: "é igual a"] # (en: 'is equal to', google translation) + else: [T: "igual a"] # (en: 'equals', google: 'iguales') + + - ">": # 0x3e + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "maior que" # (en: 'greater than') + - "?": [T: "ponto de interrogação"] # 0x3f (en: 'question mark', MathPlayer: 'cierra interrogación', google: 'signo de interrogación') + - "@": [T: "arroba"] # 0x40 (en: 'at sign') + - "[": # 0x5b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "abre colchetes"] # (en: 'open bracket', google translation) + else: [T: "abre colchetes"] # (en: 'left bracket', MathPlayer: 'abre corchetes', google: 'soporte izquierdo') + - "\\": [T: "barra invertida"] # 0x5c (en: 'back slash', MathPlayer: 'abre corchetes', google: 'back slash') + - "]": # 0x5d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "fecha colchetes"] # (en: 'close bracket', google translation) + else: [T: "fecha colchetes"] # (en: 'right bracket', MathPlayer: 'cierra corchetes', google: 'soporte derecho') + # NOTA: o inglês distingue 'hat' (ornamento sobre variável) de 'caret' + # (o símbolo isolado). O português usa "circunflexo" nos dois casos, então + # o teste contextual seria redundante e foi omitido de propósito. + - "^": [T: "circunflexo"] # 0x5e (en: 'hat' / 'caret') + - "_": [T: "sublinhado"] # 0x5f (en: 'under bar') + - "`": [T: "acento grave"] # 0x60 (en: 'grave') + - "{": # 0x7b + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "abre chaves"] # (en: 'open brace', google translation) + else: [T: "abre chaves"] # (en: 'left brace', MathPlayer: 'abre llaves', google: 'abrazadera izquierda') + - "|": # 0x7c + # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' + # CORREÇÃO: a versão anterior era uma simplificação da regra inglesa e perdia + # três casos: P(A|B) ("dado"), a|b entre números ("divide") e o intent literal. + # Fora do ClearSpeak tudo caía em "barra vertical". + - with: + variables: [DefaultToGiven: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']"] # P(A|B) + replace: + - test: + - if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" + then: [T: "barra vertical"] # (en: 'vertical line') + - else_if: "$SpeechStyle != 'ClearSpeak'" + then_test: + - if: "$DefaultToGiven" + then: [T: "dado"] # (en: 'given') + - 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: "divide"] # (en: 'divides') + else: [T: "barra vertical"] # (en: 'vertical line') + - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" + then: [T: "barra vertical"] # (en: 'vertical line') + - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" + then: [T: "tal que"] # (en: 'such that') + - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" + then: [T: "dado"] # (en: 'given') + - else: [T: "divide"] # (en: 'divides') + + - "}": # 0x7d + - test: + if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' + then: [T: "fecha chaves"] # (en: 'close brace', google translation) + else: [T: "fecha chaves"] # (en: 'right brace', MathPlayer: 'cierra llaves', google: 'abrazadera derecha') + + - "~": [T: "til"] # 0x7e + - " ": # 0xa0 + - test: + if: "@data-empty-in-2D" + then: [T: "vazio"] # want to say something for fraction (etc) with empty child (en: 'empty', google translation) + else: [T: ""] + + - "¢": [T: "centavos"] # 0xa2 (en: 'cents') + - "£": [T: "libras"] # 0xa3 (en: 'pounds') + - "¬": [T: "não"] # 0xac (en: 'not') + - "°": [T: "graus"] # 0xb0 (en: 'degrees') + - "±": [T: "mais ou menos"] # 0xb1 (en: 'plus or minus') + - "´": [T: "acento agudo"] # 0xb4 (en: 'acute') + - "·": # 0xB7 + - test: + if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" + then_test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] # (en: 'times', google translation) + else: [T: "vezes"] + else: [T: "vezes"] # (en: 'dot') + - "×": # 0xd7 + - test: + if: "$Verbosity = 'Verbose'" + then: [T: "multiplicado por"] # (en: 'times', google translation) + else: [T: "vezes"] + - "÷": [T: "dividido por"] # 0xf7 (en: 'divided by') + - "̀": [T: "acento grave"] # 0x300 (en: 'grave accent embellishment', google: 'embellido de acento grave') + - "́": [T: "com acento agudo"] # 0x301 (en: 'acute accent embellishment', google: 'embellido de acento agudo') + - "̂": [T: "com acento circunflexo"] # 0x302 (en: 'circumflex accent embellishment', google: 'embellamiento del acento circunflejo') + - "̃": [T: "til"] # 0x303 (en: 'tilde embellishment', google: 'tilde adorno') + - "̄": [T: "com mácron"] # 0x304 (en: 'macron embellishment', google: 'embellido de macron') + - "̅": [T: "com barra acima"] # 0x305 (en: 'overbar embellishment', google: 'embellido de overbar') + - "̆": [T: "breve"] # 0x306 + - "̇": [T: "ponto acima"] # 0x307 (en: 'dot above embellishment', google: 'punto por encima del adorno') + + # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong + - "Α-Ω": + - test: + if: "$CapitalLetters_Beep" + then: + - audio: + value: "beep.mp4" + replace: [] + - test: + if: "$CapitalLetters_UseWord" + then_test: + if: "$SpeechOverrides_CapitalLetters = ''" + then_test: + if: "$Impairment = 'Blindness'" + then: [T: "maiúscula"] # (en: 'cap', google 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('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] + + - "α": [T: "alfa"] # 0x3b1 (en: 'alpha') + - "β": [T: "beta"] # 0x3b2 + - "γ": [T: "gama"] # 0x3b3 (google: 'gama') + - "δ": [T: "delta"] # 0x3b4 + - "ε": [T: "épsilon"] # 0x3b5 (en: 'epsilon', google: 'epsilon') + - "ζ": [T: "zeta"] # 0x3b6 + - "η": [T: "eta"] # 0x3b7 + - "θ": [T: "teta"] # 0x3b8 + - "ι": [T: "iota"] # 0x3b9 + - "κ": [T: "capa"] # 0x3ba + - "λ": [T: "lambda"] # 0x3bb + - "μ": [T: "mi"] # 0x3bc (en: 'mu', google: 'mu') + - "ν": [T: "ni"] # 0x3bd (en: 'nu', google: 'nu') + - "ξ": [T: "csi"] # 0x3be (en: 'zai', google: 'zai') + - "ο": [T: "ômicron"] # 0x3bf (en: 'omicron', google: 'omicron') + - "π": [T: "pi"] # 0x3c0 + - "ρ": [T: "rô"] # 0x3c1 + - "ς": [T: "sigma final"] # 0x3c2 (en: 'final sigma', google: 'final sigma') + - "σ": [T: "sigma"] # 0x3c3 + - "τ": [T: "tau"] # 0x3c4 + - "υ": [T: "úpsilon"] # 0x3c5 (en: 'upsilon', google: 'upsilon') + - "φ": [T: "fi"] # 0x3c6 (google: 'fi') + - "χ": [T: "qui"] # 0x3c7 (en: 'chi', google: 'chi') + - "ψ": [T: "psi"] # 0x3c8 + - "ω": [T: "ômega"] # 0x3c9 + - "ϕ": [T: "fi reto"] # 0x3d5 (en: 'phi', google: 'fi') + - "ϖ": [T: "pi variante"] # 0x3d6 (en: 'pi', google: 'pi') + - "ϵ": [T: "épsilon variante"] # 0x3f5 (en: 'epsilon', google: 'epsilon') + - "϶": [T: "épsilon invertido"] # 0x3f6 (en: 'reversed epsilon') + + - "⁢": [T: ""] # 0x2062 + - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" + # Adjetivo de estilo POSPOSTO (decisão 8.1): o spell: vem primeiro. + - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" + - T: "vazado" # (en: 'double-struck', google: 'doble golpe') + + - "℃": [T: "graus Celsius"] # 0x2103 (en: 'degrees celsius', google: 'grados celsius') + - "ℋℛℓ": # 0x210b + # 'caligráfico', não 'cursivo': termo único da família script, igual ao + # que o unicode-full.yaml usa (ℐ ℒ ℘ ℬ ℰ ℱ ℳ). t: minúsculo porque a + # escolha entre os dois ainda depende de escuta — ver ACHADOS 7.8. + - spell: "translate('.', 'ℋℛℓ', 'HRl')" + - t: "caligráfico" # (en: 'script', google: 'guion') + - "ℜ": # 0x211c + # 'fraktur', não 'gótico': termo único da família, igual ao + # unicode-full.yaml (ℑ ℌ ℨ ℭ e os blocos do plano 1). t: minúsculo. + - spell: "'R'" + - t: "fraktur" # (en: 'fraktur', google: 'fraktur') + + - "ⅆⅇⅈⅉ": # 0x2146-9 + - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" + - T: "vazado itálico" # (en: 'double-struck italic') + + - "∥": # 0x2225 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "paralela a" # (en: 'parallel to') + - "∦": # 0x2226 + # audit-ignore: em português a negação já é frase completa; o "is" do inglês + # não tem par que valha suprimir no Terse. Com o ramo "é" a fala saía + # "é não é paralela a". Mesmo tratamento que ≢, ≇, ⊈ e ⊉. + - T: "não é paralela a" # (en: 'not parallel to') + - "≤": # 0x2264 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "menor ou igual a" + - "≥": # 0x2265 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "maior ou igual a" # (en: 'greater than or equal to') + + # --- restored complex short definitions (prefer over unicode-full) --- + - "…": # 0x2026 + test: + if: + - "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_Ellipses = 'Auto' or" + # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' + # speak '…' as 'and so on...' unless expr starts with '…' + - "../*[1][.='…']" + then: [T: "reticências"] # (en: 'dot dot dot', google translation) + else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' + if: "count(following-sibling::*) = 0" + then: [T: "etcétera"] # (en: 'and so on', google translation) + else: [T: "reticências"] # (en: 'and so on up to', MathPlayer: 'punto punteado punteado', google: 'y así sucesivamente') + - "⁡": # 0x2061 + - test: + # skip saying "of" when Terse and a trig function, when it is a shape (does this happen?), or we are in :literal mode + if: "not( + ( $Verbosity='Terse' or ($SpeechStyle = 'ClearSpeak' and IsNode(following-sibling::*[1],'simple')) and + preceding-sibling::*[1][IfThenElse($SpeechStyle='ClearSpeak', + IsInDefinition(., 'ClearSpeakTrigFunctionNames'), + IsInDefinition(., 'TrigFunctionNames') )] + ) or + preceding-sibling::*[1][IsInDefinition(., 'GeometryShapes')] or + (@data-changed='added' and ancestor-or-self::*[contains(@data-intent-property, ':literal:')]) + )" + then: [T: "de"] # (en: 'of', google translation) + - "→": # 0x2192 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "tende a"] # (en: 'approaches') + else: [T: "seta para a direita"] # (en: 'right arrow', MathPlayer: 'flecha', google: 'flecha correcta') + - "∂": # 0x2202 + - test: + if: "$Verbosity='Terse'" + then: [T: "parcial"] # (en: 'partial', google translation) + else: [T: "derivada parcial"] # (en: 'partial derivative') + - "∆": # 0x2206 + - test: + if: "$Verbosity!='Terse'" + then: [T: "o"] # (en: 'the', google translation) + - T: "incremento" # (en: 'laplacian of') + - "∈": # 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + # Também aqui o ramo dentro de um conjunto precisa do particípio: uma + # string só para os dois contextos daria "o conjunto de todos os x + # pertence a inteiros", com o verbo grudando em "conjunto". + then_test: + if: "../../self::m:set or ../../../self::m:set" + then: [T: "pertencentes a"] + else: [T: "pertence a"] # (en: 'an element of'; uso brasileiro corrente) + # 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: + # DENTRO de um conjunto a expressão modifica "todos os x": nada de + # verbo finito (grudaria em "conjunto") e concordância no plural. + # É o que o inglês faz com 'in / member of / element of / belonging to'. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "em"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "membros de"] # (en: 'member of'; plural concorda com "todos os x") + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "elementos de"] # (en: 'element of'; plural concorda com "todos os x") + - else: [T: "pertencentes a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + # Auto separado de Member, como o ∉ já tinha: com as preferências + # padrão ($ClearSpeak_SetMemberSymbol = 'Auto') o brasileiro + # corrente é "pertence a". Ver ACHADOS 7.8. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' + then: [T: "pertence a"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "é membro de"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "é um elemento de"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "está em"] # (en: 'is in', google translation) + - else: [T: "pertence a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "∉": # 0x2209 + # rule is identical to 0x2208 + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "../../self::m:set or ../../../self::m:set" + then: [T: "não pertencentes a"] + else: [T: "não pertence a"] # (en: 'is not an element of'; uso brasileiro) + # 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: + # Idem ao 0x2208: sem verbo finito, concordando com "todos os x". + # "não em" é truncado ("não" não nega preposição nua) e "fora de" + # troca o conceito (afirma localização em vez de negar pertinência, + # ambíguo com complementar). Fica a forma nominal da negação, que + # coincide com o ramo Belongs — decisão registrada em + # TERMINOLOGIA_PT_BR.md e ACHADOS 7.9. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "não pertencentes a"] # (en: 'not in') + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "não membros de"] # (en: 'not member of') + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "não elementos de"] # (en: 'not element of') + - else: [T: "não pertencentes a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'not belonging to') + else_test: + - if: $ClearSpeak_SetMemberSymbol = 'Auto' + then: [T: "não pertence a"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "não é membro de"] # (en: 'is not a member of') + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "não é um elemento de"] # (en: 'is not an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + # Era "não está contido em", que é exatamente a fala do ⊄ + # (ver 0x2284): duas relações distintas soavam iguais. Agora + # espelha o "está em" do ∈ e o que o próprio ∉ diz num conjunto. + then: [T: "não está em"] # (en: 'is not in', google translation) + - else: [T: "não pertence a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'does not belong to') + - "∊": # 0x220a + # variante de forma do 0x2208: fala igual ao ∈ em todos os ramos. + - test: + if: "$SpeechStyle != 'ClearSpeak'" + then_test: + if: "../../self::m:set or ../../../self::m:set" + then: [T: "pertencentes a"] + else: [T: "pertence a"] # alinhado ao ∈ (era "é um elemento de") + # 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: + # DENTRO de um conjunto a expressão modifica "todos os x": nada de + # verbo finito (grudaria em "conjunto") e concordância no plural. + # É o que o inglês faz com 'in / member of / element of / belonging to'. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "em"] # (en: 'in', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "membros de"] # (en: 'member of'; plural concorda com "todos os x") + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "elementos de"] # (en: 'element of'; plural concorda com "todos os x") + - else: [T: "pertencentes a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to') + else_test: + # Auto separado de Member, igual ao ∈ e ao ∉. Ver ACHADOS 7.8. + - if: $ClearSpeak_SetMemberSymbol = 'Auto' + then: [T: "pertence a"] + - else_if: $ClearSpeak_SetMemberSymbol = 'Member' + then: [T: "é membro de"] # (en: 'is a member of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'Element' + then: [T: "é um elemento de"] # (en: 'is an element of', google translation) + - else_if: $ClearSpeak_SetMemberSymbol = 'In' + then: [T: "está em"] # (en: 'is in', google translation) + - else: [T: "pertence a"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belongs to') + - "√": # 0x221a + - test: + if: "$Verbosity!='Terse'" + then: [T: "a"] # (en: 'the', google translation) + - T: "raiz quadrada de" # (en: 'square root of') + - "∝": # 0x221d + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "proporcional a" # (en: 'proportional to') + - "∶": # 0x2236 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "a" # (en: 'to') + - "∾": # 0x223e + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "mais positivo" # (en: 'most positive') + - "≠": # 0x2260 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # ("diferente de" já dispensa a cópula) + - T: "diferente de" # (en: 'not equal to'; MathPlayer sugeria 'distinto de' e o algoritmo escolheu a do Google) + - "≡": # 0x2261 + - test: + if: "$Verbosity!='Terse'" + then: [T: "é"] # (en: 'is', google translation) + - T: "idêntico a" # (en: 'identical to') + - "⊂": # 0x2282 + - test: + if: "$Verbosity!='Terse'" + then: [T: "está"] # (en: 'is a'; "está contido em" é o uso brasileiro) + - T: "contido em" # (en: 'subset of') + - "⊃": # 0x2283 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (en: 'is a'; "contém" já é verbo) + - T: "contém" # (en: 'superset of') + - "⊄": # 0x2284 + - test: + if: "$Verbosity!='Terse'" + then: [T: "não"] # (coerente com ⊂: "não está contido em") + - T: "está contido em" # (en: 'not a subset of') + - "⊅": # 0x2285 + - test: + if: "$Verbosity!='Terse'" + then: [T: "não"] # (coerente com ⊃) + - T: "contém" # (en: 'not a superset of') + - "⊆": # 0x2286 + - test: + if: "$Verbosity!='Terse'" + then: [T: "está"] # (coerente com ⊂) + - T: "contido em ou é igual a" # (en: 'subset of or equal to') + - "⊇": # 0x2287 + - test: + if: "$Verbosity!='Terse'" + then: [T: ""] # (coerente com ⊃) + - T: "contém ou é igual a" # (en: 'superset of or equal to') + + # --- restored short definitions that differ from unicode-full --- + - "–": [T: "meia-risca"] # 0x2013 (en: 'en dash') + - "—": [T: "travessão"] # 0x2014 (en: 'em dash') + - "‖": [T: "barra vertical dupla"] # 0x2016 (en: 'double vertical line') + - "″": [T: "duas linhas"] # 0x2033 (en: 'double prime', MathPlayer: 'segunda', google: 'doble primo') + - "‴": [T: "três linhas"] # 0x2034 (en: 'triple prime', MathPlayer: 'tercera', google: 'triple prime') + - "‵": [T: "linha invertida"] # 0x2035 (en: 'reversed prime') + - "‶": [T: "duas linhas invertidas"] # 0x2036 (en: 'reversed double prime') + - "‷": [T: "três linhas invertidas"] # 0x2037 (en: 'reversed triple prime', google: 'triple prime invertido') + - "℉": [T: "graus Fahrenheit"] # 0x2109 (en: 'degrees fahrenheit') + - "ℎ": [T: "constante de Planck"] # 0x210e (en: 'planck constant', MathPlayer: 'constante de Planck', google: 'planck constante') + - "K": [T: "kelvin"] # 0x212a (en: 'kelvin') + - "←": [T: "seta para a esquerda"] # 0x2190 (en: 'leftwards arrow') + - "↑": [T: "seta para cima"] # 0x2191 (en: 'upwards arrow') + - "↓": [T: "seta para baixo"] # 0x2193 (en: 'downwards arrow') + - "⇒": [T: "implica que"] # 0x21d2 (en: 'rightwards double arrow') + - "∘": [T: "composto com"] # 0x2218 (en: 'composed with') + - "∣": # 0x2223 (en: 'divides') + # O latex2mathml emite \mid como U+2223, não como "|". Em P(A ∣ B) é + # "dado" — mesma condição de contexto da regra do "|" (0x7c). Fora disso, + # continua "divide" (a ∣ b entre inteiros). Ver ACHADOS 9.6. + - test: + if: "count(preceding-sibling::*)=1 and count(following-sibling::*)=1 and ../../../*[1][.='P']" + then: [T: "dado"] # (en: 'given') + else: [T: "divide"] + - "∤": [T: "não divide"] # 0x2224 (en: 'does not divide') + - "∷": [T: "como"] # 0x2237 (en: 'as') + - "∼": [T: "varia com"] # 0x223c (en: 'varies with') + - "∽": [T: "til invertido"] # 0x223d (en: 'reversed tilde') + - "∿": [T: "onda senoidal"] # 0x223f (en: 'sine wave') + - "≦": [T: "menor ou igual a"] # 0x2266 (en: 'less than over equal to') + - "≧": [T: "maior ou igual a"] # 0x2267 (en: 'greater than over equal to') + +# --- ACRÉSCIMOS pt (não existiam no es e caíam no unicode-full em inglês) --- + - "≪": [T: "é muito menor que"] # 0x226a (en: 'much less than') + - "≫": [T: "é muito maior que"] # 0x226b (en: 'much greater than') + - "⊥": [T: "é perpendicular a"] # 0x22a5 (en: 'perpendicular to') +# Ornamentos usados em variáveis modificadas (x com trema = 2a derivada): + - "̌": [T: "cáron"] # 0x030c (en: 'caron embellishment') + - "̈": [T: "dois pontos"] # 0x0308 (en: 'double dot above') + - "⃛": [T: "três pontos acima"] # 0x20db (en: 'triple dot above') + - "⃜": [T: "quatro pontos acima"] # 0x20dc (en: 'quadruple dot above') + - "⁤": [T: "e"] # 0x2064 (invisible plus — "dois e um meio"); FALTAVA em pt + - "∐": [T: "coproduto"] # 0x2210 (en: 'co-product'); FALTAVA em pt + - "⁣": [T: ""] # 0x2063 (invisible separator — silencioso) + - "′": [T: "linha"] # 0x2032 (en: 'prime') + - "↗": # 0x2197 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "tende por baixo a"] + else: [T: "seta para nordeste"] + - "↘": # 0x2198 + - test: + if: "ancestor::*[2][self::m:limit]" + then: [T: "tende por cima a"] + else: [T: "seta para sudeste"] + - "˙": [T: "ponto"] # 0x02d9 (dot above) + - "¨": [T: "dois pontos"] # 0x00a8 (diaeresis / 2a derivada) diff --git a/tests/Languages/pt.rs b/tests/Languages/pt.rs new file mode 100644 index 000000000..dac447ebd --- /dev/null +++ b/tests/Languages/pt.rs @@ -0,0 +1,17 @@ +#![allow(non_snake_case)] +// Módulo de testes do idioma pt (português). +// IMPORTANTE: acrescente `mod pt;` em tests/languages.rs para ativar. +mod ClearSpeak { + mod sets; +} +mod SimpleSpeak { + mod functions; +} +mod shared; +mod chemistry; +mod alphabets; +mod intent; +mod units; +mod unicode_full; +mod escuta; // gerador do pacote de escuta (#[ignore]) + diff --git a/tests/Languages/pt/ClearSpeak/sets.rs b/tests/Languages/pt/ClearSpeak/sets.rs new file mode 100644 index 000000000..ff2ee45cd --- /dev/null +++ b/tests/Languages/pt/ClearSpeak/sets.rs @@ -0,0 +1,398 @@ +/// Testes de conjuntos e pertinência — pt-BR, ClearSpeak e SimpleSpeak. +/// +/// POR QUE ESTE ARQUIVO EXISTE +/// O par ∈ / ∊ falou "é membro de" com as preferências padrão durante duas +/// rodadas inteiras sem ninguém notar, porque o pt não tinha NENHUM teste de +/// pertinência — nem ClearSpeak, nem SimpleSpeak. O ∉ foi corrigido sozinho +/// numa rodada e os outros dois ficaram para trás. Ver ACHADOS 7.8. +/// +/// A invariante que este arquivo trava: **∈ (0x2208) e ∊ (0x220a) são +/// variantes de forma do mesmo símbolo e devem falar igual em todos os ramos** +/// — nas cinco preferências de ClearSpeak_SetMemberSymbol, dentro e fora de +/// um conjunto, nos dois estilos de fala. +/// +/// COMO AS EXPECTATIVAS FORAM ESCRITAS +/// Todas saíram da saída real do motor, nunca de tradução do inglês. O método +/// é o do cabeçalho de tests/Languages/pt/shared.rs: rodar, comparar `left` +/// com `right`, e se o gerado estiver certo em português, copiá-lo; se estiver +/// errado, consertar a REGRA, nunca o teste. +/// +/// Cada teste de pertinência fixa ClearSpeak_SetMemberSymbol explicitamente, +/// inclusive no caso 'Auto'. Isso é de propósito: as preferências de +/// ClearSpeak não são reinicializadas entre testes na mesma thread, então um +/// teste que dependesse do padrão implícito poderia passar ou falhar conforme +/// a ordem de execução. + +use crate::common::*; +use anyhow::Result; + +// x ℝ — pertinência FORA de um conjunto (ramo else_test das regras) +fn sozinho(simbolo: &str) -> String { + format!("x{simbolo}ℝ") +} + +// { x ℤ : x > 5 } — pertinência DENTRO de um conjunto (ramo then_test) +fn no_conjunto(simbolo: &str) -> String { + format!(" + {{ + x {simbolo} ℤ + : x > 5 + }} + ") +} + +const PERTENCE: &str = "\u{2208}"; // ∈ +const NAO_PERTENCE: &str = "\u{2209}"; // ∉ +const PERTENCE_PEQ: &str = "\u{220A}"; // ∊ — variante de forma do 0x2208 + +/// ∈ e ∊ têm de falar igual. É o caso que sobreviveu duas rodadas. +fn ambas_variantes(pref: &str, expr: fn(&str) -> String, esperado: &str) -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", pref, &expr(PERTENCE), esperado)?; + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", pref, &expr(PERTENCE_PEQ), esperado)?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Conjuntos numéricos +// --------------------------------------------------------------------------- + +#[test] +fn complexos() -> Result<()> { + test("pt", "ClearSpeak", "ℂ", "números complexos")?; + return Ok(()); +} + +#[test] +fn naturais() -> Result<()> { + test("pt", "ClearSpeak", "ℕ", "números naturais")?; + return Ok(()); +} + +#[test] +fn racionais() -> Result<()> { + test("pt", "ClearSpeak", "ℚ", "números racionais")?; + return Ok(()); +} + +#[test] +fn reais() -> Result<()> { + test("pt", "ClearSpeak", "ℝ", "números reais")?; + return Ok(()); +} + +// Sem "números", diferente dos quatro acima. O inglês tem a mesma assimetria +// ("the integers" contra "the complex numbers"), então isto acompanha o en. +#[test] +fn inteiros() -> Result<()> { + test("pt", "ClearSpeak", "ℤ", "inteiros")?; + return Ok(()); +} + +#[test] +fn conjuntos_numericos_iguais_em_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", "ℂ", "números complexos")?; + test("pt", "SimpleSpeak", "ℕ", "números naturais")?; + test("pt", "SimpleSpeak", "ℚ", "números racionais")?; + test("pt", "SimpleSpeak", "ℝ", "números reais")?; + test("pt", "SimpleSpeak", "ℤ", "inteiros")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Conjunto vazio, por extensão, por compreensão +// --------------------------------------------------------------------------- + +#[test] +fn conjunto_vazio_por_chaves() -> Result<()> { + test("pt", "ClearSpeak", "{ }", "o conjunto vazio")?; + test("pt", "SimpleSpeak", "{ }", "o conjunto vazio")?; + return Ok(()); +} + +// Sem artigo, ao contrário das chaves vazias acima. O en faz a mesma distinção +// ('empty set' para ∅, 'the empty set' para {}), então isto acompanha o en. +#[test] +fn conjunto_vazio_por_simbolo() -> Result<()> { + test("pt", "ClearSpeak", "∅", "conjunto vazio")?; + test("pt", "SimpleSpeak", "∅", "conjunto vazio")?; + return Ok(()); +} + +#[test] +fn extensao_um_elemento() -> Result<()> { + let expr = "{ 12 }"; + test("pt", "ClearSpeak", expr, "o conjunto 12")?; + test("pt", "SimpleSpeak", expr, "o conjunto 12")?; + return Ok(()); +} + +#[test] +fn extensao_varios_elementos() -> Result<()> { + let expr = " + { 5 , 10 , 15 } + "; + test("pt", "ClearSpeak", expr, "o conjunto 5 vírgula, 10 vírgula, 15")?; + test("pt", "SimpleSpeak", expr, "o conjunto 5 vírgula, 10 vírgula, 15")?; + return Ok(()); +} + +#[test] +fn compreensao_com_dois_pontos() -> Result<()> { + let expr = " + { x:x>2 } + "; + test("pt", "ClearSpeak", expr, "o conjunto de todos os x tal que x é maior que 2")?; + return Ok(()); +} + +// A barra vertical tem de falar igual aos dois pontos. +#[test] +fn compreensao_com_barra() -> Result<()> { + let expr = " + { x|x>2 } + "; + test("pt", "ClearSpeak", expr, "o conjunto de todos os x tal que x é maior que 2")?; + test("pt", "SimpleSpeak", expr, "o conjunto de todos os x tal que x é maior que 2")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// União e interseção +// --------------------------------------------------------------------------- + +#[test] +fn uniao() -> Result<()> { + let expr = "A∪B"; + test("pt", "ClearSpeak", expr, "maiúscula a união maiúscula b")?; + test("pt", "SimpleSpeak", expr, "maiúscula a união maiúscula b")?; + return Ok(()); +} + +#[test] +fn intersecao() -> Result<()> { + let expr = "A∩B"; + test("pt", "ClearSpeak", expr, "maiúscula a interseção maiúscula b")?; + test("pt", "SimpleSpeak", expr, "maiúscula a interseção maiúscula b")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Pertinência FORA de um conjunto — as cinco preferências +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_auto() -> Result<()> { + ambas_variantes("Auto", sozinho, "x pertence a números reais") +} + +#[test] +fn pertinencia_member() -> Result<()> { + ambas_variantes("Member", sozinho, "x é membro de números reais") +} + +#[test] +fn pertinencia_element() -> Result<()> { + ambas_variantes("Element", sozinho, "x é um elemento de, números reais") +} + +#[test] +fn pertinencia_belongs() -> Result<()> { + ambas_variantes("Belongs", sozinho, "x pertence a números reais") +} + +#[test] +fn pertinencia_in() -> Result<()> { + ambas_variantes("In", sozinho, "x está em números reais") +} + +// --------------------------------------------------------------------------- +// Pertinência DENTRO de um conjunto — as cinco preferências +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_no_conjunto_auto() -> Result<()> { + ambas_variantes("Auto", no_conjunto, + "o conjunto de todos os x em inteiros tal que x é maior que 5") +} + +#[test] +fn pertinencia_no_conjunto_member() -> Result<()> { + ambas_variantes("Member", no_conjunto, + "o conjunto de todos os x membros de inteiros tal que x é maior que 5") +} + +#[test] +fn pertinencia_no_conjunto_element() -> Result<()> { + ambas_variantes("Element", no_conjunto, + "o conjunto de todos os x elementos de inteiros tal que x é maior que 5") +} + +// Auto e In coincidem dentro de um conjunto, como no inglês ('Auto or In'). +#[test] +fn pertinencia_no_conjunto_in() -> Result<()> { + ambas_variantes("In", no_conjunto, + "o conjunto de todos os x em inteiros tal que x é maior que 5") +} + +// --------------------------------------------------------------------------- +// Não-pertinência +// --------------------------------------------------------------------------- + +#[test] +fn nao_pertinencia_auto() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Auto", + &sozinho(NAO_PERTENCE), "x não pertence a números reais")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_member() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Member", + &sozinho(NAO_PERTENCE), "x não é membro de, números reais")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_element() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Element", + &sozinho(NAO_PERTENCE), "x não é um elemento de, números reais")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_belongs() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Belongs", + &sozinho(NAO_PERTENCE), "x não pertence a números reais")?; + return Ok(()); +} + +// Auto e In coincidem na negação também, como no positivo. E aqui coincidem +// também com Belongs: "não em" é truncado e "fora de" troca o conceito +// (localização, não pertinência), então a negação nominal é uma só. +// Ver TERMINOLOGIA_PT_BR.md. +#[test] +fn nao_pertinencia_no_conjunto_auto() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Auto", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_no_conjunto_member() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Member", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não membros de inteiros tal que x é maior que 5")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_no_conjunto_element() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Element", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não elementos de inteiros tal que x é maior que 5")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_no_conjunto_in() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "In", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// SimpleSpeak — a preferência de ClearSpeak não vale aqui +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", &sozinho(PERTENCE), "x pertence a números reais")?; + test("pt", "SimpleSpeak", &sozinho(PERTENCE_PEQ), "x pertence a números reais")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", &sozinho(NAO_PERTENCE), "x não pertence a números reais")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Pertinência sob um operador grande (não é "dentro de um conjunto") +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_sob_somatorio() -> Result<()> { + let expr = " + + ∑ + i ∈ ℤ + + + 1 + i 2 + + "; + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Auto", expr, + "o somatório sobre i pertence a inteiros de; a fração com numerador 1; e denominador i ao quadrado")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// Ramos que exigem forma não-finita (antes falavam com verbo finito) +// +// Dentro de um conjunto a expressão modifica "todos os x". Verbo finito ali +// gruda em "conjunto" ("o conjunto de todos os x PERTENCE A inteiros") e a +// concordância cai no lugar errado. O inglês usa 'belonging to' justamente +// para evitar isso. Ver ACHADOS 7.9. +// --------------------------------------------------------------------------- + +#[test] +fn pertinencia_no_conjunto_belongs() -> Result<()> { + ambas_variantes("Belongs", no_conjunto, + "o conjunto de todos os x pertencentes a inteiros tal que x é maior que 5") +} + +#[test] +fn nao_pertinencia_no_conjunto_belongs() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "Belongs", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +// O SimpleSpeak usava UMA string só para dentro e fora do conjunto, então não +// conseguia distinguir os dois contextos. Agora bifurca como o ClearSpeak. +#[test] +fn pertinencia_no_conjunto_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", &no_conjunto(PERTENCE), + "o conjunto de todos os x pertencentes a inteiros tal que x é maior que 5")?; + test("pt", "SimpleSpeak", &no_conjunto(PERTENCE_PEQ), + "o conjunto de todos os x pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +#[test] +fn nao_pertinencia_no_conjunto_simplespeak() -> Result<()> { + test("pt", "SimpleSpeak", &no_conjunto(NAO_PERTENCE), + "o conjunto de todos os x não pertencentes a inteiros tal que x é maior que 5")?; + return Ok(()); +} + +/// Fora de um conjunto o verbo finito está certo (o sujeito é um termo só), mas +/// o ∉ com 'In' falava "não está contido em" — exatamente a fala do ⊄ +/// (unicode.yaml, 0x2284). Duas relações distintas soavam idênticas. Agora +/// espelha o "está em" do ∈, que é o que o próprio ∉ já dizia num conjunto. +#[test] +fn nao_pertinencia_in_nao_colide_com_subconjunto() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "In", + &sozinho(NAO_PERTENCE), "x não está em números reais")?; + return Ok(()); +} + +/// Guarda da distinção: ∉ e ⊄ não podem falar igual. +#[test] +fn nao_pertinencia_e_nao_subconjunto_falam_diferente() -> Result<()> { + test_ClearSpeak("pt", "ClearSpeak_SetMemberSymbol", "In", + "x\u{2209}ℝ", "x não está em números reais")?; + test("pt", "ClearSpeak", + "x\u{2284}ℝ", "x não está contido em, números reais")?; + return Ok(()); +} diff --git a/tests/Languages/pt/SimpleSpeak/functions.rs b/tests/Languages/pt/SimpleSpeak/functions.rs new file mode 100644 index 000000000..a656c2da0 --- /dev/null +++ b/tests/Languages/pt/SimpleSpeak/functions.rs @@ -0,0 +1,422 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// +/// As strings esperadas abaixo foram escritas para refletir a intenção +/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira +/// execução. Método do guia oficial de tradutores: +/// 1. rode `cargo test Languages::pt` +/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) +/// 3. se o GERADO estiver correto em português, copie-o para o teste; +/// se estiver errado, conserte a REGRA, nunca o teste. +/// +/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a +/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +/// Não herde strings esperadas de es/ sem conferir. + +use crate::common::*; +use anyhow::Result; + +#[test] +fn trig_names() -> Result<()> { + let expr = " + sinx+ + cosy+ + tanz+ + secα+ + cscϕ+ + cotφ + "; + test("pt", "SimpleSpeak", expr, "seno de x mais cosseno de y mais tangente de z mais secante de alfa, mais cossecante de fi reto, mais cotangente de fi")?; + return Ok(()); + +} + +#[test] +fn hyperbolic_trig_names() -> Result<()> { + let expr = " + sinhx+ + coshy+ + tanhz+ + sechα+ + cschϕ+ + cothφ + "; + test("pt", "SimpleSpeak", expr, "seno hiperbólico de x, mais \ + cosseno hiperbólico de y, mais \ + tangente hiperbólica de z, mais \ + secante hiperbólica de alfa, mais, \ + cossecante hiperbólica de fi reto, mais \ + cotangente hiperbólica de fi")?; + return Ok(()); + +} + + +#[test] +fn inverse_trig() -> Result<()> { + let expr = "sin-1x"; + test("pt", "SimpleSpeak", expr, "inversa de seno de x")?; + return Ok(()); + +} + +#[test] +fn trig_squared() -> Result<()> { + let expr = "sin2x"; + test("pt", "SimpleSpeak", expr, "seno ao quadrado de x")?; + return Ok(()); + +} + +#[test] +fn trig_cubed() -> Result<()> { + let expr = "tan3x"; + test("pt", "SimpleSpeak", expr, "tangente ao cubo de x")?; + return Ok(()); + +} + +#[test] +// Reconciliado com a regra function-power corrigida: ToOrdinal() gerava +// "quarto" (masculino) contra "potência" (feminino). +fn trig_fourth() -> Result<()> { + let expr = "sec4x"; + test("pt", "SimpleSpeak", expr, "a potência 4 de, secante de x")?; + return Ok(()); + +} + + +#[test] +fn trig_power_other() -> Result<()> { + let expr = "sinh>n-1x"; + test("pt", "SimpleSpeak", expr, "a potência n menos 1 de, seno hiperbólico de x")?; + return Ok(()); + +} + +#[test] +fn simple_log() -> Result<()> { + let expr = " logx "; + test("pt", "SimpleSpeak", expr, "o log de x")?; + return Ok(()); + +} + +#[test] +fn normal_log() -> Result<()> { + let expr = "log(x+y)"; + test("pt", "SimpleSpeak", expr, "o log de, abre parênteses, x mais y, fecha parênteses")?; + return Ok(()); + +} + +#[test] +fn simple_log_with_base() -> Result<()> { + let expr = " logbx "; + test("pt", "SimpleSpeak", expr, "o log na base b, de x")?; + return Ok(()); + +} + +#[test] +fn normal_log_with_base() -> Result<()> { + let expr = "logb(x+y)"; + test("pt", "SimpleSpeak", expr, "o log na base b, de, abre parênteses, x mais y, fecha parênteses")?; + return Ok(()); + +} + +/// 'Log' com maiúscula é o logaritmo de valor principal (variável complexa) e +/// tem leitura própria, diferente de 'log'. +#[test] +fn principal_value_log() -> Result<()> { + let expr = " Logx "; + test("pt", "SimpleSpeak", expr, "o log do valor principal de x")?; + return Ok(()); + +} + +#[test] +fn simple_ln() -> Result<()> { + let expr = " lnx "; + test("pt", "SimpleSpeak", expr, "o logaritmo natural de x")?; + return Ok(()); + +} + +#[test] +fn normal_ln() -> Result<()> { + let expr = "ln(x+y)"; + test("pt", "SimpleSpeak", expr, "o logaritmo natural de, abre parênteses, x mais y, fecha parênteses")?; + return Ok(()); + +} + +#[test] +fn normal_ln_terse() -> Result<()> { + let expr = "ln(x+y)"; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "l n, abre parênteses, x mais y, fecha parênteses")?; + return Ok(()); + +} + +#[test] +fn simple_ln_terse() -> Result<()> { + let expr = " lnx "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "l n x")?; + return Ok(()); + +} + +#[test] +fn explicit_function_call_with_parens() -> Result<()> { + let expr = "t⁡(x)"; + test("pt", "SimpleSpeak", expr, "t de x")?; + return Ok(()); + +} + + +#[test] +fn explicit_times_with_parens() -> Result<()> { + let expr = "t⁢(x)"; + test("pt", "SimpleSpeak", expr, "t vezes x")?; + return Ok(()); + +} + +#[test] +fn explicit_function_call() -> Result<()> { + let expr = "t⁡x"; + test("pt", "SimpleSpeak", expr, "t de x")?; + return Ok(()); + +} + +#[test] +fn explicit_times() -> Result<()> { + let expr = "t⁢x"; + test("pt", "SimpleSpeak", expr, "t x")?; + return Ok(()); + +} + + +/* + * Tests for times + */ +#[test] +fn no_times_binomial() -> Result<()> { + let expr = "x ⁢ y"; + test("pt", "SimpleSpeak", expr, "x y")?; + return Ok(()); + +} + +#[test] +fn times_following_paren() -> Result<()> { + let expr = " + 2 + ( 3 ) + "; + test("pt", "SimpleSpeak", expr, "2 vezes 3")?; + return Ok(()); + +} + +#[test] +fn times_preceding_paren() -> Result<()> { + let expr = " + ( 2 ) + 3 + "; + test("pt", "SimpleSpeak", expr, "2 vezes 3")?; + return Ok(()); + +} + +#[test] +fn no_times_sqrt() -> Result<()> { + let expr = " + a + b + = + ab + "; + test("pt", "SimpleSpeak", expr, + "a raiz quadrada de a; a raiz quadrada de b; é igual a, a raiz quadrada de a b fim da raiz")?; + return Ok(()); + +} + +/* + * Tests for parens + */ + #[test] + fn no_parens_number() -> Result<()> { + let expr = " + ( + 25 + ) + x + "; + test("pt", "SimpleSpeak", expr, "25 vezes x")?; + return Ok(()); + + } + + #[test] + fn no_parens_monomial() -> Result<()> { + let expr = " + b + ( + xy + ) + "; + test("pt", "SimpleSpeak", expr, "b x y")?; + return Ok(()); + + } + + #[test] + fn no_parens_negative_number() -> Result<()> { + let expr = " + 2+ + ( + −2 + ) + "; + test("pt", "SimpleSpeak", expr, "2 mais menos 2")?; + return Ok(()); + + } + + + #[test] + fn no_parens_negative_number_with_var() -> Result<()> { + let expr = " + ( + −2x + ) + +1 + "; + test("pt", "SimpleSpeak", expr, "menos 2 x, mais 1")?; + return Ok(()); + + } + + #[test] + fn parens_superscript() -> Result<()> { + let expr = " + + + + ( + 2x + ) + 2 + + + "; + test("pt", "SimpleSpeak", expr, "abre parênteses 2 x fecha parênteses ao quadrado")?; + return Ok(()); + + } + + #[test] + fn no_parens_fraction() -> Result<()> { + let expr = " + 2 + + + + ( + 12 + ) + "; + test("pt", "SimpleSpeak", expr, "2 mais 1 meio")?; + return Ok(()); + + } + + + // Tests for the four types of intervals in SimpleSpeak + #[test] + fn parens_interval_open_open() -> Result<()> { + let expr = " + ( + (c,d) + ) + "; + test("pt", "SimpleSpeak",expr, "o intervalo aberto de c a d")?; + return Ok(()); + +} + +#[test] + fn parens_interval_closed_open() -> Result<()> { + let expr = " + [ + [(]c,d) + ) + "; + test("pt", "SimpleSpeak",expr, "o intervalo fechado aberto de c a d")?; + return Ok(()); + +} + + +#[test] +fn parens_interval_open_closed() -> Result<()> { + let expr = " + ( + (c,d] + ] + "; + test("pt", "SimpleSpeak",expr,"o intervalo aberto fechado de c a d")?; + return Ok(()); + +} + + +#[test] +fn parens_interval_closed_closed() -> Result<()> { + let expr = " + [ + [(]c,d] + ] + "; + test("pt", "SimpleSpeak",expr, "o intervalo fechado de c a d")?; + return Ok(()); + +} + + #[test] + fn parens_interval_neg_infinity_open_open() -> Result<()> { + let expr = " + ( + - ∞,d) + ) + "; + test("pt", "SimpleSpeak",expr, + "o intervalo aberto de menos infinito a d")?; + return Ok(()); + +} + + #[test] + fn parens_interval_neg_infinity_open_closed() -> Result<()> { + let expr = " + ( + - ∞,d] + ] + "; + test("pt", "SimpleSpeak",expr, + "o intervalo aberto fechado de menos infinito a d")?; + return Ok(()); + +} + diff --git a/tests/Languages/pt/alphabets.rs b/tests/Languages/pt/alphabets.rs new file mode 100644 index 000000000..b648e59c4 --- /dev/null +++ b/tests/Languages/pt/alphabets.rs @@ -0,0 +1,438 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// Testes de alfabetos — versão pt. +/// * this has tests focused on the various alphabets +use crate::common::*; +use anyhow::Result; + + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn special_alphabet_chars() -> Result<()> { + let expr = " ℌ,ℭ"; + test("pt", "SimpleSpeak", expr, "fraktur cap h comma fraktur cap c")?; + let expr = " ℍ,ℿ"; + test("pt", "SimpleSpeak", expr, "double struck cap h comma double struck cap pi")?; + let expr = " ℐ,ℳ"; + test("pt", "SimpleSpeak", expr, "script cap i comma script cap m")?; + return Ok(()); + +} + +#[test] +fn greek() -> Result<()> { + let expr = " Α,Ω"; + // a segunda vírgula é a pausa automática do motor depois do operador; + // o inglês tem a mesma ("cap alpha comma, cap omega"). + test("pt", "SimpleSpeak", expr, "maiúscula alfa vírgula, maiúscula ômega")?; + let expr = " α,ω"; + test("pt", "SimpleSpeak", expr, "alfa vírgula, ômega")?; + return Ok(()); +} + +#[test] +#[ignore] // caracteres de área privada do MathType: dependem do unicode-full.yaml, removido de pt de propósito +fn greek_mathtype_private() -> Result<()> { + let expr = " \u{f8d3},\u{f8e0}"; + test("pt", "SimpleSpeak", expr, "maiúscula delta vazado, vírgula maiúscula úpsilon vazado")?; + return Ok(()); +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn cap_cyrillic() -> Result<()> { + let expr = " А,Я"; + test("pt", "SimpleSpeak", expr, "cap a comma cap ya")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn parenthesized() -> Result<()> { + let expr = " ⒜,⒵"; + test("pt", "SimpleSpeak", expr, "parenthesized eigh comma parenthesized z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn circled() -> Result<()> { + let expr = " Ⓐ,Ⓩ"; + test("pt", "SimpleSpeak", expr, "circled cap eigh comma circled cap z")?; + let expr = " ⓐ,ⓩ"; + test("pt", "SimpleSpeak", expr, "circled eigh comma circled z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn fraktur() -> Result<()> { + let expr = " 𝔄,𝔜"; + test("pt", "SimpleSpeak", expr, "fraktur cap eigh comma fraktur cap y")?; + let expr = " 𝔞,𝔷"; + test("pt", "SimpleSpeak", expr, "fraktur eigh comma fraktur z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "fraktur cap eigh comma fraktur cap y")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "fraktur eigh comma fraktur z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_fraktur() -> Result<()> { + let expr = " 𝕬,𝖅"; + test("pt", "SimpleSpeak", expr, "fraktur bold cap eigh, comma fraktur bold cap z")?; + let expr = " 𝖆,𝖟"; + test("pt", "SimpleSpeak", expr, "fraktur bold eigh comma fraktur bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "fraktur bold cap eigh, comma fraktur bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "fraktur bold eigh comma fraktur bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn double_struck() -> Result<()> { + let expr = " 𝔸,𝕐"; + test("pt", "SimpleSpeak", expr, "double struck cap eigh, comma double struck cap y")?; + let expr = " 𝕒,𝕫"; + test("pt", "SimpleSpeak", expr, "double struck eigh comma double struck z")?; + let expr = " 𝟘,𝟡"; + test("pt", "SimpleSpeak", expr, "double struck 0 comma double struck 9")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "double struck cap eigh, comma double struck cap y")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "double struck eigh comma double struck z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "double struck 0 comma double struck 9")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn script() -> Result<()> { + let expr = " 𝒜,𝒵"; + test("pt", "SimpleSpeak", expr, "script cap eigh comma script cap z")?; + let expr = " 𝒶,𝓏"; + test("pt", "SimpleSpeak", expr, "script eigh comma script z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "script cap eigh comma script cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "script eigh comma script z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_script() -> Result<()> { + let expr = " 𝓐,𝓩"; + test("pt", "SimpleSpeak", expr, "script bold cap eigh comma script bold cap z")?; + let expr = " 𝓪,𝔃"; + test("pt", "SimpleSpeak", expr, "script bold eigh comma script bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "script bold cap eigh comma script bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "script bold eigh comma script bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold() -> Result<()> { + let expr = " 𝐀,𝐙"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " 𝐚,𝐳"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn italic() -> Result<()> { + let expr = " 𝐴,𝑍"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " 𝑎,𝑧"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif() -> Result<()> { + let expr = " 𝖠,𝖹"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " 𝖺,𝗓"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold() -> Result<()> { + let expr = " 𝗔,𝗭"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " 𝗮,𝘇"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_italic() -> Result<()> { + let expr = " 𝘈,𝘡"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " 𝘢,𝘻"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_italic() -> Result<()> { + let expr = " 𝘼,𝙕"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " 𝙖,𝙯"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap eigh comma bold cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold eigh comma bold z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn monospace() -> Result<()> { + let expr = " 𝙰,𝚉"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " 𝚊,𝚣"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "eigh comma z")?; + return Ok(()); + +} + + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_greek() -> Result<()> { + let expr = " 𝚨,𝛀"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " 𝛂,𝛚"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_greek_others() -> Result<()> { + let expr = " 𝛛,𝛡"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + return Ok(()); + +} + + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn italic_greek() -> Result<()> { + let expr = " 𝛢,𝛺"; + test("pt", "SimpleSpeak", expr, "maiúscula alfa vírgula maiúscula ômega")?; + let expr = " 𝛼,𝜔"; + test("pt", "SimpleSpeak", expr, "alfa vírgula ômega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "maiúscula alfa vírgula maiúscula ômega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "alfa vírgula ômega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn italic_greek_others() -> Result<()> { + let expr = " 𝜕,𝜛"; + test("pt", "SimpleSpeak", expr, "partial derivative comma pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "partial derivative comma pi")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_italic_greek() -> Result<()> { + let expr = " 𝜜,𝜴"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " 𝜶,𝝎"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn bold_italic_greek_others() -> Result<()> { + let expr = " 𝝏,𝝕"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_greek() -> Result<()> { + let expr = " 𝝖,𝝮"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " 𝝰,𝞈"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_greek_others() -> Result<()> { + let expr = " 𝞉,𝞏"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_italic_greek() -> Result<()> { + let expr = " 𝞐,𝞨"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " 𝞪,𝟂"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold cap alpha comma bold cap omega")?; + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold alpha comma bold omega")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito (cai no inglês) +fn sans_serif_bold_italic_greek_others() -> Result<()> { + let expr = " 𝟃,𝟉"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + // MathType private space versions + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "bold partial derivative, comma bold pi")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito +fn pua_regular() -> Result<()> { + let expr = " ,"; + test("pt", "SimpleSpeak", expr, "cap eigh comma cap z")?; + return Ok(()); + +} + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito +fn turned() -> Result<()> { + let expr = " Ⅎ,⅄"; + test("pt", "SimpleSpeak", expr, "turned cap f comma turned sans-serif cap y")?; + return Ok(()); + + } + +#[test] +#[ignore] // depende de unicode-full.yaml, removido de pt de propósito +fn enclosed_numbers() -> Result<()> { + let expr = " ①,⑨"; + test("pt", "SimpleSpeak", expr, "circled 1 comma circled 9")?; + let expr = " ⑴,⑼"; + test("pt", "SimpleSpeak", expr, "parenthesized 1 comma parenthesized 9")?; + let expr = " ⒈,⒐"; + test("pt", "SimpleSpeak", expr, "1 with period comma 9 with period")?; + let expr = " ⓵,⓽"; + test("pt", "SimpleSpeak", expr, "double circled 1 comma double circled 9")?; + return Ok(()); + +} diff --git a/tests/Languages/pt/chemistry.rs b/tests/Languages/pt/chemistry.rs new file mode 100644 index 000000000..b8448add8 --- /dev/null +++ b/tests/Languages/pt/chemistry.rs @@ -0,0 +1,721 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// 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("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula n a; maiúscula c l")?; + return Ok(()); + +} + +#[test] +fn water() -> Result<()> { + let expr = "H2O"; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula h, 2, maiúscula o")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "maiúscula h, sub 2, maiúscula o")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "maiúscula h, subscrito 2, maiúscula o")?; + return Ok(()); + +} + +#[test] +fn carbon() -> Result<()> { + let expr = "C"; // not enough to trigger recognition + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula c")?; + return Ok(()); + +} + +#[test] +fn sulfate() -> Result<()> { + let expr = " + [SO4] + 2− + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "abre colchetes, maiúscula s, maiúscula o, sub 4; fecha colchetes super 2 menos")?; + return Ok(()); + +} + +#[test] +fn aluminum_sulfate() -> Result<()> { + let expr = "Al2 + (SO4)3"; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula a l, 2; abre parênteses, maiúscula s, maiúscula o, 4; fecha parênteses 3")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, "maiúscula a l, sub 2; abre parênteses, maiúscula s, maiúscula o, sub 4; fecha parênteses sub 3")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, "maiúscula a l, subscrito 2; abre parênteses, maiúscula s, maiúscula o, subscrito 4; fecha parênteses subscrito 3")?; + return Ok(()); + +} + +#[test] +fn ethanol_bonds() -> Result<()> { + let expr = " + + C + H 3 + − + C + H 2 + − + O + H + + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula c, maiúscula h, 3, ligação simples, maiúscula c, maiúscula h, 2, ligação simples, maiúscula o, maiúscula h")?; + + return Ok(()); + +} + +#[test] +fn dichlorine_hexoxide() -> Result<()> { + let expr = " + + [ClO2] + + + + + [ClO4] + - + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "abre colchetes, maiúscula c l; maiúscula o, 2; fecha colchetes mais; \ + abre colchetes, maiúscula c l; maiúscula o, 4; fecha colchetes menos")?; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Medium")], + expr, "abre colchetes, maiúscula c l; maiúscula o, sub 2; fecha colchetes super mais; \ + abre colchetes, maiúscula c l; maiúscula o, sub 4; fecha colchetes super menos")?; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], + expr, "abre colchetes, maiúscula c l; maiúscula o, subscrito 2; fecha colchetes sobrescrito mais; \ + abre colchetes, maiúscula c l; maiúscula o, subscrito 4; fecha colchetes sobrescrito menos")?; + return Ok(()); + +} + + +#[test] +fn ethylene_with_bond() -> Result<()> { + let expr = " + H2C + = + CH2 + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula h, 2, maiúscula c; ligação dupla, maiúscula c, maiúscula h, 2")?; + return Ok(()); + +} + +#[test] +fn ferric_chloride_aq() -> Result<()> { + let expr = " + Fe + Cl3 + (aq) + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula f e; maiúscula c l, 3, aquoso")?; + return Ok(()); + + } + +#[test] +fn ethylene_with_colon_bond() -> Result<()> { + let expr = " + H2C + :: + CH2 + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula h, 2, maiúscula c; ligação dupla, maiúscula c, maiúscula h, 2")?; + return Ok(()); + +} + +#[test] +fn beta_decay() -> Result<()> { + let expr = " + + C + + 6 + 14 + + → + + N + + 7 + 14 + + + + + e + + + − + 1 + + 0 + + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, maiúscula c; forma, 14, 7, maiúscula n; mais 0, menos 1, e")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "super 14, sub 6, maiúscula c; reage formando; super 14, sub 7, maiúscula n; mais super 0, sub menos 1, e")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "sobrescrito 14, subscrito 6, maiúscula c; reage formando; sobrescrito 14, subscrito 7, maiúscula n; mais, sobrescrito 0, subscrito menos 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 + + + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Terse")], expr, + "14, 6, maiúscula c; forma, 14, 7, maiúscula n; mais 0, menos 1, e")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Medium")], expr, + "super 14, sub 6, maiúscula c; reage formando; super 14, sub 7, maiúscula n; mais super 0, sub menos 1, e")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test_prefs("pt", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, + "sobrescrito 14, subscrito 6, maiúscula c; reage formando; sobrescrito 14, subscrito 7, maiúscula n; mais, sobrescrito 0, subscrito menos 1, e")?; + return Ok(()); + +} + +#[test] +fn hcl_na_produz() -> Result<()> { + let expr = " + 2HCl+2Na + → + 2NaCl+ + H 2 + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "2, maiúscula h, maiúscula c l; mais 2 maiúscula n a; reage formando; 2, maiúscula n a; maiúscula c l; mais maiúscula h, subscrito 2")?; + return Ok(()); + +} + +#[test] +fn mhchem_so4_2mais() -> Result<()> { + let expr = " + + + SO + + + + + + + A + + + + + + + + 4 + + + + + + + + + + A + + + + + + 2 + + + + + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "maiúscula s; maiúscula o, 4, 2 mais")?; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, "maiúscula s; maiúscula o, sub 4, super 2 mais")?; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "maiúscula s; maiúscula o, subscrito 4, sobrescrito 2 mais")?; + 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("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "2, maiúscula h, maiúscula c l; aquoso; mais, 2, maiúscula n a; sólido; forma; 2, maiúscula n a; maiúscula c l; aquoso; mais, maiúscula h, 2; gasoso")?; + + return Ok(()); + +} + + +#[test] +fn mhchem_barbed_equilibrium() -> Result<()> { + let expr = " + + + + H + 2 + + + ⁣ + + ( + g + ) + + + + + + + + I + 2 + + + ⁣ + + ( + g + ) + + + ⁢ + + + ↽ + - + + + - + ⇀ + + + ⁢ + 2 + ⁢ + + H + ⁣ + I + ⁣ + + ( + g + ) + + + + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "maiúscula h, 2; gasoso; mais; maiúscula i, 2; gasoso; está em equilíbrio com, 2, maiúscula h, maiúscula i, gasoso")?; + return Ok(()); + +} + + + +#[test] +fn mhchem_roman_in_sobrescrito() -> Result<()> { + let expr = " + + + Fe + + II + + ⁣ + + Fe + + III + + ⁣ + + O + 4 + + + + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Terse")], + expr, "maiúscula f e, 2; maiúscula f e, 3; maiúscula o, 4")?; + return Ok(()); + +} + + diff --git a/tests/Languages/pt/escuta.rs b/tests/Languages/pt/escuta.rs new file mode 100644 index 000000000..812be28be --- /dev/null +++ b/tests/Languages/pt/escuta.rs @@ -0,0 +1,33 @@ +use crate::common::*; + +fn falar(estilo: &str, verbosidade: &str, mathml: &str) -> String { + set_rules_dir(abs_rules_dir_path()).unwrap(); + set_preference("Language", "pt".to_string()).unwrap(); + set_preference("SpeechStyle", estilo.to_string()).unwrap(); + set_preference("Verbosity", verbosidade.to_string()).unwrap(); + set_preference("SpeechOverrides_CapitalLetters", "".to_string()).unwrap(); + set_preference("ClearSpeak_SetMemberSymbol", "Auto".to_string()).unwrap(); + match set_mathml(mathml.to_string()) { + Ok(_) => match get_spoken_text() { + Ok(fala) => regex::Regex::new(r" +").unwrap().replace_all(&fala, " ").to_string(), + Err(e) => format!("[ERRO ao falar: {}]", errors_to_string(&e)), + }, + Err(e) => format!("[ERRO no MathML: {}]", errors_to_string(&e)), + } +} + +#[test] +#[ignore = "gerador do pacote de escuta; rode com --ignored --nocapture"] +fn gerar_pacote_escuta() { + let tsv = include_str!("escuta_expressoes.tsv"); + for linha in tsv.lines().filter(|l| !l.starts_with('#') && !l.trim().is_empty()) { + let campos: Vec<&str> = linha.split('\t').collect(); + assert_eq!(campos.len(), 4, "linha malformada no tsv: {linha}"); + let (area, titulo, mathml) = (campos[0], campos[1], campos[3]); + for estilo in ["ClearSpeak", "SimpleSpeak"] { + for verb in ["Terse", "Medium", "Verbose"] { + println!("FALA\t{area}\t{titulo}\t{estilo}\t{verb}\t{}", falar(estilo, verb, mathml)); + } + } + } +} diff --git a/tests/Languages/pt/escuta_expressoes.tsv b/tests/Languages/pt/escuta_expressoes.tsv new file mode 100644 index 000000000..ce729ff9c --- /dev/null +++ b/tests/Languages/pt/escuta_expressoes.tsv @@ -0,0 +1,30 @@ +aritmetica Fração mista e decimal 3\frac{1}{2} + 0{,}75 = 4{,}25 312+0,75=4,25 +aritmetica Bhaskara x = \frac{-b \pm \sqrt{b^{2} - 4ac}}{2a} x=−b±b2−4ac2a +aritmetica Potência e raiz \sqrt[3]{27} = 3^{1} \quad \text{e} \quad 2^{10} = 1024 273=31e210=1024 +aritmetica Porcentagem 15\% \cdot 200 = 30 15%·200=30 +aritmetica Fração de fração \frac{\frac{1}{2}}{\frac{3}{4}} = \frac{2}{3} 1234=23 +conjuntos_logica Pertinência e compreensão \{ x \in \mathbb{Z} : x > 5 \} {x∈ℤ:x>5} +conjuntos_logica União e interseção (A \cup B) \cap C = (A \cap C) \cup (B \cap C) (A∪B)∩C=(A∩C)∪(B∩C) +conjuntos_logica Implicação p \Rightarrow q \equiv \neg p \lor q p⇒q≡¬p∨q +conjuntos_logica Quantificadores \forall \varepsilon > 0 \; \exists \delta > 0 ∀ε>0∃δ>0 +conjuntos_logica Continência \emptyset \subseteq A \subseteq \mathbb{N} ∅⊆A⊆ℕ +calculo Limite fundamental \lim_{x \to 0} \frac{\sin x}{x} = 1 limx→0sinxx=1 +calculo Derivada \frac{d}{dx}\left(x^{2} e^{x}\right) = 2x e^{x} + x^{2} e^{x} ddx(x2ex)=2xex+x2ex +calculo Integral definida \int_{0}^{1} x^{2}\,dx = \frac{1}{3} ∫01x2dx=13 +calculo Série \sum_{n=1}^{\infty} \frac{1}{n^{2}} = \frac{\pi^{2}}{6} ∑n=1∞1n2=π26 +calculo Derivada parcial \frac{\partial f}{\partial x} = 2xy ∂f∂x=2xy +algebra_linear Matriz e determinante A = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix}, \quad \det(A) = -2 A=(1234),det(A)=−2 +algebra_linear Sistema A\mathbf{x} = \mathbf{b}, \quad \mathbf{x} \in \mathbb{R}^{n} A𝐱=𝐛,𝐱∈ℝn +algebra_linear Autovalor A v = \lambda v Av=λv +algebra_linear Produto interno e norma \langle u, v \rangle = \|u\| \|v\| \cos\theta ⟨u,v⟩=‖u‖‖v‖cosθ +algebra_linear Transposta e inversa (AB)^{T} = B^{T} A^{T}, \quad A^{-1}A = I (AB)T=BTAT,A−1A=I +quimica Água \mathrm{2H_2 + O_2 \longrightarrow 2H_2O} 2H2+O2⟶2H2O +quimica Ácido carbônico \mathrm{CO_2 + H_2O \rightleftharpoons H_2CO_3} CO2+H2O⇌H2CO3 +quimica Íon \mathrm{Na^{+} + Cl^{-} \longrightarrow NaCl} Na++Cl−⟶NaCl +quimica Concentração [\mathrm{H^{+}}] = 10^{-7}\ \mathrm{mol/L} [H+]=10−7 mol/L +quimica Isótopo {}^{14}_{6}\mathrm{C} 614C +estatistica Média amostral \bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_{i} x¯=1n∑i=1nxi +estatistica Variância \sigma^{2} = \frac{\sum (x_{i} - \mu)^{2}}{N} σ2=∑(xi−μ)2N +estatistica Probabilidade condicional P(A \mid B) = \frac{P(A \cap B)}{P(B)} P(A∣B)=P(A∩B)P(B) +estatistica Binomial \binom{n}{k} p^{k} (1-p)^{n-k} (nk)pk(1−p)n−k +estatistica Normal X \sim N(\mu, \sigma^{2}) X~N(μ,σ2) diff --git a/tests/Languages/pt/intent.rs b/tests/Languages/pt/intent.rs new file mode 100644 index 000000000..df164bc1b --- /dev/null +++ b/tests/Languages/pt/intent.rs @@ -0,0 +1,72 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// +/// As strings esperadas abaixo foram escritas para refletir a intenção +/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira +/// execução. Método do guia oficial de tradutores: +/// 1. rode `cargo test Languages::pt` +/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) +/// 3. se o GERADO estiver correto em português, copie-o para o teste; +/// se estiver errado, conserte a REGRA, nunca o teste. +/// + +/// 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_mi() -> Result<()> { + let expr = " 2 x"; + test("pt", "SimpleSpeak", expr, "2")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "2")?; + return Ok(()); + +} + +#[test] +fn silent_intent_msup() -> Result<()> { + let expr = " + + H + 2 + "; + test("pt", "SimpleSpeak", expr, "maiúscula h 2")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "maiúscula h 2")?; + return Ok(()); + +} + +#[test] +fn silent_intent_underscore() -> Result<()> { + let expr = " + + H + 2 + "; + test("pt", "SimpleSpeak", expr, "maiúscula h 2")?; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "maiúscula h 2")?; + return Ok(()); + +} + +#[test] +fn intent_prob_x() -> Result<()> { + let expr = " + + x + P + "; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "probabilidade de x")?; + return Ok(()); + +} diff --git a/tests/Languages/pt/shared.rs b/tests/Languages/pt/shared.rs new file mode 100644 index 000000000..cf860236b --- /dev/null +++ b/tests/Languages/pt/shared.rs @@ -0,0 +1,346 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// +/// As strings esperadas abaixo foram escritas para refletir a intenção +/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira +/// execução. Método do guia oficial de tradutores: +/// 1. rode `cargo test Languages::pt` +/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) +/// 3. se o GERADO estiver correto em português, copie-o para o teste; +/// se estiver errado, conserte a REGRA, nunca o teste. +/// +/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a +/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +/// Não herde strings esperadas de es/ sem conferir. + +/// Tests for rules shared between various speech styles: +/// * modified var +use crate::common::*; +use anyhow::Result; + +#[test] +fn modified_vars() -> Result<()> { + let expr = " + a ` + b ~ + c ̆ + b ̌ + c ` + + x . + y ˙ + z ¨ + u ⃛ + v ⃜ + + x ^ + + t → + "; + test("pt", "SimpleSpeak", expr, + "a acento grave, b til, c breve, b cáron, c acento grave; mais; x ponto, y ponto, z dois pontos, u três pontos acima; v quatro pontos acima; mais x circunflexo, mais vetor t")?; + return Ok(()); + +} + +#[test] +fn limit() -> Result<()> { + let expr = " + + lim + x → 0 + + + + sin ⁡ x + x + + + "; + test("pt", "SimpleSpeak", expr, "limite quando x tende a 0, de, fração, seno de x, sobre x, fim da fração")?; + return Ok(()); + +} + +#[test] +fn limit_from_below() -> Result<()> { + let expr = " + + lim + x ↗ 0 + + + sin ⁡ x + + "; + test("pt", "SimpleSpeak", expr, "limite quando x tende por baixo a 0, de seno de x")?; + return Ok(()); + +} + + +#[test] +fn binomial_mmultiscripts() -> Result<()> { + let expr = "Cmn"; + test("pt", "SimpleSpeak", expr, "n escolhe m")?; + return Ok(()); + +} + + +#[test] +fn permutation_mmultiscripts() -> Result<()> { + let expr = "Pkn"; + test("pt", "SimpleSpeak", expr, "k permutações de n")?; + return Ok(()); + +} + +#[test] +fn permutation_mmultiscripts_sup() -> Result<()> { + let expr = "Pkn"; + test("pt", "SimpleSpeak", expr, "k permutações de n")?; + return Ok(()); + +} + +#[test] +fn permutation_msubsup() -> Result<()> { + let expr = "Pkn"; + test("pt", "SimpleSpeak", expr, "k permutações de n")?; + return Ok(()); + +} + +#[test] +fn tensor_mmultiscripts() -> Result<()> { + let expr = " + R i j k l + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "maiúscula r com 4 pós-escritos, subscrito i sobrescrito j subscrito k subscrito l")?; + // em Medium as regras usam a forma abreviada ('sub'/'super'), como no inglês; + // a forma longa fica reservada ao Verbose (SharedRules/default.yaml). + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Medium")], expr, + "maiúscula r com 4 pós-escritos, sub i super j sub k sub l")?; + return Ok(()); + +} + +#[test] +fn huge_num_mmultiscripts() -> Result<()> { + let expr = " + R i j k l m + I J K L + "; + test_prefs("pt", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, + "maiúscula r com 4 pré-escritos, pré-subscrito maiúscula i, pré-sobrescrito maiúscula j e pré-escritos alternados maiúscula k nenhum maiúscula l nenhum fim dos pré-escritos e com 5 pós-escritos, subscrito i sobrescrito j subscrito k subscrito l e índices alternados m nenhum fim dos índices")?; + return Ok(()); + +} + +#[test] +fn prime() -> Result<()> { + let expr = " x′ "; + test("pt", "SimpleSpeak", expr, "x linha")?; + return Ok(()); + +} + +#[test] +fn given() -> Result<()> { + let expr = "P(A|B)"; + // "dado": em P(A|B) a barra é probabilidade condicional nos dois estilos, + // como no inglês ("cap eigh given cap b"). + test("pt", "SimpleSpeak", expr, "maiúscula p; abre parênteses, maiúscula a dado maiúscula b; fecha parênteses")?; + test("pt", "ClearSpeak", expr, "maiúscula p; abre parênteses, maiúscula a dado maiúscula b; fecha parênteses")?; // not good, but follows the spec + return Ok(()); + +} + +#[test] +fn simple_msubsup() -> Result<()> { + let expr = " + + + x + + k + + + i + + + + "; + test("pt", "SimpleSpeak", expr, "x subscrito k elevado a i")?; + return Ok(()); + +} + +#[test] +fn presentation_mathml_in_semantics() -> Result<()> { + let expr = " + + {\\displaystyle x_k^i} + + + x + + k + + + i + + + + + "; + test("pt", "SimpleSpeak", expr, "x subscrito k elevado a i")?; + return Ok(()); + +} + +#[test] +fn ignore_period() -> Result<()> { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + {\\displaystyle x_k^i} + + + + P + ( + A + + +  e  + + + B + ) + = + P + ( + A + ∩ + B + ) + = + P + ( + A + ) + P + ( + B + ) + . + + + + + "; + test("pt", "SimpleSpeak", expr, "maiúscula p; abre parênteses, maiúscula a e maiúscula b; fecha parênteses; é igual a; maiúscula p; abre parênteses, maiúscula a interseção maiúscula b; fecha parênteses; é igual a; maiúscula p de maiúscula a; maiúscula p de maiúscula b")?; + return Ok(()); + +} + +#[test] +fn ignore_mtext_period() -> Result<()> { + let expr = "{2}."; + test("pt", "SimpleSpeak", expr, "o conjunto 2")?; + return Ok(()); + +} + +#[test] +fn ignore_comma() -> Result<()> { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + + ϕ + ( + x + ) + = + c + + e + + − + + h + + 2 + + + + x + + 2 + + + + + , + + +"; + test("pt", "SimpleSpeak", expr, "fi reto de x, é igual a; c vezes, e elevado à potência menos h ao quadrado, x ao quadrado")?; + return Ok(()); + +} + +#[test] +#[ignore] // issue #14 +fn ignore_period_and_space() -> Result<()> { + // from https://en.wikipedia.org/wiki/Probability + let expr = " + + + P + ( + A + ∣ + B + ) + = + + + + P + ( + A + ∩ + B + ) + + + P + ( + B + ) + + + + . + + + +"; + // ClearSpeak reativado: Rules/Languages/pt/ClearSpeak_Rules.yaml traduzido. + // Pausas (vírgula/ponto-e-vírgula) podem precisar de reconciliação via cargo test. + test("pt", "ClearSpeak", expr, "fi reto de x é igual a; c, e elevado a menos h ao quadrado x ao quadrado, fim do expoente")?; + return Ok(()); + +} + + +#[test] +fn mn_with_space() -> Result<()> { + let expr = "1 234 567"; + test("pt", "SimpleSpeak", expr, "1234567")?; + return Ok(()); + +} diff --git a/tests/Languages/pt/unicode_full.rs b/tests/Languages/pt/unicode_full.rs new file mode 100644 index 000000000..1d1d659d7 --- /dev/null +++ b/tests/Languages/pt/unicode_full.rs @@ -0,0 +1,159 @@ +/// TESTES DO IDIOMA pt — decisões de terminologia registradas em +/// Rules/Languages/pt/ACHADOS.md, seção 8. +/// +/// Este arquivo cobre duas decisões que antes não tinham teste nenhum: +/// * 8.2 — numerais romanos Unicode (0x2160-0x217F) falam o VALOR; +/// * 8.3 — os expoentes ⁰ e ⁱ usam a forma cardinal. +/// e fixa o comportamento ASCII que foi decidido PRESERVAR, para que uma +/// mudança futura no caminho de inferência de contexto não passe em silêncio. +/// +/// Todas as expectativas abaixo foram capturadas da saída real do motor, sob +/// as preferências do próprio harness — não foram escritas a partir do que se +/// esperava que saísse. +use crate::common::*; +use anyhow::Result; + +// --------------------------------------------------------------------------- +// 8.2 — Numerais romanos Unicode: falar o valor, não a grafia. +// Antes desta decisão a saída era a soletração ("I V", "X I I", "M"). +// --------------------------------------------------------------------------- + +#[test] +fn numerais_romanos_unicode_falam_o_valor() -> Result<()> { + // Representativos da faixa 0x2160-0x216F (maiúsculas). + let expr = "Ⅰ"; // 0x2160 + test("pt", "SimpleSpeak", expr, "um")?; + let expr = "Ⅳ"; // 0x2163 — o caso que motivou a decisão + test("pt", "SimpleSpeak", expr, "quatro")?; + let expr = "Ⅻ"; // 0x216b + test("pt", "SimpleSpeak", expr, "doze")?; + let expr = "Ⅼ"; // 0x216c + test("pt", "SimpleSpeak", expr, "cinquenta")?; + let expr = "Ⅽ"; // 0x216d + test("pt", "SimpleSpeak", expr, "cem")?; + let expr = "Ⅾ"; // 0x216e + test("pt", "SimpleSpeak", expr, "quinhentos")?; + let expr = "Ⅿ"; // 0x216f + test("pt", "SimpleSpeak", expr, "mil")?; + return Ok(()); +} + +#[test] +fn numerais_romanos_unicode_minusculos() -> Result<()> { + // A metade minúscula da faixa (0x2170-0x217F) tem os mesmos valores. + let expr = "ⅳ"; // 0x2173 + test("pt", "SimpleSpeak", expr, "quatro")?; + let expr = "ⅿ"; // 0x217f + test("pt", "SimpleSpeak", expr, "mil")?; + return Ok(()); +} + +#[test] +fn numerais_romanos_unicode_em_expressao() -> Result<()> { + // O valor também é falado quando o numeral aparece dentro de uma conta. + let expr = "Ⅳ+Ⅻ"; + test("pt", "SimpleSpeak", expr, "quatro mais doze")?; + // A decisão não depende do estilo de fala. + test("pt", "ClearSpeak", expr, "quatro mais doze")?; + return Ok(()); +} + +#[test] +fn numerais_romanos_unicode_em_mn() -> Result<()> { + // O caractere dedicado vale como numeral tanto em quanto em . + let expr = "Ⅳ"; + test("pt", "SimpleSpeak", expr, "quatro")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// 8.3 — Expoentes ⁰ e ⁱ na forma cardinal. +// Antes: "elevado à potência zero" / "elevado à potência i". +// --------------------------------------------------------------------------- + +#[test] +fn expoente_zero_e_i_forma_cardinal() -> Result<()> { + let expr = "x⁰"; // 0x2070 + test("pt", "SimpleSpeak", expr, "x elevado a zero")?; + let expr = "xⁱ"; // 0x2071 + test("pt", "SimpleSpeak", expr, "x elevado a i")?; + // A decisão não depende do estilo de fala. + let expr = "x⁰"; + test("pt", "ClearSpeak", expr, "x elevado a zero")?; + return Ok(()); +} + +#[test] +fn expoente_zero_e_i_isolados() -> Result<()> { + let expr = "⁰"; + test("pt", "SimpleSpeak", expr, "elevado a zero")?; + let expr = "ⁱ"; + test("pt", "SimpleSpeak", expr, "elevado a i")?; + return Ok(()); +} + +#[test] +fn expoentes_ordinais_vizinhos_intactos() -> Result<()> { + // As entradas vizinhas continuam na forma ORDINAL: a decisão 8.3 valeu só + // para ⁰ e ⁱ, que não têm ordinal. Este teste existe para impedir que + // alguém "uniformize" o bloco inteiro por engano (ver ACHADOS 5.2). + let expr = "x⁴"; // 0x2074 + test("pt", "SimpleSpeak", expr, "x elevado à quarta potência")?; + let expr = "xⁿ"; // 0x207f + test("pt", "SimpleSpeak", expr, "x elevado à enésima potência")?; + return Ok(()); +} + +// --------------------------------------------------------------------------- +// GUARDA DE REGRESSÃO — o caminho ASCII foi decidido intocado (ACHADOS 8.2). +// +// Numerais romanos escritos com letras ASCII NÃO passam pelo unicode-full.yaml: +// são marcados por src/canonicalize.rs com `data-roman-numeral` e falados pelas +// regras `default` de / em SharedRules/default.yaml, que soletram. +// Esse é o mesmo ramo de regra que trata I e V como identificador ou variável. +// +// Se algum dia o valor passar a ser falado também no caminho ASCII, ESTES +// testes vão falhar — e é essa a intenção: a mudança tem que ser deliberada. +// --------------------------------------------------------------------------- + +#[test] +fn romanos_ascii_continuam_soletrados_nao_viram_valor() -> Result<()> { + // XIV NÃO deve virar "quatorze". + let expr = "XIV"; + test("pt", "SimpleSpeak", expr, "maiúscula x maiúscula i maiúscula v")?; + let expr = "XIV"; + test("pt", "SimpleSpeak", expr, "maiúscula x maiúscula i maiúscula v")?; + // Também não depende do estilo de fala. + let expr = "XIV"; + test("pt", "ClearSpeak", expr, "maiúscula x maiúscula i maiúscula v")?; + // MIX (1009 em romano) é o caso clássico de colisão com palavra. + let expr = "MIX"; + test("pt", "SimpleSpeak", expr, "maiúscula m maiúscula i maiúscula x")?; + // Minúsculas idem: "xiv" não vira "quatorze". + let expr = "xiv"; + test("pt", "SimpleSpeak", expr, "x i v")?; + return Ok(()); +} + +#[test] +fn letras_ascii_isoladas_continuam_identificadores() -> Result<()> { + // I e V sozinhos são identificadores/variáveis, não os romanos 1 e 5. + // Este é o caminho que a decisão 8.2 mandou explicitamente NÃO tocar. + let expr = "I"; + test("pt", "SimpleSpeak", expr, "maiúscula i")?; + let expr = "V"; + test("pt", "SimpleSpeak", expr, "maiúscula v")?; + // Separados, continuam três identificadores — não o numeral 14. + let expr = "XIV"; + test("pt", "SimpleSpeak", expr, "maiúscula x maiúscula i maiúscula v")?; + return Ok(()); +} + +#[test] +fn romano_ascii_em_estado_de_oxidacao_intacto() -> Result<()> { + // O caminho da química (estado de oxidação) usa romanos ASCII e tem o seu + // próprio tratamento em src/chemistry.rs. A decisão 8.2 não o alcança. + let expr = "IV"; + test("pt", "SimpleSpeak", expr, "maiúscula i maiúscula v")?; + return Ok(()); +} diff --git a/tests/Languages/pt/units.rs b/tests/Languages/pt/units.rs new file mode 100644 index 000000000..47bd73056 --- /dev/null +++ b/tests/Languages/pt/units.rs @@ -0,0 +1,411 @@ +/// TESTES DO IDIOMA pt — como reconciliar com as regras +/// +/// As strings esperadas abaixo foram escritas para refletir a intenção +/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira +/// execução. Método do guia oficial de tradutores: +/// 1. rode `cargo test Languages::pt` +/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) +/// 3. se o GERADO estiver correto em português, copie-o para o teste; +/// se estiver errado, conserte a REGRA, nunca o teste. +/// +/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a +/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +/// Não herde strings esperadas de es/ sem conferir. + +/// 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("pt", "SimpleSpeak", expr, + "quettagramas vírgula, ronnagramas vírgula, yottagramas vírgula, zettagramas vírgula, exagramas vírgula, petagramas vírgula, teragramas vírgula, gigagramas vírgula, megagramas vírgula, quilogramas vírgula, hectogramas vírgula, decagramas vírgula, decigramas vírgula, centigramas vírgula, miligramas vírgula, microgramas vírgula, nanogramas vírgula, picogramas vírgula, femtogramas vírgula, attogramas vírgula, zeptogramas vírgula, yoctogramas vírgula, rontogramas vírgula, quectogramas")?; + return Ok(()); + +} + +#[test] +fn si_base() -> Result<()> { + let expr = r#" + 1A,2A, + 1cd,2cd, + 1K,2K, + 1K,2K, + 1g,2g, + 1m,2m, + 1mol,2mol, + 1s,2s, + 1″,2″, + 1",2", + 1sec,2sec + "#; + test("pt", "SimpleSpeak", expr, + "1 ampère, vírgula; 2 ampères, vírgula; 1 candela, vírgula; 2 candelas, vírgula; 1 kelvin, vírgula; 2 kelvins, vírgula; 1 kelvin, vírgula; 2 kelvins, vírgula, 1 grama, vírgula; 2 gramas, vírgula, 1 metro, vírgula; 2 metros, vírgula, 1 mol, vírgula, 2 mols, vírgula; 1 segundo, vírgula; 2 segundos, vírgula; 1 segundo, vírgula; 2 segundos, vírgula; 1 segundo, vírgula; 2 segundos, vírgula; 1 segundo, vírgula; 2 segundos")?; + 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("pt", "SimpleSpeak", expr, + "1 quettaampère, vírgula; 2 ronnaampères, vírgula; 1 yottacandela, vírgula; 2 zettacandelas, vírgula; 1 exakelvin, vírgula; 2 petakelvins, vírgula; 1 terakelvin, vírgula; 2 gigakelvins, vírgula; 1 megagrama, vírgula; 2 quilogramas, vírgula; 1 hectômetro, vírgula; 2 decâmetros, vírgula; 1 decimol, vírgula; 2 centimols, vírgula; 1 milissegundo, vírgula; 2 microssegundos, vírgula; 1 nanossegundo, vírgula; 2 picossegundos")?; + 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("pt", "SimpleSpeak", expr, + "1 becquerel, vírgula; 2 becquerels, vírgula; 1 coulomb, vírgula; 2 coulombs, vírgula; 1 grau Celsius, vírgula; 2 graus Celsius, vírgula; 1 grau Celsius, vírgula; 2 graus Celsius, vírgula, 1 farad, vírgula; 2 farads, vírgula, 1 gray, vírgula, 2 grays, vírgula, 1 henry, vírgula; 2 henrys, vírgula, 1 hertz, vírgula, 2 hertz, vírgula, 1 joule, vírgula; 2 joules, vírgula, 1 katal, vírgula; 2 katals, vírgula; 1 lúmen, vírgula; 2 lúmens, vírgula, 1 lux, vírgula, 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("pt", "SimpleSpeak", expr, + "1 quettabecquerel, vírgula; 2 ronnabecquerels, vírgula; 1 yottacoulomb, vírgula; 2 zettacoulombs, vírgula; 1 exafarad, vírgula; 2 petafarads, vírgula; 1 teragray, vírgula; 2 gigagrays, vírgula; 1 megahenry, vírgula; 2 quilohenrys, vírgula; 1 decahertz, vírgula; 2 decihertz, vírgula; 1 centijoule, vírgula; 2 milijoules, vírgula; 1 microkatal, vírgula; 2 nanokatals, vírgula; 1 picolúmen, vírgula; 2 femtolúmens, vírgula; 1 attolux, vírgula; 2 zeptolux, vírgula; 1 miligrau Celsius, vírgula; 2 micrograus Celsius, vírgula; 1 picograu Celsius, vírgula; 2 nanograus 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("pt", "SimpleSpeak", expr, + "1 newton, vírgula; 2 newtons, vírgula, 1 ohm, vírgula, 2 ohms, vírgula, 1 ohm, vírgula, 2 ohms, vírgula; 1 pascal, vírgula; 2 pascals, vírgula; 1 siemens, vírgula; 2 siemens, vírgula; 1 sievert, vírgula; 2 sieverts, vírgula, 1 tesla, vírgula; 2 teslas, vírgula, 1 volt, vírgula, 2 volts, vírgula, 1 watt, vírgula, 2 watts, vírgula, 1 weber, vírgula; 2 webers")?; + return Ok(()); + +} + +#[test] +fn si_derived_2_with_prefixes() -> Result<()> { + let expr = r#" + 1qN,2rN, + 1yΩ,2zΩ, + 1aΩ,2fΩ, + 1pPa,2nPa, + 1µS,2mS, + 1cSv,2dSv, + 1daT,2hT, + 1kV,2MV, + 1GW,2TW, + 1PWb,2EWb + "#; + test("pt", "SimpleSpeak", expr, + "1 quectonewton, vírgula; 2 rontonewtons, vírgula; 1 yoctoohm, vírgula; 2 zeptoohms, vírgula; 1 attoohm, vírgula; 2 femtoohms, vírgula; 1 picopascal, vírgula; 2 nanopascals, vírgula; 1 microssiemens, vírgula; 2 milissiemens, vírgula; 1 centissievert, vírgula; 2 decissieverts, vírgula; 1 decatesla, vírgula; 2 hectoteslas, vírgula; 1 quilovolt, vírgula; 2 megavolts, vírgula; 1 gigawatt, vírgula; 2 terawatts, vírgula; 1 petaweber, vírgula; 2 exawebers")?; + 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("pt", "SimpleSpeak", expr, + "1 litro, vírgula; 2 litros, vírgula, 1 litro, vírgula; 2 litros, vírgula, 1 litro, vírgula; 2 litros, vírgula; 1 tonelada, vírgula; 2 toneladas, vírgula; 1 dalton, vírgula; 2 daltons, vírgula, 1 neper, vírgula; 2 neperes, vírgula; 1 unidade de massa atômica, vírgula; 2 unidades de massa atômica; vírgula; 1 elétron-volt, vírgula; 2 elétron-volts, vírgula; 1 radiano, vírgula; 2 radianos, vírgula; 1 esferorradiano, vírgula; 2 esferorradianos, vírgula, 1 ano, vírgula, 2 anos, vírgula; 1 segundo de arco, vírgula; 2 segundos de arco, vírgula, 1 bit, vírgula, 2 bits, vírgula, 1 byte, vírgula, 2 bytes, vírgula, 1 baud, vírgula, 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("pt", "SimpleSpeak", expr, + "1 quettalitro, vírgula; 2 ronnalitros, vírgula; 1 yottalitro, vírgula; 2 zettalitros, vírgula; 1 exalitro, vírgula; 2 petalitros, vírgula; 1 teratonelada, vírgula; 2 gigatoneladas, vírgula; 1 megadalton, vírgula; 2 quilodaltons, vírgula; 1 decineper, vírgula; 2 centineperes, vírgula; 1 hectounidade de massa atômica; vírgula; 2 decaunidades de massa atômica; vírgula; 1 milielétron-volt, vírgula; 2 microelétron-volts, vírgula; 1 nanorradiano, vírgula; 2 picorradianos, vírgula; 1 femtoesferorradiano, vírgula; 2 attoesferorradianos, vírgula; 1 gigaano, vírgula; 2 megaanos, vírgula; 1 zeptossegundo de arco, vírgula; 2 yoctossegundos de arco, vírgula; 1 quilobit, vírgula; 2 megabits, vírgula; 1 gigabyte, vírgula; 2 terabytes, vírgula; 1 terabaud, vírgula; 2 exabauds")?; + 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("pt", "SimpleSpeak", expr, + "1 segundo, vírgula; 2 segundos, vírgula; 1 segundo, vírgula; 2 segundos, vírgula; 1 minuto, vírgula; 2 minutos, vírgula; 1 minuto, vírgula; 2 minutos, vírgula; 1 minuto, vírgula; 2 minutos, vírgula, 1 hora, vírgula, 2 horas, vírgula, 1 hora, vírgula, 2 horas, vírgula, 1 hora, vírgula, 2 horas, vírgula, 1 dia, vírgula, 2 dias, vírgula, 1 dia, vírgula, 2 dias, vírgula; 1 semana, vírgula; 2 semanas, vírgula; 1 semana, vírgula; 2 semanas, vírgula, 1 ano, vírgula, 2 anos, vírgula, 1 ano, vírgula, 2 anos")?; + 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("pt", "SimpleSpeak", expr, + "1 grau, vírgula, 2 graus, vírgula, \ + 1 grau, vírgula, 2 graus, vírgula; \ + 1 minuto de arco, vírgula; 2 minutos de arco, vírgula; \ + 1 minuto de arco, vírgula; 2 minutos de arco, vírgula; \ + 1 minuto de arco, vírgula; 2 minutos de arco, vírgula; \ + 1 minuto de arco, vírgula; 2 minutos de arco, vírgula; \ + 1 segundo de arco, vírgula; 2 segundos de arco, vírgula; \ + 1 segundo de arco, vírgula; 2 segundos de arco")?; + return Ok(()); + +} + +#[test] +fn without_prefix_distance() -> Result<()> { + let expr = r#" + 1au,2au, + 1ltyr,2ltyr, + 1pc,2pc, + 1Å,2Å, + 1Å,2Å, + 1fm,2fm + "#; + test("pt", "SimpleSpeak", expr, + "1 unidade astronômica, vírgula; 2 unidades astronômicas, vírgula; 1 ano-luz, vírgula; 2 anos-luz, vírgula; 1 parsec, vírgula; 2 parsecs, vírgula; 1 angström, vírgula; 2 angströms, vírgula; 1 angström, vírgula; 2 angströms, vírgula, 1 fermi, vírgula; 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, + 1℧,2℧, + 1dyn,2dyn, + 1erg,2erg + "#; + test("pt", "SimpleSpeak", expr, + "1 hectare, vírgula; 2 hectares, vírgula; 1 decibel, vírgula; 2 decibéis, vírgula; 1 atmosfera, vírgula; 2 atmosferas, vírgula; 1 unidade de massa atômica, vírgula; 2 unidades de massa atômica; vírgula, 1 bar, vírgula, 2 bares, vírgula; 1 caloria, vírgula; 2 calorias, vírgula, 1 curie, vírgula; 2 curies, vírgula, 1 grado, vírgula; 2 grados, vírgula, 1 molar, vírgula; 2 molares, vírgula; 1 roentgen, vírgula; 2 roentgens, vírgula; 1 rotação por minuto, vírgula; 2 rotações por minuto, vírgula, 1 mho, vírgula, 2 mhos, vírgula, 1 dina, vírgula, 2 dinas, vírgula, 1 erg, vírgula, 2 ergs")?; + return Ok(()); + +} + +#[test] +fn metro() -> Result<()> { + // this is a special case in Spanish + let expr = r#" + 1m, + 2m, + 1Gm, + 2Gm, + 1Mm, + 2Mm, + 1km, + 2km, + 1hm, + 2hm, + 1dam, + 2dam, + 1mm, + 2mm + "#; + test("pt", "SimpleSpeak", expr, + "1 metro, vírgula; 2 metros, vírgula; 1 gigâmetro, vírgula; 2 gigâmetros, vírgula; 1 megâmetro, vírgula; 2 megâmetros, vírgula; 1 quilômetro, vírgula; 2 quilômetros, vírgula; 1 hectômetro, vírgula; 2 hectômetros, vírgula; 1 decâmetro, vírgula; 2 decâmetros, vírgula; 1 milímetro, vírgula; 2 milímetros")?; + 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("pt", "SimpleSpeak", expr, + "1 kibibit, vírgula; 2 kibibits, vírgula; 1 mebibit, vírgula; 2 mebibits, vírgula; 1 gibibit, vírgula; 2 gibibits, vírgula; 1 tebibit, vírgula; 2 tebibits, vírgula; 1 pebibit, vírgula; 2 pebibits, vírgula; 1 exbibit, vírgula; 2 exbibits, vírgula; 1 zebibit, vírgula; 2 zebibits, vírgula; 1 yobibit, vírgula; 2 yobibits, vírgula; 1 kibibyte, vírgula; 2 kibibytes, vírgula; 1 mebibyte, vírgula; 2 mebibytes, vírgula; 1 gibibyte, vírgula; 2 gibibytes, vírgula; 1 tebibyte, vírgula; 2 tebibytes, vírgula; 1 pebibyte, vírgula; 2 pebibytes, vírgula; 1 exbibyte, vírgula; 2 exbibytes, vírgula; 1 zebibyte, vírgula; 2 zebibytes, vírgula; 1 yobibyte, vírgula; 2 yobibytes")?; + 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("pt", "SimpleSpeak", expr, + "10 litro, vírgula; 20 metros, vírgula; x milissegundos, vírgula; y microssegundos, vírgula, decagramas vírgula; 1235 decanewtons, vírgula; 25 microssegundos, vírgula; 3234 mols")?; + return Ok(()); + +} + + +#[test] +fn test_mtext_inference() -> Result<()> { + let expr = r#"[ + 1t, + 2PA, + 3Pa, + 4.5mT + ]"#; + test("pt", "SimpleSpeak", expr, + "abre colchetes; 1 tonelada, vírgula; 2 petaampères, vírgula; 3 pascals, vírgula; 45 militeslas; fecha colchetes")?; + return Ok(()); + +} + diff --git a/tests/languages.rs b/tests/languages.rs index b0552b95b..287b53652 100644 --- a/tests/languages.rs +++ b/tests/languages.rs @@ -12,6 +12,7 @@ mod Languages { mod fi; mod pl; mod sv; + mod pt; mod nb; mod de; mod fr; From aaad7468e1fb0bc266a5855253bfcd7d6561ed18 Mon Sep 17 00:00:00 2001 From: NSoiffer Date: Wed, 2 Sep 2026 06:39:05 -0700 Subject: [PATCH 04/23] Release candidate (#743) * Add UEB G1 BANA/GTM mode preference and expand Grade-2 contractions. Adding the preference is a stall tactic while I wait for feedback from ICEB about whether BANA rules are obsolete. Introduce UEB_G1_BANA_Style (default true) to choose BANA 2019 vs ICEB GTM 1.7.3/1.7.5 grade-1 indicator placement in ueb_cleanup. Implement GTM 1.7 per-symbols-sequence counting with gtm_1_7_mode, and add matching ICEB tests. Extend handle_contractions for technical vocabulary: UEB 10.8 final-letter groupsigns, dot-5 through/part, dis/con prefixes, cc/ea exception words, and a ful-pattern fix. Add ueb_technical_word_contractions (311 words, goldens cross-checked with brailletranslators.com). Wire the preference through prefs, fuzz, and docs. * updated to new BANA and ICEB spec updates. Five tests fail. Still working on them * removed an option * fix contractions involving 'be, con, dis' which can only be at the start of a 'word' (where 'word' has a specific UEB meaning) * Updated to UEB to the latest guidance for grade 1 indicators. This adds new tests and changes a few tests. Also added more contractions. * update rc # * fix new clippy warnings * fix up Vietanmese tests * fix str compile issue with no-unsafe feature --- AGENTS.md | 3 +- Cargo.toml | 2 +- PythonScripts/audit_translations/README.md | 11 +- PythonScripts/audit_translations/auditor.py | 34 +- PythonScripts/audit_translations/cli.py | 14 +- .../tests/test_cli_end_to_end.py | 74 - Rules/Braille/Nemeth/unicode-full.yaml | 2728 ++++++++--------- Rules/Braille/UEB/UEB_Rules.yaml | 9 +- Rules/prefs.yaml | 1 + docs/users.md | 42 +- src/braille.rs | 980 +++++- tests/braille/UEB/iceb.rs | 1103 ++++++- tests/braille/UEB/other.rs | 21 +- 13 files changed, 3176 insertions(+), 1846 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c6ca9e756..7093cf698 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ but add common mistakes of AI agents here instead. - `ClearSpeak_Rules.yaml`, `SimpleSpeak_Rules.yaml` - `SharedRules/`, `unicode.yaml`, `unicode-full.yaml`, `definitions.yaml`, `navigate.yaml` - `build.rs` can bundle rules into `rules.zip` when `include-zip` is enabled (always the minimized tree). Shared zipper: `src/rules_archive.rs`, invoked as `cargo run --bin package-rules -- Rules [--minimize]`. -- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (flow-style rewrite of all YAML: comments dropped). Each language/braille subdir is stored as `/.zip`; top-level and `Intent/` YAML stay loose. Inner language zips use BZIP2; the outer downloadable archive uses DEFLATE so `unzip` works. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. +- CI packages `Rules.zip` (verbatim) and `Rules-minimized.zip` (comments stripped from `Languages/**/unicode.yaml` and `unicode-full.yaml` only). Each language/braille subdir is stored as `/.zip`; top-level and `Intent/` YAML stay loose. Inner language zips use BZIP2; the outer downloadable archive uses DEFLATE so `unzip` works. Both omit `Languages/zz`; the `test-rules-package` job restores `zz` from git after unzip so unit tests still run against release-like archives. ## Translation Conventions - `t:` means untranslated or unverified. @@ -33,6 +33,7 @@ but add common mistakes of AI agents here instead. - Do not mirror README content here; keep guidance agent-specific. - Avoid broad formatting sweeps; do not run `cargo fmt` in this repo. - Keep code/rule changes focused and validate with targeted tests first: `cargo test ` +- Do **not** change test goldens (expected braille/speech/nav strings) unless the user explicitly says to. Prefer fixing code/rules to match existing goldens; if a golden looks wrong vs the spec, ask before editing it. - do not do any git commands unless explicitly asked for - Rust coverage is in `target/coverage/`. - When working with GitHub, e.g. looking at PRs and issues, check if the GitHub CLI is installed (`gh --version`). diff --git a/Cargo.toml b/Cargo.toml index fcf5428d9..2e73cbf80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mathcat" -version = "0.7.7-alpha.1" +version = "0.7.6-rc.4" authors = ["Neil Soiffer "] license = "MIT" description = "MathCAT: Math Capable Assistive Technology ('Speech and braille from MathML')" diff --git a/PythonScripts/audit_translations/README.md b/PythonScripts/audit_translations/README.md index fd399e412..8aedf1265 100644 --- a/PythonScripts/audit_translations/README.md +++ b/PythonScripts/audit_translations/README.md @@ -77,7 +77,6 @@ uv run --project PythonScripts audit-translations --list * Region variants are shown as `lang-region` (e.g., `zz-aa`) based on subdirectories under `Rules/Languages/`. * `--source`: Sets the source/reference language. Defaults to `en`. * `--file`: Audits a single specific file instead of the whole directory. -* `--exclude`: Exclude one or more files from the audit. * `--rules-dir`: Override the Rules/Languages directory path. * `--only`: Filter issue types (comma-separated): `missing`, `untranslated`, `extra`, `diffs`, `all`. * `--verbose`: Show detailed output including source/target snippets for rule differences. @@ -101,17 +100,9 @@ uv run audit-translations de # Compare Norwegian Bokmal against Swedish instead of English uv run audit-translations nb --source sv -# Audit only a specific file (note: --file is incompatible with --exclude) -uv run audit-translations es --file ClearSpeak_Rules.yaml +# Audit only a specific file uv run audit-translations es --file SharedRules/default.yaml -# Exclude a list of files from the audit, note that if you use this option before specifying the -# target language you'll need to use the option terminator (--). -# (note: --exclude is incompatible with --file) -uv run audit-translations es --exclude unicode-full.yaml -uv run audit-translations es --exclude unicode-full.yaml unicode.yaml -uv run audit-translations --exclude unicode-full.yaml -- es - # Audit a regional variant (merges Rules/Languages/de and Rules/Languages/de/CH) uv run audit-translations de-CH diff --git a/PythonScripts/audit_translations/auditor.py b/PythonScripts/audit_translations/auditor.py index 37ec44f13..b67cbf911 100644 --- a/PythonScripts/audit_translations/auditor.py +++ b/PythonScripts/audit_translations/auditor.py @@ -46,31 +46,24 @@ def is_definitions_file(file_path: str | Path) -> bool: return Path(file_path).name == "definitions.yaml" -def get_yaml_files(lang_dir: Path, region_dir: Path | None = None, excluded_files: list[str] | None = None) -> list[Path]: +def get_yaml_files(lang_dir: Path, region_dir: Path | None = None) -> list[Path]: """Get all YAML files to audit for a language, including region overrides.""" files: set[Path] = set() - def collect_from(directory: Path, root: Path, excluded: list[str] | None) -> None: + def collect_from(directory: Path, root: Path) -> None: if not directory.exists(): return - - excluded_paths = {Path(path) for path in excluded or []} - - candidates = {f for f in directory.glob("*.yaml") if f.name != "prefs.yaml"} - candidates.update((directory / "SharedRules").glob("*.yaml")) - - relative_candidates = {f.relative_to(directory): f for f in candidates} - - for path in excluded_paths - relative_candidates.keys(): - console.print(f"\n[yellow]⚠ Warning:[/] File to exclude {path} does not exist.") - - files.update( - f.relative_to(root) for relative_path, f in relative_candidates.items() if relative_path not in excluded_paths - ) - - collect_from(lang_dir, lang_dir, excluded_files) + for f in directory.glob("*.yaml"): + if f.name != "prefs.yaml": + files.add(f.relative_to(root)) + shared_dir = directory / "SharedRules" + if shared_dir.exists(): + for f in shared_dir.glob("*.yaml"): + files.add(f.relative_to(root)) + + collect_from(lang_dir, lang_dir) if region_dir: - collect_from(region_dir, region_dir, excluded_files) + collect_from(region_dir, region_dir) return sorted(files) @@ -222,7 +215,6 @@ def merge_definitions( def audit_language( language: str, specific_file: str | None = None, - excluded_files: list[str] | None = None, rules_dir: str | None = None, issue_filter: set[str] | None = None, verbose: bool = False, @@ -256,7 +248,7 @@ def audit_language( raise AuditError(f"Target region directory not found: {translated_region_dir}") # Get list of files to audit - files = [specific_file] if specific_file else get_yaml_files(source_dir, source_region_dir, excluded_files) + files = [specific_file] if specific_file else get_yaml_files(source_dir, source_region_dir) print_audit_header(language, len(files), source_language) diff --git a/PythonScripts/audit_translations/cli.py b/PythonScripts/audit_translations/cli.py index 5bdf30e6d..6916a636e 100644 --- a/PythonScripts/audit_translations/cli.py +++ b/PythonScripts/audit_translations/cli.py @@ -30,18 +30,7 @@ def main() -> None: parser.add_argument("language", nargs="?", help="Language code to audit (e.g., 'es', 'de', 'fi')") parser.add_argument("--source", default="en", help="Source/reference language code (default: 'en')") - file_group = parser.add_mutually_exclusive_group() - file_group.add_argument( - "--file", - dest="specific_file", - help="Audit only a specific file (e.g., 'SharedRules/default.yaml')", - ) - file_group.add_argument( - "--exclude", - nargs="+", - dest="excluded_files", - help="Exclude a list of files from the audit.", - ) + parser.add_argument("--file", dest="specific_file", help="Audit only a specific file (e.g., 'SharedRules/default.yaml')") parser.add_argument("--list", action="store_true", help="List available languages") parser.add_argument("--rules-dir", help="Override Rules/Languages directory path") parser.add_argument( @@ -78,7 +67,6 @@ def main() -> None: audit_language( args.language, args.specific_file, - args.excluded_files, args.rules_dir, issue_filter, args.verbose, diff --git a/PythonScripts/audit_translations/tests/test_cli_end_to_end.py b/PythonScripts/audit_translations/tests/test_cli_end_to_end.py index 40cf3f8b2..7876bc0de 100644 --- a/PythonScripts/audit_translations/tests/test_cli_end_to_end.py +++ b/PythonScripts/audit_translations/tests/test_cli_end_to_end.py @@ -127,80 +127,6 @@ def test_cli_main_rich_only_filters_issue_groups(capsys, monkeypatch) -> None: assert "Structure Differences" not in output -@pytest.mark.parametrize( - ("excluded_file", "expected_file", "expected_rule", "unexpected_rule"), - [ - ( - "default.yaml", - "SharedRules/default.yaml", - "shared-only", - "root-only", - ), - ( - "SharedRules/default.yaml", - "default.yaml", - "root-only", - "shared-only", - ), - ], - ids=["exclude-root", "exclude-shared-rules"], -) -def test_cli_main_exclude_uses_relative_paths( - tmp_path, - capsys, - monkeypatch, - excluded_file, - expected_file, - expected_rule, - unexpected_rule, -) -> None: - """Ensure --exclude distinguishes root files from SharedRules files.""" - rules_dir = tmp_path / "Rules" / "Languages" - source_dir = rules_dir / "en" - target_dir = rules_dir / "de" - - (source_dir / "SharedRules").mkdir(parents=True) - (target_dir / "SharedRules").mkdir(parents=True) - - (source_dir / "default.yaml").write_text( - '- name: root-only\n tag: mo\n match: ".//m:mi"\n replace:\n - t: "root"\n', - encoding="utf-8", - ) - (source_dir / "SharedRules" / "default.yaml").write_text( - '- name: shared-only\n tag: mo\n match: ".//m:mi"\n replace:\n - t: "shared"\n', - encoding="utf-8", - ) - - target_rule = '- name: target-only\n tag: mo\n match: ".//m:mi"\n replace:\n - t: "target"\n' - (target_dir / "default.yaml").write_text( - target_rule, - encoding="utf-8", - ) - (target_dir / "SharedRules" / "default.yaml").write_text( - target_rule, - encoding="utf-8", - ) - - args = [ - "de", - "--rules-dir", - str(rules_dir), - "--exclude", - excluded_file, - "--only", - "missing", - ] - monkeypatch.setattr(sys, "argv", ["audit_translations", *args]) - - audit_cli.main() - output = strip_ansi(capsys.readouterr().out) - - assert "Files to check: 1" in output - assert expected_file in output - assert expected_rule in output - assert unexpected_rule not in output - - def test_cli_main_accepts_source_language(capsys, monkeypatch) -> None: """ Ensure --source changes the reference language without changing target semantics. diff --git a/Rules/Braille/Nemeth/unicode-full.yaml b/Rules/Braille/Nemeth/unicode-full.yaml index bf4f842ea..30ffc561d 100644 --- a/Rules/Braille/Nemeth/unicode-full.yaml +++ b/Rules/Braille/Nemeth/unicode-full.yaml @@ -1,1364 +1,1364 @@ ---- -# To greatly simplify typeface/language generation, the chars have unique ASCII chars for them: -# Typeface: S: sans-serif, B: bold, T: script/blackboard, I: italic, R: Roman -# Language: E: English, D: German, G: Greek, V: Greek variants, H: Hebrew, U: Russian -# Indicators: C: capital, L: letter, N: number, P: punctuation, M: multipurpose -# Others: W -- whitespace that should be kept (e.g, in a numeral) -# SRE doesn't have H: Hebrew, so not encoded (yet) -# Some of the weird letters (e.g., circled letters) I didn't translate with the above because -# they don't interact with rules since they are enclosed in other chars. - - - "⨯": [t: "⠈⠡"] # U+2A2F(VECTOR OR CROSS PRODUCT) -- make the same as 0x00D7 (Multiplication sign) - - # --- Nemeth Default Alphabet bold chars. --- - - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - tc: "BE" - - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - tc: "BE" - - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - tc: "BG" - - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝛂-𝛒": # 0x1d6c2 - 0x1d6d2 - - tc: "BG" - - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒', 'αβγδεζηθικλμνξοπρ')" - - - "𝛔-𝛖": # 0x1d6d4 - 0x1d6d6 - - tc: "BG" - - spell: "translate('.', '𝛔𝛕𝛖', 'στυ')" - - - "𝛘-𝛚": # 0x1d6d8 - 0x1d6da - - tc: "BG" - - spell: "translate('.', '𝛘𝛙𝛚', 'χψω')" - - - "𝛁": [tc: "BGL⠫"] # 0x1d6c1 - - "𝛓": [tc: "BVL⠎"] # 0x1d6d3 - - "𝛗": [tc: "BVL⠋"] # 0x1d6d7 - - "𝛛": [tc: "⠸⠈⠙"] # 0x1d6db - - "𝛜": [tc: "BGL⠑"] # 0x1d6dc - - "𝛝": [tc: "BVL⠹"] # 0x1d6dd - - "𝛞": [tc: "BGL⠅"] # 0x1d6de - - "𝛟": [tc: "BGL⠋"] # 0x1d6df - - "𝛠": [tc: "BGL⠗"] # 0x1d6e0 - - "𝛡": [tc: "BGL⠏"] # 0x1d6e1 - - - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 - - tc: "B" - - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - - # --- Nemeth Default Alphabet bold-fraktur chars. --- - - - "𝕬-𝖅": # 0x1d56c - 0x1d585 - - tc: "BD" - - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - tc: "BD" - - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - - # --- Nemeth Default Alphabet bold-italic chars. --- - - "𝑨-𝒁": # 0x1d468 - 0x1d481 - - tc: "BE" - - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝒂-𝒛": # 0x1d482 - 0x1d49b - - tc: "BE" - - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝜜-𝜴": # 0x1d71c - 0x1d734 - - tc: "BG" - - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝜵": [tc: "BGL⠫"] # 0x1d735 - - - "𝜶-𝝆": # 0x1d736 - 0x1d746 - - tc: "BG" - - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆', 'αβγδεζηθικλμνξοπρ')" - - - "𝝇": [tc: "BVL⠎"] # 0x1d747 - - - "𝝈-𝝊": # 0x1d748 - 0x1d74a - - tc: "BG" - - spell: "translate('.', '𝝈𝝉𝝊', 'στυ')" - - - "𝝋": [tc: "BVL⠋"] # 0x1d74b - - - "𝝌-𝝎": # 0x1d74c - 0x1d74e - - tc: "BG" - - spell: "translate('.', '𝝌𝝍𝝎', 'χψω')" - - - "𝝏": [tc: "BVL⠙"] # 0x1d74f - - "𝝐": [tc: "BGL⠑"] # 0x1d750 - - "𝝑": [tc: "BVL⠹"] # 0x1d751 - - - "𝝒-𝝕": # 0x1d752 - 0x1d755 - - tc: "BG" - - spell: "translate('.', '𝝒𝝓𝝔𝝕', 'κφρπ')" - - # --- Nemeth Default Alphabet bold-script chars. --- - - - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - tc: "BTE" - - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - tc: "BTE" - - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝚤-𝚥": # 0x1d6a4 - 0x1d6a5 - - tc: "" - - spell: "translate('.', '𝚤𝚥', '⠊⠚')" - -# Russian Alphabet (from Nemeth book) -# NOTE: is this translation needed? - - "А-Я": # 0x410 - 0x42f - - tc: "U" - - spell: "translate('.', 'АБВГДЕЗИЙКЛМНОПРСТУФЭ', 'ABVGDEZIYKLMNOPRSTUFE')" - - - "а-я": # 0x430 - 0x44f - - tc: "U" - - spell: "translate('.', 'абвгдезийклмнопрстуфэ', 'abvgdeziylkmnoprstufye')" - - - "①-⑨": # 0x2460 - 0x2473 - - tc: "⠫⠉⠸⠫⠼" - - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" - - tc: "⠻" - - - "⓪": [tc: "⠫⠉⠸⠫⠼⠴⠻"] # 0x24ea - - - "⑩": [tc: "⠫⠉⠸⠫⠼⠂⠴⠻"] # 0x2469 - - "⑪": [tc: "⠫⠉⠸⠫⠼⠂⠂⠻"] # 0x246a - - "⑫": [tc: "⠫⠉⠸⠫⠼⠂⠆⠻"] # 0x246b - - "⑬": [tc: "⠫⠉⠸⠫⠼⠂⠒⠻"] # 0x246c - - "⑭": [tc: "⠫⠉⠸⠫⠼⠂⠲⠻"] # 0x246d - - "⑮": [tc: "⠫⠉⠸⠫⠼⠂⠢⠻"] # 0x246e - - "⑯": [tc: "⠫⠉⠸⠫⠼⠂⠖⠻"] # 0x246f - - "⑰": [tc: "⠫⠉⠸⠫⠼⠂⠶⠻"] # 0x2470 - - "⑱": [tc: "⠫⠉⠸⠫⠼⠂⠦⠻"] # 0x2471 - - "⑲": [tc: "⠫⠉⠸⠫⠼⠂⠔⠻"] # 0x2472 - - "⑳": [tc: "⠫⠉⠸⠫⠼⠆⠴⠻"] # 0x2473 - - - "㉑": [tc: "⠫⠉⠸⠫⠼⠆⠂⠻"] # 0x3251 - - "㉒": [tc: "⠫⠉⠸⠫⠼⠆⠆⠻"] # 0x3252 - - "㉓": [tc: "⠫⠉⠸⠫⠼⠆⠒⠻"] # 0x3253 - - "㉔": [tc: "⠫⠉⠸⠫⠼⠆⠲⠻"] # 0x3254 - - "㉕": [tc: "⠫⠉⠸⠫⠼⠆⠢⠻"] # 0x3255 - - "㉖": [tc: "⠫⠉⠸⠫⠼⠆⠖⠻"] # 0x3256 - - "㉗": [tc: "⠫⠉⠸⠫⠼⠆⠶⠻"] # 0x3257 - - "㉘": [tc: "⠫⠉⠸⠫⠼⠆⠦⠻"] # 0x3258 - - "㉙": [tc: "⠫⠉⠸⠫⠼⠆⠔⠻"] # 0x3259 - - "㉚": [tc: "⠫⠉⠸⠫⠼⠒⠴⠻"] # 0x325a - - "㉛": [tc: "⠫⠉⠸⠫⠼⠒⠂⠻"] # 0x325b - - "㉜": [tc: "⠫⠉⠸⠫⠼⠒⠆⠻"] # 0x325c - - "㉝": [tc: "⠫⠉⠸⠫⠼⠒⠒⠻"] # 0x325d - - "㉞": [tc: "⠫⠉⠸⠫⠼⠒⠲⠻"] # 0x325e - - "㉟": [tc: "⠫⠉⠸⠫⠼⠒⠢⠻"] # 0x325f - - "㊱": [tc: "⠫⠉⠸⠫⠼⠒⠖⠻"] # 0x32b1 - - "㊲": [tc: "⠫⠉⠸⠫⠼⠒⠶⠻"] # 0x32b2 - - "㊳": [tc: "⠫⠉⠸⠫⠼⠒⠦⠻"] # 0x32b3 - - "㊴": [tc: "⠫⠉⠸⠫⠼⠒⠔⠻"] # 0x32b4 - - "㊵": [tc: "⠫⠉⠸⠫⠼⠲⠴⠻"] # 0x32b5 - - "㊶": [tc: "⠫⠉⠸⠫⠼⠲⠂⠻"] # 0x32b6 - - "㊷": [tc: "⠫⠉⠸⠫⠼⠲⠆⠻"] # 0x32b7 - - "㊸": [tc: "⠫⠉⠸⠫⠼⠲⠒⠻"] # 0x32b8 - - "㊹": [tc: "⠫⠉⠸⠫⠼⠲⠲⠻"] # 0x32b9 - - "㊺": [tc: "⠫⠉⠸⠫⠼⠲⠢⠻"] # 0x32ba - - "㊻": [tc: "⠫⠉⠸⠫⠼⠲⠖⠻"] # 0x32bb - - "㊼": [tc: "⠫⠉⠸⠫⠼⠲⠶⠻"] # 0x32bc - - "㊽": [tc: "⠫⠉⠸⠫⠼⠲⠦⠻"] # 0x32bd - - "㊾": [tc: "⠫⠉⠸⠫⠼⠲⠔⠻"] # 0x32be - - "㊿": [tc: "⠫⠉⠸⠫⠼⠢⠴⠻"] # 0x32bf - -#NOTE: uncertainty here - - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf - - tc: "⠫⠉⠸⠫⠠" - - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - tc: "⠻" - - - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - tc: "⠫⠉⠸⠫" - - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - tc: "⠻" - - # --- Nemeth Default Alphabet circled-sans-serif chars. --- - - - "➀-➈": # 0x1f10b, 0x2780 - 0x2788 - - tc: "⠫⠉⠸⠫⠠⠨⠼" - - spell: "translate('.', '➀➁➂➃➄➅➆➇➈', '123456789')" - - tc: "⠻" - - - "🄋": [tc: "⠫⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10b - - "➉": [tc: "⠫⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2789 - - # --- Nemeth Default Alphabet comma chars. --- - - - "🄁-🄊": # 0x1f101 - 0x1f10a - - spell: "translate('.', '🄁🄂🄃🄄🄅🄆🄇🄈🄉🄊', '0123456789')" - - tc: "⠠" - - - # --- Nemeth Default Alphabet double-circled chars. --- - - - "⓵": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠻⠻"] # 0x24f5 - - "⓶": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠆⠻⠻"] # 0x24f6 - - "⓷": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠒⠻⠻"] # 0x24f7 - - "⓸": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠲⠻⠻"] # 0x24f8 - - "⓹": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠢⠻⠻"] # 0x24f9 - - "⓺": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠖⠻⠻"] # 0x24fa - - "⓻": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠶⠻⠻"] # 0x24fb - - "⓼": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠦⠻⠻"] # 0x24fc - - "⓽": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠔⠻⠻"] # 0x24fd - - "⓾": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x24fe - - # --- Nemeth Default Alphabet double-struck chars. --- - - "𝔸-𝕐": # 0x1d538 - 0x1d550 (partial, excludes ℂ ℍ ℕ ℙ ℚ ℝ ℤ) - - tc: "𝔹E" - - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABDEFGIJKLMOSTUVWXY')" - - - "ℂ": [tc: "𝔹ECL⠉"] # 0x2102 - - "ℍ": [tc: "𝔹ECL⠓"] # 0x210d - - "ℕ": [tc: "𝔹ECL⠝"] # 0x2115 - - "ℙ": [tc: "𝔹ECL⠏"] # 0x2119 - - "ℚ": [tc: "𝔹ECL⠟"] # 0x211a - - "ℝ": [tc: "𝔹ECL⠗"] # 0x211d - - "ℤ": [tc: "𝔹ECL⠵"] # 0x2124 - - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) - - - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - tc: "𝔹E" - - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - tc: "𝔹" - - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - - - # --- Nemeth Default Alphabet fraktur chars. --- - - - "𝔄-𝔜": # 0x1d504 - 0x1d51c - - tc: "D" - - spell: "translate('.', '𝔄𝔅𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABDEFGJKLMNOPQSTUVWXY')" - - - "ℭ": [tc: "DCL⠉"] # 0x212d - - "ℌ": [tc: "DCL⠓"] # 0x210c - - "ℑ": [tc: "DCL⠊"] # 0x2111 - - "ℜ": [tc: "DCL⠗"] # 0x211c - - "ℨ": [tc: "DCL⠵"] # 0x2128 - - - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - tc: "D" - - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - - # --- Nemeth Default Alphabet fullwidth chars. --- - - - "A-Z": # 0xff21 - 0xff3a - - tc: "" - - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "a-z": # 0xff41 - 0xff5a - - tc: "" - - spell: "translate('.', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz')" - - - "0-9": # 0xff10 - 0xff19 - - tc: "" - - spell: "translate('.', '0123456789', '0123456789')" - - # --- Nemeth Default Alphabet italic chars -- treat as non-italic. --- - - - "𝐴-𝑍": # 0x1d434 - 0x1d44d - - tc: "E" - - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝑎-𝑧": # 0x1d44e - 0x1d467 - - tc: "E" - - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔ℎ𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - - tc: "G" - - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝛻": [tc: "GL⠫"] # 0x1d6fb - - - "𝛼-𝜌": # 0x1d6fc - 0x1d70c - - tc: "G" - - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌', 'αβγδεζηθικλμνξοπρ')" - - "𝜍": [tc: "VL⠎"] # 0x1d70d - - - "𝜎": [tc: "GL⠎"] # 0x1d70e - - "𝜏": [tc: "GL⠞"] # 0x1d70f - - "𝜐": [tc: "GL⠥"] # 0x1d710 - - - "𝜑": [tc: "VL⠋"] # 0x1d711 - - - "𝜒": [tc: "GL⠯"] # 0x1d712 - - "𝜓": [tc: "GL⠽"] # 0x1d713 - - "𝜔": [tc: "GL⠺"] # 0x1d714 - - - "𝜕": [tc: "VL⠙"] # 0x1d715 - - - "𝜖": [tc: "GL⠑"] # 0x1d716 - - - "𝜗": [tc: "VL⠹"] # 0x1d717 - - - "𝜘": [tc: "GL⠅"] # 0x1d718 - - "𝜙": [tc: "GL⠋"] # 0x1d719 - - "𝜚": [tc: "GL⠗"] # 0x1d71a - - "𝜛": [tc: "GL⠏"] # 0x1d71b - - # --- Nemeth Default Alphabet monospace chars. --- - - - "𝙰-𝚉": # 0x1d670 - 0x1d689 - - tc: "" - - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 - - tc: "" - - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff - - tc: "" - - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" - - - # --- Nemeth Default Alphabet negative-circled chars. --- - - "⓿": [t: "⠫⠸⠉⠸⠫⠼⠴⠻"] # 0x24ff - - "❶": [t: "⠫⠸⠉⠸⠫⠼⠂⠻"] # 0x2776 - - "❷": [t: "⠫⠸⠉⠸⠫⠼⠆⠻"] # 0x2777 - - "❸": [t: "⠫⠸⠉⠸⠫⠼⠒⠻"] # 0x2778 - - "❹": [t: "⠫⠸⠉⠸⠫⠼⠲⠻"] # 0x2779 - - "❺": [t: "⠫⠸⠉⠸⠫⠼⠢⠻"] # 0x277a - - "❻": [t: "⠫⠸⠉⠸⠫⠼⠖⠻"] # 0x277b - - "❼": [t: "⠫⠸⠉⠸⠫⠼⠶⠻"] # 0x277c - - "❽": [t: "⠫⠸⠉⠸⠫⠼⠦⠻"] # 0x277d - - "❾": [t: "⠫⠸⠉⠸⠫⠼⠔⠻"] # 0x277e - - "❿": [t: "⠫⠸⠉⠸⠫⠼⠂⠴⠻"] # 0x277f - - "⓫": [t: "⠫⠸⠉⠸⠫⠼⠂⠂⠻"] # 0x24eb - - "⓬": [t: "⠫⠸⠉⠸⠫⠼⠂⠆⠻"] # 0x24ec - - "⓭": [t: "⠫⠸⠉⠸⠫⠼⠂⠒⠻"] # 0x24ed - - "⓮": [t: "⠫⠸⠉⠸⠫⠼⠂⠲⠻"] # 0x24ee - - "⓯": [t: "⠫⠸⠉⠸⠫⠼⠂⠢⠻"] # 0x24ef - - "⓰": [t: "⠫⠸⠉⠸⠫⠼⠂⠖⠻"] # 0x24f0 - - "⓱": [t: "⠫⠸⠉⠸⠫⠼⠂⠶⠻"] # 0x24f1 - - "⓲": [t: "⠫⠸⠉⠸⠫⠼⠂⠦⠻"] # 0x24f2 - - "⓳": [t: "⠫⠸⠉⠸⠫⠼⠂⠔⠻"] # 0x24f3 - - "⓴": [t: "⠫⠸⠉⠸⠫⠼⠆⠴⠻"] # 0x24f4 - - - "🅐": [t: "⠫⠸⠉⠸⠫⠠⠁⠻"] # 0x1f150 - - "🅑": [t: "⠫⠸⠉⠸⠫⠠⠃⠻"] # 0x1f151 - - "🅒": [t: "⠫⠸⠉⠸⠫⠠⠉⠻"] # 0x1f152 - - "🅓": [t: "⠫⠸⠉⠸⠫⠠⠙⠻"] # 0x1f153 - - "🅔": [t: "⠫⠸⠉⠸⠫⠠⠑⠻"] # 0x1f154 - - "🅕": [t: "⠫⠸⠉⠸⠫⠠⠋⠻"] # 0x1f155 - - "🅖": [t: "⠫⠸⠉⠸⠫⠠⠛⠻"] # 0x1f156 - - "🅗": [t: "⠫⠸⠉⠸⠫⠠⠓⠻"] # 0x1f157 - - "🅘": [t: "⠫⠸⠉⠸⠫⠠⠊⠻"] # 0x1f158 - - "🅙": [t: "⠫⠸⠉⠸⠫⠠⠚⠻"] # 0x1f159 - - "🅚": [t: "⠫⠸⠉⠸⠫⠠⠅⠻"] # 0x1f15a - - "🅛": [t: "⠫⠸⠉⠸⠫⠠⠇⠻"] # 0x1f15b - - "🅜": [t: "⠫⠸⠉⠸⠫⠠⠍⠻"] # 0x1f15c - - "🅝": [t: "⠫⠸⠉⠸⠫⠠⠝⠻"] # 0x1f15d - - "🅞": [t: "⠫⠸⠉⠸⠫⠠⠕⠻"] # 0x1f15e - - "🅟": [t: "⠫⠸⠉⠸⠫⠠⠏⠻"] # 0x1f15f - - "🅠": [t: "⠫⠸⠉⠸⠫⠠⠟⠻"] # 0x1f160 - - "🅡": [t: "⠫⠸⠉⠸⠫⠠⠗⠻"] # 0x1f161 - - "🅢": [t: "⠫⠸⠉⠸⠫⠠⠎⠻"] # 0x1f162 - - "🅣": [t: "⠫⠸⠉⠸⠫⠠⠞⠻"] # 0x1f163 - - "🅤": [t: "⠫⠸⠉⠸⠫⠠⠥⠻"] # 0x1f164 - - "🅥": [t: "⠫⠸⠉⠸⠫⠠⠧⠻"] # 0x1f165 - - "🅦": [t: "⠫⠸⠉⠸⠫⠠⠺⠻"] # 0x1f166 - - "🅧": [t: "⠫⠸⠉⠸⠫⠠⠭⠻"] # 0x1f167 - - "🅨": [t: "⠫⠸⠉⠸⠫⠠⠽⠻"] # 0x1f168 - - "🅩": [t: "⠫⠸⠉⠸⠫⠠⠵⠻"] # 0x1f169 - - # --- Nemeth Default Alphabet negative-circled-sans-serif chars. --- - - "🄌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10c - - "➊": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠻"] # 0x278a - - "➋": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠆⠻"] # 0x278b - - "➌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠒⠻"] # 0x278c - - "➍": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠲⠻"] # 0x278d - - "➎": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠢⠻"] # 0x278e - - "➏": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠖⠻"] # 0x278f - - "➐": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠶⠻"] # 0x2790 - - "➑": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠦⠻"] # 0x2791 - - "➒": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠔⠻"] # 0x2792 - - "➓": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2793 - - # --- Nemeth Default Alphabet negative-squared chars. --- - - "🅰-🆉": # 0x1f170 - 0x1f189 - - tc: "⠫⠸⠲⠸⠫⠠" - - spell: "translate('.', '🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - tc: "⠻" - - # --- Nemeth Default Alphabet parenthesized chars. --- - - - "⑴-⑼": # 0x2474 - 0x247c - - tc: "⠷" - - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" - - tc: "⠾" - - - "⑽": [t: "⠷⠂⠴⠾"] # 0x247d - - "⑾": [t: "⠷⠂⠂⠾"] # 0x247e - - "⑿": [t: "⠷⠂⠆⠾"] # 0x247f - - "⒀": [t: "⠷⠂⠒⠾"] # 0x2480 - - "⒁": [t: "⠷⠂⠲⠾"] # 0x2481 - - "⒂": [t: "⠷⠂⠢⠾"] # 0x2482 - - "⒃": [t: "⠷⠂⠖⠾"] # 0x2483 - - "⒄": [t: "⠷⠂⠶⠾"] # 0x2484 - - "⒅": [t: "⠷⠂⠦⠾"] # 0x2485 - - "⒆": [t: "⠷⠂⠔⠾"] # 0x2486 - - "⒇": [t: "⠷⠆⠴⠾"] # 0x2487 - - - "🄐-🄩": # 0x1f110 - 0x1f129 - - tc: "⠷⠠" - - spell: "translate('.', '🄐🄑🄒🄓🄔🄕🄖🄗🄘🄙🄚🄛🄜🄝🄞🄟🄠🄡🄢🄣🄤🄥🄦🄧🄨🄩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - tc: "⠾" - - - "⒜-⒵": # 0x249c - 0x24b5 - - tc: "⠷" - - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - - tc: "⠾" - - # --- Nemeth Default Alphabet period chars. --- - - "🄀": [t: "⠴⠸⠲"] # 0x1f100 - - "⒈": [t: "⠂⠸⠲"] # 0x2488 - - "⒉": [t: "⠆⠸⠲"] # 0x2489 - - "⒊": [t: "⠒⠸⠲"] # 0x248a - - "⒋": [t: "⠲⠸⠲"] # 0x248b - - "⒌": [t: "⠢⠸⠲"] # 0x248c - - "⒍": [t: "⠖⠸⠲"] # 0x248d - - "⒎": [t: "⠶⠸⠲"] # 0x248e - - "⒏": [t: "⠦⠸⠲"] # 0x248f - - "⒐": [t: "⠔⠸⠲"] # 0x2490 - - - "⒑": [t: "⠂⠴⠸⠲"] # 0x2491 - - "⒒": [t: "⠂⠂⠸⠲"] # 0x2492 - - "⒓": [t: "⠂⠆⠸⠲"] # 0x2493 - - "⒔": [t: "⠂⠒⠸⠲"] # 0x2494 - - "⒕": [t: "⠂⠲⠸⠲"] # 0x2495 - - "⒖": [t: "⠂⠢⠸⠲"] # 0x2496 - - "⒗": [t: "⠂⠖⠸⠲"] # 0x2497 - - "⒘": [t: "⠂⠶⠸⠲"] # 0x2498 - - "⒙": [t: "⠂⠦⠸⠲"] # 0x2499 - - "⒚": [t: "⠂⠔⠸⠲"] # 0x249a - - "⒛": [t: "⠆⠴⠸⠲"] # 0x249b - - # --- Nemeth Default Alphabet sans-serif chars. --- - - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 - - tc: "SE" - - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 - - tc: "SE" - - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb - - tc: "S" - - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" - - # --- Nemeth Default Alphabet sans-serif-bold chars. --- - - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - tc: "SBE" - - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - tc: "SBE" - - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝝖-𝝮": # 0x1d756 - 0x1d76e - - tc: "SBG" - - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝝰-𝞀": # 0x1d770 - 0x1d780 - - tc: "SBG" - - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀', 'αβγδεζηθικλμνξοπρ')" - - - "𝝯": [tc: "SBGL⠫"] # 0x1d76f - - - "𝞁": [tc: "SBVL⠎"] # 0x1d781 - - - "𝞂-𝞄": # 0x1d782 - 0x1d784 - - tc: "SBG" - - spell: "translate('.', '𝞂𝞃𝞄', 'στυ')" - - - "𝞅": [tc: "SBVL⠋"] # 0x1d785 - - - "𝞆-𝞈": # 0x1d786 - 0x1d788 - - tc: "SBG" - - spell: "translate('.', '𝞆𝞇𝞈', 'χψω')" - - - "𝞉": [tc: "⠠⠨⠸⠈⠙"] # 0x1d789 - - "𝞊": [tc: "SBGL⠑"] # 0x1d78a - - "𝞋": [tc: "SBVL⠹"] # 0x1d78b - - - "𝞌-𝞏": # 0x1d78c - 0x1d78f - - tc: "SBG" - - spell: "translate('.', '𝞌𝞍𝞎𝞏', 'κφρπ')" - - - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 - - tc: "SB" - - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - - # --- Nemeth Default Alphabet sans-serif-bold-italic chars. --- - - - "𝘼-𝙕": # 0x1d63c - 0x1d655 - - tc: "SBE" - - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝙖-𝙯": # 0x1d656 - 0x1d66f - - tc: "SBE" - - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - - - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - - tc: "SBG" - - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" - - - "𝞩": [t: "SBGL⠫"] # 0x1d7a9 - - - "𝞪-𝞺": # 0x1d7aa - 0x1d7ba - - tc: "SBG" - - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺', 'αβγδεζηθικλμνξοπρ')" - - - "𝞻": [t: "SBVL⠎"] # 0x1d7bb - - "𝞼": [t: "SBGL⠎"] # 0x1d7bc - - "𝞽": [t: "SBGL⠞"] # 0x1d7bd - - "𝞾": [t: "SBGL⠥"] # 0x1d7be - - "𝞿": [t: "SBVL⠋"] # 0x1d7bf - - - "𝟀": [t: "SBGL⠯"] # 0x1d7c0 - - "𝟁": [t: "SBGL⠽"] # 0x1d7c1 - - "𝟂": [t: "SBGL⠺"] # 0x1d7c2 - - "𝟃": [t: "SBVL⠙"] # 0x1d7c3 - - - "𝟄": [t: "SBGL⠑"] # 0x1d7c4 - - "𝟅": [t: "SBVL⠹"] # 0x1d7c5 - - - "𝟆": [t: "SBGL⠅"] # 0x1d7c6 - - "𝟇": [t: "SBGL⠋"] # 0x1d7c7 - - "𝟈": [t: "SBGL⠗"] # 0x1d7c8 - - "𝟉": [t: "SBGL⠏"] # 0x1d7c9 - - # --- Nemeth Default Alphabet sans-serif-italic chars. --- - - "𝘈-𝘡": # 0x1d608 - 0x1d621 - - tc: "SE" - - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - - - "𝘢-𝘻": # 0x1d622 - 0x1d63b - - tc: "SE" - - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - - # --- Nemeth Default Alphabet script chars. --- - - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - tc: "TE" - - spell: "translate('.', '𝒜𝒞𝒟𝒢𝒥𝒦𝒩𝒪𝒫𝒬𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ACDGJKNOPQSTUVWXYZ')" - - - "ℬ": [t: "TECL⠃"] # 0x212c - - "ℰ": [t: "TECL⠑"] # 0x2130 - - "ℱ": [t: "TECL⠋"] # 0x2131 - - "ℋ": [t: "TECL⠓"] # 0x210b - - "ℐ": [t: "TECL⠊"] # 0x2110 - - "ℒ": [t: "TECL⠇"] # 0x2112 - - "ℳ": [t: "TECL⠍"] # 0x2133 - - "ℛ": [t: "TECL⠗"] # 0x211b - - - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - tc: "TE" - - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒻𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdfhijklmnpqrstuvwxyz')" - - - "ℯ": [t: "TEL⠑"] # 0x212f - - "ℊ": [t: "TEL⠛"] # 0x210a - - "ℴ": [t: "TEL⠕"] # 0x2134 - - # --- Nemeth Default Alphabet squared chars. --- - - - "🄰": [t: "⠫⠲⠸⠫⠠⠁⠻"] # 0x1f130 - - "🄱": [t: "⠫⠲⠸⠫⠠⠃⠻"] # 0x1f131 - - "🄲": [t: "⠫⠲⠸⠫⠠⠉⠻"] # 0x1f132 - - "🄳": [t: "⠫⠲⠸⠫⠠⠙⠻"] # 0x1f133 - - "🄴": [t: "⠫⠲⠸⠫⠠⠑⠻"] # 0x1f134 - - "🄵": [t: "⠫⠲⠸⠫⠠⠋⠻"] # 0x1f135 - - "🄶": [t: "⠫⠲⠸⠫⠠⠛⠻"] # 0x1f136 - - "🄷": [t: "⠫⠲⠸⠫⠠⠓⠻"] # 0x1f137 - - "🄸": [t: "⠫⠲⠸⠫⠠⠊⠻"] # 0x1f138 - - "🄹": [t: "⠫⠲⠸⠫⠠⠚⠻"] # 0x1f139 - - "🄺": [t: "⠫⠲⠸⠫⠠⠅⠻"] # 0x1f13a - - "🄻": [t: "⠫⠲⠸⠫⠠⠇⠻"] # 0x1f13b - - "🄼": [t: "⠫⠲⠸⠫⠠⠍⠻"] # 0x1f13c - - "🄽": [t: "⠫⠲⠸⠫⠠⠝⠻"] # 0x1f13d - - "🄾": [t: "⠫⠲⠸⠫⠠⠕⠻"] # 0x1f13e - - "🄿": [t: "⠫⠲⠸⠫⠠⠏⠻"] # 0x1f13f - - "🅀": [t: "⠫⠲⠸⠫⠠⠟⠻"] # 0x1f140 - - "🅁": [t: "⠫⠲⠸⠫⠠⠗⠻"] # 0x1f141 - - "🅂": [t: "⠫⠲⠸⠫⠠⠎⠻"] # 0x1f142 - - "🅃": [t: "⠫⠲⠸⠫⠠⠞⠻"] # 0x1f143 - - "🅄": [t: "⠫⠲⠸⠫⠠⠥⠻"] # 0x1f144 - - "🅅": [t: "⠫⠲⠸⠫⠠⠧⠻"] # 0x1f145 - - "🅆": [t: "⠫⠲⠸⠫⠠⠺⠻"] # 0x1f146 - - "🅇": [t: "⠫⠲⠸⠫⠠⠭⠻"] # 0x1f147 - - "🅈": [t: "⠫⠲⠸⠫⠠⠽⠻"] # 0x1f148 - - "🅉": [t: "⠫⠲⠸⠫⠠⠵⠻"] # 0x1f149 - - # --- Nemeth Default Alphabet sub chars. --- - - - "₀": [t: "⠰⠴"] # 0x2080 - - "₁": [t: "⠰⠂"] # 0x2081 - - "₂": [t: "⠰⠆"] # 0x2082 - - "₃": [t: "⠰⠒"] # 0x2083 - - "₄": [t: "⠰⠲"] # 0x2084 - - "₅": [t: "⠰⠢"] # 0x2085 - - "₆": [t: "⠰⠖"] # 0x2086 - - "₇": [t: "⠰⠶"] # 0x2087 - - "₈": [t: "⠰⠦"] # 0x2088 - - "₉": [t: "⠰⠔"] # 0x2089 - - # --- Nemeth Default Alphabet super chars. --- - - - "⁰": [t: "⠘⠴"] # 0x2070 - - "¹": [t: "⠘⠂"] # 0xb9 - - "²": [t: "⠘⠆"] # 0xb2 - - "³": [t: "⠘⠒"] # 0xb3 - - "⁴": [t: "⠘⠲"] # 0x2074 - - "⁵": [t: "⠘⠢"] # 0x2075 - - "⁶": [t: "⠘⠖"] # 0x2076 - - "⁷": [t: "⠘⠶"] # 0x2077 - - "⁸": [t: "⠘⠦"] # 0x2078 - - "⁹": [t: "⠘⠔"] # 0x2079 - - # --- Nemeth Default Characters latin-lower-phonetic chars. --- - - - "ø": [t: "⠈⠕"] # 0xf8 - - # --- Nemeth Default Characters math_geometry chars. --- - - - "─": [t: "⠱"] # 0x2500 - - "│": [t: "⠳"] # 0x2502 - - "▰": [t: "⠫⠸⠛"] # 0x25b0 - - "▱": [t: "⠫⠛"] # 0x25b1 - - "▽": [t: "⠨⠫"] # 0x25bd - - "◆": [t: "⠫⠸⠙"] # 0x25c6 - - "◇": [t: "⠫⠙"] # 0x25c7 - - "◈": [t: "⠫⠸⠙"] # 0x25c8 - - "◉": [t: "⠫⠸⠉"] # 0x25c9 - - "◊": [t: "⠫⠙"] # 0x25ca - - "⬟": [t: "⠫⠸⠢"] # 0x2b1f - - "⬠": [t: "⠫⠢"] # 0x2b20 - - "⬡": [t: "⠫⠖"] # 0x2b21 - - "⬢": [t: "⠫⠸⠖"] # 0x2b22 - - "⬣": [t: "⠫⠸⠖"] # 0x2b23 - - "⬤": [t: "⠫⠸⠉"] # 0x2b24 - - "⬥": [t: "⠫⠸⠙"] # 0x2b25 - - # --- Nemeth Default Characters math_symbols chars. --- - - - "\"": [t: "⠄⠄"] # 0x22 - - "¡": [t: "⠖"] # 0xa1 - - "¢": [t: "⠈⠉"] # 0xa2 - - "£": [t: "⠈⠇"] # 0xa3 - - "¤": [t: "⠈⠫"] # 0xa4 - - "¥": [t: "⠈⠽"] # 0xa5 - - "§": [t: "⠈⠠⠎"] # 0xa7 - - "©": [t: "⠘⠉"] # 0xa9 (Copyright) - - "ª": [t: "⠸⠰⠁"] # 0xaa - - "«": [t: "⠐⠅⠈⠐⠅⠻"] # 0xab - - "®": [t: "⠘⠗"] # 0xae - - "´": [t: "⠈"] # 0xb4 - - "µ": [t: "⠨⠍"] # 0xb5 - - "¶": [t: "⠈⠠⠏"] # 0xb6 - - "¿": [t: "⠦"] # 0xbf - - "ʹ": [t: "⠄"] # 0x2b9 - - "ʺ": [t: "⠄⠄"] # 0x2ba - - "˙": [t: "⠡"] # 0x2d9 - - "˜": [t: "⠈⠱"] # 0x2dc - - "‐": [t: "⠤"] # 0x2010 - - "‑": [t: "⠤"] # 0x2011 - - "‒": [t: "⠤⠤"] # 0x2012 - - "–": [t: "⠤⠤"] # 0x2013 - - "‖": [t: "⠳⠳"] # 0x2016 - - "†": [t: "⠸⠻"] # 0x2020 - - "‡": [t: "⠸⠸⠻"] # 0x2021 - - "•": [t: "⠡"] # 0x2022 - - "․": [t: "⠄"] # 0x2024 - - "‥": [t: "⠄⠄"] # 0x2025 - - "′": [t: "⠄"] # 0x2032 - - "″": [t: "⠄⠄"] # 0x2033 - - "‴": [t: "⠄⠄."] # 0x2034 (Triple prime) - - "⁗": [t: "⠄⠄.."] # 0x2057 (Quadruple prime) - - "‼": [t: "⠖⠖"] # 0x203c - - "‾": [t: "⠱"] # 0x203e - - "⁇": [t: "⠹⠹"] # 0x2047 - - "⁈": [t: "⠹⠖"] # 0x2048 - - "⁉": [t: "⠖⠹"] # 0x2049 - - "∀": [t: "⠈⠯"] # 0x2200 - - "∃": [t: "⠈⠿"] # 0x2203 - - "∄": [t: "⠌⠈⠿"] # 0x2204 - - "∅": [t: "⠸⠴"] # 0x2205 - - "∈": [t: "⠈⠑"] # 0x2208 - - "∉": [t: "⠌⠈⠑"] # 0x2209 - - "∊": [t: "⠈⠑"] # 0x220a - - "∋": [t: "⠈⠢"] # 0x220b - - "∌": [t: "⠌⠈⠢"] # 0x220c - - "∍": [t: "⠈⠢"] # 0x220d - - "∎": [t: "⠸⠳"] # 0x220e - - "−": [t: "⠤"] # 0x2212 - - "∓": [t: "⠤⠬"] # 0x2213 - - "∕": [t: "⠸⠌"] # 0x2215 - - "∖": [t: "⠸⠡"] # 0x2216 - - "∗": [t: "⠈⠼"] # 0x2217 - - "∘": [t: "⠨⠡"] # 0x2218 - - "∝": [t: "⠸⠿"] # 0x221d - - "∞": [t: "⠠⠿"] # 0x221e - - "∟": [t: "⠫⠪⠨⠗⠻"] # 0x221f - - "∠": [t: "⠫⠪"] # 0x2220 - - "∢": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2222 - - "∣": [t: "⠳"] # 0x2223 - - "∤": [t: "⠌⠳"] # 0x2224 - - "∥": [t: "⠫⠇"] # 0x2225 - - "∦": [t: "⠌⠫⠇"] # 0x2226 - - "∧": [t: "⠈⠩"] # 0x2227 - - "∨": [t: "⠈⠬"] # 0x2228 - - "∩": [t: "⠨⠩"] # 0x2229 - - "∪": [t: "⠨⠬"] # 0x222a - - "∫": [t: "⠮"] # 0x222b - - "∬": [t: "⠮⠮"] # 0x222c - - "∭": [t: "⠮⠮⠮"] # 0x222d - - "∮": [t: "⠮⠈⠫⠉⠻"] # 0x222e - - "∲": [t: "⠮⠈⠫⠪⠢⠔⠻"] # 0x2232 - - "∳": [t: "⠮⠈⠫⠢⠔⠕⠻"] # 0x2233 - - "∴": [t: "⠠⠡"] # 0x2234 - - "∵": [t: "⠈⠌"] # 0x2235 - - "∶": [t: "⠐⠂"] # 0x2236 - - "∷": [t: "⠰⠆"] # 0x2237 - - "∸": [t: "⠨⠤"] # 0x2238 - - "∼": [t: "⠈⠱"] # 0x223c - - "≁": [t: "⠌⠈⠱"] # 0x2241 - - "≂": [t: "⠱⠈⠱"] # 0x2242 - - "≃": [t: "⠈⠱⠱"] # 0x2243 - - "≄": [t: "⠌⠈⠱⠱"] # 0x2244 - - "≅": [t: "⠈⠱⠨⠅"] # 0x2245 - - "≆": [t: "⠈⠱⠌⠨⠅"] # 0x2246 - - "≇": [t: "⠌⠈⠱⠨⠅"] # 0x2247 - - "≈": [t: "⠈⠱⠈⠱"] # 0x2248 - - "≉": [t: "⠌⠈⠱⠈⠱"] # 0x2249 - - "≊": [t: "⠈⠱⠈⠱⠱"] # 0x224a - - "≍": [t: "⠈⠣⠠⠣"] # 0x224d - - "≎": [t: "⠈⠣⠠⠣"] # 0x224e - - "≐": [t: "⠐⠨⠅⠣⠡⠻"] # 0x2250 - - "≑": [t: "⠐⠨⠅⠩⠡⠣⠡⠻"] # 0x2251 - - "≗": [t: "⠐⠨⠅⠣⠨⠡⠻"] # 0x2257 - - "≘": [t: "⠐⠨⠅⠣⠫⠁⠻"] # 0x2258 - - "≙": [t: "⠐⠨⠅⠣⠸⠣⠻"] # 0x2259 - - "≚": [t: "⠐⠨⠅⠣⠸⠩⠻"] # 0x225a - - "≛": [t: "⠐⠨⠅⠣⠫⠸⠎⠻"] # 0x225b - - "≜": [t: "⠐⠨⠅⠣⠫⠞⠻"] # 0x225c - - "≝": [t: "⠐⠨⠅⠣⠙⠑⠋⠻"] # 0x225d - - "≞": [t: "⠐⠨⠅⠣⠍⠻"] # 0x225e - - "≟": [t: "⠐⠨⠅⠣⠸⠦⠻"] # 0x225f - - "≠": [t: "⠌⠨⠅"] # 0x2260 - - "≢": [t: "⠌⠸⠇"] # 0x2262 - - "≤": [t: "⠐⠅⠱"] # 0x2264 - - "≥": [t: "⠨⠂⠱"] # 0x2265 - - "≦": [t: "⠐⠅⠨⠅"] # 0x2266 - - "≧": [t: "⠨⠂⠨⠅"] # 0x2267 - - "≨": [t: "⠐⠅⠌⠨⠅"] # 0x2268 - - "≩": [t: "⠨⠂⠌⠨⠅"] # 0x2269 - - "≪": [t: "⠐⠅⠈⠐⠅⠻"] # 0x226a - - "≫": [t: "⠨⠂⠈⠨⠂⠻"] # 0x226b - - "≭": [t: "⠌⠈⠣⠠⠣"] # 0x226d - - "≮": [t: "⠌⠐⠅"] # 0x226e - - "≯": [t: "⠌⠨⠂"] # 0x226f - - "≰": [t: "⠌⠐⠅⠱"] # 0x2270 - - "≱": [t: "⠌⠨⠂⠱"] # 0x2271 - - "≲": [t: "⠐⠅⠈⠱"] # 0x2272 - - "≳": [t: "⠨⠂⠈⠱"] # 0x2273 - - "≴": [t: "⠌⠐⠅⠈⠱"] # 0x2274 - - "≵": [t: "⠌⠨⠂⠈⠱"] # 0x2275 - - "≶": [t: "⠐⠅⠨⠂"] # 0x2276 - - "≷": [t: "⠨⠂⠐⠅"] # 0x2277 - - "≸": [t: "⠌⠐⠅⠨⠂"] # 0x2278 - - "≹": [t: "⠌⠨⠂⠐⠅"] # 0x2279 - - "≺": [t: "⠨⠐⠅"] # 0x227a - - "≻": [t: "⠨⠨⠂"] # 0x227b - - "≼": [t: "⠨⠐⠅⠱"] # 0x227c - - "≽": [t: "⠨⠨⠐⠱"] # 0x227d - - "≾": [t: "⠨⠐⠅⠈⠱"] # 0x227e - - "≿": [t: "⠨⠨⠂⠈⠱"] # 0x227f - - "⊀": [t: "⠌⠨⠐⠅"] # 0x2280 - - "⊁": [t: "⠌⠨⠐⠅"] # 0x2281 - - "⊂": [t: "⠸⠐⠅"] # 0x2282 - - "⊃": [t: "⠸⠨⠂"] # 0x2283 - - "⊄": [t: "⠌⠸⠐⠅"] # 0x2284 - - "⊅": [t: "⠌⠸⠨⠂"] # 0x2285 - - "⊆": [t: "⠸⠐⠅⠱"] # 0x2286 - - "⊇": [t: "⠸⠨⠂⠱"] # 0x2287 - - "⊈": [t: "⠌⠸⠐⠅⠱"] # 0x2288 - - "⊉": [t: "⠌⠸⠨⠂⠱"] # 0x2289 - - "⊊": [t: "⠸⠐⠅⠌⠨⠅"] # 0x228a - - "⊋": [t: "⠸⠨⠂⠌⠨⠅"] # 0x228b - - "⊥": [t: "⠫⠏"] # 0x22a5 - - "⋀": [t: "⠈⠩"] # 0x22c0 - - "⋁": [t: "⠈⠬"] # 0x22c1 - - "⋂": [t: "⠨⠩"] # 0x22c2 - - "⋃": [t: "⠨⠬"] # 0x22c3 - - "⋄": [t: "⠫⠙"] # 0x22c4 - - "⋜": [t: "⠱⠐⠅"] # 0x22dc - - "⋝": [t: "⠱⠨⠂"] # 0x22dd - - "⟂": [t: "⠫⠏"] # 0x27c2 - - "⦀": [t: "⠳⠳⠳"] # 0x2980 - - "⦶": [t: "⠫⠉⠸⠫⠳⠻"] # 0x29b6 - - "⦷": [t: "⠫⠉⠸⠫⠫⠇⠻"] # 0x29b7 - - "⦸": [t: "⠫⠉⠸⠫⠸⠡⠻"] # 0x29b8 - - "⦹": [t: "⠫⠉⠸⠫⠫⠏⠻"] # 0x29b9 - - "⦿": [t: "⠫⠉⠸⠫⠔⠔⠻"] # 0x29bf - - "⧀": [t: "⠫⠉⠸⠫⠐⠅⠻"] # 0x29c0 - - "⧁": [t: "⠫⠉⠸⠫⠨⠂⠻"] # 0x29c1 - - "⨀": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2a00 - - "⨁": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2a01 - - "⨂": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2a02 - - "⪯": [t: "⠨⠐⠅⠱"] # 0x2aaf - - "⪰": [t: "⠨⠨⠂⠱"] # 0x2ab0 - - "⪱": [t: "⠨⠐⠅⠌⠱"] # 0x2ab1 - - "⪲": [t: "⠨⠨⠂⠌⠱"] # 0x2ab2 - - "⪳": [t: "⠨⠐⠅⠨⠅"] # 0x2ab3 - - "⪴": [t: "⠨⠨⠂⠨⠅"] # 0x2ab4 - - "⪵": [t: "⠨⠐⠅⠌⠨⠅"] # 0x2ab5 - - "⪶": [t: "⠨⠨⠂⠌⠨⠅"] # 0x2ab6 - - "⪷": [t: "⠨⠐⠅⠈⠱⠈⠱"] # 0x2ab7 - - "⪸": [t: "⠨⠨⠂⠈⠱⠈⠱"] # 0x2ab8 - - "⪹": [t: "⠨⠐⠅⠌⠈⠱⠈⠱"] # 0x2ab9 - - "⪺": [t: "⠨⠨⠂⠌⠈⠱⠈⠱"] # 0x2aba - - "⪻": [t: "⠨⠐⠅⠈⠨⠐⠅⠻"] # 0x2abb - - "⪼": [t: "⠨⠨⠂⠈⠨⠨⠂⠻"] # 0x2abc - - "﹩": [t: "⠈⠎"] # 0xfe69 - - "$": [t: "⠈⠎"] # 0xff04 - - "_": [t: "⠱"] # 0xff3f - - "~": [t: "⠈⠱"] # 0xff5e - - "¢": [t: "⠈⠉"] # 0xffe0 - - "£": [t: "⠈⠇"] # 0xffe1 - - " ̄": [t: "⠱"] # 0xffe3 - - "¥": [t: "⠈⠽"] # 0xffe5 - - # --- Nemeth Default Characters rest chars. --- - - - "ℵ": [t: "⠠⠠⠁"] # 0x2135 - - "ℶ": [t: "⠠⠠⠃"] # 0x2136 - - "ℷ": [t: "⠠⠠⠉"] # 0x2137 - - "ℸ": [t: "⠠⠠⠙"] # 0x2138 - - "à": [t: "⠈⠁"] # 0xe0 - - "á": [t: "⠈⠁"] # 0xe1 - - "â": [t: "⠈⠁"] # 0xe2 - - "ã": [t: "⠈⠁"] # 0xe3 - - "ä": [t: "⠈⠁"] # 0xe4 - - "å": [t: "⠈⠁"] # 0xe5 - - "ç": [t: "⠈⠉"] # 0xe7 - - "è": [t: "⠈⠑"] # 0xe8 - - "é": [t: "⠈⠑"] # 0xe9 - - "ê": [t: "⠈⠑"] # 0xea - - "ë": [t: "⠈⠑"] # 0xeb - - "ì": [t: "⠈⠊"] # 0xec - - "í": [t: "⠈⠊"] # 0xed - - "î": [t: "⠈⠊"] # 0xee - - "ï": [t: "⠈⠊"] # 0xef - - "ñ": [t: "⠈⠝"] # 0xf1 - - "ò": [t: "⠈⠕"] # 0xf2 - - "ó": [t: "⠈⠕"] # 0xf3 - - "ô": [t: "⠈⠕"] # 0xf4 - - "õ": [t: "⠈⠕"] # 0xf5 - - "ö": [t: "⠈⠕"] # 0xf6 - - "ù": [t: "⠈⠥"] # 0xf9 - - "ú": [t: "⠈⠥"] # 0xfa - - "û": [t: "⠈⠥"] # 0xfb - - "ü": [t: "⠈⠥"] # 0xfc - - "ý": [t: "⠈⠽"] # 0xfd - - "ÿ": [t: "⠈⠽"] # 0xff - - - "À": [t: "⠠⠈⠁"] # 0xc0 - - "Á": [t: "⠠⠈⠁"] # 0xc1 - - "Â": [t: "⠠⠈⠁"] # 0xc2 - - "Ã": [t: "⠠⠈⠁"] # 0xc3 - - "Ä": [t: "⠠⠈⠁"] # 0xc4 - - "Å": [t: "⠠⠈⠁"] # 0xc5 - - "Ç": [t: "⠠⠈⠉"] # 0xc7 - - "È": [t: "⠠⠈⠑"] # 0xc8 - - "É": [t: "⠠⠈⠑"] # 0xc9 - - "Ê": [t: "⠠⠈⠑"] # 0xca - - "Ë": [t: "⠠⠈⠑"] # 0xcb - - "Ì": [t: "⠠⠈⠊"] # 0xcc - - "Í": [t: "⠠⠈⠊"] # 0xcd - - "Î": [t: "⠠⠈⠊"] # 0xce - - "Ï": [t: "⠠⠈⠊"] # 0xcf - - "Ñ": [t: "⠠⠈⠝"] # 0xd1 - - "Ò": [t: "⠠⠈⠕"] # 0xd2 - - "Ó": [t: "⠠⠈⠕"] # 0xd3 - - "Ô": [t: "⠠⠈⠕"] # 0xd4 - - "Ö": [t: "⠠⠈⠕"] # 0xd6 - - "Ù": [t: "⠠⠈⠥"] # 0xd9 - - "Ú": [t: "⠠⠈⠥"] # 0xda - - "Û": [t: "⠠⠈⠥"] # 0xdb - - "Ü": [t: "⠠⠈⠥"] # 0xdc - - "Ý": [t: "⠠⠈⠽"] # 0xdd - - "←": [t: "⠫⠪⠒⠒"] # 0x2190 - - - "↑": # 0x2191 - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠣"] - else: [t: "⠫⠣⠒⠒⠕"] - - - "↓": # 0x2193 - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠩"] - else: [t: "⠫⠩⠒⠒⠕"] - - - "↔": [t: "⠫⠪⠒⠒⠕"] # 0x2194 - - "↕": [t: "⠫⠣⠩⠪⠒⠒⠕"] # 0x2195 - - "↖": [t: "⠫⠘⠪⠒⠒"] # 0x2196 - - "↗": [t: "⠫⠘⠒⠒⠕"] # 0x2197 - - "↘": [t: "⠫⠰⠒⠒⠕"] # 0x2198 - - "↙": [t: "⠫⠰⠪⠒⠒"] # 0x2199 - - "↚": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x219a - - "↛": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x219b - - "↜": [t: "⠫⠪⠔⠒⠢"] # 0x219c - - "↝": [t: "⠫⠔⠒⠢⠕"] # 0x219d - - "↞": [t: "⠫⠪⠪⠒⠒"] # 0x219e - - "↟": [t: "⠫⠣⠒⠒⠕⠕"] # 0x219f - - "↠": [t: "⠫⠒⠒⠕⠕"] # 0x21a0 - - "↡": [t: "⠫⠩⠒⠒⠕⠕"] # 0x21a1 - - "↢": [t: "⠫⠪⠒⠒⠠⠽"] # 0x21a2 - - "↣": [t: "⠫⠠⠯⠒⠒⠕"] # 0x21a3 - - "↤": [t: "⠫⠪⠒⠒⠳"] # 0x21a4 - - "↥": [t: "⠫⠣⠳⠒⠒⠕"] # 0x21a5 - - "↦": [t: "⠫⠳⠒⠒⠕"] # 0x21a6 - - "↧": [t: "⠫⠩⠳⠒⠒⠕"] # 0x21a7 - - "↨": [t: "⠫⠪⠒⠳⠒⠕"] # 0x21a8 - - "↩": [t: "⠫⠪⠒⠒⠠⠕"] # 0x21a9 - - "↪": [t: "⠫⠠⠪⠒⠒⠕"] # 0x21aa - - "↫": [t: "⠫⠪⠒⠒⠨⠡"] # 0x21ab - - "↬": [t: "⠫⠨⠡⠒⠒⠕"] # 0x21ac - - "↭": [t: "⠫⠪⠔⠒⠢⠕"] # 0x21ad - - "↮": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21ae - - "↯": [t: "⠫⠩⠔⠢⠔"] # 0x21af - - "↴": [t: "⠫⠠⠳⠒⠒⠕"] # 0x21b4 - - "↵": [t: "⠫⠩⠠⠳⠒⠒⠕"] # 0x21b5 - - "↶": [t: "⠫⠢⠔⠕"] # 0x21b6 - - "↷": [t: "⠫⠪⠢⠔"] # 0x21b7 - - "↺": [t: "⠫⠢⠔⠕"] # 0x21ba - - "↻": [t: "⠫⠪⠢⠔"] # 0x21bb - - "⇄": [t: "⠫⠒⠒⠕⠫⠪⠒⠒"] # 0x21c4 - - "⇅": [t: "⠫⠣⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21c5 - - "⇆": [t: "⠫⠪⠒⠒⠫⠒⠒⠕"] # 0x21c6 - - "⇇": [t: "⠫⠚⠒⠒⠫⠚⠒⠒"] # 0x21c7 - - "⇈": [t: "⠫⠣⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21c8 - - "⇉": [t: "⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21c9 - - "⇊": [t: "⠫⠩⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21ca - - "⇍": [t: "⠳⠈⠫⠪⠪⠒⠒"] # 0x21cd - - "⇎": [t: "⠳⠈⠫⠪⠪⠒⠒⠕⠕"] # 0x21ce - - "⇏": [t: "⠳⠈⠫⠒⠒⠕⠕"] # 0x21cf - - "⇐": [t: "⠫⠪⠶⠶"] # 0x21d0 - - "⇑": [t: "⠫⠣⠶⠶⠕"] # 0x21d1 - - "⇒": [t: "⠫⠶⠶⠕"] # 0x21d2 - - "⇓": [t: "⠫⠣⠶⠶⠕"] # 0x21d3 - - "⇔": [t: "⠫⠪⠶⠶⠕"] # 0x21d4 - - "⇕": [t: "⠫⠣⠪⠶⠶⠕"] # 0x21d5 - - "⇖": [t: "⠫⠘⠪⠶⠶"] # 0x21d6 - - "⇗": [t: "⠫⠘⠶⠶⠕"] # 0x21d7 - - "⇘": [t: "⠫⠰⠶⠶⠕"] # 0x21d8 - - "⇙": [t: "⠫⠰⠪⠪⠒⠒"] # 0x21d9 - - "⇚": [t: "⠫⠪⠪⠶⠶"] # 0x21da FIX: how to represent triple shafts? - - "⇛": [t: "⠫⠶⠶⠕⠕"] # 0x21db FIX: how to represent triple shafts? - - "⇜": [t: "⠫⠪⠢⠤⠔⠒⠢"] # 0x21dc - - "⇝": [t: "⠫⠢⠤⠔⠒⠢⠕"] # 0x21dd - - "⇞": [t: "⠳⠳⠈⠫⠣⠒⠒⠕⠻"] # 0x21de - - "⇟": [t: "⠳⠳⠈⠫⠩⠒⠒⠕⠻"] # 0x21df - - "⇠": [t: "⠫⠪⠒⠒"] # 0x21e0 - - "⇡": [t: "⠫⠣⠒⠒⠕"] # 0x21e1 - - "⇢": [t: "⠫⠒⠒⠕"] # 0x21e2 - - "⇣": [t: "⠫⠩⠒⠒⠕"] # 0x21e3 - - "⇤": [t: "⠫⠳⠪⠒⠒"] # 0x21e4 - - "⇥": [t: "⠫⠒⠒⠕⠳"] # 0x21e5 - - "⇦": [t: "⠫⠸⠪⠒⠒"] # 0x21e6 - - "⇧": [t: "⠫⠣⠸⠒⠒⠕"] # 0x21e7 - - "⇨": [t: "⠫⠸⠒⠒⠕"] # 0x21e8 - - "⇩": [t: "⠫⠩⠸⠒⠒⠕"] # 0x21e9 - - "⇳": [t: "⠫⠣⠸⠪⠒⠒⠕"] # 0x21f3 - - "⇴": [t: "⠫⠒⠒⠕⠨⠡"] # 0x21f4 - - "⇵": [t: "⠫⠩⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21f5 - - "⇶": [t: "⠫⠒⠒⠕⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21f6 - - "⇷": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x21f7 - - "⇸": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x21f8 - - "⇹": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21f9 - - "⇺": [t: "⠳⠳⠈⠫⠪⠒⠒⠻"] # 0x21fa - - "⇻": [t: "⠳⠳⠈⠫⠒⠒⠕⠻"] # 0x21fb - - "⇼": [t: "⠳⠳⠈⠫⠪⠒⠒⠕"] # 0x21fc - - "⇽": [t: "⠫⠳⠒⠒"] # 0x21fd - - "⇾": [t: "⠫⠒⠒⠳"] # 0x21fe - - "⇿": [t: "⠫⠳⠒⠒⠳"] # 0x21ff - - - "ⅆ": [t: "⠙"] # 0x2146 - - "ⅇ": [t: "⠑"] # 0x2147 - - "ⅈ": [t: "⠊"] # 0x2148 - - "⌜": [t: "⠈⠘⠷"] # 0x231c - - "⌝": [t: "⠈⠘⠾"] # 0x231d - - "⌞": [t: "⠈⠰⠷"] # 0x231e - - "⌟": [t: "⠈⠰⠾"] # 0x231f - - "〈": [t: "⠨⠨⠷"] # 0x2329 - - "〉": [t: "⠨⠨⠾"] # 0x232a - - "⏞": [t: "⠨⠷"] # 0x23de - - "⏟": [t: "⠨⠾"] # 0x23df - - "⎴": [t: "⠈⠷"] # 0x23b4 - - "⎵": [t: "⠈⠾"] # 0x23b5 - - "⟪": [t: "⠨⠨⠨⠷"] # 0x27ea - - "⟫": [t: "⠨⠨⠨⠾"] # 0x27eb - - "〈": [t: "⠨⠨⠷"] # 0x3008 - - "〉": [t: "⠨⠨⠾"] # 0x3009 - - "《": [t: "⠨⠨⠨⠷"] # 0x300a - - "》": [t: "⠨⠨⠨⠾"] # 0x300b - - "「": [t: "⠈⠘⠷"] # 0x300c - - "」": [t: "⠈⠘⠾"] # 0x300d - - "↼": [t: "⠫⠈⠪⠒⠒"] # 0x21bc - - "↽": [t: "⠫⠠⠪⠒⠒"] # 0x21bd - - "↾": [t: "⠫⠣⠒⠒⠠⠕"] # 0x21be - - "↿": [t: "⠫⠣⠒⠒⠈⠕"] # 0x21bf - - "⇀": [t: "⠫⠒⠒⠈⠕"] # 0x21c0 - - "⇁": [t: "⠫⠒⠒⠠⠕"] # 0x21c1 - - "⇂": [t: "⠫⠪⠒⠒⠈⠕"] # 0x21c2 - - "⇃": [t: "⠫⠩⠒⠒⠠⠕"] # 0x21c3 - - "⇋": # 0x21cb - - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠫⠒⠕"] - else: [t: "⠫⠈⠪⠒⠒⠫⠒⠒⠈⠕"] - - "⇌": # 0x21cc - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] - - - "℔": [t: "⠳"] # 0x2114 - - "™": [t: "⠘⠞"] # 0x2122 - - "Å": [t: "⠈⠠⠁"] # 0x212b - - "­": [t: "⠤"] # 0xad - - " -​": [t: "W"] # 0x2000 - 0x200b (various spaces / ZWSP) - - "
": [t: "W"] # 0x2028 - - "
": [t: "W"] # 0x2029 - - " ": [t: "W"] # 0x202f - - " ": [t: "W"] # 0x205f - - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign - - "₦": [t: "⠈⠝"] # 0x2046 (Naira sign) - - "₩": [t: "⠈⠺"] # 0x20A9 (Won sign) - - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) - - "": [t: "W"] # 0xfeff - - "☆": [t: "⠫⠎"] # 0x2606 - - "✕": [t: "⠈⠡"] # 0x2715 - - "¼": [t: "⠹⠂⠌⠲⠼"] # 0xbc - - "½": [t: "⠹⠂⠌⠆⠼"] # 0xbd - - "¾": [t: "⠹⠒⠌⠲⠼"] # 0xbe - - "⅐": [t: "⠹⠂⠌⠶⠼"] # 0x2150 - - "⅑": [t: "⠹⠂⠌⠔⠼"] # 0x2151 - - "⅒": [t: "⠹⠂⠌⠂⠴⠼"] # 0x2152 - - "⅓": [t: "⠹⠂⠌⠒⠼"] # 0x2153 - - "⅔": [t: "⠹⠆⠌⠒⠼"] # 0x2154 - - "⅕": [t: "⠹⠂⠌⠢⠼"] # 0x2155 - - "⅖": [t: "⠹⠆⠌⠢⠼"] # 0x2156 - - "⅗": [t: "⠹⠒⠌⠢⠼"] # 0x2157 - - "⅘": [t: "⠹⠲⠌⠢⠼"] # 0x2158 - - "⅙": [t: "⠹⠂⠌⠖⠼"] # 0x2159 - - "⅚": [t: "⠹⠢⠌⠖⠼"] # 0x215a - - "⅛": [t: "⠹⠂⠌⠦⠼"] # 0x215b - - "⅜": [t: "⠹⠒⠌⠦⠼"] # 0x215c - - "⅝": [t: "⠹⠢⠌⠦⠼"] # 0x215d - - "⅞": [t: "⠹⠶⠌⠦⠼"] # 0x215e - - "⅟": [t: "⠹⠂⠌⠼"] # 0x215f - - "↉": [t: "⠹⠴⠌⠒⠼"] # 0x2189 - - "㉈": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x3248 - - "㉉": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠆⠴⠻⠻"] # 0x3249 - - "㉊": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠒⠴⠻⠻"] # 0x324a - - "㉋": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠲⠴⠻⠻"] # 0x324b - - "㉌": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠢⠴⠻⠻"] # 0x324c - - "㉍": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠖⠴⠻⠻"] # 0x324d - - "㉎": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠶⠴⠻⠻"] # 0x324e - - "㉏": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠦⠴⠻⠻"] # 0x324f - - - - "‘": [t: "P⠠⠦"] # 0x2018 (Left single quotation mark) - - "’": [t: "P⠠⠴"] # 0x2019 (Right single quotation mark) - - "“": [t: "P⠦"] # 0x201C (Left double quotation mark) - - "”": [t: "P⠴"] # 0x201D (Right double quotation mark) - - "‰": [t: "`00"] - - "ℏ": [t: "⠈⠓"] # 0x210F (Planck constant over two pi) - - "ℓ": [t: "TE⠇"] # 0x2113 (Script small l (differs from 1d4c1: 4-56-123)) - - "℘": [tc: "TCL⠏"] # 0x2118 (Script Capital P) -# - "ℝ": [t: ""] # 0x211D (Double-struck capital R (no nemeth double struck)) -# - "ⅆ": [t: ""] # 0x2146 (Double-struck italic small d) -# - "ⅇ": [t: ""] # 0x2147 (Double-struck italic small e) -# - "⇚": [t: "⠀⠫⠪⠸⠸⠀"] # 0x21DA (Leftwards triple arrow) -# - "⇛": [t: "⠀⠫⠸⠸⠕⠀"] # 0x21DB (Rightwards triple arrow) - - "∔": [t: "⠐⠬⠣⠡⠻"] # 0x2214 (Dot plus) - - "√": [t: "⠜"] # 0x221A (Square root) - - "∛": [t: "⠣⠒⠜"] # 0x221B (Cube root) - - "∜": [t: "⠣⠲⠜"] # 0x221C (Fourth root) - - "∡": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2221 (Measured angle) - - "∹": [t: "⠤⠐⠂"] # 0x2239 (Excess) - - "∺": [t: "⠐⠤⠩⠡⠡⠣⠡⠡⠻"] # 0x223A (Geometric proportion) - - "∻": [t: "⠐⠈⠱⠩⠡⠣⠡⠻"] # 0x223B (Homothetic) - - "∽": [t: "⠠⠱"] # 0x223D (Reversed tilde) - - "≋": [t: "⠈⠱⠈⠱⠈⠱"] # 0x224B (Triple tilde) - - "≌": [t: "⠠⠱⠨⠅"] # 0x224C (All equal to) - - "≏": [t: "⠈⠣⠱"] # 0x224F (Difference between) - - "≔": [t: "⠐⠂⠨⠅"] # 0x2254 (Colon equals) - - "≕": [t: "⠨⠅⠐⠂"] # 0x2255 (Equals colon) - - "≖": [t: "⠀⠨⠡⠈⠨⠅⠻⠀"] # 0x2256 (Ring in equal to) - - "⊌": [t: "⠨⠬⠈⠫⠪⠒⠻"] # 0x228C (Multiset) - - "⊍": [t: "⠡⠈⠨⠬⠻"] # 0x228D (Multiset multiplication) - - "⊎": [t: "⠬⠈⠨⠬⠻"] # 0x228E (Multiset union) - - "⊕": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2295 (Circled plus) - - "⊖": [t: "⠫⠉⠸⠫⠤⠻"] # 0x2296 (Circled minus) - - "⊗": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2297 (Circled times) - - "⊘": [t: "⠫⠉⠸⠫⠸⠌⠻"] # 0x2298 (Circled division slash) - - "⊙": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2299 (Circled dot operator) - - "⊚": [t: "⠫⠉⠸⠫⠘⠨⠡⠻"] # 0x229a (Circled ring operator) - - "⊛": [t: "⠫⠉⠸⠫⠈⠼⠻"] # 0x229B (Circled asterisk operator) - - "⊜": [t: "⠫⠉⠸⠫⠨⠅⠻"] # 0x229C (Circled equals) - - "⊝": [t: "⠫⠉⠸⠫⠤⠤⠻"] # 0x229D (Circled dash) - - "⊞": [t: "⠫⠲⠸⠫⠬⠻"] # 0x229E (Squared plus) - - "⊟": [t: "⠫⠲⠸⠫⠤⠻"] # 0x229F (Squared minus) - - "⊠": [t: "⠫⠲⠸⠫⠈⠡⠻"] # 0x22A0 (Squared times) - - "⊡": [t: "⠫⠲⠸⠫⠡⠻"] # 0x22A1 (Squared dot operator) - - "⊢": [t: "⠫⠳⠒"] # 0x22A2 (Right tack) - - "⊣": [t: "⠫⠒⠳"] # 0x22A3 (Left tack) - - "⊤": [t: "⠫⠩⠳⠒"] # 0x22A4 (Down tack) -# - "⊥": [t: "⠀⠫⠏⠀ or ⠀⠫⠣⠳⠒⠀"] # 0x22A5 (Up tack (See also 27C2)) -# - "⊦": [t: ""] # 0x22A6 (Assertion) -# - "⊨": [t: ""] # 0x22A8 (TRUE) -# - "⊲": [t: ""] # 0x22B2 (Normal subgroup of) -# - "⊳": [t: ""] # 0x22B3 (Contains as normal subgroup) -# - "⊴": [t: ""] # 0x22B4 (Normal subgroup of or equal to) -# - "⊵": [t: ""] # 0x22B5 (Contains as normal subgroup or equal to) - - "⊶": [t: "⠫⠨⠡⠒⠡"] # 0x22B6 (Original of) - - "⊷": [t: "⠫⠡⠒⠨⠡"] # 0x22B7 (Image of) - - "⊸": [t: "⠫⠒⠨⠡"] # 0x22B8 (Multimap) -# - "⊾": [t: ""] # 0x22BE (Right angle w arc) - - "⊿": [t: "⠫⠞⠨⠗⠻"] # 0x22BF (Right triangle) - - "⋅": [t: "⠡"] # 0x22C5 (Dot operator) - - "∙": [t: "⠡"] # 0x2219 -- similar looking to 0x22c5, so using the same braille - - "⋆": [t: "⠫⠎"] # 0x22C6 (Star operator) - - "⋍": [t: "⠠⠱⠱"] # 0x22CD (Reversed tilde equals) - - "⋖": [t: "⠡⠈⠐⠅⠻"] # 0x22D6 (Less-than w dot) - - "⋗": [t: "⠡⠈⠨⠂⠻"] # 0x22D7 (Greater-than w dot) - - "⋘": [t: "⠐⠅⠈⠐⠅⠈⠐⠅⠻"] # 0x22D8 (Much less-than) - - "⋙": [t: "⠨⠂⠈⠨⠂⠈⠨⠂⠻"] # 0x22D9 (Much greater-than) - - "⋲": [t: "⠱⠈⠈⠑⠻"] # 0x22F2 (Element of w long horizontal stroke) - - "⋵": [t: "⠐⠈⠑⠣⠡⠻"] # 0x22F5 (Element of w dot above) - - "⋶": [t: "⠱⠈⠑"] # 0x22F6 (Element of w overbar) - - "⋺": [t: "⠱⠈⠈⠢⠻"] # 0x22FA (Contains w long horizontal stroke) - - "⋽": [t: "⠱⠈⠢"] # 0x22FD (Contains w overbar) - - "⌈": [t: "⠈⠘⠷"] # 0x2308 (Left ceiling) - - "⌉": [t: "⠈⠘⠾"] # 0x2309 (Right ceiling) - - "⌊": [t: "⠈⠰⠷"] # 0x230A (Left floor) - - "⌋": [t: "⠈⠰⠾"] # 0x230B (Right floor) - - "⌢": [t: "⠫⠁"] # 0x2322 (Frown) - - "⌣": [t: "⠫⠄"] # 0x2323 (Smile) - - "■": [t: "⠫⠸⠲"] # 0x25A0 (Filled square) - - "▫": [t: "⠫⠲"] # 0x25AB (Small white Square) - - "□": [t: "⠫⠲"] # 0x25A1 (Square) - - "◻": [t: "⠫⠲"] # 0x25FB (Square) - - "▬": [t: "⠫⠸⠗"] # 0x25AC (Filled rectangle) - - "▭": [t: "⠫⠗"] # 0x25AD (Rectangle) - - "▲": [t: "⠫⠸⠞"] # 0x25B2 (Black up-pointing triangle) - - "△": [t: "⠫⠞"] # 0x25B3 (White up-pointing triangle) - - "▼": [t: "⠸⠨⠫"] # 0x25BC (Black down-pointing triangle) - - "○": [t: "⠫⠉"] # 0x25CB (White circle) - - "●": [t: "⠫⠸⠉"] # 0x25CF (Black circle) - - "◫": [t: "⠫⠲⠸⠫⠳⠻"] # 0x25EB (White square w vertical bisecting line) -# - "⊥": [t: "⠫⠏"] # 0x27C2 (Perpendicular) - - "⟃": [t: "⠨⠡⠈⠸⠐⠅⠻"] # 0x27C3 (Open subset) - - "⟄": [t: "⠨⠡⠈⠸⠨⠂⠻"] # 0x27C4 (Open superset) - - "⟜": [t: "⠫⠨⠡⠒⠒"] # 0x27DC (Left multimap) - - "⟝": [t: "⠫⠳⠒⠒"] # 0x27DD (Long right tack) - - "⟞": [t: "⠫⠒⠒⠳"] # 0x27DE (Long left tack) - - "⟟": [t: "⠫⠣⠳⠒⠒⠨⠡"] # 0x27DF (Up tack w circle above) - - "⟦": [t: "⠈⠸⠷"] # 0x27E6 (Mathematical left white square bracket) - - "⟧": [t: "⠈⠸⠾"] # 0x27E7 (Mathematical right white square bracket) - - "⟨": [t: "⠨⠨⠷"] # 0x27E8 (Mathematical left angle bracket) - - "⟩": [t: "⠨⠨⠾"] # 0x27E9 (Mathematical right angle bracket) - - "⟵": [t: "⠀⠫⠪⠒⠒⠒⠀"] # 0x27F5 (Long leftwards arrow ) - - "⟶": [t: "⠀⠫⠒⠒⠒⠕⠀"] # 0x27F6 (Long rightwards arrow) - - "⟷": [t: "⠀⠫⠪⠒⠒⠒⠕⠀"] # 0x27F7 (Long left right arrow) - - "⟸": [t: "⠀⠫⠪⠶⠶⠶⠀"] # 0x27F8 (Long leftwards arrow ) - - "⟹": [t: "⠀⠫⠶⠶⠶⠕⠀"] # 0x27F9 (Long rightwards arrow) - - "⟺": [t: "⠀⠫⠪⠶⠶⠶⠕⠀"] # 0x27FA (Long left right arrow) - - "⟻": [t: "⠀⠫⠪⠒⠒⠒⠳⠀"] # 0x27FB (Long leftwards arrow from bar) - - "⟼": [t: "⠀⠫⠳⠒⠒⠒⠕⠀"] # 0x27FC (Long rightwards arrow from bar) - - "⟽": [t: "⠀⠫⠪⠶⠶⠶⠳⠀"] # 0x27FD (Long leftwards double arrow from bar) - - "⟾": [t: "⠀⠫⠳⠶⠶⠶⠕⠀"] # 0x27FE (Long rightwards double arrow from bar) - - "⟿": [t: "⠀⠫⠢⠤⠔⠒⠢⠤⠔⠒⠢⠕⠀"] # 0x27FF (Long rightwards squiggle arrow) - - "⤡": [t: "⠀⠫⠘⠪⠒⠒⠕⠀"] # 0x2921 (North west and south east arrow) - - "⤢": [t: "⠀⠫⠰⠪⠒⠒⠕⠀"] # 0x2922 (North east and south west arrow) - - "🣐": # 0x1f8d0 (Long rightwards arrow over leftwards arrow (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] - - "🣑": # 0x1f8d1 (Long rightwards harpoon over leftwards harpoon (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] - - "🣒": # 0x1f8d2 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] - - "🣓": # 0x1f8d3 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒⠒"] - else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] - - "🣔": # 0x1f8d4 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠒⠫⠒⠕"] - else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] - - "🣕": # 0x1f8d5 (Short leftwards harpoon over long rightwards harpoon (equilibrium, trend to the left)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠫⠒⠒⠕"] - else: [t: "⠫⠈⠪⠒⠫⠒⠒⠠⠕"] - - "⥂": # 0x2942 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠒⠕⠫⠪⠒"] - else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] - - "⥄": # 0x2944 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠒⠕⠫⠪⠒⠒"] - else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] - - "⥃": # 0x2943 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) - - test: - if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" - then: [t: "⠫⠪⠒⠒⠫⠒⠕"] - else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] - - "🣖": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d6 (long rightwards arrow with through X) - - "🣗": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d7 (long rightwards arrow with double slash) chem code says it is same as 0x1f8d6 - - - - "⦃": [t: "⠨⠸⠷"] # 0x2983 (Left white curly bracket) - - "⦄": [t: "⠨⠸⠾"] # 0x2984 (Right white curly bracket) - - "⦑": [t: "⠡⠈⠨⠨⠷⠻"] # 0x2991 (Left angle bracket w dot) - - "⦒": [t: "⠡⠈⠨⠨⠾⠻"] # 0x2992 (Right angle bracket w dot) - - "⧄": [t: "⠫⠲⠸⠫⠔⠻"] # 0x29C4 (Square rising diagonal slash) - - "⧅": [t: "⠫⠲⠸⠫⠢⠻"] # 0x29C5 (Square falling diagonal slash) - - "⧆": [t: "⠫⠲⠸⠫⠈⠼⠻"] # 0x29C6 (Squared asterisk) - - "⧊": [t: "⠐⠫⠞⠣⠡⠻"] # 0x29CA (Triangle w dot above) - - "⧋": [t: "⠫⠞⠱"] # 0x29CB (Triangle w underbar) - - "⧌": [t: "⠫⠞⠎"] # 0x29CC (s in triangle §114) - - "⧦": [t: "⠫⠳⠶⠶⠳"] # 0x29E6 (Gleich stark) - - "⨌": [t: "⠮⠮⠮⠮"] # 0x2A0C (Quadruple integral operator) - - "⨍": [t: "⠮⠈⠱⠻"] # 0x2A0D (Finite part integral) - - "⨎": [t: "⠮⠈⠱⠱⠻"] # 0x2A0E (Integral w double stroke) - - "⨖": [t: "⠮⠈⠫⠲⠻"] # 0x2A16 (Quaternion integral operator) - - "⨘": [t: "⠮⠈⠈⠡⠻"] # 0x2A18 (Integral w times sign) - - "⨙": [t: "⠮⠈⠨⠩⠻"] # 0x2A19 (Integral w intersection) - - "⨚": [t: "⠮⠈⠨⠬⠻"] # 0x2A1A (Integral w union) - - "⨛": [t: "⠣⠮"] # 0x2A1B (Integral w overbar (upper)) - - "⨜": [t: "⠩⠮"] # 0x2A1C (Integral w underbar (lower)) - - "⨢": [t: "⠐⠬⠣⠨⠡⠻"] # 0x2A22 (Plus sign w small circle above) - - "⨣": [t: "⠐⠬⠣⠸⠣⠻"] # 0x2A23 (Plus sign w circumflex accent above) - - "⨤": [t: "⠐⠬⠣⠈⠱⠻"] # 0x2A24 (Plus sign w tilde above) - - "⨥": [t: "⠐⠬⠩⠡⠻"] # 0x2A25 (Plus sign w dot below) - - "⨪": [t: "⠐⠱⠩⠡⠻"] # 0x2A2A (Minus sign w dot below) - - "⨰": [t: "⠐⠈⠡⠣⠡⠻"] # 0x2A30 (Multiplication sign w dot above) - - "⨱": [t: "⠈⠡⠱"] # 0x2A31 (Multiplication sign w underbar) - - "⨸": [t: "⠫⠉⠸⠫⠨⠌⠻"] # 0x2A38 (Circled division sign) - - "⨹": [t: "⠫⠞⠸⠫⠬⠻"] # 0x2A39 (Plus sign in triangle) - - "⨺": [t: "⠫⠞⠸⠫⠤⠻"] # 0x2A3A (Minus sign in triangle) - - "⨻": [t: "⠫⠞⠸⠫⠈⠡⠻"] # 0x2A3B (Multiplication sign in triangle) - - "⩀": [t: "⠡⠈⠨⠩⠻"] # 0x2A40 (Intersection w dot) - - "⩁": [t: "⠤⠈⠨⠬⠻"] # 0x2A41 (Union w minus sign) - - "⩂": [t: "⠱⠨⠬"] # 0x2A42 (Union w overbar) - - "⩃": [t: "⠱⠨⠩"] # 0x2A43 (Intersection w overbar) - - "⩑": [t: "⠐⠈⠩⠣⠡⠻"] # 0x2A51 (Logical AND w dot above) - - "⩒": [t: "⠐⠈⠬⠣⠡⠻"] # 0x2A52 (Logical OR w dot above) - - "⩜": [t: "⠱⠈⠈⠩⠻"] # 0x2A5C (Logical AND with horizontal dash) - - "⩝": [t: "⠱⠈⠈⠬⠻"] # 0x2A5D (Logical OR with horizontal dash) - - "⩞": [t: "⠱⠱⠈⠩"] # 0x2A5E (Logical AND w double overbar) - - "⩟": [t: "⠈⠩⠱"] # 0x2A5F (Logical AND w underbar) - - "⩠": [t: "⠈⠩⠱⠱"] # 0x2A60 (Logical AND w double underbar) - - "⩢": [t: "⠱⠱⠈⠬"] # 0x2A62 (Logical OR w double overbar) - - "⩣": [t: "⠈⠬⠱⠱"] # 0x2A63 (Logical OR w double underbar) - - "⩦": [t: "⠐⠨⠅⠩⠡⠻"] # 0x2A66 (Equals sign w dot below) - - "⩧": [t: "⠐⠸⠇⠣⠡⠻"] # 0x2A67 (Identical w dot above) - - "⩪": [t: "⠐⠈⠱⠣⠡⠻"] # 0x2A6A (Tilde operator w dot above) - - "⩬": [t: "⠈⠱⠱⠈⠱"] # 0x2A6C (Similar minus similar) - - "⩭": [t: "⠐⠈⠱⠨⠅⠣⠡⠻"] # 0x2A6D (Congruent w dot above) - - "⩮": [t: "⠐⠨⠅⠣⠈⠼⠻"] # 0x2A6E (Equals w asterisk) - - "⩯": [t: "⠐⠈⠱⠈⠱⠣⠸⠣⠻"] # 0x2A6F (Almost equal to w circumflex) - - "⩰": [t: "⠈⠱⠈⠱⠨⠅"] # 0x2A70 (Approximately equal or equal to) - - "⩱": [t: "⠨⠅⠬"] # 0x2A71 (Equals sign above plus sign) - - "⩲": [t: "⠬⠨⠅"] # 0x2A72 (Plus sign above equals sign) - - "⩳": [t: "⠨⠅⠈⠱"] # 0x2A73 (Equals sign above tilde operator) - - "⩴": [t: "⠐⠂⠐⠂⠨⠅"] # 0x2A74 (Double colon equal) - - "⩵": [t: "⠨⠅⠨⠅"] # 0x2A75 (Two consecutive equals signs) - - "⩶": [t: "⠨⠅⠨⠅⠨⠅"] # 0x2A76 (Three consecutive equals signs) - - "⩷": [t: "⠐⠨⠅⠩⠡⠡⠣⠡⠡⠻"] # 0x2A77 (Equals sign w two dots above and two dots below) - - "⩸": [t: "⠐⠸⠇⠣⠡⠡⠡⠡⠻"] # 0x2A78 (Equivalent w four dots above) - - "⩹": [t: "⠐⠅⠈⠨⠡⠻"] # 0x2A79 (Less than w circle inside) - - "⩺": [t: "⠨⠂⠈⠨⠡⠻"] # 0x2A7A (Greater than w circle inside) - - "⩻": [t: "⠐⠐⠅⠣⠸⠦⠻"] # 0x2A7B (Less-than w question mark above) - - "⩼": [t: "⠐⠨⠂⠣⠸⠦⠻"] # 0x2A7C (Greater-than w question mark above) - - "⪅": [t: "⠐⠅⠈⠱⠈⠱"] # 0x2A85 (Less-than or approximate) - - "⪆": [t: "⠨⠂⠈⠱⠈⠱"] # 0x2A86 (Greater-than or approximate) - - "⪋": [t: "⠐⠅⠨⠅⠨⠂"] # 0x2A8B (Less-than above double-line equal above greater-than) - - "⪌": [t: "⠨⠂⠨⠅⠐⠅"] # 0x2A8C (Greater-than above double-line equal above less-than) - - "⪍": [t: "⠐⠅⠈⠱⠱"] # 0x2A8D (Less-than above similar or equal to) - - "⪎": [t: "⠨⠂⠈⠱⠱"] # 0x2A8E (Greater-than above similar or equal to) - - "⪏": [t: "⠐⠅⠈⠱⠨⠂"] # 0x2A8F (Less-than above similar above greater-than) - - "⪐": [t: "⠨⠂⠈⠱⠐⠅"] # 0x2A90 (Greater-than above similar above less-than) - - "⪑": [t: "⠐⠅⠨⠂⠨⠅"] # 0x2A91 (Less-than above greater-than above double-line equal) - - "⪒": [t: "⠨⠂⠐⠅⠨⠅"] # 0x2A92 (Greater-than above less-than above double-line equal) - - "⪙": [t: "⠨⠅⠐⠅"] # 0x2A99 (Double-line equal to or less-than) - - "⪚": [t: "⠨⠅⠨⠂"] # 0x2A9A (Double-line equal to or greater-than) - - "⪝": [t: "⠈⠱⠐⠅"] # 0x2A9D (Similar or less-than) - - "⪞": [t: "⠈⠱⠨⠂"] # 0x2A9E (Similar or greater-than) - - "⪟": [t: "⠈⠱⠐⠅⠨⠅"] # 0x2A9F (Similar above less-than above equals sign) - - "⪠": [t: "⠈⠱⠨⠂⠨⠅"] # 0x2AA0 (Similar above greater-than above equals sign) - - "⪮": [t: "⠈⠣⠨⠅"] # 0x2AAE (Equals sign with bumpy above) - - "⪽": [t: "⠡⠈⠸⠐⠅⠻"] # 0x2ABD (Subset w dot) - - "⪾": [t: "⠡⠈⠸⠨⠂⠻"] # 0x2ABE (Superset w dot) - - "⪿": [t: "⠐⠸⠐⠅⠩⠬⠻"] # 0x2ABF (Subset with plus sign below) - - "⫀": [t: "⠐⠸⠨⠂⠩⠬⠻"] # 0x2AC0 (Superset with plus sign below) - - "⫁": [t: "⠐⠸⠐⠅⠩⠈⠡⠻"] # 0x2AC1 (Subset with multiplication sign below) - - "⫂": [t: "⠐⠸⠨⠂⠩⠈⠡⠻"] # 0x2AC2 (Superset with multiplication sign below) - - "⫅": [t: "⠸⠐⠅⠨⠅"] # 0x2AC5 (Subset of above equals sign) - - "⫆": [t: "⠸⠨⠂⠨⠅"] # 0x2AC6 (Superset of above equals sign) - - "⫇": [t: "⠸⠐⠅⠈⠱"] # 0x2AC7 (Subset of above tilde operator) - - "⫈": [t: "⠸⠨⠂⠈⠱"] # 0x2AC8 (Superset of above tilde operator) - - "⫉": [t: "⠸⠐⠅⠈⠱⠈⠱"] # 0x2AC9 (Subset of above almost equal to) - - "⫊": [t: "⠸⠨⠂⠈⠱⠈⠱"] # 0x2ACA (Superset of above almost equal to) - - "⫋": [t: "⠸⠐⠅⠌⠨⠅"] # 0x2ACB (Subset of above not equals sign) - - "⫌": [t: "⠸⠨⠂⠌⠨⠅"] # 0x2ACC (Superset of above not equals sign) - - "⫓": [t: "⠸⠐⠅⠸⠨⠂"] # 0x2AD3 (Subset above superset) - - "⫔": [t: "⠸⠨⠂⠸⠐⠅"] # 0x2AD4 (Superset above subset) - - "⫕": [t: "⠸⠐⠅⠸⠐⠅"] # 0x2AD5 (Subset above subset) - - "⫖": [t: "⠸⠨⠂⠸⠨⠂"] # 0x2AD6 (Superset above superset) - - "⫗": [t: "⠸⠨⠂⠐⠸⠐⠅"] # 0x2AD7 (Superset beside subset) - - "⫯": [t: "⠫⠩⠨⠡⠒⠒"] # 0x2AEF (Vertical line w circle above) - - "⫰": [t: "⠫⠣⠨⠡⠒⠒"] # 0x2AF0 (Vertical line w circle below) - - "⫱": [t: "⠫⠣⠨⠡⠒⠒⠳"] # 0x2AF1 (Down tack w circle below) - - "⫲": [t: "⠱⠈⠫⠇⠻"] # 0x2AF2 (Parallel w horizontal stroke) - - "⫳": [t: "⠈⠱⠈⠫⠇⠻"] # 0x2AF3 (Parallel w tilde operator) - - "⫴": [t: "⠳⠳⠳"] # 0x2AF4 (Triple vertical bar binary relation) - - "⬬": [t: "⠫⠸⠑"] # 0x2B2C (Black ellipse) - - "⬭": [t: "⠫⠑"] # 0x2B2D (White ellipse) - - "⬰": [t: "⠨⠡⠈⠫⠪⠒⠒⠻"] # 0x2B30 (Left arrow w small circle) - - "⬱": [t: "⠫⠪⠒⠒⠫⠪⠒⠒⠫⠪⠒⠒"] # 0x2B31 (Three leftwards arrows) - - "⬲": [t: "⠫⠪⠒⠒⠈⠫⠉⠸⠫⠬⠻"] # 0x2B32 (Left arrow w circled plus) - - "⮖": [t: "⠨⠡"] # 0x2B96 (Standard State Symbol) - - "⯃": [t: "⠫⠸⠦"] # 0x2BC3 (Horizontal black octagon) - - # SRE lists this as a custom transcription - - "⋊": [t: "⠈⠡⠳"] # 0x22ca (RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT) +--- +# To greatly simplify typeface/language generation, the chars have unique ASCII chars for them: +# Typeface: S: sans-serif, B: bold, T: script/blackboard, I: italic, R: Roman +# Language: E: English, D: German, G: Greek, V: Greek variants, H: Hebrew, U: Russian +# Indicators: C: capital, L: letter, N: number, P: punctuation, M: multipurpose +# Others: W -- whitespace that should be kept (e.g, in a numeral) +# SRE doesn't have H: Hebrew, so not encoded (yet) +# Some of the weird letters (e.g., circled letters) I didn't translate with the above because +# they don't interact with rules since they are enclosed in other chars. + + - "⨯": [t: "⠈⠡"] # U+2A2F(VECTOR OR CROSS PRODUCT) -- make the same as 0x00D7 (Multiplication sign) + + # --- Nemeth Default Alphabet bold chars. --- + - "𝐀-𝐙": # 0x1d400 - 0x1d419 + - tc: "BE" + - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - "𝐚-𝐳": # 0x1d41a - 0x1d433 + - tc: "BE" + - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 + - tc: "BG" + - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝛂-𝛒": # 0x1d6c2 - 0x1d6d2 + - tc: "BG" + - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒', 'αβγδεζηθικλμνξοπρ')" + + - "𝛔-𝛖": # 0x1d6d4 - 0x1d6d6 + - tc: "BG" + - spell: "translate('.', '𝛔𝛕𝛖', 'στυ')" + + - "𝛘-𝛚": # 0x1d6d8 - 0x1d6da + - tc: "BG" + - spell: "translate('.', '𝛘𝛙𝛚', 'χψω')" + + - "𝛁": [tc: "BGL⠫"] # 0x1d6c1 + - "𝛓": [tc: "BVL⠎"] # 0x1d6d3 + - "𝛗": [tc: "BVL⠋"] # 0x1d6d7 + - "𝛛": [tc: "⠸⠈⠙"] # 0x1d6db + - "𝛜": [tc: "BGL⠑"] # 0x1d6dc + - "𝛝": [tc: "BVL⠹"] # 0x1d6dd + - "𝛞": [tc: "BGL⠅"] # 0x1d6de + - "𝛟": [tc: "BGL⠋"] # 0x1d6df + - "𝛠": [tc: "BGL⠗"] # 0x1d6e0 + - "𝛡": [tc: "BGL⠏"] # 0x1d6e1 + + - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 + - tc: "B" + - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" + + # --- Nemeth Default Alphabet bold-fraktur chars. --- + + - "𝕬-𝖅": # 0x1d56c - 0x1d585 + - tc: "BD" + - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖆-𝖟": # 0x1d586 - 0x1d59f + - tc: "BD" + - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" + + # --- Nemeth Default Alphabet bold-italic chars. --- + - "𝑨-𝒁": # 0x1d468 - 0x1d481 + - tc: "BE" + - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝒂-𝒛": # 0x1d482 - 0x1d49b + - tc: "BE" + - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝜜-𝜴": # 0x1d71c - 0x1d734 + - tc: "BG" + - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝜵": [tc: "BGL⠫"] # 0x1d735 + + - "𝜶-𝝆": # 0x1d736 - 0x1d746 + - tc: "BG" + - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆', 'αβγδεζηθικλμνξοπρ')" + + - "𝝇": [tc: "BVL⠎"] # 0x1d747 + + - "𝝈-𝝊": # 0x1d748 - 0x1d74a + - tc: "BG" + - spell: "translate('.', '𝝈𝝉𝝊', 'στυ')" + + - "𝝋": [tc: "BVL⠋"] # 0x1d74b + + - "𝝌-𝝎": # 0x1d74c - 0x1d74e + - tc: "BG" + - spell: "translate('.', '𝝌𝝍𝝎', 'χψω')" + + - "𝝏": [tc: "BVL⠙"] # 0x1d74f + - "𝝐": [tc: "BGL⠑"] # 0x1d750 + - "𝝑": [tc: "BVL⠹"] # 0x1d751 + + - "𝝒-𝝕": # 0x1d752 - 0x1d755 + - tc: "BG" + - spell: "translate('.', '𝝒𝝓𝝔𝝕', 'κφρπ')" + + # --- Nemeth Default Alphabet bold-script chars. --- + + - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 + - tc: "BTE" + - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝓪-𝔃": # 0x1d4ea - 0x1d503 + - tc: "BTE" + - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝚤-𝚥": # 0x1d6a4 - 0x1d6a5 + - tc: "" + - spell: "translate('.', '𝚤𝚥', '⠊⠚')" + +# Russian Alphabet (from Nemeth book) +# NOTE: is this translation needed? + - "А-Я": # 0x410 - 0x42f + - tc: "U" + - spell: "translate('.', 'АБВГДЕЗИЙКЛМНОПРСТУФЭ', 'ABVGDEZIYKLMNOPRSTUFE')" + + - "а-я": # 0x430 - 0x44f + - tc: "U" + - spell: "translate('.', 'абвгдезийклмнопрстуфэ', 'abvgdeziylkmnoprstufye')" + + - "①-⑨": # 0x2460 - 0x2473 + - tc: "⠫⠉⠸⠫⠼" + - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" + - tc: "⠻" + + - "⓪": [tc: "⠫⠉⠸⠫⠼⠴⠻"] # 0x24ea + + - "⑩": [tc: "⠫⠉⠸⠫⠼⠂⠴⠻"] # 0x2469 + - "⑪": [tc: "⠫⠉⠸⠫⠼⠂⠂⠻"] # 0x246a + - "⑫": [tc: "⠫⠉⠸⠫⠼⠂⠆⠻"] # 0x246b + - "⑬": [tc: "⠫⠉⠸⠫⠼⠂⠒⠻"] # 0x246c + - "⑭": [tc: "⠫⠉⠸⠫⠼⠂⠲⠻"] # 0x246d + - "⑮": [tc: "⠫⠉⠸⠫⠼⠂⠢⠻"] # 0x246e + - "⑯": [tc: "⠫⠉⠸⠫⠼⠂⠖⠻"] # 0x246f + - "⑰": [tc: "⠫⠉⠸⠫⠼⠂⠶⠻"] # 0x2470 + - "⑱": [tc: "⠫⠉⠸⠫⠼⠂⠦⠻"] # 0x2471 + - "⑲": [tc: "⠫⠉⠸⠫⠼⠂⠔⠻"] # 0x2472 + - "⑳": [tc: "⠫⠉⠸⠫⠼⠆⠴⠻"] # 0x2473 + + - "㉑": [tc: "⠫⠉⠸⠫⠼⠆⠂⠻"] # 0x3251 + - "㉒": [tc: "⠫⠉⠸⠫⠼⠆⠆⠻"] # 0x3252 + - "㉓": [tc: "⠫⠉⠸⠫⠼⠆⠒⠻"] # 0x3253 + - "㉔": [tc: "⠫⠉⠸⠫⠼⠆⠲⠻"] # 0x3254 + - "㉕": [tc: "⠫⠉⠸⠫⠼⠆⠢⠻"] # 0x3255 + - "㉖": [tc: "⠫⠉⠸⠫⠼⠆⠖⠻"] # 0x3256 + - "㉗": [tc: "⠫⠉⠸⠫⠼⠆⠶⠻"] # 0x3257 + - "㉘": [tc: "⠫⠉⠸⠫⠼⠆⠦⠻"] # 0x3258 + - "㉙": [tc: "⠫⠉⠸⠫⠼⠆⠔⠻"] # 0x3259 + - "㉚": [tc: "⠫⠉⠸⠫⠼⠒⠴⠻"] # 0x325a + - "㉛": [tc: "⠫⠉⠸⠫⠼⠒⠂⠻"] # 0x325b + - "㉜": [tc: "⠫⠉⠸⠫⠼⠒⠆⠻"] # 0x325c + - "㉝": [tc: "⠫⠉⠸⠫⠼⠒⠒⠻"] # 0x325d + - "㉞": [tc: "⠫⠉⠸⠫⠼⠒⠲⠻"] # 0x325e + - "㉟": [tc: "⠫⠉⠸⠫⠼⠒⠢⠻"] # 0x325f + - "㊱": [tc: "⠫⠉⠸⠫⠼⠒⠖⠻"] # 0x32b1 + - "㊲": [tc: "⠫⠉⠸⠫⠼⠒⠶⠻"] # 0x32b2 + - "㊳": [tc: "⠫⠉⠸⠫⠼⠒⠦⠻"] # 0x32b3 + - "㊴": [tc: "⠫⠉⠸⠫⠼⠒⠔⠻"] # 0x32b4 + - "㊵": [tc: "⠫⠉⠸⠫⠼⠲⠴⠻"] # 0x32b5 + - "㊶": [tc: "⠫⠉⠸⠫⠼⠲⠂⠻"] # 0x32b6 + - "㊷": [tc: "⠫⠉⠸⠫⠼⠲⠆⠻"] # 0x32b7 + - "㊸": [tc: "⠫⠉⠸⠫⠼⠲⠒⠻"] # 0x32b8 + - "㊹": [tc: "⠫⠉⠸⠫⠼⠲⠲⠻"] # 0x32b9 + - "㊺": [tc: "⠫⠉⠸⠫⠼⠲⠢⠻"] # 0x32ba + - "㊻": [tc: "⠫⠉⠸⠫⠼⠲⠖⠻"] # 0x32bb + - "㊼": [tc: "⠫⠉⠸⠫⠼⠲⠶⠻"] # 0x32bc + - "㊽": [tc: "⠫⠉⠸⠫⠼⠲⠦⠻"] # 0x32bd + - "㊾": [tc: "⠫⠉⠸⠫⠼⠲⠔⠻"] # 0x32be + - "㊿": [tc: "⠫⠉⠸⠫⠼⠢⠴⠻"] # 0x32bf + +#NOTE: uncertainty here + - "Ⓐ-Ⓩ": # 0x24b6 - 0x24cf + - tc: "⠫⠉⠸⠫⠠" + - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "⠻" + + - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 + - tc: "⠫⠉⠸⠫" + - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" + - tc: "⠻" + + # --- Nemeth Default Alphabet circled-sans-serif chars. --- + + - "➀-➈": # 0x1f10b, 0x2780 - 0x2788 + - tc: "⠫⠉⠸⠫⠠⠨⠼" + - spell: "translate('.', '➀➁➂➃➄➅➆➇➈', '123456789')" + - tc: "⠻" + + - "🄋": [tc: "⠫⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10b + - "➉": [tc: "⠫⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2789 + + # --- Nemeth Default Alphabet comma chars. --- + + - "🄁-🄊": # 0x1f101 - 0x1f10a + - spell: "translate('.', '🄁🄂🄃🄄🄅🄆🄇🄈🄉🄊', '0123456789')" + - tc: "⠠" + + + # --- Nemeth Default Alphabet double-circled chars. --- + + - "⓵": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠻⠻"] # 0x24f5 + - "⓶": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠆⠻⠻"] # 0x24f6 + - "⓷": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠒⠻⠻"] # 0x24f7 + - "⓸": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠲⠻⠻"] # 0x24f8 + - "⓹": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠢⠻⠻"] # 0x24f9 + - "⓺": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠖⠻⠻"] # 0x24fa + - "⓻": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠶⠻⠻"] # 0x24fb + - "⓼": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠦⠻⠻"] # 0x24fc + - "⓽": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠔⠻⠻"] # 0x24fd + - "⓾": [t: "⠫⠉⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x24fe + + # --- Nemeth Default Alphabet double-struck chars. --- + - "𝔸-𝕐": # 0x1d538 - 0x1d550 (partial, excludes ℂ ℍ ℕ ℙ ℚ ℝ ℤ) + - tc: "𝔹E" + - spell: "translate('.', '𝔸𝔹𝔻𝔼𝔽𝔾𝕀𝕁𝕂𝕃𝕄𝕆𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABDEFGIJKLMOSTUVWXY')" + + - "ℂ": [tc: "𝔹ECL⠉"] # 0x2102 + - "ℍ": [tc: "𝔹ECL⠓"] # 0x210d + - "ℕ": [tc: "𝔹ECL⠝"] # 0x2115 + - "ℙ": [tc: "𝔹ECL⠏"] # 0x2119 + - "ℚ": [tc: "𝔹ECL⠟"] # 0x211a + - "ℝ": [tc: "𝔹ECL⠗"] # 0x211d + - "ℤ": [tc: "𝔹ECL⠵"] # 0x2124 + - "Ω": [t: "CGL⠺"] # 0x2126 (Ohm sign (capital Greek omega)) + + - "𝕒-𝕫": # 0x1d552 - 0x1d56b + - tc: "𝔹E" + - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 + - tc: "𝔹" + - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" + + + # --- Nemeth Default Alphabet fraktur chars. --- + + - "𝔄-𝔜": # 0x1d504 - 0x1d51c + - tc: "D" + - spell: "translate('.', '𝔄𝔅𝔇𝔈𝔉𝔊𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABDEFGJKLMNOPQSTUVWXY')" + + - "ℭ": [tc: "DCL⠉"] # 0x212d + - "ℌ": [tc: "DCL⠓"] # 0x210c + - "ℑ": [tc: "DCL⠊"] # 0x2111 + - "ℜ": [tc: "DCL⠗"] # 0x211c + - "ℨ": [tc: "DCL⠵"] # 0x2128 + + - "𝔞-𝔷": # 0x1d51e - 0x1d537 + - tc: "D" + - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" + + # --- Nemeth Default Alphabet fullwidth chars. --- + + - "A-Z": # 0xff21 - 0xff3a + - tc: "" + - spell: "translate('.', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "a-z": # 0xff41 - 0xff5a + - tc: "" + - spell: "translate('.', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz')" + + - "0-9": # 0xff10 - 0xff19 + - tc: "" + - spell: "translate('.', '0123456789', '0123456789')" + + # --- Nemeth Default Alphabet italic chars -- treat as non-italic. --- + + - "𝐴-𝑍": # 0x1d434 - 0x1d44d + - tc: "E" + - spell: "translate('.', '𝐴𝐵𝐶𝐷𝐸𝐹𝐺𝐻𝐼𝐽𝐾𝐿𝑀𝑁𝑂𝑃𝑄𝑅𝑆𝑇𝑈𝑉𝑊𝑋𝑌𝑍', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝑎-𝑧": # 0x1d44e - 0x1d467 + - tc: "E" + - spell: "translate('.', '𝑎𝑏𝑐𝑑𝑒𝑓𝑔ℎ𝑖𝑗𝑘𝑙𝑚𝑛𝑜𝑝𝑞𝑟𝑠𝑡𝑢𝑣𝑤𝑥𝑦𝑧', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa + - tc: "G" + - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝛻": [tc: "GL⠫"] # 0x1d6fb + + - "𝛼-𝜌": # 0x1d6fc - 0x1d70c + - tc: "G" + - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌', 'αβγδεζηθικλμνξοπρ')" + - "𝜍": [tc: "VL⠎"] # 0x1d70d + + - "𝜎": [tc: "GL⠎"] # 0x1d70e + - "𝜏": [tc: "GL⠞"] # 0x1d70f + - "𝜐": [tc: "GL⠥"] # 0x1d710 + + - "𝜑": [tc: "VL⠋"] # 0x1d711 + + - "𝜒": [tc: "GL⠯"] # 0x1d712 + - "𝜓": [tc: "GL⠽"] # 0x1d713 + - "𝜔": [tc: "GL⠺"] # 0x1d714 + + - "𝜕": [tc: "VL⠙"] # 0x1d715 + + - "𝜖": [tc: "GL⠑"] # 0x1d716 + + - "𝜗": [tc: "VL⠹"] # 0x1d717 + + - "𝜘": [tc: "GL⠅"] # 0x1d718 + - "𝜙": [tc: "GL⠋"] # 0x1d719 + - "𝜚": [tc: "GL⠗"] # 0x1d71a + - "𝜛": [tc: "GL⠏"] # 0x1d71b + + # --- Nemeth Default Alphabet monospace chars. --- + + - "𝙰-𝚉": # 0x1d670 - 0x1d689 + - tc: "" + - spell: "translate('.', '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝚊-𝚣": # 0x1d68a - 0x1d6a3 + - tc: "" + - spell: "translate('.', '𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟶-𝟿": # 0x1d7f6 - 0x1d7ff + - tc: "" + - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" + + + # --- Nemeth Default Alphabet negative-circled chars. --- + - "⓿": [t: "⠫⠸⠉⠸⠫⠼⠴⠻"] # 0x24ff + - "❶": [t: "⠫⠸⠉⠸⠫⠼⠂⠻"] # 0x2776 + - "❷": [t: "⠫⠸⠉⠸⠫⠼⠆⠻"] # 0x2777 + - "❸": [t: "⠫⠸⠉⠸⠫⠼⠒⠻"] # 0x2778 + - "❹": [t: "⠫⠸⠉⠸⠫⠼⠲⠻"] # 0x2779 + - "❺": [t: "⠫⠸⠉⠸⠫⠼⠢⠻"] # 0x277a + - "❻": [t: "⠫⠸⠉⠸⠫⠼⠖⠻"] # 0x277b + - "❼": [t: "⠫⠸⠉⠸⠫⠼⠶⠻"] # 0x277c + - "❽": [t: "⠫⠸⠉⠸⠫⠼⠦⠻"] # 0x277d + - "❾": [t: "⠫⠸⠉⠸⠫⠼⠔⠻"] # 0x277e + - "❿": [t: "⠫⠸⠉⠸⠫⠼⠂⠴⠻"] # 0x277f + - "⓫": [t: "⠫⠸⠉⠸⠫⠼⠂⠂⠻"] # 0x24eb + - "⓬": [t: "⠫⠸⠉⠸⠫⠼⠂⠆⠻"] # 0x24ec + - "⓭": [t: "⠫⠸⠉⠸⠫⠼⠂⠒⠻"] # 0x24ed + - "⓮": [t: "⠫⠸⠉⠸⠫⠼⠂⠲⠻"] # 0x24ee + - "⓯": [t: "⠫⠸⠉⠸⠫⠼⠂⠢⠻"] # 0x24ef + - "⓰": [t: "⠫⠸⠉⠸⠫⠼⠂⠖⠻"] # 0x24f0 + - "⓱": [t: "⠫⠸⠉⠸⠫⠼⠂⠶⠻"] # 0x24f1 + - "⓲": [t: "⠫⠸⠉⠸⠫⠼⠂⠦⠻"] # 0x24f2 + - "⓳": [t: "⠫⠸⠉⠸⠫⠼⠂⠔⠻"] # 0x24f3 + - "⓴": [t: "⠫⠸⠉⠸⠫⠼⠆⠴⠻"] # 0x24f4 + + - "🅐": [t: "⠫⠸⠉⠸⠫⠠⠁⠻"] # 0x1f150 + - "🅑": [t: "⠫⠸⠉⠸⠫⠠⠃⠻"] # 0x1f151 + - "🅒": [t: "⠫⠸⠉⠸⠫⠠⠉⠻"] # 0x1f152 + - "🅓": [t: "⠫⠸⠉⠸⠫⠠⠙⠻"] # 0x1f153 + - "🅔": [t: "⠫⠸⠉⠸⠫⠠⠑⠻"] # 0x1f154 + - "🅕": [t: "⠫⠸⠉⠸⠫⠠⠋⠻"] # 0x1f155 + - "🅖": [t: "⠫⠸⠉⠸⠫⠠⠛⠻"] # 0x1f156 + - "🅗": [t: "⠫⠸⠉⠸⠫⠠⠓⠻"] # 0x1f157 + - "🅘": [t: "⠫⠸⠉⠸⠫⠠⠊⠻"] # 0x1f158 + - "🅙": [t: "⠫⠸⠉⠸⠫⠠⠚⠻"] # 0x1f159 + - "🅚": [t: "⠫⠸⠉⠸⠫⠠⠅⠻"] # 0x1f15a + - "🅛": [t: "⠫⠸⠉⠸⠫⠠⠇⠻"] # 0x1f15b + - "🅜": [t: "⠫⠸⠉⠸⠫⠠⠍⠻"] # 0x1f15c + - "🅝": [t: "⠫⠸⠉⠸⠫⠠⠝⠻"] # 0x1f15d + - "🅞": [t: "⠫⠸⠉⠸⠫⠠⠕⠻"] # 0x1f15e + - "🅟": [t: "⠫⠸⠉⠸⠫⠠⠏⠻"] # 0x1f15f + - "🅠": [t: "⠫⠸⠉⠸⠫⠠⠟⠻"] # 0x1f160 + - "🅡": [t: "⠫⠸⠉⠸⠫⠠⠗⠻"] # 0x1f161 + - "🅢": [t: "⠫⠸⠉⠸⠫⠠⠎⠻"] # 0x1f162 + - "🅣": [t: "⠫⠸⠉⠸⠫⠠⠞⠻"] # 0x1f163 + - "🅤": [t: "⠫⠸⠉⠸⠫⠠⠥⠻"] # 0x1f164 + - "🅥": [t: "⠫⠸⠉⠸⠫⠠⠧⠻"] # 0x1f165 + - "🅦": [t: "⠫⠸⠉⠸⠫⠠⠺⠻"] # 0x1f166 + - "🅧": [t: "⠫⠸⠉⠸⠫⠠⠭⠻"] # 0x1f167 + - "🅨": [t: "⠫⠸⠉⠸⠫⠠⠽⠻"] # 0x1f168 + - "🅩": [t: "⠫⠸⠉⠸⠫⠠⠵⠻"] # 0x1f169 + + # --- Nemeth Default Alphabet negative-circled-sans-serif chars. --- + - "🄌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠴⠻"] # 0x1f10c + - "➊": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠻"] # 0x278a + - "➋": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠆⠻"] # 0x278b + - "➌": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠒⠻"] # 0x278c + - "➍": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠲⠻"] # 0x278d + - "➎": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠢⠻"] # 0x278e + - "➏": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠖⠻"] # 0x278f + - "➐": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠶⠻"] # 0x2790 + - "➑": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠦⠻"] # 0x2791 + - "➒": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠔⠻"] # 0x2792 + - "➓": [t: "⠫⠸⠉⠸⠫⠠⠨⠼⠂⠴⠻"] # 0x2793 + + # --- Nemeth Default Alphabet negative-squared chars. --- + - "🅰-🆉": # 0x1f170 - 0x1f189 + - tc: "⠫⠸⠲⠸⠫⠠" + - spell: "translate('.', '🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "⠻" + + # --- Nemeth Default Alphabet parenthesized chars. --- + + - "⑴-⑼": # 0x2474 - 0x247c + - tc: "⠷" + - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" + - tc: "⠾" + + - "⑽": [t: "⠷⠂⠴⠾"] # 0x247d + - "⑾": [t: "⠷⠂⠂⠾"] # 0x247e + - "⑿": [t: "⠷⠂⠆⠾"] # 0x247f + - "⒀": [t: "⠷⠂⠒⠾"] # 0x2480 + - "⒁": [t: "⠷⠂⠲⠾"] # 0x2481 + - "⒂": [t: "⠷⠂⠢⠾"] # 0x2482 + - "⒃": [t: "⠷⠂⠖⠾"] # 0x2483 + - "⒄": [t: "⠷⠂⠶⠾"] # 0x2484 + - "⒅": [t: "⠷⠂⠦⠾"] # 0x2485 + - "⒆": [t: "⠷⠂⠔⠾"] # 0x2486 + - "⒇": [t: "⠷⠆⠴⠾"] # 0x2487 + + - "🄐-🄩": # 0x1f110 - 0x1f129 + - tc: "⠷⠠" + - spell: "translate('.', '🄐🄑🄒🄓🄔🄕🄖🄗🄘🄙🄚🄛🄜🄝🄞🄟🄠🄡🄢🄣🄤🄥🄦🄧🄨🄩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + - tc: "⠾" + + - "⒜-⒵": # 0x249c - 0x24b5 + - tc: "⠷" + - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" + - tc: "⠾" + + # --- Nemeth Default Alphabet period chars. --- + - "🄀": [t: "⠴⠸⠲"] # 0x1f100 + - "⒈": [t: "⠂⠸⠲"] # 0x2488 + - "⒉": [t: "⠆⠸⠲"] # 0x2489 + - "⒊": [t: "⠒⠸⠲"] # 0x248a + - "⒋": [t: "⠲⠸⠲"] # 0x248b + - "⒌": [t: "⠢⠸⠲"] # 0x248c + - "⒍": [t: "⠖⠸⠲"] # 0x248d + - "⒎": [t: "⠶⠸⠲"] # 0x248e + - "⒏": [t: "⠦⠸⠲"] # 0x248f + - "⒐": [t: "⠔⠸⠲"] # 0x2490 + + - "⒑": [t: "⠂⠴⠸⠲"] # 0x2491 + - "⒒": [t: "⠂⠂⠸⠲"] # 0x2492 + - "⒓": [t: "⠂⠆⠸⠲"] # 0x2493 + - "⒔": [t: "⠂⠒⠸⠲"] # 0x2494 + - "⒕": [t: "⠂⠲⠸⠲"] # 0x2495 + - "⒖": [t: "⠂⠢⠸⠲"] # 0x2496 + - "⒗": [t: "⠂⠖⠸⠲"] # 0x2497 + - "⒘": [t: "⠂⠶⠸⠲"] # 0x2498 + - "⒙": [t: "⠂⠦⠸⠲"] # 0x2499 + - "⒚": [t: "⠂⠔⠸⠲"] # 0x249a + - "⒛": [t: "⠆⠴⠸⠲"] # 0x249b + + # --- Nemeth Default Alphabet sans-serif chars. --- + - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 + - tc: "SE" + - spell: "translate('.', '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝖺-𝗓": # 0x1d5ba - 0x1d5d3 + - tc: "SE" + - spell: "translate('.', '𝖺𝖻𝖼𝖽𝖾𝖿𝗀𝗁𝗂𝗃𝗄𝗅𝗆𝗇𝗈𝗉𝗊𝗋𝗌𝗍𝗎𝗏𝗐𝗑𝗒𝗓', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝟢-𝟫": # 0x1d7e2 - 0x1d7eb + - tc: "S" + - spell: "translate('.', '𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫', '0123456789')" + + # --- Nemeth Default Alphabet sans-serif-bold chars. --- + - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed + - tc: "SBE" + - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝗮-𝘇": # 0x1d5ee - 0x1d607 + - tc: "SBE" + - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝝖-𝝮": # 0x1d756 - 0x1d76e + - tc: "SBG" + - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝝰-𝞀": # 0x1d770 - 0x1d780 + - tc: "SBG" + - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀', 'αβγδεζηθικλμνξοπρ')" + + - "𝝯": [tc: "SBGL⠫"] # 0x1d76f + + - "𝞁": [tc: "SBVL⠎"] # 0x1d781 + + - "𝞂-𝞄": # 0x1d782 - 0x1d784 + - tc: "SBG" + - spell: "translate('.', '𝞂𝞃𝞄', 'στυ')" + + - "𝞅": [tc: "SBVL⠋"] # 0x1d785 + + - "𝞆-𝞈": # 0x1d786 - 0x1d788 + - tc: "SBG" + - spell: "translate('.', '𝞆𝞇𝞈', 'χψω')" + + - "𝞉": [tc: "⠠⠨⠸⠈⠙"] # 0x1d789 + - "𝞊": [tc: "SBGL⠑"] # 0x1d78a + - "𝞋": [tc: "SBVL⠹"] # 0x1d78b + + - "𝞌-𝞏": # 0x1d78c - 0x1d78f + - tc: "SBG" + - spell: "translate('.', '𝞌𝞍𝞎𝞏', 'κφρπ')" + + - "𝟬-𝟵": # 0x1d7ec - 0x1d7f5 + - tc: "SB" + - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" + + # --- Nemeth Default Alphabet sans-serif-bold-italic chars. --- + + - "𝘼-𝙕": # 0x1d63c - 0x1d655 + - tc: "SBE" + - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝙖-𝙯": # 0x1d656 - 0x1d66f + - tc: "SBE" + - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" + + - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 + - tc: "SBG" + - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ')" + + - "𝞩": [t: "SBGL⠫"] # 0x1d7a9 + + - "𝞪-𝞺": # 0x1d7aa - 0x1d7ba + - tc: "SBG" + - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺', 'αβγδεζηθικλμνξοπρ')" + + - "𝞻": [t: "SBVL⠎"] # 0x1d7bb + - "𝞼": [t: "SBGL⠎"] # 0x1d7bc + - "𝞽": [t: "SBGL⠞"] # 0x1d7bd + - "𝞾": [t: "SBGL⠥"] # 0x1d7be + - "𝞿": [t: "SBVL⠋"] # 0x1d7bf + + - "𝟀": [t: "SBGL⠯"] # 0x1d7c0 + - "𝟁": [t: "SBGL⠽"] # 0x1d7c1 + - "𝟂": [t: "SBGL⠺"] # 0x1d7c2 + - "𝟃": [t: "SBVL⠙"] # 0x1d7c3 + + - "𝟄": [t: "SBGL⠑"] # 0x1d7c4 + - "𝟅": [t: "SBVL⠹"] # 0x1d7c5 + + - "𝟆": [t: "SBGL⠅"] # 0x1d7c6 + - "𝟇": [t: "SBGL⠋"] # 0x1d7c7 + - "𝟈": [t: "SBGL⠗"] # 0x1d7c8 + - "𝟉": [t: "SBGL⠏"] # 0x1d7c9 + + # --- Nemeth Default Alphabet sans-serif-italic chars. --- + - "𝘈-𝘡": # 0x1d608 - 0x1d621 + - tc: "SE" + - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" + + - "𝘢-𝘻": # 0x1d622 - 0x1d63b + - tc: "SE" + - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" + + # --- Nemeth Default Alphabet script chars. --- + - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 + - tc: "TE" + - spell: "translate('.', '𝒜𝒞𝒟𝒢𝒥𝒦𝒩𝒪𝒫𝒬𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ACDGJKNOPQSTUVWXYZ')" + + - "ℬ": [t: "TECL⠃"] # 0x212c + - "ℰ": [t: "TECL⠑"] # 0x2130 + - "ℱ": [t: "TECL⠋"] # 0x2131 + - "ℋ": [t: "TECL⠓"] # 0x210b + - "ℐ": [t: "TECL⠊"] # 0x2110 + - "ℒ": [t: "TECL⠇"] # 0x2112 + - "ℳ": [t: "TECL⠍"] # 0x2133 + - "ℛ": [t: "TECL⠗"] # 0x211b + + - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf + - tc: "TE" + - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒻𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdfhijklmnpqrstuvwxyz')" + + - "ℯ": [t: "TEL⠑"] # 0x212f + - "ℊ": [t: "TEL⠛"] # 0x210a + - "ℴ": [t: "TEL⠕"] # 0x2134 + + # --- Nemeth Default Alphabet squared chars. --- + + - "🄰": [t: "⠫⠲⠸⠫⠠⠁⠻"] # 0x1f130 + - "🄱": [t: "⠫⠲⠸⠫⠠⠃⠻"] # 0x1f131 + - "🄲": [t: "⠫⠲⠸⠫⠠⠉⠻"] # 0x1f132 + - "🄳": [t: "⠫⠲⠸⠫⠠⠙⠻"] # 0x1f133 + - "🄴": [t: "⠫⠲⠸⠫⠠⠑⠻"] # 0x1f134 + - "🄵": [t: "⠫⠲⠸⠫⠠⠋⠻"] # 0x1f135 + - "🄶": [t: "⠫⠲⠸⠫⠠⠛⠻"] # 0x1f136 + - "🄷": [t: "⠫⠲⠸⠫⠠⠓⠻"] # 0x1f137 + - "🄸": [t: "⠫⠲⠸⠫⠠⠊⠻"] # 0x1f138 + - "🄹": [t: "⠫⠲⠸⠫⠠⠚⠻"] # 0x1f139 + - "🄺": [t: "⠫⠲⠸⠫⠠⠅⠻"] # 0x1f13a + - "🄻": [t: "⠫⠲⠸⠫⠠⠇⠻"] # 0x1f13b + - "🄼": [t: "⠫⠲⠸⠫⠠⠍⠻"] # 0x1f13c + - "🄽": [t: "⠫⠲⠸⠫⠠⠝⠻"] # 0x1f13d + - "🄾": [t: "⠫⠲⠸⠫⠠⠕⠻"] # 0x1f13e + - "🄿": [t: "⠫⠲⠸⠫⠠⠏⠻"] # 0x1f13f + - "🅀": [t: "⠫⠲⠸⠫⠠⠟⠻"] # 0x1f140 + - "🅁": [t: "⠫⠲⠸⠫⠠⠗⠻"] # 0x1f141 + - "🅂": [t: "⠫⠲⠸⠫⠠⠎⠻"] # 0x1f142 + - "🅃": [t: "⠫⠲⠸⠫⠠⠞⠻"] # 0x1f143 + - "🅄": [t: "⠫⠲⠸⠫⠠⠥⠻"] # 0x1f144 + - "🅅": [t: "⠫⠲⠸⠫⠠⠧⠻"] # 0x1f145 + - "🅆": [t: "⠫⠲⠸⠫⠠⠺⠻"] # 0x1f146 + - "🅇": [t: "⠫⠲⠸⠫⠠⠭⠻"] # 0x1f147 + - "🅈": [t: "⠫⠲⠸⠫⠠⠽⠻"] # 0x1f148 + - "🅉": [t: "⠫⠲⠸⠫⠠⠵⠻"] # 0x1f149 + + # --- Nemeth Default Alphabet sub chars. --- + + - "₀": [t: "⠰⠴"] # 0x2080 + - "₁": [t: "⠰⠂"] # 0x2081 + - "₂": [t: "⠰⠆"] # 0x2082 + - "₃": [t: "⠰⠒"] # 0x2083 + - "₄": [t: "⠰⠲"] # 0x2084 + - "₅": [t: "⠰⠢"] # 0x2085 + - "₆": [t: "⠰⠖"] # 0x2086 + - "₇": [t: "⠰⠶"] # 0x2087 + - "₈": [t: "⠰⠦"] # 0x2088 + - "₉": [t: "⠰⠔"] # 0x2089 + + # --- Nemeth Default Alphabet super chars. --- + + - "⁰": [t: "⠘⠴"] # 0x2070 + - "¹": [t: "⠘⠂"] # 0xb9 + - "²": [t: "⠘⠆"] # 0xb2 + - "³": [t: "⠘⠒"] # 0xb3 + - "⁴": [t: "⠘⠲"] # 0x2074 + - "⁵": [t: "⠘⠢"] # 0x2075 + - "⁶": [t: "⠘⠖"] # 0x2076 + - "⁷": [t: "⠘⠶"] # 0x2077 + - "⁸": [t: "⠘⠦"] # 0x2078 + - "⁹": [t: "⠘⠔"] # 0x2079 + + # --- Nemeth Default Characters latin-lower-phonetic chars. --- + + - "ø": [t: "⠈⠕"] # 0xf8 + + # --- Nemeth Default Characters math_geometry chars. --- + + - "─": [t: "⠱"] # 0x2500 + - "│": [t: "⠳"] # 0x2502 + - "▰": [t: "⠫⠸⠛"] # 0x25b0 + - "▱": [t: "⠫⠛"] # 0x25b1 + - "▽": [t: "⠨⠫"] # 0x25bd + - "◆": [t: "⠫⠸⠙"] # 0x25c6 + - "◇": [t: "⠫⠙"] # 0x25c7 + - "◈": [t: "⠫⠸⠙"] # 0x25c8 + - "◉": [t: "⠫⠸⠉"] # 0x25c9 + - "◊": [t: "⠫⠙"] # 0x25ca + - "⬟": [t: "⠫⠸⠢"] # 0x2b1f + - "⬠": [t: "⠫⠢"] # 0x2b20 + - "⬡": [t: "⠫⠖"] # 0x2b21 + - "⬢": [t: "⠫⠸⠖"] # 0x2b22 + - "⬣": [t: "⠫⠸⠖"] # 0x2b23 + - "⬤": [t: "⠫⠸⠉"] # 0x2b24 + - "⬥": [t: "⠫⠸⠙"] # 0x2b25 + + # --- Nemeth Default Characters math_symbols chars. --- + + - "\"": [t: "⠄⠄"] # 0x22 + - "¡": [t: "⠖"] # 0xa1 + - "¢": [t: "⠈⠉"] # 0xa2 + - "£": [t: "⠈⠇"] # 0xa3 + - "¤": [t: "⠈⠫"] # 0xa4 + - "¥": [t: "⠈⠽"] # 0xa5 + - "§": [t: "⠈⠠⠎"] # 0xa7 + - "©": [t: "⠘⠉"] # 0xa9 (Copyright) + - "ª": [t: "⠸⠰⠁"] # 0xaa + - "«": [t: "⠐⠅⠈⠐⠅⠻"] # 0xab + - "®": [t: "⠘⠗"] # 0xae + - "´": [t: "⠈"] # 0xb4 + - "µ": [t: "⠨⠍"] # 0xb5 + - "¶": [t: "⠈⠠⠏"] # 0xb6 + - "¿": [t: "⠦"] # 0xbf + - "ʹ": [t: "⠄"] # 0x2b9 + - "ʺ": [t: "⠄⠄"] # 0x2ba + - "˙": [t: "⠡"] # 0x2d9 + - "˜": [t: "⠈⠱"] # 0x2dc + - "‐": [t: "⠤"] # 0x2010 + - "‑": [t: "⠤"] # 0x2011 + - "‒": [t: "⠤⠤"] # 0x2012 + - "–": [t: "⠤⠤"] # 0x2013 + - "‖": [t: "⠳⠳"] # 0x2016 + - "†": [t: "⠸⠻"] # 0x2020 + - "‡": [t: "⠸⠸⠻"] # 0x2021 + - "•": [t: "⠡"] # 0x2022 + - "․": [t: "⠄"] # 0x2024 + - "‥": [t: "⠄⠄"] # 0x2025 + - "′": [t: "⠄"] # 0x2032 + - "″": [t: "⠄⠄"] # 0x2033 + - "‴": [t: "⠄⠄."] # 0x2034 (Triple prime) + - "⁗": [t: "⠄⠄.."] # 0x2057 (Quadruple prime) + - "‼": [t: "⠖⠖"] # 0x203c + - "‾": [t: "⠱"] # 0x203e + - "⁇": [t: "⠹⠹"] # 0x2047 + - "⁈": [t: "⠹⠖"] # 0x2048 + - "⁉": [t: "⠖⠹"] # 0x2049 + - "∀": [t: "⠈⠯"] # 0x2200 + - "∃": [t: "⠈⠿"] # 0x2203 + - "∄": [t: "⠌⠈⠿"] # 0x2204 + - "∅": [t: "⠸⠴"] # 0x2205 + - "∈": [t: "⠈⠑"] # 0x2208 + - "∉": [t: "⠌⠈⠑"] # 0x2209 + - "∊": [t: "⠈⠑"] # 0x220a + - "∋": [t: "⠈⠢"] # 0x220b + - "∌": [t: "⠌⠈⠢"] # 0x220c + - "∍": [t: "⠈⠢"] # 0x220d + - "∎": [t: "⠸⠳"] # 0x220e + - "−": [t: "⠤"] # 0x2212 + - "∓": [t: "⠤⠬"] # 0x2213 + - "∕": [t: "⠸⠌"] # 0x2215 + - "∖": [t: "⠸⠡"] # 0x2216 + - "∗": [t: "⠈⠼"] # 0x2217 + - "∘": [t: "⠨⠡"] # 0x2218 + - "∝": [t: "⠸⠿"] # 0x221d + - "∞": [t: "⠠⠿"] # 0x221e + - "∟": [t: "⠫⠪⠨⠗⠻"] # 0x221f + - "∠": [t: "⠫⠪"] # 0x2220 + - "∢": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2222 + - "∣": [t: "⠳"] # 0x2223 + - "∤": [t: "⠌⠳"] # 0x2224 + - "∥": [t: "⠫⠇"] # 0x2225 + - "∦": [t: "⠌⠫⠇"] # 0x2226 + - "∧": [t: "⠈⠩"] # 0x2227 + - "∨": [t: "⠈⠬"] # 0x2228 + - "∩": [t: "⠨⠩"] # 0x2229 + - "∪": [t: "⠨⠬"] # 0x222a + - "∫": [t: "⠮"] # 0x222b + - "∬": [t: "⠮⠮"] # 0x222c + - "∭": [t: "⠮⠮⠮"] # 0x222d + - "∮": [t: "⠮⠈⠫⠉⠻"] # 0x222e + - "∲": [t: "⠮⠈⠫⠪⠢⠔⠻"] # 0x2232 + - "∳": [t: "⠮⠈⠫⠢⠔⠕⠻"] # 0x2233 + - "∴": [t: "⠠⠡"] # 0x2234 + - "∵": [t: "⠈⠌"] # 0x2235 + - "∶": [t: "⠐⠂"] # 0x2236 + - "∷": [t: "⠰⠆"] # 0x2237 + - "∸": [t: "⠨⠤"] # 0x2238 + - "∼": [t: "⠈⠱"] # 0x223c + - "≁": [t: "⠌⠈⠱"] # 0x2241 + - "≂": [t: "⠱⠈⠱"] # 0x2242 + - "≃": [t: "⠈⠱⠱"] # 0x2243 + - "≄": [t: "⠌⠈⠱⠱"] # 0x2244 + - "≅": [t: "⠈⠱⠨⠅"] # 0x2245 + - "≆": [t: "⠈⠱⠌⠨⠅"] # 0x2246 + - "≇": [t: "⠌⠈⠱⠨⠅"] # 0x2247 + - "≈": [t: "⠈⠱⠈⠱"] # 0x2248 + - "≉": [t: "⠌⠈⠱⠈⠱"] # 0x2249 + - "≊": [t: "⠈⠱⠈⠱⠱"] # 0x224a + - "≍": [t: "⠈⠣⠠⠣"] # 0x224d + - "≎": [t: "⠈⠣⠠⠣"] # 0x224e + - "≐": [t: "⠐⠨⠅⠣⠡⠻"] # 0x2250 + - "≑": [t: "⠐⠨⠅⠩⠡⠣⠡⠻"] # 0x2251 + - "≗": [t: "⠐⠨⠅⠣⠨⠡⠻"] # 0x2257 + - "≘": [t: "⠐⠨⠅⠣⠫⠁⠻"] # 0x2258 + - "≙": [t: "⠐⠨⠅⠣⠸⠣⠻"] # 0x2259 + - "≚": [t: "⠐⠨⠅⠣⠸⠩⠻"] # 0x225a + - "≛": [t: "⠐⠨⠅⠣⠫⠸⠎⠻"] # 0x225b + - "≜": [t: "⠐⠨⠅⠣⠫⠞⠻"] # 0x225c + - "≝": [t: "⠐⠨⠅⠣⠙⠑⠋⠻"] # 0x225d + - "≞": [t: "⠐⠨⠅⠣⠍⠻"] # 0x225e + - "≟": [t: "⠐⠨⠅⠣⠸⠦⠻"] # 0x225f + - "≠": [t: "⠌⠨⠅"] # 0x2260 + - "≢": [t: "⠌⠸⠇"] # 0x2262 + - "≤": [t: "⠐⠅⠱"] # 0x2264 + - "≥": [t: "⠨⠂⠱"] # 0x2265 + - "≦": [t: "⠐⠅⠨⠅"] # 0x2266 + - "≧": [t: "⠨⠂⠨⠅"] # 0x2267 + - "≨": [t: "⠐⠅⠌⠨⠅"] # 0x2268 + - "≩": [t: "⠨⠂⠌⠨⠅"] # 0x2269 + - "≪": [t: "⠐⠅⠈⠐⠅⠻"] # 0x226a + - "≫": [t: "⠨⠂⠈⠨⠂⠻"] # 0x226b + - "≭": [t: "⠌⠈⠣⠠⠣"] # 0x226d + - "≮": [t: "⠌⠐⠅"] # 0x226e + - "≯": [t: "⠌⠨⠂"] # 0x226f + - "≰": [t: "⠌⠐⠅⠱"] # 0x2270 + - "≱": [t: "⠌⠨⠂⠱"] # 0x2271 + - "≲": [t: "⠐⠅⠈⠱"] # 0x2272 + - "≳": [t: "⠨⠂⠈⠱"] # 0x2273 + - "≴": [t: "⠌⠐⠅⠈⠱"] # 0x2274 + - "≵": [t: "⠌⠨⠂⠈⠱"] # 0x2275 + - "≶": [t: "⠐⠅⠨⠂"] # 0x2276 + - "≷": [t: "⠨⠂⠐⠅"] # 0x2277 + - "≸": [t: "⠌⠐⠅⠨⠂"] # 0x2278 + - "≹": [t: "⠌⠨⠂⠐⠅"] # 0x2279 + - "≺": [t: "⠨⠐⠅"] # 0x227a + - "≻": [t: "⠨⠨⠂"] # 0x227b + - "≼": [t: "⠨⠐⠅⠱"] # 0x227c + - "≽": [t: "⠨⠨⠐⠱"] # 0x227d + - "≾": [t: "⠨⠐⠅⠈⠱"] # 0x227e + - "≿": [t: "⠨⠨⠂⠈⠱"] # 0x227f + - "⊀": [t: "⠌⠨⠐⠅"] # 0x2280 + - "⊁": [t: "⠌⠨⠐⠅"] # 0x2281 + - "⊂": [t: "⠸⠐⠅"] # 0x2282 + - "⊃": [t: "⠸⠨⠂"] # 0x2283 + - "⊄": [t: "⠌⠸⠐⠅"] # 0x2284 + - "⊅": [t: "⠌⠸⠨⠂"] # 0x2285 + - "⊆": [t: "⠸⠐⠅⠱"] # 0x2286 + - "⊇": [t: "⠸⠨⠂⠱"] # 0x2287 + - "⊈": [t: "⠌⠸⠐⠅⠱"] # 0x2288 + - "⊉": [t: "⠌⠸⠨⠂⠱"] # 0x2289 + - "⊊": [t: "⠸⠐⠅⠌⠨⠅"] # 0x228a + - "⊋": [t: "⠸⠨⠂⠌⠨⠅"] # 0x228b + - "⊥": [t: "⠫⠏"] # 0x22a5 + - "⋀": [t: "⠈⠩"] # 0x22c0 + - "⋁": [t: "⠈⠬"] # 0x22c1 + - "⋂": [t: "⠨⠩"] # 0x22c2 + - "⋃": [t: "⠨⠬"] # 0x22c3 + - "⋄": [t: "⠫⠙"] # 0x22c4 + - "⋜": [t: "⠱⠐⠅"] # 0x22dc + - "⋝": [t: "⠱⠨⠂"] # 0x22dd + - "⟂": [t: "⠫⠏"] # 0x27c2 + - "⦀": [t: "⠳⠳⠳"] # 0x2980 + - "⦶": [t: "⠫⠉⠸⠫⠳⠻"] # 0x29b6 + - "⦷": [t: "⠫⠉⠸⠫⠫⠇⠻"] # 0x29b7 + - "⦸": [t: "⠫⠉⠸⠫⠸⠡⠻"] # 0x29b8 + - "⦹": [t: "⠫⠉⠸⠫⠫⠏⠻"] # 0x29b9 + - "⦿": [t: "⠫⠉⠸⠫⠔⠔⠻"] # 0x29bf + - "⧀": [t: "⠫⠉⠸⠫⠐⠅⠻"] # 0x29c0 + - "⧁": [t: "⠫⠉⠸⠫⠨⠂⠻"] # 0x29c1 + - "⨀": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2a00 + - "⨁": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2a01 + - "⨂": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2a02 + - "⪯": [t: "⠨⠐⠅⠱"] # 0x2aaf + - "⪰": [t: "⠨⠨⠂⠱"] # 0x2ab0 + - "⪱": [t: "⠨⠐⠅⠌⠱"] # 0x2ab1 + - "⪲": [t: "⠨⠨⠂⠌⠱"] # 0x2ab2 + - "⪳": [t: "⠨⠐⠅⠨⠅"] # 0x2ab3 + - "⪴": [t: "⠨⠨⠂⠨⠅"] # 0x2ab4 + - "⪵": [t: "⠨⠐⠅⠌⠨⠅"] # 0x2ab5 + - "⪶": [t: "⠨⠨⠂⠌⠨⠅"] # 0x2ab6 + - "⪷": [t: "⠨⠐⠅⠈⠱⠈⠱"] # 0x2ab7 + - "⪸": [t: "⠨⠨⠂⠈⠱⠈⠱"] # 0x2ab8 + - "⪹": [t: "⠨⠐⠅⠌⠈⠱⠈⠱"] # 0x2ab9 + - "⪺": [t: "⠨⠨⠂⠌⠈⠱⠈⠱"] # 0x2aba + - "⪻": [t: "⠨⠐⠅⠈⠨⠐⠅⠻"] # 0x2abb + - "⪼": [t: "⠨⠨⠂⠈⠨⠨⠂⠻"] # 0x2abc + - "﹩": [t: "⠈⠎"] # 0xfe69 + - "$": [t: "⠈⠎"] # 0xff04 + - "_": [t: "⠱"] # 0xff3f + - "~": [t: "⠈⠱"] # 0xff5e + - "¢": [t: "⠈⠉"] # 0xffe0 + - "£": [t: "⠈⠇"] # 0xffe1 + - " ̄": [t: "⠱"] # 0xffe3 + - "¥": [t: "⠈⠽"] # 0xffe5 + + # --- Nemeth Default Characters rest chars. --- + + - "ℵ": [t: "⠠⠠⠁"] # 0x2135 + - "ℶ": [t: "⠠⠠⠃"] # 0x2136 + - "ℷ": [t: "⠠⠠⠉"] # 0x2137 + - "ℸ": [t: "⠠⠠⠙"] # 0x2138 + - "à": [t: "⠈⠁"] # 0xe0 + - "á": [t: "⠈⠁"] # 0xe1 + - "â": [t: "⠈⠁"] # 0xe2 + - "ã": [t: "⠈⠁"] # 0xe3 + - "ä": [t: "⠈⠁"] # 0xe4 + - "å": [t: "⠈⠁"] # 0xe5 + - "ç": [t: "⠈⠉"] # 0xe7 + - "è": [t: "⠈⠑"] # 0xe8 + - "é": [t: "⠈⠑"] # 0xe9 + - "ê": [t: "⠈⠑"] # 0xea + - "ë": [t: "⠈⠑"] # 0xeb + - "ì": [t: "⠈⠊"] # 0xec + - "í": [t: "⠈⠊"] # 0xed + - "î": [t: "⠈⠊"] # 0xee + - "ï": [t: "⠈⠊"] # 0xef + - "ñ": [t: "⠈⠝"] # 0xf1 + - "ò": [t: "⠈⠕"] # 0xf2 + - "ó": [t: "⠈⠕"] # 0xf3 + - "ô": [t: "⠈⠕"] # 0xf4 + - "õ": [t: "⠈⠕"] # 0xf5 + - "ö": [t: "⠈⠕"] # 0xf6 + - "ù": [t: "⠈⠥"] # 0xf9 + - "ú": [t: "⠈⠥"] # 0xfa + - "û": [t: "⠈⠥"] # 0xfb + - "ü": [t: "⠈⠥"] # 0xfc + - "ý": [t: "⠈⠽"] # 0xfd + - "ÿ": [t: "⠈⠽"] # 0xff + + - "À": [t: "⠠⠈⠁"] # 0xc0 + - "Á": [t: "⠠⠈⠁"] # 0xc1 + - "Â": [t: "⠠⠈⠁"] # 0xc2 + - "Ã": [t: "⠠⠈⠁"] # 0xc3 + - "Ä": [t: "⠠⠈⠁"] # 0xc4 + - "Å": [t: "⠠⠈⠁"] # 0xc5 + - "Ç": [t: "⠠⠈⠉"] # 0xc7 + - "È": [t: "⠠⠈⠑"] # 0xc8 + - "É": [t: "⠠⠈⠑"] # 0xc9 + - "Ê": [t: "⠠⠈⠑"] # 0xca + - "Ë": [t: "⠠⠈⠑"] # 0xcb + - "Ì": [t: "⠠⠈⠊"] # 0xcc + - "Í": [t: "⠠⠈⠊"] # 0xcd + - "Î": [t: "⠠⠈⠊"] # 0xce + - "Ï": [t: "⠠⠈⠊"] # 0xcf + - "Ñ": [t: "⠠⠈⠝"] # 0xd1 + - "Ò": [t: "⠠⠈⠕"] # 0xd2 + - "Ó": [t: "⠠⠈⠕"] # 0xd3 + - "Ô": [t: "⠠⠈⠕"] # 0xd4 + - "Ö": [t: "⠠⠈⠕"] # 0xd6 + - "Ù": [t: "⠠⠈⠥"] # 0xd9 + - "Ú": [t: "⠠⠈⠥"] # 0xda + - "Û": [t: "⠠⠈⠥"] # 0xdb + - "Ü": [t: "⠠⠈⠥"] # 0xdc + - "Ý": [t: "⠠⠈⠽"] # 0xdd + - "←": [t: "⠫⠪⠒⠒"] # 0x2190 + + - "↑": # 0x2191 + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠣"] + else: [t: "⠫⠣⠒⠒⠕"] + + - "↓": # 0x2193 + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠩"] + else: [t: "⠫⠩⠒⠒⠕"] + + - "↔": [t: "⠫⠪⠒⠒⠕"] # 0x2194 + - "↕": [t: "⠫⠣⠩⠪⠒⠒⠕"] # 0x2195 + - "↖": [t: "⠫⠘⠪⠒⠒"] # 0x2196 + - "↗": [t: "⠫⠘⠒⠒⠕"] # 0x2197 + - "↘": [t: "⠫⠰⠒⠒⠕"] # 0x2198 + - "↙": [t: "⠫⠰⠪⠒⠒"] # 0x2199 + - "↚": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x219a + - "↛": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x219b + - "↜": [t: "⠫⠪⠔⠒⠢"] # 0x219c + - "↝": [t: "⠫⠔⠒⠢⠕"] # 0x219d + - "↞": [t: "⠫⠪⠪⠒⠒"] # 0x219e + - "↟": [t: "⠫⠣⠒⠒⠕⠕"] # 0x219f + - "↠": [t: "⠫⠒⠒⠕⠕"] # 0x21a0 + - "↡": [t: "⠫⠩⠒⠒⠕⠕"] # 0x21a1 + - "↢": [t: "⠫⠪⠒⠒⠠⠽"] # 0x21a2 + - "↣": [t: "⠫⠠⠯⠒⠒⠕"] # 0x21a3 + - "↤": [t: "⠫⠪⠒⠒⠳"] # 0x21a4 + - "↥": [t: "⠫⠣⠳⠒⠒⠕"] # 0x21a5 + - "↦": [t: "⠫⠳⠒⠒⠕"] # 0x21a6 + - "↧": [t: "⠫⠩⠳⠒⠒⠕"] # 0x21a7 + - "↨": [t: "⠫⠪⠒⠳⠒⠕"] # 0x21a8 + - "↩": [t: "⠫⠪⠒⠒⠠⠕"] # 0x21a9 + - "↪": [t: "⠫⠠⠪⠒⠒⠕"] # 0x21aa + - "↫": [t: "⠫⠪⠒⠒⠨⠡"] # 0x21ab + - "↬": [t: "⠫⠨⠡⠒⠒⠕"] # 0x21ac + - "↭": [t: "⠫⠪⠔⠒⠢⠕"] # 0x21ad + - "↮": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21ae + - "↯": [t: "⠫⠩⠔⠢⠔"] # 0x21af + - "↴": [t: "⠫⠠⠳⠒⠒⠕"] # 0x21b4 + - "↵": [t: "⠫⠩⠠⠳⠒⠒⠕"] # 0x21b5 + - "↶": [t: "⠫⠢⠔⠕"] # 0x21b6 + - "↷": [t: "⠫⠪⠢⠔"] # 0x21b7 + - "↺": [t: "⠫⠢⠔⠕"] # 0x21ba + - "↻": [t: "⠫⠪⠢⠔"] # 0x21bb + - "⇄": [t: "⠫⠒⠒⠕⠫⠪⠒⠒"] # 0x21c4 + - "⇅": [t: "⠫⠣⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21c5 + - "⇆": [t: "⠫⠪⠒⠒⠫⠒⠒⠕"] # 0x21c6 + - "⇇": [t: "⠫⠚⠒⠒⠫⠚⠒⠒"] # 0x21c7 + - "⇈": [t: "⠫⠣⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21c8 + - "⇉": [t: "⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21c9 + - "⇊": [t: "⠫⠩⠒⠒⠕⠐⠫⠩⠒⠒⠕"] # 0x21ca + - "⇍": [t: "⠳⠈⠫⠪⠪⠒⠒"] # 0x21cd + - "⇎": [t: "⠳⠈⠫⠪⠪⠒⠒⠕⠕"] # 0x21ce + - "⇏": [t: "⠳⠈⠫⠒⠒⠕⠕"] # 0x21cf + - "⇐": [t: "⠫⠪⠶⠶"] # 0x21d0 + - "⇑": [t: "⠫⠣⠶⠶⠕"] # 0x21d1 + - "⇒": [t: "⠫⠶⠶⠕"] # 0x21d2 + - "⇓": [t: "⠫⠣⠶⠶⠕"] # 0x21d3 + - "⇔": [t: "⠫⠪⠶⠶⠕"] # 0x21d4 + - "⇕": [t: "⠫⠣⠪⠶⠶⠕"] # 0x21d5 + - "⇖": [t: "⠫⠘⠪⠶⠶"] # 0x21d6 + - "⇗": [t: "⠫⠘⠶⠶⠕"] # 0x21d7 + - "⇘": [t: "⠫⠰⠶⠶⠕"] # 0x21d8 + - "⇙": [t: "⠫⠰⠪⠪⠒⠒"] # 0x21d9 + - "⇚": [t: "⠫⠪⠪⠶⠶"] # 0x21da FIX: how to represent triple shafts? + - "⇛": [t: "⠫⠶⠶⠕⠕"] # 0x21db FIX: how to represent triple shafts? + - "⇜": [t: "⠫⠪⠢⠤⠔⠒⠢"] # 0x21dc + - "⇝": [t: "⠫⠢⠤⠔⠒⠢⠕"] # 0x21dd + - "⇞": [t: "⠳⠳⠈⠫⠣⠒⠒⠕⠻"] # 0x21de + - "⇟": [t: "⠳⠳⠈⠫⠩⠒⠒⠕⠻"] # 0x21df + - "⇠": [t: "⠫⠪⠒⠒"] # 0x21e0 + - "⇡": [t: "⠫⠣⠒⠒⠕"] # 0x21e1 + - "⇢": [t: "⠫⠒⠒⠕"] # 0x21e2 + - "⇣": [t: "⠫⠩⠒⠒⠕"] # 0x21e3 + - "⇤": [t: "⠫⠳⠪⠒⠒"] # 0x21e4 + - "⇥": [t: "⠫⠒⠒⠕⠳"] # 0x21e5 + - "⇦": [t: "⠫⠸⠪⠒⠒"] # 0x21e6 + - "⇧": [t: "⠫⠣⠸⠒⠒⠕"] # 0x21e7 + - "⇨": [t: "⠫⠸⠒⠒⠕"] # 0x21e8 + - "⇩": [t: "⠫⠩⠸⠒⠒⠕"] # 0x21e9 + - "⇳": [t: "⠫⠣⠸⠪⠒⠒⠕"] # 0x21f3 + - "⇴": [t: "⠫⠒⠒⠕⠨⠡"] # 0x21f4 + - "⇵": [t: "⠫⠩⠒⠒⠕⠐⠫⠣⠒⠒⠕"] # 0x21f5 + - "⇶": [t: "⠫⠒⠒⠕⠫⠒⠒⠕⠫⠒⠒⠕"] # 0x21f6 + - "⇷": [t: "⠳⠈⠫⠪⠒⠒⠻"] # 0x21f7 + - "⇸": [t: "⠳⠈⠫⠒⠒⠕⠻"] # 0x21f8 + - "⇹": [t: "⠳⠈⠫⠪⠒⠒⠕"] # 0x21f9 + - "⇺": [t: "⠳⠳⠈⠫⠪⠒⠒⠻"] # 0x21fa + - "⇻": [t: "⠳⠳⠈⠫⠒⠒⠕⠻"] # 0x21fb + - "⇼": [t: "⠳⠳⠈⠫⠪⠒⠒⠕"] # 0x21fc + - "⇽": [t: "⠫⠳⠒⠒"] # 0x21fd + - "⇾": [t: "⠫⠒⠒⠳"] # 0x21fe + - "⇿": [t: "⠫⠳⠒⠒⠳"] # 0x21ff + + - "ⅆ": [t: "⠙"] # 0x2146 + - "ⅇ": [t: "⠑"] # 0x2147 + - "ⅈ": [t: "⠊"] # 0x2148 + - "⌜": [t: "⠈⠘⠷"] # 0x231c + - "⌝": [t: "⠈⠘⠾"] # 0x231d + - "⌞": [t: "⠈⠰⠷"] # 0x231e + - "⌟": [t: "⠈⠰⠾"] # 0x231f + - "〈": [t: "⠨⠨⠷"] # 0x2329 + - "〉": [t: "⠨⠨⠾"] # 0x232a + - "⏞": [t: "⠨⠷"] # 0x23de + - "⏟": [t: "⠨⠾"] # 0x23df + - "⎴": [t: "⠈⠷"] # 0x23b4 + - "⎵": [t: "⠈⠾"] # 0x23b5 + - "⟪": [t: "⠨⠨⠨⠷"] # 0x27ea + - "⟫": [t: "⠨⠨⠨⠾"] # 0x27eb + - "〈": [t: "⠨⠨⠷"] # 0x3008 + - "〉": [t: "⠨⠨⠾"] # 0x3009 + - "《": [t: "⠨⠨⠨⠷"] # 0x300a + - "》": [t: "⠨⠨⠨⠾"] # 0x300b + - "「": [t: "⠈⠘⠷"] # 0x300c + - "」": [t: "⠈⠘⠾"] # 0x300d + - "↼": [t: "⠫⠈⠪⠒⠒"] # 0x21bc + - "↽": [t: "⠫⠠⠪⠒⠒"] # 0x21bd + - "↾": [t: "⠫⠣⠒⠒⠠⠕"] # 0x21be + - "↿": [t: "⠫⠣⠒⠒⠈⠕"] # 0x21bf + - "⇀": [t: "⠫⠒⠒⠈⠕"] # 0x21c0 + - "⇁": [t: "⠫⠒⠒⠠⠕"] # 0x21c1 + - "⇂": [t: "⠫⠪⠒⠒⠈⠕"] # 0x21c2 + - "⇃": [t: "⠫⠩⠒⠒⠠⠕"] # 0x21c3 + - "⇋": # 0x21cb + + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠫⠒⠕"] + else: [t: "⠫⠈⠪⠒⠒⠫⠒⠒⠈⠕"] + - "⇌": # 0x21cc + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] + + - "℔": [t: "⠳"] # 0x2114 + - "™": [t: "⠘⠞"] # 0x2122 + - "Å": [t: "⠈⠠⠁"] # 0x212b + - "­": [t: "⠤"] # 0xad + - " -​": [t: "W"] # 0x2000 - 0x200b (various spaces / ZWSP) + - "
": [t: "W"] # 0x2028 + - "
": [t: "W"] # 0x2029 + - " ": [t: "W"] # 0x202f + - " ": [t: "W"] # 0x205f + - "₣": [t: "⠈⠋"] # 0x20A3 (French franc sign + - "₦": [t: "⠈⠝"] # 0x2046 (Naira sign) + - "₩": [t: "⠈⠺"] # 0x20A9 (Won sign) + - "€": [t: "⠈⠑"] # 0x20AC (Euro sign) + - "": [t: "W"] # 0xfeff + - "☆": [t: "⠫⠎"] # 0x2606 + - "✕": [t: "⠈⠡"] # 0x2715 + - "¼": [t: "⠹⠂⠌⠲⠼"] # 0xbc + - "½": [t: "⠹⠂⠌⠆⠼"] # 0xbd + - "¾": [t: "⠹⠒⠌⠲⠼"] # 0xbe + - "⅐": [t: "⠹⠂⠌⠶⠼"] # 0x2150 + - "⅑": [t: "⠹⠂⠌⠔⠼"] # 0x2151 + - "⅒": [t: "⠹⠂⠌⠂⠴⠼"] # 0x2152 + - "⅓": [t: "⠹⠂⠌⠒⠼"] # 0x2153 + - "⅔": [t: "⠹⠆⠌⠒⠼"] # 0x2154 + - "⅕": [t: "⠹⠂⠌⠢⠼"] # 0x2155 + - "⅖": [t: "⠹⠆⠌⠢⠼"] # 0x2156 + - "⅗": [t: "⠹⠒⠌⠢⠼"] # 0x2157 + - "⅘": [t: "⠹⠲⠌⠢⠼"] # 0x2158 + - "⅙": [t: "⠹⠂⠌⠖⠼"] # 0x2159 + - "⅚": [t: "⠹⠢⠌⠖⠼"] # 0x215a + - "⅛": [t: "⠹⠂⠌⠦⠼"] # 0x215b + - "⅜": [t: "⠹⠒⠌⠦⠼"] # 0x215c + - "⅝": [t: "⠹⠢⠌⠦⠼"] # 0x215d + - "⅞": [t: "⠹⠶⠌⠦⠼"] # 0x215e + - "⅟": [t: "⠹⠂⠌⠼"] # 0x215f + - "↉": [t: "⠹⠴⠌⠒⠼"] # 0x2189 + - "㉈": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠂⠴⠻⠻"] # 0x3248 + - "㉉": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠆⠴⠻⠻"] # 0x3249 + - "㉊": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠒⠴⠻⠻"] # 0x324a + - "㉋": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠲⠴⠻⠻"] # 0x324b + - "㉌": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠢⠴⠻⠻"] # 0x324c + - "㉍": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠖⠴⠻⠻"] # 0x324d + - "㉎": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠶⠴⠻⠻"] # 0x324e + - "㉏": [t: "⠫⠸⠲⠸⠫⠫⠉⠸⠫⠼⠦⠴⠻⠻"] # 0x324f + + + - "‘": [t: "P⠠⠦"] # 0x2018 (Left single quotation mark) + - "’": [t: "P⠠⠴"] # 0x2019 (Right single quotation mark) + - "“": [t: "P⠦"] # 0x201C (Left double quotation mark) + - "”": [t: "P⠴"] # 0x201D (Right double quotation mark) + - "‰": [t: "`00"] + - "ℏ": [t: "⠈⠓"] # 0x210F (Planck constant over two pi) + - "ℓ": [t: "TE⠇"] # 0x2113 (Script small l (differs from 1d4c1: 4-56-123)) + - "℘": [tc: "TCL⠏"] # 0x2118 (Script Capital P) +# - "ℝ": [t: ""] # 0x211D (Double-struck capital R (no nemeth double struck)) +# - "ⅆ": [t: ""] # 0x2146 (Double-struck italic small d) +# - "ⅇ": [t: ""] # 0x2147 (Double-struck italic small e) +# - "⇚": [t: "⠀⠫⠪⠸⠸⠀"] # 0x21DA (Leftwards triple arrow) +# - "⇛": [t: "⠀⠫⠸⠸⠕⠀"] # 0x21DB (Rightwards triple arrow) + - "∔": [t: "⠐⠬⠣⠡⠻"] # 0x2214 (Dot plus) + - "√": [t: "⠜"] # 0x221A (Square root) + - "∛": [t: "⠣⠒⠜"] # 0x221B (Cube root) + - "∜": [t: "⠣⠲⠜"] # 0x221C (Fourth root) + - "∡": [t: "⠫⠪⠸⠫⠫⠁⠻"] # 0x2221 (Measured angle) + - "∹": [t: "⠤⠐⠂"] # 0x2239 (Excess) + - "∺": [t: "⠐⠤⠩⠡⠡⠣⠡⠡⠻"] # 0x223A (Geometric proportion) + - "∻": [t: "⠐⠈⠱⠩⠡⠣⠡⠻"] # 0x223B (Homothetic) + - "∽": [t: "⠠⠱"] # 0x223D (Reversed tilde) + - "≋": [t: "⠈⠱⠈⠱⠈⠱"] # 0x224B (Triple tilde) + - "≌": [t: "⠠⠱⠨⠅"] # 0x224C (All equal to) + - "≏": [t: "⠈⠣⠱"] # 0x224F (Difference between) + - "≔": [t: "⠐⠂⠨⠅"] # 0x2254 (Colon equals) + - "≕": [t: "⠨⠅⠐⠂"] # 0x2255 (Equals colon) + - "≖": [t: "⠀⠨⠡⠈⠨⠅⠻⠀"] # 0x2256 (Ring in equal to) + - "⊌": [t: "⠨⠬⠈⠫⠪⠒⠻"] # 0x228C (Multiset) + - "⊍": [t: "⠡⠈⠨⠬⠻"] # 0x228D (Multiset multiplication) + - "⊎": [t: "⠬⠈⠨⠬⠻"] # 0x228E (Multiset union) + - "⊕": [t: "⠫⠉⠸⠫⠬⠻"] # 0x2295 (Circled plus) + - "⊖": [t: "⠫⠉⠸⠫⠤⠻"] # 0x2296 (Circled minus) + - "⊗": [t: "⠫⠉⠸⠫⠈⠡⠻"] # 0x2297 (Circled times) + - "⊘": [t: "⠫⠉⠸⠫⠸⠌⠻"] # 0x2298 (Circled division slash) + - "⊙": [t: "⠫⠉⠸⠫⠡⠻"] # 0x2299 (Circled dot operator) + - "⊚": [t: "⠫⠉⠸⠫⠘⠨⠡⠻"] # 0x229a (Circled ring operator) + - "⊛": [t: "⠫⠉⠸⠫⠈⠼⠻"] # 0x229B (Circled asterisk operator) + - "⊜": [t: "⠫⠉⠸⠫⠨⠅⠻"] # 0x229C (Circled equals) + - "⊝": [t: "⠫⠉⠸⠫⠤⠤⠻"] # 0x229D (Circled dash) + - "⊞": [t: "⠫⠲⠸⠫⠬⠻"] # 0x229E (Squared plus) + - "⊟": [t: "⠫⠲⠸⠫⠤⠻"] # 0x229F (Squared minus) + - "⊠": [t: "⠫⠲⠸⠫⠈⠡⠻"] # 0x22A0 (Squared times) + - "⊡": [t: "⠫⠲⠸⠫⠡⠻"] # 0x22A1 (Squared dot operator) + - "⊢": [t: "⠫⠳⠒"] # 0x22A2 (Right tack) + - "⊣": [t: "⠫⠒⠳"] # 0x22A3 (Left tack) + - "⊤": [t: "⠫⠩⠳⠒"] # 0x22A4 (Down tack) +# - "⊥": [t: "⠀⠫⠏⠀ or ⠀⠫⠣⠳⠒⠀"] # 0x22A5 (Up tack (See also 27C2)) +# - "⊦": [t: ""] # 0x22A6 (Assertion) +# - "⊨": [t: ""] # 0x22A8 (TRUE) +# - "⊲": [t: ""] # 0x22B2 (Normal subgroup of) +# - "⊳": [t: ""] # 0x22B3 (Contains as normal subgroup) +# - "⊴": [t: ""] # 0x22B4 (Normal subgroup of or equal to) +# - "⊵": [t: ""] # 0x22B5 (Contains as normal subgroup or equal to) + - "⊶": [t: "⠫⠨⠡⠒⠡"] # 0x22B6 (Original of) + - "⊷": [t: "⠫⠡⠒⠨⠡"] # 0x22B7 (Image of) + - "⊸": [t: "⠫⠒⠨⠡"] # 0x22B8 (Multimap) +# - "⊾": [t: ""] # 0x22BE (Right angle w arc) + - "⊿": [t: "⠫⠞⠨⠗⠻"] # 0x22BF (Right triangle) + - "⋅": [t: "⠡"] # 0x22C5 (Dot operator) + - "∙": [t: "⠡"] # 0x2219 -- similar looking to 0x22c5, so using the same braille + - "⋆": [t: "⠫⠎"] # 0x22C6 (Star operator) + - "⋍": [t: "⠠⠱⠱"] # 0x22CD (Reversed tilde equals) + - "⋖": [t: "⠡⠈⠐⠅⠻"] # 0x22D6 (Less-than w dot) + - "⋗": [t: "⠡⠈⠨⠂⠻"] # 0x22D7 (Greater-than w dot) + - "⋘": [t: "⠐⠅⠈⠐⠅⠈⠐⠅⠻"] # 0x22D8 (Much less-than) + - "⋙": [t: "⠨⠂⠈⠨⠂⠈⠨⠂⠻"] # 0x22D9 (Much greater-than) + - "⋲": [t: "⠱⠈⠈⠑⠻"] # 0x22F2 (Element of w long horizontal stroke) + - "⋵": [t: "⠐⠈⠑⠣⠡⠻"] # 0x22F5 (Element of w dot above) + - "⋶": [t: "⠱⠈⠑"] # 0x22F6 (Element of w overbar) + - "⋺": [t: "⠱⠈⠈⠢⠻"] # 0x22FA (Contains w long horizontal stroke) + - "⋽": [t: "⠱⠈⠢"] # 0x22FD (Contains w overbar) + - "⌈": [t: "⠈⠘⠷"] # 0x2308 (Left ceiling) + - "⌉": [t: "⠈⠘⠾"] # 0x2309 (Right ceiling) + - "⌊": [t: "⠈⠰⠷"] # 0x230A (Left floor) + - "⌋": [t: "⠈⠰⠾"] # 0x230B (Right floor) + - "⌢": [t: "⠫⠁"] # 0x2322 (Frown) + - "⌣": [t: "⠫⠄"] # 0x2323 (Smile) + - "■": [t: "⠫⠸⠲"] # 0x25A0 (Filled square) + - "▫": [t: "⠫⠲"] # 0x25AB (Small white Square) + - "□": [t: "⠫⠲"] # 0x25A1 (Square) + - "◻": [t: "⠫⠲"] # 0x25FB (Square) + - "▬": [t: "⠫⠸⠗"] # 0x25AC (Filled rectangle) + - "▭": [t: "⠫⠗"] # 0x25AD (Rectangle) + - "▲": [t: "⠫⠸⠞"] # 0x25B2 (Black up-pointing triangle) + - "△": [t: "⠫⠞"] # 0x25B3 (White up-pointing triangle) + - "▼": [t: "⠸⠨⠫"] # 0x25BC (Black down-pointing triangle) + - "○": [t: "⠫⠉"] # 0x25CB (White circle) + - "●": [t: "⠫⠸⠉"] # 0x25CF (Black circle) + - "◫": [t: "⠫⠲⠸⠫⠳⠻"] # 0x25EB (White square w vertical bisecting line) +# - "⊥": [t: "⠫⠏"] # 0x27C2 (Perpendicular) + - "⟃": [t: "⠨⠡⠈⠸⠐⠅⠻"] # 0x27C3 (Open subset) + - "⟄": [t: "⠨⠡⠈⠸⠨⠂⠻"] # 0x27C4 (Open superset) + - "⟜": [t: "⠫⠨⠡⠒⠒"] # 0x27DC (Left multimap) + - "⟝": [t: "⠫⠳⠒⠒"] # 0x27DD (Long right tack) + - "⟞": [t: "⠫⠒⠒⠳"] # 0x27DE (Long left tack) + - "⟟": [t: "⠫⠣⠳⠒⠒⠨⠡"] # 0x27DF (Up tack w circle above) + - "⟦": [t: "⠈⠸⠷"] # 0x27E6 (Mathematical left white square bracket) + - "⟧": [t: "⠈⠸⠾"] # 0x27E7 (Mathematical right white square bracket) + - "⟨": [t: "⠨⠨⠷"] # 0x27E8 (Mathematical left angle bracket) + - "⟩": [t: "⠨⠨⠾"] # 0x27E9 (Mathematical right angle bracket) + - "⟵": [t: "⠀⠫⠪⠒⠒⠒⠀"] # 0x27F5 (Long leftwards arrow ) + - "⟶": [t: "⠀⠫⠒⠒⠒⠕⠀"] # 0x27F6 (Long rightwards arrow) + - "⟷": [t: "⠀⠫⠪⠒⠒⠒⠕⠀"] # 0x27F7 (Long left right arrow) + - "⟸": [t: "⠀⠫⠪⠶⠶⠶⠀"] # 0x27F8 (Long leftwards arrow ) + - "⟹": [t: "⠀⠫⠶⠶⠶⠕⠀"] # 0x27F9 (Long rightwards arrow) + - "⟺": [t: "⠀⠫⠪⠶⠶⠶⠕⠀"] # 0x27FA (Long left right arrow) + - "⟻": [t: "⠀⠫⠪⠒⠒⠒⠳⠀"] # 0x27FB (Long leftwards arrow from bar) + - "⟼": [t: "⠀⠫⠳⠒⠒⠒⠕⠀"] # 0x27FC (Long rightwards arrow from bar) + - "⟽": [t: "⠀⠫⠪⠶⠶⠶⠳⠀"] # 0x27FD (Long leftwards double arrow from bar) + - "⟾": [t: "⠀⠫⠳⠶⠶⠶⠕⠀"] # 0x27FE (Long rightwards double arrow from bar) + - "⟿": [t: "⠀⠫⠢⠤⠔⠒⠢⠤⠔⠒⠢⠕⠀"] # 0x27FF (Long rightwards squiggle arrow) + - "⤡": [t: "⠀⠫⠘⠪⠒⠒⠕⠀"] # 0x2921 (North west and south east arrow) + - "⤢": [t: "⠀⠫⠰⠪⠒⠒⠕⠀"] # 0x2922 (North east and south west arrow) + - "🣐": # 0x1f8d0 (Long rightwards arrow over leftwards arrow (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] + - "🣑": # 0x1f8d1 (Long rightwards harpoon over leftwards harpoon (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒"] + - "🣒": # 0x1f8d2 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] + - "🣓": # 0x1f8d3 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒⠒"] + else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] + - "🣔": # 0x1f8d4 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠒⠫⠒⠕"] + else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] + - "🣕": # 0x1f8d5 (Short leftwards harpoon over long rightwards harpoon (equilibrium, trend to the left)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠫⠒⠒⠕"] + else: [t: "⠫⠈⠪⠒⠫⠒⠒⠠⠕"] + - "⥂": # 0x2942 (Long rightwards harpoon over short leftwards harpoon (equilibrium)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠒⠕⠫⠪⠒"] + else: [t: "⠫⠒⠒⠈⠕⠫⠈⠪⠒⠒"] + - "⥄": # 0x2944 (Short rightwards harpoon over long leftwards harpoon (equilibrium, trend to the right)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠒⠕⠫⠪⠒⠒"] + else: [t: "⠫⠒⠈⠕⠫⠠⠪⠒⠒"] + - "⥃": # 0x2943 (Long leftwards harpoon over short rightwards harpoon (equilibrium, trend to the left)) + - test: + if: "@data-chem-equation-op or ancestor-or-self::*[contains(@intent, ':chemical-equation')]" + then: [t: "⠫⠪⠒⠒⠫⠒⠕"] + else: [t: "⠫⠈⠪⠒⠒⠫⠒⠠⠕"] + - "🣖": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d6 (long rightwards arrow with through X) + - "🣗": [t: "⠌⠫⠒⠒⠕"] # 0x1f8d7 (long rightwards arrow with double slash) chem code says it is same as 0x1f8d6 + + + - "⦃": [t: "⠨⠸⠷"] # 0x2983 (Left white curly bracket) + - "⦄": [t: "⠨⠸⠾"] # 0x2984 (Right white curly bracket) + - "⦑": [t: "⠡⠈⠨⠨⠷⠻"] # 0x2991 (Left angle bracket w dot) + - "⦒": [t: "⠡⠈⠨⠨⠾⠻"] # 0x2992 (Right angle bracket w dot) + - "⧄": [t: "⠫⠲⠸⠫⠔⠻"] # 0x29C4 (Square rising diagonal slash) + - "⧅": [t: "⠫⠲⠸⠫⠢⠻"] # 0x29C5 (Square falling diagonal slash) + - "⧆": [t: "⠫⠲⠸⠫⠈⠼⠻"] # 0x29C6 (Squared asterisk) + - "⧊": [t: "⠐⠫⠞⠣⠡⠻"] # 0x29CA (Triangle w dot above) + - "⧋": [t: "⠫⠞⠱"] # 0x29CB (Triangle w underbar) + - "⧌": [t: "⠫⠞⠎"] # 0x29CC (s in triangle §114) + - "⧦": [t: "⠫⠳⠶⠶⠳"] # 0x29E6 (Gleich stark) + - "⨌": [t: "⠮⠮⠮⠮"] # 0x2A0C (Quadruple integral operator) + - "⨍": [t: "⠮⠈⠱⠻"] # 0x2A0D (Finite part integral) + - "⨎": [t: "⠮⠈⠱⠱⠻"] # 0x2A0E (Integral w double stroke) + - "⨖": [t: "⠮⠈⠫⠲⠻"] # 0x2A16 (Quaternion integral operator) + - "⨘": [t: "⠮⠈⠈⠡⠻"] # 0x2A18 (Integral w times sign) + - "⨙": [t: "⠮⠈⠨⠩⠻"] # 0x2A19 (Integral w intersection) + - "⨚": [t: "⠮⠈⠨⠬⠻"] # 0x2A1A (Integral w union) + - "⨛": [t: "⠣⠮"] # 0x2A1B (Integral w overbar (upper)) + - "⨜": [t: "⠩⠮"] # 0x2A1C (Integral w underbar (lower)) + - "⨢": [t: "⠐⠬⠣⠨⠡⠻"] # 0x2A22 (Plus sign w small circle above) + - "⨣": [t: "⠐⠬⠣⠸⠣⠻"] # 0x2A23 (Plus sign w circumflex accent above) + - "⨤": [t: "⠐⠬⠣⠈⠱⠻"] # 0x2A24 (Plus sign w tilde above) + - "⨥": [t: "⠐⠬⠩⠡⠻"] # 0x2A25 (Plus sign w dot below) + - "⨪": [t: "⠐⠱⠩⠡⠻"] # 0x2A2A (Minus sign w dot below) + - "⨰": [t: "⠐⠈⠡⠣⠡⠻"] # 0x2A30 (Multiplication sign w dot above) + - "⨱": [t: "⠈⠡⠱"] # 0x2A31 (Multiplication sign w underbar) + - "⨸": [t: "⠫⠉⠸⠫⠨⠌⠻"] # 0x2A38 (Circled division sign) + - "⨹": [t: "⠫⠞⠸⠫⠬⠻"] # 0x2A39 (Plus sign in triangle) + - "⨺": [t: "⠫⠞⠸⠫⠤⠻"] # 0x2A3A (Minus sign in triangle) + - "⨻": [t: "⠫⠞⠸⠫⠈⠡⠻"] # 0x2A3B (Multiplication sign in triangle) + - "⩀": [t: "⠡⠈⠨⠩⠻"] # 0x2A40 (Intersection w dot) + - "⩁": [t: "⠤⠈⠨⠬⠻"] # 0x2A41 (Union w minus sign) + - "⩂": [t: "⠱⠨⠬"] # 0x2A42 (Union w overbar) + - "⩃": [t: "⠱⠨⠩"] # 0x2A43 (Intersection w overbar) + - "⩑": [t: "⠐⠈⠩⠣⠡⠻"] # 0x2A51 (Logical AND w dot above) + - "⩒": [t: "⠐⠈⠬⠣⠡⠻"] # 0x2A52 (Logical OR w dot above) + - "⩜": [t: "⠱⠈⠈⠩⠻"] # 0x2A5C (Logical AND with horizontal dash) + - "⩝": [t: "⠱⠈⠈⠬⠻"] # 0x2A5D (Logical OR with horizontal dash) + - "⩞": [t: "⠱⠱⠈⠩"] # 0x2A5E (Logical AND w double overbar) + - "⩟": [t: "⠈⠩⠱"] # 0x2A5F (Logical AND w underbar) + - "⩠": [t: "⠈⠩⠱⠱"] # 0x2A60 (Logical AND w double underbar) + - "⩢": [t: "⠱⠱⠈⠬"] # 0x2A62 (Logical OR w double overbar) + - "⩣": [t: "⠈⠬⠱⠱"] # 0x2A63 (Logical OR w double underbar) + - "⩦": [t: "⠐⠨⠅⠩⠡⠻"] # 0x2A66 (Equals sign w dot below) + - "⩧": [t: "⠐⠸⠇⠣⠡⠻"] # 0x2A67 (Identical w dot above) + - "⩪": [t: "⠐⠈⠱⠣⠡⠻"] # 0x2A6A (Tilde operator w dot above) + - "⩬": [t: "⠈⠱⠱⠈⠱"] # 0x2A6C (Similar minus similar) + - "⩭": [t: "⠐⠈⠱⠨⠅⠣⠡⠻"] # 0x2A6D (Congruent w dot above) + - "⩮": [t: "⠐⠨⠅⠣⠈⠼⠻"] # 0x2A6E (Equals w asterisk) + - "⩯": [t: "⠐⠈⠱⠈⠱⠣⠸⠣⠻"] # 0x2A6F (Almost equal to w circumflex) + - "⩰": [t: "⠈⠱⠈⠱⠨⠅"] # 0x2A70 (Approximately equal or equal to) + - "⩱": [t: "⠨⠅⠬"] # 0x2A71 (Equals sign above plus sign) + - "⩲": [t: "⠬⠨⠅"] # 0x2A72 (Plus sign above equals sign) + - "⩳": [t: "⠨⠅⠈⠱"] # 0x2A73 (Equals sign above tilde operator) + - "⩴": [t: "⠐⠂⠐⠂⠨⠅"] # 0x2A74 (Double colon equal) + - "⩵": [t: "⠨⠅⠨⠅"] # 0x2A75 (Two consecutive equals signs) + - "⩶": [t: "⠨⠅⠨⠅⠨⠅"] # 0x2A76 (Three consecutive equals signs) + - "⩷": [t: "⠐⠨⠅⠩⠡⠡⠣⠡⠡⠻"] # 0x2A77 (Equals sign w two dots above and two dots below) + - "⩸": [t: "⠐⠸⠇⠣⠡⠡⠡⠡⠻"] # 0x2A78 (Equivalent w four dots above) + - "⩹": [t: "⠐⠅⠈⠨⠡⠻"] # 0x2A79 (Less than w circle inside) + - "⩺": [t: "⠨⠂⠈⠨⠡⠻"] # 0x2A7A (Greater than w circle inside) + - "⩻": [t: "⠐⠐⠅⠣⠸⠦⠻"] # 0x2A7B (Less-than w question mark above) + - "⩼": [t: "⠐⠨⠂⠣⠸⠦⠻"] # 0x2A7C (Greater-than w question mark above) + - "⪅": [t: "⠐⠅⠈⠱⠈⠱"] # 0x2A85 (Less-than or approximate) + - "⪆": [t: "⠨⠂⠈⠱⠈⠱"] # 0x2A86 (Greater-than or approximate) + - "⪋": [t: "⠐⠅⠨⠅⠨⠂"] # 0x2A8B (Less-than above double-line equal above greater-than) + - "⪌": [t: "⠨⠂⠨⠅⠐⠅"] # 0x2A8C (Greater-than above double-line equal above less-than) + - "⪍": [t: "⠐⠅⠈⠱⠱"] # 0x2A8D (Less-than above similar or equal to) + - "⪎": [t: "⠨⠂⠈⠱⠱"] # 0x2A8E (Greater-than above similar or equal to) + - "⪏": [t: "⠐⠅⠈⠱⠨⠂"] # 0x2A8F (Less-than above similar above greater-than) + - "⪐": [t: "⠨⠂⠈⠱⠐⠅"] # 0x2A90 (Greater-than above similar above less-than) + - "⪑": [t: "⠐⠅⠨⠂⠨⠅"] # 0x2A91 (Less-than above greater-than above double-line equal) + - "⪒": [t: "⠨⠂⠐⠅⠨⠅"] # 0x2A92 (Greater-than above less-than above double-line equal) + - "⪙": [t: "⠨⠅⠐⠅"] # 0x2A99 (Double-line equal to or less-than) + - "⪚": [t: "⠨⠅⠨⠂"] # 0x2A9A (Double-line equal to or greater-than) + - "⪝": [t: "⠈⠱⠐⠅"] # 0x2A9D (Similar or less-than) + - "⪞": [t: "⠈⠱⠨⠂"] # 0x2A9E (Similar or greater-than) + - "⪟": [t: "⠈⠱⠐⠅⠨⠅"] # 0x2A9F (Similar above less-than above equals sign) + - "⪠": [t: "⠈⠱⠨⠂⠨⠅"] # 0x2AA0 (Similar above greater-than above equals sign) + - "⪮": [t: "⠈⠣⠨⠅"] # 0x2AAE (Equals sign with bumpy above) + - "⪽": [t: "⠡⠈⠸⠐⠅⠻"] # 0x2ABD (Subset w dot) + - "⪾": [t: "⠡⠈⠸⠨⠂⠻"] # 0x2ABE (Superset w dot) + - "⪿": [t: "⠐⠸⠐⠅⠩⠬⠻"] # 0x2ABF (Subset with plus sign below) + - "⫀": [t: "⠐⠸⠨⠂⠩⠬⠻"] # 0x2AC0 (Superset with plus sign below) + - "⫁": [t: "⠐⠸⠐⠅⠩⠈⠡⠻"] # 0x2AC1 (Subset with multiplication sign below) + - "⫂": [t: "⠐⠸⠨⠂⠩⠈⠡⠻"] # 0x2AC2 (Superset with multiplication sign below) + - "⫅": [t: "⠸⠐⠅⠨⠅"] # 0x2AC5 (Subset of above equals sign) + - "⫆": [t: "⠸⠨⠂⠨⠅"] # 0x2AC6 (Superset of above equals sign) + - "⫇": [t: "⠸⠐⠅⠈⠱"] # 0x2AC7 (Subset of above tilde operator) + - "⫈": [t: "⠸⠨⠂⠈⠱"] # 0x2AC8 (Superset of above tilde operator) + - "⫉": [t: "⠸⠐⠅⠈⠱⠈⠱"] # 0x2AC9 (Subset of above almost equal to) + - "⫊": [t: "⠸⠨⠂⠈⠱⠈⠱"] # 0x2ACA (Superset of above almost equal to) + - "⫋": [t: "⠸⠐⠅⠌⠨⠅"] # 0x2ACB (Subset of above not equals sign) + - "⫌": [t: "⠸⠨⠂⠌⠨⠅"] # 0x2ACC (Superset of above not equals sign) + - "⫓": [t: "⠸⠐⠅⠸⠨⠂"] # 0x2AD3 (Subset above superset) + - "⫔": [t: "⠸⠨⠂⠸⠐⠅"] # 0x2AD4 (Superset above subset) + - "⫕": [t: "⠸⠐⠅⠸⠐⠅"] # 0x2AD5 (Subset above subset) + - "⫖": [t: "⠸⠨⠂⠸⠨⠂"] # 0x2AD6 (Superset above superset) + - "⫗": [t: "⠸⠨⠂⠐⠸⠐⠅"] # 0x2AD7 (Superset beside subset) + - "⫯": [t: "⠫⠩⠨⠡⠒⠒"] # 0x2AEF (Vertical line w circle above) + - "⫰": [t: "⠫⠣⠨⠡⠒⠒"] # 0x2AF0 (Vertical line w circle below) + - "⫱": [t: "⠫⠣⠨⠡⠒⠒⠳"] # 0x2AF1 (Down tack w circle below) + - "⫲": [t: "⠱⠈⠫⠇⠻"] # 0x2AF2 (Parallel w horizontal stroke) + - "⫳": [t: "⠈⠱⠈⠫⠇⠻"] # 0x2AF3 (Parallel w tilde operator) + - "⫴": [t: "⠳⠳⠳"] # 0x2AF4 (Triple vertical bar binary relation) + - "⬬": [t: "⠫⠸⠑"] # 0x2B2C (Black ellipse) + - "⬭": [t: "⠫⠑"] # 0x2B2D (White ellipse) + - "⬰": [t: "⠨⠡⠈⠫⠪⠒⠒⠻"] # 0x2B30 (Left arrow w small circle) + - "⬱": [t: "⠫⠪⠒⠒⠫⠪⠒⠒⠫⠪⠒⠒"] # 0x2B31 (Three leftwards arrows) + - "⬲": [t: "⠫⠪⠒⠒⠈⠫⠉⠸⠫⠬⠻"] # 0x2B32 (Left arrow w circled plus) + - "⮖": [t: "⠨⠡"] # 0x2B96 (Standard State Symbol) + - "⯃": [t: "⠫⠸⠦"] # 0x2BC3 (Horizontal black octagon) + + # SRE lists this as a custom transcription + - "⋊": [t: "⠈⠡⠳"] # 0x22ca (RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT) diff --git a/Rules/Braille/UEB/UEB_Rules.yaml b/Rules/Braille/UEB/UEB_Rules.yaml index 912e03d8a..c161530dd 100644 --- a/Rules/Braille/UEB/UEB_Rules.yaml +++ b/Rules/Braille/UEB/UEB_Rules.yaml @@ -8,7 +8,7 @@ variables: [MatchingWhitespace: "true()"] replace: - test: - - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-previous-space-width >= 0.25" # BANA 5.3(a) + - if: "(@class='MathML-unit' or contains(@data-intent-property, ':unit:') or BaseNode(.)[@class='MathML-unit' or contains(@data-intent-property, ':unit:')]) and @data-previous-space-width >= 0.25" # treat spaced units as separate exprs for G1 placement then: [t: "𝐖"] - else_if: "@data-previous-space-width > 1.1" then: [t: "⠬"] @@ -16,7 +16,7 @@ then: [t: "W"] - x: "." - test: - - if: "(@class='MathML-unit' or BaseNode(.)[@class='MathML-unit']) and @data-following-space-width >= 0.25" # BANA 5.3(a) + - if: "(@class='MathML-unit' or contains(@data-intent-property, ':unit:') or BaseNode(.)[@class='MathML-unit' or contains(@data-intent-property, ':unit:')]) and @data-following-space-width >= 0.25" # treat spaced units as separate exprs for G1 placement then: [t: "𝐖"] - else_if: "@data-following-space-width > 1.1" then: [t: "⠬"] @@ -107,7 +107,7 @@ replace: - t: "1⠷" - x: "*[1]" - - t: "1⠨⠌" + - t: "⠨⠌" - x: "*[2]" - t: "1⠾" @@ -256,9 +256,10 @@ tag: mo # add spaces around comparison operators unless they are in a script position, variables: # ratio not spaced in UEB; also make sure it is an infix operator (e.g., "~" can be prefix) + # ∴ / ∵ / ∎ are spaced like comparison signs (GTM 1.7.9 "∴ force = …"; GTM 11) - AddSpaces: "$UseSpacesAroundAllOperators or ( parent::*[self::m:mrow] and $NewScriptContext='' and - .!='∶' and IsInDefinition(., 'Braille', 'NemethComparisonOperators') )" + .!='∶' and (IsInDefinition(., 'Braille', 'NemethComparisonOperators') or .='∴' or .='∵' or .='∎') )" match: "." replace: - test: diff --git a/Rules/prefs.yaml b/Rules/prefs.yaml index 8a324721e..6c36c4020 100644 --- a/Rules/prefs.yaml +++ b/Rules/prefs.yaml @@ -61,6 +61,7 @@ UEB: StartMode: "Grade2" # Grade1/Grade2 -- assumed starting mode UEB braille (Grade1 assumes we are in G1 passage mode) + # Grade 1 indicators follow ICEB GTM 1.7 (also BANA 2026 math/science guidance) # UEB Guide to Technical Material (https://iceb.org/Guidelines_for_Technical_Material_2008-10.pdf) # says to normally treat Fraktur and DoubleStruck as Script diff --git a/docs/users.md b/docs/users.md index 6328e522f..a5ab487d3 100644 --- a/docs/users.md +++ b/docs/users.md @@ -10,8 +10,6 @@ MathCAT is a tool used together with a screen reader. Through MathCAT, you can h In screen readers NVDA and JAWS, MathCAT comes built-in. This means you don’t have to install it as an addon. -MathCAT is still available as an addon to NVDA. You can use it if you want access to the very latest features between NVDA releases. [How to use MathCAT as an addon is described here](#how-to-install-mathcat-as-an-addon-in-nvda). - ## Get started with MathCAT Use your screen reader on a web page or in an e-book as usual. When you get to a mathematical expression, the screen reader will read it out automatically. If you want to investigate the expression more closely you can activate the navigation mode by pressing Space. In NVDA, the NVDA-key+Alt+M can also be used. If you want to leave the navigation mode, press Escape. @@ -139,42 +137,4 @@ Note: tabular math means mathematical content in a table structure such as a mat ## Do you have feedback on MathCAT? -MathCAT is under active development, and we want your feedback. Do you have a feature request, or have you found any bugs? Please create an issue on [MathCAT's GitHub page](https://github.com/daisy/MathCAT/issues). You are also welcome to get in touch by signing up to [the mailing list of the DAISY MathCAT working group](https://www.surveymonkey.com/r/HXTLXGN). - -## How to install MathCAT as an addon in NVDA - -To use MathCAT as an add-on, do the following: - -1. Open the NVDA menu. -2. Choose Tools and then Add-on store. -3. In the add-on store, choose Available add-ons. - - The channel settings have the following options: - - Stable: Will only search for stable add-ons - - All: Will search for all add-ons - - Beta: Will search for add-ons that are in beta - - Dev: Will search for add-ons in development - - Choose option "All". - -4. Search for MathCAT and install. - -5. In the settings menu, you can control how add-ons are updated: - - - Open the NVDA menu - - Choose settings and Add-on Store - - For Automatic updates, you can choose between: - - Notify - - Update Automatically - - Deactivated - - For Default update channel, you have the following options: - - - Same: If automatic updates is set to “Update Automatically” and your add-on is a beta, it will update to the first available beta. - - Any: It will update to any version of the add-on. - - Do not update - - Stable: It will only update to stable versions. - - Beta or dev: It will update to beta or dev versions. - - Beta: It will update to beta versions. - - Dev: It will update to dev versions. \ No newline at end of file +MathCAT is under active development, and we want your feedback. Do you have a feature request, or have you found any bugs? Please create an issue on [MathCAT's GitHub page](https://github.com/daisy/MathCAT/issues). You are also welcome to get in touch by signing up to [the mailing list of the DAISY MathCAT working group](https://www.surveymonkey.com/r/HXTLXGN). \ No newline at end of file diff --git a/src/braille.rs b/src/braille.rs index 1966f09c0..4f0ac0ec7 100644 --- a/src/braille.rs +++ b/src/braille.rs @@ -15,6 +15,7 @@ use crate::canonicalize::get_parent; use std::borrow::Cow; use std::ops::Range; use std::sync::LazyLock; +#[allow(unused_imports)] use log::{debug, error}; fn is_ueb_prefix(ch: char) -> bool { @@ -1047,11 +1048,9 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str let use_only_grade1 = pref_manager.pref_to_string("UEB_START_MODE").as_str() == "Grade1"; - // '𝐖' is a hard break -- basically, it separates exprs - let mut result = result.split('𝐖') - .map(|str| pick_start_mode(str, use_only_grade1) + "W") - .collect::(); - result.pop(); // we added a 'W' at the end that needs to be removed. + // 𝐖 is a unit hard-break. For GTM 1.7 it is still a symbols-sequence boundary (same as W), + // so G1 passage decisions (1.7.3(b) / 1.7.5(c)) see the whole expression. + let result = pick_start_mode(&result, use_only_grade1); let result = result.replace("tW", "W"); @@ -1067,42 +1066,42 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str return result.to_string(); fn pick_start_mode(raw_braille: &str, use_only_grade1: bool) -> String { - // Need to decide what the start mode should be - // From http://www.brailleauthority.org/ueb/ueb_math_guidance/final_for_posting_ueb_math_guidance_may_2019_102419.pdf - // Unless a math expression can be correctly represented with only a grade 1 symbol indicator in the first three cells - // or before a single letter standing alone anywhere in the expression, - // begin the expression with a grade 1 word indicator (or a passage indicator if the expression includes spaces) - // Apparently "only a grade 1 symbol..." means at most one grade 1 symbol based on some examples (GTM 6.4, example 4) + // Decide grade 1 indicator placement per ICEB GTM 1.7 (2025). + // BANA's 2026 guidance adopts the same GTM §1.7 rules: + // https://www.brailleauthority.org/sites/default/files/2026-07/Guidance%20on%20Transcribing%20Math%20and%20Science%20in%20UEB%202026.pdf + // GTM 1.7.3 decides indicators per *symbols-sequence* (RUEB 2.1 -- text separated by spaces): + // (a) allow one grade 1 symbol per symbols-sequence, or a grade 1 word indicator if a sequence needs more than one; + // (b) use a grade 1 passage only if three or more symbols-sequences each need a grade 1 symbol or word indicator. + // Grade 1 symbol indicators forced by 'a-j' following a digit are not counted (GTM 1.7.3 note). // debug!("before determining mode: '{}'", raw_braille); - // a bit ugly because we need to store the string if we have cap passage mode - let raw_braille_string = if is_cap_passage_mode_good(raw_braille) {convert_to_cap_passage_mode(raw_braille)} else {String::default()}; - let raw_braille = if raw_braille_string.is_empty() {raw_braille} else {&raw_braille_string}; - if use_only_grade1 { - return remove_unneeded_mode_changes(raw_braille, UEB_Mode::Grade1, UEB_Duration::Passage); - } - let grade2 = remove_unneeded_mode_changes(raw_braille, UEB_Mode::Grade2, UEB_Duration::Symbol); - debug!("Symbol mode: '{}'", grade2); - - if is_grade2_string_ok(&grade2) { - return grade2; + // Capital passage (RUEB §8.5): like word mode's extra 'C' (CC…), passage uses CCC…Ce. + // Count G1 on the original (with capital markers) so standing-alone letters still force + // passage when needed (BANA Ex 5-15), but apply mode changes after stripping C/𝐶 so + // Grade 2 contractions are not blocked by cap_word_mode (chem "ch" → ⠡). + let had_unit_break = raw_braille.contains('𝐖'); + let raw_braille = raw_braille.replace('𝐖', "W"); + let use_cap_passage = is_cap_passage_mode_good(&raw_braille); + let stripped_caps = raw_braille.replace(['C', '𝐶'], ""); + let apply_to = if use_cap_passage { stripped_caps.as_str() } else { raw_braille.as_str() }; + let result = if use_only_grade1 { + remove_unneeded_mode_changes(apply_to, UEB_Mode::Grade1, UEB_Duration::Passage) } else { - // BANA says use g1 word mode if spaces are present, but that's not what their examples do - // A conversation with Ms. DeAndrea from BANA said that they mean use passage mode if ≥3 "segments" (≥2 blanks) - // The G1 Word mode might not be at the start (iceb.rs:omission_3_6_7) - let grade1_word = try_grade1_word_mode(raw_braille); - debug!("Word mode: '{}'", grade1_word); - if !grade1_word.is_empty() { - return grade1_word; - } else { - let grade1_passage = remove_unneeded_mode_changes(raw_braille, UEB_Mode::Grade1, UEB_Duration::Passage); - return "⠰⠰⠰".to_string() + &grade1_passage + "⠰⠄"; - } + gtm_1_7_mode(&raw_braille, apply_to, had_unit_break) + }; + if use_cap_passage { + return convert_to_cap_passage_mode(&result); } + return result; - /// Return true if at least five (= # of cap passage indicators) cap indicators and no lower case letters + /// Return true if capital passage mode should be used (RUEB §8.5 / BANA Ex 5-15). + /// Requires no lowercase letters, and either ≥5 capital indicators (chem / dense caps) + /// or ≥3 letter-bearing symbols-sequences that are fully capitalized. + /// Grade 1 / numeric / other non-letter markers are transparent (do not abort the scan). fn is_cap_passage_mode_good(braille: &str) -> bool { let mut n_caps = 0; + let mut n_letter_seqs = 0; + let mut seq_has_letter = false; let mut is_cap_mode = false; let mut cap_mode = UEB_Duration::Symbol; // real value set when is_cap_mode is set to true let mut chars = braille.chars(); @@ -1115,6 +1114,7 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str if !is_cap_mode { return false; } + seq_has_letter = true; chars.next(); // skip letter if cap_mode == UEB_Duration::Symbol { is_cap_mode = false; @@ -1130,76 +1130,33 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str } n_caps += 1; } else if ch == 'W' || ch == '𝐖' { - if is_cap_mode { - assert!(cap_mode == UEB_Duration::Word); + if seq_has_letter { + n_letter_seqs += 1; + seq_has_letter = false; } is_cap_mode = false; - } else if ch == '1' && is_cap_mode { - break; } + // else: '1', '𝟙', 'N', operators, typeforms, etc. — transparent } - return n_caps > 4; + if seq_has_letter { + n_letter_seqs += 1; + } + return n_caps >= 5 || n_letter_seqs >= 3; } + /// After G1 placement: strip any leftover capital markers and wrap with intermediate + /// `CCC`…`Ce` (same map as word mode: C→⠠, e→⠄ → ⠠⠠⠠…⠠⠄). Applied after + /// remove_unneeded_mode_changes so parsers never treat passage opener as CL letters. + /// If G1 passage is present (⠰⠰⠰…⠰⠄), capital passage goes inside (BANA Ex 5-15). fn convert_to_cap_passage_mode(braille: &str) -> String { - return "⠠⠠⠠".to_string() + &braille.replace(['C', '𝐶'], "") + "⠠⠄"; - } - - /// Return true if the BANA or ICEB guidelines say it is ok to start with grade 2 - fn is_grade2_string_ok(grade2_braille: &str) -> bool { - // BANA says use grade 2 if there is not more than one grade one symbol or single letter standing alone. - // The exact quote from their guidance: - // Unless a math expression can be correctly represented with only a grade 1 symbol indicator in the first three cells - // or before a single letter standing alone anywhere in the expression, - // begin the expression with a grade 1 word indicator - // Note: I modified this slightly to exclude the cap indicator in the count. That allows three more ICEB rule to pass and seems - // like it is a reasonable thing to do. - // Another modification is allow a single G1 indicator to occur after whitespace later on - // because ICEB examples show it and it seems better than going to passage mode if it is the only G1 indicator - - // Because of the 'L's which go away, we have to put a little more work into finding the first three chars - let chars = grade2_braille.chars().collect::>(); - let mut n_real_chars = 0; // actually number of chars - let mut found_g1 = false; - let mut i = 0; - while i < chars.len() { - let ch = chars[i]; - if ch == '1' && !is_forced_grade1(&chars, i) { - if found_g1 { - return false; - } - found_g1 = true; - } else if !"𝐶CLobc".contains(ch) { - if n_real_chars == 2 { - i += 1; - break; // this is the third real char - }; - n_real_chars += 1; - } - i += 1 - } - - // if we find *another* g1 that isn't forced and isn't standing alone, we are done - // I've added a 'follows whitespace' clause for test iceb.rs:omission_3_6_2 to the standing alone rule - // we only allow one standing alone example -- not sure if BANA guidance has this limit, but GTM 11_5_5_3 seems better with it - // Same for GTM 1_7_3_1 (passage mode is mentioned also) - let mut is_standing_alone_already_encountered = false; - let mut is_after_whitespace = false; - while i < chars.len() { - let ch = chars[i]; - if ch == 'W' { - is_after_whitespace = true; - } else if ch == '1' && !is_forced_grade1(&chars, i) { - if is_standing_alone_already_encountered || - ((found_g1 || !is_after_whitespace) && !is_single_letter_on_right(&chars, i)) { - return false; - } - found_g1 = true; - is_standing_alone_already_encountered = true; + let body = braille.replace(['C', '𝐶'], ""); + const G1_START: &str = "⠰⠰⠰"; + const G1_END: &str = "⠰⠄"; + if let Some(rest) = body.strip_prefix(G1_START) + && let Some(mid) = rest.strip_suffix(G1_END) { + return format!("{G1_START}CCC{mid}Ce{G1_END}"); } - i += 1; - } - return true; + return format!("CCC{body}Ce"); } /// Return true if the sequence of chars forces a '1' at the `i`th position @@ -1221,56 +1178,139 @@ fn ueb_cleanup(pref_manager: Ref, raw_braille: String) -> Str return false; } - fn is_single_letter_on_right(chars: &[char], i: usize) -> bool { - fn is_skip_char(ch: char) -> bool { - matches!(ch, 'B' | 'I' | '𝔹' | 'S' | 'T' | 'D' | 'C' | '𝐶' | 's' | 'w') - } + /// Count the number of non-forced grade 1 indicators needed for a single symbols-sequence. + /// (Forced indicators -- 'a-j' following a digit -- are excluded per the GTM 1.7.3 note.) + fn grade1_count(raw_word: &str) -> usize { + let grade2 = remove_unneeded_mode_changes(raw_word, UEB_Mode::Grade2, UEB_Duration::Symbol); + let chars = grade2.chars().collect::>(); + return chars.iter().enumerate() + .filter(|&(i, &ch)| ch == '1' && !is_forced_grade1(&chars, i)) + .count(); + } - // find the first char (if any) - let mut count = 0; // how many letters - let mut i = i+1; + /// True if this symbols-sequence contains a literary English word (4+ letters). + /// GTM 1.7.5: short math names (sin, cos, lim, min, …) and single-letter variables + /// are not treated as words. + fn sequence_contains_word(raw_word: &str) -> bool { + let chars: Vec = raw_word.chars().collect(); + let mut run = 0usize; + let mut i = 0usize; while i < chars.len() { let ch = chars[i]; - if !is_skip_char(ch) { - if ch == 'L' { - if count == 1 { - return false; // found a second letter in the sequence - } - count += 1; - } else { - return count==1; + if ch == 'L' { + run += 1; + i += 1; + if i < chars.len() { + i += 1; // skip the braille cell after 'L' + } + if run >= 4 { + return true; } - i += 2; // eat 'L' and actual letter + } else if ch == 'A' { + run += 1; + i += 1; + if run >= 4 { + return true; + } + } else if is_math_alphabet_typeform(ch) { + // Double-struck/script/fraktur/sans-serif letters are not part of an English word. + let end = math_typeform_item_end(&chars, i); + i = if end > i { end } else { i + 1 }; + run = 0; + } else if matches!(ch, 'C' | '𝐶' | 'G' | 'V' | 'B' | 'I' | 's' | 'w' | 'e') { + i += 1; // letter prefixes / literary typeform — do not break the run } else { + run = 0; i += 1; } } - return true; + false + } + + /// G2 form of a general-fraction sequence when two symbol indicators keep words + /// contracted (GTM 1.7.5(a)). `None` if more than two G1 symbols would remain. + fn g2_two_symbol_form(raw_word: &str) -> Option { + // Only the GTM 1.7.5(a) case: a general fraction whose numerator/denominator + // contain literary words. Superscripts, radicals, etc. keep 1.7.3 word indicators. + if !(raw_word.contains('⠷') && raw_word.contains("⠨⠌")) { + return None; + } + let g2 = remove_unneeded_mode_changes(raw_word, UEB_Mode::Grade2, UEB_Duration::Symbol); + let chars: Vec = g2.chars().collect(); + let n_g1 = chars.iter().enumerate() + .filter(|&(i, &ch)| ch == '1' && !is_forced_grade1(&chars, i)) + .count(); + if n_g1 <= 2 { + Some(g2) + } else { + None + } } - fn try_grade1_word_mode(raw_braille: &str) -> String { - // this isn't quite right, but pretty close -- try splitting at 'W' (words) - // only one of the parts can be in word mode and none of the others can have '1' unless forced - let mut g1_words = Vec::default(); - let mut found_word_mode = false; - for raw_word in raw_braille.split('W') { - let word = remove_unneeded_mode_changes(raw_word, UEB_Mode::Grade2, UEB_Duration::Symbol); - // debug!("try_grade1_word_mode: word='{}'", word); - let word_chars = word.chars().collect::>(); - let needs_word_mode = word_chars.iter().enumerate() - .any(|(i, &ch) | ch == '1' && !is_forced_grade1(&word_chars, i)); - if needs_word_mode { - if found_word_mode { - return "".to_string(); + /// ICEB GTM 1.7 grade 1 indicator placement (per symbols-sequence). + /// GTM 1.7.3: one grade 1 symbol per sequence, or a word indicator if more than one. + /// GTM 1.7.5(a): for a sequence containing word(s), allow two grade 1 symbol + /// indicators when that keeps the words in their usual contracted form + /// (e.g. ⠷…⠾ around work/distance). More than two still uses a word indicator. + /// `count_src` decides passage vs word vs symbol; changes are applied to `apply_to` + /// (may differ when capital markers were stripped for capital-passage mode). + fn gtm_1_7_mode(count_src: &str, apply_to: &str, had_unit_break: bool) -> String { + let count_words: Vec<&str> = count_src.split('W').collect(); + let apply_words: Vec<&str> = apply_to.split('W').collect(); + assert_eq!(count_words.len(), apply_words.len(), + "gtm_1_7_mode: count_src and apply_to must have the same number of symbols-sequences"); + + // Count how many symbols-sequences (whitespace-separated) need a non-forced grade 1 indicator. + let n_seq_needing = count_words.iter().filter(|raw_word| grade1_count(raw_word) >= 1).count(); + + // GTM 1.7.3(b) / 1.7.5(c): use a grade 1 passage if three or more sequences + // each need grade 1. 1.7.5(c) starts the passage at the first such sequence so + // preceding words (e.g. "speed") stay contracted. That delayed start is used when + // spaced units (𝐖) joined the expression; otherwise a passage wraps the whole + // expression (chem, roots, labelled equations). + if n_seq_needing >= 3 { + let first = count_words.iter().position(|w| grade1_count(w) >= 1) + .expect("n_seq_needing >= 3 implies a sequence that needs grade 1"); + let delay_start = had_unit_break && first > 0; + if delay_start { + let prefix: Vec = apply_words[..first].iter() + .map(|w| remove_unneeded_mode_changes(w, UEB_Mode::Grade2, UEB_Duration::Symbol)) + .collect(); + let rest = apply_words[first..].join("W"); + let passage = remove_unneeded_mode_changes(&rest, UEB_Mode::Grade1, UEB_Duration::Passage); + let mut out = prefix.join("W"); + if !out.is_empty() { + out.push('W'); } - found_word_mode = true; - g1_words.push("⠰⠰".to_string() + &remove_unneeded_mode_changes(raw_word, UEB_Mode::Grade1, UEB_Duration::Word) - ); - } else { - g1_words.push(word); + out.push_str("⠰⠰⠰"); + out.push_str(&passage); + out.push_str("⠰⠄"); + return out; } + let grade1_passage = remove_unneeded_mode_changes(apply_to, UEB_Mode::Grade1, UEB_Duration::Passage); + return "⠰⠰⠰".to_string() + &grade1_passage + "⠰⠄"; } - return if found_word_mode {g1_words.join("W")} else {"".to_string()}; + + // GTM 1.7.3(a): per sequence, allow one grade 1 symbol indicator, or a grade 1 word + // indicator if the sequence needs more than one. + let words = count_words.iter().zip(apply_words.iter()) + .map(|(&count_word, &apply_word)| { + let n_g1 = grade1_count(count_word); + if n_g1 >= 2 { + // GTM 1.7.5(a): two symbol indicators if that preserves contractions + if sequence_contains_word(count_word) + && let Some(g2) = g2_two_symbol_form(apply_word) { + g2 + } else { + "⠰⠰".to_string() + &remove_unneeded_mode_changes(apply_word, UEB_Mode::Grade1, UEB_Duration::Word) + } + } else { + // 0 or 1 grade 1 indicators: the grade 2 form leaves a single symbol indicator inline + remove_unneeded_mode_changes(apply_word, UEB_Mode::Grade2, UEB_Duration::Symbol) + } + }) + .collect::>(); + return words.join("W"); } } } @@ -1510,6 +1550,93 @@ fn is_left_intervening_char(ch: char) -> bool { matches!(ch, 'B' | 'I' | '𝔹' | 'S' | 'T' | 'D' | 'C' | '𝐶' | 's' | 'w') } +/// Double-struck / script / fraktur / sans-serif: math alphabets, not literary emphasis. +fn is_math_alphabet_typeform(ch: char) -> bool { + matches!(ch, '𝔹' | 'T' | 'D' | 'S') +} + +/// Advance past one letter with optional capital, Greek, and accent prefixes (`C? G|V? A…? L cell`). +fn skip_one_prefixed_letter(chars: &[char], mut i: usize) -> usize { + if i >= chars.len() { + return i; + } + if matches!(chars[i], 'C' | '𝐶') { + i += 1; + } + if i < chars.len() && matches!(chars[i], 'G' | 'V') { + i += 1; + } + if i < chars.len() && chars[i] == 'A' { + match index_after_accent_to_l(chars, i + 1) { + Some(i_l) => i = i_l, + None => return i, + } + } + if i < chars.len() && chars[i] == 'L' { + i += 1; + if i < chars.len() { + i += 1; // braille cell + } + } + i +} + +/// End index of a math-alphabet typeform item starting at `i` (`𝔹`/`T`/`D`/`S`). +/// `s` covers one letter; `w` covers the typeform word until its terminator. +fn math_typeform_item_end(chars: &[char], i: usize) -> usize { + if i >= chars.len() || !is_math_alphabet_typeform(chars[i]) { + return i; + } + let typeform = chars[i]; + let mut j = i + 1; + let word_mode = j < chars.len() && chars[j] == 'w'; + if j < chars.len() && matches!(chars[j], 's' | 'w') { + j += 1; + } + if word_mode { + loop { + let next = skip_one_prefixed_letter(chars, j); + if next == j { + break; + } + j = next; + } + if j + 1 < chars.len() && chars[j] == typeform && chars[j + 1] == 'e' { + j += 2; + } else if j < chars.len() && chars[j] == 'e' { + j += 1; + } + return j; + } + return skip_one_prefixed_letter(chars, j); +} + +/// RUEB 10.6.2: lower groupsigns "be", "con", "dis" only at the beginning of a word. +/// Beginning of a word = letters-sequence after space, hyphen or dash, optionally with +/// intervening punctuation/indicators from RUEB 2.6.2 (opening brackets/quotes, typeform, +/// capitals). Math operators and fraction indicators are not word boundaries. +/// `word_start` is the index of the first char of a grade-2 letter run ('L', 'C', or 'A'). +fn allows_lower_word_sign_at(chars: &[char], word_start: usize) -> bool { + if word_start >= chars.len() { + return false; + } + if word_start == 0 { + return true; + } + let mut j = word_start; + while j > 0 { + j -= 1; + let ch = chars[j]; + // 2.6.2 intervening symbols (opening punctuation flags, typeform, capitals, etc.) + if is_left_intervening_char(ch) || matches!(ch, 'e' | 'c' | 's' | 'w' | 'o' | 'b' | 'G' | 'V') { + continue; + } + // Must be space, hyphen or dash (RUEB 10.6.2 Note) + return "W𝐖-—―".contains(ch); + } + true +} + /// Return value for use_g1_word_mode() #[derive(Debug, PartialEq)] enum Grade1WordIndicator { @@ -1677,6 +1804,34 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d } // debug!("Grade 2: ch={}, duration: {:?}", ch, duration); match ch { + '𝔹' | 'T' | 'D' | 'S' => { + // Math-alphabet typeform: this letter is not part of an English word + // (GTM 11.6). Close any current contraction run, emit the typeform + // item on its own, then let following letters start a new word. + if let Some(start) = start_g2_letter { + if !cap_word_mode { + result = handle_contractions(&chars, start, i, result); + } + cap_word_mode = false; + start_g2_letter = None; + } + let unit_end = math_typeform_item_end(&chars, i); + // Typeform prefix (`𝔹s`) must precede the grade 1 indicator: ⠈⠆⠰⠠⠗, not ⠰⠈⠆⠠⠗. + let mut letter_start = i + 1; + if letter_start < unit_end && matches!(chars[letter_start], 's' | 'w') { + letter_start += 1; + } + result.extend(chars[i..letter_start].iter().copied()); + if let Some(letter_idx) = chars[i..unit_end].iter().position(|&c| c == 'L') { + let (is_alone, _, n_letters) = stands_alone(&chars, i + letter_idx); + if is_alone && n_letters == 1 { + result.push('1'); + mode = UEB_Mode::Grade1; + } + } + result.extend(chars[letter_start..unit_end].iter().copied()); + i = unit_end; + }, 'L' => { if start_g2_letter.is_none() { start_g2_letter = Some(i); @@ -1758,6 +1913,16 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d } }, '1' => { + // Contract the preceding letter run before consuming '1'. The '1' arm used + // to increment first, so handle_contractions saw "work1" and the whole-word + // patterns `^work$` / `^time$` failed (GTM 1.7.9 work/distance, 1.7.5(a) time). + if let Some(start) = start_g2_letter { + if !cap_word_mode { + result = handle_contractions(&chars, start, i, result); + } + cap_word_mode = false; + start_g2_letter = None; + } result.push(ch); i += 1; mode = UEB_Mode::Grade1; @@ -1778,7 +1943,7 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d _ => { if let Some(start) = start_g2_letter { if !cap_word_mode { - result = handle_contractions(&chars[start..i], result); + result = handle_contractions(&chars, start, i, result); } cap_word_mode = false; start_g2_letter = None; // not start of char sequence @@ -1794,7 +1959,7 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d } if mode != UEB_Mode::Grade2 && !cap_word_mode && let Some(start) = start_g2_letter { - result = handle_contractions(&chars[start..i], result); + result = handle_contractions(&chars, start, i, result); start_g2_letter = None; // not start of char sequence } }, @@ -1814,7 +1979,7 @@ fn remove_unneeded_mode_changes(raw_braille: &str, start_mode: UEB_Mode, start_d } if mode == UEB_Mode::Grade2 && let Some(start) = start_g2_letter { - result = handle_contractions(&chars[start..i], result); + result = handle_contractions(&chars, start, i, result); } return result; @@ -1946,10 +2111,12 @@ fn stands_alone(chars: &[char], i: usize) -> (bool, &[char], usize) { /// Return a modified result if chars can be contracted. /// Otherwise, the original string is returned -fn handle_contractions(chars: &[char], mut result: String) -> String { +fn handle_contractions(full_chars: &[char], start: usize, end: usize, mut result: String) -> String { struct Replacement { pattern: String, - replacement: &'static str + replacement: &'static str, + skip_if_word_in: Option<&'static phf::Set<&'static str>>, + word_start_only: bool, } const ASCII_TO_UNICODE: &[char] = &[ @@ -1968,47 +2135,95 @@ fn handle_contractions(chars: &[char], mut result: String) -> String { return unicode; } + // Whole words where the lower groupsign 'cc' must not apply (10.11.1 compound/function names). + static CC_EXCEPTION_WORDS: phf::Set<&str> = phf_set! { + "L⠁L⠗L⠉L⠉L⠕L⠎", // arccos + "L⠁L⠗L⠉L⠉L⠕L⠎L⠊L⠝L⠑", // arccosine + "L⠁L⠗L⠉L⠉L⠕L⠎L⠓", // arccosh + "L⠁L⠗L⠉L⠉L⠕L⠎L⠑L⠉", // arccosec + "L⠁L⠗L⠉L⠉L⠕L⠎L⠑L⠉L⠁L⠝L⠞", // arccosecant + "L⠁L⠗L⠉L⠉L⠕L⠞", // arccot + "L⠁L⠗L⠉L⠉L⠕L⠞L⠁L⠝L⠛L⠑L⠝L⠞", // arccotangent + "L⠁L⠗L⠉L⠉L⠎L⠉", // arccsc + }; + + // Words where the 'ea' lower groupsign must not apply (re- prefix morpheme boundary). + static EA_EXCEPTION_WORDS: phf::Set<&str> = phf_set! { + "L⠗L⠑L⠁L⠉L⠞L⠁L⠝L⠉L⠑", // reactance + "L⠗L⠑L⠁L⠉L⠞L⠊L⠕L⠝", // reaction + "L⠗L⠑L⠁L⠉L⠞L⠊L⠧L⠊L⠞L⠽", // reactivity + }; + + // Words where "be" is not the first syllable (RUEB 10.6.1 "But:" cases and similar). + static BE_EXCEPTION_WORDS: phf::Set<&str> = phf_set! { + "L⠃L⠑L⠁L⠗L⠊L⠝L⠛", // bearing + "L⠃L⠑L⠝L⠉L⠓L⠍L⠁L⠗L⠅", // benchmark + }; + // It would be much better from an extensibility point of view to read the table in from a file static CONTRACTIONS: LazyLock> = LazyLock::new(|| { vec![ + // 10.9: initial-letter (dot-5) wordsigns -- whole word only + Replacement{ pattern: format!("^{}$", to_unicode_braille("time")), replacement: "⠐⠞", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: format!("^{}$", to_unicode_braille("work")), replacement: "⠐⠺", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: format!("^{}$", to_unicode_braille("leverage")), replacement: "⠇⠐⠑⠁⠛⠑", skip_if_word_in: None, word_start_only: false }, + + // 10.7.1: dot-5 initial-letter contractions (as wordsigns / groupsigns) + Replacement{ pattern: format!("^{}", to_unicode_braille("through")), replacement: "⠐⠹", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: format!("(?PL.){}(?PL.)", to_unicode_braille("part")), replacement: "${s}⠐⠏${e}", skip_if_word_in: None, word_start_only: false }, + // 10.3: Strong contractions - Replacement{ pattern: to_unicode_braille("and"), replacement: "L⠯"}, - Replacement{ pattern: to_unicode_braille("for"), replacement: "L⠿"}, - Replacement{ pattern: to_unicode_braille("of"), replacement: "L⠷"}, - Replacement{ pattern: to_unicode_braille("the"), replacement: "L⠮"}, - Replacement{ pattern: to_unicode_braille("with"), replacement: "L⠾"}, + Replacement{ pattern: to_unicode_braille("and"), replacement: "L⠯", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("for"), replacement: "L⠿", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("of"), replacement: "L⠷", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("the"), replacement: "L⠮", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("with"), replacement: "L⠾", skip_if_word_in: None, word_start_only: false }, + + // 10.6.1-10.6.4 / 10.10.4: lower groupsigns be/con/dis -- only at word start, + // and preferred over other groupsigns (e.g. "distance" is ⠲⠞⠨⠑, not di+st+ance). + Replacement{ pattern: format!("^{}", to_unicode_braille("be")), replacement: "⠆", skip_if_word_in: Some(&BE_EXCEPTION_WORDS), word_start_only: true }, + Replacement{ pattern: format!("^{}", to_unicode_braille("con")), replacement: "⠒", skip_if_word_in: None, word_start_only: true }, + Replacement{ pattern: format!("^{}", to_unicode_braille("dis")), replacement: "⠲", skip_if_word_in: None, word_start_only: true }, - // 10.8: final-letter group signs (this need to precede 'en' and any other shorter contraction) - Replacement{ pattern: "(?PL.)L⠍L⠑L⠝L⠞".to_string(), replacement: "${s}L⠰L⠞" }, // ment - Replacement{ pattern: "(?PL.)L⠞L⠊L⠕L⠝".to_string(), replacement: "${s}L⠰L⠝" } ,// tion + // 10.8: final-letter group signs (these need to precede 'en' and any other shorter contraction) + Replacement{ pattern: "(?PL.)L⠍L⠑L⠝L⠞".to_string(), replacement: "${s}L⠰L⠞", skip_if_word_in: None, word_start_only: false }, // ment + Replacement{ pattern: "(?PL.)L⠞L⠊L⠕L⠝".to_string(), replacement: "${s}L⠰L⠝", skip_if_word_in: None, word_start_only: false }, // tion + Replacement{ pattern: "(?PL.)L⠊L⠞L⠽".to_string(), replacement: "${s}L⠰L⠽", skip_if_word_in: None, word_start_only: false }, // ity + Replacement{ pattern: "(?PL.)L⠁L⠝L⠉L⠑".to_string(), replacement: "${s}L⠨L⠑", skip_if_word_in: None, word_start_only: false }, // ance + Replacement{ pattern: "(?PL.)L⠎L⠊L⠕L⠝".to_string(), replacement: "${s}L⠨L⠝", skip_if_word_in: None, word_start_only: false }, // sion + Replacement{ pattern: "(?PL.)L⠑L⠝L⠉L⠑".to_string(), replacement: "${s}L⠰L⠑", skip_if_word_in: None, word_start_only: false }, // ence + Replacement{ pattern: "(?PL.)L⠝L⠑L⠎L⠎".to_string(), replacement: "${s}L⠰L⠎", skip_if_word_in: None, word_start_only: false }, // ness + Replacement{ pattern: "(?PL.)L⠕L⠥L⠝L⠙".to_string(), replacement: "${s}L⠨L⠙", skip_if_word_in: None, word_start_only: false }, // ound + Replacement{ pattern: "(?PL.)L⠕L⠥L⠝L⠞".to_string(), replacement: "${s}L⠨L⠞", skip_if_word_in: None, word_start_only: false }, // ount + Replacement{ pattern: "(?PL.)L⠇L⠑L⠎L⠎".to_string(), replacement: "${s}L⠨L⠎", skip_if_word_in: None, word_start_only: false }, // less + Replacement{ pattern: "(?PL.)L⠕L⠝L⠛".to_string(), replacement: "${s}L⠰L⠛", skip_if_word_in: None, word_start_only: false }, // ong + Replacement{ pattern: "(?PL.)L⠋L⠥L⠇".to_string(), replacement: "${s}L⠰L⠇", skip_if_word_in: None, word_start_only: false }, // ful // 10.4: Strong group signs - Replacement{ pattern: to_unicode_braille("ch"), replacement: "L⠡"}, - Replacement{ pattern: to_unicode_braille("gh"), replacement: "L⠣"}, - Replacement{ pattern: to_unicode_braille("sh"), replacement: "L⠩"}, - Replacement{ pattern: to_unicode_braille("th"), replacement: "L⠹"}, - Replacement{ pattern: to_unicode_braille("wh"), replacement: "L⠱"}, - Replacement{ pattern: to_unicode_braille("ed"), replacement: "L⠫"}, - Replacement{ pattern: to_unicode_braille("er"), replacement: "L⠻"}, - Replacement{ pattern: to_unicode_braille("ou"), replacement: "L⠳"}, - Replacement{ pattern: to_unicode_braille("ow"), replacement: "L⠪"}, - Replacement{ pattern: to_unicode_braille("st"), replacement: "L⠌"}, - Replacement{ pattern: "(?PL.)L⠊L⠝L⠛".to_string(), replacement: "${s}L⠬" }, // 'ing', not at start - Replacement{ pattern: to_unicode_braille("ar"), replacement: "L⠜"}, + Replacement{ pattern: to_unicode_braille("ch"), replacement: "L⠡", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("gh"), replacement: "L⠣", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("sh"), replacement: "L⠩", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("th"), replacement: "L⠹", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("wh"), replacement: "L⠱", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("ed"), replacement: "L⠫", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("er"), replacement: "L⠻", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("ou"), replacement: "L⠳", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("ow"), replacement: "L⠪", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("st"), replacement: "L⠌", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: "(?PL.)L⠊L⠝L⠛".to_string(), replacement: "${s}L⠬", skip_if_word_in: None, word_start_only: false }, // 'ing', not at start + Replacement{ pattern: to_unicode_braille("ar"), replacement: "L⠜", skip_if_word_in: None, word_start_only: false }, // 10.6.5: Lower group signs preceded and followed by letters // FIX: don't match if after/before a cap letter -- can't use negative pattern (?!...) in regex package - // Note: removed cc because "arccos" shouldn't be contracted (10.11.1), but there is no way to know about compound words - // Add it back after implementing a lookup dictionary of exceptions - Replacement{ pattern: "(?PL.)L⠑L⠁(?PL.)".to_string(), replacement: "${s}L⠂${e}" }, // ea - Replacement{ pattern: "(?PL.)L⠃L⠃(?PL.)".to_string(), replacement: "${s}L⠆${e}" }, // bb - // Replacement{ pattern: "(?PL.)L⠉L⠉(?PL.)".to_string(), replacement: "${s}L⠒${e}" }, // cc - Replacement{ pattern: "(?PL.)L⠋L⠋(?PL.)".to_string(), replacement: "${s}L⠖${e}" }, // ff - Replacement{ pattern: "(?PL.)L⠛L⠛(?PL.)".to_string(), replacement: "${s}L⠶${e}" }, // gg - - // 10.6.8: Lower group signs ("in" also 10.5.4 lower word signs) + Replacement{ pattern: "(?PL.)L⠑L⠁(?PL.)".to_string(), replacement: "${s}L⠂${e}", skip_if_word_in: Some(&EA_EXCEPTION_WORDS), word_start_only: false }, // ea + Replacement{ pattern: "(?PL.)L⠃L⠃(?PL.)".to_string(), replacement: "${s}L⠆${e}", skip_if_word_in: None, word_start_only: false }, // bb + Replacement{ pattern: "(?PL.)L⠉L⠉(?PL.)".to_string(), replacement: "${s}L⠒${e}", skip_if_word_in: Some(&CC_EXCEPTION_WORDS), word_start_only: false }, // cc + Replacement{ pattern: "(?PL.)L⠋L⠋(?PL.)".to_string(), replacement: "${s}L⠖${e}", skip_if_word_in: None, word_start_only: false }, // ff + Replacement{ pattern: "(?PL.)L⠛L⠛(?PL.)".to_string(), replacement: "${s}L⠶${e}", skip_if_word_in: None, word_start_only: false }, // gg + + // 10.6.8: lower group signs; also 10.6.2 word signs when at word start ("sin", etc.) // FIX: these need restrictions about only applying when upper dots are present - Replacement{ pattern: to_unicode_braille("en"), replacement: "⠢"}, - Replacement{ pattern: to_unicode_braille("in"), replacement: "⠔"}, + Replacement{ pattern: to_unicode_braille("en"), replacement: "⠢", skip_if_word_in: None, word_start_only: false }, + Replacement{ pattern: to_unicode_braille("in"), replacement: "⠔", skip_if_word_in: None, word_start_only: false }, ] }); @@ -2016,11 +2231,28 @@ fn handle_contractions(chars: &[char], mut result: String) -> String { static CONTRACTION_PATTERNS: LazyLock = LazyLock::new(|| init_patterns(&CONTRACTIONS)); static CONTRACTION_REGEX: LazyLock> = LazyLock::new(|| init_regex(&CONTRACTIONS)); + let word_start_ok = allows_lower_word_sign_at(full_chars, start); + let chars = &full_chars[start..end]; + // A non-English letter glued to an English word (GTM 1.7.9 Δtime, or a + // double-struck/script/fraktur letter) is not part of the English + // letters-sequence; contract the following word on its own (time → ⠐⠞). + let skip = leading_non_word_letter_len(chars); + if skip > 0 && skip < chars.len() { + return handle_contractions(full_chars, start + skip, end, result); + } let mut chars_as_str = chars.iter().collect::(); + let original_chars_as_str = chars_as_str.clone(); // debug!(" handle_contractions: examine '{}'", &chars_as_str); let matches = CONTRACTION_PATTERNS.matches(&chars_as_str); for i in matches.iter() { let element = &CONTRACTIONS[i]; + if let Some(exceptions) = element.skip_if_word_in + && exceptions.contains(&original_chars_as_str) { + continue; + } + if element.word_start_only && !word_start_ok { + continue; + } // debug!(" replacing '{}' with '{}' in '{}'", element.pattern, element.replacement, &chars_as_str); result.truncate(result.len() - chars_as_str.len()); chars_as_str = CONTRACTION_REGEX[i].replace_all(&chars_as_str, element.replacement).to_string(); @@ -2031,6 +2263,31 @@ fn handle_contractions(chars: &[char], mut result: String) -> String { + fn leading_non_word_letter_len(chars: &[char]) -> usize { + if chars.is_empty() { + return 0; + } + if is_math_alphabet_typeform(chars[0]) { + let end = math_typeform_item_end(chars, 0); + return if end < chars.len() { end } else { 0 }; + } + let mut i = 0; + if i < chars.len() && matches!(chars[i], 'C' | '𝐶') { + i += 1; + } + if i < chars.len() && matches!(chars[i], 'G' | 'V') { + i += 1; + if i < chars.len() && chars[i] == 'L' { + i += 1; + if i < chars.len() { + i += 1; // braille cell + } + return i; + } + } + 0 + } + fn init_patterns(contractions: &[Replacement]) -> RegexSet { let mut vec: Vec<&str> = Vec::with_capacity(contractions.len()); for contraction in contractions { @@ -3808,6 +4065,26 @@ mod tests { }); } + #[test] + fn ueb_lower_word_sign_contractions() -> Result<()> { + return braille_test(|| { + init_braille_mathml("distance")?; + set_preference("BrailleCode", "UEB")?; + let distance = get_braille("")?; + // RUEB 10.6.1 / 10.10.4: distance at word start uses dis lower groupsign + assert_eq!(distance, "⠲⠞⠨⠑", "dis lower groupsign at word start: got '{distance}'"); + // After fraction open (not a RUEB 10.6.2 word start), dis must not apply; st+ance may. + init_braille_mathml("distancetime")?; + let frac = get_braille("")?; + assert!(!frac.contains("⠲"), "dis wrongly used after fraction open: got '{frac}'"); + assert!(frac.contains("⠙⠊⠌⠨⠑") || frac.contains("⠙⠊⠎⠞⠁⠝⠉⠑"), + "expected st+ance or uncontracted distance after fraction open: got '{frac}'"); + init_braille_mathml("include")?; + assert!(get_braille("")?.starts_with("⠔"), "in lower groupsign at word start"); + return Ok(()); + }); + } + #[test] // This test probably should be repeated for each braille code and be taken out of here fn find_mathml_from_braille() -> Result<()> { @@ -3868,7 +4145,7 @@ mod tests { set_preference("BrailleCode", "UEB")?; let _braille = get_braille("")?; - let answers= &[0, 0, 0, 2, 3, 3, 3, 3, 4, 7, 7, 8, 9, 9, 10, 13, 12, 14, 14, 15, 15, 17, 17, 19, 19, 21, 10, 4, 4, 23, 23, 25, 25, 4, 0, 0]; + let answers= &[2, 2, 3, 3, 3, 3, 4, 4, 4, 7, 7, 8, 9, 9, 10, 13, 12, 14, 14, 15, 15, 17, 17, 19, 19, 21, 10, 4, 4, 23, 23, 25, 25, 4]; let answers = answers.map(|num| format!("id-{}", num)); debug!("\n\n*** Testing UEB ***"); for (i, answer) in answers.iter().enumerate() { @@ -3927,4 +4204,367 @@ mod tests { "oL⠈N⠹⠜L⠁cL⠈N⠩⠜L⠃" ); } + + /// Letter-to-Unicode-braille mapping (matches handle_contractions). + const TEST_ASCII_TO_UNICODE: &[char] = &[ + '⠀', '⠮', '⠐', '⠼', '⠫', '⠩', '⠯', '⠄', '⠷', '⠾', '⠡', '⠬', '⠠', '⠤', '⠨', '⠌', + '⠴', '⠂', '⠆', '⠒', '⠲', '⠢', '⠖', '⠶', '⠦', '⠔', '⠱', '⠰', '⠣', '⠿', '⠜', '⠹', + '⠈', '⠁', '⠃', '⠉', '⠙', '⠑', '⠋', '⠛', '⠓', '⠊', '⠚', '⠅', '⠇', '⠍', '⠝', '⠕', + '⠏', '⠟', '⠗', '⠎', '⠞', '⠥', '⠧', '⠺', '⠭', '⠽', '⠵', '⠪', '⠳', '⠻', '⠘', '⠸', + ]; + + fn ascii_to_uncontracted_braille(word: &str) -> String { + word.bytes() + .map(|b| TEST_ASCII_TO_UNICODE[(b.to_ascii_uppercase() - 32) as usize]) + .collect() + } + + /// Run handle_contractions on a lowercase ASCII word (L-cell input) and return Unicode braille. + fn contract_word(word: &str) -> String { + let l_chars: Vec = word.bytes() + .flat_map(|b| { + let ch = TEST_ASCII_TO_UNICODE[(b.to_ascii_uppercase() - 32) as usize]; + ['L', ch] + }) + .collect(); + let input: String = l_chars.iter().collect(); + let output = handle_contractions(&l_chars, 0, l_chars.len(), input); + output.chars().filter(|&c| c != 'L').collect() + } + + /// Grade-2 contraction coverage for technical vocabulary (311 words). + /// Cross-check goldens at https://brailletranslators.com/ (Grade 2 / UEB). + /// Should contract (225): force, work, time, speed, distance, area, height, weight, power, energy, density, gravity, acceleration, length, width, depth, cost, profit, interest, revenue, clearance, conductance, capacitance, resistance, impedance, reactance, variance, tolerance, luminosity, reliability, velocity, viscosity, precision, tension, efficiency, frequency, valence, stiffness, thickness, displacement, concentration, consumption, duration, elevation, fraction, friction, inflation, iteration, population, position, potential, production, resolution, rotation, charge, chord, pitch, growth, head, heat, reach, shear, margin, salary, offset, income, input, inventory, current, error, leverage, temperature, turnover, accuracy, breadth, strength, spread, discount, count, version, inductance, intensity, interval, perimeter, probability, utility, validity, parity, permeability, proportion, uncertainty, circumference, capacity, deceleration, dilution, enthalpy, entropy, equity, expense, gradient, headroom, inertia, latency, longitude, permittivity, period, principal, sensitivity, stress, throughput, thrust, wavelength, absorption, activation, activity, admittance, affinity, albedo, aperture, attenuation, average, bandwidth, baseline, bearing, benchmark, boiling, boundary, cohesion, compliance, compression, conductivity, coverage, damping, deflection, departure, depreciation, deviation, diffusion, dispersion, dissipation, distortion, divergence, downforce, elasticity, emissivity, emission, erosion, evaporation, expansion, expectation, extent, feedback, fidelity, filament, hardness, humidity, hysteresis, illuminance, incidence, index, inflow, influx, inhibition, injection, irradiance, kinetic, leakage, luminance, maturity, mean, median, melting, minimum, mobility, molarity, moisture, opacity, oscillation, outflow, overlap, parallax, parameter, peak, percentile, percentage, polarization, propagation, purity, quality, quantity, quenching, quotient, radiance, radiation, reaction, reactivity, redshift, reflectance, reflection, refraction, reluctance, remanence, resistivity, resonance, restitution, retardation, rigidity, salinity, saturation, scalar, scattering, separation, shrinkage, similarity, battery, diameter, epoch, gain, jitter, joule, momentum, shift, step, stride, zenith + /// Should not contract (86): mass, volume, base, rate, drag, drift, gap, lag, loss, pace, radius, range, ratio, risk, run, scale, size, slope, tax, torque, capital, impulse, latitude, magnitude, premium, pressure, response, return, trajectory, voltage, aspect, backlog, curvature, dosage, dose, equilibrium, excess, exposure, fatigue, hydraulic, lifetime, likelihood, maximum, metric, orbit, osmosis, pulse, quanta, quantum, regret, residual, ripple, root, rotor, sag, secant, signal, altitude, amplitude, angle, bias, bitrate, budget, bulk, decay, deficit, degree, delay, duty, lift, limit, load, modulus, payload, phase, price, sample, skew, slack, span, supply, total, value, vector, wage, yield + /// Note: arccos (cc exception, partial ar groupsign) is covered in tests/braille/UEB/other.rs contractions_1. + #[test] + fn ueb_technical_word_contractions() { + const SHOULD_CONTRACT: &[(&str, &str)] = &[ + ("force", "⠿⠉⠑"), + ("work", "⠐⠺"), + ("time", "⠐⠞"), + ("speed", "⠎⠏⠑⠫"), + ("distance", "⠲⠞⠨⠑"), + ("area", "⠜⠑⠁"), + ("height", "⠓⠑⠊⠣⠞"), + ("weight", "⠺⠑⠊⠣⠞"), + ("power", "⠏⠪⠻"), + ("energy", "⠢⠻⠛⠽"), + ("density", "⠙⠢⠎⠰⠽"), + ("gravity", "⠛⠗⠁⠧⠰⠽"), + ("acceleration", "⠁⠒⠑⠇⠻⠁⠰⠝"), + ("length", "⠇⠢⠛⠹"), + ("width", "⠺⠊⠙⠹"), + ("depth", "⠙⠑⠏⠹"), + ("cost", "⠉⠕⠌"), + ("profit", "⠏⠗⠷⠊⠞"), + ("interest", "⠔⠞⠻⠑⠌"), + ("revenue", "⠗⠑⠧⠢⠥⠑"), + ("clearance", "⠉⠇⠑⠜⠨⠑"), + ("conductance", "⠒⠙⠥⠉⠞⠨⠑"), + ("capacitance", "⠉⠁⠏⠁⠉⠊⠞⠨⠑"), + ("resistance", "⠗⠑⠎⠊⠌⠨⠑"), + ("impedance", "⠊⠍⠏⠫⠨⠑"), + ("reactance", "⠗⠑⠁⠉⠞⠨⠑"), + ("variance", "⠧⠜⠊⠨⠑"), + ("tolerance", "⠞⠕⠇⠻⠨⠑"), + ("luminosity", "⠇⠥⠍⠔⠕⠎⠰⠽"), + ("reliability", "⠗⠑⠇⠊⠁⠃⠊⠇⠰⠽"), + ("velocity", "⠧⠑⠇⠕⠉⠰⠽"), + ("viscosity", "⠧⠊⠎⠉⠕⠎⠰⠽"), + ("precision", "⠏⠗⠑⠉⠊⠨⠝"), + ("tension", "⠞⠢⠨⠝"), + ("efficiency", "⠑⠖⠊⠉⠊⠢⠉⠽"), + ("frequency", "⠋⠗⠑⠟⠥⠢⠉⠽"), + ("valence", "⠧⠁⠇⠰⠑"), + ("stiffness", "⠌⠊⠖⠰⠎"), + ("thickness", "⠹⠊⠉⠅⠰⠎"), + ("displacement", "⠲⠏⠇⠁⠉⠑⠰⠞"), + ("concentration", "⠒⠉⠢⠞⠗⠁⠰⠝"), + ("consumption", "⠒⠎⠥⠍⠏⠰⠝"), + ("duration", "⠙⠥⠗⠁⠰⠝"), + ("elevation", "⠑⠇⠑⠧⠁⠰⠝"), + ("fraction", "⠋⠗⠁⠉⠰⠝"), + ("friction", "⠋⠗⠊⠉⠰⠝"), + ("inflation", "⠔⠋⠇⠁⠰⠝"), + ("iteration", "⠊⠞⠻⠁⠰⠝"), + ("population", "⠏⠕⠏⠥⠇⠁⠰⠝"), + ("position", "⠏⠕⠎⠊⠰⠝"), + ("potential", "⠏⠕⠞⠢⠞⠊⠁⠇"), + ("production", "⠏⠗⠕⠙⠥⠉⠰⠝"), + ("resolution", "⠗⠑⠎⠕⠇⠥⠰⠝"), + ("rotation", "⠗⠕⠞⠁⠰⠝"), + ("charge", "⠡⠜⠛⠑"), + ("chord", "⠡⠕⠗⠙"), + ("pitch", "⠏⠊⠞⠡"), + ("growth", "⠛⠗⠪⠹"), + ("head", "⠓⠂⠙"), + ("heat", "⠓⠂⠞"), + ("reach", "⠗⠂⠡"), + ("shear", "⠩⠑⠜"), + ("margin", "⠍⠜⠛⠔"), + ("salary", "⠎⠁⠇⠜⠽"), + ("offset", "⠷⠋⠎⠑⠞"), + ("income", "⠔⠉⠕⠍⠑"), + ("input", "⠔⠏⠥⠞"), + ("inventory", "⠔⠧⠢⠞⠕⠗⠽"), + ("current", "⠉⠥⠗⠗⠢⠞"), + ("error", "⠻⠗⠕⠗"), + ("leverage", "⠇⠐⠑⠁⠛⠑"), + ("temperature", "⠞⠑⠍⠏⠻⠁⠞⠥⠗⠑"), + ("turnover", "⠞⠥⠗⠝⠕⠧⠻"), + ("accuracy", "⠁⠒⠥⠗⠁⠉⠽"), + ("breadth", "⠃⠗⠂⠙⠹"), + ("strength", "⠌⠗⠢⠛⠹"), + ("spread", "⠎⠏⠗⠂⠙"), + ("discount", "⠲⠉⠨⠞"), + ("count", "⠉⠨⠞"), + ("version", "⠧⠻⠨⠝"), + ("inductance", "⠔⠙⠥⠉⠞⠨⠑"), + ("intensity", "⠔⠞⠢⠎⠰⠽"), + ("interval", "⠔⠞⠻⠧⠁⠇"), + ("perimeter", "⠏⠻⠊⠍⠑⠞⠻"), + ("probability", "⠏⠗⠕⠃⠁⠃⠊⠇⠰⠽"), + ("utility", "⠥⠞⠊⠇⠰⠽"), + ("validity", "⠧⠁⠇⠊⠙⠰⠽"), + ("parity", "⠏⠜⠰⠽"), + ("permeability", "⠏⠻⠍⠂⠃⠊⠇⠰⠽"), + ("proportion", "⠏⠗⠕⠏⠕⠗⠰⠝"), + ("uncertainty", "⠥⠝⠉⠻⠞⠁⠔⠞⠽"), + ("circumference", "⠉⠊⠗⠉⠥⠍⠋⠻⠰⠑"), + ("capacity", "⠉⠁⠏⠁⠉⠰⠽"), + ("deceleration", "⠙⠑⠉⠑⠇⠻⠁⠰⠝"), + ("dilution", "⠙⠊⠇⠥⠰⠝"), + ("enthalpy", "⠢⠹⠁⠇⠏⠽"), + ("entropy", "⠢⠞⠗⠕⠏⠽"), + ("equity", "⠑⠟⠥⠰⠽"), + ("expense", "⠑⠭⠏⠢⠎⠑"), + ("gradient", "⠛⠗⠁⠙⠊⠢⠞"), + ("headroom", "⠓⠂⠙⠗⠕⠕⠍"), + ("inertia", "⠔⠻⠞⠊⠁"), + ("latency", "⠇⠁⠞⠢⠉⠽"), + ("longitude", "⠇⠰⠛⠊⠞⠥⠙⠑"), + ("permittivity", "⠏⠻⠍⠊⠞⠞⠊⠧⠰⠽"), + ("period", "⠏⠻⠊⠕⠙"), + ("principal", "⠏⠗⠔⠉⠊⠏⠁⠇"), + ("sensitivity", "⠎⠢⠎⠊⠞⠊⠧⠰⠽"), + ("stress", "⠌⠗⠑⠎⠎"), + ("throughput", "⠐⠹⠏⠥⠞"), + ("thrust", "⠹⠗⠥⠌"), + ("wavelength", "⠺⠁⠧⠑⠇⠢⠛⠹"), + ("absorption", "⠁⠃⠎⠕⠗⠏⠰⠝"), + ("activation", "⠁⠉⠞⠊⠧⠁⠰⠝"), + ("activity", "⠁⠉⠞⠊⠧⠰⠽"), + ("admittance", "⠁⠙⠍⠊⠞⠞⠨⠑"), + ("affinity", "⠁⠖⠔⠰⠽"), + ("albedo", "⠁⠇⠃⠫⠕"), + ("aperture", "⠁⠏⠻⠞⠥⠗⠑"), + ("attenuation", "⠁⠞⠞⠢⠥⠁⠰⠝"), + ("average", "⠁⠧⠻⠁⠛⠑"), + ("bandwidth", "⠃⠯⠺⠊⠙⠹"), + ("baseline", "⠃⠁⠎⠑⠇⠔⠑"), + ("bearing", "⠃⠑⠜⠬"), + ("benchmark", "⠃⠢⠡⠍⠜⠅"), + ("boiling", "⠃⠕⠊⠇⠬"), + ("boundary", "⠃⠨⠙⠜⠽"), + ("cohesion", "⠉⠕⠓⠑⠨⠝"), + ("compliance", "⠉⠕⠍⠏⠇⠊⠨⠑"), + ("compression", "⠉⠕⠍⠏⠗⠑⠎⠨⠝"), + ("conductivity", "⠒⠙⠥⠉⠞⠊⠧⠰⠽"), + ("coverage", "⠉⠕⠧⠻⠁⠛⠑"), + ("damping", "⠙⠁⠍⠏⠬"), + ("deflection", "⠙⠑⠋⠇⠑⠉⠰⠝"), + ("departure", "⠙⠑⠐⠏⠥⠗⠑"), + ("depreciation", "⠙⠑⠏⠗⠑⠉⠊⠁⠰⠝"), + ("deviation", "⠙⠑⠧⠊⠁⠰⠝"), + ("diffusion", "⠙⠊⠖⠥⠨⠝"), + ("dispersion", "⠲⠏⠻⠨⠝"), + ("dissipation", "⠲⠎⠊⠏⠁⠰⠝"), + ("distortion", "⠲⠞⠕⠗⠰⠝"), + ("divergence", "⠙⠊⠧⠻⠛⠰⠑"), + ("downforce", "⠙⠪⠝⠿⠉⠑"), + ("elasticity", "⠑⠇⠁⠌⠊⠉⠰⠽"), + ("emissivity", "⠑⠍⠊⠎⠎⠊⠧⠰⠽"), + ("emission", "⠑⠍⠊⠎⠨⠝"), + ("erosion", "⠻⠕⠨⠝"), + ("evaporation", "⠑⠧⠁⠏⠕⠗⠁⠰⠝"), + ("expansion", "⠑⠭⠏⠁⠝⠨⠝"), + ("expectation", "⠑⠭⠏⠑⠉⠞⠁⠰⠝"), + ("extent", "⠑⠭⠞⠢⠞"), + ("feedback", "⠋⠑⠫⠃⠁⠉⠅"), + ("fidelity", "⠋⠊⠙⠑⠇⠰⠽"), + ("filament", "⠋⠊⠇⠁⠰⠞"), + ("hardness", "⠓⠜⠙⠰⠎"), + ("humidity", "⠓⠥⠍⠊⠙⠰⠽"), + ("hysteresis", "⠓⠽⠌⠻⠑⠎⠊⠎"), + ("illuminance", "⠊⠇⠇⠥⠍⠔⠨⠑"), + ("incidence", "⠔⠉⠊⠙⠰⠑"), + ("index", "⠔⠙⠑⠭"), + ("inflow", "⠔⠋⠇⠪"), + ("influx", "⠔⠋⠇⠥⠭"), + ("inhibition", "⠔⠓⠊⠃⠊⠰⠝"), + ("injection", "⠔⠚⠑⠉⠰⠝"), + ("irradiance", "⠊⠗⠗⠁⠙⠊⠨⠑"), + ("kinetic", "⠅⠔⠑⠞⠊⠉"), + ("leakage", "⠇⠂⠅⠁⠛⠑"), + ("luminance", "⠇⠥⠍⠔⠨⠑"), + ("maturity", "⠍⠁⠞⠥⠗⠰⠽"), + ("mean", "⠍⠂⠝"), + ("median", "⠍⠫⠊⠁⠝"), + ("melting", "⠍⠑⠇⠞⠬"), + ("minimum", "⠍⠔⠊⠍⠥⠍"), + ("mobility", "⠍⠕⠃⠊⠇⠰⠽"), + ("molarity", "⠍⠕⠇⠜⠰⠽"), + ("moisture", "⠍⠕⠊⠌⠥⠗⠑"), + ("opacity", "⠕⠏⠁⠉⠰⠽"), + ("oscillation", "⠕⠎⠉⠊⠇⠇⠁⠰⠝"), + ("outflow", "⠳⠞⠋⠇⠪"), + ("overlap", "⠕⠧⠻⠇⠁⠏"), + ("parallax", "⠏⠜⠁⠇⠇⠁⠭"), + ("parameter", "⠏⠜⠁⠍⠑⠞⠻"), + ("peak", "⠏⠂⠅"), + ("percentile", "⠏⠻⠉⠢⠞⠊⠇⠑"), + ("percentage", "⠏⠻⠉⠢⠞⠁⠛⠑"), + ("polarization", "⠏⠕⠇⠜⠊⠵⠁⠰⠝"), + ("propagation", "⠏⠗⠕⠏⠁⠛⠁⠰⠝"), + ("purity", "⠏⠥⠗⠰⠽"), + ("quality", "⠟⠥⠁⠇⠰⠽"), + ("quantity", "⠟⠥⠁⠝⠞⠰⠽"), + ("quenching", "⠟⠥⠢⠡⠬"), + ("quotient", "⠟⠥⠕⠞⠊⠢⠞"), + ("radiance", "⠗⠁⠙⠊⠨⠑"), + ("radiation", "⠗⠁⠙⠊⠁⠰⠝"), + ("reaction", "⠗⠑⠁⠉⠰⠝"), + ("reactivity", "⠗⠑⠁⠉⠞⠊⠧⠰⠽"), + ("redshift", "⠗⠫⠩⠊⠋⠞"), + ("reflectance", "⠗⠑⠋⠇⠑⠉⠞⠨⠑"), + ("reflection", "⠗⠑⠋⠇⠑⠉⠰⠝"), + ("refraction", "⠗⠑⠋⠗⠁⠉⠰⠝"), + ("reluctance", "⠗⠑⠇⠥⠉⠞⠨⠑"), + ("remanence", "⠗⠑⠍⠁⠝⠰⠑"), + ("resistivity", "⠗⠑⠎⠊⠌⠊⠧⠰⠽"), + ("resonance", "⠗⠑⠎⠕⠝⠨⠑"), + ("restitution", "⠗⠑⠌⠊⠞⠥⠰⠝"), + ("retardation", "⠗⠑⠞⠜⠙⠁⠰⠝"), + ("rigidity", "⠗⠊⠛⠊⠙⠰⠽"), + ("salinity", "⠎⠁⠇⠔⠰⠽"), + ("saturation", "⠎⠁⠞⠥⠗⠁⠰⠝"), + ("scalar", "⠎⠉⠁⠇⠜"), + ("scattering", "⠎⠉⠁⠞⠞⠻⠬"), + ("separation", "⠎⠑⠏⠜⠁⠰⠝"), + ("shrinkage", "⠩⠗⠔⠅⠁⠛⠑"), + ("similarity", "⠎⠊⠍⠊⠇⠜⠰⠽"), + ("battery", "⠃⠁⠞⠞⠻⠽"), + ("diameter", "⠙⠊⠁⠍⠑⠞⠻"), + ("epoch", "⠑⠏⠕⠡"), + ("gain", "⠛⠁⠔"), + ("jitter", "⠚⠊⠞⠞⠻"), + ("joule", "⠚⠳⠇⠑"), + ("momentum", "⠍⠕⠰⠞⠥⠍"), + ("shift", "⠩⠊⠋⠞"), + ("step", "⠌⠑⠏"), + ("stride", "⠌⠗⠊⠙⠑"), + ("zenith", "⠵⠢⠊⠹"), + ]; + const SHOULD_NOT_CONTRACT: &[&str] = &[ + "mass", "volume", "base", "rate", "drag", "drift", "gap", "lag", "loss", "pace", + "radius", "range", "ratio", "risk", "run", "scale", "size", "slope", "tax", "torque", + "capital", "impulse", "latitude", "magnitude", "premium", "pressure", "response", "return", + "trajectory", "voltage", "aspect", "backlog", "curvature", "dosage", "dose", "equilibrium", + "excess", "exposure", "fatigue", "hydraulic", "lifetime", "likelihood", "maximum", "metric", + "orbit", "osmosis", "pulse", "quanta", "quantum", "regret", "residual", "ripple", "root", + "rotor", "sag", "secant", "signal", "altitude", "amplitude", "angle", "bias", "bitrate", + "budget", "bulk", "decay", "deficit", "degree", "delay", "duty", "lift", "limit", "load", + "modulus", "payload", "phase", "price", "sample", "skew", "slack", "span", "supply", + "total", "value", "vector", "wage", "yield", + ]; + + for &(word, expected) in SHOULD_CONTRACT { + let got = contract_word(word); + assert_eq!(expected, got, "word '{word}'"); + assert_ne!(ascii_to_uncontracted_braille(word), got, "word '{word}' should contract"); + } + for &word in SHOULD_NOT_CONTRACT { + let got = contract_word(word); + let uncontracted = ascii_to_uncontracted_braille(word); + assert_eq!(uncontracted, got, "word '{word}' should not contract"); + } + } + + #[test] + #[ignore] + fn ueb_technical_word_contractions_probe_batch2() { + let try_contract = [ + "circumference", "capacity", "deceleration", "dilution", "enthalpy", "entropy", "equity", "expense", + "gradient", "headroom", "inertia", "latency", "longitude", "permittivity", "period", "principal", + "sensitivity", "stress", "throughput", "thrust", "wavelength", "absorption", "activation", "activity", + "admittance", "affinity", "albedo", "aperture", "attenuation", "average", "bandwidth", "baseline", + "bearing", "benchmark", "boiling", "boundary", "cohesion", "compliance", "compression", "conductivity", + "coverage", "damping", "deflection", "departure", "depreciation", "deviation", "diffusion", "dispersion", + "dissipation", "distortion", "divergence", "downforce", "elasticity", "emissivity", "emission", "erosion", + "evaporation", "expansion", "expectation", "extent", "feedback", "fidelity", "filament", "hardness", + "humidity", "hysteresis", "illuminance", "incidence", "index", "inflow", "influx", "inhibition", + "injection", "irradiance", "kinetic", "leakage", "luminance", "maturity", "mean", "median", "melting", + "minimum", "mobility", "molarity", "moisture", "opacity", "oscillation", "outflow", "overlap", "parallax", + "parameter", "peak", "percentile", "percentage", "polarization", "propagation", "purity", "quality", + "quantity", "quenching", "quotient", "radiance", "radiation", "reaction", "reactivity", "redshift", + "reflectance", "reflection", "refraction", "reluctance", "remanence", "resistivity", "resonance", + "restitution", "retardation", "rigidity", "salinity", "saturation", "scalar", "scattering", "separation", + "shrinkage", "similarity", "battery", "diameter", "epoch", "gain", "jitter", "joule", "momentum", "shift", + "step", "stride", "zenith", + ]; + let try_not = [ + "capital", "impulse", "latitude", "magnitude", "premium", "pressure", "response", "return", "trajectory", + "voltage", "aspect", "backlog", "curvature", "dosage", "dose", "equilibrium", "excess", "exposure", + "fatigue", "hydraulic", "lifetime", "likelihood", "maximum", "metric", "orbit", "osmosis", "pulse", + "quanta", "quantum", "regret", "residual", "ripple", "root", "rotor", "sag", "secant", "signal", + "altitude", "amplitude", "angle", "bias", "bitrate", "budget", "bulk", "decay", "deficit", "degree", + "delay", "duty", "lift", "limit", "load", "modulus", "payload", "phase", "price", "sample", "skew", + "slack", "span", "supply", "total", "value", "vector", "wage", "yield", + ]; + let mut out = String::new(); + for w in try_contract { + let c = contract_word(w); + out.push_str(&format!("(\"{w}\", \"{c}\"),\n")); + } + for w in try_not { + out.push_str(&format!("// no: {w}\n")); + } + let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("notes/_batch2_goldens.txt"); + std::fs::write(path, out).unwrap(); + } + + #[test] + #[ignore] + fn ueb_technical_word_contractions_probe() { + let should_contract = [ + "force", "work", "time", "speed", "distance", "area", "height", "weight", "power", "energy", + "density", "gravity", "acceleration", "length", "width", "depth", "cost", "profit", "interest", "revenue", + "clearance", "conductance", "capacitance", "resistance", "impedance", "reactance", "variance", "tolerance", + "luminosity", "reliability", "velocity", "viscosity", "precision", "tension", "efficiency", "frequency", + "valence", "stiffness", "thickness", "displacement", "concentration", "consumption", "duration", "elevation", + "fraction", "friction", "inflation", "iteration", "population", "position", "potential", "production", + "resolution", "rotation", "charge", "chord", "pitch", "growth", "head", "heat", "reach", "shear", "margin", + "salary", "offset", "income", "input", "inventory", "current", "error", "leverage", "temperature", + "turnover", "accuracy", "breadth", "strength", "spread", "discount", "count", "version", "inductance", + "intensity", "interval", "perimeter", "probability", "utility", "validity", "parity", "permeability", + "proportion", "uncertainty", + ]; + let should_not = [ + "mass", "volume", "base", "rate", "drag", "drift", "gap", "lag", "loss", "pace", + "radius", "range", "ratio", "risk", "run", "scale", "size", "slope", "tax", "torque", + ]; + eprintln!("=== SHOULD CONTRACT ==="); + for w in should_contract { + let c = contract_word(w); + let u = ascii_to_uncontracted_braille(w); + eprintln!("(\"{w}\", \"{c}\"), // uncontracted={u} changed={}", c != u); + } + eprintln!("=== SHOULD NOT CONTRACT ==="); + for w in should_not { + let c = contract_word(w); + let u = ascii_to_uncontracted_braille(w); + eprintln!("{w}: contracted={c} uncontracted={u} ok={}", c == u); + } + } } diff --git a/tests/braille/UEB/iceb.rs b/tests/braille/UEB/iceb.rs index 3bd48b19b..70eb878f8 100644 --- a/tests/braille/UEB/iceb.rs +++ b/tests/braille/UEB/iceb.rs @@ -1,7 +1,8 @@ // UEB tests for the basic mathml tags -// Initial tests are from BANA guidelines, mostly about initial chars for code switching -// http://www.brailleauthority.org/ueb/ueb_math_guidance/final_for_posting_ueb_math_guidance_may_2019_102419.pdf -// These tests start with "bana_" +// BANA guidance (2026; replaces 2019 provisional): +// https://www.brailleauthority.org/sites/default/files/2026-07/Guidance%20on%20Transcribing%20Math%20and%20Science%20in%20UEB%202026.pdf +// Older `bana_*` names map from 2019 section numbers where still valid; `bana2026_*` are new 2026 examples. +// Grade 1 indicators follow ICEB GTM §1.7 (adopted by BANA 2026). // // Many come from (refer to) https://iceb.org/guidelines_for_technical_material_2014.pdf // For example, "fraction_6_1_1" is a fraction example from section 6.1, and is the first example there. @@ -10,7 +11,8 @@ use anyhow::Result; #[test] fn bana_2_1() -> Result<()> { - let expr = "6=1×2×3 + // BANA 2026 Ex 2-1 (spacing of signs) + let expr = "6=1×2×3 =1+2+3"; test_braille("UEB", expr, "⠼⠋⠀⠐⠶⠀⠼⠁⠐⠦⠼⠃⠐⠦⠼⠉⠀⠐⠶⠀⠼⠁⠐⠖⠼⠃⠐⠖⠼⠉")?; return Ok(()); @@ -19,6 +21,7 @@ fn bana_2_1() -> Result<()> { #[test] fn bana_5_1() -> Result<()> { + // BANA 2026 Ex 5-1 let expr = "x+y=6"; test_braille("UEB", expr, "⠭⠐⠖⠽⠀⠐⠶⠀⠼⠋")?; return Ok(()); @@ -27,6 +30,7 @@ fn bana_5_1() -> Result<()> { #[test] fn bana_5_2() -> Result<()> { + // BANA 2026 Ex 5-7 let expr = "x2+y2=C"; test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠖⠽⠔⠼⠃⠀⠐⠶⠀⠰⠠⠉")?; return Ok(()); @@ -35,6 +39,7 @@ fn bana_5_2() -> Result<()> { #[test] fn bana_5_3() -> Result<()> { + // BANA 2026 Ex 5-10 let expr = "ab+cd"; test_braille("UEB", expr, "⠰⠰⠷⠁⠨⠌⠃⠾⠐⠖⠷⠉⠨⠌⠙⠾")?; return Ok(()); @@ -43,26 +48,27 @@ fn bana_5_3() -> Result<()> { #[test] fn bana_5_4() -> Result<()> { - let expr = "an×am= + // BANA 2026 Ex 5-14 (GTM 1.7: word indicator per sequence, not passage) + let expr = "an×am= an+m"; - test_braille("UEB", expr, "⠰⠰⠰⠁⠔⠝⠐⠦⠁⠔⠍⠀⠐⠶⠀⠁⠔⠣⠝⠐⠖⠍⠜⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠁⠔⠝⠐⠦⠁⠔⠍⠀⠐⠶⠀⠰⠰⠁⠔⠣⠝⠐⠖⠍⠜")?; return Ok(()); } #[test] fn bana_5_5() -> Result<()> { - let expr = "logxy"; - // BANA example contradicts GTM 9.2 that says don't use a space after a function name if there is an intervening indicator. - // Corrected: removed the space and the G1 indicator needed if a space were inserted - test_braille("UEB", expr, "⠰⠰⠇⠕⠛⠢⠭⠽")?; + // BANA 2026 Ex 5-8 (replaces 2019 log_x y example) + let expr = "log2x+logx"; + test_braille("UEB", expr, "⠇⠕⠛⠰⠢⠼⠃⠭⠐⠖⠇⠕⠛⠀⠰⠭")?; return Ok(()); } #[test] fn bana_5a_1() -> Result<()> { - let expr = "100°F"; + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice + let expr = "100°F"; test_braille("UEB", expr, "⠼⠁⠚⠚⠘⠚⠠⠋")?; return Ok(()); @@ -70,7 +76,17 @@ fn bana_5a_1() -> Result<()> { #[test] fn bana_5a_1_baseline() -> Result<()> { - let expr = "100°F"; + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice + let expr = "100°F"; + test_braille("UEB", expr, "⠼⠁⠚⠚⠘⠚⠠⠋")?; + return Ok(()); + +} + +#[test] +fn bana_5a_1_baseline_unit() -> Result<()> { + // Same as bana_5a_1_baseline; unit marked via data-intent-property + let expr = "100°F"; test_braille("UEB", expr, "⠼⠁⠚⠚⠘⠚⠠⠋")?; return Ok(()); @@ -78,22 +94,43 @@ fn bana_5a_1_baseline() -> Result<()> { #[test] fn bana_5a_2() -> Result<()> { + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice let expr = "25 km2"; test_braille("UEB", expr, "⠼⠃⠑⠀⠅⠍⠰⠔⠼⠃")?; return Ok(()); } +#[test] +fn bana_5a_2_unit() -> Result<()> { + // Same as bana_5a_2; unit marked via data-intent-property + let expr = "25 km2"; + test_braille("UEB", expr, "⠼⠃⠑⠀⠅⠍⠰⠔⠼⠃")?; + return Ok(()); + +} + #[test] fn bana_5a_2_mtext() -> Result<()> { + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice let expr = "25 km2"; test_braille("UEB", expr, "⠼⠃⠑⠀⠅⠍⠰⠔⠼⠃")?; return Ok(()); } +#[test] +fn bana_5a_2_mtext_unit() -> Result<()> { + // Same as bana_5a_2_mtext; unit marked via data-intent-property + let expr = "25 km2"; + test_braille("UEB", expr, "⠼⠃⠑⠀⠅⠍⠰⠔⠼⠃")?; + return Ok(()); + +} + #[test] fn bana_5a_3() -> Result<()> { + // Former 2019 §5(a) units example (dropped from BANA 2026); kept as unit-spacing practice let expr = "6 m  s-1"; test_braille("UEB", expr, "⠼⠋⠀⠰⠍⠀⠰⠰⠎⠔⠣⠐⠤⠼⠁⠜")?; @@ -101,11 +138,183 @@ fn bana_5a_3() -> Result<()> { } +#[test] +fn bana_5a_3_unit() -> Result<()> { + // Same as bana_5a_3; unit marked via data-intent-property + let expr = "6 m  + s-1"; + test_braille("UEB", expr, "⠼⠋⠀⠰⠍⠀⠰⠰⠎⠔⠣⠐⠤⠼⠁⠜")?; + return Ok(()); + +} + #[test] fn bana_6_1() -> Result<()> { + // Punctuation before G1 terminator (BANA 2026 §5.4 / GTM 1.7.3b note) let expr = "x+y=z =t2."; - test_braille("UEB", expr, "⠰⠰⠰⠭⠐⠖⠽⠀⠐⠶⠀⠵⠀⠐⠶⠀⠞⠔⠼⠃⠲⠰⠄")?; + test_braille("UEB", expr, "⠭⠐⠖⠽⠀⠐⠶⠀⠰⠵⠀⠐⠶⠀⠞⠰⠔⠼⠃⠲")?; + return Ok(()); + +} + +// --- BANA 2026 examples not covered by older bana_* tests --- + +#[test] +fn bana2026_2_2() -> Result<()> { + // BANA 2026 Ex 2-2: spaced operation signs for beginning readers + let expr = "6-3=_"; + test_braille_prefs("UEB", vec![("UseSpacesAroundAllOperators", "true")], expr, "⠼⠋⠀⠐⠤⠀⠼⠉⠀⠐⠶⠀⠨⠤")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_2() -> Result<()> { + // BANA 2026 Ex 5-2: words with contractions in a technical expression + let expr = "Surface area=2lh+2lw+2wh"; + test_braille("UEB", expr, "⠠⠎⠥⠗⠋⠁⠉⠑⠀⠜⠑⠁⠀⠐⠶⠀⠼⠃⠇⠓⠐⠖⠼⠃⠇⠺⠐⠖⠼⠃⠺⠓")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_3() -> Result<()> { + // BANA 2026 Ex 5-3 + let expr = "NaCl+H2O"; + test_braille("UEB", expr, "⠠⠝⠁⠠⠉⠇⠐⠖⠠⠓⠰⠢⠼⠃⠠⠕")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_4() -> Result<()> { + // BANA 2026 Ex 5-4 + let expr = "5x2y3z"; + test_braille("UEB", expr, "⠰⠷⠼⠑⠭⠔⠼⠃⠨⠌⠽⠔⠼⠉⠵⠾")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_5() -> Result<()> { + // BANA 2026 Ex 5-5: 1×3 matrix and column (linearized like other matrix_* tests) + let expr = r#" + (abc) + ( + -1 + 2 + -3 + ) + "#; + test_braille("UEB", expr, "⠠⠐⠣⠁⠀⠰⠃⠀⠉⠠⠐⠜⠠⠐⠣⠐⠤⠼⠁⠠⠐⠜⠸⠀⠠⠐⠣⠼⠃⠠⠐⠜⠸⠀⠠⠐⠣⠐⠤⠼⠉⠠⠐⠜")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_6() -> Result<()> { + // BANA 2026 Ex 5-6 + let expr = r#" + (ab) + (-x2y) + "#; + test_braille("UEB", expr, "⠠⠐⠣⠁⠀⠃⠠⠐⠜⠠⠐⠣⠐⠤⠭⠠⠐⠜⠸⠀⠠⠐⠣⠼⠃⠽⠠⠐⠜")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_9_slope() -> Result<()> { + // BANA 2026 Ex 5-9 (math fragments): slope 3/5 and parallel lines l₁ ∥ l₂ + let expr = "l1∥l2"; + test_braille("UEB", expr, "⠇⠰⠢⠼⠁⠀⠼⠇⠀⠇⠰⠢⠼⠃")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_11() -> Result<()> { + // BANA 2026 Ex 5-11 + let expr = "ab"; + test_braille("UEB", expr, "⠰⠰⠷⠁⠨⠌⠃⠾")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_12() -> Result<()> { + // BANA 2026 Ex 5-12: vector AB with arrow + let expr = "AB→"; + test_braille("UEB", expr, "⠰⠰⠣⠠⠠⠁⠃⠜⠘⠱")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_13() -> Result<()> { + // BANA 2026 Ex 5-13 + let expr = "x-1=1x"; + test_braille("UEB", expr, "⠰⠰⠭⠔⠣⠐⠤⠼⠁⠜⠀⠐⠶⠀⠰⠷⠼⠁⠨⠌⠭⠾")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_15() -> Result<()> { + // BANA 2026 Ex 5-15: all-caps print uses capital passage (⠠⠠⠠ … ⠠⠄) inside G1 passage + let expr = "P=VI=I2R=V2R"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠠⠠⠏⠀⠐⠶⠀⠧⠊⠀⠐⠶⠀⠊⠔⠼⠃⠗⠀⠐⠶⠀⠷⠧⠔⠼⠃⠨⠌⠗⠾⠠⠄⠰⠄")?; + return Ok(()); + +} + +#[test] +fn bana2026_5_16() -> Result<()> { + // BANA 2026 Ex 5-16: CaCO₃ ⇄ CaO + CO₂ + let expr = "CaCO3 + ⇄ + CaO+ + CO2"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠉⠁⠠⠉⠠⠕⠢⠼⠉⠀⠳⠕⠻⠳⠪⠀⠠⠉⠁⠠⠕⠐⠖⠠⠉⠠⠕⠢⠼⠃⠰⠄")?; + return Ok(()); + +} + +#[test] +fn bana2026_7_1() -> Result<()> { + // BANA 2026 Ex 7-1: V = lim Δx→0 Σ f(xᵢ)Δx (single-line) + let expr = r#"V= + limΔx→0 + ∑i + f(xi)Δx + "#; + test_braille("UEB", expr, "⠰⠠⠧⠀⠐⠶⠀⠰⠰⠇⠊⠍⠨⠢⠣⠠⠨⠙⠭⠳⠕⠼⠚⠜⠠⠨⠎⠨⠢⠊⠋⠐⠣⠭⠢⠊⠐⠜⠠⠨⠙⠭")?; + return Ok(()); + +} + +#[test] +fn bana2026_7_2() -> Result<()> { + // BANA 2026 Ex 7-2: first step of radical simplification chain + let expr = r#"x= + 36-4(9)+3(12)18 + "#; + test_braille("UEB", expr, "⠰⠭⠀⠐⠶⠀⠰⠰⠷⠩⠼⠉⠋⠐⠤⠼⠙⠐⠣⠼⠊⠐⠜⠐⠖⠼⠉⠐⠣⠼⠁⠃⠐⠜⠬⠨⠌⠼⠁⠓⠾")?; + return Ok(()); + +} + +#[test] +fn bana2026_7_3() -> Result<()> { + // BANA 2026 Ex 7-3 + let expr = r#"x= + + 54+7-111×2+8000+1000 + -42 + + "#; + test_braille("UEB", expr, "⠰⠭⠀⠐⠶⠀⠰⠷⠼⠑⠙⠐⠖⠼⠛⠐⠤⠼⠁⠁⠁⠐⠦⠼⠃⠐⠖⠼⠓⠚⠚⠚⠐⠖⠼⠁⠚⠚⠚⠨⠌⠐⠤⠼⠙⠃⠾")?; return Ok(()); } @@ -167,7 +376,7 @@ fn grade1_1_7_2() -> Result<()> { #[test] fn grade1_1_7_3_1() -> Result<()> { let expr = " - 3x−4y+ + 3x−4y+ y2 = x2 @@ -193,13 +402,614 @@ fn grade1_1_7_3_2() -> Result<()> { #[test] fn grade1_1_7_4() -> Result<()> { let expr = " - (y−x2) + (y−x2) "; test_braille("UEB", expr, "⠰⠰⠩⠐⠣⠽⠐⠤⠭⠔⠼⠃⠐⠜⠬")?; return Ok(()); } +// Additional examples from GTM 1.7 (July 2025): +// https://iceb.org/wp-content/uploads/2026/02/GTM-1.7-Grade-1-Indicators-Approved.pdf +// Ordinary surrounding text is omitted; braille is the preferred math from the spec. + +#[test] +fn grade1_1_7_3_a_1() -> Result<()> { + let expr = "x2"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_3_a_2() -> Result<()> { + let expr = "x→∞"; + test_braille("UEB", expr, "⠰⠭⠀⠰⠳⠕⠀⠼⠿")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_3_a_3() -> Result<()> { + let expr = "xy"; + test_braille("UEB", expr, "⠰⠰⠷⠭⠨⠌⠽⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_3_b_1() -> Result<()> { + let expr = "xa=xb + =xc"; + test_braille("UEB", expr, "⠰⠰⠰⠭⠢⠁⠀⠐⠶⠀⠭⠢⠃⠀⠐⠶⠀⠭⠢⠉⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_3_b_2() -> Result<()> { + let expr = "y=x2-4; +  y=x2-2x; +  y=x-x2."; + test_braille("UEB", expr, "⠰⠰⠰⠽⠀⠐⠶⠀⠭⠔⠼⠃⠐⠤⠼⠙⠆⠀⠽⠀⠐⠶⠀⠭⠔⠼⠃⠐⠤⠼⠃⠭⠆⠀⠽⠀⠐⠶⠀⠭⠐⠤⠭⠔⠼⠃⠲⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_4_1() -> Result<()> { + let expr = "x2-x-2 + =0"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠤⠭⠐⠤⠼⠃⠀⠐⠶⠀⠼⠚")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_4_2() -> Result<()> { + let expr = "x2-4x-3 + =0"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠤⠼⠙⠭⠐⠤⠼⠉⠀⠐⠶⠀⠼⠚")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_4_3() -> Result<()> { + let expr = "x2-1=0"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠤⠼⠁⠀⠐⠶⠀⠼⠚")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_5_a() -> Result<()> { + let expr = "speed= + distancetime"; + // GTM 1.7.5(a) (2025): two grade 1 symbol indicators so the words stay contracted. + // After the fraction open, "dis" is not a word start (RUEB 10.6.2), so st+ance: ⠙⠊⠌⠨⠑. + test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠷⠙⠊⠌⠨⠑⠨⠌⠐⠞⠰⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_5_b() -> Result<()> { + let expr = "luminositysun"; + test_braille("UEB", expr, "⠰⠰⠇⠥⠍⠊⠝⠕⠎⠊⠞⠽⠢⠣⠎⠥⠝⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_5_c() -> Result<()> { + let expr = "speed= + distancetime= + 30,000 m + 60 s= + 500 m/s"; + test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠰⠰⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾⠀⠐⠶⠀⠷⠼⠉⠚⠂⠚⠚⠚⠀⠍⠨⠌⠼⠋⠚⠀⠎⠾⠀⠐⠶⠀⠼⠑⠚⠚⠀⠍⠸⠌⠎⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_5_c_unit() -> Result<()> { + // Same as grade1_1_7_5_c; unit marked via data-intent-property + let expr = "speed= + distancetime= + 30,000 m + 60 s= + 500 m/s"; + test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠰⠰⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾⠀⠐⠶⠀⠷⠼⠉⠚⠂⠚⠚⠚⠀⠍⠨⠌⠼⠋⠚⠀⠎⠾⠀⠐⠶⠀⠼⠑⠚⠚⠀⠍⠸⠌⠎⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_1() -> Result<()> { + let expr = "y=x"; + test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠰⠭")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_2() -> Result<()> { + let expr = "25=5"; + test_braille("UEB", expr, "⠰⠩⠼⠃⠑⠬⠀⠐⠶⠀⠼⠑")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_3() -> Result<()> { + let expr = "x=7"; + test_braille("UEB", expr, "⠰⠰⠩⠭⠬⠀⠐⠶⠀⠼⠛")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_4() -> Result<()> { + let expr = "ms + -1"; + test_braille("UEB", expr, "⠰⠰⠍⠎⠔⠣⠐⠤⠼⠁⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_4_unit() -> Result<()> { + // Same as grade1_1_7_9_4; unit marked via data-intent-property + let expr = "ms + -1"; + test_braille("UEB", expr, "⠰⠰⠍⠎⠔⠣⠐⠤⠼⠁⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_5() -> Result<()> { + let expr = "y=x2"; + // GTM 1.7.9 (July 2025): one symbol indicator; numeric mode covers the closer. + test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠰⠷⠭⠨⠌⠼⠃⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_6() -> Result<()> { + let expr = "y=x22"; + test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠰⠰⠷⠭⠔⠼⠃⠨⠌⠼⠃⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_7() -> Result<()> { + let expr = "xy=cd"; + test_braille("UEB", expr, "⠰⠰⠷⠭⠨⠌⠽⠾⠀⠐⠶⠀⠰⠰⠷⠉⠨⠌⠙⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_8() -> Result<()> { + let expr = "(x,y)"; + test_braille("UEB", expr, "⠐⠣⠰⠭⠂⠀⠰⠽⠐⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_9() -> Result<()> { + let expr = "(xi,yi)"; + test_braille("UEB", expr, "⠐⠣⠭⠰⠢⠊⠂⠀⠽⠰⠢⠊⠐⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_10() -> Result<()> { + let expr = "(xi2, + yi2)"; + test_braille("UEB", expr, "⠰⠰⠐⠣⠭⠢⠊⠔⠼⠃⠂⠀⠰⠰⠽⠢⠊⠔⠼⠃⠐⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_11() -> Result<()> { + let expr = "B¯"; + test_braille("UEB", expr, "⠠⠃⠰⠱")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_12() -> Result<()> { + let expr = "M↔"; + test_braille("UEB", expr, "⠠⠍⠨⠔⠰⠳⠺⠗⠕")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_13() -> Result<()> { + let expr = "AZ + ↔"; + test_braille("UEB", expr, "⠰⠰⠣⠠⠠⠁⠵⠜⠨⠔⠳⠺⠗⠕")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_14() -> Result<()> { + let expr = "1327Al"; + test_braille("UEB", expr, "⠰⠢⠼⠁⠉⠔⠼⠃⠛⠠⠁⠇")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_15() -> Result<()> { + let expr = "O2-"; + test_braille("UEB", expr, "⠰⠰⠠⠕⠔⠣⠼⠃⠐⠤⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_16() -> Result<()> { + let expr = "2H2 + (g)+ + O2 + (g)→ + 2H2 + O(l)"; + test_braille("UEB", expr, "⠼⠃⠠⠓⠢⠼⠃⠐⠣⠛⠐⠜⠐⠖⠠⠕⠢⠼⠃⠐⠣⠛⠐⠜⠀⠰⠳⠕⠀⠼⠃⠠⠓⠢⠼⠃⠠⠕⠐⠣⠇⠐⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_17() -> Result<()> { + let expr = "y=mx+c"; + test_braille("UEB", expr, "⠰⠽⠀⠐⠶⠀⠍⠭⠐⠖⠉")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_18() -> Result<()> { + let expr = "A=πr2"; + test_braille("UEB", expr, "⠠⠁⠀⠐⠶⠀⠨⠏⠗⠰⠔⠼⠃")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_19() -> Result<()> { + let expr = "E=mc2"; + test_braille("UEB", expr, "⠰⠠⠑⠀⠐⠶⠀⠍⠉⠰⠔⠼⠃")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_20() -> Result<()> { + let expr = "x2-2x+1 + =(x-1)2"; + test_braille("UEB", expr, "⠭⠰⠔⠼⠃⠐⠤⠼⠃⠭⠐⠖⠼⠁⠀⠐⠶⠀⠐⠣⠭⠐⠤⠼⠁⠐⠜⠔⠼⠃")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_21() -> Result<()> { + let expr = "xn=1+ + -1nn"; + test_braille("UEB", expr, "⠭⠰⠢⠝⠀⠐⠶⠀⠼⠁⠐⠖⠷⠐⠤⠼⠁⠔⠝⠨⠌⠝⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_22() -> Result<()> { + let expr = "xn= + 2nn2"; + test_braille("UEB", expr, "⠭⠰⠢⠝⠀⠐⠶⠀⠰⠷⠼⠃⠔⠝⠨⠌⠝⠔⠼⠃⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_23() -> Result<()> { + let expr = "x= + + −b± + b2−4ac + + 2a + + "; + test_braille("UEB", expr, "⠰⠭⠀⠐⠶⠀⠰⠰⠷⠐⠤⠃⠸⠖⠩⠃⠔⠼⠃⠐⠤⠼⠙⠰⠁⠉⠬⠨⠌⠼⠃⠰⠁⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_24() -> Result<()> { + let expr = "xsinθ"; + test_braille("UEB", expr, "⠰⠰⠭⠩⠎⠊⠝⠨⠹⠬")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_25() -> Result<()> { + let expr = "Version1b"; + test_braille("UEB", expr, "⠰⠰⠠⠧⠑⠗⠎⠊⠕⠝⠔⠣⠼⠁⠰⠃⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_26() -> Result<()> { + let expr = "W=Fs"; + test_braille("UEB", expr, "⠰⠠⠺⠀⠐⠶⠀⠠⠋⠎")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_27() -> Result<()> { + let expr = "work=force×distance"; + test_braille("UEB", expr, "⠐⠺⠀⠐⠶⠀⠿⠉⠑⠐⠦⠙⠊⠌⠨⠑")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_28() -> Result<()> { + let expr = "∴force= + workdistance"; + test_braille("UEB", expr, "⠰⠠⠡⠀⠿⠉⠑⠀⠐⠶⠀⠰⠷⠐⠺⠨⠌⠙⠊⠌⠨⠑⠰⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_29() -> Result<()> { + let expr = "acceleration= + Δspeed + Δtime"; + test_braille("UEB", expr, "⠁⠒⠑⠇⠻⠁⠰⠝⠀⠐⠶⠀⠰⠷⠠⠨⠙⠎⠏⠑⠫⠨⠌⠠⠨⠙⠐⠞⠰⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_30() -> Result<()> { + let expr = "frequency=1time"; + test_braille("UEB", expr, "⠋⠗⠑⠟⠥⠢⠉⠽⠀⠐⠶⠀⠰⠷⠼⠁⠨⠌⠞⠊⠍⠑⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_31() -> Result<()> { + let expr = "frequency=1/time"; + test_braille("UEB", expr, "⠋⠗⠑⠟⠥⠢⠉⠽⠀⠐⠶⠀⠼⠁⠸⠌⠞⠊⠍⠑")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_32() -> Result<()> { + let expr = "Vcone= + 13π + r2h"; + test_braille("UEB", expr, "⠰⠰⠠⠧⠢⠣⠉⠕⠝⠑⠜⠀⠐⠶⠀⠼⠁⠌⠉⠨⠏⠗⠔⠼⠃⠰⠓")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_33() -> Result<()> { + let expr = "V=∫π + y2dx"; + test_braille("UEB", expr, "⠰⠠⠧⠀⠐⠶⠀⠰⠰⠮⠨⠏⠽⠔⠼⠃⠰⠙⠭")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_34() -> Result<()> { + let expr = "period=2π + + lcosα + g + "; + test_braille("UEB", expr, "⠏⠻⠊⠕⠙⠀⠐⠶⠀⠼⠃⠨⠏⠩⠷⠇⠀⠰⠰⠉⠕⠎⠨⠁⠨⠌⠛⠾⠬")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_35() -> Result<()> { + let expr = "Assume g=9.81  + ms + -2"; + test_braille("UEB", expr, "⠠⠁⠎⠎⠥⠍⠑⠀⠰⠛⠀⠐⠶⠀⠼⠊⠲⠓⠁⠀⠰⠰⠍⠎⠔⠣⠐⠤⠼⠃⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_35_unit() -> Result<()> { + // Same as grade1_1_7_9_35; unit marked via data-intent-property + let expr = "Assume g=9.81  + ms + -2"; + test_braille("UEB", expr, "⠠⠁⠎⠎⠥⠍⠑⠀⠰⠛⠀⠐⠶⠀⠼⠊⠲⠓⠁⠀⠰⠰⠍⠎⠔⠣⠐⠤⠼⠃⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_36() -> Result<()> { + let expr = "v1=x  + ms + -1"; + test_braille("UEB", expr, "⠰⠰⠰⠧⠢⠼⠁⠀⠐⠶⠀⠭⠀⠍⠎⠔⠣⠐⠤⠼⠁⠜⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_36_unit() -> Result<()> { + // Same as grade1_1_7_9_36; unit marked via data-intent-property + let expr = "v1=x  + ms + -1"; + test_braille("UEB", expr, "⠰⠰⠰⠧⠢⠼⠁⠀⠐⠶⠀⠭⠀⠍⠎⠔⠣⠐⠤⠼⠁⠜⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_37() -> Result<()> { + let expr = "P= + t,u,v"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠏⠀⠐⠶⠀⠸⠣⠞⠂⠀⠥⠂⠀⠧⠸⠜⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_38() -> Result<()> { + let expr = "xa=xb + =xc=xd"; + test_braille("UEB", expr, "⠰⠰⠰⠭⠢⠁⠀⠐⠶⠀⠭⠢⠃⠀⠐⠶⠀⠭⠢⠉⠀⠐⠶⠀⠭⠢⠙⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_39() -> Result<()> { + let expr = "x2×x3 + =x2+3 + =x5"; + test_braille("UEB", expr, "⠰⠰⠰⠭⠔⠼⠃⠐⠦⠭⠔⠼⠉⠀⠐⠶⠀⠭⠔⠣⠼⠃⠐⠖⠼⠉⠜⠀⠐⠶⠀⠭⠔⠼⠑⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_40() -> Result<()> { + let expr = "am×an + =am+n"; + test_braille("UEB", expr, "⠰⠰⠁⠔⠍⠐⠦⠁⠔⠝⠀⠐⠶⠀⠰⠰⠁⠔⠣⠍⠐⠖⠝⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_41() -> Result<()> { + let expr = "(am)n + =amn"; + test_braille("UEB", expr, "⠰⠰⠐⠣⠁⠔⠍⠐⠜⠔⠝⠀⠐⠶⠀⠰⠰⠁⠔⠣⠍⠝⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_42() -> Result<()> { + let expr = "aman + =am-n"; + test_braille("UEB", expr, "⠰⠰⠷⠁⠔⠍⠨⠌⠁⠔⠝⠾⠀⠐⠶⠀⠰⠰⠁⠔⠣⠍⠐⠤⠝⠜")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_43() -> Result<()> { + let expr = "a-m + =1am"; + test_braille("UEB", expr, "⠰⠰⠁⠔⠣⠐⠤⠍⠜⠀⠐⠶⠀⠰⠷⠼⠁⠨⠌⠁⠔⠍⠾")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_44() -> Result<()> { + let expr = "a0=1"; + test_braille("UEB", expr, "⠁⠰⠔⠼⠚⠀⠐⠶⠀⠼⠁")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_45() -> Result<()> { + let expr = "a1n + =an"; + test_braille("UEB", expr, "⠰⠰⠁⠔⠷⠼⠁⠨⠌⠝⠾⠀⠐⠶⠀⠰⠰⠩⠔⠝⠁⠬")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_46() -> Result<()> { + let expr = "B→C"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠃⠀⠳⠕⠀⠠⠉⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_47() -> Result<()> { + let expr = "x+y=5"; + test_braille("UEB", expr, "⠭⠐⠖⠽⠀⠐⠶⠀⠼⠑")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_48() -> Result<()> { + let expr = "CH4 + +4Cl2 + → + CCl4 + +4HCl"; + test_braille("UEB", expr, "⠰⠰⠰⠠⠉⠠⠓⠢⠼⠙⠐⠖⠼⠙⠠⠉⠇⠢⠼⠃⠀⠳⠕⠀⠠⠉⠠⠉⠇⠢⠼⠙⠐⠖⠼⠙⠠⠓⠠⠉⠇⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_49() -> Result<()> { + let expr = "614C + → + 714N + + + -10β"; + test_braille("UEB", expr, "⠰⠰⠰⠢⠼⠋⠔⠼⠁⠙⠠⠉⠀⠳⠕⠀⠢⠼⠛⠔⠼⠁⠙⠠⠝⠐⠖⠢⠣⠐⠤⠼⠁⠜⠔⠼⠚⠨⠃⠰⠄")?; + return Ok(()); + +} + +#[test] +fn grade1_1_7_9_50() -> Result<()> { + let expr = "reliability= + number of faultstotal number of items + =p"; + test_braille("UEB", expr, "⠰⠰⠰⠗⠑⠇⠊⠁⠃⠊⠇⠊⠞⠽⠀⠐⠶⠀⠷⠝⠥⠍⠃⠑⠗⠀⠕⠋⠀⠋⠁⠥⠇⠞⠎⠨⠌⠞⠕⠞⠁⠇⠀⠝⠥⠍⠃⠑⠗⠀⠕⠋⠀⠊⠞⠑⠍⠎⠾⠀⠐⠶⠀⠏⠰⠄")?; + return Ok(()); + +} + #[test] fn number_2_1_2() -> Result<()> { let expr = "3,000"; @@ -313,7 +1123,7 @@ fn bold_2_7_3() -> Result<()> { fn signs_2_10_2() -> Result<()> { let expr = "$0.30,  30c  - or 30¢"; + or 30¢"; test_braille("UEB", expr, "⠈⠎⠼⠚⠲⠉⠚⠂⠀⠼⠉⠚⠰⠉⠀⠕⠗⠀⠼⠉⠚⠈⠉")?; return Ok(()); @@ -323,7 +1133,7 @@ fn signs_2_10_2() -> Result<()> { fn signs_2_10_5() -> Result<()> { let expr = "1 ft 6 in  or  - 1′ 6′′"; + 1′ 6′′"; test_braille("UEB", expr, "⠼⠁⠀⠋⠞⠀⠼⠋⠀⠔⠀⠕⠗⠀⠼⠁⠶⠀⠼⠋⠶⠶")?; return Ok(()); @@ -331,8 +1141,8 @@ fn signs_2_10_5() -> Result<()> { #[test] fn signs_2_10_8() -> Result<()> { - let expr = "0°C or -  32°F"; + let expr = "0°C or +  32°F"; test_braille("UEB", expr, "⠼⠚⠘⠚⠠⠉⠀⠕⠗⠀⠼⠉⠃⠘⠚⠠⠋")?; return Ok(()); @@ -340,9 +1150,9 @@ fn signs_2_10_8() -> Result<()> { #[test] fn signs_2_10_16() -> Result<()> { - let expr = "1 Å= + let expr = "1 Å= 110,000  - μ"; + μ"; test_braille("UEB", expr, "⠼⠁⠀⠠⠘⠫⠁⠀⠐⠶⠀⠼⠁⠌⠁⠚⠂⠚⠚⠚⠀⠨⠍")?; return Ok(()); @@ -384,7 +1194,7 @@ fn expr_3_1_2() -> Result<()> { #[test] fn expr_3_1_3() -> Result<()> { - let expr = "3×5=5×3=15"; + let expr = "3×5=5×3=15"; test_braille("UEB", expr, "⠼⠉⠐⠦⠼⠑⠀⠐⠶⠀⠼⠑⠐⠦⠼⠉⠀⠐⠶⠀⠼⠁⠑")?; return Ok(()); @@ -393,7 +1203,7 @@ fn expr_3_1_3() -> Result<()> { #[test] fn expr_3_1_6() -> Result<()> { // example includes spaces, so does the MathML (from WIRIS) - let expr = "5.72 m÷10= + let expr = "5.72 m÷10= 57.2 cm"; test_braille("UEB", expr, "⠼⠑⠲⠛⠃⠀⠍⠐⠌⠼⠁⠚⠀⠐⠶⠀⠼⠑⠛⠲⠃⠀⠉⠍")?; return Ok(()); @@ -402,7 +1212,7 @@ fn expr_3_1_6() -> Result<()> { #[test] fn expr_3_1_7() -> Result<()> { - let expr = "15±0.5"; + let expr = "15±0.5"; test_braille("UEB", expr, "⠼⠁⠑⠸⠖⠼⠚⠲⠑")?; return Ok(()); @@ -411,7 +1221,7 @@ fn expr_3_1_7() -> Result<()> { #[test] fn expr_3_1_8() -> Result<()> { let expr = "Area=bh= - 5·3=15"; + 5·3=15"; test_braille("UEB", expr, "⠠⠜⠑⠁⠀⠐⠶⠀⠃⠓⠀⠐⠶⠀⠼⠑⠐⠲⠼⠉⠀⠐⠶⠀⠼⠁⠑")?; return Ok(()); @@ -419,7 +1229,7 @@ fn expr_3_1_8() -> Result<()> { #[test] fn expr_3_1_9_wiris() -> Result<()> { - let expr = "3.9×4.1≃16"; + let expr = "3.9×4.1≃16"; test_braille("UEB", expr, "⠼⠉⠲⠊⠐⠦⠼⠙⠲⠁⠀⠸⠔⠀⠼⠁⠋")?; return Ok(()); @@ -427,7 +1237,7 @@ fn expr_3_1_9_wiris() -> Result<()> { #[test] fn expr_3_1_9() -> Result<()> { - let expr = "3.9×4.1≃16"; + let expr = "3.9×4.1≃16"; test_braille("UEB", expr, "⠼⠉⠲⠊⠐⠦⠼⠙⠲⠁⠀⠸⠔⠀⠼⠁⠋")?; return Ok(()); @@ -435,7 +1245,7 @@ fn expr_3_1_9() -> Result<()> { #[test] fn expr_3_1_10() -> Result<()> { - let expr = "5-3≠3-5"; + let expr = "5-3≠3-5"; test_braille("UEB", expr, "⠼⠑⠐⠤⠼⠉⠀⠐⠶⠈⠱⠀⠼⠉⠐⠤⠼⠑")?; return Ok(()); @@ -459,7 +1269,7 @@ fn ratio_3_1_12() -> Result<()> { #[test] fn alg_3_2_1_1() -> Result<()> { - let expr = "y∝x"; + let expr = "y∝x"; test_braille("UEB", expr, "⠰⠽⠀⠸⠐⠶⠀⠰⠭")?; return Ok(()); @@ -475,8 +1285,8 @@ fn alg_3_2_1_2() -> Result<()> { #[test] fn alg_3_2_2() -> Result<()> { - let expr = "0≤θ - ≤2π"; + let expr = "0≤θ + ≤2π"; test_braille("UEB", expr, "⠼⠚⠀⠸⠈⠣⠀⠨⠹⠀⠸⠈⠣⠀⠼⠃⠨⠏")?; return Ok(()); @@ -502,10 +1312,7 @@ fn alg_3_2_4() -> Result<()> { #[test] fn alg_3_2_5() -> Result<()> { let expr = "d+ab=ac"; - // BANA says use a word indicator if G1 not in first 3 cells (it is after the '='); use passage if >=2 whitespace - // This seems like a poor choice in this case since there is only one G1 indicator, but that's the BANA guidance so... - // "⠰⠰⠰⠙⠐⠖⠁⠃⠀⠐⠶⠀⠁⠉⠰⠄" - // GTM says to use the following and it is more sensisble, so I'm going with it + // GTM 1.7 / BANA 2026: one G1 symbol for standing-alone 'a' after '=' test_braille("UEB", expr, "⠙⠐⠖⠁⠃⠀⠐⠶⠀⠰⠁⠉")?; return Ok(()); @@ -541,10 +1348,10 @@ fn example_3_4_1() -> Result<()> { fn example_3_4_2() -> Result<()> { // removed some cruft from TeX output of {}^{-}2+{}^{+}3, but the basics are preserved let expr = " - − + − 2 + - − + − 3 "; test_braille("UEB", expr, "⠰⠔⠐⠤⠼⠃⠐⠖⠔⠐⠤⠼⠉")?; @@ -578,7 +1385,7 @@ fn omission_3_6_3() -> Result<()> { #[test] fn omission_3_6_4() -> Result<()> { - let expr = "3□7=10"; + let expr = "3□7=10"; test_braille("UEB", expr, "⠼⠉⠫⠼⠙⠱⠼⠛⠀⠐⠶⠀⠼⠁⠚")?; return Ok(()); @@ -637,9 +1444,21 @@ fn fraction_6_2_1() -> Result<()> { #[test] fn fraction_6_2_2() -> Result<()> { let expr = "1750 -  cm= +  cm= + 134 +  m"; + test_braille("UEB", expr, "⠼⠁⠛⠑⠚⠀⠉⠍⠀⠐⠶⠀⠼⠁⠼⠉⠌⠙⠀⠰⠍")?; + return Ok(()); + +} + +#[test] +fn fraction_6_2_2_unit() -> Result<()> { + // Same as fraction_6_2_2; unit marked via data-intent-property + let expr = "1750 +  cm= 134 -  m"; +  m"; test_braille("UEB", expr, "⠼⠁⠛⠑⠚⠀⠉⠍⠀⠐⠶⠀⠼⠁⠼⠉⠌⠙⠀⠰⠍")?; return Ok(()); @@ -648,26 +1467,30 @@ fn fraction_6_2_2() -> Result<()> { #[test] fn fraction_6_2_2_unicode_frac() -> Result<()> { let expr = "1750 -  cm= - 1¾ -  m"; +  cm= + 1¾ +  m"; test_braille("UEB", expr, "⠼⠁⠛⠑⠚⠀⠉⠍⠀⠐⠶⠀⠼⠁⠼⠉⠌⠙⠀⠰⠍")?; return Ok(()); } #[test] -fn fraction_6_3_1() -> Result<()> { - let expr = "3/8"; - test_braille("UEB", expr, "⠼⠉⠸⠌⠼⠓")?; +fn fraction_6_2_2_unicode_frac_unit() -> Result<()> { + // Same as fraction_6_2_2_unicode_frac; unit marked via data-intent-property + let expr = "1750 +  cm= + 1¾ +  m"; + test_braille("UEB", expr, "⠼⠁⠛⠑⠚⠀⠉⠍⠀⠐⠶⠀⠼⠁⠼⠉⠌⠙⠀⠰⠍")?; return Ok(()); } #[test] -fn fraction_6_4_1() -> Result<()> { - let expr = "y=x2"; - test_braille("UEB", expr, "⠰⠰⠰⠽⠀⠐⠶⠀⠷⠭⠨⠌⠼⠃⠾⠰⠄")?; +fn fraction_6_3_1() -> Result<()> { + let expr = "3/8"; + test_braille("UEB", expr, "⠼⠉⠸⠌⠼⠓")?; return Ok(()); } @@ -716,8 +1539,9 @@ fn fraction_6_4_5() -> Result<()> { #[test] fn fraction_6_4_6() -> Result<()> { let expr = "speed=distancetime"; - // GTM lists two options: "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠰⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾" and "⠰⠰⠰⠎⠏⠑⠑⠙⠀⠐⠶⠀⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾⠰⠄" - test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠰⠷⠙⠊⠎⠞⠁⠝⠉⠑⠨⠌⠞⠊⠍⠑⠾")?; + // GTM 2014 §6.4 listed word-indicator and passage alternatives (uncontracted words). + // GTM 1.7.5(a) (2025) prefers two grade 1 symbol indicators with contracted words. + test_braille("UEB", expr, "⠎⠏⠑⠫⠀⠐⠶⠀⠰⠷⠙⠊⠌⠨⠑⠨⠌⠐⠞⠰⠾")?; return Ok(()); } @@ -766,7 +1590,7 @@ fn msup_7_3_7() -> Result<()> { #[test] fn msup_7_3_11() -> Result<()> { let expr = "xaby=x"; - test_braille("UEB", expr, "⠰⠰⠰⠭⠔⠷⠁⠨⠌⠃⠾⠽⠀⠐⠶⠀⠭⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠭⠔⠷⠁⠨⠌⠃⠾⠽⠀⠐⠶⠀⠰⠭")?; return Ok(()); } @@ -798,7 +1622,7 @@ fn msub_7_4_3() -> Result<()> { #[test] fn msup_7_5_1() -> Result<()> { let expr = "0.0045= - 4.5×10-3 + 4.5×10-3 "; test_braille("UEB", expr, "⠼⠚⠲⠚⠚⠙⠑⠀⠐⠶⠀⠼⠙⠲⠑⠐⠦⠼⠁⠚⠔⠣⠐⠤⠼⠉⠜")?; return Ok(()); @@ -824,7 +1648,7 @@ fn msup_7_6_2() -> Result<()> { #[test] fn msubsup_7_7_1() -> Result<()> { let expr = "x12=y23"; - test_braille("UEB", expr, "⠰⠰⠰⠭⠢⠼⠁⠔⠼⠃⠀⠐⠶⠀⠽⠢⠼⠃⠔⠼⠉⠰⠄")?; + test_braille("UEB", expr, "⠭⠰⠢⠼⠁⠔⠼⠃⠀⠐⠶⠀⠽⠰⠢⠼⠃⠔⠼⠉")?; return Ok(()); } @@ -852,7 +1676,7 @@ fn pre_sup_7_8_2() -> Result<()> { +3- =5- "; - test_braille("UEB", expr, "⠰⠰⠰⠔⠐⠤⠼⠃⠐⠖⠔⠐⠤⠼⠉⠀⠐⠶⠀⠔⠐⠤⠼⠑⠰⠄")?; + test_braille("UEB", expr, "⠰⠔⠐⠤⠼⠃⠐⠖⠔⠐⠤⠼⠉⠀⠐⠶⠀⠰⠔⠐⠤⠼⠑")?; return Ok(()); } @@ -860,9 +1684,9 @@ fn pre_sup_7_8_2() -> Result<()> { #[test] fn sum_7_9_1() -> Result<()> { - let expr = "∑x=1n + let expr = "∑x=1n xi2"; - test_braille("UEB", expr, "⠰⠰⠠⠨⠎⠨⠢⠣⠭⠐⠶⠼⠁⠜⠨⠔⠝⠭⠢⠊⠔⠼⠃")?; + test_braille("UEB", expr, "⠠⠨⠎⠨⠢⠰⠣⠭⠐⠶⠼⠁⠜⠨⠔⠝⠭⠢⠊⠔⠼⠃")?; return Ok(()); } @@ -870,7 +1694,7 @@ fn sum_7_9_1() -> Result<()> { #[test] fn lim_7_9_2() -> Result<()> { // Note: modified because passage indicator is not needed (same expr when word indicator is used) - let expr = "limx→a + let expr = "limx→a f(x)=1"; test_braille("UEB", expr, "⠰⠰⠇⠊⠍⠨⠢⠣⠭⠳⠕⠁⠜⠋⠐⠣⠭⠐⠜⠀⠐⠶⠀⠼⠁")?; return Ok(()); @@ -889,7 +1713,7 @@ fn sqrt_8_1_1() -> Result<()> { fn sqrt_8_1_2() -> Result<()> { let expr = "r= x2+y2"; - test_braille("UEB", expr, "⠰⠰⠰⠗⠀⠐⠶⠀⠩⠭⠔⠼⠃⠐⠖⠽⠔⠼⠃⠬⠰⠄")?; + test_braille("UEB", expr, "⠰⠗⠀⠐⠶⠀⠰⠰⠩⠭⠔⠼⠃⠐⠖⠽⠔⠼⠃⠬")?; return Ok(()); } @@ -899,7 +1723,7 @@ fn sqrt_8_1_3() -> Result<()> { let expr = " - 783.2×6.547 + 783.2×6.547 0.4628 @@ -915,17 +1739,17 @@ fn sqrt_8_1_4() -> Result<()> { x = - −b± + −b± b 2 - −4ac + −4ac 2a "; - test_braille("UEB", expr, "⠰⠰⠰⠭⠀⠐⠶⠀⠷⠐⠤⠃⠸⠖⠩⠃⠔⠼⠃⠐⠤⠼⠙⠰⠁⠉⠬⠨⠌⠼⠃⠰⠁⠾⠰⠄")?; + test_braille("UEB", expr, "⠰⠭⠀⠐⠶⠀⠰⠰⠷⠐⠤⠃⠸⠖⠩⠃⠔⠼⠃⠐⠤⠼⠙⠰⠁⠉⠬⠨⠌⠼⠃⠰⠁⠾")?; return Ok(()); } @@ -946,7 +1770,7 @@ fn root_8_2_2() -> Result<()> { y3+ z3 3"; - test_braille("UEB", expr, "⠰⠰⠰⠟⠀⠐⠶⠀⠩⠔⠼⠉⠭⠔⠼⠉⠐⠖⠽⠔⠼⠉⠐⠖⠵⠔⠼⠉⠬⠰⠄")?; + test_braille("UEB", expr, "⠰⠟⠀⠐⠶⠀⠰⠰⠩⠔⠼⠉⠭⠔⠼⠉⠐⠖⠽⠔⠼⠉⠐⠖⠵⠔⠼⠉⠬")?; return Ok(()); } @@ -992,7 +1816,7 @@ fn spacing_9_3_1_1() -> Result<()> { #[test] fn spacing_9_3_1_2() -> Result<()> { - let expr = "3tan45°"; + let expr = "3tan45°"; test_braille("UEB", expr, "⠼⠉⠞⠁⠝⠼⠙⠑⠘⠚")?; return Ok(()); @@ -1016,7 +1840,7 @@ fn spacing_9_3_2_1() -> Result<()> { #[test] fn spacing_9_3_2_2() -> Result<()> { - let expr = "sinθ"; + let expr = "sinθ"; test_braille("UEB", expr, "⠎⠔⠨⠹")?; return Ok(()); @@ -1041,7 +1865,9 @@ fn spacing_9_3_2_4() -> Result<()> { #[test] fn spacing_9_3_2_5() -> Result<()> { let expr = "Limx2"; - test_braille("UEB", expr, "⠰⠰⠠⠇⠊⠍⠷⠭⠨⠌⠼⠃⠾")?; + // GTM 2014 9.3.2 used a word indicator (;;,lim(x./#b)). GTM 1.7.3(a): one + // symbol indicator on the fraction open; numeric mode covers the closer. + test_braille("UEB", expr, "⠠⠇⠊⠍⠰⠷⠭⠨⠌⠼⠃⠾")?; return Ok(()); } @@ -1091,8 +1917,8 @@ fn spacing_9_3_3_5() -> Result<()> { #[test] fn spacing_9_3_3_6() -> Result<()> { - let expr = "sin2β= - 2sinβcosβ"; + let expr = "sin2β= + 2sinβcosβ"; test_braille("UEB", expr, "⠎⠔⠼⠃⠨⠃⠀⠐⠶⠀⠼⠃⠎⠊⠝⠨⠃⠉⠕⠎⠨⠃")?; return Ok(()); @@ -1121,9 +1947,9 @@ fn text_9_7_1() -> Result<()> { fn stat_9_7_2() -> Result<()> { let expr = "Exp(R)= n2+1"; - // GTM uses "⠰⠰⠰⠠⠑⠭⠏⠐⠣⠠⠗⠐⠜⠀⠐⠶⠀⠷⠝⠨⠌⠼⠃⠾⠐⠖⠼⠁⠰⠄", - // but "⠠⠑⠭⠏⠐⠣⠠⠗⠐⠜⠀⠐⠶⠀⠰⠰⠷⠝⠨⠌⠼⠃⠾⠐⠖⠼⠁" is shorter and is consistent with omission_3_6_7 and fraction_6_4_6 - test_braille("UEB", expr, "⠠⠑⠭⠏⠐⠣⠠⠗⠐⠜⠀⠐⠶⠀⠰⠰⠷⠝⠨⠌⠼⠃⠾⠐⠖⠼⠁")?; + // GTM 2014 9.7 used a passage around the whole equation. GTM 1.7.3(a): one + // symbol indicator on n/2 (same as grade1_1_7_9_5). + test_braille("UEB", expr, "⠠⠑⠭⠏⠐⠣⠠⠗⠐⠜⠀⠐⠶⠀⠰⠷⠝⠨⠌⠼⠃⠾⠐⠖⠼⠁")?; return Ok(()); } @@ -1141,7 +1967,7 @@ fn set_10_1() -> Result<()> { #[test] fn set_10_3() -> Result<()> { - let expr = "3∈A∩B"; + let expr = "3∈A∩B"; test_braille("UEB", expr, "⠼⠉⠀⠘⠑⠀⠠⠁⠨⠦⠠⠃")?; return Ok(()); @@ -1149,7 +1975,7 @@ fn set_10_3() -> Result<()> { #[test] fn set_10_4() -> Result<()> { - let expr = "A∩B⊂A∪B"; + let expr = "A∩B⊂A∪B"; test_braille("UEB", expr, "⠠⠁⠨⠦⠠⠃⠀⠘⠣⠀⠠⠁⠨⠖⠠⠃")?; return Ok(()); @@ -1158,7 +1984,7 @@ fn set_10_4() -> Result<()> { fn set_10_5() -> Result<()> { let expr = "A'∪B'= (A∩B)'"; - test_braille("UEB", expr, "⠰⠰⠰⠠⠁⠶⠨⠖⠠⠃⠶⠀⠐⠶⠀⠐⠣⠠⠁⠨⠦⠠⠃⠐⠜⠶⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠠⠁⠶⠨⠖⠠⠃⠶⠀⠐⠶⠀⠐⠣⠠⠁⠨⠦⠠⠃⠐⠜⠰⠶")?; return Ok(()); } @@ -1166,11 +1992,9 @@ fn set_10_5() -> Result<()> { #[test] fn set_10_6() -> Result<()> { // Note: example uses the wrong char "├" in the display -- should be "⊢" - let expr = "[(p∨q)∧¬p] + let expr = "[(p∨q)∧¬p] ⊢q"; - // Acceptable: GTM does uses a G1 passage indicator: "⠰⠰⠰⠨⠣⠐⠣⠏⠈⠖⠟⠐⠜⠈⠦⠈⠹⠏⠨⠜⠀⠸⠒⠀⠟⠰⠄" - // However, the BANA G1 standing alone rule ("...before a single letter standing alone") applies, so start in G2 mode. - // Corrected to remove the passage indicator + // GTM / BANA 2026: grade 1 passage test_braille("UEB", expr, "⠨⠣⠐⠣⠏⠈⠖⠟⠐⠜⠈⠦⠈⠹⠏⠨⠜⠀⠸⠒⠀⠰⠟")?; return Ok(()); @@ -1187,9 +2011,7 @@ fn example_11_5_1_2() -> Result<()> { #[test] fn example_11_5_1_3() -> Result<()> { let expr = "f'(x)"; - // Acceptable: GTM uses a G1 start indicator: "⠰⠰⠋⠶⠐⠣⠭⠐⠜" - // However, BANA says don't use a word indicator if G1 is in first 3 cells (the ':' needs it) - // Corrected to avoid word indicator + // GTM / BANA 2026: grade 1 word indicator test_braille("UEB", expr, "⠋⠰⠶⠐⠣⠭⠐⠜")?; return Ok(()); @@ -1197,7 +2019,7 @@ fn example_11_5_1_3() -> Result<()> { #[test] fn example_11_5_1_4() -> Result<()> { - let expr = "∂y∂x"; + let expr = "∂y∂x"; test_braille("UEB", expr, "⠰⠰⠷⠈⠙⠽⠨⠌⠈⠙⠭⠾")?; return Ok(()); @@ -1205,11 +2027,11 @@ fn example_11_5_1_4() -> Result<()> { #[test] fn example_11_5_2() -> Result<()> { - let expr = "∫23(2x+1)dx + let expr = "∫23(2x+1)dx =x2+x23 =(32+3)-(22+2) =12-6=6"; - test_braille("UEB", expr, "⠰⠰⠰⠮⠢⠼⠃⠔⠼⠉⠐⠣⠼⠃⠭⠐⠖⠼⠁⠐⠜⠙⠭⠀⠐⠶⠀⠨⠣⠭⠔⠼⠃⠐⠖⠭⠨⠜⠢⠼⠃⠔⠼⠉⠀⠐⠶⠀⠐⠣⠼⠉⠔⠼⠃⠐⠖⠼⠉⠐⠜⠐⠤⠐⠣⠼⠃⠔⠼⠃⠐⠖⠼⠃⠐⠜⠀⠐⠶⠀⠼⠁⠃⠐⠤⠼⠋⠀⠐⠶⠀⠼⠋⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠮⠢⠼⠃⠔⠼⠉⠐⠣⠼⠃⠭⠐⠖⠼⠁⠐⠜⠙⠭⠀⠐⠶⠀⠨⠣⠭⠰⠔⠼⠃⠐⠖⠭⠨⠜⠢⠼⠃⠔⠼⠉⠀⠐⠶⠀⠐⠣⠼⠉⠔⠼⠃⠐⠖⠼⠉⠐⠜⠐⠤⠐⠣⠼⠃⠔⠼⠃⠐⠖⠼⠃⠐⠜⠀⠐⠶⠀⠼⠁⠃⠐⠤⠼⠋⠀⠐⠶⠀⠼⠋")?; return Ok(()); } @@ -1229,19 +2051,19 @@ fn example_11_5_3() -> Result<()> { = n! - r!(n−r)! + r!(n−r)! "; // modified to use "shape" as recommended in a comment on this example - test_braille("UEB", expr, "⠰⠰⠰⠔⠝⠠⠉⠢⠗⠀⠐⠶⠀⠐⠣⠝⠰⠻⠗⠐⠜⠀⠐⠶⠀⠷⠝⠖⠨⠌⠗⠖⠐⠣⠝⠐⠤⠗⠐⠜⠖⠾⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠔⠝⠠⠉⠢⠗⠀⠐⠶⠀⠐⠣⠝⠰⠻⠗⠐⠜⠀⠐⠶⠀⠰⠰⠷⠝⠖⠨⠌⠗⠖⠐⠣⠝⠐⠤⠗⠐⠜⠖⠾")?; return Ok(()); } #[test] fn example_11_5_4() -> Result<()> { - let expr = "a∗(b◦c) - =(a∗b)◦(a∗c)"; + let expr = "a∗(b◦c) + =(a∗b)◦(a∗c)"; test_braille("UEB", expr, "⠁⠐⠔⠐⠣⠃⠐⠴⠉⠐⠜⠀⠐⠶⠀⠐⠣⠁⠐⠔⠃⠐⠜⠐⠴⠐⠣⠁⠐⠔⠉⠐⠜")?; return Ok(()); @@ -1252,11 +2074,11 @@ fn example_11_5_5_2() -> Result<()> { let expr = " f - − 1 + − 1 : Y - → + → X "; test_braille("UEB", expr, "⠰⠰⠰⠋⠔⠣⠐⠤⠼⠁⠜⠒⠀⠠⠽⠀⠳⠕⠀⠠⠭⠰⠄")?; @@ -1268,17 +2090,17 @@ fn example_11_5_5_2() -> Result<()> { fn example_11_5_5_3() -> Result<()> { // this comes from MathJax let expr = " - ∀ + ∀ y - ∈ + ∈ Y - ∃ + ∃ x - ∈ + ∈ X "; - test_braille("UEB", expr, "⠰⠰⠰⠘⠁⠽⠀⠘⠑⠀⠠⠽⠀⠘⠢⠭⠀⠘⠑⠀⠠⠭⠰⠄")?; + test_braille("UEB", expr, "⠘⠁⠽⠀⠘⠑⠀⠰⠠⠽⠀⠘⠢⠭⠀⠘⠑⠀⠰⠠⠭")?; return Ok(()); } @@ -1291,7 +2113,7 @@ fn example_11_5_6() -> Result<()> { x + y = 6 return Ok(()); } "; - test_braille("UEB", expr, "⠰⠰⠰⠸⠣⠐⠣⠭⠂⠀⠽⠐⠜⠀⠸⠳⠀⠭⠐⠖⠽⠀⠐⠶⠀⠼⠋⠸⠜⠰⠄")?; + test_braille("UEB", expr, "⠸⠣⠐⠣⠰⠭⠂⠀⠰⠽⠐⠜⠀⠸⠳⠀⠭⠐⠖⠽⠀⠐⠶⠀⠼⠋⠸⠜")?; return Ok(()); } @@ -1315,7 +2137,7 @@ fn example_11_6() -> Result<()> { fn bar_over_12_1_1() -> Result<()> { let expr = "x_= 10+11+123"; - test_braille("UEB", expr, "⠰⠰⠰⠭⠱⠀⠐⠶⠀⠷⠼⠁⠚⠐⠖⠼⠁⠁⠐⠖⠼⠁⠃⠨⠌⠼⠉⠾⠰⠄")?; + test_braille("UEB", expr, "⠭⠰⠱⠀⠐⠶⠀⠰⠷⠼⠁⠚⠐⠖⠼⠁⠁⠐⠖⠼⠁⠃⠨⠌⠼⠉⠾")?; return Ok(()); } @@ -1346,8 +2168,8 @@ fn dot_12_1_4() -> Result<()> { #[test] fn dot_12_1_5() -> Result<()> { - let expr = "0.561˙ - 23˙"; + let expr = "0.561˙ + 23˙"; test_braille("UEB", expr, "⠼⠚⠲⠑⠋⠣⠼⠁⠜⠘⠲⠼⠃⠣⠼⠉⠜⠘⠲")?; return Ok(()); @@ -1355,7 +2177,7 @@ fn dot_12_1_5() -> Result<()> { #[test] fn dot_12_1_6_single() -> Result<()> { - let expr = "x˙"; + let expr = "x˙"; test_braille("UEB", expr, "⠭⠘⠲")?; return Ok(()); @@ -1363,7 +2185,7 @@ fn dot_12_1_6_single() -> Result<()> { #[test] fn dot_12_1_6_double() -> Result<()> { - let expr = "x¨"; + let expr = "x¨"; test_braille("UEB", expr, "⠰⠰⠭⠨⠔⠣⠲⠲⠜")?; return Ok(()); @@ -1372,9 +2194,7 @@ fn dot_12_1_6_double() -> Result<()> { #[test] fn hat_12_1_7() -> Result<()> { let expr = "AB^C"; - // Acceptable: GTM uses a G1 start indicator: "⠰⠰⠠⠁⠠⠃⠐⠱⠠⠉" - // BANA says use a word indicator if G1 not in first 3 cells (modified it to not count cap indicators since that helps with GTM compatibility) - // Corrected to skip the G1 indicator at the start (it's debatable as to which is better) + // GTM / BANA 2026: grade 1 word indicator test_braille("UEB", expr, "⠠⠁⠠⠃⠰⠐⠱⠠⠉")?; return Ok(()); @@ -1400,7 +2220,7 @@ fn arrow_under_12() -> Result<()> { #[test] fn bar_12_2_1() -> Result<()> { - let expr = "xy¯"; + let expr = "xy¯"; test_braille("UEB", expr, "⠰⠰⠭⠔⠣⠽⠱⠜")?; return Ok(()); @@ -1408,7 +2228,7 @@ fn bar_12_2_1() -> Result<()> { #[test] fn bar_12_2_2() -> Result<()> { - let expr = "xy¯"; + let expr = "xy¯"; test_braille("UEB", expr, "⠰⠰⠣⠭⠔⠽⠜⠱")?; return Ok(()); @@ -1416,7 +2236,7 @@ fn bar_12_2_2() -> Result<()> { #[test] fn shape_14_1_1_1() -> Result<()> { - let expr = "△ ABC"; + let expr = "△ ABC"; test_braille("UEB", expr, "⠰⠫⠼⠉⠀⠠⠠⠁⠃⠉")?; return Ok(()); @@ -1424,7 +2244,7 @@ fn shape_14_1_1_1() -> Result<()> { #[test] fn shape_14_1_2_1() -> Result<()> { - let expr = "△ABC"; + let expr = "△ABC"; test_braille("UEB", expr, "⠰⠫⠼⠉⠱⠠⠠⠁⠃⠉")?; return Ok(()); @@ -1433,11 +2253,11 @@ fn shape_14_1_2_1() -> Result<()> { #[test] fn shape_14_1_2_2() -> Result<()> { // the for the shapes are wrong -- but it isn't clear what they should be (from WIRIS editor) - let expr = "{□, -  ◍, -  ▲, + let expr = "{□, +  ◍, +  ▲, return Ok(()); -  ▧ …}"; +  ▧ …}"; test_braille("UEB", expr, "⠸⠣⠰⠫⠼⠙⠱⠂⠀⠨⠫⠿⠱⠂⠀⠸⠫⠼⠉⠱⠂⠀⠨⠫⠼⠙⠀⠲⠲⠲⠸⠜")?; return Ok(()); } @@ -1584,11 +2404,8 @@ fn omission_15_4_1() -> Result<()> { #[test] fn chem_16_2_8() -> Result<()> { let expr = "Ca(OH)2"; - // Acceptable: GTM does not use a G1 start indicator: "⠠⠉⠁⠐⠣⠠⠕⠠⠓⠐⠜⠰⠢⠼⠃" - // However, BANA says use a word indicator if G1 not in first 3 cells (it is before the subscript near the end); use passage if >=2 whitespace - // This seems like a debateable choice in this case since there is only one G1 indicator, but that's the BANA guidance so... - // Corrected to use word indicator - test_braille("UEB", expr, "⠰⠰⠠⠉⠁⠐⠣⠠⠕⠠⠓⠐⠜⠢⠼⠃")?; + // GTM / BANA 2026: single G1 symbol for subscript (no word indicator) + test_braille("UEB", expr, "⠠⠉⠁⠐⠣⠠⠕⠠⠓⠐⠜⠰⠢⠼⠃")?; return Ok(()); } @@ -1623,7 +2440,7 @@ fn chem_16_2_9() -> Result<()> { - ⋅ + ⋅ @@ -1658,11 +2475,8 @@ fn chem_16_2_9() -> Result<()> { "; - // Acceptable: GTM does not use a G1 start indicator: "⠠⠉⠥⠠⠎⠠⠕⠰⠢⠼⠙⠐⠲⠼⠑⠠⠓⠢⠼⠃⠠⠕" - // However, BANA says use a word indicator if G1 not in first 3 cells (it is before the subscript); use passage if >=2 whitespace - // This seems like a debatable choice in this case since there is only one G1 indicator, but that's the BANA guidance so... - // Corrected to use word indicator - test_braille("UEB", expr, "⠰⠰⠠⠉⠥⠠⠎⠠⠕⠢⠼⠙⠐⠲⠼⠑⠠⠓⠢⠼⠃⠠⠕")?; + // GTM / BANA 2026: single G1 symbol for first subscript (no word indicator) + test_braille("UEB", expr, "⠠⠉⠥⠠⠎⠠⠕⠰⠢⠼⠙⠐⠲⠼⠑⠠⠓⠢⠼⠃⠠⠕")?; return Ok(()); } @@ -1693,14 +2507,14 @@ fn chem_16_2_12() -> Result<()> { R - ⋅ + ⋅ CH ( OH ) - ⋅ + ⋅ CH @@ -1708,7 +2522,7 @@ fn chem_16_2_12() -> Result<()> { 2 - ⋅ + ⋅ CH @@ -1716,7 +2530,7 @@ fn chem_16_2_12() -> Result<()> { 2 - ⋅ + ⋅ CO @@ -1726,9 +2540,8 @@ fn chem_16_2_12() -> Result<()> { H "; - // GTM uses G2 mode and has two G1 indicators (in middle and near end). That definitely violates BANA guidelines and maybe there guidelines. - // I have switched it to G1 word mode, which seems better (same length, but no switching) - test_braille("UEB", expr, "⠰⠰⠠⠠⠠⠗⠐⠲⠉⠓⠐⠣⠕⠓⠐⠜⠐⠲⠉⠓⠢⠼⠃⠐⠲⠉⠓⠢⠼⠃⠐⠲⠉⠕⠢⠼⠃⠰⠓⠠⠄")?; + // GTM / BANA 2026: G2 with inline G1 symbols (not forced word mode) + test_braille("UEB", expr, "⠠⠠⠠⠗⠐⠲⠡⠐⠣⠕⠓⠐⠜⠐⠲⠡⠰⠢⠼⠃⠐⠲⠉⠓⠢⠼⠃⠐⠲⠉⠕⠢⠼⠃⠰⠓⠠⠄")?; return Ok(()); } @@ -1815,7 +2628,7 @@ fn chem_16_5_1() -> Result<()> { - → + → Na @@ -1861,7 +2674,7 @@ fn chem_16_5_1() -> Result<()> { "#; - test_braille("UEB", expr, "⠰⠰⠰⠼⠃⠠⠝⠁⠠⠕⠠⠓⠐⠖⠠⠓⠢⠼⠃⠠⠎⠠⠕⠢⠼⠙⠀⠳⠕⠀⠠⠝⠁⠢⠼⠃⠠⠎⠠⠕⠢⠼⠙⠐⠖⠼⠃⠠⠓⠢⠼⠃⠠⠕⠰⠄")?; + test_braille("UEB", expr, "⠼⠃⠠⠝⠁⠠⠕⠠⠓⠐⠖⠠⠓⠢⠼⠃⠠⠎⠠⠕⠢⠼⠙⠀⠰⠳⠕⠀⠠⠝⠁⠰⠢⠼⠃⠠⠎⠠⠕⠢⠼⠙⠐⠖⠼⠃⠠⠓⠢⠼⠃⠠⠕")?; return Ok(()); } @@ -1872,7 +2685,7 @@ fn chem_16_5_2() -> Result<()> { let expr = r#" N2 - →Haber processH2 + →Haber processH2 N H3 @@ -1952,7 +2765,7 @@ fn chem_16_5_4() -> Result<()> { - → + → @@ -1983,7 +2796,7 @@ fn chem_16_5_4() -> Result<()> { - ⋅ + ⋅ @@ -1995,7 +2808,7 @@ fn chem_16_5_4() -> Result<()> { - ⋅ + ⋅ @@ -2005,7 +2818,7 @@ fn chem_16_5_4() -> Result<()> { - → + → @@ -2040,7 +2853,7 @@ fn chem_16_5_4() -> Result<()> { - ⋅ + ⋅ @@ -2052,7 +2865,7 @@ fn chem_16_5_4() -> Result<()> { - ⋅ + ⋅ @@ -2111,16 +2924,16 @@ fn chem_16_5_5() -> Result<()> { - ↽ + ↽ - − + − - − + − - ⇀ + ⇀ @@ -2128,7 +2941,7 @@ fn chem_16_5_5() -> Result<()> { "#; - test_braille("UEB", expr, "⠰⠰⠰⠠⠏⠃⠔⠣⠐⠖⠐⠖⠜⠐⠖⠼⠃⠰⠑⠀⠘⠸⠶⠀⠠⠏⠃⠰⠄")?; + test_braille("UEB", expr, "⠰⠰⠠⠏⠃⠔⠣⠐⠖⠐⠖⠜⠐⠖⠼⠃⠰⠑⠀⠰⠘⠸⠶⠀⠠⠏⠃")?; return Ok(()); } diff --git a/tests/braille/UEB/other.rs b/tests/braille/UEB/other.rs index 7dda38f6c..9b8a1ab29 100644 --- a/tests/braille/UEB/other.rs +++ b/tests/braille/UEB/other.rs @@ -12,7 +12,7 @@ use anyhow::Result; #[test] fn overscript_grouping_aph_5_4_8() -> Result<()> { // this test was added because #220 (failed to add grouping around overscript) - let expr = " MN ↔ "; + let expr = " MN ↔ "; test_braille("UEB", expr, "⠰⠰⠣⠠⠠⠍⠝⠜⠨⠔⠳⠺⠗⠕")?; return Ok(()); @@ -39,7 +39,7 @@ fn blank_aph_7_1_ex5() -> Result<()> { #[test] fn word_symbol_aph_10_3_11() -> Result<()> { // this test was added because ⊻ (U+22bb) uses a 'G1 Word mode' char, so is different than others - let expr = " p ⊻ q "; + let expr = " p ⊻ q "; test_braille("UEB", expr, "⠰⠰⠏⠈⠖⠠⠱⠟")?; return Ok(()); @@ -247,6 +247,23 @@ fn ueb_no_italic_typeform_for_math_letters() -> Result<()> { return Ok(()); } +#[test] +fn ueb_space_because_and_qed() -> Result<()> { + // ∵ and ∎ are spaced like ∴ (GTM 11 miscellaneous; same mo AddSpaces path as 1.7.9). + test_braille("UEB", "∵x=1", "⠈⠌⠀⠰⠭⠀⠐⠶⠀⠼⠁")?; + test_braille("UEB", "x=1∎", "⠰⠭⠀⠐⠶⠀⠼⠁⠀⠸⠫⠼⠙⠱")?; + return Ok(()); +} + +#[test] +fn ueb_math_typeform_not_part_of_word() -> Result<()> { + // Double-struck/script/fraktur letters are math alphabets, not part of an English + // letters-sequence, so a following whole word still takes its contraction (time → ⠐⠞). + test_braille("UEB", "Rtime", "⠈⠆⠠⠗⠐⠞")?; + test_braille("UEB", "R", "⠈⠆⠰⠠⠗")?; + return Ok(()); +} + #[test] fn ueb_italic_typeform_for_digits() -> Result<()> { // UEB uses italic typeform for digits (GTM 2.7 emphasis of numeric material). From 9ea98c23e8c44eb19975f3da4a0284b5eaf0c056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Wed, 2 Sep 2026 15:42:45 +0200 Subject: [PATCH 05/23] pl: fix five speech/navigation defects and catch up with recent en changes (#738) * pl: speak up tack (U+22A5) as perpendicular, matching en Follow-up to 45aefb2d for Polish. Editors commonly emit U+22A5 where perpendicularity is meant, so both U+27C2 and U+22A5 now say "jest prostopadle do". LiteralSpeak keeps reading U+22A5 literally as "dol". Previously Polish said "dol" for U+22A5, so the same formula was read differently in Polish than in English. Adds up_tack_330 to tests/Languages/pl/alphabets.rs, mirroring the English test. * pl: adopt the `|` argument-glue syntax from definitions.yaml Follow-up to 4347d884 for Polish. That commit added the `|` syntax and updated the Polish tests, but not the Polish rule files, so several intents lost their function name in speech. Fixed, with the spoken output before -> after: quotient "podzielone przez z x przecinek, y" -> "czesc calkowita z x podzielone przez y" remainder "podzielone przez z x przecinek, y" -> "reszta z x podzielone przez y" set-difference "i z wielka a przecinek, wielka b" -> "roznica zbiorow z wielka a i wielka b" polar-coordinate "przecinek z x przecinek, y" -> "wspolrzedna biegunowa z x przecinek, y" The `|` syntax needs the function-intent rule to call IntentFunctionUseArityPath / IntentFunctionGlueBefore. Only en and hu had it, so it is now ported to pl (with "of" -> "z"). Also here: * SharedRules/geometry.yaml: the `coordinate` rule matched "." instead of "not(*[@arg])", so it swallowed coordinate($x,...) intents that should fall through to IntentMappings. Its name was also mistranslated as "przecinek" (comma) rather than "punkt" (point). * transpose: fixity order now matches en (postfix first). The function form is tested explicitly via intent='transpose:function($x)', as en does. * empty-set: added, it was missing. NOT adopted: arity templates ("| po | od,do") for sum/product. intent_function_glue_before in src/infer_intent.rs hardcodes the English word "of" for the last argument, which yields "suma po i of x" in Polish. This affects every non-English language; hu avoids it the same way. The binary separator form works correctly and is what this commit uses. * pl: fix navigation direction words, unreachable for any translation Follow-up to ec36e057 and 080ca162 for Polish, but it also fixes a long-standing Polish bug rather than only porting the new code. navigate.yaml compared the suffix of $NavCommand (always English, e.g. "ZoomIn") against a substring offset by the length of the SPOKEN $Prefix. For English those are the same; for any translation they are not. With "przybliz" (8 chars) vs "Zoom" (4), "ZoomIn" was cut to "" instead of "In", so ALL 16 branches were dead: ZoomIn -> "" (want "In") ZoomOutAll -> "ll" (want "OutAll") MoveNext -> "t" (want "Next") DescribeNext -> "ibeNext" (want "Next") Users heard "przejdz; do mianownika" with no direction, never "przejdz w prawo". Using $CommandOffset, as ec36e057 introduced, fixes all of them. Two more things here: * Polish needs two verbs where English reuses "zoom": "przybliz na zewnatrz" (zoom in outwards) is self-contradictory, so ZoomOut* now says "oddal". The direction word for plain In/Out is dropped, as the verb already carries it: "przybliz" / "oddal", and "przybliz maksymalnie" / "oddal maksymalnie". * Ports into-or-out-of-prefix-or-silent-without-parts (080ca162) and the SpeakIntentName fallbacks in into-or-out-of-default, keeping our own Polish preposition logic (including "ze stopnia" euphony). Adds zoom_speech_pl and move_char_speech_pl. Both fail on the old formula, showing the missing direction word, so they do discriminate. * pl: announce table column and row separators Follow-up to fbc49bb7 (#679) for Polish. The HasVisibleColumnLine / HasVisibleRowLine rules were missing from pl/SharedRules/default.yaml, so visible lines in a matrix were silent for Polish users, e.g. an augmented matrix was read exactly like a plain one. before: "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, 4; ..." after: "2 na 3 macierz rozszerzona; wiersz 1; 3, 1, separator, 4; ..." Two existing tests (augmented_matrix_2x3, augmented_matrix_3x4_end_matrix) were pinning the pre-#679 output; their English counterparts already expect "separator", so they are updated rather than worked around. Adds dashed_augmented_matrix_separator and matrix_row_separator, ported from tests/Languages/en/mtable.rs. Removing either rule fails all four tests, so they discriminate. * pl: clear the remaining untranslated unicode entries The audit tool reported 81 unicode entries whose text equals the English source. Reviewing them one by one, only two were actually untranslated: U+2127 "mhos" -> "mho" (unit, as nb and sv have it) U+2644 "Saturn" (Polish spelling is the same; key raised) The other 75 are correct as-is and only needed the verified key: * 30 Roman numerals (U+2160..U+217F) spelled out letter by letter * 29 space, PUA and zero-width entries with no speech at all * 6 typographic ligatures (ff, fl, ffi, ffl, ft, st) * 10 proper names and symbols (spesmilos, paragraphos, hypodiastole, digamma, differential d, imaginary j, oV, pH) Four more in unicode.yaml (digit separator, space, U+2062, U+2063) likewise carry no translatable speech. Raising the key on an entry whose text legitimately matches English is what the convention is for; it is not the same as marking English text as verified. Only the wording of "mhos" changed - the diff is otherwise key case only, checked line by line. Audit's "untranslated" for unicode files: 81 -> 0. --- Rules/Languages/pl/SharedRules/default.yaml | 47 ++++- Rules/Languages/pl/SharedRules/geometry.yaml | 10 +- Rules/Languages/pl/definitions.yaml | 35 ++-- Rules/Languages/pl/navigate.yaml | 80 ++++++--- Rules/Languages/pl/unicode-full.yaml | 173 +++++++++---------- Rules/Languages/pl/unicode.yaml | 8 +- src/navigate.rs | 53 ++++++ tests/Languages/pl/alphabets.rs | 15 ++ tests/Languages/pl/definitions.rs | 40 ++++- tests/Languages/pl/mtable.rs | 47 ++++- 10 files changed, 356 insertions(+), 152 deletions(-) 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 a3365ef56..1fac4e766 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 = "a⟂b"; // 0x27c2 + test("pl", "SimpleSpeak", perp, "a jest prostopadłe do b")?; + test("pl", "LiteralSpeak", perp, "a jest prostopadłe do b")?; + let up_tack = "a⊥b"; // 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(()) +} From df565e27cdf776249c7f97d37f126c38e6fcfeed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Thu, 3 Sep 2026 12:59:09 +0200 Subject: [PATCH 06/23] pl: inflect unit names according to the numeral, not with an English "s" (#744) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * pl: mark the unicode translations as verified (t -> T) Mechanical change: 2435 text keys raised from t/ot/ct to T/OT/CT in the two unicode files. No text is touched. The Polish rules were written before the lowercase/uppercase convention was in use, so entries that have been translated all along still carried the "needs review" key. The audit tool therefore reported them as untranslated, which made the real gaps impossible to see: audit-translations pl, untranslated text: 3162 -> 727 The remaining 727 are in the rule files, where the entries need reading rather than a mechanical pass, so they are deliberately left alone. Every raised entry was checked to differ from the English source, i.e. it really is translated. Entries whose text legitimately equals English (Roman numerals, ligatures, proper names, whitespace) were handled separately in the previous PR; entries still holding English text are NOT raised, since that would assert a translation that does not exist. Verification: cargo test --test languages Languages::pl 609 passed, 0 failed diff: 2436 insertions, 2436 deletions, zero changes outside key case The last point is checked by normalising the key case in the diff and confirming no unpaired lines remain (without normalising, 4710 remain, so the check does discriminate). * pl: also mark the multi-line unicode entries as verified The previous commit raised the key on entries written on a single line (`- "±": [t: "..."]`), but not on entries whose body is a block: - "°": - test: if: "parent::*[name(.)='msup' ...]" then: [t: "stopni"] else: [t: "stopień"] Those are exactly the entries carrying inflection or a TTS condition, so 312 of the most deliberate translations in the file were left looking unreviewed. This raises them: 64 in unicode.yaml, 247 in unicode-full.yaml and one single-line entry (U+23E6) missed earlier. One entry is deliberately left with a lower-case key: `t: ""` for U+00A0, the else-branch of the `@data-empty-in-2D` test. That is silence rather than text, and an upper-case key means "a translator checked this wording" - there is no wording to check. English keeps a lower-case key there too. No content changes; only key case. `cargo test --test languages Languages::pl` gives 609 passed, 0 failed, which is the same result as before this commit, as expected for a change the engine treats as equivalent (src/speech.rs matches "t"|"T" in one match arm). * pl: raise the remaining rule-file keys and test the number-set rules Two loose ends in the Polish localization. **Rule-file keys.** 248 entries in the rule files still used a lower-case key while carrying translated Polish text. Content is untouched - every one of the 248 changed lines differs from its predecessor only in the case of the key name, verified line by line after normalizing the key. 17 entries are deliberately left lower-case: five are the letters C, N, Q, R, Z in `dimension-number-sets` (the letter itself is the wording, as in English); `ct: "s"`/`ct: "-"` in the unit rule are the plural suffix and prefix separator; `navigate.yaml:176` is a Polish euphony variant ("ze" before "st-"); the remaining seven are XPath expressions rather than speech. **Tests for the number-set rules.** These rules had no Polish test at all, in a file where two silent defects were already found. New `tests/Languages/pl/number_sets.rs` covers the bare symbols, the dimension form, both sign variants, and ClearSpeak agreeing with SimpleSpeak. The `number_set_with_variable_exponent` case is the negative control: `dimension-number-sets` fires on `count(*)=2`, so a non-numeric exponent must fall through to the full phrase ("liczby całkowite do potęgi n") rather than being read as a dimension. Without it, a rule that swallowed every superscript would still pass. Polish keeps the letter with a dimension ("R 3"), matching en, de, fr, nb, sv, fi and es; Hungarian is the only language that translates in that position too. Measured with the SAPI voice NVDA actually uses: "R 3" is byte-identical to a phonetic "er 3" and "N 4" to "en 4", so the letters are pronounced as their Polish names. cargo test --test languages Languages::pl 614 passed, 0 failed * pl: inflect unit names according to the numeral, not with an English "s" The `unit` rule appended `ct: "s"` whenever a unit had no entry in `PluralForms`, and the Polish `PluralForms` contained no SI base unit at all. Measured output of the engine before this change: 1 metr, 2 metrs, 5 metrs, 21 metrs, 2 grams, 2 sekundas, 2 ampers, 2 mols, 2 kilo-metrs So a Polish NVDA user heard an English plural ending on essentially every quantity. Hungarian avoids this with `CT: ""` (it appends nothing); French and German legitimately use "s"; Russian, whose plurals work like Polish, does not rely on a suffix at all and fills in `PluralForms` instead. Polish was in the wrong group. Polish does not have one plural form. The noun follows the numeral: 1 metr | 2, 3, 4 metry (nominative plural) | 5 metrów (genitive plural) and the teens are the exception that breaks the naive rule: 12, 13, 14 metrów, likewise 112-114, while 22 and 102 take the nominative again. One extra plural column is therefore not enough, so this adds a second definition section, `PluralGenitive`, next to `PluralForms` (now the nominative plural). No Rust change is needed: `build_values` accepts any definition name as a hashmap. The `unit` rule (both the bare and the prefixed branch) and the `currency` rule now read the value of the numeral and pick the section accordingly. When the numeral cannot be determined - a variable coefficient, as in "x ms" - `$Coefficient` is 0 and the genitive is used, which is also what Polish uses for unknown quantities ("x mili-sekund"). Where no inflected form is known the singular is spoken rather than a guessed ending: a wrong ending is worse for a screen reader user than a missing one. Both sections cover all 131 unit and currency names that the Polish `SIUnits`, `UnitsWithoutPrefixes`, `EnglishUnits` and `CurrencySymbols` can produce. The forms are written out because Polish inflection cannot be derived from the ending: metr/metry but litr/litry, om/omy, dzień/dni, tydzień/tygodnie, rok/lata. Multi-word units inflect the head noun and keep the dependent word's case ("5 lat świetlnych", "5 minut łuku"). They were checked against hunspell pl_PL; the only words it does not know are the binary-prefix neologisms (kibibajt, gibibit, ...) whose singular forms already existed in the file. Three base forms were themselves wrong - plurals used as singulars, so the engine said "1 herce" and "1 konie mechaniczne": Hz herce -> herc hp konie mechaniczne -> koń mechaniczny ℧ M h o -> mho Every other language has a singular here (en hertz, ru герц, fi hertsi, es hercio; hp: ru "лошадиная сила", hu "lóerő", nb "hestekraft"; ℧: de/fr "mho"). Why this survived: the existing Polish expectations in tests/Languages/pl/units.rs recorded the broken output, so 609 tests passed while the speech was wrong ("2 dzieńs", "2 tydzieńs", "kwetta-grams"). Expectations harvested from real engine output are a good regression net but prove nothing about correctness unless they are read as a user would hear them. 21 test expectations are updated here, each difference reviewed word by word. Verification: cargo test --test languages Languages::pl 615 passed, 0 failed reverting general.yaml alone -> 6 of 6 new tests fail The new tests in tests/Languages/pl/unit_plurals.rs cover one class of phenomenon each: the three numeral classes including the teens exception, SI base units, the prefixed branch of the rule, irregular nouns, the corrected base forms, and multi-word units. --- Rules/Languages/pl/ClearSpeak_Rules.yaml | 50 +- Rules/Languages/pl/SharedRules/calculus.yaml | 12 +- Rules/Languages/pl/SharedRules/default.yaml | 80 +- Rules/Languages/pl/SharedRules/general.yaml | 189 +- Rules/Languages/pl/SharedRules/geometry.yaml | 14 +- .../pl/SharedRules/linear-algebra.yaml | 2 +- Rules/Languages/pl/definitions.yaml | 286 +- Rules/Languages/pl/navigate.yaml | 152 +- Rules/Languages/pl/overview.yaml | 30 +- Rules/Languages/pl/unicode-full.yaml | 5238 ++++++++--------- Rules/Languages/pl/unicode.yaml | 262 +- tests/Languages/pl.rs | 2 + tests/Languages/pl/ClearSpeak/mfrac.rs | 2 +- tests/Languages/pl/SimpleSpeak/mfrac.rs | 6 +- tests/Languages/pl/number_sets.rs | 69 + tests/Languages/pl/unit_plurals.rs | 86 + tests/Languages/pl/units.rs | 38 +- 17 files changed, 3474 insertions(+), 3044 deletions(-) create mode 100644 tests/Languages/pl/number_sets.rs create mode 100644 tests/Languages/pl/unit_plurals.rs diff --git a/Rules/Languages/pl/ClearSpeak_Rules.yaml b/Rules/Languages/pl/ClearSpeak_Rules.yaml index 5e6cca14c..c7bb0fc7f 100644 --- a/Rules/Languages/pl/ClearSpeak_Rules.yaml +++ b/Rules/Languages/pl/ClearSpeak_Rules.yaml @@ -228,13 +228,13 @@ tag: fraction match: "." replace: - - t: "ułamek z licznikiem" # phrase(the 'fraction with numerator' 6) + - T: "ułamek z licznikiem" # phrase(the 'fraction with numerator' 6) - test: if: "not(IsNode(*[1], 'simple'))" then: [pause: medium] - x: "*[1]" - pause: medium - - t: "i mianownikiem" # phrase(the fraction with numerator 5 'and denominator' 8) + - T: "i mianownikiem" # phrase(the fraction with numerator 5 'and denominator' 8) - x: "*[2]" - pause: long - test: @@ -525,7 +525,7 @@ replace: - test: - if: "count(*)=0" - then: [t: "zbiór pusty"] # phrase('the empty set') + then: [T: "zbiór pusty"] # phrase('the empty set') - else_if: "count(*)=2" then: - test: @@ -537,10 +537,10 @@ - test: if: "$Verbosity!='Terse'" then: [T: ""] # phrase('the' set of all integers) - - t: "zbiór" # phrase(this is a 'set of' numbers) + - T: "zbiór" # phrase(this is a 'set of' numbers) - test: if: "$ClearSpeak_Sets != 'woAll'" - then: [t: "wszystkie"] # phrase(the set of 'all' integers) + then: [T: "wszystkie"] # phrase(the set of 'all' integers) - x: "*[1]/*[1]" - T: "takich że" # phrase(the set S 'such that' x is less than y) - x: "*[1]/*[3]" @@ -645,31 +645,31 @@ - if: "$IsCase" then_test: - if: "$LineCount = 1" - then: [t: "przypadek"] # phrase(this is the first 'case' of three cases) + then: [T: "przypadek"] # phrase(this is the first 'case' of three cases) - else_if: "$Paucal" - then: [t: "przypadki"] # phrase(there are 'two cases' to consider) - else: [t: "przypadków"] # phrase(there are 'five cases' to consider) + then: [T: "przypadki"] # phrase(there are 'two cases' to consider) + else: [T: "przypadków"] # phrase(there are 'five cases' to consider) - else_if: "$IsLine" then_test: - if: "$LineCount = 1" - then: [t: "linia"] # phrase(this is the first 'line' of three lines) + then: [T: "linia"] # phrase(this is the first 'line' of three lines) - else_if: "$Paucal" - then: [t: "linie"] # phrase(there are 'two lines' shown) - else: [t: "linii"] # phrase(there are 'five lines' shown) + then: [T: "linie"] # phrase(there are 'two lines' shown) + else: [T: "linii"] # phrase(there are 'five lines' shown) - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" then_test: - if: "$LineCount = 1" - then: [t: "warunek"] # phrase(this is the first 'constraint' of three constraints) + then: [T: "warunek"] # phrase(this is the first 'constraint' of three constraints) - else_if: "$Paucal" - then: [t: "warunki"] # phrase(there are 'two constraints' to satisfy) - else: [t: "warunków"] # phrase(there are 'five constraints' to satisfy) + then: [T: "warunki"] # phrase(there are 'two constraints' to satisfy) + else: [T: "warunków"] # phrase(there are 'five constraints' to satisfy) - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" then_test: - if: "$LineCount = 1" - then: [t: "równanie"] # phrase(this is the first 'equation' of three equations) + then: [T: "równanie"] # phrase(this is the first 'equation' of three equations) - else_if: "$Paucal" - then: [t: "równania"] # phrase(there are 'two equations' to solve) - else: [t: "równań"] # phrase(there are 'five equations' to solve) + then: [T: "równania"] # phrase(there are 'two equations' to solve) + else: [T: "równań"] # phrase(there are 'five equations' to solve) - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" then_test: - if: "$LineCount = 1" @@ -680,10 +680,10 @@ - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" then_test: - if: "$LineCount = 1" - then: [t: "krok"] # phrase(this is the first 'step' of three steps) + then: [T: "krok"] # phrase(this is the first 'step' of three steps) - else_if: "$Paucal" - then: [t: "kroki"] # phrase(there are 'two steps' to follow) - else: [t: "kroków"] # phrase(there are 'five steps' to follow) + then: [T: "kroki"] # phrase(there are 'two steps' to follow) + else: [T: "kroków"] # phrase(there are 'five steps' to follow) # else 'None -- don't say anything' - pause: short - x: "*" @@ -700,17 +700,17 @@ - pause: medium - test: - if: "($ClearSpeak_MultiLineLabel = 'Auto' and parent::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case'" - then: [t: "przypadek"] # phrase(in this 'case' x is not equal to y) + then: [T: "przypadek"] # 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: "linia"] # phrase(the straight 'line' between x and y) + then: [T: "linia"] # phrase(the straight 'line' between x and y) - else_if: "$ClearSpeak_MultiLineLabel = 'Constraint'" - then: [t: "warunek"] # phrase(there is a 'constraint' on possible values) + then: [T: "warunek"] # phrase(there is a 'constraint' on possible values) - else_if: "$ClearSpeak_MultiLineLabel = 'Equation'" - then: [t: "równanie"] # phrase(the 'equation' pi r squared gives the area of a circle) + then: [T: "równanie"] # phrase(the 'equation' pi r squared gives the area of a circle) - else_if: "$ClearSpeak_MultiLineLabel = 'Row'" then: [T: "wiersz"] # phrase(the values on the top 'row' are relevant) - else_if: "$ClearSpeak_MultiLineLabel = 'Step'" - then: [t: "krok"] # phrase(this is a 'step' by step process) + then: [T: "krok"] # 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: diff --git a/Rules/Languages/pl/SharedRules/calculus.yaml b/Rules/Languages/pl/SharedRules/calculus.yaml index 777ca4171..4d499f9a8 100644 --- a/Rules/Languages/pl/SharedRules/calculus.yaml +++ b/Rules/Languages/pl/SharedRules/calculus.yaml @@ -4,7 +4,7 @@ tag: laplacian match: "count(*) <= 1" # can be on ∇^2 or on enclosing mrow replace: - - t: "laplasjan" # phrase('laplacian' of x) -- "LahPlahsian" sounds better with speech engines tested + - T: "laplasjan" # phrase('laplacian' of x) -- "LahPlahsian" sounds better with speech engines tested - test: if: "count(*) = 1" then: @@ -22,8 +22,8 @@ replace: - test: if: "$Verbosity='Terse'" - then: [t: "dywergencja"] # phrase('div' is short for divergence) -- note OneCore voices spell out "div" - else: [t: "dywergencja z"] # phrase('divergence of' this function from the mean) + then: [T: "dywergencja"] # phrase('div' is short for divergence) -- note OneCore voices spell out "div" + else: [T: "dywergencja z"] # phrase('divergence of' this function from the mean) - test: if: "not(IsNode(*[1], 'leaf'))" then: [pause: short] @@ -33,7 +33,7 @@ tag: curl match: "count(*) = 1" replace: - - t: "rotacja" # phrase(the 'curl of' a field) + - T: "rotacja" # phrase(the 'curl of' a field) - test: if: "$Verbosity!='Terse'" then: [T: "z"] # phrase(function 'of' one variable) -- note OneCore voices spell out "div" @@ -48,8 +48,8 @@ replace: - test: if: "$Verbosity!='Terse'" - then: [t: "gradient z"] # phrase(the hill has a 'gradient of' five percent) - else: [t: "gradient"] # phrase(the delete key is labeled 'del') + then: [T: "gradient z"] # phrase(the hill has a 'gradient of' five percent) + else: [T: "gradient"] # phrase(the delete key is labeled 'del') - test: if: "not(IsNode(*[1], 'leaf'))" then: [pause: short] diff --git a/Rules/Languages/pl/SharedRules/default.yaml b/Rules/Languages/pl/SharedRules/default.yaml index 531f57a5d..8397efb7b 100644 --- a/Rules/Languages/pl/SharedRules/default.yaml +++ b/Rules/Languages/pl/SharedRules/default.yaml @@ -100,7 +100,7 @@ tag: ms match: "." replace: - - t: "string" # phrase('the string' is long) + - T: "string" # phrase('the string' is long) - pause: short - x: "text()" @@ -142,7 +142,7 @@ - pause: short - test: if: "$Impairment = 'Blindness'" - then: [t: "koniec ułamka"] # phrase("start of fraction x over y 'end over'") + then: [T: "koniec ułamka"] # phrase("start of fraction x over y 'end over'") - pause: medium @@ -332,7 +332,7 @@ then: - T: "z" # phrase(substitute x 'with' y) - x: "count($Prescripts) div 2" - - t: "lewe indeksy" # phrase(in this equation certain 'prescripts' apply) + - T: "lewe indeksy" # phrase(in this equation certain 'prescripts' apply) - pause: short - test: if: "not($Prescripts[1][self::m:none])" @@ -367,9 +367,9 @@ - test: if: "count($Prescripts) > 4" # give up and just dump them out so at least the content is there then: - - t: "i kolejne lewe indeksy" # phrase(in this case there are values 'and alternating prescripts') + - T: "i kolejne lewe indeksy" # phrase(in this case there are values 'and alternating prescripts') - x: "$Prescripts[position() > 4]" - - t: "koniec lewych indeksów" # phrase(This is where 'end prescripts' occurs) + - T: "koniec lewych indeksów" # phrase(This is where 'end prescripts' occurs) - test: if: "$Postscripts" then: @@ -386,7 +386,7 @@ then: [T: "i"] # phrase(10 is greater than 8 'and' less than 15) - T: "z" # phrase(substitute x 'with' y) - x: "count($Postscripts) div 2" - - t: "prawe indeksy" # phrase(this material includes several 'postscripts') + - T: "prawe indeksy" # phrase(this material includes several 'postscripts') - pause: short - test: if: "not($Postscripts[1][self::m:none])" @@ -452,9 +452,9 @@ - test: if: "count($Postscripts) > 8" # give up and just dump them out so at least the content is there then: - - t: "i kolejne indeksy" # phrase(this situation involves complexities 'and alternating scripts') + - T: "i kolejne indeksy" # phrase(this situation involves complexities 'and alternating scripts') - x: "$Postscripts[position() > 8]" - - t: "koniec indeksów" # phrase(At this point 'end scripts' occurs) + - T: "koniec indeksów" # phrase(At this point 'end scripts' occurs) - name: default tag: mtable @@ -540,7 +540,7 @@ tag: menclose match: "@notation='box' and *[self::m:mtext and .=' ']" replace: - - t: "pusta ramka" # phrase(the 'empty box' contains no values) + - T: "pusta ramka" # 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 @@ -550,29 +550,29 @@ replace: - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' box ')]" - then: [t: "ramka", pause: short] # phrase(the 'box' around the expression) + then: [T: "ramka", pause: short] # phrase(the 'box' around the expression) - test: if: ".[contains(@notation,'roundedbox')]" - then: [t: "zaokrąglona ramka", pause: short] # phrase(the 'round box' around the expression) + then: [T: "zaokrąglona ramka", pause: short] # phrase(the 'round box' around the expression) - test: if: ".[contains(@notation,'circle')]" - then: [t: "okrąg", pause: short] # phrase(the 'circle' around the expression) + then: [T: "okrąg", 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: "linia na" # phrase(draw a straight 'line' on the page) + - T: "linia na" # phrase(draw a straight 'line' on the page) - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]" - then: [t: "lewo", pause: short] # phrase(line on 'left' of the expression) + then: [T: "lewo", pause: short] # phrase(line on 'left' of the expression) - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]" - then: [t: "prawo", pause: short] # phrase(line on 'right' of the expression) + then: [T: "prawo", pause: short] # phrase(line on 'right' of the expression) - test: if: ".[contains(@notation,'top')]" - then: [t: "góra", pause: short] # phrase(line on 'top' of the expression) + then: [T: "góra", pause: short] # phrase(line on 'top' of the expression) - test: if: ".[contains(@notation,'bottom')]" - then: [t: "dół", pause: short] # phrase(line on the 'bottom' of the expression) + then: [T: "dół", 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: @@ -582,77 +582,77 @@ else: - test: if: ".[contains(@notation,'updiagonalstrike')]" - then: [t: "ukośnie w górę", pause: short] # phrase(the line runs 'up diagonal') + then: [T: "ukośnie w górę", pause: short] # phrase(the line runs 'up diagonal') - test: if: ".[contains(@notation,'downdiagonalstrike')]" - then: [t: "ukośnie w dół", pause: short] # phrase(the line runs 'down diagonal') + then: [T: "ukośnie w dół", pause: short] # phrase(the line runs 'down diagonal') - test: if: ".[contains(@notation,'verticalstrike')]" - then: [t: "pionowy", pause: short] # phrase(the line is 'vertical') + then: [T: "pionowy", pause: short] # phrase(the line is 'vertical') - test: if: ".[contains(@notation,'horizontalstrike')]" - then: [t: "poziomy", pause: short] # phrase(the line is 'horizontal') - - t: "krzyż na zewnątrz" # phrase(please 'cross out' the incorrect answer) + then: [T: "poziomy", pause: short] # phrase(the line is 'horizontal') + - T: "krzyż na zewnątrz" # phrase(please 'cross out' the incorrect answer) - pause: short - test: if: ".[contains(@notation,'uparrow')]" - then: [t: "strzałka w górę", pause: short] # phrase(direction is shown by the 'up arrow') + then: [T: "strzałka w górę", pause: short] # phrase(direction is shown by the 'up arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]" - then: [t: "strzałka w dół", pause: short] # phrase(the trend is shown by the 'down arrow') + then: [T: "strzałka w dół", pause: short] # phrase(the trend is shown by the 'down arrow') - test: if: ".[contains(@notation,'leftarrow')]" - then: [t: "strzałka w lewo", pause: short] # phrase(the 'left arrow' indicates going back) + then: [T: "strzałka w lewo", pause: short] # phrase(the 'left arrow' indicates going back) - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' rightarrow ')]" - then: [t: "strzałka w prawo", pause: short] # phrase(the 'right arrow' indicates moving forward) + then: [T: "strzałka w prawo", pause: short] # phrase(the 'right arrow' indicates moving forward) - test: if: ".[contains(@notation,'northeastarrow')]" - then: [t: "strzałka na północny wschód", pause: short] # phrase(direction is indicated by the 'northeast arrow') + then: [T: "strzałka na północny wschód", pause: short] # phrase(direction is indicated by the 'northeast arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southeastarrow ')]" - then: [t: "strzałka na południowy wschód", pause: short] # phrase(direction is shown by the 'southeast arrow') + then: [T: "strzałka na południowy wschód", pause: short] # phrase(direction is shown by the 'southeast arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' southwestarrow ')]" - then: [t: "strzałka na południowy zachód", pause: short] # phrase(direction is shown by the 'southwest arrow') + then: [T: "strzałka na południowy zachód", pause: short] # phrase(direction is shown by the 'southwest arrow') - test: if: ".[contains(@notation,'northwestarrow')]" - then: [t: "strzałka na północny zachód", pause: short] # phrase(direction is shown by the 'northwest arrow') + then: [T: "strzałka na północny zachód", pause: short] # phrase(direction is shown by the 'northwest arrow') - test: if: ".[contains(@notation,'updownarrow')]" - then: [t: "strzałka dwukierunkowa pionowa", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') + then: [T: "strzałka dwukierunkowa pionowa", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') - test: if: ".[contains(@notation,'leftrightarrow')]" - then: [t: "strzałka dwukierunkowa pozioma", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') + then: [T: "strzałka dwukierunkowa pozioma", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') - test: if: ".[contains(@notation,'northeastsouthwestarrow')]" - then: [t: "strzałka dwukierunkowa ukośna w górę", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') + then: [T: "strzałka dwukierunkowa ukośna w górę", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') - test: if: ".[contains(@notation,'northwestsoutheastarrow')]" - then: [t: "strzałka dwukierunkowa ukośna w dół", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') + then: [T: "strzałka dwukierunkowa ukośna w dół", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') - test: if: ".[contains(@notation,'actuarial')]" - then: [t: "symbol aktuarialny", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) + then: [T: "symbol aktuarialny", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) - test: if: ".[contains(@notation,'madrub')]" - then: [t: "arabski symbol silni", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) + then: [T: "arabski symbol silni", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) - test: if: ".[contains(@notation,'phasorangle')]" - then: [t: "kąt fazowy", pause: short] # phrase(the 'phasor angle' is used to measure electrical current) + then: [T: "kąt fazowy", 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: "znak dzielenia pisemnego", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) + then: [T: "znak dzielenia pisemnego", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) - test: if: ".[contains(@notation,'radical')]" then: [T: "pierwiastek kwadratowy", pause: short] # phrase(5 is the 'square root' of 25) - - t: "obejmujący" # phrase(parentheses are 'enclosing' part of the equation) + - T: "obejmujący" # phrase(parentheses are 'enclosing' part of the equation) - test: if: "*[self::m:mtext and .=' ']" then: [T: "spacja"] # 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: "koniec obramowania"] # phrase(reached the 'end enclosure' point) + then: [T: "koniec obramowania"] # phrase(reached the 'end enclosure' point) - pause: short - name: semantics diff --git a/Rules/Languages/pl/SharedRules/general.yaml b/Rules/Languages/pl/SharedRules/general.yaml index 40e996f49..f3d026f2b 100644 --- a/Rules/Languages/pl/SharedRules/general.yaml +++ b/Rules/Languages/pl/SharedRules/general.yaml @@ -17,15 +17,15 @@ - bookmark: "*[1]/@id" - test: - if: "*[1][.='ℂ']" - then: [t: "liczby zespolone"] # phrase('complex numbers' consist of two parts) + then: [T: "liczby zespolone"] # phrase('complex numbers' consist of two parts) - else_if: "*[1][.='ℕ']" - then: [t: "liczby naturalne"] # phrase('natural numbers' are numbers from 1 to infinity) + then: [T: "liczby naturalne"] # phrase('natural numbers' are numbers from 1 to infinity) - else_if: "*[1][.='ℚ']" - then: [t: "liczby wymierne"] # phrase('rational numbers' are the fraction of 2 integers) + then: [T: "liczby wymierne"] # phrase('rational numbers' are the fraction of 2 integers) - else_if: "*[1][.='ℝ']" - then: [t: "liczby rzeczywiste"] # phrase('real numbers' can be both positive and negative) + then: [T: "liczby rzeczywiste"] # phrase('real numbers' can be both positive and negative) - else_if: "*[1][.='ℤ']" - then: [t: "liczby całkowite"] # phrase(positive 'integers' are natural numbers above 0) + then: [T: "liczby całkowite"] # phrase(positive 'integers' are natural numbers above 0) else: [x: "*[1][text()]"] # shouldn't happen - name: dimension-number-sets @@ -57,15 +57,15 @@ - bookmark: "@id" - test: - if: ".='ℂ'" - then: [t: "liczby zespolone"] # phrase('the complex numbers' include 2 parts) + then: [T: "liczby zespolone"] # phrase('the complex numbers' include 2 parts) - else_if: ".='ℕ'" - then: [t: "liczby naturalne"] # phrase('the natural numbers' begin at 1) + then: [T: "liczby naturalne"] # phrase('the natural numbers' begin at 1) - else_if: ".='ℚ'" - then: [t: "liczby wymierne"] # phrase('the rational numbers' are the fraction of 2 integers) + then: [T: "liczby wymierne"] # phrase('the rational numbers' are the fraction of 2 integers) - else_if: ".='ℝ'" - then: [t: "liczby rzeczywiste"] # phrase('the real numbers' can be both positive and negative) + then: [T: "liczby rzeczywiste"] # phrase('the real numbers' can be both positive and negative) - else_if: ".='ℤ'" - then: [t: "liczby całkowite"] # phrase('the integers' are natural numbers above 0) + then: [T: "liczby całkowite"] # phrase('the integers' are natural numbers above 0) else: [x: "text()"] # shouldn't happen - name: word-degree-celsius-fahrenheit-unit @@ -101,14 +101,14 @@ match: "." replace: - bookmark: "@id" - - t: "część rzeczywista" # phrase('the real part' of a complex number does not include the imaginary part) + - T: "część rzeczywista" # 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: "część urojona" # phrase('the imaginary part' is part of a complex number) + - T: "część urojona" # phrase('the imaginary part' is part of a complex number) # rules on scripted vertical bars ('evaluated at') - name: evaluated-at-2 @@ -117,7 +117,7 @@ replace: - x: "*[1]" - pause: auto - - t: "obliczone w" # phrase(results were 'evaluated at' a given point) + - T: "obliczone w" # phrase(results were 'evaluated at' a given point) - pause: auto - x: "*[2]" @@ -127,10 +127,10 @@ replace: - x: "*[1]" - pause: auto - - t: "obliczone w" # phrase(results were 'evaluated at' this point) + - T: "obliczone w" # phrase(results were 'evaluated at' this point) - pause: auto - x: "*[3]" - - t: "minus to samo wyrażenie obliczone w" # phrase(this result is 'minus the same expression evaluated at' an earlier point) + - T: "minus to samo wyrażenie obliczone w" # phrase(this result is 'minus the same expression evaluated at' an earlier point) - x: "*[2]" - name: permutation @@ -139,7 +139,7 @@ match: "count(*)=2 and contains(@data-intent-property, ':infix:')" replace: - x: "*[2]" - - t: "permutacji z" # phrase(the solution involves several 'permutations of' values) + - T: "permutacji z" # phrase(the solution involves several 'permutations of' values) - x: "*[1]" - name: intervals @@ -221,7 +221,7 @@ match: "." replace: - x: "*[1]" - - t: "z okresem" # phrase('with repeating digits') + - T: "z okresem" # phrase('with repeating digits') - spell: "*[2]" - name: msubsup-skip-super @@ -286,6 +286,15 @@ 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')])" + # Polish plural depends on the numeral, not only on "is it one": + # 1 metr | 2, 3, 4 metry (nominative plural) | 5 metrów (genitive plural) + # and the teens break the naive rule: 12, 13, 14 metrów (genitive, despite + # ending in 2, 3, 4), likewise 112-114. $Coefficient is 0 when the numeral + # cannot be determined, which falls through to the genitive - the form + # Polish uses with unknown or large quantities. + - Coefficient: "IfThenElse($MRowForCoefficient, number($MRowForCoefficient/*[1][self::m:mn]), 0)" + - IsNominativePlural: "$Coefficient mod 10 >= 2 and $Coefficient mod 10 <= 4 and + not($Coefficient mod 100 >= 12 and $Coefficient mod 100 <= 14)" - Prefix: "''" - Word: "''" replace: @@ -333,9 +342,13 @@ - 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') != ''" + - else_if: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''" then: [x: "DefinitionValue($Word, 'Speech', 'PluralForms')"] - else: [x: "$Word", ct: "s"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralGenitive') != ''" + then: [x: "DefinitionValue($Word, 'Speech', 'PluralGenitive')"] + # No inflected form is known: speak the singular, because a wrong + # ending is worse for a screen reader user than a missing one. + else: [x: "$Word"] else: - x: "$Prefix" - ct: "-" @@ -343,9 +356,11 @@ - 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') != ''" + - else_if: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''" then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralForms'))"] - else: [x: "concat('\uF8FE', $Word)", ct: "s"] + - else_if: "DefinitionValue($Word, 'Speech', 'PluralGenitive') != ''" + then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'PluralGenitive'))"] + else: [x: "concat('\uF8FE', $Word)"] # need to reverse the order of speech: $ 3 -> 3 dollars - name: currency @@ -355,15 +370,21 @@ # If the amount is singular, we don't add the plural ending. - IsSingular: "*[3][self::m:mn and .=1] and *[2]='\u2062'" - CurrencyWord: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')" + # Same numeral-dependent choice as in the 'unit' rule above. + - Coefficient: "IfThenElse(*[3][self::m:mn], number(*[3]), 0)" + - IsNominativePlural: "$Coefficient mod 10 >= 2 and $Coefficient mod 10 <= 4 and + not($Coefficient mod 100 >= 12 and $Coefficient mod 100 <= 14)" replace: - bookmark: "*[3]/@id" - x: "*[3]" - test: - if: "$IsSingular" then: [x: "$CurrencyWord"] - - else_if: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms') != ''" + - else_if: "$IsNominativePlural and DefinitionValue($CurrencyWord, 'Speech', 'PluralForms') != ''" then: [x: "DefinitionValue($CurrencyWord, 'Speech', 'PluralForms')"] - else: [x: "DefinitionValue(*[1], 'Speech', 'CurrencySymbols')", ct: "s"] + - else_if: "DefinitionValue($CurrencyWord, 'Speech', 'PluralGenitive') != ''" + then: [x: "DefinitionValue($CurrencyWord, 'Speech', 'PluralGenitive')"] + else: [x: "$CurrencyWord"] - name: sin tag: mi @@ -378,7 +399,7 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cosinus"] # phrase('cos' is the abbreviation for cosine) + then: [T: "cosinus"] # phrase('cos' is the abbreviation for cosine) else: [T: "cosinus"] # phrase(find the 'cosine' in a right-angle triangle) - name: tan tag: mi @@ -387,7 +408,7 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "tangens"] # phrase(the 'tan' is the ratio of the opposite to the adjacent side of a right-angled triangle) + then: [T: "tangens"] # phrase(the 'tan' is the ratio of the opposite to the adjacent side of a right-angled triangle) else: [T: "tangens"] # phrase(a 'tangent' is a straight line that touches a curve) - name: sec tag: mi @@ -396,8 +417,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "sekans"] # phrase(to 'seek' a solution) - else: [t: "sekans"] # phrase(a 'secant' intersects a curve at two or more points) + then: [T: "sekans"] # phrase(to 'seek' a solution) + else: [T: "sekans"] # phrase(a 'secant' intersects a curve at two or more points) - name: csc tag: mi match: ".='csc'" @@ -405,8 +426,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "kosekans"] # phrase(we will 'cosecant' a solution) - else: [t: "kosekans"] # phrase(the 'cosecant' is the reciprocal of the secant) + then: [T: "kosekans"] # phrase(we will 'cosecant' a solution) + else: [T: "kosekans"] # phrase(the 'cosecant' is the reciprocal of the secant) - name: cot tag: mi match: ".='cot'" @@ -414,8 +435,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cotangens"] # phrase(find the 'cotangent' in a right-angle triangle) - else: [t: "cotangens"] # phrase(the 'cotangent' is the reciprocal of the tangent) + then: [T: "cotangens"] # phrase(find the 'cotangent' in a right-angle triangle) + else: [T: "cotangens"] # phrase(the 'cotangent' is the reciprocal of the tangent) - name: sinh tag: mi @@ -424,8 +445,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "sinus hiperboliczny"] # phrase(the word 'sinch' is an abbreviation for hyperbolic sine) - else: [t: "sinus hiperboliczny"] # phrase(the 'hyperbolic sine' is used in mathematics) + then: [T: "sinus hiperboliczny"] # phrase(the word 'sinch' is an abbreviation for hyperbolic sine) + else: [T: "sinus hiperboliczny"] # phrase(the 'hyperbolic sine' is used in mathematics) - name: cosh tag: mi match: ".='cosh'" @@ -433,8 +454,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cosinus hiperboliczny"] # phrase('cosh' is an abbreviation of hyperbolic cosine) - else: [t: "cosinus hiperboliczny"] # phrase(the 'hyperbolic cosine' is a mathematical function) + then: [T: "cosinus hiperboliczny"] # phrase('cosh' is an abbreviation of hyperbolic cosine) + else: [T: "cosinus hiperboliczny"] # phrase(the 'hyperbolic cosine' is a mathematical function) - name: tanh tag: mi match: ".='tanh'" @@ -442,8 +463,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "tangens hiperboliczny"] # phrase('tanch' is shorthand for hyperbolic tangent) - else: [t: "tangens hiperboliczny"] # phrase('hyperbolic tangent' is a mathematical function) + then: [T: "tangens hiperboliczny"] # phrase('tanch' is shorthand for hyperbolic tangent) + else: [T: "tangens hiperboliczny"] # phrase('hyperbolic tangent' is a mathematical function) - name: sech tag: mi match: ".='sech'" @@ -451,8 +472,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "sekans hiperboliczny"] # phrase('sheck' is shorthand for hyperbolic secant) - else: [t: "sekans hiperboliczny"] # phrase('hyperbolic secant' is a mathematical function) + then: [T: "sekans hiperboliczny"] # phrase('sheck' is shorthand for hyperbolic secant) + else: [T: "sekans hiperboliczny"] # phrase('hyperbolic secant' is a mathematical function) - name: csch tag: mi match: ".='csch'" @@ -460,8 +481,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "kosekans hiperboliczny"] # phrase('cosheck' is shorthand for hyperbolic cosecant) - else: [t: "kosekans hiperboliczny"] # phrase('hyperbolic cosecant' is a mathematical function) + then: [T: "kosekans hiperboliczny"] # phrase('cosheck' is shorthand for hyperbolic cosecant) + else: [T: "kosekans hiperboliczny"] # phrase('hyperbolic cosecant' is a mathematical function) - name: coth tag: mi match: ".='coth'" @@ -469,8 +490,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "cotangens hiperboliczny"] # phrase('cotanch' is shorthand for hyperbolic cotangent) - else: [t: "cotangens hiperboliczny"] # phrase(the 'hyperbolic cotangent' is a mathematical function) + then: [T: "cotangens hiperboliczny"] # phrase('cotanch' is shorthand for hyperbolic cotangent) + else: [T: "cotangens hiperboliczny"] # phrase(the 'hyperbolic cotangent' is a mathematical function) - name: exponential tag: mi match: ".='exp'" @@ -478,8 +499,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "eksponenta"] # phrase('exp' means exponential function) - else: [t: "funkcja wykładnicza"] # phrase('exponential' function) + then: [T: "eksponenta"] # phrase('exp' means exponential function) + else: [T: "funkcja wykładnicza"] # phrase('exponential' function) - name: covariance tag: mi match: ".='Cov'" @@ -487,8 +508,8 @@ - bookmark: "@id" - test: if: "$Verbosity='Terse'" - then: [t: "kowariancja"] # phrase('Cov' is shorthand for the covariance function) - else: [t: "kowariancja"] # phrase('covariance' function) + then: [T: "kowariancja"] # phrase('Cov' is shorthand for the covariance function) + else: [T: "kowariancja"] # phrase('covariance' function) - name: maximum tag: mi @@ -551,25 +572,25 @@ then: - test: - if: "self::m:piecewise" - then: [t: "przypadek"] # phrase(this is the first 'case' of three cases) + then: [T: "przypadek"] # phrase(this is the first 'case' of three cases) - else_if: "self::m:system-of-equations" - then: [t: "równanie"] # phrase(this is the first 'equation' of three equations) - else: [t: "linia"] # phrase(this is the first 'line' of three lines) + then: [T: "równanie"] # phrase(this is the first 'equation' of three equations) + else: [T: "linia"] # phrase(this is the first 'line' of three lines) - else_if: "($LineCount mod 10 = 2 or $LineCount mod 10 = 3 or $LineCount mod 10 = 4) and not($LineCount mod 100 = 12 or $LineCount mod 100 = 13 or $LineCount mod 100 = 14)" then: - test: - if: "self::m:piecewise" - then: [t: "przypadki"] # phrase(there are 'two cases' to consider) + then: [T: "przypadki"] # phrase(there are 'two cases' to consider) - else_if: "self::m:system-of-equations" - then: [t: "równania"] # phrase(there are 'two equations' to solve) - else: [t: "linie"] # phrase(there are 'two lines' shown) + then: [T: "równania"] # phrase(there are 'two equations' to solve) + else: [T: "linie"] # phrase(there are 'two lines' shown) - else: - test: - if: "self::m:piecewise" - then: [t: "przypadków"] # phrase(there are 'five cases' to consider) + then: [T: "przypadków"] # phrase(there are 'five cases' to consider) - else_if: "self::m:system-of-equations" - then: [t: "równań"] # phrase(there are 'five equations' to solve) - else: [t: "linii"] # phrase(there are 'five lines' shown) + then: [T: "równań"] # phrase(there are 'five equations' to solve) + else: [T: "linii"] # phrase(there are 'five lines' shown) - pause: short - x: "*" - pause: long @@ -586,10 +607,10 @@ - pause: medium - test: - if: "parent::m:piecewise" - then: [t: "przypadek"] # phrase('case' 1 of 10 cases) + then: [T: "przypadek"] # phrase('case' 1 of 10 cases) - else_if: "parent::m:system-of-equations" - then: [t: "równanie"] # phrase('equation' 1 of 10 equations) - else: [t: "linia"] # phrase('line 1 of 10 lines) + then: [T: "równanie"] # phrase('equation' 1 of 10 equations) + else: [T: "linia"] # phrase('line 1 of 10 lines) - x: "count(preceding-sibling::*[not(contains(@data-intent-property, ':continued-row:'))]) + 1" - test: if: "self::m:mlabeledtr" @@ -638,13 +659,13 @@ variables: [IsColumnSilent: true()] match: "count(*)=1 and *[self::m:mtr][count(*) = 1]" replace: - - t: "jeden na jeden" # phrase(the '1 by 1' matrix) + - T: "jeden na jeden" # 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: "wyznacznik"] # phrase(the 2 by 2 'determinant')) else: [T: "macierz"] # phrase(the 2 by 2 'matrix') - - t: "z elementem" # phrase(the 2 by 2 matrix 'with entry' x) + - T: "z elementem" # phrase(the 2 by 2 matrix 'with entry' x) - x: "*[1]/*" # simpler reading methods for special case matrices @@ -657,7 +678,7 @@ - x: count(*) - T: "na" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - t: "macierz zerowa" # phrase(the 2 by 2 'zero matrix') + - T: "macierz zerowa" # phrase(the 2 by 2 'zero matrix') - pause: long - name: identity-matrix @@ -672,7 +693,7 @@ - x: count(*) - T: "na" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - t: "macierz jednostkowa" # phrase(the 2 by 2 'identity matrix') + - T: "macierz jednostkowa" # phrase(the 2 by 2 'identity matrix') - pause: long - name: diagonal-matrix @@ -689,7 +710,7 @@ - x: count(*) - T: "na" # phrase(the 1 'by' 2 matrix) - x: count(*[self::m:mtr][1]/*) - - t: "macierz diagonalna" # phrase(the 2 by 2 'diagonal matrix') + - T: "macierz diagonalna" # 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 @@ -711,7 +732,7 @@ replace: - T: "" # phrase('the' 2 by 2 matrix M) - x: count(*) - - t: "na jedną kolumnę" # phrase(the 2 'by 1 column' matrix) + - T: "na jedną kolumnę" # phrase(the 2 'by 1 column' matrix) - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" then: [T: "wektor"] # phrase(the 2 by 2 'vector') @@ -733,7 +754,7 @@ replace: - T: "" # phrase('the' 2 by 2 matrix M) - x: "count(*)" - - t: "na jedną kolumnę" # phrase(the 2 'by 1 column' matrix) + - T: "na jedną kolumnę" # phrase(the 2 'by 1 column' matrix) - test: if: "$ClearSpeak_Matrix = 'Vector' or $ClearSpeak_Matrix = 'EndVector'" then: [T: "wektor"] # phrase(the 2 column 'vector') @@ -742,7 +763,7 @@ - x: "*" # select the rows (mtr) - test: if: "$ClearSpeak_Matrix = 'EndMatrix' or $ClearSpeak_Matrix = 'EndVector'" - then: [t: "koniec macierzy"] # phrase(the 'end of matrix' has been reached) + then: [T: "koniec macierzy"] # phrase(the 'end of matrix' has been reached) - name: 1x2-or-3-matrix tag: matrix @@ -753,7 +774,7 @@ - count(*[1]/*)<=3 and # at least two cols - IsNode(*/*/*,'simple') # IsNode() returns true if all the nodes are simple replace: - - t: "jeden na" # phrase('the 1 by' 2 matrix) + - T: "jeden na" # phrase('the 1 by' 2 matrix) - x: count(*/*) - T: "wiersz" # phrase(the 1 by 4 'row' matrix) - test: @@ -775,7 +796,7 @@ variables: [IsColumnSilent: "$SpeechStyle = 'ClearSpeak' and $ClearSpeak_Matrix = 'SilentColNum'"] match: "count(*)=1" # one row replace: - - t: "jeden na" # phrase('the 1 by' 2 matrix) + - T: "jeden na" # phrase('the 1 by' 2 matrix) - x: "count(*/*)" - T: "wiersz" # phrase(the 1 by 2 'row' matrix) - test: @@ -811,7 +832,7 @@ else: - test: if: "@columnlines and (contains(normalize-space(@columnlines), 'solid') or contains(normalize-space(@columnlines), 'dashed'))" - then: [t: "macierz rozszerzona"] # phrase(the 2 by 2 'augmented matrix') + then: [T: "macierz rozszerzona"] # phrase(the 2 by 2 'augmented matrix') else: [T: "macierz"] # phrase(the 2 by 2 'matrix') - pause: long - x: "*" @@ -838,7 +859,7 @@ else: - test: if: "@columnlines and (contains(normalize-space(@columnlines), 'solid') or contains(normalize-space(@columnlines), 'dashed'))" - then: [t: "macierz rozszerzona"] # phrase(the 2 by 2 'augmented matrix') + then: [T: "macierz rozszerzona"] # phrase(the 2 by 2 'augmented matrix') else: [T: "macierz"] # phrase(the 2 by 2 'matrix') - pause: long - x: "*" @@ -1077,12 +1098,12 @@ - bookmark: "*[1]/@id" - test: - if: ".='s'" - then: [t: "ciało stałe"] # phrase(Boron is a 'solid' in its natural state) + then: [T: "ciało stałe"] # phrase(Boron is a 'solid' in its natural state) - else_if: ".='l'" - then: [t: "ciecz"] # phrase(water is a 'liquid') + then: [T: "ciecz"] # phrase(water is a 'liquid') - else_if: ".='g'" - then: [t: "gaz"] # phrase(hydrogen is a 'gas' ) - else: [t: "wodny"] # phrase(an 'aqueous' solution is contained in water) + then: [T: "gaz"] # phrase(hydrogen is a 'gas' ) + else: [T: "wodny"] # phrase(an 'aqueous' solution is contained in water) - pause: short - name: chemical-formula-operator-bond @@ -1093,13 +1114,13 @@ - bookmark: "@id" - test: - if: ".='-' or .=':'" - then: [t: "wiązanie pojedyncze"] # phrase(a 'single bond' is formed when two atoms share one pair of electrons) + then: [T: "wiązanie pojedyncze"] # phrase(a 'single bond' is formed when two atoms share one pair of electrons) - else_if: ".='=' or .='∷'" - then: [t: "wiązanie podwójne"] # phrase(a 'double bond' may occur when two atoms share two pairs of electrons) + then: [T: "wiązanie podwójne"] # phrase(a 'double bond' may occur when two atoms share two pairs of electrons) - else_if: ".='≡'" - then: [t: "wiązanie potrójne"] # phrase(a 'triple bond' occurs when two atoms share three pairs of electrons) + then: [T: "wiązanie potrójne"] # phrase(a 'triple bond' occurs when two atoms share three pairs of electrons) - else_if: ".='≣'" - then: [t: "wiązanie poczwórne"] # phrase(a 'quadruple bond' occurs when two atoms share four pairs of electrons) + then: [T: "wiązanie poczwórne"] # phrase(a 'quadruple bond' occurs when two atoms share four pairs of electrons) else: [x: "text()"] - name: chemical-formula-operator @@ -1118,14 +1139,14 @@ - if: ".='→' or .='⟶'" then_test: if: "$Verbosity='Terse'" - then: [t: "tworzy"] # phrase(hydrogen and oxygen 'forms' water ) - else: [t: "reaguje tworząc"] # phrase(hydrogen and oxygen 'reacts to form' water) + then: [T: "tworzy"] # phrase(hydrogen and oxygen 'forms' water ) + else: [T: "reaguje tworząc"] # phrase(hydrogen and oxygen 'reacts to form' water) - else_if: ".='⇌' or .='🣑'" # U+01F8D1 - then: [t: "jest w równowadze z"] # phrase(a reactant 'is in equilibrium with' a product) + then: [T: "jest w równowadze z"] # phrase(a reactant 'is in equilibrium with' a product) - else_if: ".='🣓'" # U+1F8D3 - then: [t: "jest w równowadze przesuniętej w lewo z"] # phrase(the reactant 'is in equilibrium biased to the left with' the product) + then: [T: "jest w równowadze przesuniętej w lewo z"] # phrase(the reactant 'is in equilibrium biased to the left with' the product) - else_if: ".='🣒'" # U+1F8D2 - then: [t: "jest w równowadze przesuniętej w prawo z"] # phrase(the reactant 'is in equilibrium biased to the right with' the product) + then: [T: "jest w równowadze przesuniętej w prawo z"] # phrase(the reactant 'is in equilibrium biased to the right with' the product) else: [x: "*"] - name: chemical-equation-operator diff --git a/Rules/Languages/pl/SharedRules/geometry.yaml b/Rules/Languages/pl/SharedRules/geometry.yaml index f110a71ed..3fa9c9ccc 100644 --- a/Rules/Languages/pl/SharedRules/geometry.yaml +++ b/Rules/Languages/pl/SharedRules/geometry.yaml @@ -7,12 +7,12 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "odcinek od" # phrase('the line segment from' A to B) + - T: "odcinek od" # phrase('the line segment from' A to B) - x: "*[1]" - T: "do" # phrase(the line segment from A 'to' B) - x: "*[2]" else: - - t: "odcinek" # phrase(the 'line segment' A B) + - T: "odcinek" # phrase(the 'line segment' A B) - x: "*[1]" - x: "*[2]" @@ -23,12 +23,12 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "półprosta od" # phrase('the ray from' A to B) + - T: "półprosta od" # phrase('the ray from' A to B) - x: "*[1]" - T: "do" # phrase(the ray from A 'to' B) - x: "*[2]" else: - - t: "półprosta" # phrase(the 'ray'A B) + - T: "półprosta" # phrase(the 'ray'A B) - x: "*[1]" - x: "*[2]" @@ -47,9 +47,9 @@ - test: if: "$Verbosity='Verbose'" then: - - t: "miara kąta" # phrase('the measure of the angle' ABC) + - T: "miara kąta" # phrase('the measure of the angle' ABC) else: - - t: "miara kąta" # phrase('measure of angle' ABC) + - T: "miara kąta" # phrase('measure of angle' ABC) - x: "*[1]" - x: "*[2]" - x: "*[3]" @@ -74,4 +74,4 @@ - pause: short - test: if: "($SpeechStyle='ClearSpeak' and $Verbosity='Verbose') or not(IsNode(*[last()],'leaf'))" - then: [t: "punkt końcowy"] # phrase(start point, 'end point') + then: [T: "punkt końcowy"] # phrase(start point, 'end point') diff --git a/Rules/Languages/pl/SharedRules/linear-algebra.yaml b/Rules/Languages/pl/SharedRules/linear-algebra.yaml index 1ebcf9f95..69752bd48 100644 --- a/Rules/Languages/pl/SharedRules/linear-algebra.yaml +++ b/Rules/Languages/pl/SharedRules/linear-algebra.yaml @@ -36,7 +36,7 @@ - x: "*[1]" - test: if: "not(IsNode(*[1], 'simple')) and $Impairment = 'Blindness'" - then: [t: "koniec wyznacznika"] # phrase('end determinant' of a matrix) + then: [T: "koniec wyznacznika"] # phrase('end determinant' of a matrix) - name: subscripted-norm diff --git a/Rules/Languages/pl/definitions.yaml b/Rules/Languages/pl/definitions.yaml index 9c4c6e69c..18785562b 100644 --- a/Rules/Languages/pl/definitions.yaml +++ b/Rules/Languages/pl/definitions.yaml @@ -363,7 +363,7 @@ "F": "farad", "Gy": "grej", "H": "henr", - "Hz": "herce", + "Hz": "herc", "J": "dżul", "kat": "katal", "lm": "lumen", @@ -438,7 +438,7 @@ "M": "molowy", "R": "rentgen", "rpm": "obrót na minutę", - "℧": "M h o", + "℧": "mho", "dyn": "dyna", "erg": "erg", @@ -495,7 +495,7 @@ "lb t": "funt trojański", # energy - "hp": "konie mechaniczne", + "hp": "koń mechaniczny", "BTU": "btu", "°F": "stopień Fahrenheita", "℉": "stopień Fahrenheita", @@ -511,25 +511,277 @@ } - PluralForms: { - # FIX: this needs to be flushed out - "cal": "cale", "cal kwadratowy": "cale kwadratowe", "cal sześcienny": "cale sześcienne", - "stopa": "stopy", "stopa kwadratowa": "stopy kwadratowe", "stopa sześcienna": "stopy sześcienne", + # Nominative plural - after the numerals 2, 3, 4 (but not 12-14 or 112-114). + # The genitive plural (5 and above) lives in PluralGenitive below. + "akr": "akry", + "amper": "ampery", + "angstrem": "angstremy", + "atmosfera": "atmosfery", + "bajt": "bajty", + "bar": "bary", + "baryłka": "baryłki", + "bekerel": "bekerele", + "bel": "bele", + "bit": "bity", + "bitcoin": "bitcoiny", + "bod": "body", + "btu": "btu", + "buszel": "buszle", + "cal": "cale", + "cal kwadratowy": "cale kwadratowe", + "cal sześcienny": "cale sześcienne", + "cent": "centy", + "cetnar": "cetnary", + "colon": "colony", + "dalton": "daltony", + "decybel": "decybele", + "dolar": "dolary", + "drachma": "drachmy", + "drachma płynu": "drachmy płynu", + "dyna": "dyny", + "dzień": "dni", + "dżul": "dżule", + "eksbibajt": "eksbibajty", + "eksbibit": "eksbibity", + "elektronowolt": "elektronowolty", + "erg": "ergi", + "euro": "euro", + "farad": "farady", + "fermi": "fermi", + "funt": "funty", + "funt trojański": "funty trojańskie", + "galon": "galony", + "gibibajt": "gibibajty", + "gibibit": "gibibity", + "gill": "gille", + "godzina": "godziny", + "grad": "grady", + "gram": "gramy", + "gran": "grany", + "grej": "greje", + "hektar": "hektary", + "henr": "henry", + "herc": "herce", + "jard kwadratowy": "jardy kwadratowe", + "jard sześcienny": "jardy sześcienne", + "jednostka astronomiczna": "jednostki astronomiczne", + "jednostka masy atomowej": "jednostki masy atomowej", + "jobibajt": "jobibajty", + "jobibit": "jobibity", + "kaloria": "kalorie", + "kandela": "kandele", + "katal": "katale", + "kelwin": "kelwiny", + "kibibajt": "kibibajty", + "kibibit": "kibibity", + "kiur": "kiury", + "koń mechaniczny": "konie mechaniczne", + "kubek": "kubki", + "kulomb": "kulomby", + "kwarta": "kwarty", + "lir": "liry", + "litr": "litry", + "luks": "luksy", + "lumen": "lumeny", + "mebibajt": "mebibajty", + "mebibit": "mebibity", + "metr": "metry", + "mho": "mho", + "mila": "mile", + "mila kwadratowa": "mile kwadratowe", + "mila na galon": "mile na galon", + "mila na godzinę": "mile na godzinę", + "minuta": "minuty", + "minuta łuku": "minuty łuku", + "mol": "mole", + "molowy": "molowe", + "neper": "nepery", + "niuton": "niutony", + "obrót na minutę": "obroty na minutę", + "ogniwo": "ogniwa", + "om": "omy", + "parsek": "parseki", + "paskal": "paskale", + "pebibajt": "pebibajty", + "pebibit": "pebibity", + "pek": "peki", + "pennyweight": "pennyweight", + "peso": "peso", + "pinta": "pinty", + "pręt": "pręty", + "radian": "radiany", + "rentgen": "rentgeny", + "rok": "lata", + "rok świetlny": "lata świetlne", + "rupia": "rupie", + "sekunda": "sekundy", + "sekunda łuku": "sekundy łuku", + "siemens": "siemensy", + "siwert": "siwerty", + "steradian": "steradiany", + "stopa": "stopy", "stopa deskowa": "stopy deskowe", + "stopa kwadratowa": "stopy kwadratowe", + "stopa sześcienna": "stopy sześcienne", "stopień": "stopnie", "stopień Celsjusza": "stopnie Celsjusza", "stopień Fahrenheita": "stopnie Fahrenheita", - "degree celsius": "stopnie Celsjusza", - "degree fahrenheit": "stopnie Fahrenheita", - "henr": "henry", - "wolt": "wolty", + "szekel": "szekle", + "tebibajt": "tebibajty", + "tebibit": "tebibity", + "tesla": "tesle", + "tona": "tony", + "tydzień": "tygodnie", + "uncja": "uncje", + "uncja płynu": "uncje płynu", + "uncja trojańska": "uncje trojańskie", "wat": "waty", - "hertz": "herce", - "luks": "luksy", - "siemens": "siemens", - "obrót na minutę": "obroty na minutę", - "mila na godzinę": "mile na godzinę", - "mila na galon": "mile na galon", - "colon": "colony", "lir": "liry", "won": "wony", "bitcoin": "bitcoiny" + "weber": "webery", + "wolt": "wolty", + "won": "wony", + "zebibajt": "zebibajty", + "zebibit": "zebibity", + "łańcuch": "łańcuchy", + "łyżeczka": "łyżeczki", + "łyżka stołowa": "łyżki stołowe" + } + +- PluralGenitive: { + # Genitive plural - after 5 and above, and after 12-14, 112-114. + # Polish inflects the noun according to the numeral, so a single plural + # form is not enough: 2 metry but 5 metrów. The 'unit' and 'currency' + # rules pick the section based on the value of the numeral. + "akr": "akrów", + "amper": "amperów", + "angstrem": "angstremów", + "atmosfera": "atmosfer", + "bajt": "bajtów", + "bar": "barów", + "baryłka": "baryłek", + "bekerel": "bekereli", + "bel": "beli", + "bit": "bitów", + "bitcoin": "bitcoinów", + "bod": "bodów", + "btu": "btu", + "buszel": "buszli", + "cal": "cali", + "cal kwadratowy": "cali kwadratowych", + "cal sześcienny": "cali sześciennych", + "cent": "centów", + "cetnar": "cetnarów", + "colon": "colonów", + "dalton": "daltonów", + "decybel": "decybeli", + "dolar": "dolarów", + "drachma": "drachm", + "drachma płynu": "drachm płynu", + "dyna": "dyn", + "dzień": "dni", + "dżul": "dżuli", + "eksbibajt": "eksbibajtów", + "eksbibit": "eksbibitów", + "elektronowolt": "elektronowoltów", + "erg": "ergów", + "euro": "euro", + "farad": "faradów", + "fermi": "fermi", + "funt": "funtów", + "funt trojański": "funtów trojańskich", + "galon": "galonów", + "gibibajt": "gibibajtów", + "gibibit": "gibibitów", + "gill": "gilli", + "godzina": "godzin", + "grad": "gradów", + "gram": "gramów", + "gran": "granów", + "grej": "grejów", + "hektar": "hektarów", + "henr": "henrów", + "herc": "herców", + "jard kwadratowy": "jardów kwadratowych", + "jard sześcienny": "jardów sześciennych", + "jednostka astronomiczna": "jednostek astronomicznych", + "jednostka masy atomowej": "jednostek masy atomowej", + "jobibajt": "jobibajtów", + "jobibit": "jobibitów", + "kaloria": "kalorii", + "kandela": "kandeli", + "katal": "katali", + "kelwin": "kelwinów", + "kibibajt": "kibibajtów", + "kibibit": "kibibitów", + "kiur": "kiurów", + "koń mechaniczny": "koni mechanicznych", + "kubek": "kubków", + "kulomb": "kulombów", + "kwarta": "kwart", + "lir": "lirów", + "litr": "litrów", + "luks": "luksów", + "lumen": "lumenów", + "mebibajt": "mebibajtów", + "mebibit": "mebibitów", + "metr": "metrów", + "mho": "mho", + "mila": "mil", + "mila kwadratowa": "mil kwadratowych", + "mila na galon": "mil na galon", + "mila na godzinę": "mil na godzinę", + "minuta": "minut", + "minuta łuku": "minut łuku", + "mol": "moli", + "molowy": "molowych", + "neper": "neperów", + "niuton": "niutonów", + "obrót na minutę": "obrotów na minutę", + "ogniwo": "ogniw", + "om": "omów", + "parsek": "parseków", + "paskal": "paskali", + "pebibajt": "pebibajtów", + "pebibit": "pebibitów", + "pek": "peków", + "pennyweight": "pennyweight", + "peso": "peso", + "pinta": "pint", + "pręt": "prętów", + "radian": "radianów", + "rentgen": "rentgenów", + "rok": "lat", + "rok świetlny": "lat świetlnych", + "rupia": "rupii", + "sekunda": "sekund", + "sekunda łuku": "sekund łuku", + "siemens": "siemensów", + "siwert": "siwertów", + "steradian": "steradianów", + "stopa": "stóp", + "stopa deskowa": "stóp deskowych", + "stopa kwadratowa": "stóp kwadratowych", + "stopa sześcienna": "stóp sześciennych", + "stopień": "stopni", + "stopień Celsjusza": "stopni Celsjusza", + "stopień Fahrenheita": "stopni Fahrenheita", + "szekel": "szekli", + "tebibajt": "tebibajtów", + "tebibit": "tebibitów", + "tesla": "tesli", + "tona": "ton", + "tydzień": "tygodni", + "uncja": "uncji", + "uncja płynu": "uncji płynu", + "uncja trojańska": "uncji trojańskich", + "wat": "watów", + "weber": "weberów", + "wolt": "woltów", + "won": "wonów", + "zebibajt": "zebibajtów", + "zebibit": "zebibitów", + "łańcuch": "łańcuchów", + "łyżeczka": "łyżeczek", + "łyżka stołowa": "łyżek stołowych" } # Lines starting with "#" are a comment diff --git a/Rules/Languages/pl/navigate.yaml b/Rules/Languages/pl/navigate.yaml index c99b60490..bb89c8a9a 100644 --- a/Rules/Languages/pl/navigate.yaml +++ b/Rules/Languages/pl/navigate.yaml @@ -48,9 +48,9 @@ - if: "$MatchCounter = 0 and $SayCommand = 'true'" then_test: - if: "self::m:math and starts-with($NavCommand, 'ZoomOut')" - then: [t: "maksymalnie oddalono", pause: "medium"] + then: [T: "maksymalnie oddalono", pause: "medium"] - else_if: "IsNode(., 'leaf') and starts-with($NavCommand, 'ZoomIn')" - then: [t: "maksymalnie oddalono", pause: "medium"] + then: [T: "maksymalnie oddalono", pause: "medium"] else: - test: # CommandOffset to 1 + długość ANGIELSKIEGO rdzenia $NavCommand @@ -133,13 +133,13 @@ replace: - test: - if: "$Move2D = 'in'" - then: [t: "do"] # phrase(move 'in' to a part) + then: [T: "do"] # phrase(move 'in' to a part) - else_if: "$Move2D = 'out of'" - then: [t: "z"] # phrase(move 'out of' a part) + then: [T: "z"] # phrase(move 'out of' a part) - else_if: "$Move2D = 'end of'" - then: [t: "na koniec"] # phrase(move to the 'end of' a part) + then: [T: "na koniec"] # phrase(move to the 'end of' a part) - else_if: "$Move2D = 'start of'" - then: [t: "na początek"] # phrase(move to the 'start of' a part) + then: [T: "na początek"] # phrase(move to the 'start of' a part) else: [x: "$Move2D"] - test: - if: "$NumPrecedingSiblings=0" @@ -148,8 +148,8 @@ then: - test: # in postscripts -- base shifts by one if: "$NumPrecedingSiblings mod 2 = 0" - then: [t: "lewego indeksu dolnego"] # phrase(x with 'subscript' 2) - else: [t: "lewego indeksu górnego"] # phrase(x with 'superscript' 2) + then: [T: "lewego indeksu dolnego"] # phrase(x with 'subscript' 2) + else: [T: "lewego indeksu górnego"] # phrase(x with 'superscript' 2) else: - test: if: "$NumPrecedingSiblings mod 2 = 0" @@ -171,15 +171,15 @@ replace: - test: - if: "$Move2D = 'in'" - then: [t: "do"] # phrase(move 'in' to a part) + then: [T: "do"] # phrase(move 'in' to a part) - else_if: "$Move2D = 'out of' and starts-with($PartName, 'st')" then: [t: "ze"] # "ze stopnia" (eufonia przed 'st') - else_if: "$Move2D = 'out of'" - then: [t: "z"] # phrase(move 'out of' a part) + then: [T: "z"] # phrase(move 'out of' a part) - else_if: "$Move2D = 'end of'" - then: [t: "na koniec"] # phrase(move to the 'end of' a part) + then: [T: "na koniec"] # phrase(move to the 'end of' a part) - else_if: "$Move2D = 'start of'" - then: [t: "na początek"] # phrase(move to the 'start of' a part) + then: [T: "na początek"] # phrase(move to the 'start of' a part) else: [x: "$Move2D"] - test: - if: "$PartName != ''" @@ -203,7 +203,7 @@ then: [x: "SpeakIntentName(name(.), $Verbosity, 'silent')"] - else: [x: "SpeakIntentName(name(.), $Verbosity, 'other')"] else: - - t: "części" # phrase(the 'part' of the expression) + - T: "części" # phrase(the 'part' of the expression) - x: "count($Child2D/preceding-sibling::*) + 1" - pause: "medium" @@ -226,19 +226,19 @@ then: - test: - if: "$PreviousNavCommand = 'ZoomIn'" - then: [t: "cofnij przybliżenie"] # phrase('undo zoom in') + then: [T: "cofnij przybliżenie"] # phrase('undo zoom in') - else_if: "$PreviousNavCommand = 'ZoomOut'" - then: [t: "cofnij oddalenie"] # phrase('undo zoom out') + then: [T: "cofnij oddalenie"] # phrase('undo zoom out') - else_if: "$PreviousNavCommand = 'ZoomInAll'" - then: [t: "cofnij maksymalne przybliżenie"] # phrase('undo zooming in all the way') + then: [T: "cofnij maksymalne przybliżenie"] # phrase('undo zooming in all the way') - else_if: "$PreviousNavCommand = 'ZoomOutAll'" - then: [t: "cofnij maksymalne oddalenie"] # phrase('undo zooming out all the way') + then: [T: "cofnij maksymalne oddalenie"] # phrase('undo zooming out all the way') - else_if: "$PreviousNavCommand = 'MovePrevious' or $PreviousNavCommand = 'MovePreviousZoom'" - then: [t: "cofnij ruch w lewo"] # phrase('undo move left') + then: [T: "cofnij ruch w lewo"] # phrase('undo move left') - else_if: "$PreviousNavCommand = 'MoveNext' or $PreviousNavCommand = 'MoveNextZoom'" - then: [t: "cofnij ruch w prawo"] # phrase('undo move right') + then: [T: "cofnij ruch w prawo"] # phrase('undo move right') - else_if: "$PreviousNavCommand = 'None'" - then: [t: "brak poprzedniego polecenia"] # phrase('no previous command') + then: [T: "brak poprzedniego polecenia"] # phrase('no previous command') - pause: "medium" - set_variables: [NavNode: "@id"] @@ -261,7 +261,7 @@ replace: - test: if: "$MatchCounter = 0 and $NavVerbosity != 'Terse'" - then: [t: "maksymalnie przybliżono", pause: "long"] # phrase('zoomed in all of the way') + then: [T: "maksymalnie przybliżono", pause: "long"] # phrase('zoomed in all of the way') - test: if: "$ReadZoomLevel!=-1" then: @@ -552,12 +552,12 @@ then: - test: - if: "$NavCommand = 'MoveStart'" - then: [t: "przejdź na początek wyrażenia matematycznego"] # phrase('move to start of math') + then: [T: "przejdź na początek wyrażenia matematycznego"] # phrase('move to start of math') - else_if: "$NavCommand = 'MoveLineStart'" - then: [t: "przejdź na początek linii"] # phrase('move to start of line') + then: [T: "przejdź na początek linii"] # phrase('move to start of line') - else_if: "$NavCommand = 'MoveEnd'" - then: [t: "przejdź na koniec wyrażenia matematycznego"] # phrase('move to end of math') - else: [t: "przejdź na koniec linii"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') + then: [T: "przejdź na koniec wyrażenia matematycznego"] # phrase('move to end of math') + else: [T: "przejdź na koniec linii"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') - pause: "medium" - test: if: "$NavCommand = 'MoveStart' or $NavCommand = 'MoveLineStart'" @@ -597,8 +597,8 @@ then: - test: if: "$NavCommand = 'MoveLineStart'" - then: [t: "przejdź na początek linii"] # phrase('move to start of line') - else: [t: "przejdź na koniec linii"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') + then: [T: "przejdź na początek linii"] # phrase('move to start of line') + else: [T: "przejdź na koniec linii"] # "$NavCommand = 'MoveLineEnd'" # phrase('move to end of line') - pause: "medium" - test: if: "self::m:mrow or @data-from-mathml = 'mrow'" @@ -634,7 +634,7 @@ - "$NavCommand='MoveColumnStart' or $NavCommand='MoveColumnEnd' or" - "$NavCommand='ReadCellCurrent'" replace: - - t: "poza tabelą" # phrase('not in table') + - T: "poza tabelą" # phrase('not in table') - pause: long - set_variables: [SpeakExpression: "'false'"] @@ -648,7 +648,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź w lewo" # phrase('move left') + - T: "przejdź w lewo" # phrase('move left') - pause: short - test: if: "$NavVerbosity != 'Terse'" @@ -665,7 +665,7 @@ else: - set_variables: [NavNode: "preceding-sibling::*[1]/*[1]/@id"] else: - - t: "brak poprzedniej kolumny" # phrase('no previous column' in the table) + - T: "brak poprzedniej kolumny" # phrase('no previous column' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-next @@ -678,7 +678,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź w prawo" # phrase('move right') + - T: "przejdź w prawo" # phrase('move right') - pause: short - test: if: "$NavVerbosity != 'Terse'" @@ -695,7 +695,7 @@ else: - set_variables: [NavNode: "following-sibling::*[1]/*[1]/@id"] else: - - t: "brak następnej kolumny" # phrase('no next column' in the table) + - T: "brak następnej kolumny" # phrase('no next column' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-up @@ -711,7 +711,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź w górę" # phrase('move up' to previous row in the table) + - T: "przejdź w górę" # phrase('move up' to previous row in the table) - pause: short - test: if: "$NavVerbosity != 'Terse'" @@ -731,7 +731,7 @@ else: - set_variables: [NavNode: "../preceding-sibling::*[1]/*[$Column]/*[1]/@id"] else: - - t: "brak poprzedniego wiersza" # phrase('no previous row' in the table) + - T: "brak poprzedniego wiersza" # phrase('no previous row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-down @@ -747,7 +747,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź w dół" # phrase('move down to the next row in the table) + - T: "przejdź w dół" # phrase('move down to the next row in the table) - pause: short - test: if: "$NavVerbosity != 'Terse'" @@ -767,7 +767,7 @@ else: - set_variables: [NavNode: "../following-sibling::*[1]/*[$Column]/*[1]/@id"] else: - - t: "brak następnego wiersza" # phrase('no next row' in the table) + - T: "brak następnego wiersza" # phrase('no next row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-up @@ -777,7 +777,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź do poprzedniego wiersza" # phrase('move to previous row' to the previous row in the table) + - T: "przejdź do poprzedniego wiersza" # phrase('move to previous row' to the previous row in the table) - pause: medium - test: if: "preceding-sibling::*" @@ -791,7 +791,7 @@ else: - set_variables: [NavNode: "preceding-sibling::*[1]/@id"] else: - - t: "brak poprzedniego wiersza" # phrase('no previous row' in the table) + - T: "brak poprzedniego wiersza" # phrase('no previous row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-down @@ -801,7 +801,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź do następnego wiersza" # phrase('move to next row' to the next row in the table) + - T: "przejdź do następnego wiersza" # phrase('move to next row' to the next row in the table) - pause: medium - test: if: "following-sibling::*" @@ -815,7 +815,7 @@ else: - set_variables: [NavNode: "following-sibling::*[1]/@id"] else: - - t: "brak następnego wiersza" # phrase('no next row' in the table) + - T: "brak następnego wiersza" # phrase('no next row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-previous @@ -826,9 +826,9 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź do poprzedniej kolumny" # phrase('move to previous column' to the previous row in the table) + - T: "przejdź do poprzedniej kolumny" # phrase('move to previous column' to the previous row in the table) - pause: medium - - t: "brak poprzedniej kolumny" # phrase('no previous column' in the table) + - T: "brak poprzedniej kolumny" # phrase('no previous column' in the table) - set_variables: [SpeakExpression: "'false'"] - name: move-cell-next @@ -839,9 +839,9 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "przejdź do następnej kolumny" # phrase('move up' to the previous row in the table) + - T: "przejdź do następnej kolumny" # phrase('move up' to the previous row in the table) - pause: medium - - t: "brak następnej kolumny" # phrase('no next row' in the table) + - T: "brak następnej kolumny" # phrase('no next row' in the table) - set_variables: [SpeakExpression: "'false'"] - name: default-read-cell @@ -857,7 +857,7 @@ - test: if: "$NavVerbosity = 'Verbose'" then: - - t: "czytaj bieżący element" # phrase('read current entry' in the table) + - T: "czytaj bieżący element" # phrase('read current entry' in the table) - pause: medium - test: if: "$NavVerbosity != 'Terse'" @@ -870,7 +870,7 @@ - pause: short - set_variables: [NavNode: "$MTD[1]/*[1]/@id"] else: - - t: "poza tabelą" # phrase('not in table' or matrix) + - T: "poza tabelą" # phrase('not in table' or matrix) - pause: long - set_variables: [SpeakExpression: "'false'"] @@ -1110,7 +1110,7 @@ then: - x: "ancestor::m:mtd[1]" # try again on an mtd node else: - - t: "poza tabelą" # phrase('not in table' or matrix) + - T: "poza tabelą" # phrase('not in table' or matrix) - pause: long - set_variables: [SpeakExpression: "'false'"] @@ -1187,7 +1187,7 @@ - test: if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" then: - - t: "nie można przejść w prawo" # phrase('cannot move right') + - T: "nie można przejść w prawo" # phrase('cannot move right') - pause: medium - with: variables: @@ -1208,14 +1208,14 @@ - test: if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" then: - - t: "nie można" # phrase('cannot' move right in expression) + - T: "nie można" # phrase('cannot' move right in expression) - test: - if: "$NavCommand = 'MoveNext'" - then: [t: "przejść"] # phrase('move' to next entry in table) + then: [T: "przejść"] # phrase('move' to next entry in table) - else_if: "$NavCommand = 'ReadNext'" - then: [t: "odczytać"] # phrase('read' next entry in table) - else: [t: "opisać"] # phrase('describe' next entry in table) - - t: "w prawo" # phrase(move 'right') + then: [T: "odczytać"] # phrase('read' next entry in table) + else: [T: "opisać"] # phrase('describe' next entry in table) + - T: "w prawo" # phrase(move 'right') - pause: short - T: "koniec matematyki" # phrase(move 'end of math') - pause: long @@ -1382,7 +1382,7 @@ - test: if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose' and $NavCommand = 'MovePrevious'" then: - - t: "nie można przejść w lewo" # phrase('cannot move left' in expression) + - T: "nie można przejść w lewo" # phrase('cannot move left' in expression) - pause: medium - with: variables: @@ -1399,7 +1399,7 @@ - "($NavCommand = 'MovePrevious' or $NavCommand = 'ReadPrevious' or $NavCommand = 'DescribePrevious') and" - "(self::m:math or name(EdgeNode(., 'left', 'math'))='math')" replace: - - t: "początek wyrażenia matematycznego" # phrase('start of math') + - T: "początek wyrażenia matematycznego" # phrase('start of math') - pause: long - set_variables: [SpeakExpression: "'false'"] @@ -1412,7 +1412,7 @@ - test: if: "$MatchCounter = 0 and $NavVerbosity = 'Verbose'" then: - - t: "nie można przejść w lewo" # phrase('cannot move left') + - T: "nie można przejść w lewo" # phrase('cannot move left') - pause: short - with: variables: [Move2D: "'start of'", Child2D: "."] @@ -1573,16 +1573,16 @@ - test: - if: "$NavMode = 'Enhanced'" then: - - t: "znak" # phrase(a mathematical 'character') + - T: "znak" # phrase(a mathematical 'character') - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] - else_if: "$NavMode = 'Character'" then: - - t: "prosty" # phrase(a 'simple' way to do something) + - T: "prosty" # phrase(a 'simple' way to do something) - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] - else: - - t: "rozszerzony" # phrase(an 'enhanced' way to do something) + - T: "rozszerzony" # phrase(an 'enhanced' way to do something) - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] - - t: "tryb" # phrase(a simple 'mode' of use) + - T: "tryb" # phrase(a simple 'mode' of use) - pause: long - test: - if: "$NavMode != 'Enhanced'" # potentially need to zoom to the sibling @@ -1598,16 +1598,16 @@ - test: - if: "$NavMode = 'Enhanced'" then: - - t: "prosty" # phrase(an 'simple' way to do something) + - T: "prosty" # phrase(an 'simple' way to do something) - set_variables: [NavMode: "'Simple'", ReadZoomLevel: "1"] - else_if: "$NavMode = 'Character'" then: - - t: "rozszerzony" # phrase(an 'enhanced' way to do something) + - T: "rozszerzony" # phrase(an 'enhanced' way to do something) - set_variables: [NavMode: "'Enhanced'", ReadZoomLevel: "-1"] - else: - - t: "znak" # phrase(a mathematical 'character') + - T: "znak" # phrase(a mathematical 'character') - set_variables: [NavMode: "'Character'", ReadZoomLevel: "1"] - - t: "tryb" # phrase(a simple 'mode' of use) + - T: "tryb" # phrase(a simple 'mode' of use) - pause: long - test: - if: "$NavMode != 'Enhanced'" # potentially need to zoom to the sibling @@ -1623,7 +1623,7 @@ - test: if: "$Overview = 'true'" then: - - t: "czytaj wyrażenie po ruchu" # phrase('speak expression after move') + - T: "czytaj wyrażenie po ruchu" # phrase('speak expression after move') - pause: long - set_variables: [Overview: "'false'"] else: @@ -1640,9 +1640,9 @@ then: - test: - if: "$NavCommand = 'ReadCurrent'" - then: [t: "czytaj"] # phrase('read' next entry in table) - else: [t: "opisz"] # phrase('describe' next entry in table) - - t: "bieżący" # phrase('current' entry in table) + then: [T: "czytaj"] # phrase('read' next entry in table) + else: [T: "opisz"] # phrase('describe' next entry in table) + - T: "bieżący" # phrase('current' entry in table) - pause: long - set_variables: [NavNode: "@id"] @@ -1660,13 +1660,13 @@ then: - test: - if: "starts-with($NavCommand, 'Read')" - then: [t: "czytaj"] # phrase('read' next entry in table) + then: [T: "czytaj"] # phrase('read' next entry in table) - else_if: "starts-with($NavCommand, 'Describe')" - then: [t: "opisz"] # phrase('describe' next entry in table) + then: [T: "opisz"] # phrase('describe' next entry in table) - else_if: "starts-with($NavCommand, 'MoveTo')" - then: [t: "przejdź do"] # phrase('move to' the next entry in table) + then: [T: "przejdź do"] # phrase('move to' the next entry in table) else: [T: "zbiór"] # phrase('set' the value of the next entry in table) - - t: "symbol zastępczy" # phrase('placeholder' for the value) + - T: "symbol zastępczy" # phrase('placeholder' for the value) - x: "$PlaceMarkerIndex" - pause: long - set_variables: [NavNode: "$PlaceMarker"] @@ -1678,7 +1678,7 @@ - test: if: "$NavVerbosity != 'Terse'" then: - - t: "ustaw symbol zastępczy" # phrase('set placeholder' to the value) + - T: "ustaw symbol zastępczy" # phrase('set placeholder' to the value) - x: "$PlaceMarkerIndex" - pause: long - set_variables: [NavNode: "@id"] @@ -1710,11 +1710,11 @@ - test: if: "$NavCommand = 'WhereAmI'" then: - - t: "wewnątrz niczego więcej" # phrase('inside of nothing more') + - T: "wewnątrz niczego więcej" # phrase('inside of nothing more') - pause: long - set_variables: [SpeakExpression: "'false'"] else: - - t: "wewnątrz" # phrase('inside' a big expression) + - T: "wewnątrz" # phrase('inside' a big expression) - pause: medium - set_variables: [NavNode: "@id"] @@ -1722,7 +1722,7 @@ tag: "*" match: "$NavCommand = 'WhereAmI' or $NavCommand = 'WhereAmIAll'" replace: - - t: "wewnątrz" # phrase('inside' a big expression) + - T: "wewnątrz" # phrase('inside' a big expression) - pause: medium - test: - if: "$NavMode='Enhanced' and parent::*[self::m:mrow and (IsBracketed(., '(', ')', false) or IsBracketed(., '[', ']', false))]" diff --git a/Rules/Languages/pl/overview.yaml b/Rules/Languages/pl/overview.yaml index a65395889..a51169bb3 100644 --- a/Rules/Languages/pl/overview.yaml +++ b/Rules/Languages/pl/overview.yaml @@ -21,22 +21,22 @@ if: "IsNode(*[1], 'simple') and IsNode(*[2], 'simple')" then: - x: "*[1]" - - t: "przez" + - T: "przez" - x: "*[2]" else: - - t: "ułamek" + - T: "ułamek" - name: overview-default tag: [msqrt, "square-root"] match: "." replace: - - t: "pierwiastek kwadratowy" + - T: "pierwiastek kwadratowy" - test: if: "IsNode(*[1], 'simple')" then: - test: if: "$Verbosity!='Terse'" - then: [t: "z"] + then: [T: "z"] - x: "*[1]" - name: overview-default @@ -47,24 +47,24 @@ if: "*[2][self::m:mn]" then_test: - if: "*[2][.='2']" - then: [t: "pierwiastek kwadratowy"] + then: [T: "pierwiastek kwadratowy"] - else_if: "*[2][.='3']" - then: [t: "pierwiastek sześcienny"] + then: [T: "pierwiastek sześcienny"] - else_if: "*[2][not(contains(., '.'))]" - then: [x: "ToOrdinal(*[2])", t: "pierwiastek"] + then: [x: "ToOrdinal(*[2])", T: "pierwiastek"] else: - test: if: "*[2][self::m:mi][string-length(.)=1]" then: - x: "*[2]" else: {x: "*[2]"} - - t: "pierwiastek" + - T: "pierwiastek" - test: if: "IsNode(*[1], 'simple')" then: - test: if: "$Verbosity!='Terse'" - then: [t: "z"] + then: [T: "z"] - x: "*[1]" - name: matrix-override @@ -75,12 +75,12 @@ replace: - t: "" - x: count(*[2]/*) - - t: "na" + - T: "na" - x: count(*[2]/*[self::m:mtr][1]/*) - test: if: "*[1][.='|']" # just need to check the first bracket since we know it must be (, [, or | - then: [t: "wyznacznik"] - else: [t: "macierz"] + then: [T: "wyznacznik"] + else: [T: "macierz"] - name: overview-default tag: mtable @@ -88,9 +88,9 @@ replace: - t: "" - x: count(*[2]/*) - - t: "na" + - T: "na" - x: count(*[2]/*[self::m:mtr][1]/*) - - t: "tabela" + - T: "tabela" - name: short-mrow tag: mrow @@ -114,6 +114,6 @@ - pause: auto - x: "*[5]" - pause: auto - - t: "i tak dalej" + - T: "i tak dalej" - include: "SimpleSpeak_Rules.yaml" diff --git a/Rules/Languages/pl/unicode-full.yaml b/Rules/Languages/pl/unicode-full.yaml index 8246f4650..3c378bc8c 100644 --- a/Rules/Languages/pl/unicode-full.yaml +++ b/Rules/Languages/pl/unicode-full.yaml @@ -1,28 +1,28 @@ --- - - "¢": [t: "centy"] # 0xa2 - - "£": [t: "funty"] # 0xa3 - - "¤": [t: "znak waluty"] # 0xa4 - - "¥": [t: "jen"] # 0xa5 - - "¦": [t: "przerwana kreska"] # 0xa6 - - "§": [t: "paragraf"] # 0xa7 - - "¨": [t: "diereza"] # 0xa8 - - "©": [t: "znak praw autorskich"] # 0xa9 - - "ª": [t: "żeński wskaźnik liczebnika porządkowego"] # 0xaa + - "¢": [T: "centy"] # 0xa2 + - "£": [T: "funty"] # 0xa3 + - "¤": [T: "znak waluty"] # 0xa4 + - "¥": [T: "jen"] # 0xa5 + - "¦": [T: "przerwana kreska"] # 0xa6 + - "§": [T: "paragraf"] # 0xa7 + - "¨": [T: "diereza"] # 0xa8 + - "©": [T: "znak praw autorskich"] # 0xa9 + - "ª": [T: "żeński wskaźnik liczebnika porządkowego"] # 0xaa - "¬": [T: "nie"] # 0xac - - "«": [t: "lewy podwójny cudzysłów ostrokątny"] # 0xab + - "«": [T: "lewy podwójny cudzysłów ostrokątny"] # 0xab - "¯": # 0xaf - test: if: "ancestor::m:modified-variable and preceding-sibling::*[1][self::m:mi]" - then: [t: "kreska"] - else: [t: "linia"] - - "²": [t: "dwa"] # 0xb2 - - "³": [t: "trzy"] # 0xb3 - - "´": [t: "akut"] # 0xb4 - - "µ": [t: "mikro"] # 0xb5 - - "¹": [t: "jeden"] # 0xb9 - - "º": [t: "męski wskaźnik liczebnika porządkowego"] # 0xb9 + then: [T: "kreska"] + else: [T: "linia"] + - "²": [T: "dwa"] # 0xb2 + - "³": [T: "trzy"] # 0xb3 + - "´": [T: "akut"] # 0xb4 + - "µ": [T: "mikro"] # 0xb5 + - "¹": [T: "jeden"] # 0xb9 + - "º": [T: "męski wskaźnik liczebnika porządkowego"] # 0xb9 - "·": - test: if: "$SpeechStyle != 'ClearSpeak' or $ClearSpeak_MultSymbolDot = 'Auto'" @@ -35,162 +35,162 @@ else_test: if: $ClearSpeak_MultSymbolX = 'By' then: [T: "na"] - else: [t: "krzyż"] + else: [T: "krzyż"] - "÷": [T: "podzielone przez"] # 0xf7 - - "¡": [t: "odwrócony wykrzyknik"] # 0xa1 - - "¶": [t: "znak akapitu"] # 0xb6 - - "¿": [t: "odwrócony znak zapytania"] # 0xbf - - - "ʰ": [t: "modyfikator mały h"] # 0x2b0 - - "ʱ": [t: "modyfikator mały h z haczykiem"] # 0x2b1 - - "ʲ": [t: "modyfikator mały j"] # 0x2b2 - - "ʳ": [t: "modyfikator mały R"] # 0x2b3 - - "ʴ": [t: "modyfikator mały odwrócony R"] # 0x2b4 - - "ʵ": [t: "modyfikator mały odwrócony R z haczykiem"] # 0x2b5 + - "¡": [T: "odwrócony wykrzyknik"] # 0xa1 + - "¶": [T: "znak akapitu"] # 0xb6 + - "¿": [T: "odwrócony znak zapytania"] # 0xbf + + - "ʰ": [T: "modyfikator mały h"] # 0x2b0 + - "ʱ": [T: "modyfikator mały h z haczykiem"] # 0x2b1 + - "ʲ": [T: "modyfikator mały j"] # 0x2b2 + - "ʳ": [T: "modyfikator mały R"] # 0x2b3 + - "ʴ": [T: "modyfikator mały odwrócony R"] # 0x2b4 + - "ʵ": [T: "modyfikator mały odwrócony R z haczykiem"] # 0x2b5 - "ʶ": # 0x2b6 - - t: "modyfikator mały odwrócony" + - T: "modyfikator mały odwrócony" - spell: "translate('R', 'R', 'R')" - - "ʷ": [t: "modyfikator mały w"] # 0x2b7 - - "ʸ": [t: "modyfikator mały y"] # 0x2b8 - - "ʹ": [t: "modyfikator prim"] # 0x2b9 - - "ʺ": [t: "modyfikator podwójny prim"] # 0x2ba - - "ʻ": [t: "modyfikator odwrócony przecinek"] # 0x2bb - - "ʼ": [t: "modyfikator apostrof"] # 0x2bc - - "ʽ": [t: "modyfikator odwrócony przecinek"] # 0x2bd - - "ʾ": [t: "modyfikator prawa połowa pierścień"] # 0x2be - - "ʿ": [t: "modyfikator lewa połowa pierścień"] # 0x2bf - - "ˀ": [t: "modyfikator zwarcie krtaniowe"] # 0x2c0 - - "ˁ": [t: "modyfikator odwrócone zwarcie krtaniowe"] # 0x2c1 - - "˂": [t: "modyfikator lewy grot strzałki"] # 0x2c2 - - "˃": [t: "modyfikator prawy grot strzałki"] # 0x2c3 - - "˄": [t: "modyfikator górny grot strzałki"] # 0x2c4 - - "˅": [t: "modyfikator dolny grot strzałki"] # 0x2c5 - - "ˆ": [t: "modyfikator akcent daszkowy"] # 0x2c6 - - "ˇ": [t: "haczek"] # 0x2c7 - - "ˈ": [t: "modyfikator pionowej kreski"] # 0x2c8 - - "ˉ": [t: "modyfikator makron"] # 0x2c9 - - "ˊ": [t: "modyfikator akut akcent"] # 0x2ca - - "ˋ": [t: "modyfikator grawis akcent"] # 0x2cb - - "ˌ": [t: "modyfikator dolnej pionowej kreski"] # 0x2cc - - "ˍ": [t: "modyfikator dolny makron"] # 0x2cd - - "ˎ": [t: "modyfikator dolny akcent grawis"] # 0x2ce - - "ˏ": [t: "modyfikator dolny akcent akut"] # 0x2cf - - "ː": [t: "modyfikator trójkątny dwukropek"] # 0x2d0 - - "ˑ": [t: "modyfikator połowa trójkątny dwukropek"] # 0x2d1 - - "˒": [t: "modyfikator wyśrodkowany prawa połowa pierścień"] # 0x2d2 - - "˓": [t: "modyfikator wyśrodkowany lewa połowa pierścień"] # 0x2d3 - - "˔": [t: "modyfikator górnej pinezki"] # 0x2d4 - - "˕": [t: "modyfikator dolnej pinezki"] # 0x2d5 - - "˖": [t: "modyfikator znaku plus"] # 0x2d6 - - "˗": [t: "modyfikator znaku minus"] # 0x2d7 - - "˘": [t: "znak krótkości"] # 0x2d8 + - "ʷ": [T: "modyfikator mały w"] # 0x2b7 + - "ʸ": [T: "modyfikator mały y"] # 0x2b8 + - "ʹ": [T: "modyfikator prim"] # 0x2b9 + - "ʺ": [T: "modyfikator podwójny prim"] # 0x2ba + - "ʻ": [T: "modyfikator odwrócony przecinek"] # 0x2bb + - "ʼ": [T: "modyfikator apostrof"] # 0x2bc + - "ʽ": [T: "modyfikator odwrócony przecinek"] # 0x2bd + - "ʾ": [T: "modyfikator prawa połowa pierścień"] # 0x2be + - "ʿ": [T: "modyfikator lewa połowa pierścień"] # 0x2bf + - "ˀ": [T: "modyfikator zwarcie krtaniowe"] # 0x2c0 + - "ˁ": [T: "modyfikator odwrócone zwarcie krtaniowe"] # 0x2c1 + - "˂": [T: "modyfikator lewy grot strzałki"] # 0x2c2 + - "˃": [T: "modyfikator prawy grot strzałki"] # 0x2c3 + - "˄": [T: "modyfikator górny grot strzałki"] # 0x2c4 + - "˅": [T: "modyfikator dolny grot strzałki"] # 0x2c5 + - "ˆ": [T: "modyfikator akcent daszkowy"] # 0x2c6 + - "ˇ": [T: "haczek"] # 0x2c7 + - "ˈ": [T: "modyfikator pionowej kreski"] # 0x2c8 + - "ˉ": [T: "modyfikator makron"] # 0x2c9 + - "ˊ": [T: "modyfikator akut akcent"] # 0x2ca + - "ˋ": [T: "modyfikator grawis akcent"] # 0x2cb + - "ˌ": [T: "modyfikator dolnej pionowej kreski"] # 0x2cc + - "ˍ": [T: "modyfikator dolny makron"] # 0x2cd + - "ˎ": [T: "modyfikator dolny akcent grawis"] # 0x2ce + - "ˏ": [T: "modyfikator dolny akcent akut"] # 0x2cf + - "ː": [T: "modyfikator trójkątny dwukropek"] # 0x2d0 + - "ˑ": [T: "modyfikator połowa trójkątny dwukropek"] # 0x2d1 + - "˒": [T: "modyfikator wyśrodkowany prawa połowa pierścień"] # 0x2d2 + - "˓": [T: "modyfikator wyśrodkowany lewa połowa pierścień"] # 0x2d3 + - "˔": [T: "modyfikator górnej pinezki"] # 0x2d4 + - "˕": [T: "modyfikator dolnej pinezki"] # 0x2d5 + - "˖": [T: "modyfikator znaku plus"] # 0x2d6 + - "˗": [T: "modyfikator znaku minus"] # 0x2d7 + - "˘": [T: "znak krótkości"] # 0x2d8 - "˙": [T: "kropka"] # 0x2d9 - - "˚": [t: "pierścień nad"] # 0x2da + - "˚": [T: "pierścień nad"] # 0x2da - "˛": [t: "ogonek"] # 0x2db - - "˜": [t: "mały tylda"] # 0x2dc - - "˝": [t: "podwójny akut akcent"] # 0x2dd - - "˞": [t: "modyfikator rotycznego haczyka"] # 0x2de - - "˟": [t: "modyfikator krzyż akcent"] # 0x2df - - "ˠ": [t: "modyfikator mały gamma"] # 0x2e0 - - "ˡ": [t: "modyfikator mały L"] # 0x2e1 - - "ˢ": [t: "modyfikator mały s"] # 0x2e2 - - "ˣ": [t: "modyfikator mały X"] # 0x2e3 - - "ˤ": [t: "modyfikator mały odwrócone zwarcie krtaniowe"] # 0x2e4 - - "˥": [t: "modyfikator kreski bardzo wysokiego tonu"] # 0x2e5 - - "˦": [t: "modyfikator kreski wysokiego tonu"] # 0x2e6 - - "˧": [t: "modyfikator środkowy tonowy kreska"] # 0x2e7 - - "˨": [t: "modyfikator kreski niskiego tonu"] # 0x2e8 - - "˩": [t: "modyfikator kreski bardzo niskiego tonu"] # 0x2e9 - - "˪": [t: "modyfikator znak tonu yin odchodzącego"] # 0x2ea - - "˫": [t: "modyfikator znak tonu yang odchodzącego"] # 0x2eb - - "ˬ": [t: "modyfikator dźwięczność"] # 0x2ec - - "˭": [t: "modyfikator nieaspirowany"] # 0x2ed - - "ˮ": [t: "modyfikator podwójny apostrof"] # 0x2ee - - "˯": [t: "modyfikator dolny grot strzałki"] # 0x2ef - - "˰": [t: "modyfikator dolny górny grot strzałki"] # 0x2f0 - - "˱": [t: "modyfikator dolny lewy grot strzałki"] # 0x2f1 - - "˲": [t: "modyfikator dolny prawy grot strzałki"] # 0x2f2 - - "˳": [t: "modyfikator dolny pierścień"] # 0x2f3 - - "˴": [t: "modyfikator środkowy grawis akcent"] # 0x2f4 - - "˵": [t: "modyfikator środkowy podwójny grawis akcent"] # 0x2f5 - - "˶": [t: "modyfikator środkowy podwójny akut akcent"] # 0x2f6 - - "˷": [t: "modyfikator dolna tylda"] # 0x2f7 - - "˸": [t: "modyfikator podniesiony dwukropek"] # 0x2f8 - - "˹": [t: "modyfikator początek wysoki ton"] # 0x2f9 - - "˺": [t: "modyfikator koniec wysoki ton"] # 0x2fa - - "˻": [t: "modyfikator początek niski ton"] # 0x2fb - - "˼": [t: "modyfikator koniec niski ton"] # 0x2fc - - "˽": [t: "modyfikator półka"] # 0x2fd - - "˾": [t: "modyfikator otwórz półka"] # 0x2fe - - "˿": [t: "modyfikator dolny strzałka w lewo"] # 0x2ff - - "̀": [t: "ozdobnik akcentu grawis"] # 0x300 - - "́": [t: "ozdobnik akcentu ostrego"] # 0x301 - - "̂": [t: "ozdobnik daszka"] # 0x302 - - "̃": [t: "ozdobnik tyldy"] # 0x303 - - "̄": [t: "ozdobnik makronu"] # 0x304 - - "̅": [t: "ozdobnik kreski górnej"] # 0x305 - - "̆": [t: "ozdobnik znaku krótkości"] # 0x306 - - "̇": [t: "ozdobnik kropki nad"] # 0x307 - - "̈": [t: "ozdobnik diaerezy"] # 0x308 - - "̉": [t: "hak nad ozdobnik"] # 0x309 - - "̊": [t: "pierścień nad ozdobnik"] # 0x30a - - "̋": [t: "ozdobnik podwójnego akutu"] # 0x30b - - "̌": [t: "haczek"] # 0x30c - - "̍": [t: "ozdobnik pionowej kreski nad"] # 0x30d - - "̎": [t: "ozdobnik podwójnej pionowej kreski nad"] # 0x30e - - "̏": [t: "ozdobnik podwójnego grawisu"] # 0x30f - - "̐": [t: "ozdobnik ćandrabindu"] # 0x310 - - "̑": [t: "odwrócony ozdobnik znaku krótkości"] # 0x311 - - "̒": [t: "odwrócony przecinek nad ozdobnik"] # 0x312 - - "̓": [t: "przecinek nad ozdobnik"] # 0x313 - - "̔": [t: "odwrócony przecinek nad ozdobnik"] # 0x314 - - "̕": [t: "przecinek nad prawy ozdobnik"] # 0x315 - - "̖": [t: "ozdobnik akcentu grawis pod"] # 0x316 - - "̗": [t: "ozdobnik akcentu ostrego pod"] # 0x317 - - "̘": [t: "ozdobnik lewej pinezki pod spodem"] # 0x318 - - "̙": [t: "ozdobnik prawej pinezki pod spodem"] # 0x319 - - "̚": [t: "lewy kąt nad ozdobnik"] # 0x31a - - "̛": [t: "ozdobnik rożka"] # 0x31b - - "̜": [t: "lewa połowa pierścień pod ozdobnik"] # 0x31c - - "̝": [t: "ozdobnik górnej pinezki pod spodem"] # 0x31d - - "̞": [t: "ozdobnik dolnej pinezki pod spodem"] # 0x31e - - "̟": [t: "ozdobnik znaku plus pod spodem"] # 0x31f - - "̠": [t: "ozdobnik znaku minus pod spodem"] # 0x320 - - "̡": [t: "palatalizowany haczyk pod spodem"] # 0x321 - - "̢": [t: "retrofleksyjny haczyk pod spodem"] # 0x322 - - "̣": [t: "ozdobnik kropki pod"] # 0x323 - - "̤": [t: "ozdobnik dierezy pod spodem"] # 0x324 - - "̥": [t: "pierścień pod ozdobnik"] # 0x325 - - "̦": [t: "przecinek pod ozdobnik"] # 0x326 - - "̧": [t: "ozdobnik cedilli"] # 0x327 - - "̨": [t: "ogonek ozdobnik"] # 0x328 - - "̩": [t: "ozdobnik pionowej kreski pod spodem"] # 0x329 - - "̪": [t: "mostek pod ozdobnik"] # 0x32a - - "̫": [t: "odwrócony podwójny łuk pod spodem"] # 0x32b - - "̬": [t: "haczek pod ozdobnik"] # 0x32c - - "̭": [t: "ozdobnik daszka pod"] # 0x32d - - "̮": [t: "ozdobnik znaku krótkości pod spodem"] # 0x32e - - "̯": [t: "odwrócony ozdobnik znaku krótkości pod spodem"] # 0x32f - - "̰": [t: "tylda pod ozdobnik"] # 0x330 - - "̱": [t: "ozdobnik makronu pod"] # 0x331 - - "̲": [t: "dolny linia ozdobnik"] # 0x332 - - "̳": [t: "podwójny dolny linia ozdobnik"] # 0x333 - - "̴": [t: "tylda nakładka ozdobnik"] # 0x334 - - "̵": [t: "krótkie przekreślenie nakładane jako ozdobnik"] # 0x335 - - "̶": [t: "długie przekreślenie nakładane jako ozdobnik"] # 0x336 - - "̷": [t: "krótki ukośnik nakładka ozdobnik"] # 0x337 - - "̸": [t: "długi ukośnik nakładka ozdobnik"] # 0x338 - - "̹": [t: "prawa połowa pierścień pod ozdobnik"] # 0x339 - - "̺": [t: "odwrócony mostek pod ozdobnik"] # 0x33a - - "̻": [t: "kwadrat pod ozdobnik"] # 0x33b - - "̼": [t: "ozdobnik mewy pod spodem"] # 0x33c - - "̽": [t: "X nad ozdobnik"] # 0x33d - - "̾": [t: "pionowy ozdobnik tyldy"] # 0x33e - - "̿": [t: "ozdobnik podwójnej kreski górnej"] # 0x33f - - "̀": [t: "grawis tonowy znak ozdobnik"] # 0x340 - - "́": [t: "akut tonowy znak ozdobnik"] # 0x341 - - "͆": [t: "mostek nad"] # 0x346 + - "˜": [T: "mały tylda"] # 0x2dc + - "˝": [T: "podwójny akut akcent"] # 0x2dd + - "˞": [T: "modyfikator rotycznego haczyka"] # 0x2de + - "˟": [T: "modyfikator krzyż akcent"] # 0x2df + - "ˠ": [T: "modyfikator mały gamma"] # 0x2e0 + - "ˡ": [T: "modyfikator mały L"] # 0x2e1 + - "ˢ": [T: "modyfikator mały s"] # 0x2e2 + - "ˣ": [T: "modyfikator mały X"] # 0x2e3 + - "ˤ": [T: "modyfikator mały odwrócone zwarcie krtaniowe"] # 0x2e4 + - "˥": [T: "modyfikator kreski bardzo wysokiego tonu"] # 0x2e5 + - "˦": [T: "modyfikator kreski wysokiego tonu"] # 0x2e6 + - "˧": [T: "modyfikator środkowy tonowy kreska"] # 0x2e7 + - "˨": [T: "modyfikator kreski niskiego tonu"] # 0x2e8 + - "˩": [T: "modyfikator kreski bardzo niskiego tonu"] # 0x2e9 + - "˪": [T: "modyfikator znak tonu yin odchodzącego"] # 0x2ea + - "˫": [T: "modyfikator znak tonu yang odchodzącego"] # 0x2eb + - "ˬ": [T: "modyfikator dźwięczność"] # 0x2ec + - "˭": [T: "modyfikator nieaspirowany"] # 0x2ed + - "ˮ": [T: "modyfikator podwójny apostrof"] # 0x2ee + - "˯": [T: "modyfikator dolny grot strzałki"] # 0x2ef + - "˰": [T: "modyfikator dolny górny grot strzałki"] # 0x2f0 + - "˱": [T: "modyfikator dolny lewy grot strzałki"] # 0x2f1 + - "˲": [T: "modyfikator dolny prawy grot strzałki"] # 0x2f2 + - "˳": [T: "modyfikator dolny pierścień"] # 0x2f3 + - "˴": [T: "modyfikator środkowy grawis akcent"] # 0x2f4 + - "˵": [T: "modyfikator środkowy podwójny grawis akcent"] # 0x2f5 + - "˶": [T: "modyfikator środkowy podwójny akut akcent"] # 0x2f6 + - "˷": [T: "modyfikator dolna tylda"] # 0x2f7 + - "˸": [T: "modyfikator podniesiony dwukropek"] # 0x2f8 + - "˹": [T: "modyfikator początek wysoki ton"] # 0x2f9 + - "˺": [T: "modyfikator koniec wysoki ton"] # 0x2fa + - "˻": [T: "modyfikator początek niski ton"] # 0x2fb + - "˼": [T: "modyfikator koniec niski ton"] # 0x2fc + - "˽": [T: "modyfikator półka"] # 0x2fd + - "˾": [T: "modyfikator otwórz półka"] # 0x2fe + - "˿": [T: "modyfikator dolny strzałka w lewo"] # 0x2ff + - "̀": [T: "ozdobnik akcentu grawis"] # 0x300 + - "́": [T: "ozdobnik akcentu ostrego"] # 0x301 + - "̂": [T: "ozdobnik daszka"] # 0x302 + - "̃": [T: "ozdobnik tyldy"] # 0x303 + - "̄": [T: "ozdobnik makronu"] # 0x304 + - "̅": [T: "ozdobnik kreski górnej"] # 0x305 + - "̆": [T: "ozdobnik znaku krótkości"] # 0x306 + - "̇": [T: "ozdobnik kropki nad"] # 0x307 + - "̈": [T: "ozdobnik diaerezy"] # 0x308 + - "̉": [T: "hak nad ozdobnik"] # 0x309 + - "̊": [T: "pierścień nad ozdobnik"] # 0x30a + - "̋": [T: "ozdobnik podwójnego akutu"] # 0x30b + - "̌": [T: "haczek"] # 0x30c + - "̍": [T: "ozdobnik pionowej kreski nad"] # 0x30d + - "̎": [T: "ozdobnik podwójnej pionowej kreski nad"] # 0x30e + - "̏": [T: "ozdobnik podwójnego grawisu"] # 0x30f + - "̐": [T: "ozdobnik ćandrabindu"] # 0x310 + - "̑": [T: "odwrócony ozdobnik znaku krótkości"] # 0x311 + - "̒": [T: "odwrócony przecinek nad ozdobnik"] # 0x312 + - "̓": [T: "przecinek nad ozdobnik"] # 0x313 + - "̔": [T: "odwrócony przecinek nad ozdobnik"] # 0x314 + - "̕": [T: "przecinek nad prawy ozdobnik"] # 0x315 + - "̖": [T: "ozdobnik akcentu grawis pod"] # 0x316 + - "̗": [T: "ozdobnik akcentu ostrego pod"] # 0x317 + - "̘": [T: "ozdobnik lewej pinezki pod spodem"] # 0x318 + - "̙": [T: "ozdobnik prawej pinezki pod spodem"] # 0x319 + - "̚": [T: "lewy kąt nad ozdobnik"] # 0x31a + - "̛": [T: "ozdobnik rożka"] # 0x31b + - "̜": [T: "lewa połowa pierścień pod ozdobnik"] # 0x31c + - "̝": [T: "ozdobnik górnej pinezki pod spodem"] # 0x31d + - "̞": [T: "ozdobnik dolnej pinezki pod spodem"] # 0x31e + - "̟": [T: "ozdobnik znaku plus pod spodem"] # 0x31f + - "̠": [T: "ozdobnik znaku minus pod spodem"] # 0x320 + - "̡": [T: "palatalizowany haczyk pod spodem"] # 0x321 + - "̢": [T: "retrofleksyjny haczyk pod spodem"] # 0x322 + - "̣": [T: "ozdobnik kropki pod"] # 0x323 + - "̤": [T: "ozdobnik dierezy pod spodem"] # 0x324 + - "̥": [T: "pierścień pod ozdobnik"] # 0x325 + - "̦": [T: "przecinek pod ozdobnik"] # 0x326 + - "̧": [T: "ozdobnik cedilli"] # 0x327 + - "̨": [T: "ogonek ozdobnik"] # 0x328 + - "̩": [T: "ozdobnik pionowej kreski pod spodem"] # 0x329 + - "̪": [T: "mostek pod ozdobnik"] # 0x32a + - "̫": [T: "odwrócony podwójny łuk pod spodem"] # 0x32b + - "̬": [T: "haczek pod ozdobnik"] # 0x32c + - "̭": [T: "ozdobnik daszka pod"] # 0x32d + - "̮": [T: "ozdobnik znaku krótkości pod spodem"] # 0x32e + - "̯": [T: "odwrócony ozdobnik znaku krótkości pod spodem"] # 0x32f + - "̰": [T: "tylda pod ozdobnik"] # 0x330 + - "̱": [T: "ozdobnik makronu pod"] # 0x331 + - "̲": [T: "dolny linia ozdobnik"] # 0x332 + - "̳": [T: "podwójny dolny linia ozdobnik"] # 0x333 + - "̴": [T: "tylda nakładka ozdobnik"] # 0x334 + - "̵": [T: "krótkie przekreślenie nakładane jako ozdobnik"] # 0x335 + - "̶": [T: "długie przekreślenie nakładane jako ozdobnik"] # 0x336 + - "̷": [T: "krótki ukośnik nakładka ozdobnik"] # 0x337 + - "̸": [T: "długi ukośnik nakładka ozdobnik"] # 0x338 + - "̹": [T: "prawa połowa pierścień pod ozdobnik"] # 0x339 + - "̺": [T: "odwrócony mostek pod ozdobnik"] # 0x33a + - "̻": [T: "kwadrat pod ozdobnik"] # 0x33b + - "̼": [T: "ozdobnik mewy pod spodem"] # 0x33c + - "̽": [T: "X nad ozdobnik"] # 0x33d + - "̾": [T: "pionowy ozdobnik tyldy"] # 0x33e + - "̿": [T: "ozdobnik podwójnej kreski górnej"] # 0x33f + - "̀": [T: "grawis tonowy znak ozdobnik"] # 0x340 + - "́": [T: "akut tonowy znak ozdobnik"] # 0x341 + - "͆": [T: "mostek nad"] # 0x346 - "ΪΫϏ": # 0x3aa, 0x3ab, 0x3cf - test: @@ -205,29 +205,29 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" replace: [spell: "translate('.', 'ΪΫϏ', 'ιυϗ')"] - - t: "z dialityką" - - "ϊ": [t: "jota z dialityką"] # 0x3ca - - "ϋ": [t: "ypsilon z dialityką"] # 0x3cb - - "ό": [t: "omikron z tonosem"] # 0x3cc - - "ύ": [t: "ypsilon z tonosem"] # 0x3cd - - "ώ": [t: "omega z tonosem"] # 0x3ce + - T: "z dialityką" + - "ϊ": [T: "jota z dialityką"] # 0x3ca + - "ϋ": [T: "ypsilon z dialityką"] # 0x3cb + - "ό": [T: "omikron z tonosem"] # 0x3cc + - "ύ": [T: "ypsilon z tonosem"] # 0x3cd + - "ώ": [T: "omega z tonosem"] # 0x3ce - "ϐ": [t: "beta"] # 0x3d0 - "ϑ": [t: "theta"] # 0x3d1 - - "ϒ": [t: "ypsilon z haczykiem"] # 0x3d2 - - "ϓ": [t: "ypsilon z akutem i haczykiem"] # 0x3d3 - - "ϔ": [t: "ypsilon z dierezą i haczykiem"] # 0x3d4 - - "ϕ": [t: "fi"] # 0x3d5 + - "ϒ": [T: "ypsilon z haczykiem"] # 0x3d2 + - "ϓ": [T: "ypsilon z akutem i haczykiem"] # 0x3d3 + - "ϔ": [T: "ypsilon z dierezą i haczykiem"] # 0x3d4 + - "ϕ": [T: "fi"] # 0x3d5 - "ϖ": [t: "pi"] # 0x3d6 - "ϗ": [t: "kai"] # 0x3d7 - - "Ϙ": [t: "wielka archaiczna koppa"] # 0x3d8 - - "ϙ": [t: "archaiczna koppa"] # 0x3d9 + - "Ϙ": [T: "wielka archaiczna koppa"] # 0x3d8 + - "ϙ": [T: "archaiczna koppa"] # 0x3d9 - "ϵ": [t: "epsilon"] # 0x3f5 - - "϶": [t: "odwrócony epsilon"] # 0x3f6 + - "϶": [T: "odwrócony epsilon"] # 0x3f6 - "А-Я": # 0x410 - 0x42f - test: if: "$CapitalLetters_Beep" @@ -241,23 +241,23 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" replace: [spell: "translate('.', 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', 'абвгдежзийклмнопрстуфхцчшщъыьэюя')"] - "а": [T: "a"] # 0x430 - "б": [t: "be"] # 0x431 - - "в": [t: "we"] # 0x432 - - "г": [t: "ge"] # 0x433 + - "в": [T: "we"] # 0x432 + - "г": [T: "ge"] # 0x433 - "д": [t: "de"] # 0x434 - - "е": [t: "je"] # 0x435 - - "ж": [t: "że"] # 0x436 + - "е": [T: "je"] # 0x435 + - "ж": [T: "że"] # 0x436 - "з": [t: "ze"] # 0x437 - "и": [t: "i"] # 0x438 - - "й": [t: "krótkie i"] # 0x439 + - "й": [T: "krótkie i"] # 0x439 - "к": [t: "ka"] # 0x43a - - "л": [t: "eł"] # 0x43b + - "л": [T: "eł"] # 0x43b - "м": [t: "em"] # 0x43c - "н": [t: "en"] # 0x43d - "о": [t: "o"] # 0x43e @@ -267,29 +267,29 @@ - "т": [t: "te"] # 0x442 - "у": [t: "u"] # 0x443 - "ф": [t: "ef"] # 0x444 - - "х": [t: "cha"] # 0x445 - - "ц": [t: "ce"] # 0x446 - - "ч": [t: "cze"] # 0x447 - - "ш": [t: "sza"] # 0x448 - - "щ": [t: "szcza"] # 0x449 - - "ъ": [t: "twardy znak"] # 0x44a - - "ы": [t: "jery"] # 0x44b - - "ь": [t: "miękki znak"] # 0x44c + - "х": [T: "cha"] # 0x445 + - "ц": [T: "ce"] # 0x446 + - "ч": [T: "cze"] # 0x447 + - "ш": [T: "sza"] # 0x448 + - "щ": [T: "szcza"] # 0x449 + - "ъ": [T: "twardy znak"] # 0x44a + - "ы": [T: "jery"] # 0x44b + - "ь": [T: "miękki znak"] # 0x44c - "э": [t: "e"] # 0x44d - - "ю": [t: "ju"] # 0x44e - - "я": [t: "ja"] # 0x44f - - "؆": [t: "arabsko-indyjski pierwiastek sześcienny"] # 0x606 - - "؇": [t: "arabsko-indyjski czwarty pierwiastek"] # 0x607 - - "؈": [t: "arabski półprosta"] # 0x608 - - "‐": [t: "łącznik"] # 0x2010 - - "‑": [t: "łącznik"] # 0x2011 - - "‒": [t: "pauza cyfrowa"] # 0x2012 - - "–": [t: "półpauza"] # 0x2013 - - "—": [t: "pauza"] # 0x2014 - - "―": [t: "kreska pozioma"] # 0x2015 - - "‖": [t: "podwójna pionowa kreska"] # 0x2016 - - "†": [t: "obelisk"] # 0x2020 - - "‡": [t: "podwójny obelisk"] # 0x2021 + - "ю": [T: "ju"] # 0x44e + - "я": [T: "ja"] # 0x44f + - "؆": [T: "arabsko-indyjski pierwiastek sześcienny"] # 0x606 + - "؇": [T: "arabsko-indyjski czwarty pierwiastek"] # 0x607 + - "؈": [T: "arabski półprosta"] # 0x608 + - "‐": [T: "łącznik"] # 0x2010 + - "‑": [T: "łącznik"] # 0x2011 + - "‒": [T: "pauza cyfrowa"] # 0x2012 + - "–": [T: "półpauza"] # 0x2013 + - "—": [T: "pauza"] # 0x2014 + - "―": [T: "kreska pozioma"] # 0x2015 + - "‖": [T: "podwójna pionowa kreska"] # 0x2016 + - "†": [T: "obelisk"] # 0x2020 + - "‡": [T: "podwójny obelisk"] # 0x2021 - " - ": [T: " "] # 0x2000 - 0x2007 @@ -297,7 +297,7 @@ - test: if: "@data-chem-formula-op" then: [T: "kropka"] - else: [t: "punkt"] + else: [T: "punkt"] - "…": # 0x2026 test: @@ -306,221 +306,221 @@ # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' # speak '…' as 'and so on...' unless expr starts with '…' - "../*[1][.='…']" - then: [t: "trzy kropki"] + then: [T: "trzy kropki"] else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' if: "count(following-sibling::*) = 0" - then: [t: "i tak dalej"] - else: [t: "i tak dalej aż do"] - - - "‰": [t: "promil"] # 0x2030 - - "‱": [t: "na dziesięć tysięcy"] # 0x2031 - - "′": [t: "prim"] # 0x2032 - - "″": [t: "podwójny prim"] # 0x2033 - - "‴": [t: "potrójny prim"] # 0x2034 - - "‵": [t: "odwrócony prim"] # 0x2035 - - "‶": [t: "odwrócony podwójny prim"] # 0x2036 - - "‷": [t: "odwrócony potrójny prim"] # 0x2037 + then: [T: "i tak dalej"] + else: [T: "i tak dalej aż do"] + + - "‰": [T: "promil"] # 0x2030 + - "‱": [T: "na dziesięć tysięcy"] # 0x2031 + - "′": [T: "prim"] # 0x2032 + - "″": [T: "podwójny prim"] # 0x2033 + - "‴": [T: "potrójny prim"] # 0x2034 + - "‵": [T: "odwrócony prim"] # 0x2035 + - "‶": [T: "odwrócony podwójny prim"] # 0x2036 + - "‷": [T: "odwrócony potrójny prim"] # 0x2037 - "‸": [T: "do potęgi"] # 0x2038 - - "‹": [t: "pojedynczy lewy cudzysłów ostrokątny"] # 0x2039 - - "›": [t: "pojedynczy prawy cudzysłów ostrokątny"] # 0x203a + - "‹": [T: "pojedynczy lewy cudzysłów ostrokątny"] # 0x2039 + - "›": [T: "pojedynczy prawy cudzysłów ostrokątny"] # 0x203a - "‼": # 0x203c - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "podwójny wykrzyknik punkt"] # 0x203c - else: [t: "podwójny silnia"] # 0x203c + then: [T: "podwójny wykrzyknik punkt"] # 0x203c + else: [T: "podwójny silnia"] # 0x203c - "⁄": # 0x2044 - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "duży ukośnik"] # 0x203c + then: [T: "duży ukośnik"] # 0x203c else: [T: "podzielone przez"] # 0x203c - - "⁅": [t: "lewy kwadratowy nawias z piórem"] # 0x2045 - - "⁆": [t: "prawy kwadratowy nawias z piórem"] # 0x2046 - - "※": [t: "znak odsyłacza"] # 0x203b - - "‿": [t: "łuk dolny"] # 0x203F - - "⁀": [t: "łuk górny"] # 0x2040 - - "⁎": [t: "dolna gwiazdka"] # 0x204e - - "⁏": [t: "odwrócony średnik"] # 0x204f - - "⁐": [t: "zamknij górny"] # 0x2050 - - "⁑": [t: "dwie pionowe gwiazdki"] # 0x2051 - - "⁒": [t: "handlowy znak minus"] # 0x2052 - - "⁗": [t: "poczwórny prim"] # 0x2057 + - "⁅": [T: "lewy kwadratowy nawias z piórem"] # 0x2045 + - "⁆": [T: "prawy kwadratowy nawias z piórem"] # 0x2046 + - "※": [T: "znak odsyłacza"] # 0x203b + - "‿": [T: "łuk dolny"] # 0x203F + - "⁀": [T: "łuk górny"] # 0x2040 + - "⁎": [T: "dolna gwiazdka"] # 0x204e + - "⁏": [T: "odwrócony średnik"] # 0x204f + - "⁐": [T: "zamknij górny"] # 0x2050 + - "⁑": [T: "dwie pionowe gwiazdki"] # 0x2051 + - "⁒": [T: "handlowy znak minus"] # 0x2052 + - "⁗": [T: "poczwórny prim"] # 0x2057 - "⁠": [T: ""] # 0x2060 - - "⁰": [t: "do zerowej potęgi"] # 0x2070 - - "ⁱ": [t: "do potęgi i"] # 0x2071 - - "⁴": [t: "do czwartej potęgi"] # 0x2074 - - "⁵": [t: "do piątej potęgi"] # 0x2075 - - "⁶": [t: "do szóstej potęgi"] # 0x2076 - - "⁷": [t: "do siódmej potęgi"] # 0x2077 - - "⁸": [t: "do ósmej potęgi"] # 0x2078 - - "⁹": [t: "do dziewiątej potęgi"] # 0x2079 - - "⁺": [t: "znak plus w indeksie górnym"] # 0x207a - - "⁻": [t: "znak minus w indeksie górnym"] # 0x207b - - "⁼": [t: "znak równości w indeksie górnym"] # 0x207c - - "⁽": [t: "lewy nawias w indeksie górnym"] # 0x207d - - "⁾": [t: "prawy nawias w indeksie górnym"] # 0x207e - - "ⁿ": [t: "do potęgi n"] # 0x207f - - "₀": [t: "indeks dolny zero"] # 0x2080 - - "₁": [t: "indeks dolny jeden"] # 0x2081 - - "₂": [t: "indeks dolny dwa"] # 0x2082 - - "₃": [t: "indeks dolny trzy"] # 0x2083 - - "₄": [t: "indeks dolny cztery"] # 0x2084 - - "₅": [t: "indeks dolny pięć"] # 0x2085 - - "₆": [t: "indeks dolny sześć"] # 0x2086 - - "₇": [t: "indeks dolny siedem"] # 0x2087 - - "₈": [t: "indeks dolny osiem"] # 0x2088 - - "₉": [t: "indeks dolny dziewięć"] # 0x2089 - - "₊": [t: "znak plus w indeksie dolnym"] # 0x208a - - "₋": [t: "znak minus w indeksie dolnym"] # 0x208b - - "₌": [t: "znak równości w indeksie dolnym"] # 0x208c - - "₍": [t: "lewy nawias w indeksie dolnym"] # 0x208d - - "₎": [t: "prawy nawias w indeksie dolnym"] # 0x208e - - "ₐ": [t: "indeks dolny a"] # 0x2090 - - "ₑ": [t: "indeks dolny e"] # 0x2091 - - "ₒ": [t: "indeks dolny o"] # 0x2092 - - "ₓ": [t: "indeks dolny X"] # 0x2093 - - "ₕ": [t: "indeks dolny h"] # 0x2095 - - "ₖ": [t: "indeks dolny k"] # 0x2096 - - "ₗ": [t: "indeks dolny L"] # 0x2097 - - "ₘ": [t: "indeks dolny M"] # 0x2098 - - "ₙ": [t: "indeks dolny N"] # 0x2099 - - "ₚ": [t: "indeks dolny p"] # 0x209a - - "ₛ": [t: "indeks dolny s"] # 0x209b - - "ₜ": [t: "indeks dolny t"] # 0x209c - - "₠": [t: "europejska jednostka walutowa"] # 0x20a0 - - "₡": [t: "kolon"] # 0x20a1 - - "₢": [t: "znak cruzeiro"] # 0x20a2 - - "₣": [t: "frank"] # 0x20a3 + - "⁰": [T: "do zerowej potęgi"] # 0x2070 + - "ⁱ": [T: "do potęgi i"] # 0x2071 + - "⁴": [T: "do czwartej potęgi"] # 0x2074 + - "⁵": [T: "do piątej potęgi"] # 0x2075 + - "⁶": [T: "do szóstej potęgi"] # 0x2076 + - "⁷": [T: "do siódmej potęgi"] # 0x2077 + - "⁸": [T: "do ósmej potęgi"] # 0x2078 + - "⁹": [T: "do dziewiątej potęgi"] # 0x2079 + - "⁺": [T: "znak plus w indeksie górnym"] # 0x207a + - "⁻": [T: "znak minus w indeksie górnym"] # 0x207b + - "⁼": [T: "znak równości w indeksie górnym"] # 0x207c + - "⁽": [T: "lewy nawias w indeksie górnym"] # 0x207d + - "⁾": [T: "prawy nawias w indeksie górnym"] # 0x207e + - "ⁿ": [T: "do potęgi n"] # 0x207f + - "₀": [T: "indeks dolny zero"] # 0x2080 + - "₁": [T: "indeks dolny jeden"] # 0x2081 + - "₂": [T: "indeks dolny dwa"] # 0x2082 + - "₃": [T: "indeks dolny trzy"] # 0x2083 + - "₄": [T: "indeks dolny cztery"] # 0x2084 + - "₅": [T: "indeks dolny pięć"] # 0x2085 + - "₆": [T: "indeks dolny sześć"] # 0x2086 + - "₇": [T: "indeks dolny siedem"] # 0x2087 + - "₈": [T: "indeks dolny osiem"] # 0x2088 + - "₉": [T: "indeks dolny dziewięć"] # 0x2089 + - "₊": [T: "znak plus w indeksie dolnym"] # 0x208a + - "₋": [T: "znak minus w indeksie dolnym"] # 0x208b + - "₌": [T: "znak równości w indeksie dolnym"] # 0x208c + - "₍": [T: "lewy nawias w indeksie dolnym"] # 0x208d + - "₎": [T: "prawy nawias w indeksie dolnym"] # 0x208e + - "ₐ": [T: "indeks dolny a"] # 0x2090 + - "ₑ": [T: "indeks dolny e"] # 0x2091 + - "ₒ": [T: "indeks dolny o"] # 0x2092 + - "ₓ": [T: "indeks dolny X"] # 0x2093 + - "ₕ": [T: "indeks dolny h"] # 0x2095 + - "ₖ": [T: "indeks dolny k"] # 0x2096 + - "ₗ": [T: "indeks dolny L"] # 0x2097 + - "ₘ": [T: "indeks dolny M"] # 0x2098 + - "ₙ": [T: "indeks dolny N"] # 0x2099 + - "ₚ": [T: "indeks dolny p"] # 0x209a + - "ₛ": [T: "indeks dolny s"] # 0x209b + - "ₜ": [T: "indeks dolny t"] # 0x209c + - "₠": [T: "europejska jednostka walutowa"] # 0x20a0 + - "₡": [T: "kolon"] # 0x20a1 + - "₢": [T: "znak cruzeiro"] # 0x20a2 + - "₣": [T: "frank"] # 0x20a3 - "₤": [t: "lira"] # 0x20a4 - - "₥": [t: "mille"] # 0x20a5 + - "₥": [T: "mille"] # 0x20a5 - "₦": [t: "naira"] # 0x20a6 - "₧": [t: "peseta"] # 0x20a7 - - "₨": [t: "rupie"] # 0x20a8 + - "₨": [T: "rupie"] # 0x20a8 - "₩": [t: "won"] # 0x20a9 - - "₪": [t: "nowe szekle"] # 0x20aa + - "₪": [T: "nowe szekle"] # 0x20aa - "₫": [t: "dong"] # 0x20ab - - "€": [t: "euro"] # 0x20ac + - "€": [T: "euro"] # 0x20ac - "₭": [t: "kip"] # 0x20ad - "₮": [t: "tugrik"] # 0x20ae - "₯": [t: "drachma"] # 0x20af - - "₰": [t: "niemieckie fenigi"] # 0x20b0 - - "₱": [t: "peso"] # 0x20b1 - - "₲": [t: "guarani"] # 0x20b2 - - "₳": [t: "australe"] # 0x20b3 - - "₴": [t: "hrywny"] # 0x20b4 - - "₵": [t: "cedi"] # 0x20b5 - - "₶": [t: "liwr turoński"] # 0x20b6 + - "₰": [T: "niemieckie fenigi"] # 0x20b0 + - "₱": [T: "peso"] # 0x20b1 + - "₲": [T: "guarani"] # 0x20b2 + - "₳": [T: "australe"] # 0x20b3 + - "₴": [T: "hrywny"] # 0x20b4 + - "₵": [T: "cedi"] # 0x20b5 + - "₶": [T: "liwr turoński"] # 0x20b6 - "₷": [T: "spesmilos"] # 0x20b7 - - "₸": [t: "tenge"] # 0x20b8 - - "₹": [t: "rupie indyjskie"] # 0x20b9 - - "₺": [t: "liry tureckie"] # 0x20ba - - "⃐": [t: "lewy harpun nad ozdobnik"] # 0x20d0 - - "⃑": [t: "prawy harpun nad ozdobnik"] # 0x20d1 - - "⃒": [t: "ozdobnik długiej pionowej kreski nakładanej"] # 0x20d2 - - "⃓": [t: "ozdobnik krótkiej pionowej kreski nakładanej"] # 0x20d3 - - "⃔": [t: "strzałka nad przeciwnie do ruchu wskazówek zegara, ozdobnik"] # 0x20d4 - - "⃕": [t: "strzałka nad zgodnie z ruchem wskazówek zegara, ozdobnik"] # 0x20d5 - - "⃖": [t: "strzałka w lewo nad ozdobnik"] # 0x20d6 - - "⃗": [t: "strzałka w prawo nad ozdobnik"] # 0x20d7 - - "⃘": [t: "pierścień nakładka ozdobnik"] # 0x20d8 - - "⃙": [t: "pierścień zgodnie z ruchem wskazówek zegara, ozdobnik nakładany"] # 0x20d9 - - "⃚": [t: "pierścień przeciwnie do ruchu wskazówek zegara, ozdobnik nakładany"] # 0x20da - - "⃛": [t: "potrójny kropka"] # 0x20db - - "⃜": [t: "poczwórny kropka"] # 0x20dc - - "⃝": [t: "obejmujący okrąg ozdobnik"] # 0x20dd - - "⃞": [t: "obejmujący kwadrat ozdobnik"] # 0x20de - - "⃟": [t: "obejmujący romb ozdobnik"] # 0x20df - - "⃠": [t: "obejmujący okrąg ukośnik odwrotny ozdobnik"] # 0x20e0 - - "⃡": [t: "lewy strzałka w prawo nad ozdobnik"] # 0x20e1 - - "⃢": [t: "obejmujący ekran, ozdobnik"] # 0x20e2 - - "⃣": [t: "obejmujący nasadkę klawisza, ozdobnik"] # 0x20e3 - - "⃤": [t: "obejmujący w górę skierowany trójkąt ozdobnik"] # 0x20e4 - - "⃥": [t: "odwrotny ukośnik nakładka ozdobnik"] # 0x20e5 - - "⃦": [t: "ozdobnik podwójnej pionowej kreski"] # 0x20e6 - - "⃧": [t: "symbol renty, ozdobnik"] # 0x20e7 - - "⃨": [t: "potrójna kropka pod spodem"] # 0x20e8 - - "⃩": [t: "szeroki mostek nad, ozdobnik"] # 0x20e9 - - "⃪": [t: "strzałka w lewo nakładka ozdobnik"] # 0x20ea - - "⃫": [t: "długi podwójny ukośnik nakładka ozdobnik"] # 0x20eb - - "⃬": [t: "prawy harpun z grotem dolnym ozdobnik"] # 0x20ec - - "⃭": [t: "lewy harpun z grotem dolnym ozdobnik"] # 0x20ed - - "⃮": [t: "strzałka w lewo pod ozdobnik"] # 0x20ee - - "⃯": [t: "strzałka w prawo pod ozdobnik"] # 0x20ef - - "⃰": [t: "gwiazdka nad ozdobnik"] # 0x20f0 - - "℄": [t: "symbol linii środkowej"] # 0x2104 - - "℅": [t: "do rąk"] # 0x2105 - - "℆": [t: "każda"] # 0x2106 - - "ℇ": [t: "stała Eulera"] # 0x2107 - - "℈": [t: "skrupule"] # 0x2108 - - "℉": [t: "stopnie Fahrenheita"] # 0x2109 - - "ℊ": [t: "pisane g"] # 0x210a + - "₸": [T: "tenge"] # 0x20b8 + - "₹": [T: "rupie indyjskie"] # 0x20b9 + - "₺": [T: "liry tureckie"] # 0x20ba + - "⃐": [T: "lewy harpun nad ozdobnik"] # 0x20d0 + - "⃑": [T: "prawy harpun nad ozdobnik"] # 0x20d1 + - "⃒": [T: "ozdobnik długiej pionowej kreski nakładanej"] # 0x20d2 + - "⃓": [T: "ozdobnik krótkiej pionowej kreski nakładanej"] # 0x20d3 + - "⃔": [T: "strzałka nad przeciwnie do ruchu wskazówek zegara, ozdobnik"] # 0x20d4 + - "⃕": [T: "strzałka nad zgodnie z ruchem wskazówek zegara, ozdobnik"] # 0x20d5 + - "⃖": [T: "strzałka w lewo nad ozdobnik"] # 0x20d6 + - "⃗": [T: "strzałka w prawo nad ozdobnik"] # 0x20d7 + - "⃘": [T: "pierścień nakładka ozdobnik"] # 0x20d8 + - "⃙": [T: "pierścień zgodnie z ruchem wskazówek zegara, ozdobnik nakładany"] # 0x20d9 + - "⃚": [T: "pierścień przeciwnie do ruchu wskazówek zegara, ozdobnik nakładany"] # 0x20da + - "⃛": [T: "potrójny kropka"] # 0x20db + - "⃜": [T: "poczwórny kropka"] # 0x20dc + - "⃝": [T: "obejmujący okrąg ozdobnik"] # 0x20dd + - "⃞": [T: "obejmujący kwadrat ozdobnik"] # 0x20de + - "⃟": [T: "obejmujący romb ozdobnik"] # 0x20df + - "⃠": [T: "obejmujący okrąg ukośnik odwrotny ozdobnik"] # 0x20e0 + - "⃡": [T: "lewy strzałka w prawo nad ozdobnik"] # 0x20e1 + - "⃢": [T: "obejmujący ekran, ozdobnik"] # 0x20e2 + - "⃣": [T: "obejmujący nasadkę klawisza, ozdobnik"] # 0x20e3 + - "⃤": [T: "obejmujący w górę skierowany trójkąt ozdobnik"] # 0x20e4 + - "⃥": [T: "odwrotny ukośnik nakładka ozdobnik"] # 0x20e5 + - "⃦": [T: "ozdobnik podwójnej pionowej kreski"] # 0x20e6 + - "⃧": [T: "symbol renty, ozdobnik"] # 0x20e7 + - "⃨": [T: "potrójna kropka pod spodem"] # 0x20e8 + - "⃩": [T: "szeroki mostek nad, ozdobnik"] # 0x20e9 + - "⃪": [T: "strzałka w lewo nakładka ozdobnik"] # 0x20ea + - "⃫": [T: "długi podwójny ukośnik nakładka ozdobnik"] # 0x20eb + - "⃬": [T: "prawy harpun z grotem dolnym ozdobnik"] # 0x20ec + - "⃭": [T: "lewy harpun z grotem dolnym ozdobnik"] # 0x20ed + - "⃮": [T: "strzałka w lewo pod ozdobnik"] # 0x20ee + - "⃯": [T: "strzałka w prawo pod ozdobnik"] # 0x20ef + - "⃰": [T: "gwiazdka nad ozdobnik"] # 0x20f0 + - "℄": [T: "symbol linii środkowej"] # 0x2104 + - "℅": [T: "do rąk"] # 0x2105 + - "℆": [T: "każda"] # 0x2106 + - "ℇ": [T: "stała Eulera"] # 0x2107 + - "℈": [T: "skrupule"] # 0x2108 + - "℉": [T: "stopnie Fahrenheita"] # 0x2109 + - "ℊ": [T: "pisane g"] # 0x210a - "ℌℑℨℭ": # 0x210c, 0x2111, 0x2128, 0x212d - - t: "fraktura" + - T: "fraktura" - spell: "translate('.', 'ℌℑℨℭ', 'HIZC')" - "ℍℙℾℿ": # 0x210d, 0x2119, 0x213e, 0x213f - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', 'ℍℙℾℿ', 'HPΓΠ')" - - "ℎ": [t: "stała Plancka"] # 0x210e - - "ℏ": [t: "h kreślone"] # 0x210f + - "ℎ": [T: "stała Plancka"] # 0x210e + - "ℏ": [T: "h kreślone"] # 0x210f - "ℐℒ℘ℬℰℱℳ": # 0x2110, 0x2112, 0x2118, 0x2130, 0x2131, 0x2133 - - t: "pisane" + - T: "pisane" - spell: "translate('.', 'ℐℒ℘ℬℰℱℳ', 'ILPBEFM')" - - "ℓ": [t: "pisane L"] # 0x2113 - - "℔": [t: "funty"] # 0x2114 - - "№": [t: "numer"] # 0x2116 - - "℥": [t: "uncje"] # 0x2125 - - "Ω": [t: "omy"] # 0x2126 + - "ℓ": [T: "pisane L"] # 0x2113 + - "℔": [T: "funty"] # 0x2114 + - "№": [T: "numer"] # 0x2116 + - "℥": [T: "uncje"] # 0x2125 + - "Ω": [T: "omy"] # 0x2126 - "℧": [T: "mho"] # 0x2127 - - "℩": [t: "odwrócony jota"] # 0x2129 - - "K": [t: "kelwin"] # 0x212a - - "Å": [t: "angstremy"] # 0x212b - - "ℯ": [t: "pisane e"] # 0x212f + - "℩": [T: "odwrócony jota"] # 0x2129 + - "K": [T: "kelwin"] # 0x212a + - "Å": [T: "angstremy"] # 0x212b + - "ℯ": [T: "pisane e"] # 0x212f # coalesced some chars that use cap letters - "Ⅎ℺⅁⅂⅃⅄": # 0x2132, 0x213a, 0x2141, 0x2142, 0x2143, 0x2144 - test: - if: "'.' = '℺'" - then: [t: "obrócone"] + then: [T: "obrócone"] - else_if: "'.' = 'Ⅎ'" - then: [t: "odwrócone"] + then: [T: "odwrócone"] - else_if: "'.' = '⅃'" - then: [t: "odwrócone bezszeryfowe"] - else: [t: "odwrócony bezszeryfowe"] + then: [T: "odwrócone bezszeryfowe"] + else: [T: "odwrócony bezszeryfowe"] - spell: "translate('.', 'Ⅎ℺⅁⅂⅃⅄', 'FQGLLY')" - - "ℴ": [t: "pisane o"] # 0x2134 - - "ℵ": [t: "pierwsza pozaskończona liczba kardynalna"] # 0x2135 - - "ℶ": [t: "druga pozaskończona liczba kardynalna"] # 0x2136 - - "ℷ": [t: "trzecia pozaskończona liczba kardynalna"] # 0x2137 - - "ℸ": [t: "czwarta pozaskończona liczba kardynalna"] # 0x2138 - - "ℼ": [t: "dwukreskowe pi"] # 0x213c - - "ℽ": [t: "dwukreskowe gamma"] # 0x213d - - "⅀": [t: "dwukreskowa suma N-arna"] # 0x2140 - - "⅋": [t: "odwrócony znak et"] # 0x214b + - "ℴ": [T: "pisane o"] # 0x2134 + - "ℵ": [T: "pierwsza pozaskończona liczba kardynalna"] # 0x2135 + - "ℶ": [T: "druga pozaskończona liczba kardynalna"] # 0x2136 + - "ℷ": [T: "trzecia pozaskończona liczba kardynalna"] # 0x2137 + - "ℸ": [T: "czwarta pozaskończona liczba kardynalna"] # 0x2138 + - "ℼ": [T: "dwukreskowe pi"] # 0x213c + - "ℽ": [T: "dwukreskowe gamma"] # 0x213d + - "⅀": [T: "dwukreskowa suma N-arna"] # 0x2140 + - "⅋": [T: "odwrócony znak et"] # 0x214b - "⅌": [T: "na"] # 0x214c - - "ⅎ": [t: "odwrócony f"] # 0x214e - - "¼": [t: "jedna czwarta"] # 0x00bc - - "½": [t: "jedna druga"] # 0x00bd - - "¾": [t: "trzy czwarte"] # 0x00be - - "⅐": [t: "jeden siódmy"] # 0x2150 - - "⅑": [t: "jeden dziewiąty"] # 0x2151 - - "⅒": [t: "jedna dziesiąta"] # 0x2152 - - "⅓": [t: "jeden trzeci"] # 0x2153 - - "⅔": [t: "dwie trzecie"] # 0x2154 - - "⅕": [t: "jeden piąty"] # 0x2155 - - "⅖": [t: "dwie piąte"] # 0x2156 - - "⅗": [t: "trzy piąte"] # 0x2157 - - "⅘": [t: "cztery piąte"] # 0x2158 - - "⅙": [t: "jeden szósty"] # 0x2159 - - "⅚": [t: "pięć szóstych"] # 0x215a - - "⅛": [t: "jeden ósmy"] # 0x215b - - "⅜": [t: "trzy ósme"] # 0x215c - - "⅝": [t: "pięć ósmych"] # 0x215d - - "⅞": [t: "siedem ósmych"] # 0x215e - - "⅟": [t: "jeden przez"] # 0x215f + - "ⅎ": [T: "odwrócony f"] # 0x214e + - "¼": [T: "jedna czwarta"] # 0x00bc + - "½": [T: "jedna druga"] # 0x00bd + - "¾": [T: "trzy czwarte"] # 0x00be + - "⅐": [T: "jeden siódmy"] # 0x2150 + - "⅑": [T: "jeden dziewiąty"] # 0x2151 + - "⅒": [T: "jedna dziesiąta"] # 0x2152 + - "⅓": [T: "jeden trzeci"] # 0x2153 + - "⅔": [T: "dwie trzecie"] # 0x2154 + - "⅕": [T: "jeden piąty"] # 0x2155 + - "⅖": [T: "dwie piąte"] # 0x2156 + - "⅗": [T: "trzy piąte"] # 0x2157 + - "⅘": [T: "cztery piąte"] # 0x2158 + - "⅙": [T: "jeden szósty"] # 0x2159 + - "⅚": [T: "pięć szóstych"] # 0x215a + - "⅛": [T: "jeden ósmy"] # 0x215b + - "⅜": [T: "trzy ósme"] # 0x215c + - "⅝": [T: "pięć ósmych"] # 0x215d + - "⅞": [T: "siedem ósmych"] # 0x215e + - "⅟": [T: "jeden przez"] # 0x215f - "Ⅰ": [t: "I"] # 0x2160 - "Ⅱ": [T: "I I"] # 0x2161 - "Ⅲ": [T: "I I I"] # 0x2162 @@ -553,170 +553,170 @@ - "ⅽ": [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 - - "↖": [t: "północ zachód strzałka"] # 0x2196 + - "↉": [T: "zero trzecich"] # 0x2189 + - "↔": [T: "lewy strzałka w prawo"] # 0x2194 + - "↕": [T: "górny strzałka w dół"] # 0x2195 + - "↖": [T: "północ zachód strzałka"] # 0x2196 - "↗": # 0x2197 - test: if: "ancestor::*[2][self::m:limit]" - then: [t: "dąży od dołu"] - else: [t: "północ wschód strzałka"] + then: [T: "dąży od dołu"] + else: [T: "północ wschód strzałka"] - "↘": # 0x2198 - test: if: "ancestor::*[2][self::m:limit]" - then: [t: "dąży od góry"] - else: [t: "południe wschód strzałka"] - - - "↙": [t: "południe zachód strzałka"] # 0x2199 - - "↚": [t: "przekreślona strzałka w lewo"] # 0x219a - - "↛": [t: "przekreślona strzałka w prawo"] # 0x219b - - "↜": [t: "falista strzałka w lewo"] # 0x219c - - "↝": [t: "falista strzałka w prawo"] # 0x219d - - "↞": [t: "strzałka w lewo z dwoma grotami"] # 0x219e - - "↟": [t: "strzałka w górę z dwoma grotami"] # 0x219f - - "↠": [t: "strzałka w prawo z dwoma grotami"] # 0x21a0 - - "↡": [t: "strzałka w dół z dwoma grotami"] # 0x21a1 - - "↢": [t: "strzałka w lewo z ogon"] # 0x21a2 - - "↣": [t: "strzałka w prawo z ogon"] # 0x21a3 - - "↤": [t: "strzałka w lewo od kreski"] # 0x21a4 - - "↥": [t: "strzałka w górę od kreski"] # 0x21a5 - - "↦": [t: "strzałka w prawo od kreski"] # 0x21a6 - - "↧": [t: "strzałka w dół od kreski"] # 0x21a7 - - "↨": [t: "górny strzałka w dół z podstawa"] # 0x21a8 - - "↩": [t: "strzałka w lewo z hak"] # 0x21a9 - - "↪": [t: "strzałka w prawo z hak"] # 0x21aa - - "↫": [t: "strzałka w lewo z pętlą"] # 0x21ab - - "↬": [t: "strzałka w prawo z pętlą"] # 0x21ac - - "↭": [t: "falista strzałka w lewo i w prawo"] # 0x21ad - - "↮": [t: "przekreślona strzałka w lewo i w prawo"] # 0x21ae - - "↯": [t: "strzałka zygzakowata w dół"] # 0x21af - - "↰": [t: "strzałka w górę z tip lewy"] # 0x21b0 - - "↱": [t: "strzałka w górę z tip prawy"] # 0x21b1 - - "↲": [t: "strzałka w dół z tip lewy"] # 0x21b2 - - "↳": [t: "strzałka w dół z tip prawy"] # 0x21b3 - - "↴": [t: "strzałka w prawo z narożnikiem w dół"] # 0x21b4 - - "↵": [t: "strzałka w dół z narożnikiem w lewo"] # 0x21b5 - - "↶": [t: "strzałka po górnym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0x21b6 - - "↷": [t: "strzałka po górnym półokręgu zgodnie z ruchem wskazówek zegara"] # 0x21b7 - - "↸": [t: "strzałka północno-zachodnia do długiej kreski"] # 0x21b8 - - "↹": [t: "strzałka w lewo do kreski nad strzałką w prawo do kreski"] # 0x21b9 - - "↺": [t: "strzałka po otwartym okręgu przeciwnie do ruchu wskazówek zegara"] # 0x21ba - - "↻": [t: "strzałka po otwartym okręgu zgodnie z ruchem wskazówek zegara"] # 0x21bb - - "↼": [t: "lewy harpun górny"] # 0x21bc - - "↽": [t: "lewy harpun dolny"] # 0x21bd - - "↾": [t: "górny harpun prawy"] # 0x21be - - "↿": [t: "górny harpun lewy"] # 0x21bf - - "⇀": [t: "prawy harpun górny"] # 0x21c0 - - "⇁": [t: "prawy harpun dolny"] # 0x21c1 - - "⇂": [t: "dolny harpun prawy"] # 0x21c2 - - "⇃": [t: "dolny harpun lewy"] # 0x21c3 - - "⇄": [t: "strzałka w prawo nad strzałką w lewo"] # 0x21c4 - - "⇅": [t: "strzałka w górę po lewej i strzałka w dół"] # 0x21c5 - - "⇆": [t: "strzałka w lewo nad strzałką w prawo"] # 0x21c6 - - "⇇": [t: "podwójne strzałki w lewo"] # 0x21c7 - - "⇈": [t: "podwójne strzałki w górę"] # 0x21c8 - - "⇉": [t: "podwójne strzałki w prawo"] # 0x21c9 - - "⇊": [t: "podwójne strzałki w dół"] # 0x21ca - - "⇋": [t: "lewy harpun przez prawy harpun"] # 0x21cb - - "⇌": [t: "prawy harpun przez lewy harpun"] # 0x21cc + then: [T: "dąży od góry"] + else: [T: "południe wschód strzałka"] + + - "↙": [T: "południe zachód strzałka"] # 0x2199 + - "↚": [T: "przekreślona strzałka w lewo"] # 0x219a + - "↛": [T: "przekreślona strzałka w prawo"] # 0x219b + - "↜": [T: "falista strzałka w lewo"] # 0x219c + - "↝": [T: "falista strzałka w prawo"] # 0x219d + - "↞": [T: "strzałka w lewo z dwoma grotami"] # 0x219e + - "↟": [T: "strzałka w górę z dwoma grotami"] # 0x219f + - "↠": [T: "strzałka w prawo z dwoma grotami"] # 0x21a0 + - "↡": [T: "strzałka w dół z dwoma grotami"] # 0x21a1 + - "↢": [T: "strzałka w lewo z ogon"] # 0x21a2 + - "↣": [T: "strzałka w prawo z ogon"] # 0x21a3 + - "↤": [T: "strzałka w lewo od kreski"] # 0x21a4 + - "↥": [T: "strzałka w górę od kreski"] # 0x21a5 + - "↦": [T: "strzałka w prawo od kreski"] # 0x21a6 + - "↧": [T: "strzałka w dół od kreski"] # 0x21a7 + - "↨": [T: "górny strzałka w dół z podstawa"] # 0x21a8 + - "↩": [T: "strzałka w lewo z hak"] # 0x21a9 + - "↪": [T: "strzałka w prawo z hak"] # 0x21aa + - "↫": [T: "strzałka w lewo z pętlą"] # 0x21ab + - "↬": [T: "strzałka w prawo z pętlą"] # 0x21ac + - "↭": [T: "falista strzałka w lewo i w prawo"] # 0x21ad + - "↮": [T: "przekreślona strzałka w lewo i w prawo"] # 0x21ae + - "↯": [T: "strzałka zygzakowata w dół"] # 0x21af + - "↰": [T: "strzałka w górę z tip lewy"] # 0x21b0 + - "↱": [T: "strzałka w górę z tip prawy"] # 0x21b1 + - "↲": [T: "strzałka w dół z tip lewy"] # 0x21b2 + - "↳": [T: "strzałka w dół z tip prawy"] # 0x21b3 + - "↴": [T: "strzałka w prawo z narożnikiem w dół"] # 0x21b4 + - "↵": [T: "strzałka w dół z narożnikiem w lewo"] # 0x21b5 + - "↶": [T: "strzałka po górnym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0x21b6 + - "↷": [T: "strzałka po górnym półokręgu zgodnie z ruchem wskazówek zegara"] # 0x21b7 + - "↸": [T: "strzałka północno-zachodnia do długiej kreski"] # 0x21b8 + - "↹": [T: "strzałka w lewo do kreski nad strzałką w prawo do kreski"] # 0x21b9 + - "↺": [T: "strzałka po otwartym okręgu przeciwnie do ruchu wskazówek zegara"] # 0x21ba + - "↻": [T: "strzałka po otwartym okręgu zgodnie z ruchem wskazówek zegara"] # 0x21bb + - "↼": [T: "lewy harpun górny"] # 0x21bc + - "↽": [T: "lewy harpun dolny"] # 0x21bd + - "↾": [T: "górny harpun prawy"] # 0x21be + - "↿": [T: "górny harpun lewy"] # 0x21bf + - "⇀": [T: "prawy harpun górny"] # 0x21c0 + - "⇁": [T: "prawy harpun dolny"] # 0x21c1 + - "⇂": [T: "dolny harpun prawy"] # 0x21c2 + - "⇃": [T: "dolny harpun lewy"] # 0x21c3 + - "⇄": [T: "strzałka w prawo nad strzałką w lewo"] # 0x21c4 + - "⇅": [T: "strzałka w górę po lewej i strzałka w dół"] # 0x21c5 + - "⇆": [T: "strzałka w lewo nad strzałką w prawo"] # 0x21c6 + - "⇇": [T: "podwójne strzałki w lewo"] # 0x21c7 + - "⇈": [T: "podwójne strzałki w górę"] # 0x21c8 + - "⇉": [T: "podwójne strzałki w prawo"] # 0x21c9 + - "⇊": [T: "podwójne strzałki w dół"] # 0x21ca + - "⇋": [T: "lewy harpun przez prawy harpun"] # 0x21cb + - "⇌": [T: "prawy harpun przez lewy harpun"] # 0x21cc - "⇍": [T: "nie wynika z"] # 0x21cd - "⇎": [T: "nie jest równoważne"] # 0x21ce - "⇏": [T: "nie implikuje"] # 0x21cf - "⇐": [T: "wynika z"] # 0x21d0 - - "⇑": [t: "podwójna strzałka w górę"] # 0x21d1 - - "⇒": [t: "implikuje"] # 0x21d2 - - "⇓": [t: "podwójna strzałka w dół"] # 0x21d3 - - "⇔": [t: "wtedy i tylko wtedy"] # 0x21d4 - - "⇕": [t: "podwójna strzałka w górę i w dół"] # 0x21d5 - - "⇖": [t: "podwójna strzałka na północny zachód"] # 0x21d6 - - "⇗": [t: "podwójna strzałka na północny wschód"] # 0x21d7 - - "⇘": [t: "podwójna strzałka na południowy wschód"] # 0x21d8 - - "⇙": [t: "podwójna strzałka na południowy zachód"] # 0x21d9 - - "⇚": [t: "lewy potrójny strzałka"] # 0x21da - - "⇛": [t: "prawy potrójny strzałka"] # 0x21db - - "⇜": [t: "falista strzałka w lewo"] # 0x21dc - - "⇝": [t: "falista strzałka w prawo"] # 0x21dd - - "⇞": [t: "strzałka w górę z podwójną kreską"] # 0x21de - - "⇟": [t: "strzałka w dół z podwójną kreską"] # 0x21df - - "⇠": [t: "przerywana strzałka w lewo"] # 0x21e0 - - "⇡": [t: "przerywana strzałka w górę"] # 0x21e1 - - "⇢": [t: "przerywana strzałka w prawo"] # 0x21e2 - - "⇣": [t: "przerywana strzałka w dół"] # 0x21e3 - - "⇤": [t: "strzałka w lewo do kreski"] # 0x21e4 - - "⇥": [t: "strzałka w prawo do kreski"] # 0x21e5 - - "⇦": [t: "biała strzałka w lewo"] # 0x21e6 - - "⇧": [t: "biała strzałka w górę"] # 0x21e7 - - "⇨": [t: "biała strzałka w prawo"] # 0x21e8 - - "⇩": [t: "biała strzałka w dół"] # 0x21e9 - - "⇪": [t: "biała strzałka w górę od kreski"] # 0x21ea - - "⇫": [t: "górna biała strzałka na podstawie"] # 0x21eb - - "⇬": [t: "górna biała strzałka na podstawie z kreską poziomą"] # 0x21ec - - "⇭": [t: "górna biała strzałka na podstawie z kreską pionową"] # 0x21ed - - "⇮": [t: "górny biały podwójna strzałka"] # 0x21ee - - "⇯": [t: "górna biała podwójna strzałka na podstawie"] # 0x21ef - - "⇰": [t: "biała strzałka w prawo od ściany"] # 0x21f0 - - "⇱": [t: "strzałka północno-zachodnia do narożnika"] # 0x21f1 - - "⇲": [t: "strzałka południowo-wschodnia do narożnika"] # 0x21f2 - - "⇳": [t: "biała strzałka w górę i w dół"] # 0x21f3 - - "⇴": [t: "strzałka w prawo z małym okręgiem"] # 0x21f4 - - "⇵": [t: "strzałka w dół po lewej od strzałki w górę"] # 0x21f5 - - "⇶": [t: "trzy strzałki w prawo"] # 0x21f6 - - "⇷": [t: "strzałka w lewo z pionową kreską"] # 0x21f7 - - "⇸": [t: "strzałka w prawo z pionową kreską"] # 0x21f8 - - "⇹": [t: "strzałki w lewo i w prawo z pionową kreską"] # 0x21f9 - - "⇺": [t: "strzałka w lewo z podwójną pionową kreską"] # 0x21fa - - "⇻": [t: "strzałka w prawo z podwójną pionową kreską"] # 0x21fb - - "⇼": [t: "strzałki w lewo i w prawo z podwójną pionową kreską"] # 0x21fc - - "⇽": [t: "strzałka w lewo z otwartym grotem"] # 0x21fd - - "⇾": [t: "strzałka w prawo z otwartym grotem"] # 0x21fe - - "⇿": [t: "strzałka w lewo i w prawo z otwartymi grotami"] # 0x21ff - - "∀": [t: "dla każdego"] # 0x2200 + - "⇑": [T: "podwójna strzałka w górę"] # 0x21d1 + - "⇒": [T: "implikuje"] # 0x21d2 + - "⇓": [T: "podwójna strzałka w dół"] # 0x21d3 + - "⇔": [T: "wtedy i tylko wtedy"] # 0x21d4 + - "⇕": [T: "podwójna strzałka w górę i w dół"] # 0x21d5 + - "⇖": [T: "podwójna strzałka na północny zachód"] # 0x21d6 + - "⇗": [T: "podwójna strzałka na północny wschód"] # 0x21d7 + - "⇘": [T: "podwójna strzałka na południowy wschód"] # 0x21d8 + - "⇙": [T: "podwójna strzałka na południowy zachód"] # 0x21d9 + - "⇚": [T: "lewy potrójny strzałka"] # 0x21da + - "⇛": [T: "prawy potrójny strzałka"] # 0x21db + - "⇜": [T: "falista strzałka w lewo"] # 0x21dc + - "⇝": [T: "falista strzałka w prawo"] # 0x21dd + - "⇞": [T: "strzałka w górę z podwójną kreską"] # 0x21de + - "⇟": [T: "strzałka w dół z podwójną kreską"] # 0x21df + - "⇠": [T: "przerywana strzałka w lewo"] # 0x21e0 + - "⇡": [T: "przerywana strzałka w górę"] # 0x21e1 + - "⇢": [T: "przerywana strzałka w prawo"] # 0x21e2 + - "⇣": [T: "przerywana strzałka w dół"] # 0x21e3 + - "⇤": [T: "strzałka w lewo do kreski"] # 0x21e4 + - "⇥": [T: "strzałka w prawo do kreski"] # 0x21e5 + - "⇦": [T: "biała strzałka w lewo"] # 0x21e6 + - "⇧": [T: "biała strzałka w górę"] # 0x21e7 + - "⇨": [T: "biała strzałka w prawo"] # 0x21e8 + - "⇩": [T: "biała strzałka w dół"] # 0x21e9 + - "⇪": [T: "biała strzałka w górę od kreski"] # 0x21ea + - "⇫": [T: "górna biała strzałka na podstawie"] # 0x21eb + - "⇬": [T: "górna biała strzałka na podstawie z kreską poziomą"] # 0x21ec + - "⇭": [T: "górna biała strzałka na podstawie z kreską pionową"] # 0x21ed + - "⇮": [T: "górny biały podwójna strzałka"] # 0x21ee + - "⇯": [T: "górna biała podwójna strzałka na podstawie"] # 0x21ef + - "⇰": [T: "biała strzałka w prawo od ściany"] # 0x21f0 + - "⇱": [T: "strzałka północno-zachodnia do narożnika"] # 0x21f1 + - "⇲": [T: "strzałka południowo-wschodnia do narożnika"] # 0x21f2 + - "⇳": [T: "biała strzałka w górę i w dół"] # 0x21f3 + - "⇴": [T: "strzałka w prawo z małym okręgiem"] # 0x21f4 + - "⇵": [T: "strzałka w dół po lewej od strzałki w górę"] # 0x21f5 + - "⇶": [T: "trzy strzałki w prawo"] # 0x21f6 + - "⇷": [T: "strzałka w lewo z pionową kreską"] # 0x21f7 + - "⇸": [T: "strzałka w prawo z pionową kreską"] # 0x21f8 + - "⇹": [T: "strzałki w lewo i w prawo z pionową kreską"] # 0x21f9 + - "⇺": [T: "strzałka w lewo z podwójną pionową kreską"] # 0x21fa + - "⇻": [T: "strzałka w prawo z podwójną pionową kreską"] # 0x21fb + - "⇼": [T: "strzałki w lewo i w prawo z podwójną pionową kreską"] # 0x21fc + - "⇽": [T: "strzałka w lewo z otwartym grotem"] # 0x21fd + - "⇾": [T: "strzałka w prawo z otwartym grotem"] # 0x21fe + - "⇿": [T: "strzałka w lewo i w prawo z otwartymi grotami"] # 0x21ff + - "∀": [T: "dla każdego"] # 0x2200 - "∁": # 0x2201 - - t: "dopełnienie" + - T: "dopełnienie" - "∂": # 0x2202 - test: if: "$Verbosity='Terse'" - then: [t: "cząstkowe"] - else: [t: "pochodna cząstkowa"] - - "∃": [t: "istnieje"] # 0x2203 - - "∄": [t: "nie istnieje"] # 0x2204 + then: [T: "cząstkowe"] + else: [T: "pochodna cząstkowa"] + - "∃": [T: "istnieje"] # 0x2203 + - "∄": [T: "nie istnieje"] # 0x2204 - "∅": [T: "zbiór pusty"] # 0x2205 - "∆": # 0x2206 - test: if: "following-sibling::*" then_test: if: "$Verbosity!='Terse'" - then: [t: "laplasjan"] # "LahPlahsian" sounds better than "laplacian" in speech engines tested - else: [t: "laplasjan"] - else: [t: "laplasjan"] + then: [T: "laplasjan"] # "LahPlahsian" sounds better than "laplacian" in speech engines tested + else: [T: "laplasjan"] + else: [T: "laplasjan"] - - "∇": [t: "nabla"] # 0x2207 + - "∇": [T: "nabla"] # 0x2207 - "∉": # 0x2209 # rule is identical to 0x2208 - test: if: "$SpeechStyle != 'ClearSpeak'" - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] # 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: "nie należy do"] + then: [T: "nie należy do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "nie jest elementem zbioru"] - - else: [t: "nienależące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "nie jest elementem zbioru"] + - else: [T: "nienależące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "nie należy do"] - - else: [t: "nie należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "nie należy do"] + - else: [T: "nie należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - "∊": # 0x220a - test: if: "$SpeechStyle != 'ClearSpeak'" @@ -724,7 +724,7 @@ - test: if: "$Verbosity!='Terse' and not(parent::m:set)" # "the set x is an element of ..." sounds bad then: [T: "jest"] - - t: "element zbioru" + - T: "element zbioru" # 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 @@ -732,32 +732,32 @@ - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "element zbioru"] + then: [T: "element zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "należy do"] - - else: [t: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "należy do"] - - else: [t: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - - "∋": [t: "zawiera element"] # 0x220b - - "∌": [t: "nie zawiera elementu"] # 0x220c - - "∍": [t: "zawiera element"] # 0x220d - - "∎": [t: "koniec dowodu"] # 0x220e + then: [T: "należy do"] + - else: [T: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + - "∋": [T: "zawiera element"] # 0x220b + - "∌": [T: "nie zawiera elementu"] # 0x220c + - "∍": [T: "zawiera element"] # 0x220d + - "∎": [T: "koniec dowodu"] # 0x220e - "∏": [T: "iloczyn"] # 0x220f - - "∐": [t: "koprodukt"] # 0x2210 + - "∐": [T: "koprodukt"] # 0x2210 - "∑": [T: "suma"] # 0x2211 - "−": [T: "minus"] # 0x2212 - "∓": [T: "minus plus"] # 0x2213 - - "∔": [t: "kropka plus"] # 0x2214 + - "∔": [T: "kropka plus"] # 0x2214 - "∕": [T: "podzielone przez"] # 0x2215 - - "∖": [t: "zbiór minus"] # 0x2216 + - "∖": [T: "zbiór minus"] # 0x2216 - "∗": [T: "razy"] # 0x2217 - - "∘": [t: "złożone z"] # 0x2218 + - "∘": [T: "złożone z"] # 0x2218 - "∙": # 0x2219 - test: if: "@data-chem-formula-op" @@ -765,71 +765,71 @@ else: [T: "razy"] - "√": # 0x221a - - t: "pierwiastek kwadratowy z" + - T: "pierwiastek kwadratowy z" - "∛": # 0x221b - - t: "pierwiastek sześcienny z" + - T: "pierwiastek sześcienny z" - "∜": # 0x221c - - t: "czwarty pierwiastek z" + - T: "czwarty pierwiastek z" - "∝": # 0x221d - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "proporcjonalne do" + - T: "proporcjonalne do" - "∞": - test: if: "ancestor::*[self::m:limit or self::m:limit-sup or self::m:limit-inf or self::m:large-op]" then: [T: "nieskończoności"] else: [T: "nieskończoność"] # 0x221e - - "∟": [t: "kąt prosty"] # 0x221f - - "∠": [t: "kąt"] # 0x2220 - - "∡": [t: "kąt mierzony"] # 0x2221 - - "∢": [t: "kąt sferyczny"] # 0x2222 + - "∟": [T: "kąt prosty"] # 0x221f + - "∠": [T: "kąt"] # 0x2220 + - "∡": [T: "kąt mierzony"] # 0x2221 + - "∢": [T: "kąt sferyczny"] # 0x2222 - "∣": [T: "dzieli"] # 0x2223 - - "∤": [t: "nie dzieli"] # 0x2224 + - "∤": [T: "nie dzieli"] # 0x2224 - "∧": [T: "i"] # 0x2227 - "∨": [T: "lub"] # 0x2228 - "∩": [T: "przecięcie"] # 0x2229 - "∪": [T: "suma zbiorów"] # 0x222a - "∫": [T: "całka"] # 0x222b - - "∬": [t: "całka podwójna"] # 0x222c - - "∭": [t: "całka potrójna"] # 0x222d - - "∮": [t: "całka krzywoliniowa"] # 0x222e - - "∯": [t: "całka powierzchniowa"] # 0x222f - - "∰": [t: "całka objętościowa"] # 0x2230 - - "∱": [t: "całka zgodnie z ruchem wskazówek zegara"] # 0x2231 - - "∲": [t: "całka krzywoliniowa zgodnie z ruchem wskazówek zegara"] # 0x2232 - - "∳": [t: "całka krzywoliniowa przeciwnie do ruchu wskazówek zegara"] # 0x2233 - - "∴": [t: "zatem"] # 0x2234 - - "∵": [t: "ponieważ"] # 0x2235 + - "∬": [T: "całka podwójna"] # 0x222c + - "∭": [T: "całka potrójna"] # 0x222d + - "∮": [T: "całka krzywoliniowa"] # 0x222e + - "∯": [T: "całka powierzchniowa"] # 0x222f + - "∰": [T: "całka objętościowa"] # 0x2230 + - "∱": [T: "całka zgodnie z ruchem wskazówek zegara"] # 0x2231 + - "∲": [T: "całka krzywoliniowa zgodnie z ruchem wskazówek zegara"] # 0x2232 + - "∳": [T: "całka krzywoliniowa przeciwnie do ruchu wskazówek zegara"] # 0x2233 + - "∴": [T: "zatem"] # 0x2234 + - "∵": [T: "ponieważ"] # 0x2235 - "∶": # 0x2236 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "do" - - "∷": [t: "jako"] # 0x2237 - - "∸": [t: "kropka minus"] # 0x2238 - - "∹": [t: "ma nadmiar względem"] # 0x2239 + - "∷": [T: "jako"] # 0x2237 + - "∸": [T: "kropka minus"] # 0x2238 + - "∹": [T: "ma nadmiar względem"] # 0x2239 - "∺": # 0x223a - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "geometrycznie proporcjonalne do" + - T: "geometrycznie proporcjonalne do" - "∻": # 0x223b - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "homotetyczne do" - - "∼": [t: "tylda"] # 0x223c - - "∽": [t: "odwrócona tylda"] # 0x223d + - T: "homotetyczne do" + - "∼": [T: "tylda"] # 0x223c + - "∽": [T: "odwrócona tylda"] # 0x223d - "∾": # 0x223e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "most dodatnie" - - "∿": [t: "fala sinusoidalna"] # 0x223f - - "≀": [t: "iloczyn wieńcowy"] # 0x2240 - - "≁": [t: "nie jest podobne"] # 0x2241 - - "≂": [t: "minus tylda"] # 0x2242 + - T: "most dodatnie" + - "∿": [T: "fala sinusoidalna"] # 0x223f + - "≀": [T: "iloczyn wieńcowy"] # 0x2240 + - "≁": [T: "nie jest podobne"] # 0x2241 + - "≂": [T: "minus tylda"] # 0x2242 - "≃": # 0x2243 - test: if: "$Verbosity!='Terse'" @@ -844,7 +844,7 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "przystające do" + - T: "przystające do" - "≆": # 0x2246 - test: if: "$Verbosity!='Terse'" @@ -854,7 +854,7 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie przystające do" + - T: "nie przystające do" - "≈": # 0x2248 - test: if: "$Verbosity!='Terse'" @@ -870,21 +870,21 @@ if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "w przybliżeniu równe lub równe" - - "≋": [t: "potrójny tylda"] # 0x224b + - "≋": [T: "potrójny tylda"] # 0x224b - "≌": [T: "wszystkie równe"] # 0x224c - "≍": # 0x224d - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "Równoważne" + - T: "Równoważne" - "≎": # 0x224e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "geometrycznie równoważne" - "≏": # 0x224f - - t: "różnica między" - - "≐": [t: "dąży do granicy"] # 0x2250 + - T: "różnica między" + - "≐": [T: "dąży do granicy"] # 0x2250 - "≑": # 0x2251 - test: if: "$Verbosity!='Terse'" @@ -898,32 +898,32 @@ - "≓": # 0x2253 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] + then: [T: "jest"] - T: "obrazem lub w przybliżeniu równe" - - "≔": [t: "dwukropek równa się"] # 0x2254 - - "≕": [t: "równa się dwukropek"] # 0x2255 - - "≖": [t: "pierścień w znaku równości"] # 0x2256 + - "≔": [T: "dwukropek równa się"] # 0x2254 + - "≕": [T: "równa się dwukropek"] # 0x2255 + - "≖": [T: "pierścień w znaku równości"] # 0x2256 - "≗": # 0x2257 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "w przybliżeniu równe" - - "≘": [t: "odpowiada"] # 0x2258 - - "≙": [t: "estymuje"] # 0x2259 + - "≘": [T: "odpowiada"] # 0x2258 + - "≙": [T: "estymuje"] # 0x2259 - "≚": # 0x225a - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równokątne do" - - "≛": [t: "gwiazda równa się"] # 0x225b - - "≜": [t: "delta równa się"] # 0x225c - - "≝": [t: "jest z definicji równe"] # 0x225d + - T: "równokątne do" + - "≛": [T: "gwiazda równa się"] # 0x225b + - "≜": [T: "delta równa się"] # 0x225c + - "≝": [T: "jest z definicji równe"] # 0x225d - "≞": # 0x225e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mierzone na" - - "≟": [t: "ma nieznaną relację z"] # 0x225f + - T: "mierzone na" + - "≟": [T: "ma nieznaną relację z"] # 0x225f - "≠": # 0x2260 - test: if: "$Verbosity!='Terse'" @@ -933,209 +933,209 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "identyczne z" + - T: "identyczne z" - "≢": # 0x2262 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie identyczne z" + - T: "nie identyczne z" - "≣": # 0x2263 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "ściśle równoważne" - - "≦": [t: "mniejsze nad równe"] # 0x2266 - - "≧": [t: "większe nad równe"] # 0x2267 + - T: "ściśle równoważne" + - "≦": [T: "mniejsze nad równe"] # 0x2266 + - "≧": [T: "większe nad równe"] # 0x2267 - "≨": # 0x2268 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze niż ale nie równa się" + - T: "mniejsze niż ale nie równa się" - "≩": # 0x2269 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe niż ale nie równa się" + - T: "większe niż ale nie równa się" - "≪": # 0x226a - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "znacznie mniejsze niż" + - T: "znacznie mniejsze niż" - "≫": # 0x226b - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "znacznie większe niż" + - T: "znacznie większe niż" - "≬": # 0x226c - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "między" + - T: "między" - "≭": # 0x226d - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie równoważne" + - T: "nie równoważne" - "≮": # 0x226e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie mniejsze niż" + - T: "nie mniejsze niż" - "≯": # 0x226f - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie większe niż" + - T: "nie większe niż" - "≰": # 0x2270 - - t: "nie jest mniejsze ani równe" + - T: "nie jest mniejsze ani równe" - "≱": # 0x2271 - - t: "nie jest większe ani równe" + - T: "nie jest większe ani równe" - "≲": # 0x2272 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze niż lub równoważne" + - T: "mniejsze niż lub równoważne" - "≳": # 0x2273 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe niż lub równoważne" + - T: "większe niż lub równoważne" - "≴": # 0x2274 - - t: "nie jest mniejsze ani równoważne" + - T: "nie jest mniejsze ani równoważne" - "≵": # 0x2275 - - t: "nie jest większe ani równoważne" + - T: "nie jest większe ani równoważne" - "≶": # 0x2276 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze lub większe niż" + - T: "mniejsze lub większe niż" - "≷": # 0x2277 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe lub mniejsze niż" + - T: "większe lub mniejsze niż" - "≸": # 0x2278 - - t: "nie jest mniejsze ani większe niż" + - T: "nie jest mniejsze ani większe niż" - "≹": # 0x2279 - - t: "nie jest większe ani mniejsze niż" - - "≺": [t: "poprzedza"] # 0x227a - - "≻": [t: "następuje po"] # 0x227b + - T: "nie jest większe ani mniejsze niż" + - "≺": [T: "poprzedza"] # 0x227a + - "≻": [T: "następuje po"] # 0x227b - "≼": [T: "poprzedza lub jest równe"] # 0x227c - "≽": [T: "następuje po lub jest równe"] # 0x227d - - "≾": [t: "poprzedza lub jest równoważne"] # 0x227e - - "≿": [t: "następuje po lub jest równoważne"] # 0x227f + - "≾": [T: "poprzedza lub jest równoważne"] # 0x227e + - "≿": [T: "następuje po lub jest równoważne"] # 0x227f - "⊀": [T: "nie poprzedza"] # 0x2280 - "⊁": [T: "nie następuje po"] # 0x2281 - "⊂": # 0x2282 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "podzbiór" + then: [T: "jest"] + - T: "podzbiór" - "⊃": # 0x2283 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "nadzbiór" + then: [T: "jest"] + - T: "nadzbiór" - "⊄": # 0x2284 - - t: "nie jest podzbiorem" + - T: "nie jest podzbiorem" - "⊅": # 0x2285 - - t: "nie jest nadzbiorem" + - T: "nie jest nadzbiorem" - "⊆": # 0x2286 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "podzbiór lub równy" + then: [T: "jest"] + - T: "podzbiór lub równy" - "⊇": # 0x2287 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "nadzbiór lub równy" + then: [T: "jest"] + - T: "nadzbiór lub równy" - "⊈": # 0x2288 - - t: "nie jest podzbiorem ani nie jest równe" + - T: "nie jest podzbiorem ani nie jest równe" - "⊉": # 0x2289 - - t: "nie jest nadzbiorem ani nie jest równe" - - "⊊": [t: "podzbiór z nie równa się"] # 0x228a - - "⊋": [t: "nadzbiór z nie równa się"] # 0x228b - - "⊌": [t: "wielozbiór"] # 0x228c - - "⊍": [t: "mnożenie wielozbiorów"] # 0x228d - - "⊎": [t: "suma wielozbiorów"] # 0x228e + - T: "nie jest nadzbiorem ani nie jest równe" + - "⊊": [T: "podzbiór z nie równa się"] # 0x228a + - "⊋": [T: "nadzbiór z nie równa się"] # 0x228b + - "⊌": [T: "wielozbiór"] # 0x228c + - "⊍": [T: "mnożenie wielozbiorów"] # 0x228d + - "⊎": [T: "suma wielozbiorów"] # 0x228e - "⊏": [T: "kwadratowo poprzedza"] # 0x228f - "⊐": [T: "kwadratowo następuje po"] # 0x2290 - "⊑": [T: "kwadratowo poprzedza lub jest równe"] # 0x2291 - "⊒": [T: "kwadratowo następuje po lub jest równe"] # 0x2292 - - "⊓": [t: "kwadratowa część wspólna"] # 0x2293 - - "⊔": [t: "kwadratowa suma zbiorów"] # 0x2294 - - "⊕": [t: "w kółku plus"] # 0x2295 - - "⊖": [t: "w kółku minus"] # 0x2296 - - "⊗": [t: "w kółku razy"] # 0x2297 - - "⊘": [t: "w kółku ukośnik"] # 0x2298 - - "⊙": [t: "kropka w kółku"] # 0x2299 - - "⊚": [t: "pierścień w kółku"] # 0x229a - - "⊛": [t: "gwiazdka w kółku"] # 0x229b - - "⊜": [t: "równa się w kółku"] # 0x229c - - "⊝": [t: "kreska w kółku"] # 0x229d - - "⊞": [t: "plus w kwadracie"] # 0x229e - - "⊟": [t: "minus w kwadracie"] # 0x229f - - "⊠": [t: "razy w kwadracie"] # 0x22a0 - - "⊡": [t: "kropka w kwadracie"] # 0x22a1 - - "⊢": [t: "dowodzi"] # 0x22a2 - - "⊣": [t: "jest dowodzone przez"] # 0x22a3 - - "⊤": [t: "góra"] # 0x22a4 - - "⊦": [t: "redukuje się do"] # 0x22a6 - - "⊧": [t: "modeluje"] # 0x22a7 + - "⊓": [T: "kwadratowa część wspólna"] # 0x2293 + - "⊔": [T: "kwadratowa suma zbiorów"] # 0x2294 + - "⊕": [T: "w kółku plus"] # 0x2295 + - "⊖": [T: "w kółku minus"] # 0x2296 + - "⊗": [T: "w kółku razy"] # 0x2297 + - "⊘": [T: "w kółku ukośnik"] # 0x2298 + - "⊙": [T: "kropka w kółku"] # 0x2299 + - "⊚": [T: "pierścień w kółku"] # 0x229a + - "⊛": [T: "gwiazdka w kółku"] # 0x229b + - "⊜": [T: "równa się w kółku"] # 0x229c + - "⊝": [T: "kreska w kółku"] # 0x229d + - "⊞": [T: "plus w kwadracie"] # 0x229e + - "⊟": [T: "minus w kwadracie"] # 0x229f + - "⊠": [T: "razy w kwadracie"] # 0x22a0 + - "⊡": [T: "kropka w kwadracie"] # 0x22a1 + - "⊢": [T: "dowodzi"] # 0x22a2 + - "⊣": [T: "jest dowodzone przez"] # 0x22a3 + - "⊤": [T: "góra"] # 0x22a4 + - "⊦": [T: "redukuje się do"] # 0x22a6 + - "⊧": [T: "modeluje"] # 0x22a7 - "⊨": # 0x22a8 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "prawdziwe" - - "⊩": [t: "wymusza"] # 0x22a9 - - "⊪": [t: "potrójna pionowa kreska z prawym znacznikiem dedukcji"] # 0x22aa - - "⊫": [t: "podwójna pionowa kreska z podwójnym prawym znacznikiem dedukcji"] # 0x22ab - - "⊬": [t: "nie dowodzi"] # 0x22ac + - T: "prawdziwe" + - "⊩": [T: "wymusza"] # 0x22a9 + - "⊪": [T: "potrójna pionowa kreska z prawym znacznikiem dedukcji"] # 0x22aa + - "⊫": [T: "podwójna pionowa kreska z podwójnym prawym znacznikiem dedukcji"] # 0x22ab + - "⊬": [T: "nie dowodzi"] # 0x22ac - "⊭": # 0x22ad - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie jest prawdziwe" - - "⊮": [t: "nie wymusza"] # 0x22ae - - "⊯": [t: "zanegowana podwójna pionowa kreska z podwójnym prawym znacznikiem dedukcji"] # 0x22af - - "⊰": [t: "poprzedza pod relacją"] # 0x22b0 - - "⊱": [t: "następuje po pod relacją"] # 0x22b1 + - T: "nie jest prawdziwe" + - "⊮": [T: "nie wymusza"] # 0x22ae + - "⊯": [T: "zanegowana podwójna pionowa kreska z podwójnym prawym znacznikiem dedukcji"] # 0x22af + - "⊰": [T: "poprzedza pod relacją"] # 0x22b0 + - "⊱": [T: "następuje po pod relacją"] # 0x22b1 - "⊲": # 0x22b2 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "normalną podgrupą" - - "⊳": [t: "zawiera jako normalną podgrupę"] # 0x22b3 + - T: "normalną podgrupą" + - "⊳": [T: "zawiera jako normalną podgrupę"] # 0x22b3 - "⊴": # 0x22b4 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "normalną podgrupą lub równe" - - "⊵": [t: "zawiera jako normalną podgrupę lub jest równe"] # 0x22b5 + - T: "normalną podgrupą lub równe" + - "⊵": [T: "zawiera jako normalną podgrupę lub jest równe"] # 0x22b5 - "⊶": # 0x22b6 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "oryginałem" + - T: "oryginałem" - "⊷": # 0x22b7 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "obrazem" - - "⊸": [t: "multimapa"] # 0x22b8 - - "⊹": [t: "macierz sprzężona hermitowsko"] # 0x22b9 - - "⊺": [t: "interkalacja"] # 0x22ba - - "⊻": [t: "alternatywa wykluczająca"] # 0x22bb - - "⊼": [t: "negacja koniunkcji"] # 0x22bc - - "⊽": [t: "negacja alternatywy"] # 0x22bd - - "⊾": [t: "kąt prosty z łukiem"] # 0x22be - - "⊿": [t: "prawy trójkąt"] # 0x22bf - - "⋀": [t: "logiczne I"] # 0x22c0 - - "⋁": [t: "logiczne lub"] # 0x22c1 + - T: "obrazem" + - "⊸": [T: "multimapa"] # 0x22b8 + - "⊹": [T: "macierz sprzężona hermitowsko"] # 0x22b9 + - "⊺": [T: "interkalacja"] # 0x22ba + - "⊻": [T: "alternatywa wykluczająca"] # 0x22bb + - "⊼": [T: "negacja koniunkcji"] # 0x22bc + - "⊽": [T: "negacja alternatywy"] # 0x22bd + - "⊾": [T: "kąt prosty z łukiem"] # 0x22be + - "⊿": [T: "prawy trójkąt"] # 0x22bf + - "⋀": [T: "logiczne I"] # 0x22c0 + - "⋁": [T: "logiczne lub"] # 0x22c1 - "⋂": [T: "przecięcie"] # 0x22c2 - "⋃": [T: "suma zbiorów"] # 0x22c3 - - "⋄": [t: "operator rombu"] # 0x22c4 + - "⋄": [T: "operator rombu"] # 0x22c4 - "⋅": # 0x22c5 - test: if: "@data-chem-formula-op" @@ -1143,520 +1143,520 @@ else: [T: "razy"] - "⋆": [T: "razy"] # 0x22c6 - - "⋇": [t: "znak dzielenia razy"] # 0x22c7 - - "⋈": [t: "muszka"] # 0x22c8 + - "⋇": [T: "znak dzielenia razy"] # 0x22c7 + - "⋈": [T: "muszka"] # 0x22c8 - "⋉": # 0x22c9 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "lewym iloczynem półprostym z czynnikiem normalnym" + - T: "lewym iloczynem półprostym z czynnikiem normalnym" - "⋊": # 0x22ca - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "prawym iloczynem półprostym z czynnikiem normalnym" + - T: "prawym iloczynem półprostym z czynnikiem normalnym" - "⋋": # 0x22cb - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "lewym iloczynem półprostym" + - T: "lewym iloczynem półprostym" - "⋌": # 0x22cc - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "prawym iloczynem półprostym" - - "⋍": [t: "odwrócona tylda równa się"] # 0x22cd - - "⋎": [t: "zakręcone logiczne lub"] # 0x22ce - - "⋏": [t: "zakręcone logiczne i"] # 0x22cf + - T: "prawym iloczynem półprostym" + - "⋍": [T: "odwrócona tylda równa się"] # 0x22cd + - "⋎": [T: "zakręcone logiczne lub"] # 0x22ce + - "⋏": [T: "zakręcone logiczne i"] # 0x22cf - "⋐": # 0x22d0 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "podwójnym podzbiorem" + - T: "podwójnym podzbiorem" - "⋑": # 0x22d1 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "podwójnym nadzbiorem" + - T: "podwójnym nadzbiorem" - "⋒": # 0x22d2 - - t: "podwójna część wspólna" + - T: "podwójna część wspólna" - "⋓": # 0x22d3 - - t: "podwójna suma zbiorów" + - T: "podwójna suma zbiorów" - "⋔": # 0x22d4 - - t: "właściwa część wspólna" + - T: "właściwa część wspólna" - "⋕": # 0x22d5 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe i równoległe do" - - "⋖": [t: "mniejsze niż z kropką"] # 0x22d6 - - "⋗": [t: "większe niż z kropką"] # 0x22d7 + - T: "równe i równoległe do" + - "⋖": [T: "mniejsze niż z kropką"] # 0x22d6 + - "⋗": [T: "większe niż z kropką"] # 0x22d7 - "⋘": # 0x22d8 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "bardzo znacznie mniejsze niż" + - T: "bardzo znacznie mniejsze niż" - "⋙": # 0x22d9 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "bardzo znacznie większe niż" + - T: "bardzo znacznie większe niż" - "⋚": # 0x22da - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze niż, równe lub większe niż" + - T: "mniejsze niż, równe lub większe niż" - "⋛": # 0x22db - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe niż, równe lub mniejsze niż" + - T: "większe niż, równe lub mniejsze niż" - "⋜": # 0x22dc - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe lub mniejsze niż" + - T: "równe lub mniejsze niż" - "⋝": # 0x22dd - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe lub większe niż" + - T: "równe lub większe niż" - "⋞": # 0x22de - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe lub poprzedza" + - T: "równe lub poprzedza" - "⋟": # 0x22df - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równe lub następuje po" - - "⋠": [t: "nie poprzedza ani nie jest równe"] # 0x22e0 - - "⋡": [t: "nie następuje po ani nie jest równe"] # 0x22e1 - - "⋢": [t: "nie poprzedza kwadratowo ani nie jest równe"] # 0x22e2 - - "⋣": [t: "nie następuje kwadratowo po ani nie jest równe"] # 0x22e3 - - "⋤": [t: "poprzedza kwadratowo, ale nie jest równe"] # 0x22e4 - - "⋥": [t: "następuje kwadratowo po, ale nie jest równe"] # 0x22e5 + - T: "równe lub następuje po" + - "⋠": [T: "nie poprzedza ani nie jest równe"] # 0x22e0 + - "⋡": [T: "nie następuje po ani nie jest równe"] # 0x22e1 + - "⋢": [T: "nie poprzedza kwadratowo ani nie jest równe"] # 0x22e2 + - "⋣": [T: "nie następuje kwadratowo po ani nie jest równe"] # 0x22e3 + - "⋤": [T: "poprzedza kwadratowo, ale nie jest równe"] # 0x22e4 + - "⋥": [T: "następuje kwadratowo po, ale nie jest równe"] # 0x22e5 - "⋦": # 0x22e6 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "mniejsze niż, ale nie równoważne" + - T: "mniejsze niż, ale nie równoważne" - "⋧": # 0x22e7 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "większe niż, ale nie równoważne" - - "⋨": [t: "poprzedza, ale nie jest równoważne"] # 0x22e8 - - "⋩": [t: "następuje po, ale nie jest równoważne"] # 0x22e9 + - T: "większe niż, ale nie równoważne" + - "⋨": [T: "poprzedza, ale nie jest równoważne"] # 0x22e8 + - "⋩": [T: "następuje po, ale nie jest równoważne"] # 0x22e9 - "⋪": # 0x22ea - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie jest normalną podgrupą" - - "⋫": [t: "nie zawiera jako normalnej podgrupy"] # 0x22eb + - T: "nie jest normalną podgrupą" + - "⋫": [T: "nie zawiera jako normalnej podgrupy"] # 0x22eb - "⋬": # 0x22ec - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nie jest normalną podgrupą ani równe" - - "⋭": [t: "nie zawiera jako normalnej podgrupy ani równe"] # 0x22ed - - "⋮": [t: "pionowy wielokropek"] # 0x22ee - - "⋯": [t: "trzy kropki"] # 0x22ef - - "⋰": [t: "ukośny wielokropek w górę"] # 0x22f0 - - "⋱": [t: "ukośny wielokropek w dół"] # 0x22f1 - - "⋲": [t: "należy do z długą poziomą kreską"] # 0x22f2 - - "⋳": [t: "należy do z pionową kreską na końcu i poziomą kreską"] # 0x22f3 - - "⋴": [t: "należy do z pionową kreską na końcu i poziomą kreską"] # 0x22f4 - - "⋵": [t: "należy do z kropką nad"] # 0x22f5 - - "⋶": [t: "należy do z kreską nad"] # 0x22f6 - - "⋷": [t: "należy do z kreską nad"] # 0x22f7 - - "⋸": [t: "należy do z podkreśleniem"] # 0x22f8 - - "⋹": [t: "należy do z dwiema poziomymi kreskami"] # 0x22f9 - - "⋺": [t: "zawiera z długą poziomą kreską"] # 0x22fa - - "⋻": [t: "zawiera z pionową kreską na końcu i poziomą kreską"] # 0x22fb - - "⋼": [t: "zawiera z pionową kreską na końcu i poziomą kreską"] # 0x22fc - - "⋽": [t: "zawiera z kreską nad"] # 0x22fd - - "⋾": [t: "zawiera z kreską nad"] # 0x22fe - - "⋿": [t: "przynależność do wielozbioru w notacji Z"] # 0x22ff - - "⌀": [t: "znak średnicy"] # 0x2300 - - "⌁": [t: "strzałka elektryczna"] # 0x2301 - - "⌂": [t: "dom"] # 0x2302 - - "⌃": [t: "górny grot strzałki"] # 0x2303 - - "⌄": [t: "dolny grot strzałki"] # 0x2304 - - "⌅": [t: "rzutowy"] # 0x2305 - - "⌆": [t: "perspektywiczny"] # 0x2306 - - "⌇": [t: "linia falista"] # 0x2307 - - "⌈": [t: "lewy sufit"] # 0x2308 - - "⌉": [t: "prawy sufit"] # 0x2309 - - "⌊": [t: "lewa podłoga"] # 0x230a - - "⌋": [t: "prawa podłoga"] # 0x230b - - "⌌": [t: "dolny prawy znacznik kadrowania"] # 0x230c - - "⌍": [t: "dolny lewy znacznik kadrowania"] # 0x230d - - "⌎": [t: "górny prawy znacznik kadrowania"] # 0x230e - - "⌏": [t: "górny lewy znacznik kadrowania"] # 0x230f - - "⌐": [t: "odwrócony nie znak"] # 0x2310 - - "⌑": [t: "kwadrat romb"] # 0x2311 + - T: "nie jest normalną podgrupą ani równe" + - "⋭": [T: "nie zawiera jako normalnej podgrupy ani równe"] # 0x22ed + - "⋮": [T: "pionowy wielokropek"] # 0x22ee + - "⋯": [T: "trzy kropki"] # 0x22ef + - "⋰": [T: "ukośny wielokropek w górę"] # 0x22f0 + - "⋱": [T: "ukośny wielokropek w dół"] # 0x22f1 + - "⋲": [T: "należy do z długą poziomą kreską"] # 0x22f2 + - "⋳": [T: "należy do z pionową kreską na końcu i poziomą kreską"] # 0x22f3 + - "⋴": [T: "należy do z pionową kreską na końcu i poziomą kreską"] # 0x22f4 + - "⋵": [T: "należy do z kropką nad"] # 0x22f5 + - "⋶": [T: "należy do z kreską nad"] # 0x22f6 + - "⋷": [T: "należy do z kreską nad"] # 0x22f7 + - "⋸": [T: "należy do z podkreśleniem"] # 0x22f8 + - "⋹": [T: "należy do z dwiema poziomymi kreskami"] # 0x22f9 + - "⋺": [T: "zawiera z długą poziomą kreską"] # 0x22fa + - "⋻": [T: "zawiera z pionową kreską na końcu i poziomą kreską"] # 0x22fb + - "⋼": [T: "zawiera z pionową kreską na końcu i poziomą kreską"] # 0x22fc + - "⋽": [T: "zawiera z kreską nad"] # 0x22fd + - "⋾": [T: "zawiera z kreską nad"] # 0x22fe + - "⋿": [T: "przynależność do wielozbioru w notacji Z"] # 0x22ff + - "⌀": [T: "znak średnicy"] # 0x2300 + - "⌁": [T: "strzałka elektryczna"] # 0x2301 + - "⌂": [T: "dom"] # 0x2302 + - "⌃": [T: "górny grot strzałki"] # 0x2303 + - "⌄": [T: "dolny grot strzałki"] # 0x2304 + - "⌅": [T: "rzutowy"] # 0x2305 + - "⌆": [T: "perspektywiczny"] # 0x2306 + - "⌇": [T: "linia falista"] # 0x2307 + - "⌈": [T: "lewy sufit"] # 0x2308 + - "⌉": [T: "prawy sufit"] # 0x2309 + - "⌊": [T: "lewa podłoga"] # 0x230a + - "⌋": [T: "prawa podłoga"] # 0x230b + - "⌌": [T: "dolny prawy znacznik kadrowania"] # 0x230c + - "⌍": [T: "dolny lewy znacznik kadrowania"] # 0x230d + - "⌎": [T: "górny prawy znacznik kadrowania"] # 0x230e + - "⌏": [T: "górny lewy znacznik kadrowania"] # 0x230f + - "⌐": [T: "odwrócony nie znak"] # 0x2310 + - "⌑": [T: "kwadrat romb"] # 0x2311 - "⌒": [T: "łuk"] # 0x2312 - - "⌓": [t: "odcinek"] # 0x2313 - - "⌔": [t: "sektor"] # 0x2314 - - "⌕": [t: "rejestrator telefoniczny"] # 0x2315 - - "⌖": [t: "celownik wskaźnika pozycji"] # 0x2316 - - "⌗": [t: "kwadrat danych ekranowych"] # 0x2317 - - "⌘": [t: "znak miejsca zainteresowania"] # 0x2318 - - "⌙": [t: "odwrócony nie znak"] # 0x2319 - - "⌚": [t: "zegarek"] # 0x231a - - "⌛": [t: "klepsydra"] # 0x231b - - "⌜": [t: "górny lewy narożnik"] # 0x231c - - "⌝": [t: "górny prawy narożnik"] # 0x231d - - "⌞": [t: "dolny lewy narożnik"] # 0x231e - - "⌟": [t: "dolny prawy narożnik"] # 0x231f - - "⌠": [t: "górna połowa całki"] # 0x2320 - - "⌡": [t: "dolna połowa całki"] # 0x2321 - - "⌢": [t: "łuk w dół"] # 0x2322 - - "⌣": [t: "łuk w górę"] # 0x2323 - - "⌤": [t: "górny grot strzałki między dwiema poziomymi kreskami"] # 0x2324 - - "⌥": [t: "klawisz opcji"] # 0x2325 - - "⌦": [t: "wymaż w prawo"] # 0x2326 - - "⌧": [t: "X w prostokątnej ramce"] # 0x2327 - - "⌨": [t: "klawiatura"] # 0x2328 - - "〈": [t: "kąt skierowany w lewo nawias kwadratowy"] # 0x2329 - - "〉": [t: "kąt skierowany w prawo nawias kwadratowy"] # 0x232a - - "⌫": [t: "wymaż w lewo"] # 0x232b - - "⌬": [t: "pierścień benzenowy"] # 0x232c - - "⌭": [t: "walcowość"] # 0x232d - - "⌮": [t: "profil dookoła"] # 0x232e - - "⌯": [t: "symetria"] # 0x232f - - "⌰": [t: "bicie całkowite"] # 0x2330 - - "⌱": [t: "początek wymiarowania"] # 0x2331 - - "⌲": [t: "stożkowatość"] # 0x2332 - - "⌳": [t: "nachylenie"] # 0x2333 - - "⌴": [t: "pogłębienie walcowe"] # 0x2334 - - "⌵": [t: "pogłębienie stożkowe"] # 0x2335 - - "⌶": [t: "belka i APL"] # 0x2336 - - "⌽": [t: "okrąg z kreską pionową APL"] # 0x233d - - "⌿": [t: "apl ukośnik kreska"] # 0x233f - - "⍰": [t: "nieznana ramka"] # 0x2370 - - "⍼": [t: "kąt prosty z dolną strzałką zygzakowatą"] # 0x237c - - "⎔": [t: "sześciokąt"] # 0x2394 - - "⎕": [t: "ramka"] # 0x2395 - - "⎶": [t: "dolny nawias kwadratowy nad górnym nawiasem kwadratowym"] # 0x23b6 - - "⏜": [t: "górny nawias"] # 0x23dc - - "⏝": [t: "dolny nawias"] # 0x23dd - - "⏞": [t: "górny nawias klamrowy"] # 0x23de - - "⏟": [t: "dolny nawias klamrowy"] # 0x23df - - "⏠": [t: "górny nawias skorupowy"] # 0x23e0 - - "⏡": [t: "dolny nawias skorupowy"] # 0x23e1 - - "⏢": [t: "biały trapez"] # 0x23e2 - - "⏣": [t: "benzenowy pierścień z okręgiem po prawej"] # 0x23e3 - - "⏤": [t: "prostoliniowość"] # 0x23e4 - - "⏥": [t: "płaskość"] # 0x23e5 - - "⏦": [t: "prąd przemienny"] # 0x23e6 - - "⏧": [t: "symbol elektrycznego przecięcia"] # 0x23e7 + - "⌓": [T: "odcinek"] # 0x2313 + - "⌔": [T: "sektor"] # 0x2314 + - "⌕": [T: "rejestrator telefoniczny"] # 0x2315 + - "⌖": [T: "celownik wskaźnika pozycji"] # 0x2316 + - "⌗": [T: "kwadrat danych ekranowych"] # 0x2317 + - "⌘": [T: "znak miejsca zainteresowania"] # 0x2318 + - "⌙": [T: "odwrócony nie znak"] # 0x2319 + - "⌚": [T: "zegarek"] # 0x231a + - "⌛": [T: "klepsydra"] # 0x231b + - "⌜": [T: "górny lewy narożnik"] # 0x231c + - "⌝": [T: "górny prawy narożnik"] # 0x231d + - "⌞": [T: "dolny lewy narożnik"] # 0x231e + - "⌟": [T: "dolny prawy narożnik"] # 0x231f + - "⌠": [T: "górna połowa całki"] # 0x2320 + - "⌡": [T: "dolna połowa całki"] # 0x2321 + - "⌢": [T: "łuk w dół"] # 0x2322 + - "⌣": [T: "łuk w górę"] # 0x2323 + - "⌤": [T: "górny grot strzałki między dwiema poziomymi kreskami"] # 0x2324 + - "⌥": [T: "klawisz opcji"] # 0x2325 + - "⌦": [T: "wymaż w prawo"] # 0x2326 + - "⌧": [T: "X w prostokątnej ramce"] # 0x2327 + - "⌨": [T: "klawiatura"] # 0x2328 + - "〈": [T: "kąt skierowany w lewo nawias kwadratowy"] # 0x2329 + - "〉": [T: "kąt skierowany w prawo nawias kwadratowy"] # 0x232a + - "⌫": [T: "wymaż w lewo"] # 0x232b + - "⌬": [T: "pierścień benzenowy"] # 0x232c + - "⌭": [T: "walcowość"] # 0x232d + - "⌮": [T: "profil dookoła"] # 0x232e + - "⌯": [T: "symetria"] # 0x232f + - "⌰": [T: "bicie całkowite"] # 0x2330 + - "⌱": [T: "początek wymiarowania"] # 0x2331 + - "⌲": [T: "stożkowatość"] # 0x2332 + - "⌳": [T: "nachylenie"] # 0x2333 + - "⌴": [T: "pogłębienie walcowe"] # 0x2334 + - "⌵": [T: "pogłębienie stożkowe"] # 0x2335 + - "⌶": [T: "belka i APL"] # 0x2336 + - "⌽": [T: "okrąg z kreską pionową APL"] # 0x233d + - "⌿": [T: "apl ukośnik kreska"] # 0x233f + - "⍰": [T: "nieznana ramka"] # 0x2370 + - "⍼": [T: "kąt prosty z dolną strzałką zygzakowatą"] # 0x237c + - "⎔": [T: "sześciokąt"] # 0x2394 + - "⎕": [T: "ramka"] # 0x2395 + - "⎶": [T: "dolny nawias kwadratowy nad górnym nawiasem kwadratowym"] # 0x23b6 + - "⏜": [T: "górny nawias"] # 0x23dc + - "⏝": [T: "dolny nawias"] # 0x23dd + - "⏞": [T: "górny nawias klamrowy"] # 0x23de + - "⏟": [T: "dolny nawias klamrowy"] # 0x23df + - "⏠": [T: "górny nawias skorupowy"] # 0x23e0 + - "⏡": [T: "dolny nawias skorupowy"] # 0x23e1 + - "⏢": [T: "biały trapez"] # 0x23e2 + - "⏣": [T: "benzenowy pierścień z okręgiem po prawej"] # 0x23e3 + - "⏤": [T: "prostoliniowość"] # 0x23e4 + - "⏥": [T: "płaskość"] # 0x23e5 + - "⏦": [T: "prąd przemienny"] # 0x23e6 + - "⏧": [T: "symbol elektrycznego przecięcia"] # 0x23e7 - "①-⑨": # 0x2460 - 0x2469 - - t: "w kółku" + - T: "w kółku" - spell: "translate('.', '①②③④⑤⑥⑦⑧⑨', '123456789')" - - "⑩": [t: "w kółku dziesięć"] # 0x2469 - - "⑪": [t: "w kółku jedenaście"] # 0x246a - - "⑫": [t: "w kółku dwanaście"] # 0x246b - - "⑬": [t: "w kółku trzynaście"] # 0x246c - - "⑭": [t: "w kółku czternaście"] # 0x246d - - "⑮": [t: "w kółku piętnaście"] # 0x246e - - "⑯": [t: "w kółku szesnaście"] # 0x246f - - "⑰": [t: "w kółku siedemnaście"] # 0x2470 - - "⑱": [t: "w kółku osiemnaście"] # 0x2471 - - "⑳": [t: "w kółku dwadzieścia"] # 0x2473 + - "⑩": [T: "w kółku dziesięć"] # 0x2469 + - "⑪": [T: "w kółku jedenaście"] # 0x246a + - "⑫": [T: "w kółku dwanaście"] # 0x246b + - "⑬": [T: "w kółku trzynaście"] # 0x246c + - "⑭": [T: "w kółku czternaście"] # 0x246d + - "⑮": [T: "w kółku piętnaście"] # 0x246e + - "⑯": [T: "w kółku szesnaście"] # 0x246f + - "⑰": [T: "w kółku siedemnaście"] # 0x2470 + - "⑱": [T: "w kółku osiemnaście"] # 0x2471 + - "⑳": [T: "w kółku dwadzieścia"] # 0x2473 - "⑴-⑼": # 0x2474 - 0x247d - - t: "w nawiasie" + - T: "w nawiasie" - spell: "translate('.', '⑴⑵⑶⑷⑸⑹⑺⑻⑼', '123456789')" - - "⑽": [t: "w nawiasie dziesięć"] # 0x247d - - "⑾": [t: "w nawiasie jedenaście"] # 0x247e - - "⑿": [t: "w nawiasie dwanaście"] # 0x247f - - "⒀": [t: "w nawiasie trzynaście"] # 0x2480 - - "⒁": [t: "w nawiasie czternaście"] # 0x2481 - - "⒂": [t: "w nawiasie piętnaście"] # 0x2482 - - "⒃": [t: "w nawiasie szesnaście"] # 0x2483 - - "⒄": [t: "w nawiasie siedemnaście"] # 0x2484 - - "⒅": [t: "w nawiasie osiemnaście"] # 0x2485 - - "⒆": [t: "w nawiasie dziewiętnaście"] # 0x2486 - - "⒇": [t: "w nawiasie dwadzieścia"] # 0x2487 + - "⑽": [T: "w nawiasie dziesięć"] # 0x247d + - "⑾": [T: "w nawiasie jedenaście"] # 0x247e + - "⑿": [T: "w nawiasie dwanaście"] # 0x247f + - "⒀": [T: "w nawiasie trzynaście"] # 0x2480 + - "⒁": [T: "w nawiasie czternaście"] # 0x2481 + - "⒂": [T: "w nawiasie piętnaście"] # 0x2482 + - "⒃": [T: "w nawiasie szesnaście"] # 0x2483 + - "⒄": [T: "w nawiasie siedemnaście"] # 0x2484 + - "⒅": [T: "w nawiasie osiemnaście"] # 0x2485 + - "⒆": [T: "w nawiasie dziewiętnaście"] # 0x2486 + - "⒇": [T: "w nawiasie dwadzieścia"] # 0x2487 - "⒈-⒐": # 0x2488 - 0x2491 - spell: "translate('.', '⒈⒉⒊⒋⒌⒍⒎⒏⒐', '123456789')" - - t: "z kropką" - - "⒑": [t: "dziesięć z kropką"] # 0x2491 - - "⒒": [t: "jedenaście z kropką"] # 0x2492 - - "⒓": [t: "dwanaście z kropką"] # 0x2493 - - "⒔": [t: "trzynaście z kropką"] # 0x2494 - - "⒕": [t: "czternaście z kropką"] # 0x2495 - - "⒖": [t: "piętnaście z kropką"] # 0x2496 - - "⒗": [t: "szesnaście z kropką"] # 0x2497 - - "⒘": [t: "siedemnaście z kropką"] # 0x2498 - - "⒙": [t: "osiemnaście z kropką"] # 0x2499 - - "⒚": [t: "dziewiętnaście z kropką"] # 0x249a - - "⒛": [t: "dwadzieścia z kropką"] # 0x249b + - T: "z kropką" + - "⒑": [T: "dziesięć z kropką"] # 0x2491 + - "⒒": [T: "jedenaście z kropką"] # 0x2492 + - "⒓": [T: "dwanaście z kropką"] # 0x2493 + - "⒔": [T: "trzynaście z kropką"] # 0x2494 + - "⒕": [T: "czternaście z kropką"] # 0x2495 + - "⒖": [T: "piętnaście z kropką"] # 0x2496 + - "⒗": [T: "szesnaście z kropką"] # 0x2497 + - "⒘": [T: "siedemnaście z kropką"] # 0x2498 + - "⒙": [T: "osiemnaście z kropką"] # 0x2499 + - "⒚": [T: "dziewiętnaście z kropką"] # 0x249a + - "⒛": [T: "dwadzieścia z kropką"] # 0x249b - "⒜-⒵": # 0x249c - 0x24b5 - - t: "w nawiasie" + - T: "w nawiasie" - spell: "translate('.', '⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵', 'abcdefghijklmnopqrstuvwxyz')" - "Ⓐ-ⓩ": # 0x24b6 - 0x24cf - - t: "w kółku" + - T: "w kółku" - spell: "translate('.', 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "🅐-🅩": # 0x1f150 - 0x1f169 - - t: "czarny w kółku" + - T: "czarny w kółku" - spell: "translate('.', '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "ⓐ-ⓩ": # 0x24d0 - 0x24e9 - - t: "w kółku" + - T: "w kółku" - spell: "translate('.', 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz')" - - "⓪": [t: "w kółku zero"] # 0x24ea - - "⓫": [t: "czarny w kółku jedenaście"] # 0x24eb - - "⓬": [t: "czarny w kółku dwanaście"] # 0x24ec - - "⓭": [t: "czarny w kółku trzynaście"] # 0x24ed - - "⓮": [t: "czarny w kółku czternaście"] # 0x24ee - - "⓯": [t: "czarny w kółku piętnaście"] # 0x24ef - - "⓰": [t: "czarny w kółku szesnaście"] # 0x24f0 - - "⓱": [t: "czarny w kółku siedemnaście"] # 0x24f1 - - "⓲": [t: "czarny w kółku osiemnaście"] # 0x24f2 - - "⓳": [t: "czarny w kółku dziewiętnaście"] # 0x24f3 - - "⓴": [t: "czarny w kółku dwadzieścia"] # 0x24f4 + - "⓪": [T: "w kółku zero"] # 0x24ea + - "⓫": [T: "czarny w kółku jedenaście"] # 0x24eb + - "⓬": [T: "czarny w kółku dwanaście"] # 0x24ec + - "⓭": [T: "czarny w kółku trzynaście"] # 0x24ed + - "⓮": [T: "czarny w kółku czternaście"] # 0x24ee + - "⓯": [T: "czarny w kółku piętnaście"] # 0x24ef + - "⓰": [T: "czarny w kółku szesnaście"] # 0x24f0 + - "⓱": [T: "czarny w kółku siedemnaście"] # 0x24f1 + - "⓲": [T: "czarny w kółku osiemnaście"] # 0x24f2 + - "⓳": [T: "czarny w kółku dziewiętnaście"] # 0x24f3 + - "⓴": [T: "czarny w kółku dwadzieścia"] # 0x24f4 - "⓵-⓽": # 0x24f5 - 0x24fe - - t: "podwójny w kółku" + - T: "podwójny w kółku" - spell: "translate('.', '⓵⓶⓷⓸⓹⓺⓻⓼⓽', '123456789')" - - "⓾": [t: "podwójny w kółku dziesięć"] # 0x24fe - - "⓿": [t: "czarny w kółku zero"] # 0x24ff - - "■": [t: "czarny kwadrat"] # 0x25a0 - - "□": [t: "biały kwadrat"] # 0x25a1 - - "▢": [t: "biały kwadrat z zaokrąglonymi narożnikami"] # 0x25a2 - - "▣": [t: "biały kwadrat zawierający mały czarny kwadrat"] # 0x25a3 - - "▤": [t: "kwadrat z poziomym wypełnieniem"] # 0x25a4 - - "▥": [t: "kwadrat z pionowym wypełnieniem"] # 0x25a5 - - "▦": [t: "kwadrat z ortogonalnym kreskowanym wypełnieniem"] # 0x25a6 - - "▧": [t: "kwadrat z wypełnieniem od góry po lewej do dołu po prawej"] # 0x25a7 - - "▨": [t: "kwadrat z wypełnieniem od góry po prawej do dołu po lewej"] # 0x25a8 - - "▩": [t: "kwadrat z ukośnym kreskowanym wypełnieniem"] # 0x25a9 - - "▪": [t: "czarny mały kwadrat"] # 0x25aa - - "▫": [t: "biały mały kwadrat"] # 0x25ab - - "▬": [t: "czarny prostokąt"] # 0x25ac - - "▭": [t: "biały prostokąt"] # 0x25ad - - "▮": [t: "czarny pionowy prostokąt"] # 0x25ae - - "▯": [t: "biały pionowy prostokąt"] # 0x25af - - "▰": [t: "czarny Równoległobok"] # 0x25b0 - - "▱": [t: "biały Równoległobok"] # 0x25b1 - - "▲": [t: "czarny trójkąt skierowany w górę"] # 0x25b2 - - "△": [t: "trójkąt"] # 0x25b3 - - "▴": [t: "czarny mały trójkąt skierowany w górę"] # 0x25b4 - - "▵": [t: "biały mały trójkąt skierowany w górę"] # 0x25b5 - - "▶": [t: "czarny trójkąt skierowany w prawo"] # 0x25b6 - - "▷": [t: "biały trójkąt skierowany w prawo"] # 0x25b7 - - "▸": [t: "czarny mały trójkąt skierowany w prawo"] # 0x25b8 - - "▹": [t: "biały mały trójkąt skierowany w prawo"] # 0x25b9 - - "►": [t: "czarny wskaźnik skierowany w prawo"] # 0x25ba - - "▻": [t: "biały wskaźnik skierowany w prawo"] # 0x25bb - - "▼": [t: "czarny trójkąt skierowany w dół"] # 0x25bc - - "▽": [t: "biały trójkąt skierowany w dół"] # 0x25bd - - "▾": [t: "czarny mały trójkąt skierowany w dół"] # 0x25be - - "▿": [t: "biały mały trójkąt skierowany w dół"] # 0x25bf - - "◀": [t: "czarny trójkąt skierowany w lewo"] # 0x25c0 - - "◁": [t: "biały trójkąt skierowany w lewo"] # 0x25c1 - - "◂": [t: "czarny mały trójkąt skierowany w lewo"] # 0x25c2 - - "◃": [t: "biały mały trójkąt skierowany w lewo"] # 0x25c3 - - "◄": [t: "czarny wskaźnik skierowany w lewo"] # 0x25c4 - - "◅": [t: "biały wskaźnik skierowany w lewo"] # 0x25c5 - - "◆": [t: "czarny romb"] # 0x25c6 - - "◇": [t: "biały romb"] # 0x25c7 - - "◈": [t: "biały romb zawierający czarny mały romb"] # 0x25c8 - - "◉": [t: "rybie oko"] # 0x25c9 - - "◊": [t: "romb"] # 0x25ca - - "○": [t: "białe koło"] # 0x25cb - - "◌": [t: "kropkowany okrąg"] # 0x25cc - - "◍": [t: "okrąg z pionowe wypełnienie"] # 0x25cd - - "◎": [t: "tarcza"] # 0x25ce - - "●": [t: "czarne koło"] # 0x25cf - - "◐": [t: "okrąg z czarną lewą połową"] # 0x25d0 - - "◑": [t: "okrąg z czarną prawą połową"] # 0x25d1 - - "◒": [t: "okrąg z czarną dolną połową"] # 0x25d2 - - "◓": [t: "okrąg z czarną górną połową"] # 0x25d3 - - "◔": [t: "okrąg z czarną górną prawą ćwiartką"] # 0x25d4 - - "◕": [t: "okrąg czarny poza górną lewą ćwiartką"] # 0x25d5 - - "◖": [t: "czarne koło z lewą połową"] # 0x25d6 - - "◗": [t: "czarne koło z prawą połową"] # 0x25d7 - - "◘": [t: "odwrotność punkt"] # 0x25d8 - - "◙": [t: "odwrotność białe koło"] # 0x25d9 - - "◚": [t: "górna połowa odwrotność białe koło"] # 0x25da - - "◛": [t: "dolna połowa odwrotność białe koło"] # 0x25db - - "◜": [t: "górny lewy ćwiartka łuk kołowy"] # 0x25dc - - "◝": [t: "górny prawy ćwiartka łuk kołowy"] # 0x25dd - - "◞": [t: "dolny prawy ćwiartka łuk kołowy"] # 0x25de - - "◟": [t: "dolny lewy ćwiartka łuk kołowy"] # 0x25df - - "◠": [t: "górna połowa okrąg"] # 0x25e0 - - "◡": [t: "dolna połowa okrąg"] # 0x25e1 - - "◢": [t: "czarny dolny prawy trójkąt"] # 0x25e2 - - "◣": [t: "czarny dolny lewy trójkąt"] # 0x25e3 - - "◤": [t: "czarny górny lewy trójkąt"] # 0x25e4 - - "◥": [t: "czarny górny prawy trójkąt"] # 0x25e5 - - "◦": [t: "złożenie"] # 0x25e6 - - "◧": [t: "kwadrat z czarną lewą połową"] # 0x25e7 - - "◨": [t: "kwadrat z czarną prawą połową"] # 0x25e8 - - "◩": [t: "kwadrat z czarną górną lewą połową"] # 0x25e9 - - "◪": [t: "kwadrat z czarną dolną prawą połową"] # 0x25ea - - "◫": [t: "biały kwadrat z linią dzielącą na pół"] # 0x25eb - - "◬": [t: "biały trójkąt skierowany w górę z kropką"] # 0x25ec - - "◭": [t: "trójkąt skierowany w górę z czarną lewą połową"] # 0x25ed - - "◮": [t: "trójkąt skierowany w górę z czarną prawą połową"] # 0x25ee - - "◯": [t: "duży okrąg"] # 0x25ef - - "◰": [t: "biały kwadrat z górną lewą ćwiartką"] # 0x25f0 - - "◱": [t: "biały kwadrat z dolną lewą ćwiartką"] # 0x25f1 - - "◲": [t: "biały kwadrat z dolną prawą ćwiartką"] # 0x25f2 - - "◳": [t: "biały kwadrat z górną prawą ćwiartką"] # 0x25f3 - - "◴": [t: "białe koło z górną lewą ćwiartką"] # 0x25f4 - - "◵": [t: "białe koło z dolną lewą ćwiartką"] # 0x25f5 - - "◶": [t: "białe koło z dolną prawą ćwiartką"] # 0x25f6 - - "◷": [t: "białe koło z górną prawą ćwiartką"] # 0x25f7 - - "◸": [t: "górny lewy trójkąt"] # 0x25f8 - - "◹": [t: "górny prawy trójkąt"] # 0x25f9 - - "◺": [t: "dolny lewy trójkąt"] # 0x25fa - - "◻": [t: "biały średni kwadrat"] # 0x25fb - - "◼": [t: "czarny średni kwadrat"] # 0x25fc - - "◽": [t: "biały średni mały kwadrat"] # 0x25fd - - "◾": [t: "czarny średni mały kwadrat"] # 0x25fe - - "◿": [t: "dolny prawy trójkąt"] # 0x25ff - - "★": [t: "czarna gwiazda"] # 0x2605 - - "☆": [t: "biały gwiazda"] # 0x2606 - - "☉": [t: "słońce"] # 0x2609 - - "☌": [t: "koniunkcja"] # 0x260c - - "☒": [t: "ramka wyboru z iksem"] # 0x2612 - - "☽": [t: "przybywający księżyc"] # 0x263d - - "☾": [t: "ubywający księżyc"] # 0x263e - - "☿": [t: "Merkury"] # 0x263f - - "♀": [t: "żeńskie"] # 0x2640 - - "♁": [t: "Ziemia"] # 0x2641 - - "♂": [t: "męskie"] # 0x2642 - - "♃": [t: "Jowisz"] # 0x2643 + - "⓾": [T: "podwójny w kółku dziesięć"] # 0x24fe + - "⓿": [T: "czarny w kółku zero"] # 0x24ff + - "■": [T: "czarny kwadrat"] # 0x25a0 + - "□": [T: "biały kwadrat"] # 0x25a1 + - "▢": [T: "biały kwadrat z zaokrąglonymi narożnikami"] # 0x25a2 + - "▣": [T: "biały kwadrat zawierający mały czarny kwadrat"] # 0x25a3 + - "▤": [T: "kwadrat z poziomym wypełnieniem"] # 0x25a4 + - "▥": [T: "kwadrat z pionowym wypełnieniem"] # 0x25a5 + - "▦": [T: "kwadrat z ortogonalnym kreskowanym wypełnieniem"] # 0x25a6 + - "▧": [T: "kwadrat z wypełnieniem od góry po lewej do dołu po prawej"] # 0x25a7 + - "▨": [T: "kwadrat z wypełnieniem od góry po prawej do dołu po lewej"] # 0x25a8 + - "▩": [T: "kwadrat z ukośnym kreskowanym wypełnieniem"] # 0x25a9 + - "▪": [T: "czarny mały kwadrat"] # 0x25aa + - "▫": [T: "biały mały kwadrat"] # 0x25ab + - "▬": [T: "czarny prostokąt"] # 0x25ac + - "▭": [T: "biały prostokąt"] # 0x25ad + - "▮": [T: "czarny pionowy prostokąt"] # 0x25ae + - "▯": [T: "biały pionowy prostokąt"] # 0x25af + - "▰": [T: "czarny Równoległobok"] # 0x25b0 + - "▱": [T: "biały Równoległobok"] # 0x25b1 + - "▲": [T: "czarny trójkąt skierowany w górę"] # 0x25b2 + - "△": [T: "trójkąt"] # 0x25b3 + - "▴": [T: "czarny mały trójkąt skierowany w górę"] # 0x25b4 + - "▵": [T: "biały mały trójkąt skierowany w górę"] # 0x25b5 + - "▶": [T: "czarny trójkąt skierowany w prawo"] # 0x25b6 + - "▷": [T: "biały trójkąt skierowany w prawo"] # 0x25b7 + - "▸": [T: "czarny mały trójkąt skierowany w prawo"] # 0x25b8 + - "▹": [T: "biały mały trójkąt skierowany w prawo"] # 0x25b9 + - "►": [T: "czarny wskaźnik skierowany w prawo"] # 0x25ba + - "▻": [T: "biały wskaźnik skierowany w prawo"] # 0x25bb + - "▼": [T: "czarny trójkąt skierowany w dół"] # 0x25bc + - "▽": [T: "biały trójkąt skierowany w dół"] # 0x25bd + - "▾": [T: "czarny mały trójkąt skierowany w dół"] # 0x25be + - "▿": [T: "biały mały trójkąt skierowany w dół"] # 0x25bf + - "◀": [T: "czarny trójkąt skierowany w lewo"] # 0x25c0 + - "◁": [T: "biały trójkąt skierowany w lewo"] # 0x25c1 + - "◂": [T: "czarny mały trójkąt skierowany w lewo"] # 0x25c2 + - "◃": [T: "biały mały trójkąt skierowany w lewo"] # 0x25c3 + - "◄": [T: "czarny wskaźnik skierowany w lewo"] # 0x25c4 + - "◅": [T: "biały wskaźnik skierowany w lewo"] # 0x25c5 + - "◆": [T: "czarny romb"] # 0x25c6 + - "◇": [T: "biały romb"] # 0x25c7 + - "◈": [T: "biały romb zawierający czarny mały romb"] # 0x25c8 + - "◉": [T: "rybie oko"] # 0x25c9 + - "◊": [T: "romb"] # 0x25ca + - "○": [T: "białe koło"] # 0x25cb + - "◌": [T: "kropkowany okrąg"] # 0x25cc + - "◍": [T: "okrąg z pionowe wypełnienie"] # 0x25cd + - "◎": [T: "tarcza"] # 0x25ce + - "●": [T: "czarne koło"] # 0x25cf + - "◐": [T: "okrąg z czarną lewą połową"] # 0x25d0 + - "◑": [T: "okrąg z czarną prawą połową"] # 0x25d1 + - "◒": [T: "okrąg z czarną dolną połową"] # 0x25d2 + - "◓": [T: "okrąg z czarną górną połową"] # 0x25d3 + - "◔": [T: "okrąg z czarną górną prawą ćwiartką"] # 0x25d4 + - "◕": [T: "okrąg czarny poza górną lewą ćwiartką"] # 0x25d5 + - "◖": [T: "czarne koło z lewą połową"] # 0x25d6 + - "◗": [T: "czarne koło z prawą połową"] # 0x25d7 + - "◘": [T: "odwrotność punkt"] # 0x25d8 + - "◙": [T: "odwrotność białe koło"] # 0x25d9 + - "◚": [T: "górna połowa odwrotność białe koło"] # 0x25da + - "◛": [T: "dolna połowa odwrotność białe koło"] # 0x25db + - "◜": [T: "górny lewy ćwiartka łuk kołowy"] # 0x25dc + - "◝": [T: "górny prawy ćwiartka łuk kołowy"] # 0x25dd + - "◞": [T: "dolny prawy ćwiartka łuk kołowy"] # 0x25de + - "◟": [T: "dolny lewy ćwiartka łuk kołowy"] # 0x25df + - "◠": [T: "górna połowa okrąg"] # 0x25e0 + - "◡": [T: "dolna połowa okrąg"] # 0x25e1 + - "◢": [T: "czarny dolny prawy trójkąt"] # 0x25e2 + - "◣": [T: "czarny dolny lewy trójkąt"] # 0x25e3 + - "◤": [T: "czarny górny lewy trójkąt"] # 0x25e4 + - "◥": [T: "czarny górny prawy trójkąt"] # 0x25e5 + - "◦": [T: "złożenie"] # 0x25e6 + - "◧": [T: "kwadrat z czarną lewą połową"] # 0x25e7 + - "◨": [T: "kwadrat z czarną prawą połową"] # 0x25e8 + - "◩": [T: "kwadrat z czarną górną lewą połową"] # 0x25e9 + - "◪": [T: "kwadrat z czarną dolną prawą połową"] # 0x25ea + - "◫": [T: "biały kwadrat z linią dzielącą na pół"] # 0x25eb + - "◬": [T: "biały trójkąt skierowany w górę z kropką"] # 0x25ec + - "◭": [T: "trójkąt skierowany w górę z czarną lewą połową"] # 0x25ed + - "◮": [T: "trójkąt skierowany w górę z czarną prawą połową"] # 0x25ee + - "◯": [T: "duży okrąg"] # 0x25ef + - "◰": [T: "biały kwadrat z górną lewą ćwiartką"] # 0x25f0 + - "◱": [T: "biały kwadrat z dolną lewą ćwiartką"] # 0x25f1 + - "◲": [T: "biały kwadrat z dolną prawą ćwiartką"] # 0x25f2 + - "◳": [T: "biały kwadrat z górną prawą ćwiartką"] # 0x25f3 + - "◴": [T: "białe koło z górną lewą ćwiartką"] # 0x25f4 + - "◵": [T: "białe koło z dolną lewą ćwiartką"] # 0x25f5 + - "◶": [T: "białe koło z dolną prawą ćwiartką"] # 0x25f6 + - "◷": [T: "białe koło z górną prawą ćwiartką"] # 0x25f7 + - "◸": [T: "górny lewy trójkąt"] # 0x25f8 + - "◹": [T: "górny prawy trójkąt"] # 0x25f9 + - "◺": [T: "dolny lewy trójkąt"] # 0x25fa + - "◻": [T: "biały średni kwadrat"] # 0x25fb + - "◼": [T: "czarny średni kwadrat"] # 0x25fc + - "◽": [T: "biały średni mały kwadrat"] # 0x25fd + - "◾": [T: "czarny średni mały kwadrat"] # 0x25fe + - "◿": [T: "dolny prawy trójkąt"] # 0x25ff + - "★": [T: "czarna gwiazda"] # 0x2605 + - "☆": [T: "biały gwiazda"] # 0x2606 + - "☉": [T: "słońce"] # 0x2609 + - "☌": [T: "koniunkcja"] # 0x260c + - "☒": [T: "ramka wyboru z iksem"] # 0x2612 + - "☽": [T: "przybywający księżyc"] # 0x263d + - "☾": [T: "ubywający księżyc"] # 0x263e + - "☿": [T: "Merkury"] # 0x263f + - "♀": [T: "żeńskie"] # 0x2640 + - "♁": [T: "Ziemia"] # 0x2641 + - "♂": [T: "męskie"] # 0x2642 + - "♃": [T: "Jowisz"] # 0x2643 - "♄": [T: "Saturn"] # 0x2644 - - "♅": [t: "Uran"] # 0x2645 - - "♆": [t: "Neptun"] # 0x2646 - - "♇": [t: "Pluton"] # 0x2647 - - "♈": [t: "Baran"] # 0x2648 - - "♉": [t: "Byk"] # 0x2649 - - "♩": [t: "ćwierćnuta"] # 0x2669 - - "♭": [t: "bemol"] # 0x266d - - "♮": [t: "kasownik"] # 0x266e - - "♯": [t: "krzyżyk"] # 0x266f - - "♠": [t: "czarny pik"] # 0x2660 - - "♡": [t: "biały kier"] # 0x2661 - - "♢": [t: "biały karo"] # 0x2662 - - "♣": [t: "czarny trefl"] # 0x2663 - - "♤": [t: "biały pik"] # 0x2664 - - "♥": [t: "czarny kier"] # 0x2665 - - "♦": [t: "czarny karo"] # 0x2666 - - "♧": [t: "biały trefl"] # 0x2667 - - "⚀": [t: "ścianka kostki 1"] # 0x2680 - - "⚁": [t: "ścianka kostki 2"] # 0x2681 - - "⚂": [t: "ścianka kostki 3"] # 0x2682 - - "⚃": [t: "ścianka kostki 4"] # 0x2683 - - "⚄": [t: "ścianka kostki 5"] # 0x2684 - - "⚅": [t: "ścianka kostki 6"] # 0x2685 - - "⚆": [t: "białe koło z kropką prawy"] # 0x2686 - - "⚇": [t: "białe koło z dwiema kropkami"] # 0x2687 - - "⚈": [t: "czarne koło z kropką prawy"] # 0x2688 - - "⚉": [t: "czarne koło z dwiema kropkami"] # 0x2689 - - "⚪": [t: "średni białe koło"] # 0x26aa - - "⚫": [t: "średni czarne koło"] # 0x26ab - - "⚬": [t: "średni mały białe koło"] # 0x26ac - - "⚲": [t: "neutralny"] # 0x26b2 - - "✓": [t: "haczek znak"] # 0x2713 - - "✠": [t: "krzyż maltański"] # 0x2720 - - "✪": [t: "w kółku biały gwiazda"] # 0x272a - - "✶": [t: "czarna sześcioramienna gwiazda"] # 0x2736 - - "❨": [t: "średni lewy ornament nawiasu okrągłego"] # 0x2768 - - "❩": [t: "średni prawy ornament nawiasu okrągłego"] # 0x2769 - - "❪": [t: "średni spłaszczony lewy ornament nawiasu okrągłego"] # 0x276a - - "❫": [t: "średni spłaszczony prawy ornament nawiasu okrągłego"] # 0x276b - - "❬": [t: "średni kąt skierowany w lewo nawias kwadratowy ornament"] # 0x276c - - "❭": [t: "średni kąt skierowany w prawo nawias kwadratowy ornament"] # 0x276d - - "❮": [t: "gruby kąt skierowany w lewo cudzysłów ornament"] # 0x276e - - "❯": [t: "gruby kąt skierowany w prawo cudzysłów ornament"] # 0x276f - - "❰": [t: "gruby kąt skierowany w lewo nawias kwadratowy ornament"] # 0x2770 - - "❱": [t: "gruby kąt skierowany w prawo nawias kwadratowy ornament"] # 0x2771 - - "❲": [t: "lekki lewy nawias skorupowy ornament"] # 0x2772 - - "❳": [t: "lekki prawy nawias skorupowy ornament"] # 0x2773 - - "❴": [t: "średni lewy nawias klamrowy ornament"] # 0x2774 - - "❵": [t: "średni prawy nawias klamrowy ornament"] # 0x2775 - - "❶": [t: "czarny w kółku jeden"] # 0x2776 - - "❷": [t: "czarny w kółku dwa"] # 0x2777 - - "❸": [t: "czarny w kółku trzy"] # 0x2778 - - "❹": [t: "czarny w kółku cztery"] # 0x2779 - - "❺": [t: "czarny w kółku pięć"] # 0x277a - - "❻": [t: "czarny w kółku sześć"] # 0x277b - - "❼": [t: "czarny w kółku siedem"] # 0x277c - - "❽": [t: "czarny w kółku osiem"] # 0x277d - - "❾": [t: "czarny w kółku dziewięć"] # 0x277e - - "❿": [t: "czarny w kółku dziesięć"] # 0x277f - - "➀": [t: "w kółku bezszeryfowe jeden"] # 0x2780 - - "➁": [t: "w kółku bezszeryfowe dwa"] # 0x2781 - - "➂": [t: "w kółku bezszeryfowe trzy"] # 0x2782 - - "➃": [t: "w kółku bezszeryfowe cztery"] # 0x2783 - - "➄": [t: "w kółku bezszeryfowe pięć"] # 0x2784 - - "➅": [t: "w kółku bezszeryfowe sześć"] # 0x2785 - - "➆": [t: "w kółku bezszeryfowe siedem"] # 0x2786 - - "➇": [t: "w kółku bezszeryfowe osiem"] # 0x2787 - - "➈": [t: "w kółku bezszeryfowe dziewięć"] # 0x2788 - - "➉": [t: "w kółku bezszeryfowe dziesięć"] # 0x2789 - - "➊": [t: "czarny w kółku bezszeryfowe jeden"] # 0x278a - - "➋": [t: "czarny w kółku bezszeryfowe dwa"] # 0x278b - - "➌": [t: "czarny w kółku bezszeryfowe trzy"] # 0x278c - - "➍": [t: "czarny w kółku bezszeryfowe cztery"] # 0x278d - - "➎": [t: "czarny w kółku bezszeryfowe pięć"] # 0x278e - - "➏": [t: "czarny w kółku bezszeryfowe sześć"] # 0x278f - - "➐": [t: "czarny w kółku bezszeryfowe siedem"] # 0x2790 - - "➑": [t: "czarny w kółku bezszeryfowe osiem"] # 0x2791 - - "➒": [t: "czarny w kółku bezszeryfowe dziewięć"] # 0x2792 - - "➓": [t: "czarny w kółku bezszeryfowe dziesięć"] # 0x2793 - - "➔": [t: "gruba strzałka w prawo z szerokim grotem"] # 0x2794 - - "➕": [t: "gruby znak plus"] # 0x2795 - - "➖": [t: "gruby znak minus"] # 0x2796 - - "➗": [t: "gruby znak dzielenia"] # 0x2797 - - "➘": [t: "gruba strzałka na południowy wschód"] # 0x2798 - - "➙": [t: "gruby strzałka w prawo"] # 0x2799 - - "➚": [t: "gruba strzałka na północny wschód"] # 0x279a - - "➛": [t: "strzałka w prawo z grotem kreślarskim"] # 0x279b - - "➜": [t: "gruba strzałka w prawo z okrągłym grotem"] # 0x279c - - "➝": [t: "strzałka w prawo z trójkątnym grotem"] # 0x279d - - "➞": [t: "gruba strzałka w prawo z trójkątnym grotem"] # 0x279e - - "➟": [t: "kreskowana strzałka w prawo z trójkątnym grotem"] # 0x279f - - "➠": [t: "gruba kreskowana strzałka w prawo z trójkątnym grotem"] # 0x27a0 - - "➡": [t: "czarny strzałka w prawo"] # 0x27a1 - - "➢": [t: "trójwymiarowa strzałka w prawo podświetlona od góry"] # 0x27a2 - - "➣": [t: "trójwymiarowa strzałka w prawo podświetlona od dołu"] # 0x27a3 - - "➤": [t: "czarny prawy grot strzałki"] # 0x27a4 - - "➥": [t: "gruba czarna zakrzywiona dolna strzałka w prawo"] # 0x27a5 - - "➦": [t: "gruba czarna zakrzywiona górna strzałka w prawo"] # 0x27a6 - - "➧": [t: "krótki czarny strzałka w prawo"] # 0x27a7 - - "➨": [t: "gruba czarna wklęsła ostro zakończona strzałka w prawo"] # 0x27a8 - - "➩": [t: "prawostronnie cieniowana biała strzałka w prawo"] # 0x27a9 - - "➪": [t: "lewostronnie cieniowana biała strzałka w prawo"] # 0x27aa - - "➫": [t: "biała strzałka w prawo pochylona do tyłu z cieniem"] # 0x27ab - - "➬": [t: "biała strzałka w prawo pochylona do przodu z cieniem"] # 0x27ac - - "➭": [t: "gruba biała strzałka w prawo z cieniem w dolnym prawym rogu"] # 0x27ad - - "➮": [t: "gruba biała strzałka w prawo z cieniem w górnym prawym rogu"] # 0x27ae - - "➯": [t: "biała strzałka w prawo z dolnym prawym wcięciem i cieniem"] # 0x27af - - "➱": [t: "biała strzałka w prawo z górnym prawym wcięciem i cieniem"] # 0x27b1 - - "➲": [t: "gruba biała strzałka w prawo w kółku"] # 0x27b2 - - "➳": [t: "biała pierzasta strzałka w prawo"] # 0x27b3 - - "➴": [t: "czarna pierzasta strzałka południowo-wschodnia"] # 0x27b4 - - "➵": [t: "czarna pierzasta strzałka w prawo"] # 0x27b5 - - "➶": [t: "czarny pierzasty północ wschód strzałka"] # 0x27b6 - - "➷": [t: "gruby czarna pierzasta strzałka południowo-wschodnia"] # 0x27b7 - - "➸": [t: "gruby czarna pierzasta strzałka w prawo"] # 0x27b8 - - "➹": [t: "gruby czarny pierzasty północ wschód strzałka"] # 0x27b9 - - "➺": [t: "strzałka w prawo z łezkowatym grotem z zadziorami"] # 0x27ba - - "➻": [t: "gruba strzałka w prawo z łezkowatym grotem i trzonkiem"] # 0x27bb - - "➼": [t: "strzałka w prawo z klinowym ogonem"] # 0x27bc - - "➽": [t: "gruby strzałka w prawo z klinowym ogonem"] # 0x27bd - - "➾": [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 + - "♅": [T: "Uran"] # 0x2645 + - "♆": [T: "Neptun"] # 0x2646 + - "♇": [T: "Pluton"] # 0x2647 + - "♈": [T: "Baran"] # 0x2648 + - "♉": [T: "Byk"] # 0x2649 + - "♩": [T: "ćwierćnuta"] # 0x2669 + - "♭": [T: "bemol"] # 0x266d + - "♮": [T: "kasownik"] # 0x266e + - "♯": [T: "krzyżyk"] # 0x266f + - "♠": [T: "czarny pik"] # 0x2660 + - "♡": [T: "biały kier"] # 0x2661 + - "♢": [T: "biały karo"] # 0x2662 + - "♣": [T: "czarny trefl"] # 0x2663 + - "♤": [T: "biały pik"] # 0x2664 + - "♥": [T: "czarny kier"] # 0x2665 + - "♦": [T: "czarny karo"] # 0x2666 + - "♧": [T: "biały trefl"] # 0x2667 + - "⚀": [T: "ścianka kostki 1"] # 0x2680 + - "⚁": [T: "ścianka kostki 2"] # 0x2681 + - "⚂": [T: "ścianka kostki 3"] # 0x2682 + - "⚃": [T: "ścianka kostki 4"] # 0x2683 + - "⚄": [T: "ścianka kostki 5"] # 0x2684 + - "⚅": [T: "ścianka kostki 6"] # 0x2685 + - "⚆": [T: "białe koło z kropką prawy"] # 0x2686 + - "⚇": [T: "białe koło z dwiema kropkami"] # 0x2687 + - "⚈": [T: "czarne koło z kropką prawy"] # 0x2688 + - "⚉": [T: "czarne koło z dwiema kropkami"] # 0x2689 + - "⚪": [T: "średni białe koło"] # 0x26aa + - "⚫": [T: "średni czarne koło"] # 0x26ab + - "⚬": [T: "średni mały białe koło"] # 0x26ac + - "⚲": [T: "neutralny"] # 0x26b2 + - "✓": [T: "haczek znak"] # 0x2713 + - "✠": [T: "krzyż maltański"] # 0x2720 + - "✪": [T: "w kółku biały gwiazda"] # 0x272a + - "✶": [T: "czarna sześcioramienna gwiazda"] # 0x2736 + - "❨": [T: "średni lewy ornament nawiasu okrągłego"] # 0x2768 + - "❩": [T: "średni prawy ornament nawiasu okrągłego"] # 0x2769 + - "❪": [T: "średni spłaszczony lewy ornament nawiasu okrągłego"] # 0x276a + - "❫": [T: "średni spłaszczony prawy ornament nawiasu okrągłego"] # 0x276b + - "❬": [T: "średni kąt skierowany w lewo nawias kwadratowy ornament"] # 0x276c + - "❭": [T: "średni kąt skierowany w prawo nawias kwadratowy ornament"] # 0x276d + - "❮": [T: "gruby kąt skierowany w lewo cudzysłów ornament"] # 0x276e + - "❯": [T: "gruby kąt skierowany w prawo cudzysłów ornament"] # 0x276f + - "❰": [T: "gruby kąt skierowany w lewo nawias kwadratowy ornament"] # 0x2770 + - "❱": [T: "gruby kąt skierowany w prawo nawias kwadratowy ornament"] # 0x2771 + - "❲": [T: "lekki lewy nawias skorupowy ornament"] # 0x2772 + - "❳": [T: "lekki prawy nawias skorupowy ornament"] # 0x2773 + - "❴": [T: "średni lewy nawias klamrowy ornament"] # 0x2774 + - "❵": [T: "średni prawy nawias klamrowy ornament"] # 0x2775 + - "❶": [T: "czarny w kółku jeden"] # 0x2776 + - "❷": [T: "czarny w kółku dwa"] # 0x2777 + - "❸": [T: "czarny w kółku trzy"] # 0x2778 + - "❹": [T: "czarny w kółku cztery"] # 0x2779 + - "❺": [T: "czarny w kółku pięć"] # 0x277a + - "❻": [T: "czarny w kółku sześć"] # 0x277b + - "❼": [T: "czarny w kółku siedem"] # 0x277c + - "❽": [T: "czarny w kółku osiem"] # 0x277d + - "❾": [T: "czarny w kółku dziewięć"] # 0x277e + - "❿": [T: "czarny w kółku dziesięć"] # 0x277f + - "➀": [T: "w kółku bezszeryfowe jeden"] # 0x2780 + - "➁": [T: "w kółku bezszeryfowe dwa"] # 0x2781 + - "➂": [T: "w kółku bezszeryfowe trzy"] # 0x2782 + - "➃": [T: "w kółku bezszeryfowe cztery"] # 0x2783 + - "➄": [T: "w kółku bezszeryfowe pięć"] # 0x2784 + - "➅": [T: "w kółku bezszeryfowe sześć"] # 0x2785 + - "➆": [T: "w kółku bezszeryfowe siedem"] # 0x2786 + - "➇": [T: "w kółku bezszeryfowe osiem"] # 0x2787 + - "➈": [T: "w kółku bezszeryfowe dziewięć"] # 0x2788 + - "➉": [T: "w kółku bezszeryfowe dziesięć"] # 0x2789 + - "➊": [T: "czarny w kółku bezszeryfowe jeden"] # 0x278a + - "➋": [T: "czarny w kółku bezszeryfowe dwa"] # 0x278b + - "➌": [T: "czarny w kółku bezszeryfowe trzy"] # 0x278c + - "➍": [T: "czarny w kółku bezszeryfowe cztery"] # 0x278d + - "➎": [T: "czarny w kółku bezszeryfowe pięć"] # 0x278e + - "➏": [T: "czarny w kółku bezszeryfowe sześć"] # 0x278f + - "➐": [T: "czarny w kółku bezszeryfowe siedem"] # 0x2790 + - "➑": [T: "czarny w kółku bezszeryfowe osiem"] # 0x2791 + - "➒": [T: "czarny w kółku bezszeryfowe dziewięć"] # 0x2792 + - "➓": [T: "czarny w kółku bezszeryfowe dziesięć"] # 0x2793 + - "➔": [T: "gruba strzałka w prawo z szerokim grotem"] # 0x2794 + - "➕": [T: "gruby znak plus"] # 0x2795 + - "➖": [T: "gruby znak minus"] # 0x2796 + - "➗": [T: "gruby znak dzielenia"] # 0x2797 + - "➘": [T: "gruba strzałka na południowy wschód"] # 0x2798 + - "➙": [T: "gruby strzałka w prawo"] # 0x2799 + - "➚": [T: "gruba strzałka na północny wschód"] # 0x279a + - "➛": [T: "strzałka w prawo z grotem kreślarskim"] # 0x279b + - "➜": [T: "gruba strzałka w prawo z okrągłym grotem"] # 0x279c + - "➝": [T: "strzałka w prawo z trójkątnym grotem"] # 0x279d + - "➞": [T: "gruba strzałka w prawo z trójkątnym grotem"] # 0x279e + - "➟": [T: "kreskowana strzałka w prawo z trójkątnym grotem"] # 0x279f + - "➠": [T: "gruba kreskowana strzałka w prawo z trójkątnym grotem"] # 0x27a0 + - "➡": [T: "czarny strzałka w prawo"] # 0x27a1 + - "➢": [T: "trójwymiarowa strzałka w prawo podświetlona od góry"] # 0x27a2 + - "➣": [T: "trójwymiarowa strzałka w prawo podświetlona od dołu"] # 0x27a3 + - "➤": [T: "czarny prawy grot strzałki"] # 0x27a4 + - "➥": [T: "gruba czarna zakrzywiona dolna strzałka w prawo"] # 0x27a5 + - "➦": [T: "gruba czarna zakrzywiona górna strzałka w prawo"] # 0x27a6 + - "➧": [T: "krótki czarny strzałka w prawo"] # 0x27a7 + - "➨": [T: "gruba czarna wklęsła ostro zakończona strzałka w prawo"] # 0x27a8 + - "➩": [T: "prawostronnie cieniowana biała strzałka w prawo"] # 0x27a9 + - "➪": [T: "lewostronnie cieniowana biała strzałka w prawo"] # 0x27aa + - "➫": [T: "biała strzałka w prawo pochylona do tyłu z cieniem"] # 0x27ab + - "➬": [T: "biała strzałka w prawo pochylona do przodu z cieniem"] # 0x27ac + - "➭": [T: "gruba biała strzałka w prawo z cieniem w dolnym prawym rogu"] # 0x27ad + - "➮": [T: "gruba biała strzałka w prawo z cieniem w górnym prawym rogu"] # 0x27ae + - "➯": [T: "biała strzałka w prawo z dolnym prawym wcięciem i cieniem"] # 0x27af + - "➱": [T: "biała strzałka w prawo z górnym prawym wcięciem i cieniem"] # 0x27b1 + - "➲": [T: "gruba biała strzałka w prawo w kółku"] # 0x27b2 + - "➳": [T: "biała pierzasta strzałka w prawo"] # 0x27b3 + - "➴": [T: "czarna pierzasta strzałka południowo-wschodnia"] # 0x27b4 + - "➵": [T: "czarna pierzasta strzałka w prawo"] # 0x27b5 + - "➶": [T: "czarny pierzasty północ wschód strzałka"] # 0x27b6 + - "➷": [T: "gruby czarna pierzasta strzałka południowo-wschodnia"] # 0x27b7 + - "➸": [T: "gruby czarna pierzasta strzałka w prawo"] # 0x27b8 + - "➹": [T: "gruby czarny pierzasty północ wschód strzałka"] # 0x27b9 + - "➺": [T: "strzałka w prawo z łezkowatym grotem z zadziorami"] # 0x27ba + - "➻": [T: "gruba strzałka w prawo z łezkowatym grotem i trzonkiem"] # 0x27bb + - "➼": [T: "strzałka w prawo z klinowym ogonem"] # 0x27bc + - "➽": [T: "gruby strzałka w prawo z klinowym ogonem"] # 0x27bd + - "➾": [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, 22A5 (22A5 wrongly used for perpendicular by most editors) - test: - if: "$SpeechStyle = 'LiteralSpeak' and text()='⊥'" # 22A5 (up tack/bottom) @@ -1670,1327 +1670,1327 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "otwórz podzbiór" + - T: "otwórz podzbiór" - "⟄": # 0x27c4 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "otwórz nadzbiór" - - "⟅": [t: "lewy ogranicznik workowy w kształcie S"] # 0x27c5 - - "⟆": [t: "prawy ogranicznik workowy w kształcie S"] # 0x27c6 - - "⟇": [t: "lub z kropką wewnątrz"] # 0x27c7 - - "⟈": [t: "odwrotny ukośnik poprzedzający podzbiór"] # 0x27c8 - - "⟉": [t: "nadzbiór poprzedzający ukośnik"] # 0x27c9 - - "⟊": [t: "pionowa kreska z poziomą kreską"] # 0x27ca - - "⟋": [t: "matematyczny ukośnik wznoszący"] # 0x27cb - - "⟌": [t: "dzielenie pisemne"] # 0x27cc - - "⟍": [t: "matematyczny ukośnik opadający"] # 0x27cd - - "⟎": [t: "kwadratowa koniunkcja logiczna"] # 0x27ce - - "⟏": [t: "do kwadratu logiczne lub"] # 0x27cf - - "⟐": [t: "biały romb z wyśrodkowaną kropką"] # 0x27d0 - - "⟑": [t: "i z kropką"] # 0x27d1 - - "⟒": [t: "należy do z otwarciem u góry"] # 0x27d2 - - "⟓": [t: "prawy dolny narożnik z kropką"] # 0x27d3 - - "⟔": [t: "górny lewy narożnik z kropką"] # 0x27d4 - - "⟕": [t: "lewe złączenie zewnętrzne"] # 0x27d5 - - "⟖": [t: "prawe złączenie zewnętrzne"] # 0x27d6 - - "⟗": [t: "pełne złączenie zewnętrzne"] # 0x27d7 - - "⟘": [t: "duży górny znacznik"] # 0x27d8 - - "⟙": [t: "duży dolny znacznik"] # 0x27d9 - - "⟚": [t: "lewy i prawy podwójny znacznik dedukcji"] # 0x27da - - "⟛": [t: "lewy i prawy znacznik"] # 0x27db - - "⟜": [t: "lewa multimapa"] # 0x27dc - - "⟝": [t: "długi prawy znacznik"] # 0x27dd - - "⟞": [t: "długi lewy znacznik"] # 0x27de - - "⟟": [t: "górny znacznik z okręgiem nad"] # 0x27df - - "⟠": [t: "romb podzielony poziomą kreską"] # 0x27e0 - - "⟡": [t: "biały romb o wklęsłych bokach"] # 0x27e1 - - "⟢": [t: "biały romb o wklęsłych bokach z lewym haczykiem"] # 0x27e2 - - "⟣": [t: "biały romb o wklęsłych bokach z prawym haczykiem"] # 0x27e3 - - "⟤": [t: "biały kwadrat z lewym haczykiem"] # 0x27e4 - - "⟥": [t: "biały kwadrat z prawym haczykiem"] # 0x27e5 - - "⟦": [t: "lewy biały nawias kwadratowy"] # 0x27e6 - - "⟧": [t: "prawy biały nawias kwadratowy"] # 0x27e7 - - "⟨": [t: "lewy nawias kątowy"] # 0x27e8 - - "⟩": [t: "prawy nawias kątowy"] # 0x27e9 - - "⟪": [t: "lewy podwójny nawias kątowy"] # 0x27ea - - "⟫": [t: "prawy podwójny nawias kątowy"] # 0x27eb - - "⟬": [t: "lewy biały nawias skorupowy"] # 0x27ec - - "⟭": [t: "prawy biały nawias skorupowy"] # 0x27ed - - "⟮": [t: "lewy spłaszczony nawias"] # 0x27ee - - "⟯": [t: "prawy spłaszczony nawias"] # 0x27ef - - "⟰": [t: "poczwórna strzałka w górę"] # 0x27f0 - - "⟱": [t: "poczwórna strzałka w dół"] # 0x27f1 - - "⟲": [t: "okrężna strzałka z przerwą przeciwnie do ruchu wskazówek zegara"] # 0x27f2 - - "⟳": [t: "okrężna strzałka z przerwą zgodnie z ruchem wskazówek zegara"] # 0x27f3 - - "⟴": [t: "strzałka w prawo z plusem w kółku"] # 0x27f4 - - "⟵": [t: "długa strzałka w lewo"] # 0x27f5 - - "⟶": [t: "długa strzałka w prawo"] # 0x27f6 - - "⟷": [t: "długa strzałka w lewo i w prawo"] # 0x27f7 - - "⟸": [t: "długa podwójna strzałka w lewo"] # 0x27f8 - - "⟹": [t: "implikuje"] # 0x27f9 - - "⟺": [t: "wtedy i tylko wtedy"] # 0x27fa - - "⟻": [t: "długa strzałka w lewo od kreski"] # 0x27fb - - "⟼": [t: "długa strzałka w prawo od kreski"] # 0x27fc - - "⟽": [t: "długa podwójna strzałka w lewo od kreski"] # 0x27fd - - "⟾": [t: "długa podwójna strzałka w prawo od kreski"] # 0x27fe - - "⟿": [t: "długa falista strzałka w prawo"] # 0x27ff - - "⤀": [t: "strzałka w prawo z dwoma grotami i pionowym przekreśleniem"] # 0x2900 - - "⤁": [t: "strzałka w prawo z dwoma grotami i podwójnym pionowym przekreśleniem"] # 0x2901 - - "⤂": [t: "podwójna strzałka w lewo z pionową kreską"] # 0x2902 - - "⤃": [t: "podwójna strzałka w prawo z pionową kreską"] # 0x2903 - - "⤄": [t: "podwójna strzałka w lewo i w prawo z pionową kreską"] # 0x2904 - - "⤅": [t: "strzałka w prawo z dwoma grotami od kreski"] # 0x2905 - - "⤆": [t: "podwójna strzałka w lewo od kreski"] # 0x2906 - - "⤇": [t: "podwójna strzałka w prawo od kreski"] # 0x2907 - - "⤈": [t: "strzałka w dół z poziomą kreską"] # 0x2908 - - "⤉": [t: "strzałka w górę z poziomą kreską"] # 0x2909 - - "⤊": [t: "górny potrójny strzałka"] # 0x290a - - "⤋": [t: "dolny potrójny strzałka"] # 0x290b - - "⤌": [t: "lewy podwójny kreska strzałka"] # 0x290c - - "⤍": [t: "prawy podwójny kreska strzałka"] # 0x290d - - "⤎": [t: "lewy potrójny kreska strzałka"] # 0x290e - - "⤏": [t: "prawy potrójny kreska strzałka"] # 0x290f - - "⤐": [t: "strzałka w prawo z dwoma grotami i potrójną kreską"] # 0x2910 - - "⤑": [t: "strzałka w prawo z kropkowanym trzonem"] # 0x2911 - - "⤒": [t: "strzałka w górę do kreski"] # 0x2912 - - "⤓": [t: "strzałka w dół do kreski"] # 0x2913 - - "⤔": [t: "strzałka w prawo z ogonem i pionową kreską"] # 0x2914 - - "⤕": [t: "strzałka w prawo z ogonem i podwójną pionową kreską"] # 0x2915 - - "⤖": [t: "strzałka w prawo z dwoma grotami i ogonem"] # 0x2916 - - "⤗": [t: "strzałka w prawo z dwoma grotami, ogonem i pionowym przekreśleniem"] # 0x2917 - - "⤘": [t: "strzałka w prawo z dwoma grotami, ogonem i podwójnym pionowym przekreśleniem"] # 0x2918 - - "⤙": [t: "strzałka w lewo ogon"] # 0x2919 - - "⤚": [t: "strzałka w prawo ogon"] # 0x291a - - "⤛": [t: "lewy podwójna strzałka ogon"] # 0x291b - - "⤜": [t: "prawy podwójna strzałka ogon"] # 0x291c - - "⤝": [t: "strzałka w lewo do wypełnionego rombu"] # 0x291d - - "⤞": [t: "strzałka w prawo do wypełnionego rombu"] # 0x291e - - "⤟": [t: "strzałka w lewo od kreski do wypełnionego rombu"] # 0x291f - - "⤠": [t: "strzałka w prawo od kreski do wypełnionego rombu"] # 0x2920 - - "⤡": [t: "strzałka północno-zachodnia i południowo-wschodnia"] # 0x2921 - - "⤢": [t: "strzałka północno-wschodnia i południowo-zachodnia"] # 0x2922 - - "⤣": [t: "strzałka północno-zachodnia z hakiem"] # 0x2923 - - "⤤": [t: "strzałka północno-wschodnia z hakiem"] # 0x2924 - - "⤥": [t: "strzałka południowo-wschodnia z hakiem"] # 0x2925 - - "⤦": [t: "strzałka południowo-zachodnia z hakiem"] # 0x2926 - - "⤧": [t: "strzałka północno-zachodnia i strzałka północno-wschodnia"] # 0x2927 - - "⤨": [t: "strzałka północno-wschodnia i strzałka południowo-wschodnia"] # 0x2928 - - "⤩": [t: "strzałka południowo-wschodnia i strzałka południowo-zachodnia"] # 0x2929 - - "⤪": [t: "strzałka południowo-zachodnia i strzałka północno-zachodnia"] # 0x292a - - "⤫": [t: "ukośna wznosząca przecinająca ukośną opadającą"] # 0x292b - - "⤬": [t: "ukośna opadająca przecinająca ukośną wznoszącą"] # 0x292c - - "⤭": [t: "strzałka południowo-wschodnia przecinająca strzałkę północno-wschodnią"] # 0x292d - - "⤮": [t: "strzałka północno-wschodnia przecinająca strzałkę południowo-wschodnią"] # 0x292e - - "⤯": [t: "ukośna opadająca przecinająca strzałkę północno-wschodnią"] # 0x292f - - "⤰": [t: "ukośna wznosząca przecinająca strzałkę południowo-wschodnią"] # 0x2930 - - "⤱": [t: "strzałka północno-wschodnia przecinająca strzałkę północno-zachodnią"] # 0x2931 - - "⤲": [t: "strzałka północno-zachodnia przecinająca strzałkę północno-wschodnią"] # 0x2932 - - "⤳": [t: "falista strzałka skierowana bezpośrednio w prawo"] # 0x2933 - - "⤴": [t: "strzałka skierowana w prawo, potem zakrzywiona w górę"] # 0x2934 - - "⤵": [t: "strzałka skierowana w prawo, potem zakrzywiona w dół"] # 0x2935 - - "⤶": [t: "strzałka skierowana w dół, potem zakrzywiona w lewo"] # 0x2936 - - "⤷": [t: "strzałka skierowana w dół, potem zakrzywiona w prawo"] # 0x2937 - - "⤸": [t: "prawostronna strzałka łukowa zgodna z ruchem wskazówek zegara"] # 0x2938 - - "⤹": [t: "lewostronna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x2939 - - "⤺": [t: "górna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x293a - - "⤻": [t: "dolna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x293b - - "⤼": [t: "górna strzałka łukowa zgodna z ruchem wskazówek zegara z minusem"] # 0x293c - - "⤽": [t: "górna strzałka łukowa przeciwna do ruchu wskazówek zegara z plusem"] # 0x293d - - "⤾": [t: "dolna prawa strzałka półokrągła zgodna z ruchem wskazówek zegara"] # 0x293e - - "⤿": [t: "dolna lewa strzałka półokrągła przeciwna do ruchu wskazówek zegara"] # 0x293f - - "⥀": [t: "zamknięta strzałka okrężna przeciwna do ruchu wskazówek zegara"] # 0x2940 - - "⥁": [t: "zamknięta strzałka okrężna zgodna z ruchem wskazówek zegara"] # 0x2941 - - "⥂": [t: "strzałka w prawo nad krótką strzałką w lewo"] # 0x2942 - - "⥃": [t: "strzałka w lewo nad krótką strzałką w prawo"] # 0x2943 - - "⥄": [t: "krótka strzałka w prawo nad strzałką w lewo"] # 0x2944 - - "⥅": [t: "strzałka w prawo z plusem pod spodem"] # 0x2945 - - "⥆": [t: "strzałka w lewo z plusem pod spodem"] # 0x2946 - - "⥇": [t: "strzałka w prawo przez X"] # 0x2947 - - "⥈": [t: "strzałka w lewo i w prawo przez okrąg"] # 0x2948 - - "⥉": [t: "strzałka w górę z dwoma grotami od okręgu"] # 0x2949 - - "⥊": [t: "lewy grot górny prawy grot dolny harpun"] # 0x294a - - "⥋": [t: "lewy grot dolny prawy grot górny harpun"] # 0x294b - - "⥌": [t: "górny grot prawy dolny grot lewy harpun"] # 0x294c - - "⥍": [t: "górny grot lewy dolny grot prawy harpun"] # 0x294d - - "⥎": [t: "lewy grot górny prawy grot górny harpun"] # 0x294e - - "⥏": [t: "górny grot prawy dolny grot prawy harpun"] # 0x294f - - "⥐": [t: "lewy grot dolny prawy grot dolny harpun"] # 0x2950 - - "⥑": [t: "górny grot lewy dolny grot lewy harpun"] # 0x2951 - - "⥒": [t: "lewy harpun z grotem górnym do kreski"] # 0x2952 - - "⥓": [t: "prawy harpun z grotem górnym do kreski"] # 0x2953 - - "⥔": [t: "górny harpun z grotem prawym do kreski"] # 0x2954 - - "⥕": [t: "dolny harpun z grotem prawym do kreski"] # 0x2955 - - "⥖": [t: "lewy harpun z grotem dolnym do kreski"] # 0x2956 - - "⥗": [t: "prawy harpun z grotem dolnym do kreski"] # 0x2957 - - "⥘": [t: "górny harpun z grotem lewym do kreski"] # 0x2958 - - "⥙": [t: "dolny harpun z grotem lewym do kreski"] # 0x2959 - - "⥚": [t: "lewy harpun z grotem górnym od kreski"] # 0x295a - - "⥛": [t: "prawy harpun z grotem górnym od kreski"] # 0x295b - - "⥜": [t: "górny harpun z grotem prawym od kreski"] # 0x295c - - "⥝": [t: "dolny harpun z grotem prawym od kreski"] # 0x295d - - "⥞": [t: "lewy harpun z grotem dolnym od kreski"] # 0x295e - - "⥟": [t: "prawy harpun z grotem dolnym od kreski"] # 0x295f - - "⥠": [t: "górny harpun z grotem lewym od kreski"] # 0x2960 - - "⥡": [t: "dolny harpun z grotem lewym od kreski"] # 0x2961 - - "⥢": [t: "lewy harpun z grotem górnym nad lewy harpun z grotem dolnym"] # 0x2962 - - "⥣": [t: "górny harpun z grotem w lewo obok górnego harpuna z grotem w prawo"] # 0x2963 - - "⥤": [t: "prawy harpun z grotem górnym nad prawy harpun z grotem dolnym"] # 0x2964 - - "⥥": [t: "dolny harpun z grotem w lewo obok dolnego harpuna z grotem w prawo"] # 0x2965 - - "⥦": [t: "lewy harpun z grotem górnym nad prawy harpun z grotem górnym"] # 0x2966 - - "⥧": [t: "lewy harpun z grotem dolnym nad prawy harpun z grotem dolnym"] # 0x2967 - - "⥨": [t: "prawy harpun z grotem górnym nad lewy harpun z grotem górnym"] # 0x2968 - - "⥩": [t: "prawy harpun z grotem dolnym nad lewy harpun z grotem dolnym"] # 0x2969 - - "⥪": [t: "lewy harpun z grotem górnym nad długą kreską"] # 0x296a - - "⥫": [t: "lewy harpun z grotem dolnym pod długą kreską"] # 0x296b - - "⥬": [t: "prawy harpun z grotem górnym nad długą kreską"] # 0x296c - - "⥭": [t: "prawy harpun z grotem dolnym pod długą kreską"] # 0x296d - - "⥮": [t: "górny harpun z grotem w lewo obok dolnego harpuna z grotem w prawo"] # 0x296e - - "⥯": [t: "dolny harpun z grotem w lewo obok górnego harpuna z grotem w prawo"] # 0x296f - - "⥰": [t: "podwójna strzałka w prawo z zaokrąglonym grotem"] # 0x2970 - - "⥱": [t: "równa się nad strzałka w prawo"] # 0x2971 - - "⥲": [t: "operator tyldy nad strzałką w prawo"] # 0x2972 - - "⥳": [t: "strzałka w lewo nad operatorem tyldy"] # 0x2973 - - "⥴": [t: "strzałka w prawo nad operatorem tyldy"] # 0x2974 - - "⥵": [t: "strzałka w prawo nad znakiem przybliżonej równości"] # 0x2975 - - "⥶": [t: "mniejsze niż nad strzałka w lewo"] # 0x2976 - - "⥷": [t: "strzałka w lewo przez znak mniejsze niż"] # 0x2977 - - "⥸": [t: "większe niż nad strzałka w prawo"] # 0x2978 - - "⥹": [t: "podzbiór nad strzałka w prawo"] # 0x2979 - - "⥺": [t: "strzałka w lewo przez znak podzbioru"] # 0x297a - - "⥻": [t: "nadzbiór nad strzałka w lewo"] # 0x297b - - "⥼": [t: "lewy rybi ogon"] # 0x297c - - "⥽": [t: "prawy rybi ogon"] # 0x297d - - "⥾": [t: "górny rybi ogon"] # 0x297e - - "⥿": [t: "dolny rybi ogon"] # 0x297f - - "⦀": [t: "potrójna pionowa kreska jako ogranicznik"] # 0x2980 - - "⦁": [t: "punkt w notacji Z"] # 0x2981 - - "⦂": [t: "dwukropek typu w notacji Z"] # 0x2982 - - "⦃": [t: "lewy biały nawias klamrowy"] # 0x2983 - - "⦄": [t: "prawy biały nawias klamrowy"] # 0x2984 - - "⦅": [t: "lewy biały nawias"] # 0x2985 - - "⦆": [t: "prawy biały nawias"] # 0x2986 - - "⦇": [t: "lewy nawias kwadratowy obrazu w notacji Z"] # 0x2987 - - "⦈": [t: "prawy nawias kwadratowy obrazu w notacji Z"] # 0x2988 - - "⦉": [t: "lewy nawias kwadratowy wiązania w notacji Z"] # 0x2989 - - "⦊": [t: "prawy nawias kwadratowy wiązania w notacji Z"] # 0x298a - - "⦋": [t: "lewy nawias kwadratowy z podkreśleniem"] # 0x298b - - "⦌": [t: "prawy nawias kwadratowy z podkreśleniem"] # 0x298c - - "⦍": [t: "lewy nawias kwadratowy z haczykiem w górnym rogu"] # 0x298d - - "⦎": [t: "prawy nawias kwadratowy z haczykiem w dolnym rogu"] # 0x298e - - "⦏": [t: "lewy nawias kwadratowy z haczykiem w dolnym rogu"] # 0x298f - - "⦐": [t: "prawy nawias kwadratowy z haczykiem w górnym rogu"] # 0x2990 - - "⦑": [t: "lewy kąt nawias kwadratowy z kropką"] # 0x2991 - - "⦒": [t: "prawy nawias kątowy z kropką"] # 0x2992 - - "⦓": [t: "lewy łuk mniejsze niż nawias kwadratowy"] # 0x2993 - - "⦔": [t: "prawy łuk większe niż nawias kwadratowy"] # 0x2994 - - "⦕": [t: "podwójny lewy łuk większe niż nawias kwadratowy"] # 0x2995 - - "⦖": [t: "podwójny prawy łuk mniejsze niż nawias kwadratowy"] # 0x2996 - - "⦗": [t: "lewy czarny nawias skorupowy"] # 0x2997 - - "⦘": [t: "prawy czarny nawias skorupowy"] # 0x2998 - - "⦙": [t: "kropkowany ogranicznik"] # 0x2999 - - "⦚": [t: "pionowa linia zygzakowata"] # 0x299a - - "⦛": [t: "kąt mierzony otwarty w lewo"] # 0x299b - - "⦜": [t: "wariant kąta prostego z kwadratem"] # 0x299c - - "⦝": [t: "mierzony kąt prosty z kropką"] # 0x299d - - "⦞": [t: "kąt z s wewnątrz"] # 0x299e - - "⦟": [t: "akut kąt"] # 0x299f - - "⦠": [t: "kąt sferyczny otwarty w lewo"] # 0x29a0 - - "⦡": [t: "kąt sferyczny otwarty w górę"] # 0x29a1 - - "⦢": [t: "odwrócony kąt"] # 0x29a2 - - "⦣": [t: "kąt odwrócony"] # 0x29a3 - - "⦤": [t: "kąt z podkreśleniem"] # 0x29a4 - - "⦥": [t: "kąt odwrócony z podkreśleniem"] # 0x29a5 - - "⦦": [t: "kąt ukośny otwarty w górę"] # 0x29a6 - - "⦧": [t: "kąt ukośny otwarty w dół"] # 0x29a7 - - "⦨": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w górę i w prawo"] # 0x29a8 - - "⦩": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w górę i w lewo"] # 0x29a9 - - "⦪": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w dół i w prawo"] # 0x29aa - - "⦫": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w dół i w lewo"] # 0x29ab - - "⦬": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w prawo i w górę"] # 0x29ac - - "⦭": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w lewo i w górę"] # 0x29ad - - "⦮": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w prawo i w dół"] # 0x29ae - - "⦯": [t: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w lewo i w dół"] # 0x29af - - "⦰": [t: "odwrócony zbiór pusty"] # 0x29b0 - - "⦱": [t: "zbiór pusty z kreską nad"] # 0x29b1 - - "⦲": [t: "zbiór pusty z małym okręgiem nad"] # 0x29b2 - - "⦳": [t: "zbiór pusty ze strzałką w prawo nad"] # 0x29b3 - - "⦴": [t: "zbiór pusty ze strzałką w lewo nad"] # 0x29b4 - - "⦵": [t: "okrąg z kreską poziomą"] # 0x29b5 - - "⦶": [t: "pionowa kreska w kółku"] # 0x29b6 - - "⦷": [t: "w kółku równoległe"] # 0x29b7 - - "⦸": [t: "ukośnik odwrotny w kółku"] # 0x29b8 - - "⦹": [t: "w kółku prostopadłe"] # 0x29b9 - - "⦺": [t: "okrąg podzielony kreską poziomą, z górną połową podzieloną kreską pionową"] # 0x29ba - - "⦻": [t: "okrąg z nałożonym X"] # 0x29bb - - "⦼": [t: "znak dzielenia w kółku obrócony przeciwnie do ruchu wskazówek zegara"] # 0x29bc - - "⦽": [t: "strzałka w górę przez okrąg"] # 0x29bd - - "⦾": [t: "w kółku biały punkt"] # 0x29be - - "⦿": [t: "w kółku punkt"] # 0x29bf - - "⧀": [t: "w kółku mniejsze niż"] # 0x29c0 - - "⧁": [t: "w kółku większe niż"] # 0x29c1 - - "⧂": [t: "okrąg z małym okręgiem po prawej"] # 0x29c2 - - "⧃": [t: "okrąg z dwiema poziomymi kreskami po prawej"] # 0x29c3 - - "⧄": [t: "kwadrat z ukośnikiem wznoszącym"] # 0x29c4 - - "⧅": [t: "kwadrat z ukośnikiem opadającym"] # 0x29c5 - - "⧆": [t: "do kwadratu gwiazdka"] # 0x29c6 - - "⧇": [t: "do kwadratu mały okrąg"] # 0x29c7 - - "⧈": [t: "do kwadratu kwadrat"] # 0x29c8 - - "⧉": [t: "dwa połączone kwadraty"] # 0x29c9 - - "⧊": [t: "trójkąt z kropką nad"] # 0x29ca - - "⧋": [t: "trójkąt z podkreśleniem"] # 0x29cb - - "⧌": [t: "s w trójkąt"] # 0x29cc - - "⧍": [t: "trójkąt z szeryfami u dołu"] # 0x29cd - - "⧎": [t: "prawy trójkąt nad lewy trójkąt"] # 0x29ce - - "⧏": [t: "lewy trójkąt obok pionowej kreski"] # 0x29cf - - "⧐": [t: "pionowa kreska obok prawego trójkąta"] # 0x29d0 - - "⧑": [t: "kokarda z lewą połową czarną"] # 0x29d1 - - "⧒": [t: "kokarda z prawą połową czarną"] # 0x29d2 - - "⧓": [t: "czarna kokarda"] # 0x29d3 - - "⧔": [t: "znak mnożenia z lewą połową czarną"] # 0x29d4 - - "⧕": [t: "znak mnożenia z prawą połową czarną"] # 0x29d5 - - "⧖": [t: "biały klepsydra"] # 0x29d6 - - "⧗": [t: "czarny klepsydra"] # 0x29d7 - - "⧘": [t: "lewy falisty ogranicznik"] # 0x29d8 - - "⧙": [t: "prawy falisty ogranicznik"] # 0x29d9 - - "⧚": [t: "lewy podwójny falisty ogranicznik"] # 0x29da - - "⧛": [t: "prawy podwójny falisty ogranicznik"] # 0x29db - - "⧜": [t: "niepełna nieskończoność"] # 0x29dc - - "⧝": [t: "wiązanie nad nieskończonością"] # 0x29dd - - "⧞": [t: "zanegowana nieskończoność z kreską pionową"] # 0x29de - - "⧟": [t: "podwójnie zakończona strzałka mapująca"] # 0x29df - - "⧠": [t: "kwadrat z konturowym obrysem"] # 0x29e0 - - "⧡": [t: "wzrasta jak"] # 0x29e1 - - "⧢": [t: "iloczyn przetasowania"] # 0x29e2 - - "⧣": [t: "znak równości i ukośne równoległe"] # 0x29e3 - - "⧤": [t: "znak równości i ukośne równoległe z tyldą nad"] # 0x29e4 - - "⧥": [t: "identyczne i ukośne równoległe"] # 0x29e5 - - "⧦": [t: "równoliczne"] # 0x29e6 - - "⧧": [t: "termodynamiczny"] # 0x29e7 - - "⧨": [t: "trójkąt skierowany w dół z lewą połową czarną"] # 0x29e8 - - "⧩": [t: "trójkąt skierowany w dół z prawą połową czarną"] # 0x29e9 - - "⧪": [t: "czarny romb ze strzałką w dół"] # 0x29ea - - "⧫": [t: "czarny romb"] # 0x29eb - - "⧬": [t: "białe koło ze strzałką w dół"] # 0x29ec - - "⧭": [t: "czarne koło ze strzałką w dół"] # 0x29ed - - "⧮": [t: "biały kwadrat z przekreśleniem błędu"] # 0x29ee - - "⧯": [t: "czarny kwadrat z przekreśleniem błędu"] # 0x29ef - - "⧰": [t: "biały romb z przekreśleniem błędu"] # 0x29f0 - - "⧱": [t: "czarny romb z przekreśleniem błędu"] # 0x29f1 - - "⧲": [t: "białe koło z przekreśleniem błędu"] # 0x29f2 - - "⧳": [t: "czarne koło z przekreśleniem błędu"] # 0x29f3 - - "⧴": [t: "opóźniona reguła"] # 0x29f4 - - "⧵": [t: "operator ukośnika odwrotnego"] # 0x29f5 - - "⧶": [t: "ukośnik z kreską nad"] # 0x29f6 - - "⧷": [t: "ukośnik odwrotny z poziomą kreską"] # 0x29f7 - - "⧸": [t: "duży ukośnik"] # 0x29f8 - - "⧹": [t: "duży ukośnik odwrotny"] # 0x29f9 - - "⧺": [t: "podwójny plus"] # 0x29fa - - "⧻": [t: "potrójny plus"] # 0x29fb - - "⧼": [t: "lewy zakrzywiony nawias kątowy"] # 0x29fc - - "⧽": [t: "prawy zakrzywiony nawias kątowy"] # 0x29fd - - "⧾": [t: "maleńki"] # 0x29fe - - "⧿": [t: "mini"] # 0x29ff - - "⨀": [t: "operator kropka w kółku"] # 0x2a00 - - "⨁": [t: "operator plus w kółku"] # 0x2a01 - - "⨂": [t: "operator razy w kółku"] # 0x2a02 - - "⨃": [t: "operator sumy zbiorów z kropką"] # 0x2a03 - - "⨄": [t: "operator sumy zbiorów z plusem"] # 0x2a04 - - "⨅": [t: "operator kwadratowej części wspólnej"] # 0x2a05 - - "⨆": [t: "operator kwadratowej sumy zbiorów"] # 0x2a06 - - "⨇": [t: "operator podwójnej koniunkcji logicznej"] # 0x2a07 - - "⨈": [t: "dwa logiczne lub operator"] # 0x2a08 - - "⨉": [t: "razy operator"] # 0x2a09 - - "⨊": [t: "suma modulo dwa"] # 0x2a0a - - "⨋": [t: "suma z całką"] # 0x2a0b - - "⨌": [t: "operator poczwórnej całki"] # 0x2a0c - - "⨍": [t: "całka części skończonej"] # 0x2a0d - - "⨎": [t: "całka z podwójnym przekreśleniem"] # 0x2a0e - - "⨏": [t: "całka uśredniona z ukośnikiem"] # 0x2a0f - - "⨐": [t: "funkcja cyrkulacji"] # 0x2a10 - - "⨑": [t: "całka przeciwna do ruchu wskazówek zegara"] # 0x2a11 - - "⨒": [t: "całka liniowa po prostokątnej ścieżce wokół bieguna"] # 0x2a12 - - "⨓": [t: "całka liniowa po półokrągłej ścieżce wokół bieguna"] # 0x2a13 - - "⨔": [t: "całka liniowa bez pola"] # 0x2a14 - - "⨕": [t: "operator całki wokół punktu"] # 0x2a15 - - "⨖": [t: "operator całki kwaternionowej"] # 0x2a16 - - "⨗": [t: "całka ze strzałką w lewo z haczykiem"] # 0x2a17 - - "⨘": [t: "całka ze znakiem razy"] # 0x2a18 - - "⨙": [t: "całka z częścią wspólną"] # 0x2a19 - - "⨚": [t: "całka z sumą zbiorów"] # 0x2a1a - - "⨛": [t: "całka z kreską nad"] # 0x2a1b - - "⨜": [t: "całka z podkreśleniem"] # 0x2a1c - - "⨝": [t: "złączenie"] # 0x2a1d - - "⨞": [t: "duży lewy trójkąt operator"] # 0x2a1e - - "⨟": [t: "składanie schematów w notacji Z"] # 0x2a1f - - "⨠": [t: "potok schematów w notacji Z"] # 0x2a20 - - "⨡": [t: "rzutowanie schematów w notacji Z"] # 0x2a21 - - "⨢": [t: "znak plus z okręgiem nad"] # 0x2a22 - - "⨣": [t: "znak plus z daszkiem nad"] # 0x2a23 - - "⨤": [t: "znak plus z tyldą nad"] # 0x2a24 - - "⨥": [t: "znak plus z kropką pod"] # 0x2a25 - - "⨦": [t: "znak plus z tyldą pod"] # 0x2a26 - - "⨧": [t: "znak plus z indeksem dolnym dwa"] # 0x2a27 - - "⨨": [t: "znak plus z czarnym trójkątem"] # 0x2a28 - - "⨩": [t: "znak minus z przecinkiem nad"] # 0x2a29 - - "⨪": [t: "znak minus z kropką pod"] # 0x2a2a - - "⨫": [t: "znak minus z kropkami opadającymi"] # 0x2a2b - - "⨬": [t: "znak minus z kropkami wznoszącymi"] # 0x2a2c - - "⨭": [t: "znak plus w lewej połówce okręgu"] # 0x2a2d - - "⨮": [t: "znak plus w prawej połówce okręgu"] # 0x2a2e + - T: "otwórz nadzbiór" + - "⟅": [T: "lewy ogranicznik workowy w kształcie S"] # 0x27c5 + - "⟆": [T: "prawy ogranicznik workowy w kształcie S"] # 0x27c6 + - "⟇": [T: "lub z kropką wewnątrz"] # 0x27c7 + - "⟈": [T: "odwrotny ukośnik poprzedzający podzbiór"] # 0x27c8 + - "⟉": [T: "nadzbiór poprzedzający ukośnik"] # 0x27c9 + - "⟊": [T: "pionowa kreska z poziomą kreską"] # 0x27ca + - "⟋": [T: "matematyczny ukośnik wznoszący"] # 0x27cb + - "⟌": [T: "dzielenie pisemne"] # 0x27cc + - "⟍": [T: "matematyczny ukośnik opadający"] # 0x27cd + - "⟎": [T: "kwadratowa koniunkcja logiczna"] # 0x27ce + - "⟏": [T: "do kwadratu logiczne lub"] # 0x27cf + - "⟐": [T: "biały romb z wyśrodkowaną kropką"] # 0x27d0 + - "⟑": [T: "i z kropką"] # 0x27d1 + - "⟒": [T: "należy do z otwarciem u góry"] # 0x27d2 + - "⟓": [T: "prawy dolny narożnik z kropką"] # 0x27d3 + - "⟔": [T: "górny lewy narożnik z kropką"] # 0x27d4 + - "⟕": [T: "lewe złączenie zewnętrzne"] # 0x27d5 + - "⟖": [T: "prawe złączenie zewnętrzne"] # 0x27d6 + - "⟗": [T: "pełne złączenie zewnętrzne"] # 0x27d7 + - "⟘": [T: "duży górny znacznik"] # 0x27d8 + - "⟙": [T: "duży dolny znacznik"] # 0x27d9 + - "⟚": [T: "lewy i prawy podwójny znacznik dedukcji"] # 0x27da + - "⟛": [T: "lewy i prawy znacznik"] # 0x27db + - "⟜": [T: "lewa multimapa"] # 0x27dc + - "⟝": [T: "długi prawy znacznik"] # 0x27dd + - "⟞": [T: "długi lewy znacznik"] # 0x27de + - "⟟": [T: "górny znacznik z okręgiem nad"] # 0x27df + - "⟠": [T: "romb podzielony poziomą kreską"] # 0x27e0 + - "⟡": [T: "biały romb o wklęsłych bokach"] # 0x27e1 + - "⟢": [T: "biały romb o wklęsłych bokach z lewym haczykiem"] # 0x27e2 + - "⟣": [T: "biały romb o wklęsłych bokach z prawym haczykiem"] # 0x27e3 + - "⟤": [T: "biały kwadrat z lewym haczykiem"] # 0x27e4 + - "⟥": [T: "biały kwadrat z prawym haczykiem"] # 0x27e5 + - "⟦": [T: "lewy biały nawias kwadratowy"] # 0x27e6 + - "⟧": [T: "prawy biały nawias kwadratowy"] # 0x27e7 + - "⟨": [T: "lewy nawias kątowy"] # 0x27e8 + - "⟩": [T: "prawy nawias kątowy"] # 0x27e9 + - "⟪": [T: "lewy podwójny nawias kątowy"] # 0x27ea + - "⟫": [T: "prawy podwójny nawias kątowy"] # 0x27eb + - "⟬": [T: "lewy biały nawias skorupowy"] # 0x27ec + - "⟭": [T: "prawy biały nawias skorupowy"] # 0x27ed + - "⟮": [T: "lewy spłaszczony nawias"] # 0x27ee + - "⟯": [T: "prawy spłaszczony nawias"] # 0x27ef + - "⟰": [T: "poczwórna strzałka w górę"] # 0x27f0 + - "⟱": [T: "poczwórna strzałka w dół"] # 0x27f1 + - "⟲": [T: "okrężna strzałka z przerwą przeciwnie do ruchu wskazówek zegara"] # 0x27f2 + - "⟳": [T: "okrężna strzałka z przerwą zgodnie z ruchem wskazówek zegara"] # 0x27f3 + - "⟴": [T: "strzałka w prawo z plusem w kółku"] # 0x27f4 + - "⟵": [T: "długa strzałka w lewo"] # 0x27f5 + - "⟶": [T: "długa strzałka w prawo"] # 0x27f6 + - "⟷": [T: "długa strzałka w lewo i w prawo"] # 0x27f7 + - "⟸": [T: "długa podwójna strzałka w lewo"] # 0x27f8 + - "⟹": [T: "implikuje"] # 0x27f9 + - "⟺": [T: "wtedy i tylko wtedy"] # 0x27fa + - "⟻": [T: "długa strzałka w lewo od kreski"] # 0x27fb + - "⟼": [T: "długa strzałka w prawo od kreski"] # 0x27fc + - "⟽": [T: "długa podwójna strzałka w lewo od kreski"] # 0x27fd + - "⟾": [T: "długa podwójna strzałka w prawo od kreski"] # 0x27fe + - "⟿": [T: "długa falista strzałka w prawo"] # 0x27ff + - "⤀": [T: "strzałka w prawo z dwoma grotami i pionowym przekreśleniem"] # 0x2900 + - "⤁": [T: "strzałka w prawo z dwoma grotami i podwójnym pionowym przekreśleniem"] # 0x2901 + - "⤂": [T: "podwójna strzałka w lewo z pionową kreską"] # 0x2902 + - "⤃": [T: "podwójna strzałka w prawo z pionową kreską"] # 0x2903 + - "⤄": [T: "podwójna strzałka w lewo i w prawo z pionową kreską"] # 0x2904 + - "⤅": [T: "strzałka w prawo z dwoma grotami od kreski"] # 0x2905 + - "⤆": [T: "podwójna strzałka w lewo od kreski"] # 0x2906 + - "⤇": [T: "podwójna strzałka w prawo od kreski"] # 0x2907 + - "⤈": [T: "strzałka w dół z poziomą kreską"] # 0x2908 + - "⤉": [T: "strzałka w górę z poziomą kreską"] # 0x2909 + - "⤊": [T: "górny potrójny strzałka"] # 0x290a + - "⤋": [T: "dolny potrójny strzałka"] # 0x290b + - "⤌": [T: "lewy podwójny kreska strzałka"] # 0x290c + - "⤍": [T: "prawy podwójny kreska strzałka"] # 0x290d + - "⤎": [T: "lewy potrójny kreska strzałka"] # 0x290e + - "⤏": [T: "prawy potrójny kreska strzałka"] # 0x290f + - "⤐": [T: "strzałka w prawo z dwoma grotami i potrójną kreską"] # 0x2910 + - "⤑": [T: "strzałka w prawo z kropkowanym trzonem"] # 0x2911 + - "⤒": [T: "strzałka w górę do kreski"] # 0x2912 + - "⤓": [T: "strzałka w dół do kreski"] # 0x2913 + - "⤔": [T: "strzałka w prawo z ogonem i pionową kreską"] # 0x2914 + - "⤕": [T: "strzałka w prawo z ogonem i podwójną pionową kreską"] # 0x2915 + - "⤖": [T: "strzałka w prawo z dwoma grotami i ogonem"] # 0x2916 + - "⤗": [T: "strzałka w prawo z dwoma grotami, ogonem i pionowym przekreśleniem"] # 0x2917 + - "⤘": [T: "strzałka w prawo z dwoma grotami, ogonem i podwójnym pionowym przekreśleniem"] # 0x2918 + - "⤙": [T: "strzałka w lewo ogon"] # 0x2919 + - "⤚": [T: "strzałka w prawo ogon"] # 0x291a + - "⤛": [T: "lewy podwójna strzałka ogon"] # 0x291b + - "⤜": [T: "prawy podwójna strzałka ogon"] # 0x291c + - "⤝": [T: "strzałka w lewo do wypełnionego rombu"] # 0x291d + - "⤞": [T: "strzałka w prawo do wypełnionego rombu"] # 0x291e + - "⤟": [T: "strzałka w lewo od kreski do wypełnionego rombu"] # 0x291f + - "⤠": [T: "strzałka w prawo od kreski do wypełnionego rombu"] # 0x2920 + - "⤡": [T: "strzałka północno-zachodnia i południowo-wschodnia"] # 0x2921 + - "⤢": [T: "strzałka północno-wschodnia i południowo-zachodnia"] # 0x2922 + - "⤣": [T: "strzałka północno-zachodnia z hakiem"] # 0x2923 + - "⤤": [T: "strzałka północno-wschodnia z hakiem"] # 0x2924 + - "⤥": [T: "strzałka południowo-wschodnia z hakiem"] # 0x2925 + - "⤦": [T: "strzałka południowo-zachodnia z hakiem"] # 0x2926 + - "⤧": [T: "strzałka północno-zachodnia i strzałka północno-wschodnia"] # 0x2927 + - "⤨": [T: "strzałka północno-wschodnia i strzałka południowo-wschodnia"] # 0x2928 + - "⤩": [T: "strzałka południowo-wschodnia i strzałka południowo-zachodnia"] # 0x2929 + - "⤪": [T: "strzałka południowo-zachodnia i strzałka północno-zachodnia"] # 0x292a + - "⤫": [T: "ukośna wznosząca przecinająca ukośną opadającą"] # 0x292b + - "⤬": [T: "ukośna opadająca przecinająca ukośną wznoszącą"] # 0x292c + - "⤭": [T: "strzałka południowo-wschodnia przecinająca strzałkę północno-wschodnią"] # 0x292d + - "⤮": [T: "strzałka północno-wschodnia przecinająca strzałkę południowo-wschodnią"] # 0x292e + - "⤯": [T: "ukośna opadająca przecinająca strzałkę północno-wschodnią"] # 0x292f + - "⤰": [T: "ukośna wznosząca przecinająca strzałkę południowo-wschodnią"] # 0x2930 + - "⤱": [T: "strzałka północno-wschodnia przecinająca strzałkę północno-zachodnią"] # 0x2931 + - "⤲": [T: "strzałka północno-zachodnia przecinająca strzałkę północno-wschodnią"] # 0x2932 + - "⤳": [T: "falista strzałka skierowana bezpośrednio w prawo"] # 0x2933 + - "⤴": [T: "strzałka skierowana w prawo, potem zakrzywiona w górę"] # 0x2934 + - "⤵": [T: "strzałka skierowana w prawo, potem zakrzywiona w dół"] # 0x2935 + - "⤶": [T: "strzałka skierowana w dół, potem zakrzywiona w lewo"] # 0x2936 + - "⤷": [T: "strzałka skierowana w dół, potem zakrzywiona w prawo"] # 0x2937 + - "⤸": [T: "prawostronna strzałka łukowa zgodna z ruchem wskazówek zegara"] # 0x2938 + - "⤹": [T: "lewostronna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x2939 + - "⤺": [T: "górna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x293a + - "⤻": [T: "dolna strzałka łukowa przeciwna do ruchu wskazówek zegara"] # 0x293b + - "⤼": [T: "górna strzałka łukowa zgodna z ruchem wskazówek zegara z minusem"] # 0x293c + - "⤽": [T: "górna strzałka łukowa przeciwna do ruchu wskazówek zegara z plusem"] # 0x293d + - "⤾": [T: "dolna prawa strzałka półokrągła zgodna z ruchem wskazówek zegara"] # 0x293e + - "⤿": [T: "dolna lewa strzałka półokrągła przeciwna do ruchu wskazówek zegara"] # 0x293f + - "⥀": [T: "zamknięta strzałka okrężna przeciwna do ruchu wskazówek zegara"] # 0x2940 + - "⥁": [T: "zamknięta strzałka okrężna zgodna z ruchem wskazówek zegara"] # 0x2941 + - "⥂": [T: "strzałka w prawo nad krótką strzałką w lewo"] # 0x2942 + - "⥃": [T: "strzałka w lewo nad krótką strzałką w prawo"] # 0x2943 + - "⥄": [T: "krótka strzałka w prawo nad strzałką w lewo"] # 0x2944 + - "⥅": [T: "strzałka w prawo z plusem pod spodem"] # 0x2945 + - "⥆": [T: "strzałka w lewo z plusem pod spodem"] # 0x2946 + - "⥇": [T: "strzałka w prawo przez X"] # 0x2947 + - "⥈": [T: "strzałka w lewo i w prawo przez okrąg"] # 0x2948 + - "⥉": [T: "strzałka w górę z dwoma grotami od okręgu"] # 0x2949 + - "⥊": [T: "lewy grot górny prawy grot dolny harpun"] # 0x294a + - "⥋": [T: "lewy grot dolny prawy grot górny harpun"] # 0x294b + - "⥌": [T: "górny grot prawy dolny grot lewy harpun"] # 0x294c + - "⥍": [T: "górny grot lewy dolny grot prawy harpun"] # 0x294d + - "⥎": [T: "lewy grot górny prawy grot górny harpun"] # 0x294e + - "⥏": [T: "górny grot prawy dolny grot prawy harpun"] # 0x294f + - "⥐": [T: "lewy grot dolny prawy grot dolny harpun"] # 0x2950 + - "⥑": [T: "górny grot lewy dolny grot lewy harpun"] # 0x2951 + - "⥒": [T: "lewy harpun z grotem górnym do kreski"] # 0x2952 + - "⥓": [T: "prawy harpun z grotem górnym do kreski"] # 0x2953 + - "⥔": [T: "górny harpun z grotem prawym do kreski"] # 0x2954 + - "⥕": [T: "dolny harpun z grotem prawym do kreski"] # 0x2955 + - "⥖": [T: "lewy harpun z grotem dolnym do kreski"] # 0x2956 + - "⥗": [T: "prawy harpun z grotem dolnym do kreski"] # 0x2957 + - "⥘": [T: "górny harpun z grotem lewym do kreski"] # 0x2958 + - "⥙": [T: "dolny harpun z grotem lewym do kreski"] # 0x2959 + - "⥚": [T: "lewy harpun z grotem górnym od kreski"] # 0x295a + - "⥛": [T: "prawy harpun z grotem górnym od kreski"] # 0x295b + - "⥜": [T: "górny harpun z grotem prawym od kreski"] # 0x295c + - "⥝": [T: "dolny harpun z grotem prawym od kreski"] # 0x295d + - "⥞": [T: "lewy harpun z grotem dolnym od kreski"] # 0x295e + - "⥟": [T: "prawy harpun z grotem dolnym od kreski"] # 0x295f + - "⥠": [T: "górny harpun z grotem lewym od kreski"] # 0x2960 + - "⥡": [T: "dolny harpun z grotem lewym od kreski"] # 0x2961 + - "⥢": [T: "lewy harpun z grotem górnym nad lewy harpun z grotem dolnym"] # 0x2962 + - "⥣": [T: "górny harpun z grotem w lewo obok górnego harpuna z grotem w prawo"] # 0x2963 + - "⥤": [T: "prawy harpun z grotem górnym nad prawy harpun z grotem dolnym"] # 0x2964 + - "⥥": [T: "dolny harpun z grotem w lewo obok dolnego harpuna z grotem w prawo"] # 0x2965 + - "⥦": [T: "lewy harpun z grotem górnym nad prawy harpun z grotem górnym"] # 0x2966 + - "⥧": [T: "lewy harpun z grotem dolnym nad prawy harpun z grotem dolnym"] # 0x2967 + - "⥨": [T: "prawy harpun z grotem górnym nad lewy harpun z grotem górnym"] # 0x2968 + - "⥩": [T: "prawy harpun z grotem dolnym nad lewy harpun z grotem dolnym"] # 0x2969 + - "⥪": [T: "lewy harpun z grotem górnym nad długą kreską"] # 0x296a + - "⥫": [T: "lewy harpun z grotem dolnym pod długą kreską"] # 0x296b + - "⥬": [T: "prawy harpun z grotem górnym nad długą kreską"] # 0x296c + - "⥭": [T: "prawy harpun z grotem dolnym pod długą kreską"] # 0x296d + - "⥮": [T: "górny harpun z grotem w lewo obok dolnego harpuna z grotem w prawo"] # 0x296e + - "⥯": [T: "dolny harpun z grotem w lewo obok górnego harpuna z grotem w prawo"] # 0x296f + - "⥰": [T: "podwójna strzałka w prawo z zaokrąglonym grotem"] # 0x2970 + - "⥱": [T: "równa się nad strzałka w prawo"] # 0x2971 + - "⥲": [T: "operator tyldy nad strzałką w prawo"] # 0x2972 + - "⥳": [T: "strzałka w lewo nad operatorem tyldy"] # 0x2973 + - "⥴": [T: "strzałka w prawo nad operatorem tyldy"] # 0x2974 + - "⥵": [T: "strzałka w prawo nad znakiem przybliżonej równości"] # 0x2975 + - "⥶": [T: "mniejsze niż nad strzałka w lewo"] # 0x2976 + - "⥷": [T: "strzałka w lewo przez znak mniejsze niż"] # 0x2977 + - "⥸": [T: "większe niż nad strzałka w prawo"] # 0x2978 + - "⥹": [T: "podzbiór nad strzałka w prawo"] # 0x2979 + - "⥺": [T: "strzałka w lewo przez znak podzbioru"] # 0x297a + - "⥻": [T: "nadzbiór nad strzałka w lewo"] # 0x297b + - "⥼": [T: "lewy rybi ogon"] # 0x297c + - "⥽": [T: "prawy rybi ogon"] # 0x297d + - "⥾": [T: "górny rybi ogon"] # 0x297e + - "⥿": [T: "dolny rybi ogon"] # 0x297f + - "⦀": [T: "potrójna pionowa kreska jako ogranicznik"] # 0x2980 + - "⦁": [T: "punkt w notacji Z"] # 0x2981 + - "⦂": [T: "dwukropek typu w notacji Z"] # 0x2982 + - "⦃": [T: "lewy biały nawias klamrowy"] # 0x2983 + - "⦄": [T: "prawy biały nawias klamrowy"] # 0x2984 + - "⦅": [T: "lewy biały nawias"] # 0x2985 + - "⦆": [T: "prawy biały nawias"] # 0x2986 + - "⦇": [T: "lewy nawias kwadratowy obrazu w notacji Z"] # 0x2987 + - "⦈": [T: "prawy nawias kwadratowy obrazu w notacji Z"] # 0x2988 + - "⦉": [T: "lewy nawias kwadratowy wiązania w notacji Z"] # 0x2989 + - "⦊": [T: "prawy nawias kwadratowy wiązania w notacji Z"] # 0x298a + - "⦋": [T: "lewy nawias kwadratowy z podkreśleniem"] # 0x298b + - "⦌": [T: "prawy nawias kwadratowy z podkreśleniem"] # 0x298c + - "⦍": [T: "lewy nawias kwadratowy z haczykiem w górnym rogu"] # 0x298d + - "⦎": [T: "prawy nawias kwadratowy z haczykiem w dolnym rogu"] # 0x298e + - "⦏": [T: "lewy nawias kwadratowy z haczykiem w dolnym rogu"] # 0x298f + - "⦐": [T: "prawy nawias kwadratowy z haczykiem w górnym rogu"] # 0x2990 + - "⦑": [T: "lewy kąt nawias kwadratowy z kropką"] # 0x2991 + - "⦒": [T: "prawy nawias kątowy z kropką"] # 0x2992 + - "⦓": [T: "lewy łuk mniejsze niż nawias kwadratowy"] # 0x2993 + - "⦔": [T: "prawy łuk większe niż nawias kwadratowy"] # 0x2994 + - "⦕": [T: "podwójny lewy łuk większe niż nawias kwadratowy"] # 0x2995 + - "⦖": [T: "podwójny prawy łuk mniejsze niż nawias kwadratowy"] # 0x2996 + - "⦗": [T: "lewy czarny nawias skorupowy"] # 0x2997 + - "⦘": [T: "prawy czarny nawias skorupowy"] # 0x2998 + - "⦙": [T: "kropkowany ogranicznik"] # 0x2999 + - "⦚": [T: "pionowa linia zygzakowata"] # 0x299a + - "⦛": [T: "kąt mierzony otwarty w lewo"] # 0x299b + - "⦜": [T: "wariant kąta prostego z kwadratem"] # 0x299c + - "⦝": [T: "mierzony kąt prosty z kropką"] # 0x299d + - "⦞": [T: "kąt z s wewnątrz"] # 0x299e + - "⦟": [T: "akut kąt"] # 0x299f + - "⦠": [T: "kąt sferyczny otwarty w lewo"] # 0x29a0 + - "⦡": [T: "kąt sferyczny otwarty w górę"] # 0x29a1 + - "⦢": [T: "odwrócony kąt"] # 0x29a2 + - "⦣": [T: "kąt odwrócony"] # 0x29a3 + - "⦤": [T: "kąt z podkreśleniem"] # 0x29a4 + - "⦥": [T: "kąt odwrócony z podkreśleniem"] # 0x29a5 + - "⦦": [T: "kąt ukośny otwarty w górę"] # 0x29a6 + - "⦧": [T: "kąt ukośny otwarty w dół"] # 0x29a7 + - "⦨": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w górę i w prawo"] # 0x29a8 + - "⦩": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w górę i w lewo"] # 0x29a9 + - "⦪": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w dół i w prawo"] # 0x29aa + - "⦫": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w dół i w lewo"] # 0x29ab + - "⦬": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w prawo i w górę"] # 0x29ac + - "⦭": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w lewo i w górę"] # 0x29ad + - "⦮": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w prawo i w dół"] # 0x29ae + - "⦯": [T: "kąt mierzony z otwartym ramieniem zakończonym strzałką skierowaną w lewo i w dół"] # 0x29af + - "⦰": [T: "odwrócony zbiór pusty"] # 0x29b0 + - "⦱": [T: "zbiór pusty z kreską nad"] # 0x29b1 + - "⦲": [T: "zbiór pusty z małym okręgiem nad"] # 0x29b2 + - "⦳": [T: "zbiór pusty ze strzałką w prawo nad"] # 0x29b3 + - "⦴": [T: "zbiór pusty ze strzałką w lewo nad"] # 0x29b4 + - "⦵": [T: "okrąg z kreską poziomą"] # 0x29b5 + - "⦶": [T: "pionowa kreska w kółku"] # 0x29b6 + - "⦷": [T: "w kółku równoległe"] # 0x29b7 + - "⦸": [T: "ukośnik odwrotny w kółku"] # 0x29b8 + - "⦹": [T: "w kółku prostopadłe"] # 0x29b9 + - "⦺": [T: "okrąg podzielony kreską poziomą, z górną połową podzieloną kreską pionową"] # 0x29ba + - "⦻": [T: "okrąg z nałożonym X"] # 0x29bb + - "⦼": [T: "znak dzielenia w kółku obrócony przeciwnie do ruchu wskazówek zegara"] # 0x29bc + - "⦽": [T: "strzałka w górę przez okrąg"] # 0x29bd + - "⦾": [T: "w kółku biały punkt"] # 0x29be + - "⦿": [T: "w kółku punkt"] # 0x29bf + - "⧀": [T: "w kółku mniejsze niż"] # 0x29c0 + - "⧁": [T: "w kółku większe niż"] # 0x29c1 + - "⧂": [T: "okrąg z małym okręgiem po prawej"] # 0x29c2 + - "⧃": [T: "okrąg z dwiema poziomymi kreskami po prawej"] # 0x29c3 + - "⧄": [T: "kwadrat z ukośnikiem wznoszącym"] # 0x29c4 + - "⧅": [T: "kwadrat z ukośnikiem opadającym"] # 0x29c5 + - "⧆": [T: "do kwadratu gwiazdka"] # 0x29c6 + - "⧇": [T: "do kwadratu mały okrąg"] # 0x29c7 + - "⧈": [T: "do kwadratu kwadrat"] # 0x29c8 + - "⧉": [T: "dwa połączone kwadraty"] # 0x29c9 + - "⧊": [T: "trójkąt z kropką nad"] # 0x29ca + - "⧋": [T: "trójkąt z podkreśleniem"] # 0x29cb + - "⧌": [T: "s w trójkąt"] # 0x29cc + - "⧍": [T: "trójkąt z szeryfami u dołu"] # 0x29cd + - "⧎": [T: "prawy trójkąt nad lewy trójkąt"] # 0x29ce + - "⧏": [T: "lewy trójkąt obok pionowej kreski"] # 0x29cf + - "⧐": [T: "pionowa kreska obok prawego trójkąta"] # 0x29d0 + - "⧑": [T: "kokarda z lewą połową czarną"] # 0x29d1 + - "⧒": [T: "kokarda z prawą połową czarną"] # 0x29d2 + - "⧓": [T: "czarna kokarda"] # 0x29d3 + - "⧔": [T: "znak mnożenia z lewą połową czarną"] # 0x29d4 + - "⧕": [T: "znak mnożenia z prawą połową czarną"] # 0x29d5 + - "⧖": [T: "biały klepsydra"] # 0x29d6 + - "⧗": [T: "czarny klepsydra"] # 0x29d7 + - "⧘": [T: "lewy falisty ogranicznik"] # 0x29d8 + - "⧙": [T: "prawy falisty ogranicznik"] # 0x29d9 + - "⧚": [T: "lewy podwójny falisty ogranicznik"] # 0x29da + - "⧛": [T: "prawy podwójny falisty ogranicznik"] # 0x29db + - "⧜": [T: "niepełna nieskończoność"] # 0x29dc + - "⧝": [T: "wiązanie nad nieskończonością"] # 0x29dd + - "⧞": [T: "zanegowana nieskończoność z kreską pionową"] # 0x29de + - "⧟": [T: "podwójnie zakończona strzałka mapująca"] # 0x29df + - "⧠": [T: "kwadrat z konturowym obrysem"] # 0x29e0 + - "⧡": [T: "wzrasta jak"] # 0x29e1 + - "⧢": [T: "iloczyn przetasowania"] # 0x29e2 + - "⧣": [T: "znak równości i ukośne równoległe"] # 0x29e3 + - "⧤": [T: "znak równości i ukośne równoległe z tyldą nad"] # 0x29e4 + - "⧥": [T: "identyczne i ukośne równoległe"] # 0x29e5 + - "⧦": [T: "równoliczne"] # 0x29e6 + - "⧧": [T: "termodynamiczny"] # 0x29e7 + - "⧨": [T: "trójkąt skierowany w dół z lewą połową czarną"] # 0x29e8 + - "⧩": [T: "trójkąt skierowany w dół z prawą połową czarną"] # 0x29e9 + - "⧪": [T: "czarny romb ze strzałką w dół"] # 0x29ea + - "⧫": [T: "czarny romb"] # 0x29eb + - "⧬": [T: "białe koło ze strzałką w dół"] # 0x29ec + - "⧭": [T: "czarne koło ze strzałką w dół"] # 0x29ed + - "⧮": [T: "biały kwadrat z przekreśleniem błędu"] # 0x29ee + - "⧯": [T: "czarny kwadrat z przekreśleniem błędu"] # 0x29ef + - "⧰": [T: "biały romb z przekreśleniem błędu"] # 0x29f0 + - "⧱": [T: "czarny romb z przekreśleniem błędu"] # 0x29f1 + - "⧲": [T: "białe koło z przekreśleniem błędu"] # 0x29f2 + - "⧳": [T: "czarne koło z przekreśleniem błędu"] # 0x29f3 + - "⧴": [T: "opóźniona reguła"] # 0x29f4 + - "⧵": [T: "operator ukośnika odwrotnego"] # 0x29f5 + - "⧶": [T: "ukośnik z kreską nad"] # 0x29f6 + - "⧷": [T: "ukośnik odwrotny z poziomą kreską"] # 0x29f7 + - "⧸": [T: "duży ukośnik"] # 0x29f8 + - "⧹": [T: "duży ukośnik odwrotny"] # 0x29f9 + - "⧺": [T: "podwójny plus"] # 0x29fa + - "⧻": [T: "potrójny plus"] # 0x29fb + - "⧼": [T: "lewy zakrzywiony nawias kątowy"] # 0x29fc + - "⧽": [T: "prawy zakrzywiony nawias kątowy"] # 0x29fd + - "⧾": [T: "maleńki"] # 0x29fe + - "⧿": [T: "mini"] # 0x29ff + - "⨀": [T: "operator kropka w kółku"] # 0x2a00 + - "⨁": [T: "operator plus w kółku"] # 0x2a01 + - "⨂": [T: "operator razy w kółku"] # 0x2a02 + - "⨃": [T: "operator sumy zbiorów z kropką"] # 0x2a03 + - "⨄": [T: "operator sumy zbiorów z plusem"] # 0x2a04 + - "⨅": [T: "operator kwadratowej części wspólnej"] # 0x2a05 + - "⨆": [T: "operator kwadratowej sumy zbiorów"] # 0x2a06 + - "⨇": [T: "operator podwójnej koniunkcji logicznej"] # 0x2a07 + - "⨈": [T: "dwa logiczne lub operator"] # 0x2a08 + - "⨉": [T: "razy operator"] # 0x2a09 + - "⨊": [T: "suma modulo dwa"] # 0x2a0a + - "⨋": [T: "suma z całką"] # 0x2a0b + - "⨌": [T: "operator poczwórnej całki"] # 0x2a0c + - "⨍": [T: "całka części skończonej"] # 0x2a0d + - "⨎": [T: "całka z podwójnym przekreśleniem"] # 0x2a0e + - "⨏": [T: "całka uśredniona z ukośnikiem"] # 0x2a0f + - "⨐": [T: "funkcja cyrkulacji"] # 0x2a10 + - "⨑": [T: "całka przeciwna do ruchu wskazówek zegara"] # 0x2a11 + - "⨒": [T: "całka liniowa po prostokątnej ścieżce wokół bieguna"] # 0x2a12 + - "⨓": [T: "całka liniowa po półokrągłej ścieżce wokół bieguna"] # 0x2a13 + - "⨔": [T: "całka liniowa bez pola"] # 0x2a14 + - "⨕": [T: "operator całki wokół punktu"] # 0x2a15 + - "⨖": [T: "operator całki kwaternionowej"] # 0x2a16 + - "⨗": [T: "całka ze strzałką w lewo z haczykiem"] # 0x2a17 + - "⨘": [T: "całka ze znakiem razy"] # 0x2a18 + - "⨙": [T: "całka z częścią wspólną"] # 0x2a19 + - "⨚": [T: "całka z sumą zbiorów"] # 0x2a1a + - "⨛": [T: "całka z kreską nad"] # 0x2a1b + - "⨜": [T: "całka z podkreśleniem"] # 0x2a1c + - "⨝": [T: "złączenie"] # 0x2a1d + - "⨞": [T: "duży lewy trójkąt operator"] # 0x2a1e + - "⨟": [T: "składanie schematów w notacji Z"] # 0x2a1f + - "⨠": [T: "potok schematów w notacji Z"] # 0x2a20 + - "⨡": [T: "rzutowanie schematów w notacji Z"] # 0x2a21 + - "⨢": [T: "znak plus z okręgiem nad"] # 0x2a22 + - "⨣": [T: "znak plus z daszkiem nad"] # 0x2a23 + - "⨤": [T: "znak plus z tyldą nad"] # 0x2a24 + - "⨥": [T: "znak plus z kropką pod"] # 0x2a25 + - "⨦": [T: "znak plus z tyldą pod"] # 0x2a26 + - "⨧": [T: "znak plus z indeksem dolnym dwa"] # 0x2a27 + - "⨨": [T: "znak plus z czarnym trójkątem"] # 0x2a28 + - "⨩": [T: "znak minus z przecinkiem nad"] # 0x2a29 + - "⨪": [T: "znak minus z kropką pod"] # 0x2a2a + - "⨫": [T: "znak minus z kropkami opadającymi"] # 0x2a2b + - "⨬": [T: "znak minus z kropkami wznoszącymi"] # 0x2a2c + - "⨭": [T: "znak plus w lewej połówce okręgu"] # 0x2a2d + - "⨮": [T: "znak plus w prawej połówce okręgu"] # 0x2a2e - "⨯": # 0x2a2f - test: if: "$Verbosity='Terse'" - then: [t: "krzyż"] - else: [t: "krzyż iloczyn"] - - "⨰": [t: "znak mnożenia z kropką nad"] # 0x2a30 - - "⨱": [t: "znak mnożenia z podkreśleniem"] # 0x2a31 - - "⨲": [t: "iloczyn półprosty domknięty od dołu"] # 0x2a32 - - "⨳": [t: "iloczyn spłaszczony"] # 0x2a33 - - "⨴": [t: "znak mnożenia w lewej połówce okręgu"] # 0x2a34 - - "⨵": [t: "znak mnożenia w prawej połówce okręgu"] # 0x2a35 - - "⨶": [t: "znak mnożenia w kółku z daszkiem"] # 0x2a36 - - "⨷": [t: "znak mnożenia w podwójnym okręgu"] # 0x2a37 - - "⨸": [t: "znak dzielenia w kółku"] # 0x2a38 - - "⨹": [t: "znak plus w trójkącie"] # 0x2a39 - - "⨺": [t: "znak minus w trójkącie"] # 0x2a3a - - "⨻": [t: "znak mnożenia w trójkącie"] # 0x2a3b - - "⨼": [t: "iloczyn wewnętrzny"] # 0x2a3c - - "⨽": [t: "prawostronny iloczyn wewnętrzny"] # 0x2a3d - - "⨾": [t: "składanie relacji w notacji Z"] # 0x2a3e - - "⨿": [t: "amalgamacja lub koprodukt"] # 0x2a3f - - "⩀": [t: "część wspólna z kropką"] # 0x2a40 - - "⩁": [t: "suma zbiorów ze znakiem minus"] # 0x2a41 - - "⩂": [t: "suma zbiorów z kreską nad"] # 0x2a42 - - "⩃": [t: "część wspólna z kreską nad"] # 0x2a43 - - "⩄": [t: "część wspólna z koniunkcją logiczną"] # 0x2a44 - - "⩅": [t: "suma zbiorów z alternatywą logiczną"] # 0x2a45 - - "⩆": [t: "suma zbiorów nad część wspólna"] # 0x2a46 - - "⩇": [t: "część wspólna nad suma zbiorów"] # 0x2a47 - - "⩈": [t: "suma zbiorów nad kreska nad część wspólna"] # 0x2a48 - - "⩉": [t: "część wspólna nad kreska nad suma zbiorów"] # 0x2a49 - - "⩊": [t: "suma zbiorów obok sumy zbiorów połączona kreską"] # 0x2a4a - - "⩋": [t: "część wspólna obok części wspólnej połączona kreską"] # 0x2a4b - - "⩌": [t: "zamknięta suma zbiorów z szeryfami"] # 0x2a4c - - "⩍": [t: "zamknięta część wspólna z szeryfami"] # 0x2a4d - - "⩎": [t: "podwójny kwadrat część wspólna"] # 0x2a4e - - "⩏": [t: "podwójny kwadrat suma zbiorów"] # 0x2a4f - - "⩐": [t: "zamknięta suma zbiorów z szeryfami i iloczynem spłaszczonym"] # 0x2a50 - - "⩑": [t: "koniunkcja logiczna z kropką nad"] # 0x2a51 - - "⩒": [t: "logiczne lub z kropką nad"] # 0x2a52 - - "⩓": [t: "podwójna koniunkcja logiczna"] # 0x2a53 - - "⩔": [t: "podwójny logiczne lub"] # 0x2a54 - - "⩕": [t: "dwa przecinające się logiczne i"] # 0x2a55 - - "⩖": [t: "dwa przecinające się logiczne lub"] # 0x2a56 - - "⩗": [t: "skośne duże lub"] # 0x2a57 - - "⩘": [t: "skośne duże i"] # 0x2a58 - - "⩙": [t: "logiczne lub nakładające się na logiczne i"] # 0x2a59 - - "⩚": [t: "logiczne i ze środkowym trzonem"] # 0x2a5a - - "⩛": [t: "logiczne lub ze środkowym trzonem"] # 0x2a5b - - "⩜": [t: "koniunkcja logiczna z poziomą kreską"] # 0x2a5c - - "⩝": [t: "alternatywa logiczna z poziomą kreską"] # 0x2a5d - - "⩞": [t: "logiczne i z podwójną kreską nad"] # 0x2a5e - - "⩟": [t: "koniunkcja logiczna z podkreśleniem"] # 0x2a5f - - "⩠": [t: "logiczne i z podwójną kreską pod"] # 0x2a60 - - "⩡": [t: "małe logiczne lub z podkreśleniem"] # 0x2a61 - - "⩢": [t: "logiczne lub z podwójną kreską nad"] # 0x2a62 - - "⩣": [t: "logiczne lub z podwójną kreską pod"] # 0x2a63 - - "⩤": [t: "antyograniczenie dziedziny w notacji Z"] # 0x2a64 - - "⩥": [t: "antyograniczenie przeciwdziedziny w notacji Z"] # 0x2a65 - - "⩦": [t: "znak równości z kropką pod spodem"] # 0x2a66 - - "⩧": [t: "identyczne z kropką nad"] # 0x2a67 - - "⩨": [t: "potrójna kreska pozioma z podwójną pionową kreską"] # 0x2a68 - - "⩩": [t: "potrójna kreska pozioma z potrójną pionową kreską"] # 0x2a69 - - "⩪": [t: "operator tyldy z kropką nad"] # 0x2a6a - - "⩫": [t: "operator tyldy ze wznoszącymi kropkami"] # 0x2a6b - - "⩬": [t: "podobne minus podobne"] # 0x2a6c - - "⩭": [t: "przystające z kropką nad"] # 0x2a6d - - "⩮": [t: "równa się z gwiazdką"] # 0x2a6e - - "⩯": [t: "w przybliżeniu równe z daszkiem"] # 0x2a6f - - "⩰": [t: "w przybliżeniu równe lub równe"] # 0x2a70 - - "⩱": [t: "znak równości nad znakiem plus"] # 0x2a71 - - "⩲": [t: "znak plus nad znakiem równości"] # 0x2a72 - - "⩳": [t: "znak równości nad operatorem tyldy"] # 0x2a73 - - "⩴": [t: "podwójny dwukropek równe"] # 0x2a74 - - "⩵": [t: "dwa kolejne znaki równości"] # 0x2a75 - - "⩶": [t: "trzy kolejne znaki równości"] # 0x2a76 - - "⩷": [t: "znak równości z dwiema kropkami nad i dwiema kropkami pod"] # 0x2a77 - - "⩸": [t: "równoważne z czterema kropkami nad"] # 0x2a78 - - "⩹": [t: "mniejsze niż z okrąg wewnątrz"] # 0x2a79 - - "⩺": [t: "większe niż z okrąg wewnątrz"] # 0x2a7a - - "⩻": [t: "mniejsze niż ze znakiem zapytania nad"] # 0x2a7b - - "⩼": [t: "większe niż ze znakiem zapytania nad"] # 0x2a7c - - "⩽": [t: "mniejsze niż lub ukośnie równe"] # 0x2a7d - - "⩾": [t: "większe niż lub ukośnie równe"] # 0x2a7e - - "⩿": [t: "mniejsze niż lub ukośnie równe z kropką wewnątrz"] # 0x2a7f - - "⪀": [t: "większe niż lub ukośnie równe z kropką wewnątrz"] # 0x2a80 - - "⪁": [t: "mniejsze niż lub ukośnie równe z kropką nad"] # 0x2a81 - - "⪂": [t: "większe niż lub ukośnie równe z kropką nad"] # 0x2a82 - - "⪃": [t: "mniejsze niż lub ukośnie równe z kropką nad prawą stroną"] # 0x2a83 - - "⪄": [t: "większe niż lub ukośnie równe z kropką nad lewą stroną"] # 0x2a84 - - "⪅": [t: "mniejsze niż lub przybliżone"] # 0x2a85 - - "⪆": [t: "większe niż lub przybliżone"] # 0x2a86 - - "⪇": [t: "mniejsze niż z pojedynczą linią nierówności"] # 0x2a87 - - "⪈": [t: "większe niż z pojedynczą linią nierówności"] # 0x2a88 - - "⪉": [t: "mniejsze niż i nie przybliżone"] # 0x2a89 - - "⪊": [t: "większe niż i nie przybliżone"] # 0x2a8a - - "⪋": [t: "mniejsze niż nad podwójną linią równości nad większe niż"] # 0x2a8b - - "⪌": [t: "większe niż nad podwójną linią równości nad mniejsze niż"] # 0x2a8c - - "⪍": [t: "mniejsze niż nad podobne lub równe"] # 0x2a8d - - "⪎": [t: "większe niż nad podobne lub równe"] # 0x2a8e - - "⪏": [t: "mniejsze niż nad podobne nad większe niż"] # 0x2a8f - - "⪐": [t: "większe niż nad podobne nad mniejsze niż"] # 0x2a90 - - "⪑": [t: "mniejsze niż nad większe niż nad podwójną linią równości"] # 0x2a91 - - "⪒": [t: "większe niż nad mniejsze niż nad podwójną linią równości"] # 0x2a92 - - "⪓": [t: "mniejsze niż nad ukośnie równe nad większe niż nad ukośnie równe"] # 0x2a93 - - "⪔": [t: "większe niż nad ukośnie równe nad mniejsze niż nad ukośnie równe"] # 0x2a94 - - "⪕": [t: "ukośnie równe lub mniejsze niż"] # 0x2a95 - - "⪖": [t: "ukośnie równe lub większe niż"] # 0x2a96 - - "⪗": [t: "ukośnie równe lub mniejsze niż z kropką wewnątrz"] # 0x2a97 - - "⪘": [t: "ukośnie równe lub większe niż z kropką wewnątrz"] # 0x2a98 - - "⪙": [t: "podwójna linia równa lub mniejsze niż"] # 0x2a99 - - "⪚": [t: "podwójna linia równa lub większe niż"] # 0x2a9a - - "⪛": [t: "podwójna linia ukośnie równa lub mniejsze niż"] # 0x2a9b - - "⪜": [t: "podwójna linia ukośnie równa lub większe niż"] # 0x2a9c - - "⪝": [t: "podobne lub mniejsze niż"] # 0x2a9d - - "⪞": [t: "podobne lub większe niż"] # 0x2a9e - - "⪟": [t: "podobne nad mniejsze niż nad znakiem równości"] # 0x2a9f - - "⪠": [t: "podobne nad większe niż nad znakiem równości"] # 0x2aa0 - - "⪡": [t: "podwójnie zagnieżdżone mniejsze niż"] # 0x2aa1 - - "⪢": [t: "podwójnie zagnieżdżone większe niż"] # 0x2aa2 - - "⪣": [t: "podwójnie zagnieżdżone mniejsze niż z podkreśleniem"] # 0x2aa3 - - "⪤": [t: "większe niż nakładające się na mniejsze niż"] # 0x2aa4 - - "⪥": [t: "większe niż obok mniejsze niż"] # 0x2aa5 - - "⪦": [t: "mniejsze niż zamknięte krzywą"] # 0x2aa6 - - "⪧": [t: "większe niż zamknięte krzywą"] # 0x2aa7 - - "⪨": [t: "mniejsze niż zamknięte krzywą nad ukośnie równe"] # 0x2aa8 - - "⪩": [t: "większe niż zamknięte krzywą nad ukośnie równe"] # 0x2aa9 - - "⪪": [t: "mniejsze niż"] # 0x2aaa - - "⪫": [t: "większe niż"] # 0x2aab - - "⪬": [t: "mniejsze niż lub równe"] # 0x2aac - - "⪭": [t: "większe niż lub równe"] # 0x2aad - - "⪮": [t: "znak równości z garbem nad"] # 0x2aae - - "⪯": [t: "poprzedza nad pojedynczą linią równości"] # 0x2aaf - - "⪰": [t: "następuje po nad pojedynczą linią równości"] # 0x2ab0 - - "⪱": [t: "poprzedza nad pojedynczą linią nierówności"] # 0x2ab1 - - "⪲": [t: "następuje po nad pojedynczy linia nie równa się"] # 0x2ab2 - - "⪳": [t: "poprzedza nad znakiem równości"] # 0x2ab3 - - "⪴": [t: "następuje po nad znakiem równości"] # 0x2ab4 - - "⪵": [t: "poprzedza nad nie równa się"] # 0x2ab5 - - "⪶": [t: "następuje po nad nie równa się"] # 0x2ab6 - - "⪷": [t: "poprzedza nad znakiem przybliżonej równości"] # 0x2ab7 - - "⪸": [t: "następuje po nad znakiem przybliżonej równości"] # 0x2ab8 - - "⪹": [t: "poprzedza nad znakiem nie w przybliżeniu równe"] # 0x2ab9 - - "⪺": [t: "następuje po nad znakiem nie w przybliżeniu równe"] # 0x2aba - - "⪻": [t: "podwójny poprzedza"] # 0x2abb - - "⪼": [t: "podwójny następuje po"] # 0x2abc - - "⪽": [t: "podzbiór z kropką"] # 0x2abd - - "⪾": [t: "nadzbiór z kropką"] # 0x2abe - - "⪿": [t: "podzbiór ze znakiem plus pod spodem"] # 0x2abf - - "⫀": [t: "nadzbiór ze znakiem plus pod spodem"] # 0x2ac0 - - "⫁": [t: "podzbiór ze znakiem mnożenia pod"] # 0x2ac1 - - "⫂": [t: "nadzbiór ze znakiem mnożenia pod"] # 0x2ac2 - - "⫃": [t: "podzbiór lub równy z kropką nad"] # 0x2ac3 - - "⫄": [t: "nadzbiór lub równy z kropką nad"] # 0x2ac4 - - "⫅": [t: "podzbiór nad znakiem równości"] # 0x2ac5 - - "⫆": [t: "nadzbiór nad znakiem równości"] # 0x2ac6 - - "⫇": [t: "podzbiór nad operatorem tyldy"] # 0x2ac7 - - "⫈": [t: "nadzbiór nad operatorem tyldy"] # 0x2ac8 - - "⫉": [t: "podzbiór nad znakiem przybliżonej równości"] # 0x2ac9 - - "⫊": [t: "nadzbiór nad znakiem przybliżonej równości"] # 0x2aca - - "⫋": [t: "podzbiór nad nie równa się"] # 0x2acb - - "⫌": [t: "nadzbiór nad nie równa się"] # 0x2acc - - "⫍": [t: "kwadrat lewy otwórz ramka operator"] # 0x2acd - - "⫎": [t: "kwadrat prawy otwórz ramka operator"] # 0x2ace - - "⫏": [t: "zamknięty podzbiór"] # 0x2acf - - "⫐": [t: "zamknięty nadzbiór"] # 0x2ad0 - - "⫑": [t: "zamknięty podzbiór lub równe"] # 0x2ad1 - - "⫒": [t: "zamknięty nadzbiór lub równe"] # 0x2ad2 - - "⫓": [t: "podzbiór nad nadzbiór"] # 0x2ad3 - - "⫔": [t: "nadzbiór nad podzbiór"] # 0x2ad4 - - "⫕": [t: "podzbiór nad podzbiór"] # 0x2ad5 - - "⫖": [t: "nadzbiór nad nadzbiór"] # 0x2ad6 - - "⫗": [t: "nadzbiór obok podzbioru"] # 0x2ad7 - - "⫘": [t: "nadzbiór obok podzbioru połączony kreską"] # 0x2ad8 - - "⫙": [t: "należy do otwarte od dołu"] # 0x2ad9 - - "⫚": [t: "widły z górną poprzeczką"] # 0x2ada - - "⫛": [t: "poprzeczna część wspólna"] # 0x2adb - - "⫝̸": [t: "rozwidlanie"] # 0x2adc - - "⫝": [t: "nierozwidlanie"] # 0x2add - - "⫞": [t: "krótki lewy znacznik"] # 0x2ade - - "⫟": [t: "krótki dolny znacznik"] # 0x2adf - - "⫠": [t: "krótki górny znacznik"] # 0x2ae0 - - "⫡": [t: "prostopadłe z literą s"] # 0x2ae1 - - "⫢": [t: "pionowa kreska z potrójnym prawym znacznikiem dedukcji"] # 0x2ae2 - - "⫣": [t: "podwójna pionowa kreska z lewym znacznikiem dedukcji"] # 0x2ae3 - - "⫤": [t: "pionowa kreska z podwójnym lewym znacznikiem dedukcji"] # 0x2ae4 - - "⫥": [t: "podwójna pionowa kreska z podwójnym lewym znacznikiem dedukcji"] # 0x2ae5 - - "⫦": [t: "długa kreska od lewego elementu z podwójną pionową kreską"] # 0x2ae6 - - "⫧": [t: "krótki dolny znacznik z kreską nad"] # 0x2ae7 - - "⫨": [t: "krótki górny znacznik z podkreśleniem"] # 0x2ae8 - - "⫩": [t: "krótki górny znacznik nad krótkim dolnym znacznikiem"] # 0x2ae9 - - "⫪": [t: "podwójny dolny znacznik"] # 0x2aea - - "⫫": [t: "podwójny górny znacznik"] # 0x2aeb - - "⫬": [t: "znak negacji z podwójnym przekreśleniem"] # 0x2aec - - "⫭": [t: "odwrócony znak negacji z podwójnym przekreśleniem"] # 0x2aed - - "⫮": [t: "nie dzieli z odwróconym ukośnikiem negacji"] # 0x2aee - - "⫯": [t: "pionowa linia z okręgiem nad"] # 0x2aef - - "⫰": [t: "pionowa linia z okręgiem pod"] # 0x2af0 - - "⫱": [t: "dolny znacznik z okręgiem pod"] # 0x2af1 - - "⫲": [t: "równoległe z poziomą kreską"] # 0x2af2 - - "⫳": [t: "równoległe z operatorem tyldy"] # 0x2af3 - - "⫴": [t: "potrójna pionowa kreska jako relacja binarna"] # 0x2af4 - - "⫵": [t: "potrójna pionowa kreska z poziomą kreską"] # 0x2af5 - - "⫶": [t: "potrójny dwukropek operator"] # 0x2af6 - - "⫷": [t: "potrójnie zagnieżdżone mniejsze niż"] # 0x2af7 - - "⫸": [t: "potrójnie zagnieżdżone większe niż"] # 0x2af8 - - "⫹": [t: "podwójna linia ukośnie mniejsze lub równe"] # 0x2af9 - - "⫺": [t: "podwójna linia ukośnie większe lub równe"] # 0x2afa - - "⫻": [t: "potrójny ukośnik jako relacja binarna"] # 0x2afb - - "⫼": [t: "operator dużej potrójnej pionowej kreski"] # 0x2afc - - "⫽": [t: "podwójny ukośnik operator"] # 0x2afd - - "⫾": [t: "biała pionowa kreska"] # 0x2afe - - "⫿": [t: "biała pionowa kreska"] # 0x2aff - - "⬀": [t: "biała strzałka na północny wschód"] # 0x2b00 - - "⬁": [t: "biała strzałka na północny zachód"] # 0x2b01 - - "⬂": [t: "biała strzałka na południowy wschód"] # 0x2b02 - - "⬃": [t: "biała strzałka na południowy zachód"] # 0x2b03 - - "⬄": [t: "biała strzałka w lewo i w prawo"] # 0x2b04 - - "⬅": [t: "lewy czarny strzałka"] # 0x2b05 - - "⬆": [t: "górny czarny strzałka"] # 0x2b06 - - "⬇": [t: "dolny czarny strzałka"] # 0x2b07 - - "⬈": [t: "północ wschód czarny strzałka"] # 0x2b08 - - "⬉": [t: "północ zachód czarny strzałka"] # 0x2b09 - - "⬊": [t: "południe wschód czarny strzałka"] # 0x2b0a - - "⬋": [t: "południe zachód czarny strzałka"] # 0x2b0b - - "⬌": [t: "lewy prawy czarny strzałka"] # 0x2b0c - - "⬍": [t: "górny dolny czarny strzałka"] # 0x2b0d - - "⬎": [t: "strzałka w prawo z dolnym czubkiem"] # 0x2b0e - - "⬏": [t: "strzałka w prawo z górnym czubkiem"] # 0x2b0f - - "⬐": [t: "strzałka w lewo z dolnym czubkiem"] # 0x2b10 - - "⬑": [t: "strzałka w lewo z górnym czubkiem"] # 0x2b11 - - "⬒": [t: "kwadrat z górną połową czarną"] # 0x2b12 - - "⬓": [t: "kwadrat z dolną połową czarną"] # 0x2b13 - - "⬔": [t: "kwadrat z górną prawą ukośną połową czarną"] # 0x2b14 - - "⬕": [t: "kwadrat z dolną lewą ukośną połową czarną"] # 0x2b15 - - "⬖": [t: "romb z lewą połową czarną"] # 0x2b16 - - "⬗": [t: "romb z prawą połową czarną"] # 0x2b17 - - "⬘": [t: "romb z górną połową czarną"] # 0x2b18 - - "⬙": [t: "romb z dolną połową czarną"] # 0x2b19 - - "⬚": [t: "ramka"] # 0x2b1a - - "⬛": [t: "czarny duży kwadrat"] # 0x2b1b - - "⬜": [t: "biały duży kwadrat"] # 0x2b1c - - "⬝": [t: "czarny bardzo mały kwadrat"] # 0x2b1d - - "⬞": [t: "biały bardzo mały kwadrat"] # 0x2b1e - - "⬟": [t: "czarny pięciokąt"] # 0x2b1f - - "⬠": [t: "biały pięciokąt"] # 0x2b20 - - "⬡": [t: "biały sześciokąt"] # 0x2b21 - - "⬢": [t: "czarny sześciokąt"] # 0x2b22 - - "⬣": [t: "poziomy czarny sześciokąt"] # 0x2b23 - - "⬤": [t: "czarny duży okrąg"] # 0x2b24 - - "⬥": [t: "czarny średni romb"] # 0x2b25 - - "⬦": [t: "biały średni romb"] # 0x2b26 - - "⬧": [t: "czarny średni romb"] # 0x2b27 - - "⬨": [t: "biały średni romb"] # 0x2b28 - - "⬩": [t: "czarny mały romb"] # 0x2b29 - - "⬪": [t: "czarny mały romb"] # 0x2b2a - - "⬫": [t: "biały mały romb"] # 0x2b2b - - "⬬": [t: "czarna pozioma elipsa"] # 0x2b2c - - "⬭": [t: "biała pozioma elipsa"] # 0x2b2d - - "⬮": [t: "czarna pionowa elipsa"] # 0x2b2e - - "⬯": [t: "biała pionowa elipsa"] # 0x2b2f - - "⬰": [t: "strzałka w lewo z małym okręgiem"] # 0x2b30 - - "⬱": [t: "trzy strzałki w lewo"] # 0x2b31 - - "⬲": [t: "strzałka w lewo z plusem w kółku"] # 0x2b32 - - "⬳": [t: "długa falista strzałka w lewo"] # 0x2b33 - - "⬴": [t: "strzałka w lewo z dwoma grotami i pionowym przekreśleniem"] # 0x2b34 - - "⬵": [t: "strzałka w lewo z dwoma grotami i podwójnym pionowym przekreśleniem"] # 0x2b35 - - "⬶": [t: "strzałka w lewo z dwoma grotami od kreski"] # 0x2b36 - - "⬷": [t: "strzałka w lewo z dwoma grotami i potrójną kreską"] # 0x2b37 - - "⬸": [t: "strzałka w lewo z kropkowanym trzonem"] # 0x2b38 - - "⬹": [t: "strzałka w lewo z ogonem i pionową kreską"] # 0x2b39 - - "⬺": [t: "strzałka w lewo z ogonem i podwójną pionową kreską"] # 0x2b3a - - "⬻": [t: "strzałka w lewo z dwoma grotami i ogonem"] # 0x2b3b - - "⬼": [t: "strzałka w lewo z dwoma grotami, ogonem i pionowym przekreśleniem"] # 0x2b3c - - "⬽": [t: "strzałka w lewo z dwoma grotami, ogonem i podwójnym pionowym przekreśleniem"] # 0x2b3d - - "⬾": [t: "strzałka w lewo przez X"] # 0x2b3e - - "⬿": [t: "falista strzałka skierowana bezpośrednio w lewo"] # 0x2b3f - - "⭀": [t: "znak równości nad strzałką w lewo"] # 0x2b40 - - "⭁": [t: "operator odwrotnej tyldy nad strzałką w lewo"] # 0x2b41 - - "⭂": [t: "strzałka w lewo nad odwróconym znakiem przybliżonej równości"] # 0x2b42 - - "⭃": [t: "strzałka w prawo przez znak większe niż"] # 0x2b43 - - "⭄": [t: "strzałka w prawo przez znak nadzbioru"] # 0x2b44 - - "⭅": [t: "lewy poczwórny strzałka"] # 0x2b45 - - "⭆": [t: "prawy poczwórny strzałka"] # 0x2b46 - - "⭇": [t: "operator odwrotnej tyldy nad strzałką w prawo"] # 0x2b47 - - "⭈": [t: "strzałka w prawo nad odwróconym znakiem przybliżonej równości"] # 0x2b48 - - "⭉": [t: "operator tyldy nad strzałką w lewo"] # 0x2b49 - - "⭊": [t: "strzałka w lewo nad znakiem przybliżonej równości"] # 0x2b4a - - "⭋": [t: "strzałka w lewo nad operatorem odwrotnej tyldy"] # 0x2b4b - - "⭌": [t: "strzałka w prawo nad operatorem odwrotnej tyldy"] # 0x2b4c - - "⭐": [t: "biały średni gwiazda"] # 0x2b50 - - "⭑": [t: "czarny mały gwiazda"] # 0x2b51 - - "⭒": [t: "biały mały gwiazda"] # 0x2b52 - - "⭓": [t: "czarny prawy skierowany pięciokąt"] # 0x2b53 - - "⭔": [t: "biały prawy skierowany pięciokąt"] # 0x2b54 - - "⭕": [t: "gruby duży okrąg"] # 0x2b55 - - "⭖": [t: "gruby owal z owalem wewnątrz"] # 0x2b56 - - "⭗": [t: "gruby okrąg z okręgiem wewnątrz"] # 0x2b57 - - "⭘": [t: "gruby okrąg"] # 0x2b58 - - "⭙": [t: "gruby ukośny krzyż w kółku"] # 0x2b59 - - "⸀": [t: "kąt prosty znacznik podstawienia"] # 0x2e00 - - "⸁": [t: "kąt prosty kropkowany znacznik podstawienia"] # 0x2e01 - - "⸂": [t: "lewy nawias kwadratowy podstawienia"] # 0x2e02 - - "⸃": [t: "prawy nawias kwadratowy podstawienia"] # 0x2e03 - - "⸄": [t: "lewy kropkowany nawias kwadratowy podstawienia"] # 0x2e04 - - "⸅": [t: "prawy kropkowany nawias kwadratowy podstawienia"] # 0x2e05 - - "⸆": [t: "podniesiony znacznik interpolacji"] # 0x2e06 - - "⸇": [t: "podniesiony kropkowany znacznik interpolacji"] # 0x2e07 - - "⸈": [t: "kropkowany znacznik transpozycji"] # 0x2e08 - - "⸉": [t: "lewy nawias kwadratowy transpozycji"] # 0x2e09 - - "⸊": [t: "prawy nawias kwadratowy transpozycji"] # 0x2e0a - - "⸋": [t: "podniesiony kwadrat"] # 0x2e0b - - "⸌": [t: "lewy podniesiony pominięcia nawias kwadratowy"] # 0x2e0c - - "⸍": [t: "prawy podniesiony pominięcia nawias kwadratowy"] # 0x2e0d - - "⸎": [t: "redakcyjny koronis"] # 0x2e0e + then: [T: "krzyż"] + else: [T: "krzyż iloczyn"] + - "⨰": [T: "znak mnożenia z kropką nad"] # 0x2a30 + - "⨱": [T: "znak mnożenia z podkreśleniem"] # 0x2a31 + - "⨲": [T: "iloczyn półprosty domknięty od dołu"] # 0x2a32 + - "⨳": [T: "iloczyn spłaszczony"] # 0x2a33 + - "⨴": [T: "znak mnożenia w lewej połówce okręgu"] # 0x2a34 + - "⨵": [T: "znak mnożenia w prawej połówce okręgu"] # 0x2a35 + - "⨶": [T: "znak mnożenia w kółku z daszkiem"] # 0x2a36 + - "⨷": [T: "znak mnożenia w podwójnym okręgu"] # 0x2a37 + - "⨸": [T: "znak dzielenia w kółku"] # 0x2a38 + - "⨹": [T: "znak plus w trójkącie"] # 0x2a39 + - "⨺": [T: "znak minus w trójkącie"] # 0x2a3a + - "⨻": [T: "znak mnożenia w trójkącie"] # 0x2a3b + - "⨼": [T: "iloczyn wewnętrzny"] # 0x2a3c + - "⨽": [T: "prawostronny iloczyn wewnętrzny"] # 0x2a3d + - "⨾": [T: "składanie relacji w notacji Z"] # 0x2a3e + - "⨿": [T: "amalgamacja lub koprodukt"] # 0x2a3f + - "⩀": [T: "część wspólna z kropką"] # 0x2a40 + - "⩁": [T: "suma zbiorów ze znakiem minus"] # 0x2a41 + - "⩂": [T: "suma zbiorów z kreską nad"] # 0x2a42 + - "⩃": [T: "część wspólna z kreską nad"] # 0x2a43 + - "⩄": [T: "część wspólna z koniunkcją logiczną"] # 0x2a44 + - "⩅": [T: "suma zbiorów z alternatywą logiczną"] # 0x2a45 + - "⩆": [T: "suma zbiorów nad część wspólna"] # 0x2a46 + - "⩇": [T: "część wspólna nad suma zbiorów"] # 0x2a47 + - "⩈": [T: "suma zbiorów nad kreska nad część wspólna"] # 0x2a48 + - "⩉": [T: "część wspólna nad kreska nad suma zbiorów"] # 0x2a49 + - "⩊": [T: "suma zbiorów obok sumy zbiorów połączona kreską"] # 0x2a4a + - "⩋": [T: "część wspólna obok części wspólnej połączona kreską"] # 0x2a4b + - "⩌": [T: "zamknięta suma zbiorów z szeryfami"] # 0x2a4c + - "⩍": [T: "zamknięta część wspólna z szeryfami"] # 0x2a4d + - "⩎": [T: "podwójny kwadrat część wspólna"] # 0x2a4e + - "⩏": [T: "podwójny kwadrat suma zbiorów"] # 0x2a4f + - "⩐": [T: "zamknięta suma zbiorów z szeryfami i iloczynem spłaszczonym"] # 0x2a50 + - "⩑": [T: "koniunkcja logiczna z kropką nad"] # 0x2a51 + - "⩒": [T: "logiczne lub z kropką nad"] # 0x2a52 + - "⩓": [T: "podwójna koniunkcja logiczna"] # 0x2a53 + - "⩔": [T: "podwójny logiczne lub"] # 0x2a54 + - "⩕": [T: "dwa przecinające się logiczne i"] # 0x2a55 + - "⩖": [T: "dwa przecinające się logiczne lub"] # 0x2a56 + - "⩗": [T: "skośne duże lub"] # 0x2a57 + - "⩘": [T: "skośne duże i"] # 0x2a58 + - "⩙": [T: "logiczne lub nakładające się na logiczne i"] # 0x2a59 + - "⩚": [T: "logiczne i ze środkowym trzonem"] # 0x2a5a + - "⩛": [T: "logiczne lub ze środkowym trzonem"] # 0x2a5b + - "⩜": [T: "koniunkcja logiczna z poziomą kreską"] # 0x2a5c + - "⩝": [T: "alternatywa logiczna z poziomą kreską"] # 0x2a5d + - "⩞": [T: "logiczne i z podwójną kreską nad"] # 0x2a5e + - "⩟": [T: "koniunkcja logiczna z podkreśleniem"] # 0x2a5f + - "⩠": [T: "logiczne i z podwójną kreską pod"] # 0x2a60 + - "⩡": [T: "małe logiczne lub z podkreśleniem"] # 0x2a61 + - "⩢": [T: "logiczne lub z podwójną kreską nad"] # 0x2a62 + - "⩣": [T: "logiczne lub z podwójną kreską pod"] # 0x2a63 + - "⩤": [T: "antyograniczenie dziedziny w notacji Z"] # 0x2a64 + - "⩥": [T: "antyograniczenie przeciwdziedziny w notacji Z"] # 0x2a65 + - "⩦": [T: "znak równości z kropką pod spodem"] # 0x2a66 + - "⩧": [T: "identyczne z kropką nad"] # 0x2a67 + - "⩨": [T: "potrójna kreska pozioma z podwójną pionową kreską"] # 0x2a68 + - "⩩": [T: "potrójna kreska pozioma z potrójną pionową kreską"] # 0x2a69 + - "⩪": [T: "operator tyldy z kropką nad"] # 0x2a6a + - "⩫": [T: "operator tyldy ze wznoszącymi kropkami"] # 0x2a6b + - "⩬": [T: "podobne minus podobne"] # 0x2a6c + - "⩭": [T: "przystające z kropką nad"] # 0x2a6d + - "⩮": [T: "równa się z gwiazdką"] # 0x2a6e + - "⩯": [T: "w przybliżeniu równe z daszkiem"] # 0x2a6f + - "⩰": [T: "w przybliżeniu równe lub równe"] # 0x2a70 + - "⩱": [T: "znak równości nad znakiem plus"] # 0x2a71 + - "⩲": [T: "znak plus nad znakiem równości"] # 0x2a72 + - "⩳": [T: "znak równości nad operatorem tyldy"] # 0x2a73 + - "⩴": [T: "podwójny dwukropek równe"] # 0x2a74 + - "⩵": [T: "dwa kolejne znaki równości"] # 0x2a75 + - "⩶": [T: "trzy kolejne znaki równości"] # 0x2a76 + - "⩷": [T: "znak równości z dwiema kropkami nad i dwiema kropkami pod"] # 0x2a77 + - "⩸": [T: "równoważne z czterema kropkami nad"] # 0x2a78 + - "⩹": [T: "mniejsze niż z okrąg wewnątrz"] # 0x2a79 + - "⩺": [T: "większe niż z okrąg wewnątrz"] # 0x2a7a + - "⩻": [T: "mniejsze niż ze znakiem zapytania nad"] # 0x2a7b + - "⩼": [T: "większe niż ze znakiem zapytania nad"] # 0x2a7c + - "⩽": [T: "mniejsze niż lub ukośnie równe"] # 0x2a7d + - "⩾": [T: "większe niż lub ukośnie równe"] # 0x2a7e + - "⩿": [T: "mniejsze niż lub ukośnie równe z kropką wewnątrz"] # 0x2a7f + - "⪀": [T: "większe niż lub ukośnie równe z kropką wewnątrz"] # 0x2a80 + - "⪁": [T: "mniejsze niż lub ukośnie równe z kropką nad"] # 0x2a81 + - "⪂": [T: "większe niż lub ukośnie równe z kropką nad"] # 0x2a82 + - "⪃": [T: "mniejsze niż lub ukośnie równe z kropką nad prawą stroną"] # 0x2a83 + - "⪄": [T: "większe niż lub ukośnie równe z kropką nad lewą stroną"] # 0x2a84 + - "⪅": [T: "mniejsze niż lub przybliżone"] # 0x2a85 + - "⪆": [T: "większe niż lub przybliżone"] # 0x2a86 + - "⪇": [T: "mniejsze niż z pojedynczą linią nierówności"] # 0x2a87 + - "⪈": [T: "większe niż z pojedynczą linią nierówności"] # 0x2a88 + - "⪉": [T: "mniejsze niż i nie przybliżone"] # 0x2a89 + - "⪊": [T: "większe niż i nie przybliżone"] # 0x2a8a + - "⪋": [T: "mniejsze niż nad podwójną linią równości nad większe niż"] # 0x2a8b + - "⪌": [T: "większe niż nad podwójną linią równości nad mniejsze niż"] # 0x2a8c + - "⪍": [T: "mniejsze niż nad podobne lub równe"] # 0x2a8d + - "⪎": [T: "większe niż nad podobne lub równe"] # 0x2a8e + - "⪏": [T: "mniejsze niż nad podobne nad większe niż"] # 0x2a8f + - "⪐": [T: "większe niż nad podobne nad mniejsze niż"] # 0x2a90 + - "⪑": [T: "mniejsze niż nad większe niż nad podwójną linią równości"] # 0x2a91 + - "⪒": [T: "większe niż nad mniejsze niż nad podwójną linią równości"] # 0x2a92 + - "⪓": [T: "mniejsze niż nad ukośnie równe nad większe niż nad ukośnie równe"] # 0x2a93 + - "⪔": [T: "większe niż nad ukośnie równe nad mniejsze niż nad ukośnie równe"] # 0x2a94 + - "⪕": [T: "ukośnie równe lub mniejsze niż"] # 0x2a95 + - "⪖": [T: "ukośnie równe lub większe niż"] # 0x2a96 + - "⪗": [T: "ukośnie równe lub mniejsze niż z kropką wewnątrz"] # 0x2a97 + - "⪘": [T: "ukośnie równe lub większe niż z kropką wewnątrz"] # 0x2a98 + - "⪙": [T: "podwójna linia równa lub mniejsze niż"] # 0x2a99 + - "⪚": [T: "podwójna linia równa lub większe niż"] # 0x2a9a + - "⪛": [T: "podwójna linia ukośnie równa lub mniejsze niż"] # 0x2a9b + - "⪜": [T: "podwójna linia ukośnie równa lub większe niż"] # 0x2a9c + - "⪝": [T: "podobne lub mniejsze niż"] # 0x2a9d + - "⪞": [T: "podobne lub większe niż"] # 0x2a9e + - "⪟": [T: "podobne nad mniejsze niż nad znakiem równości"] # 0x2a9f + - "⪠": [T: "podobne nad większe niż nad znakiem równości"] # 0x2aa0 + - "⪡": [T: "podwójnie zagnieżdżone mniejsze niż"] # 0x2aa1 + - "⪢": [T: "podwójnie zagnieżdżone większe niż"] # 0x2aa2 + - "⪣": [T: "podwójnie zagnieżdżone mniejsze niż z podkreśleniem"] # 0x2aa3 + - "⪤": [T: "większe niż nakładające się na mniejsze niż"] # 0x2aa4 + - "⪥": [T: "większe niż obok mniejsze niż"] # 0x2aa5 + - "⪦": [T: "mniejsze niż zamknięte krzywą"] # 0x2aa6 + - "⪧": [T: "większe niż zamknięte krzywą"] # 0x2aa7 + - "⪨": [T: "mniejsze niż zamknięte krzywą nad ukośnie równe"] # 0x2aa8 + - "⪩": [T: "większe niż zamknięte krzywą nad ukośnie równe"] # 0x2aa9 + - "⪪": [T: "mniejsze niż"] # 0x2aaa + - "⪫": [T: "większe niż"] # 0x2aab + - "⪬": [T: "mniejsze niż lub równe"] # 0x2aac + - "⪭": [T: "większe niż lub równe"] # 0x2aad + - "⪮": [T: "znak równości z garbem nad"] # 0x2aae + - "⪯": [T: "poprzedza nad pojedynczą linią równości"] # 0x2aaf + - "⪰": [T: "następuje po nad pojedynczą linią równości"] # 0x2ab0 + - "⪱": [T: "poprzedza nad pojedynczą linią nierówności"] # 0x2ab1 + - "⪲": [T: "następuje po nad pojedynczy linia nie równa się"] # 0x2ab2 + - "⪳": [T: "poprzedza nad znakiem równości"] # 0x2ab3 + - "⪴": [T: "następuje po nad znakiem równości"] # 0x2ab4 + - "⪵": [T: "poprzedza nad nie równa się"] # 0x2ab5 + - "⪶": [T: "następuje po nad nie równa się"] # 0x2ab6 + - "⪷": [T: "poprzedza nad znakiem przybliżonej równości"] # 0x2ab7 + - "⪸": [T: "następuje po nad znakiem przybliżonej równości"] # 0x2ab8 + - "⪹": [T: "poprzedza nad znakiem nie w przybliżeniu równe"] # 0x2ab9 + - "⪺": [T: "następuje po nad znakiem nie w przybliżeniu równe"] # 0x2aba + - "⪻": [T: "podwójny poprzedza"] # 0x2abb + - "⪼": [T: "podwójny następuje po"] # 0x2abc + - "⪽": [T: "podzbiór z kropką"] # 0x2abd + - "⪾": [T: "nadzbiór z kropką"] # 0x2abe + - "⪿": [T: "podzbiór ze znakiem plus pod spodem"] # 0x2abf + - "⫀": [T: "nadzbiór ze znakiem plus pod spodem"] # 0x2ac0 + - "⫁": [T: "podzbiór ze znakiem mnożenia pod"] # 0x2ac1 + - "⫂": [T: "nadzbiór ze znakiem mnożenia pod"] # 0x2ac2 + - "⫃": [T: "podzbiór lub równy z kropką nad"] # 0x2ac3 + - "⫄": [T: "nadzbiór lub równy z kropką nad"] # 0x2ac4 + - "⫅": [T: "podzbiór nad znakiem równości"] # 0x2ac5 + - "⫆": [T: "nadzbiór nad znakiem równości"] # 0x2ac6 + - "⫇": [T: "podzbiór nad operatorem tyldy"] # 0x2ac7 + - "⫈": [T: "nadzbiór nad operatorem tyldy"] # 0x2ac8 + - "⫉": [T: "podzbiór nad znakiem przybliżonej równości"] # 0x2ac9 + - "⫊": [T: "nadzbiór nad znakiem przybliżonej równości"] # 0x2aca + - "⫋": [T: "podzbiór nad nie równa się"] # 0x2acb + - "⫌": [T: "nadzbiór nad nie równa się"] # 0x2acc + - "⫍": [T: "kwadrat lewy otwórz ramka operator"] # 0x2acd + - "⫎": [T: "kwadrat prawy otwórz ramka operator"] # 0x2ace + - "⫏": [T: "zamknięty podzbiór"] # 0x2acf + - "⫐": [T: "zamknięty nadzbiór"] # 0x2ad0 + - "⫑": [T: "zamknięty podzbiór lub równe"] # 0x2ad1 + - "⫒": [T: "zamknięty nadzbiór lub równe"] # 0x2ad2 + - "⫓": [T: "podzbiór nad nadzbiór"] # 0x2ad3 + - "⫔": [T: "nadzbiór nad podzbiór"] # 0x2ad4 + - "⫕": [T: "podzbiór nad podzbiór"] # 0x2ad5 + - "⫖": [T: "nadzbiór nad nadzbiór"] # 0x2ad6 + - "⫗": [T: "nadzbiór obok podzbioru"] # 0x2ad7 + - "⫘": [T: "nadzbiór obok podzbioru połączony kreską"] # 0x2ad8 + - "⫙": [T: "należy do otwarte od dołu"] # 0x2ad9 + - "⫚": [T: "widły z górną poprzeczką"] # 0x2ada + - "⫛": [T: "poprzeczna część wspólna"] # 0x2adb + - "⫝̸": [T: "rozwidlanie"] # 0x2adc + - "⫝": [T: "nierozwidlanie"] # 0x2add + - "⫞": [T: "krótki lewy znacznik"] # 0x2ade + - "⫟": [T: "krótki dolny znacznik"] # 0x2adf + - "⫠": [T: "krótki górny znacznik"] # 0x2ae0 + - "⫡": [T: "prostopadłe z literą s"] # 0x2ae1 + - "⫢": [T: "pionowa kreska z potrójnym prawym znacznikiem dedukcji"] # 0x2ae2 + - "⫣": [T: "podwójna pionowa kreska z lewym znacznikiem dedukcji"] # 0x2ae3 + - "⫤": [T: "pionowa kreska z podwójnym lewym znacznikiem dedukcji"] # 0x2ae4 + - "⫥": [T: "podwójna pionowa kreska z podwójnym lewym znacznikiem dedukcji"] # 0x2ae5 + - "⫦": [T: "długa kreska od lewego elementu z podwójną pionową kreską"] # 0x2ae6 + - "⫧": [T: "krótki dolny znacznik z kreską nad"] # 0x2ae7 + - "⫨": [T: "krótki górny znacznik z podkreśleniem"] # 0x2ae8 + - "⫩": [T: "krótki górny znacznik nad krótkim dolnym znacznikiem"] # 0x2ae9 + - "⫪": [T: "podwójny dolny znacznik"] # 0x2aea + - "⫫": [T: "podwójny górny znacznik"] # 0x2aeb + - "⫬": [T: "znak negacji z podwójnym przekreśleniem"] # 0x2aec + - "⫭": [T: "odwrócony znak negacji z podwójnym przekreśleniem"] # 0x2aed + - "⫮": [T: "nie dzieli z odwróconym ukośnikiem negacji"] # 0x2aee + - "⫯": [T: "pionowa linia z okręgiem nad"] # 0x2aef + - "⫰": [T: "pionowa linia z okręgiem pod"] # 0x2af0 + - "⫱": [T: "dolny znacznik z okręgiem pod"] # 0x2af1 + - "⫲": [T: "równoległe z poziomą kreską"] # 0x2af2 + - "⫳": [T: "równoległe z operatorem tyldy"] # 0x2af3 + - "⫴": [T: "potrójna pionowa kreska jako relacja binarna"] # 0x2af4 + - "⫵": [T: "potrójna pionowa kreska z poziomą kreską"] # 0x2af5 + - "⫶": [T: "potrójny dwukropek operator"] # 0x2af6 + - "⫷": [T: "potrójnie zagnieżdżone mniejsze niż"] # 0x2af7 + - "⫸": [T: "potrójnie zagnieżdżone większe niż"] # 0x2af8 + - "⫹": [T: "podwójna linia ukośnie mniejsze lub równe"] # 0x2af9 + - "⫺": [T: "podwójna linia ukośnie większe lub równe"] # 0x2afa + - "⫻": [T: "potrójny ukośnik jako relacja binarna"] # 0x2afb + - "⫼": [T: "operator dużej potrójnej pionowej kreski"] # 0x2afc + - "⫽": [T: "podwójny ukośnik operator"] # 0x2afd + - "⫾": [T: "biała pionowa kreska"] # 0x2afe + - "⫿": [T: "biała pionowa kreska"] # 0x2aff + - "⬀": [T: "biała strzałka na północny wschód"] # 0x2b00 + - "⬁": [T: "biała strzałka na północny zachód"] # 0x2b01 + - "⬂": [T: "biała strzałka na południowy wschód"] # 0x2b02 + - "⬃": [T: "biała strzałka na południowy zachód"] # 0x2b03 + - "⬄": [T: "biała strzałka w lewo i w prawo"] # 0x2b04 + - "⬅": [T: "lewy czarny strzałka"] # 0x2b05 + - "⬆": [T: "górny czarny strzałka"] # 0x2b06 + - "⬇": [T: "dolny czarny strzałka"] # 0x2b07 + - "⬈": [T: "północ wschód czarny strzałka"] # 0x2b08 + - "⬉": [T: "północ zachód czarny strzałka"] # 0x2b09 + - "⬊": [T: "południe wschód czarny strzałka"] # 0x2b0a + - "⬋": [T: "południe zachód czarny strzałka"] # 0x2b0b + - "⬌": [T: "lewy prawy czarny strzałka"] # 0x2b0c + - "⬍": [T: "górny dolny czarny strzałka"] # 0x2b0d + - "⬎": [T: "strzałka w prawo z dolnym czubkiem"] # 0x2b0e + - "⬏": [T: "strzałka w prawo z górnym czubkiem"] # 0x2b0f + - "⬐": [T: "strzałka w lewo z dolnym czubkiem"] # 0x2b10 + - "⬑": [T: "strzałka w lewo z górnym czubkiem"] # 0x2b11 + - "⬒": [T: "kwadrat z górną połową czarną"] # 0x2b12 + - "⬓": [T: "kwadrat z dolną połową czarną"] # 0x2b13 + - "⬔": [T: "kwadrat z górną prawą ukośną połową czarną"] # 0x2b14 + - "⬕": [T: "kwadrat z dolną lewą ukośną połową czarną"] # 0x2b15 + - "⬖": [T: "romb z lewą połową czarną"] # 0x2b16 + - "⬗": [T: "romb z prawą połową czarną"] # 0x2b17 + - "⬘": [T: "romb z górną połową czarną"] # 0x2b18 + - "⬙": [T: "romb z dolną połową czarną"] # 0x2b19 + - "⬚": [T: "ramka"] # 0x2b1a + - "⬛": [T: "czarny duży kwadrat"] # 0x2b1b + - "⬜": [T: "biały duży kwadrat"] # 0x2b1c + - "⬝": [T: "czarny bardzo mały kwadrat"] # 0x2b1d + - "⬞": [T: "biały bardzo mały kwadrat"] # 0x2b1e + - "⬟": [T: "czarny pięciokąt"] # 0x2b1f + - "⬠": [T: "biały pięciokąt"] # 0x2b20 + - "⬡": [T: "biały sześciokąt"] # 0x2b21 + - "⬢": [T: "czarny sześciokąt"] # 0x2b22 + - "⬣": [T: "poziomy czarny sześciokąt"] # 0x2b23 + - "⬤": [T: "czarny duży okrąg"] # 0x2b24 + - "⬥": [T: "czarny średni romb"] # 0x2b25 + - "⬦": [T: "biały średni romb"] # 0x2b26 + - "⬧": [T: "czarny średni romb"] # 0x2b27 + - "⬨": [T: "biały średni romb"] # 0x2b28 + - "⬩": [T: "czarny mały romb"] # 0x2b29 + - "⬪": [T: "czarny mały romb"] # 0x2b2a + - "⬫": [T: "biały mały romb"] # 0x2b2b + - "⬬": [T: "czarna pozioma elipsa"] # 0x2b2c + - "⬭": [T: "biała pozioma elipsa"] # 0x2b2d + - "⬮": [T: "czarna pionowa elipsa"] # 0x2b2e + - "⬯": [T: "biała pionowa elipsa"] # 0x2b2f + - "⬰": [T: "strzałka w lewo z małym okręgiem"] # 0x2b30 + - "⬱": [T: "trzy strzałki w lewo"] # 0x2b31 + - "⬲": [T: "strzałka w lewo z plusem w kółku"] # 0x2b32 + - "⬳": [T: "długa falista strzałka w lewo"] # 0x2b33 + - "⬴": [T: "strzałka w lewo z dwoma grotami i pionowym przekreśleniem"] # 0x2b34 + - "⬵": [T: "strzałka w lewo z dwoma grotami i podwójnym pionowym przekreśleniem"] # 0x2b35 + - "⬶": [T: "strzałka w lewo z dwoma grotami od kreski"] # 0x2b36 + - "⬷": [T: "strzałka w lewo z dwoma grotami i potrójną kreską"] # 0x2b37 + - "⬸": [T: "strzałka w lewo z kropkowanym trzonem"] # 0x2b38 + - "⬹": [T: "strzałka w lewo z ogonem i pionową kreską"] # 0x2b39 + - "⬺": [T: "strzałka w lewo z ogonem i podwójną pionową kreską"] # 0x2b3a + - "⬻": [T: "strzałka w lewo z dwoma grotami i ogonem"] # 0x2b3b + - "⬼": [T: "strzałka w lewo z dwoma grotami, ogonem i pionowym przekreśleniem"] # 0x2b3c + - "⬽": [T: "strzałka w lewo z dwoma grotami, ogonem i podwójnym pionowym przekreśleniem"] # 0x2b3d + - "⬾": [T: "strzałka w lewo przez X"] # 0x2b3e + - "⬿": [T: "falista strzałka skierowana bezpośrednio w lewo"] # 0x2b3f + - "⭀": [T: "znak równości nad strzałką w lewo"] # 0x2b40 + - "⭁": [T: "operator odwrotnej tyldy nad strzałką w lewo"] # 0x2b41 + - "⭂": [T: "strzałka w lewo nad odwróconym znakiem przybliżonej równości"] # 0x2b42 + - "⭃": [T: "strzałka w prawo przez znak większe niż"] # 0x2b43 + - "⭄": [T: "strzałka w prawo przez znak nadzbioru"] # 0x2b44 + - "⭅": [T: "lewy poczwórny strzałka"] # 0x2b45 + - "⭆": [T: "prawy poczwórny strzałka"] # 0x2b46 + - "⭇": [T: "operator odwrotnej tyldy nad strzałką w prawo"] # 0x2b47 + - "⭈": [T: "strzałka w prawo nad odwróconym znakiem przybliżonej równości"] # 0x2b48 + - "⭉": [T: "operator tyldy nad strzałką w lewo"] # 0x2b49 + - "⭊": [T: "strzałka w lewo nad znakiem przybliżonej równości"] # 0x2b4a + - "⭋": [T: "strzałka w lewo nad operatorem odwrotnej tyldy"] # 0x2b4b + - "⭌": [T: "strzałka w prawo nad operatorem odwrotnej tyldy"] # 0x2b4c + - "⭐": [T: "biały średni gwiazda"] # 0x2b50 + - "⭑": [T: "czarny mały gwiazda"] # 0x2b51 + - "⭒": [T: "biały mały gwiazda"] # 0x2b52 + - "⭓": [T: "czarny prawy skierowany pięciokąt"] # 0x2b53 + - "⭔": [T: "biały prawy skierowany pięciokąt"] # 0x2b54 + - "⭕": [T: "gruby duży okrąg"] # 0x2b55 + - "⭖": [T: "gruby owal z owalem wewnątrz"] # 0x2b56 + - "⭗": [T: "gruby okrąg z okręgiem wewnątrz"] # 0x2b57 + - "⭘": [T: "gruby okrąg"] # 0x2b58 + - "⭙": [T: "gruby ukośny krzyż w kółku"] # 0x2b59 + - "⸀": [T: "kąt prosty znacznik podstawienia"] # 0x2e00 + - "⸁": [T: "kąt prosty kropkowany znacznik podstawienia"] # 0x2e01 + - "⸂": [T: "lewy nawias kwadratowy podstawienia"] # 0x2e02 + - "⸃": [T: "prawy nawias kwadratowy podstawienia"] # 0x2e03 + - "⸄": [T: "lewy kropkowany nawias kwadratowy podstawienia"] # 0x2e04 + - "⸅": [T: "prawy kropkowany nawias kwadratowy podstawienia"] # 0x2e05 + - "⸆": [T: "podniesiony znacznik interpolacji"] # 0x2e06 + - "⸇": [T: "podniesiony kropkowany znacznik interpolacji"] # 0x2e07 + - "⸈": [T: "kropkowany znacznik transpozycji"] # 0x2e08 + - "⸉": [T: "lewy nawias kwadratowy transpozycji"] # 0x2e09 + - "⸊": [T: "prawy nawias kwadratowy transpozycji"] # 0x2e0a + - "⸋": [T: "podniesiony kwadrat"] # 0x2e0b + - "⸌": [T: "lewy podniesiony pominięcia nawias kwadratowy"] # 0x2e0c + - "⸍": [T: "prawy podniesiony pominięcia nawias kwadratowy"] # 0x2e0d + - "⸎": [T: "redakcyjny koronis"] # 0x2e0e - "⸏": [T: "paragraphos"] # 0x2e0f - - "⸐": [t: "rozwidlony paragrafos"] # 0x2e10 - - "⸑": [t: "odwrócony rozwidlony paragrafos"] # 0x2e11 + - "⸐": [T: "rozwidlony paragrafos"] # 0x2e10 + - "⸑": [T: "odwrócony rozwidlony paragrafos"] # 0x2e11 - "⸒": [T: "hypodiastole"] # 0x2e12 - - "⸓": [t: "kropkowany obelos"] # 0x2e13 - - "⸔": [t: "dolny ancora"] # 0x2e14 - - "⸕": [t: "górny ancora"] # 0x2e15 - - "⸖": [t: "kropkowany kąt skierowany w prawo"] # 0x2e16 - - "⸗": [t: "podwójny ukośny łącznik"] # 0x2e17 - - "⸘": [t: "odwrócony interrobang"] # 0x2e18 - - "⸙": [t: "gałązka palmowa"] # 0x2e19 - - "⸚": [t: "łącznik z dierezą"] # 0x2e1a - - "⸛": [t: "tylda z pierścieniem nad"] # 0x2e1b - - "⸜": [t: "lewy dolny nawias kwadratowy parafrazy"] # 0x2e1c - - "⸝": [t: "prawy dolny nawias kwadratowy parafrazy"] # 0x2e1d - - "⸞": [t: "tylda z kropką nad"] # 0x2e1e - - "⸟": [t: "tylda z kropką pod"] # 0x2e1f - - "⸠": [t: "lewa pionowa kreska z piórem"] # 0x2e20 - - "⸡": [t: "prawa pionowa kreska z piórem"] # 0x2e21 - - "⸢": [t: "górny lewa połowa nawias kwadratowy"] # 0x2e22 - - "⸣": [t: "górny prawa połowa nawias kwadratowy"] # 0x2e23 - - "⸤": [t: "dolny lewa połowa nawias kwadratowy"] # 0x2e24 - - "⸥": [t: "dolny prawa połowa nawias kwadratowy"] # 0x2e25 - - "⸦": [t: "lewy obrócony nawias kwadratowy u"] # 0x2e26 - - "⸧": [t: "prawy obrócony nawias kwadratowy u"] # 0x2e27 - - "⸨": [t: "lewy podwójny nawias okrągły"] # 0x2e28 - - "⸩": [t: "prawy podwójny nawias okrągły"] # 0x2e29 - - "⸪": [t: "dwie kropki nad jedną kropką interpunkcyjną"] # 0x2e2a - - "⸫": [t: "jedna kropka nad dwiema kropkami interpunkcyjnymi"] # 0x2e2b - - "⸬": [t: "do kwadratu cztery kropka interpunkcyjny"] # 0x2e2c - - "⸭": [t: "pięć kropka znak"] # 0x2e2d - - "⸮": [t: "odwrócony zapytania znak"] # 0x2e2e - - "ⸯ": [t: "pionowy tylda"] # 0x2e2f - - "⸰": [t: "pierścień punkt"] # 0x2e30 - - "⸱": [t: "separator wyrazów środkowa kropka"] # 0x2e31 - - "⸲": [t: "odwrócony przecinek"] # 0x2e32 - - "⸳": [t: "podniesiony kropka"] # 0x2e33 - - "⸴": [t: "podniesiony przecinek"] # 0x2e34 - - "⸵": [t: "odwrócony średnik"] # 0x2e35 - - "⸶": [t: "obelisk z lewą osłoną"] # 0x2e36 - - "⸷": [t: "obelisk z prawą osłoną"] # 0x2e37 - - "⸸": [t: "odwrócony obelisk"] # 0x2e38 - - "⸹": [t: "górna połowa paragraf znak"] # 0x2e39 - - "⸺": [t: "dwa pauza"] # 0x2e3a - - "⸻": [t: "trzy pauza"] # 0x2e3b - - "〃": [t: "znak powtórzenia"] # 0x3003 - - "〈": [t: "lewy nawias kątowy"] # 0x3008 - - "〉": [t: "prawy nawias kątowy"] # 0x3009 - - "《": [t: "lewy podwójny nawias kątowy"] # 0x300a - - "》": [t: "prawy podwójny nawias kątowy"] # 0x300b - - "「": [t: "lewy nawias narożny"] # 0x300c - - "」": [t: "prawy nawias narożny"] # 0x300d - - "『": [t: "lewy biały nawias narożny"] # 0x300e - - "』": [t: "prawy biały nawias narożny"] # 0x300f - - "【": [t: "lewy czarny nawias soczewkowy"] # 0x3010 - - "】": [t: "prawy czarny nawias soczewkowy"] # 0x3011 - - "〔": [t: "lewy nawias skorupowy"] # 0x3014 - - "〕": [t: "prawy nawias skorupowy"] # 0x3015 - - "〖": [t: "lewy biały nawias soczewkowy"] # 0x3016 - - "〗": [t: "prawy biały nawias soczewkowy"] # 0x3017 - - "〘": [t: "lewy biały nawias skorupowy"] # 0x3018 - - "〙": [t: "prawy biały nawias skorupowy"] # 0x3019 - - "〚": [t: "lewy biały nawias kwadratowy"] # 0x301a - - "〛": [t: "prawy biały nawias kwadratowy"] # 0x301b - - "〜": [t: "falista kreska"] # 0x301c - - "〰": [t: "falista kreska"] # 0x3030 - - "㉈": [t: "liczba dziesięć w kółku na czarnym kwadracie"] # 0x3248 - - "㉉": [t: "liczba dwadzieścia w kółku na czarnym kwadracie"] # 0x3249 - - "㉊": [t: "liczba trzydzieści w kółku na czarnym kwadracie"] # 0x324a - - "㉋": [t: "liczba czterdzieści w kółku na czarnym kwadracie"] # 0x324b - - "㉌": [t: "liczba pięćdziesiąt w kółku na czarnym kwadracie"] # 0x324c - - "㉍": [t: "liczba sześćdziesiąt w kółku na czarnym kwadracie"] # 0x324d - - "㉎": [t: "liczba siedemdziesiąt w kółku na czarnym kwadracie"] # 0x324e - - "㉏": [t: "liczba osiemdziesiąt w kółku na czarnym kwadracie"] # 0x324f - - "㉑": [t: "w kółku numer dwadzieścia jeden"] # 0x3251 - - "㉒": [t: "w kółku numer dwadzieścia dwa"] # 0x3252 - - "㉓": [t: "w kółku numer dwadzieścia trzy"] # 0x3253 - - "㉔": [t: "w kółku numer dwadzieścia cztery"] # 0x3254 - - "㉕": [t: "w kółku numer dwadzieścia pięć"] # 0x3255 - - "㉖": [t: "w kółku numer dwadzieścia sześć"] # 0x3256 - - "㉗": [t: "w kółku numer dwadzieścia siedem"] # 0x3257 - - "㉘": [t: "w kółku numer dwadzieścia osiem"] # 0x3258 - - "㉙": [t: "w kółku numer dwadzieścia dziewięć"] # 0x3259 - - "㉚": [t: "w kółku numer trzydzieści"] # 0x325a - - "㉛": [t: "w kółku numer trzydzieści jeden"] # 0x325b - - "㉜": [t: "w kółku numer trzydzieści dwa"] # 0x325c - - "㉝": [t: "w kółku numer trzydzieści trzy"] # 0x325d - - "㉞": [t: "w kółku numer trzydzieści cztery"] # 0x325e - - "㉟": [t: "w kółku numer trzydzieści pięć"] # 0x325f - - "㊱": [t: "w kółku numer trzydzieści sześć"] # 0x32b1 - - "㊲": [t: "w kółku numer trzydzieści siedem"] # 0x32b2 (GPT-5.4 translation) - - "㊳": [t: "w kółku numer trzydzieści osiem"] # 0x32b3 (GPT-5.4 translation) - - "㊴": [t: "w kółku numer trzydzieści dziewięć"] # 0x32b4 (GPT-5.4 translation) - - "㊵": [t: "w kółku numer czterdzieści"] # 0x32b5 (GPT-5.4 translation) - - "㊶": [t: "w kółku numer czterdzieści jeden"] # 0x32b6 (GPT-5.4 translation) - - "㊷": [t: "w kółku numer czterdzieści dwa"] # 0x32b7 (GPT-5.4 translation) - - "㊸": [t: "w kółku numer czterdzieści trzy"] # 0x32b8 (GPT-5.4 translation) - - "㊹": [t: "w kółku numer czterdzieści cztery"] # 0x32b9 (GPT-5.4 translation) - - "㊺": [t: "w kółku numer czterdzieści pięć"] # 0x32ba (GPT-5.4 translation) - - "㊻": [t: "w kółku numer czterdzieści sześć"] # 0x32bb (GPT-5.4 translation) - - "㊼": [t: "w kółku numer czterdzieści siedem"] # 0x32bc (GPT-5.4 translation) - - "㊽": [t: "w kółku numer czterdzieści osiem"] # 0x32bd (GPT-5.4 translation) - - "㊾": [t: "w kółku numer czterdzieści dziewięć"] # 0x32be (GPT-5.4 translation) - - "㊿": [t: "w kółku numer pięćdziesiąt"] # 0x32bf (GPT-5.4 translation) - - "㋌": [t: "Merkury"] # 0x32cc - - "㋍": [t: "ergi"] # 0x32cd - - "㋎": [t: "elektron wolty"] # 0x32ce - - "㋏": [t: "znak ograniczonej odpowiedzialności"] # 0x32cf - - "㍱": [t: "hektopaskale"] # 0x3371 - - "㍲": [t: "daltony"] # 0x3372 - - "㍳": [t: "jednostki astronomiczne"] # 0x3373 - - "㍴": [t: "bary"] # 0x3374 + - "⸓": [T: "kropkowany obelos"] # 0x2e13 + - "⸔": [T: "dolny ancora"] # 0x2e14 + - "⸕": [T: "górny ancora"] # 0x2e15 + - "⸖": [T: "kropkowany kąt skierowany w prawo"] # 0x2e16 + - "⸗": [T: "podwójny ukośny łącznik"] # 0x2e17 + - "⸘": [T: "odwrócony interrobang"] # 0x2e18 + - "⸙": [T: "gałązka palmowa"] # 0x2e19 + - "⸚": [T: "łącznik z dierezą"] # 0x2e1a + - "⸛": [T: "tylda z pierścieniem nad"] # 0x2e1b + - "⸜": [T: "lewy dolny nawias kwadratowy parafrazy"] # 0x2e1c + - "⸝": [T: "prawy dolny nawias kwadratowy parafrazy"] # 0x2e1d + - "⸞": [T: "tylda z kropką nad"] # 0x2e1e + - "⸟": [T: "tylda z kropką pod"] # 0x2e1f + - "⸠": [T: "lewa pionowa kreska z piórem"] # 0x2e20 + - "⸡": [T: "prawa pionowa kreska z piórem"] # 0x2e21 + - "⸢": [T: "górny lewa połowa nawias kwadratowy"] # 0x2e22 + - "⸣": [T: "górny prawa połowa nawias kwadratowy"] # 0x2e23 + - "⸤": [T: "dolny lewa połowa nawias kwadratowy"] # 0x2e24 + - "⸥": [T: "dolny prawa połowa nawias kwadratowy"] # 0x2e25 + - "⸦": [T: "lewy obrócony nawias kwadratowy u"] # 0x2e26 + - "⸧": [T: "prawy obrócony nawias kwadratowy u"] # 0x2e27 + - "⸨": [T: "lewy podwójny nawias okrągły"] # 0x2e28 + - "⸩": [T: "prawy podwójny nawias okrągły"] # 0x2e29 + - "⸪": [T: "dwie kropki nad jedną kropką interpunkcyjną"] # 0x2e2a + - "⸫": [T: "jedna kropka nad dwiema kropkami interpunkcyjnymi"] # 0x2e2b + - "⸬": [T: "do kwadratu cztery kropka interpunkcyjny"] # 0x2e2c + - "⸭": [T: "pięć kropka znak"] # 0x2e2d + - "⸮": [T: "odwrócony zapytania znak"] # 0x2e2e + - "ⸯ": [T: "pionowy tylda"] # 0x2e2f + - "⸰": [T: "pierścień punkt"] # 0x2e30 + - "⸱": [T: "separator wyrazów środkowa kropka"] # 0x2e31 + - "⸲": [T: "odwrócony przecinek"] # 0x2e32 + - "⸳": [T: "podniesiony kropka"] # 0x2e33 + - "⸴": [T: "podniesiony przecinek"] # 0x2e34 + - "⸵": [T: "odwrócony średnik"] # 0x2e35 + - "⸶": [T: "obelisk z lewą osłoną"] # 0x2e36 + - "⸷": [T: "obelisk z prawą osłoną"] # 0x2e37 + - "⸸": [T: "odwrócony obelisk"] # 0x2e38 + - "⸹": [T: "górna połowa paragraf znak"] # 0x2e39 + - "⸺": [T: "dwa pauza"] # 0x2e3a + - "⸻": [T: "trzy pauza"] # 0x2e3b + - "〃": [T: "znak powtórzenia"] # 0x3003 + - "〈": [T: "lewy nawias kątowy"] # 0x3008 + - "〉": [T: "prawy nawias kątowy"] # 0x3009 + - "《": [T: "lewy podwójny nawias kątowy"] # 0x300a + - "》": [T: "prawy podwójny nawias kątowy"] # 0x300b + - "「": [T: "lewy nawias narożny"] # 0x300c + - "」": [T: "prawy nawias narożny"] # 0x300d + - "『": [T: "lewy biały nawias narożny"] # 0x300e + - "』": [T: "prawy biały nawias narożny"] # 0x300f + - "【": [T: "lewy czarny nawias soczewkowy"] # 0x3010 + - "】": [T: "prawy czarny nawias soczewkowy"] # 0x3011 + - "〔": [T: "lewy nawias skorupowy"] # 0x3014 + - "〕": [T: "prawy nawias skorupowy"] # 0x3015 + - "〖": [T: "lewy biały nawias soczewkowy"] # 0x3016 + - "〗": [T: "prawy biały nawias soczewkowy"] # 0x3017 + - "〘": [T: "lewy biały nawias skorupowy"] # 0x3018 + - "〙": [T: "prawy biały nawias skorupowy"] # 0x3019 + - "〚": [T: "lewy biały nawias kwadratowy"] # 0x301a + - "〛": [T: "prawy biały nawias kwadratowy"] # 0x301b + - "〜": [T: "falista kreska"] # 0x301c + - "〰": [T: "falista kreska"] # 0x3030 + - "㉈": [T: "liczba dziesięć w kółku na czarnym kwadracie"] # 0x3248 + - "㉉": [T: "liczba dwadzieścia w kółku na czarnym kwadracie"] # 0x3249 + - "㉊": [T: "liczba trzydzieści w kółku na czarnym kwadracie"] # 0x324a + - "㉋": [T: "liczba czterdzieści w kółku na czarnym kwadracie"] # 0x324b + - "㉌": [T: "liczba pięćdziesiąt w kółku na czarnym kwadracie"] # 0x324c + - "㉍": [T: "liczba sześćdziesiąt w kółku na czarnym kwadracie"] # 0x324d + - "㉎": [T: "liczba siedemdziesiąt w kółku na czarnym kwadracie"] # 0x324e + - "㉏": [T: "liczba osiemdziesiąt w kółku na czarnym kwadracie"] # 0x324f + - "㉑": [T: "w kółku numer dwadzieścia jeden"] # 0x3251 + - "㉒": [T: "w kółku numer dwadzieścia dwa"] # 0x3252 + - "㉓": [T: "w kółku numer dwadzieścia trzy"] # 0x3253 + - "㉔": [T: "w kółku numer dwadzieścia cztery"] # 0x3254 + - "㉕": [T: "w kółku numer dwadzieścia pięć"] # 0x3255 + - "㉖": [T: "w kółku numer dwadzieścia sześć"] # 0x3256 + - "㉗": [T: "w kółku numer dwadzieścia siedem"] # 0x3257 + - "㉘": [T: "w kółku numer dwadzieścia osiem"] # 0x3258 + - "㉙": [T: "w kółku numer dwadzieścia dziewięć"] # 0x3259 + - "㉚": [T: "w kółku numer trzydzieści"] # 0x325a + - "㉛": [T: "w kółku numer trzydzieści jeden"] # 0x325b + - "㉜": [T: "w kółku numer trzydzieści dwa"] # 0x325c + - "㉝": [T: "w kółku numer trzydzieści trzy"] # 0x325d + - "㉞": [T: "w kółku numer trzydzieści cztery"] # 0x325e + - "㉟": [T: "w kółku numer trzydzieści pięć"] # 0x325f + - "㊱": [T: "w kółku numer trzydzieści sześć"] # 0x32b1 + - "㊲": [T: "w kółku numer trzydzieści siedem"] # 0x32b2 (GPT-5.4 translation) + - "㊳": [T: "w kółku numer trzydzieści osiem"] # 0x32b3 (GPT-5.4 translation) + - "㊴": [T: "w kółku numer trzydzieści dziewięć"] # 0x32b4 (GPT-5.4 translation) + - "㊵": [T: "w kółku numer czterdzieści"] # 0x32b5 (GPT-5.4 translation) + - "㊶": [T: "w kółku numer czterdzieści jeden"] # 0x32b6 (GPT-5.4 translation) + - "㊷": [T: "w kółku numer czterdzieści dwa"] # 0x32b7 (GPT-5.4 translation) + - "㊸": [T: "w kółku numer czterdzieści trzy"] # 0x32b8 (GPT-5.4 translation) + - "㊹": [T: "w kółku numer czterdzieści cztery"] # 0x32b9 (GPT-5.4 translation) + - "㊺": [T: "w kółku numer czterdzieści pięć"] # 0x32ba (GPT-5.4 translation) + - "㊻": [T: "w kółku numer czterdzieści sześć"] # 0x32bb (GPT-5.4 translation) + - "㊼": [T: "w kółku numer czterdzieści siedem"] # 0x32bc (GPT-5.4 translation) + - "㊽": [T: "w kółku numer czterdzieści osiem"] # 0x32bd (GPT-5.4 translation) + - "㊾": [T: "w kółku numer czterdzieści dziewięć"] # 0x32be (GPT-5.4 translation) + - "㊿": [T: "w kółku numer pięćdziesiąt"] # 0x32bf (GPT-5.4 translation) + - "㋌": [T: "Merkury"] # 0x32cc + - "㋍": [T: "ergi"] # 0x32cd + - "㋎": [T: "elektron wolty"] # 0x32ce + - "㋏": [T: "znak ograniczonej odpowiedzialności"] # 0x32cf + - "㍱": [T: "hektopaskale"] # 0x3371 + - "㍲": [T: "daltony"] # 0x3372 + - "㍳": [T: "jednostki astronomiczne"] # 0x3373 + - "㍴": [T: "bary"] # 0x3374 - "㍵": [T: "o V"] # 0x3375 - - "㍶": [t: "parseki"] # 0x3376 - - "㍷": [t: "decymetry"] # 0x3377 - - "㍸": [t: "decymetry do kwadratu"] # 0x3378 - - "㍹": [t: "decymetry do sześcianu"] # 0x3379 - - "㍺": [t: "jednostki międzynarodowe"] # 0x337a - - "㎀": [t: "pikoampery"] # 0x3380 - - "㎁": [t: "nanoampery"] # 0x3381 - - "㎂": [t: "mikroampery"] # 0x3382 - - "㎃": [t: "miliampery"] # 0x3383 - - "㎄": [t: "kiloampery"] # 0x3384 - - "㎅": [t: "kilobajty"] # 0x3385 - - "㎆": [t: "megabajty"] # 0x3386 - - "㎇": [t: "gigabajty"] # 0x3387 - - "㎈": [t: "kalorie"] # 0x3388 - - "㎉": [t: "kilokalorie"] # 0x3389 - - "㎊": [t: "pikofarady"] # 0x338a - - "㎋": [t: "nanofarady"] # 0x338b - - "㎌": [t: "mikrofarady"] # 0x338c - - "㎍": [t: "mikrogramy"] # 0x338d - - "㎎": [t: "miligramy"] # 0x338e - - "㎏": [t: "kilogramy"] # 0x338f - - "㎐": [t: "herce"] # 0x3390 - - "㎑": [t: "kiloherce"] # 0x3391 - - "㎒": [t: "megaherce"] # 0x3392 - - "㎓": [t: "gigaherce"] # 0x3393 - - "㎔": [t: "teraherce"] # 0x3394 - - "㎕": [t: "mikrolitry"] # 0x3395 - - "㎖": [t: "mililitry"] # 0x3396 - - "㎗": [t: "decylitry"] # 0x3397 - - "㎘": [t: "kilolitry"] # 0x3398 - - "㎙": [t: "femtometry"] # 0x3399 - - "㎚": [t: "nanometry"] # 0x339a - - "㎛": [t: "mikrometry"] # 0x339b - - "㎜": [t: "milimetry"] # 0x339c - - "㎝": [t: "centymetry"] # 0x339d - - "㎞": [t: "kilometry"] # 0x339e - - "㎟": [t: "milimetry do kwadratu"] # 0x339f - - "㎠": [t: "centymetry do kwadratu"] # 0x33a0 - - "㎡": [t: "metry do kwadratu"] # 0x33a1 - - "㎢": [t: "kilometry do kwadratu"] # 0x33a2 - - "㎣": [t: "milimetry do sześcianu"] # 0x33a3 - - "㎤": [t: "centymetry do sześcianu"] # 0x33a4 - - "㎥": [t: "metry do sześcianu"] # 0x33a5 - - "㎦": [t: "kilometry do sześcianu"] # 0x33a6 - - "㎧": [t: "metry na drugi"] # 0x33a7 - - "㎨": [t: "metry na drugi do kwadratu"] # 0x33a8 - - "㎩": [t: "paskale"] # 0x33a9 - - "㎪": [t: "kilopaskale"] # 0x33aa - - "㎫": [t: "megapaskale"] # 0x33ab - - "㎬": [t: "gigapaskale"] # 0x33ac - - "㎭": [t: "radiany"] # 0x33ad - - "㎮": [t: "radiany na sekundę"] # 0x33ae - - "㎯": [t: "radiany na sekundę do kwadratu"] # 0x33af - - "㎰": [t: "pikosekundy"] # 0x33b0 - - "㎱": [t: "nanosekundy"] # 0x33b1 - - "㎲": [t: "mikrosekundy"] # 0x33b2 - - "㎳": [t: "milisekundy"] # 0x33b3 - - "㎴": [t: "pikowolty"] # 0x33b4 - - "㎵": [t: "nanowolty"] # 0x33b5 - - "㎶": [t: "mikrowolty"] # 0x33b6 - - "㎷": [t: "miliwolty"] # 0x33b7 - - "㎸": [t: "kilowolty"] # 0x33b8 - - "㎹": [t: "megawolty"] # 0x33b9 - - "㎺": [t: "pikowaty"] # 0x33ba - - "㎻": [t: "nanowaty"] # 0x33bb - - "㎼": [t: "mikrowaty"] # 0x33bc - - "㎽": [t: "miliwaty"] # 0x33bd - - "㎾": [t: "kilowaty"] # 0x33be - - "㎿": [t: "megawaty"] # 0x33bf - - "㏀": [t: "kilo omy"] # 0x33c0 - - "㏁": [t: "megaomy"] # 0x33c1 - - "㏂": [t: "A M"] # 0x33c2 - - "㏃": [t: "bekerele"] # 0x33c3 - - "㏄": [t: "centymetry sześcienne"] # 0x33c4 - - "㏅": [t: "kandele"] # 0x33c5 - - "㏆": [t: "kulomby na kilogram"] # 0x33c6 - - "㏇": [t: "wielkie C, o, kropka"] # 0x33c7 (I have no idea what this is) - - "㏈": [t: "decybele"] # 0x33c8 - - "㏉": [t: "greje"] # 0x33c9 - - "㏊": [t: "hektary"] # 0x33ca - - "㏋": [t: "konie mechaniczne"] # 0x33cb - - "㏌": [t: "cale"] # 0x33cc - - "㏍": [t: "kilokelwiny"] # 0x33cd - - "㏎": [t: "kilometry"] # 0x33ce - - "㏏": [t: "węzły"] # 0x33cf - - "㏐": [t: "lumeny"] # 0x33d0 + - "㍶": [T: "parseki"] # 0x3376 + - "㍷": [T: "decymetry"] # 0x3377 + - "㍸": [T: "decymetry do kwadratu"] # 0x3378 + - "㍹": [T: "decymetry do sześcianu"] # 0x3379 + - "㍺": [T: "jednostki międzynarodowe"] # 0x337a + - "㎀": [T: "pikoampery"] # 0x3380 + - "㎁": [T: "nanoampery"] # 0x3381 + - "㎂": [T: "mikroampery"] # 0x3382 + - "㎃": [T: "miliampery"] # 0x3383 + - "㎄": [T: "kiloampery"] # 0x3384 + - "㎅": [T: "kilobajty"] # 0x3385 + - "㎆": [T: "megabajty"] # 0x3386 + - "㎇": [T: "gigabajty"] # 0x3387 + - "㎈": [T: "kalorie"] # 0x3388 + - "㎉": [T: "kilokalorie"] # 0x3389 + - "㎊": [T: "pikofarady"] # 0x338a + - "㎋": [T: "nanofarady"] # 0x338b + - "㎌": [T: "mikrofarady"] # 0x338c + - "㎍": [T: "mikrogramy"] # 0x338d + - "㎎": [T: "miligramy"] # 0x338e + - "㎏": [T: "kilogramy"] # 0x338f + - "㎐": [T: "herce"] # 0x3390 + - "㎑": [T: "kiloherce"] # 0x3391 + - "㎒": [T: "megaherce"] # 0x3392 + - "㎓": [T: "gigaherce"] # 0x3393 + - "㎔": [T: "teraherce"] # 0x3394 + - "㎕": [T: "mikrolitry"] # 0x3395 + - "㎖": [T: "mililitry"] # 0x3396 + - "㎗": [T: "decylitry"] # 0x3397 + - "㎘": [T: "kilolitry"] # 0x3398 + - "㎙": [T: "femtometry"] # 0x3399 + - "㎚": [T: "nanometry"] # 0x339a + - "㎛": [T: "mikrometry"] # 0x339b + - "㎜": [T: "milimetry"] # 0x339c + - "㎝": [T: "centymetry"] # 0x339d + - "㎞": [T: "kilometry"] # 0x339e + - "㎟": [T: "milimetry do kwadratu"] # 0x339f + - "㎠": [T: "centymetry do kwadratu"] # 0x33a0 + - "㎡": [T: "metry do kwadratu"] # 0x33a1 + - "㎢": [T: "kilometry do kwadratu"] # 0x33a2 + - "㎣": [T: "milimetry do sześcianu"] # 0x33a3 + - "㎤": [T: "centymetry do sześcianu"] # 0x33a4 + - "㎥": [T: "metry do sześcianu"] # 0x33a5 + - "㎦": [T: "kilometry do sześcianu"] # 0x33a6 + - "㎧": [T: "metry na drugi"] # 0x33a7 + - "㎨": [T: "metry na drugi do kwadratu"] # 0x33a8 + - "㎩": [T: "paskale"] # 0x33a9 + - "㎪": [T: "kilopaskale"] # 0x33aa + - "㎫": [T: "megapaskale"] # 0x33ab + - "㎬": [T: "gigapaskale"] # 0x33ac + - "㎭": [T: "radiany"] # 0x33ad + - "㎮": [T: "radiany na sekundę"] # 0x33ae + - "㎯": [T: "radiany na sekundę do kwadratu"] # 0x33af + - "㎰": [T: "pikosekundy"] # 0x33b0 + - "㎱": [T: "nanosekundy"] # 0x33b1 + - "㎲": [T: "mikrosekundy"] # 0x33b2 + - "㎳": [T: "milisekundy"] # 0x33b3 + - "㎴": [T: "pikowolty"] # 0x33b4 + - "㎵": [T: "nanowolty"] # 0x33b5 + - "㎶": [T: "mikrowolty"] # 0x33b6 + - "㎷": [T: "miliwolty"] # 0x33b7 + - "㎸": [T: "kilowolty"] # 0x33b8 + - "㎹": [T: "megawolty"] # 0x33b9 + - "㎺": [T: "pikowaty"] # 0x33ba + - "㎻": [T: "nanowaty"] # 0x33bb + - "㎼": [T: "mikrowaty"] # 0x33bc + - "㎽": [T: "miliwaty"] # 0x33bd + - "㎾": [T: "kilowaty"] # 0x33be + - "㎿": [T: "megawaty"] # 0x33bf + - "㏀": [T: "kilo omy"] # 0x33c0 + - "㏁": [T: "megaomy"] # 0x33c1 + - "㏂": [T: "A M"] # 0x33c2 + - "㏃": [T: "bekerele"] # 0x33c3 + - "㏄": [T: "centymetry sześcienne"] # 0x33c4 + - "㏅": [T: "kandele"] # 0x33c5 + - "㏆": [T: "kulomby na kilogram"] # 0x33c6 + - "㏇": [T: "wielkie C, o, kropka"] # 0x33c7 (I have no idea what this is) + - "㏈": [T: "decybele"] # 0x33c8 + - "㏉": [T: "greje"] # 0x33c9 + - "㏊": [T: "hektary"] # 0x33ca + - "㏋": [T: "konie mechaniczne"] # 0x33cb + - "㏌": [T: "cale"] # 0x33cc + - "㏍": [T: "kilokelwiny"] # 0x33cd + - "㏎": [T: "kilometry"] # 0x33ce + - "㏏": [T: "węzły"] # 0x33cf + - "㏐": [T: "lumeny"] # 0x33d0 - "㏑": [T: "logarytm naturalny"] # 0x33d1 - - "㏒": [t: "logarytm"] # 0x33d2 - - "㏓": [t: "luksy"] # 0x33d3 - - "㏔": [t: "milibarny"] # 0x33d4 - - "㏕": [t: "mile"] # 0x33d5 - - "㏖": [t: "mole"] # 0x33d6 + - "㏒": [T: "logarytm"] # 0x33d2 + - "㏓": [T: "luksy"] # 0x33d3 + - "㏔": [T: "milibarny"] # 0x33d4 + - "㏕": [T: "mile"] # 0x33d5 + - "㏖": [T: "mole"] # 0x33d6 - "㏗": [T: "p h"] # 0x33d7 - - "㏘": [t: "pikometry"] # 0x33d8 - - "㏙": [t: "części na milion"] # 0x33d9 - - "㏚": [t: "petarentgeny"] # 0x33da - - "㏛": [t: "steradiany"] # 0x33db - - "㏜": [t: "siwerty"] # 0x33dc - - "㏝": [t: "webery"] # 0x33dd - - "㏞": [t: "wolty na metr"] # 0x33de - - "㏟": [t: "ampery na metr"] # 0x33df - - "㏿": [t: "galony"] # 0x33ff - - "": [t: "równa się z daszkiem pod"] # 0xe900 - - "": [t: "równa się z plusem nad"] # 0xe901 - - "": [t: "równa się z plusem pod"] # 0xe902 - - "": [t: "tylda z plusem nad"] # 0xe903 - - "": [t: "tylda z plusem pod"] # 0xe904 - - "": [t: "równe podwójny przez większe niż"] # 0xe908 - - "": [t: "równe podwójny przez mniejsze niż"] # 0xe909 - - "": [t: "zawiera lub równe"] # 0xe90a - - "": [t: "nadzbiór lub równy"] # 0xe90b - - "": [t: "podzbiór lub równy"] # 0xe90c - - "": [t: "równe przez mniejsze niż"] # 0xe90d - - "": [t: "należy do lub równe"] # 0xe912 - - "": [t: "równe lub większe niż"] # 0xe913 - - "": [t: "przybliżone nadzbiór"] # 0xe914 - - "": [t: "przybliżone podzbiór"] # 0xe915 - - "": [t: "nadzbiór z kropką zawiera jako relację indeksu dolnego"] # 0xe916 - - "": [t: "podzbiór z kropką jest zawarty jako relacja indeksu dolnego"] # 0xe917 - - "": [t: "równe z kropką pod"] # 0xe918 - - "": [t: "lewy kropka nad minus przez prawy kropka"] # 0xe919 - - "": [t: "prawy kropka nad minus przez lewy kropka"] # 0xe91a - - "": [t: "w przybliżeniu równe minus"] # 0xe91f - - "": [t: "podwójna kwadratowa suma zbiorów"] # 0xe920 - - "": [t: "podwójny kwadrat wielka"] # 0xe921 - - "": [t: "mniejsze niż równe lub większe niż"] # 0xe922 - - "": [t: "tylda z kropką"] # 0xe924 - - "": [t: "tylda z dwiema kropkami"] # 0xe925 - - "": [t: "mniejsze niż większe lub równe"] # 0xe926 - - "": [t: "większe niż mniejsze lub równe"] # 0xe927 - - "": [t: "Równoważne lub mniejsze niż"] # 0xe928 - - "": [t: "Równoważne lub większe niż"] # 0xe929 - - "": [t: "lewy otwórz ramka operator"] # 0xe92a - - "": [t: "prawy otwórz ramka operator"] # 0xe92b - - "": [t: "identyczne z kropką"] # 0xe92c - - "": [t: "większe niż równe lub mniejsze niż"] # 0xe92d - - "": [t: "kreska operator"] # 0xe92e - - "": [t: "podwójny kreska operator"] # 0xe92f - - "": [t: "potrójny kreska operator"] # 0xe930 - - "": [t: "mniejsze niż lub w przybliżeniu równe"] # 0xe932 - - "": [t: "większe niż lub w przybliżeniu równe"] # 0xe933 - - "": [t: "zagnieżdżone mniejsze niż"] # 0xe936 - - "": [t: "zagnieżdżone większe niż"] # 0xe937 - - "": [t: "poprzedza lub Równoważne"] # 0xe93a - - "": [t: "następuje po lub Równoważne"] # 0xe93b - - "": [t: "poprzedza nad równe"] # 0xe940 - - "": [t: "następuje po nad równe"] # 0xe941 - - "": [t: "mniejsze niż nad ukośnie równe nad większe niż"] # 0xe942 - - "": [t: "większe niż nad ukośnie równe nad mniejsze niż"] # 0xe943 - - "": [t: "spełnione przez"] # 0xe948 - - "": [t: "leniwe s"] # 0xe949 - - "": [t: "nie asercja"] # 0xe94a - - "": [t: "podwójny równe"] # 0xe94b - - "": [t: "potrójny równe"] # 0xe94c - - "": [t: "reguła opóźniona"] # 0xe94d - - "": [t: "alias ogranicznika"] # 0xe94e - - "": [t: "normalna podgrupa z kreską"] # 0xe950 - - "": [t: "zawiera jako normalny podgrupa z kreską"] # 0xe951 - - "": [t: "zaokrąglone implikuje"] # 0xe954 - - "": [t: "uśmiech pod kreską"] # 0xe955 - - "": [t: "smutek przez kreskę"] # 0xe956 - - "": [t: "nadzbiór lub w przybliżeniu równe"] # 0xe957 - - "": [t: "podzbiór lub w przybliżeniu równe"] # 0xe958 - - "": [t: "większe niż w przybliżeniu równe lub mniejsze niż"] # 0xe959 - - "": [t: "mniejsze niż w przybliżeniu równe lub większe niż"] # 0xe95a - - "": [t: "podwójny logiczne lub"] # 0xe95c - - "": [t: "podwójna koniunkcja logiczna"] # 0xe95d - - "": [t: "alternatywa logiczna z podwójną kreską pod"] # 0xe95e - - "": [t: "logiczne lub z kreską pod"] # 0xe95f - - "": [t: "w przybliżeniu równe nad równe"] # 0xe962 - - "": [t: "trójkąt skierowany w lewo z kreską dzielącą"] # 0xe964 - - "": [t: "trójkąt skierowany w prawo z kreską dzielącą"] # 0xe965 - - "": [t: "równa się z kropkowaną górną linią"] # 0xe966 - - "": [t: "poprzedza z dwukropkiem"] # 0xe967 - - "": [t: "następuje po z dwukropkiem"] # 0xe968 - - "": [t: "mniejsze niż lub ukośnie równe"] # 0xe969 - - "": [t: "większe niż lub ukośnie równe"] # 0xe96a - - "": [t: "zagnieżdżone bardzo znacznie mniejsze niż"] # 0xe96b - - "": [t: "zagnieżdżone bardzo znacznie większe niż"] # 0xe96c - - "": [t: "wariant różnicy między"] # 0xe96d - - "": [t: "mniejsze niż większe niż nakładka"] # 0xe96e - - "": [t: "alternatywa logiczna z nałożoną koniunkcją logiczną"] # 0xe96f - - "": [t: "nadzbiór przez nadzbiór"] # 0xe970 - - "": [t: "podzbiór przez podzbiór"] # 0xe971 - - "": [t: "nadzbiór przez podzbiór"] # 0xe972 - - "": [t: "podzbiór przez nadzbiór"] # 0xe973 - - "": [t: "potrójna pionowa kreska"] # 0xe979 - - "": [t: "sparowane poczwórne pionowe kropki"] # 0xe97a - - "": [t: "prostopadłe przez kreskę"] # 0xe97b - - "": [t: "lewy znak dedukcji z podwójną pionową kreską"] # 0xe97c - - "": [t: "podwójny lewy znak dedukcji z podwójną pionową kreską"] # 0xe97d - - "": [t: "prostopadłe przez odwrócony prostopadłe"] # 0xe97e - - "": [t: "podwójny lewy znak dedukcji z pionową kreską"] # 0xe97f - - "": [t: "kąt sferyczny otwarty w górę"] # 0xe980 - - "": [t: "podwójny ukośnik"] # 0xe981 - - "": [t: "kąt prosty z narożnikiem"] # 0xe982 - - "": [t: "pionowa kreska w kółku"] # 0xe984 - - "": [t: "znak dzielenia w kółku"] # 0xe985 - - "": [t: "kreskowany ukośnik"] # 0xe986 - - "": [t: "kreskowany ukośnik odwrotny"] # 0xe987 - - "": [t: "kreskowana linia środkowa"] # 0xe988 - - "": [t: "kreskowana pionowa kreska"] # 0xe989 - - "": [t: "prostopadłe z s"] # 0xe98a - - "": [t: "kąt z s"] # 0xe98b - - "": [t: "kąt sferyczny otwarty w lewo"] # 0xe98c - - "": [t: "kąt otwarty w lewo"] # 0xe98d - - "": [t: "pionowa kreska z podwójnym haczykiem"] # 0xe98e - - "": [t: "operator średniej kropki wolnego rodnika"] # 0xe98f - - "": [t: "biały trójkąt skierowany w górę nad kreską"] # 0xe990 - - "": [t: "identyczne i równoległe do"] # 0xe991 - - "": [t: "iloczyn spłaszczony"] # 0xe992 - - "": [t: "potrójny operator kreski z kreską poziomą"] # 0xe993 - - "": [t: "identyczne z podwójnym ukośnikiem"] # 0xe994 - - "": [t: "potrójne skrzyżowane kreski"] # 0xe995 - - "": [t: "pionowa kreska przez okrąg"] # 0xe996 - - "": [t: "pionowy proporcjonalne do"] # 0xe997 - - "": [t: "czarna ostatnia kwadra księżyca"] # 0xe998 - - "": [t: "czarna pierwsza kwadra księżyca"] # 0xe999 - - "": [t: "ujemna fala sinusoidalna"] # 0xe9a0 - - "": [t: "kropka w nawiasach"] # 0xe9a1 - - "": [t: "nawiasy"] # 0xe9a2 - - "": [t: "biały uśmiech"] # 0xe9a3 - - "": [t: "biały smutek"] # 0xe9a4 - - "": [t: "sześciokąt"] # 0xe9a5 - - "": [t: "Równoważne nad plus"] # 0xe9a6 - - "": [t: "plus przez Równoważne"] # 0xe9a7 - - "": [t: "część wspólna z szeryfami"] # 0xe9b0 - - "": [t: "suma zbiorów z szeryfami"] # 0xe9b1 - - "": [t: "kwadratowa część wspólna z szeryfami"] # 0xe9b2 - - "": [t: "kwadratowa suma zbiorów z szeryfami"] # 0xe9b3 - - "": [t: "poprzedza Równoważne lub następuje po"] # 0xe9e0 - - "": [t: "następuje po Równoważne lub poprzedza"] # 0xe9e1 - - "": [t: "poprzedza w przybliżeniu równe lub następuje po"] # 0xe9e2 - - "": [t: "następuje po w przybliżeniu równe lub poprzedza"] # 0xe9e3 - - "": [t: "mniejsze niż Równoważne lub większe niż"] # 0xe9f0 - - "": [t: "większe niż Równoważne lub mniejsze niż"] # 0xe9f1 - - "": [t: "pionowo przekreślone znacznie mniejsze niż"] # 0xea00 - - "": [t: "pionowo przekreślone znacznie większe niż"] # 0xea01 - - "": [t: "nie jest znacznie mniejsze niż, wariant"] # 0xea02 - - "": [t: "nie jest znacznie większe niż, wariant"] # 0xea03 - - "": [t: "mniejsze niż z pionową kreską i nie podwójne równe"] # 0xea04 - - "": [t: "większe niż z pionową kreską i nie podwójne równe"] # 0xea05 - - "": [t: "nie mniejsze lub równe"] # 0xea06 - - "": [t: "nie większe lub równe"] # 0xea07 - - "": [t: "ani równe, ani mniejsze niż"] # 0xea09 - - "": [t: "nie zawiera lub równe"] # 0xea0a - - "": [t: "ani nadzbiór, ani równe"] # 0xea0b - - "": [t: "ani podzbiór, ani równe"] # 0xea0c - - "": [t: "ukośnik odwrotny z podzbiorem"] # 0xea0d - - "": [t: "ani równe, ani większe niż"] # 0xea0e - - "": [t: "nie minus operator tyldy"] # 0xea0f - - "": [t: "ani równe, ani mniejsze niż"] # 0xea10 - - "": [t: "nie operator tyldy"] # 0xea11 - - "": [t: "nie jest elementem zbioru lub równe"] # 0xea12 - - "": [t: "ani równe, ani większe niż"] # 0xea13 - - "": [t: "nie w przybliżeniu równe"] # 0xea14 - - "": [t: "nie następuje po podobne"] # 0xea15 - - "": [t: "mniejsze niż lub ukośnie równe z ukośnikiem"] # 0xea16 - - "": [t: "większe niż lub ukośnie równe z ukośnikiem"] # 0xea17 - - "": [t: "nadzbiór ukośnik"] # 0xea1a - - "": [t: "nie zawiera"] # 0xea1b - - "": [t: "nie mniejsze lub równe"] # 0xea1d - - "": [t: "nie większe lub równe"] # 0xea1e - - "": [t: "nie w przybliżeniu równe minus"] # 0xea1f - - "": [t: "zanegowana przynależność do zbioru z kropką nad"] # 0xea22 - - "": [t: "nie kąt pionowy"] # 0xea2c - - "": [t: "nie ukośnie równoległe"] # 0xea2d - - "": [t: "nie kreska operator"] # 0xea2e - - "": [t: "nie podwójny kreska operator"] # 0xea2f - - "": [t: "nie potrójny kreska operator"] # 0xea30 - - "": [t: "mniejsze niż ale nie w przybliżeniu równe"] # 0xea32 - - "": [t: "większe niż ale nie w przybliżeniu równe"] # 0xea33 - - "": [t: "mniejsze niż lub nie równa się"] # 0xea34 - - "": [t: "większe niż lub nie równa się"] # 0xea35 - - "": [t: "nie zagnieżdżone mniejsze niż"] # 0xea36 - - "": [t: "nie zagnieżdżone większe niż"] # 0xea37 - - "": [t: "nie jest znacznie mniejsze niż"] # 0xea38 - - "": [t: "nie jest znacznie większe niż"] # 0xea39 - - "": [t: "poprzedza ale nie Równoważne"] # 0xea3a - - "": [t: "następuje po ale nie Równoważne"] # 0xea3b - - "": [t: "poprzedza ale nie równa się"] # 0xea3c - - "": [t: "następuje po ale nie równa się"] # 0xea3d - - "": [t: "nie równa się ani nie poprzedza"] # 0xea3e - - "": [t: "nie równa się ani nie następuje po"] # 0xea3f - - "": [t: "poprzedza ale nie równa się"] # 0xea40 - - "": [t: "następuje po ale nie równa się"] # 0xea41 - - "": [t: "ani podzbiór, ani równe"] # 0xea42 - - "": [t: "ani nadzbiór, ani równe"] # 0xea43 - - "": [t: "podzbiór lub nie równa się"] # 0xea44 - - "": [t: "nadzbiór lub nie równa się"] # 0xea45 - - "": [t: "ani podzbiór, ani równe"] # 0xea46 - - "": [t: "ani nadzbiór, ani równe"] # 0xea47 - - "": [t: "nie potrójny mniejsze niż"] # 0xea48 - - "": [t: "nie potrójny większe niż"] # 0xea49 - - "": [t: "nie poprzedza równa się"] # 0xea4c - - "": [t: "nie następuje po równa się"] # 0xea4d - - "": [t: "nie normalna podgrupa z kreską"] # 0xea50 - - "": [t: "nie zawiera jako normalnej podgrupy z kreską"] # 0xea51 - - "": [t: "nie różnica między"] # 0xea52 - - "": [t: "nie geometrycznie równoważne"] # 0xea53 - - "": [t: "nie pionowo podobne"] # 0xea54 - - "": [t: "nie równe lub podobne"] # 0xea55 - - "": [t: "nie pionowo przybliżone"] # 0xea56 - - "": [t: "nie w przybliżeniu identyczne z"] # 0xea57 - - "": [t: "nie wyboiście równe"] # 0xea58 - - "": [t: "nie wyboiście pojedynczo równe"] # 0xea59 - - "": [t: "nie równe kropka"] # 0xea5a - - "": [t: "odwrotne nie równoważne"] # 0xea5b - - "": [t: "nie kwadrat podzbiór"] # 0xea60 - - "": [t: "nie kwadrat nadzbiór"] # 0xea61 - - "": [t: "nie w przybliżeniu równe nad znakiem równości"] # 0xea62 - - "": [t: "nie ściśle równoważne"] # 0xea63 - - "": [t: "nie przystające z kropką"] # 0xea64 - - "": [t: "odwrotnie nie równe"] # 0xea65 - - "": [t: "nie pionowy lewy trójkąt równa się"] # 0xea70 - - "": [t: "nie pionowy prawy trójkąt równa się"] # 0xea71 - - "": [t: "nie cząstkowe"] # 0xea80 - - "": [t: "ozdobnik przedłużenia strzałki"] # 0xeb00 - - "": [t: "strzałka prawy przeze strzałką lewy"] # 0xeb01 - - "": [t: "strzałka prawy przeze strzałką lewy"] # 0xeb02 - - "": [t: "harpun prawy przez harpun lewy"] # 0xeb03 - - "": [t: "harpun prawy przez harpun lewy"] # 0xeb04 - - "": [t: "podwójna strzałka północny wschód południowy zachód"] # 0xeb05 - - "": [t: "podwójna strzałka północny zachód południowy wschód"] # 0xeb06 - - "": [t: "poziome przedłużenie harpuna"] # 0xeb07 - - "": [t: "łuk ze strzałką w lewo przeciwnie do ruchu wskazówek zegara"] # 0xeb08 - - "": [t: "łuk ze strzałką w prawo przeciwnie do ruchu wskazówek zegara"] # 0xeb09 - - "": [t: "duży strzałka w prawo akcent"] # 0xeb0b - - "": [t: "duży strzałka w lewo akcent"] # 0xeb0c - - "": [t: "lewy grot strzałki"] # 0xeb0d - - "": [t: "prawy grot strzałki"] # 0xeb0e - - "": [t: "duża strzałka w prawo z lewym przekreśleniem"] # 0xeb0f - - "": [t: "poziome przedłużenie podwójnej strzałki"] # 0xeb10 - - "": [t: "duża podwójna strzałka w lewo i prawo z przekreśleniem"] # 0xeb11 - - "": [t: "strzałka w dół po lewej i strzałka w górę"] # 0xeb12 - - "": [t: "strzałka w lewo z dolnym narożnikiem"] # 0xeb13 - - "": [t: "strzałka w prawo z górnym narożnikiem"] # 0xeb14 - - "": [t: "strzałka w lewo z górnym narożnikiem"] # 0xeb15 - - "": [t: "strzałka po górnym półokręgu przeciwnie do ruchu wskazówek zegara z plusem"] # 0xeb16 - - "": [t: "strzałka po górnym półokręgu zgodnie z ruchem wskazówek zegara z minusem"] # 0xeb17 - - "": [t: "strzałka w prawo z ogonem i przekreśleniem"] # 0xeb18 - - "": [t: "prawy harpun dolny"] # 0xeb19 - - "": [t: "lewy harpun dolny"] # 0xeb1a - - "": [t: "lewy prawy harpun dolny"] # 0xeb1b - - "": [t: "lewy prawy harpun górny"] # 0xeb1c - - "": [t: "górny dolny harpun lewy"] # 0xeb1d - - "": [t: "górny dolny harpun prawy"] # 0xeb1e - - "": [t: "strzałka w górę w prawo ze strzałką w dół"] # 0xeb1f - - "": [t: "lewy harpun do kreski z grotem górnym"] # 0xeb20 - - "": [t: "prawy harpun do kreski z grotem górnym"] # 0xeb21 - - "": [t: "lewy harpun do kreski z grotem dolnym"] # 0xeb22 - - "": [t: "prawy harpun do kreski z grotem dolnym"] # 0xeb23 - - "": [t: "lewy harpun od kreski z grotem górnym"] # 0xeb24 - - "": [t: "prawy harpun od kreski z grotem górnym"] # 0xeb25 - - "": [t: "lewy harpun od kreski z grotem dolnym"] # 0xeb26 - - "": [t: "prawy harpun od kreski z grotem dolnym"] # 0xeb27 - - "": [t: "górny harpun do kreski z grotem lewym"] # 0xeb28 - - "": [t: "dolny harpun do kreski z grotem lewym"] # 0xeb29 - - "": [t: "górny harpun do kreski z grotem prawym"] # 0xeb2a - - "": [t: "dolny harpun do kreski z grotem prawym"] # 0xeb2b - - "": [t: "górny harpun od kreski z grotem lewym"] # 0xeb2c - - "": [t: "dolny harpun od kreski z grotem lewym"] # 0xeb2d - - "": [t: "górny harpun od kreski z grotem prawym"] # 0xeb2e - - "": [t: "dolny harpun od kreski z grotem prawym"] # 0xeb2f - - "": [t: "strzałka w górę do kreski"] # 0xeb30 - - "": [t: "strzałka w dół do kreski"] # 0xeb31 - - "": [t: "górny harpun w lewo z dolnym harpunem"] # 0xeb32 - - "": [t: "górny harpun w prawo z dolnym harpunem"] # 0xeb33 - - "": [t: "górny grot strzałki"] # 0xeb34 - - "": [t: "dolny grot strzałki"] # 0xeb35 - - "": [t: "podwójny harpun z lewym grotem dolnym i prawym grotem górnym"] # 0xeb36 - - "": [t: "podwójny harpun z lewym grotem górnym i prawym grotem dolnym"] # 0xeb37 - - "": [t: "strzałka w lewo przez kreskę"] # 0xeb38 - - "": [t: "strzałka w prawo przez kreskę"] # 0xeb39 - - "": [t: "strzałka w lewo pod kreski"] # 0xeb3a - - "": [t: "strzałka w prawo pod kreski"] # 0xeb3b - - "": [t: "lewy prawy potrójny strzałka"] # 0xeb3c - - "": [t: "podwójna strzałka północny wschód południowy wschód"] # 0xeb3f - - "": [t: "strzałka po lewym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0xeb40 - - "": [t: "strzałka po lewym półokręgu zgodnie z ruchem wskazówek zegara"] # 0xeb41 - - "": [t: "lewy otwarty okrąg lewy strzałka w prawo"] # 0xeb42 - - "": [t: "strzałka w prawo przez tylda"] # 0xeb44 - - "": [t: "strzałka w lewo przez tylda"] # 0xeb45 - - "": [t: "lewy harpun przez kreskę"] # 0xeb48 - - "": [t: "prawy harpun przez kreskę"] # 0xeb49 - - "": [t: "lewy harpun pod kreski"] # 0xeb4a - - "": [t: "prawy harpun pod kreski"] # 0xeb4b - - "": [t: "krótka czarna strzałka w lewo"] # 0xeb4c - - "": [t: "strzałka po prawym półokręgu zgodnie z ruchem wskazówek zegara"] # 0xeb50 - - "": [t: "strzałka po prawym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0xeb51 - - "": [t: "lewy otwarty okrąg lewy prawy harpun"] # 0xeb52 - - "": [t: "strzałka w górę lewy z pionową kreską"] # 0xeb58 - - "": [t: "strzałka w dół lewy z pionową kreską"] # 0xeb59 - - "": [t: "strzałka w górę prawy z pionową kreską"] # 0xeb5a - - "": [t: "strzałka w dół prawy z pionową kreską"] # 0xeb5b - - "": [t: "strzałka w prawo z wydłużonym dolnym hakiem"] # 0xeb5c - - "": [t: "strzałka w lewo z wydłużonym hakiem"] # 0xeb5d - - "": [t: "strzałka w lewo z wydłużonym dolnym hakiem"] # 0xeb5e - - "": [t: "strzałka w prawo z wydłużonym hakiem"] # 0xeb5f - - "": [t: "nie strzałka w prawo falista"] # 0xeb60 - - "": [t: "nie strzałka w prawo zakrzywiony"] # 0xeb61 - - "": [t: "górny harpun lewy z pionową kreską"] # 0xeb68 - - "": [t: "dolny harpun lewy z pionową kreską"] # 0xeb69 - - "": [t: "górny harpun prawy z pionową kreską"] # 0xeb6a - - "": [t: "dolny harpun prawy z pionową kreską"] # 0xeb6b - - "": [t: "pionowe przedłużenie podwójnej strzałki"] # 0xeb6c - - "": [t: "pionowe przedłużenie harpuna z grotem w lewo"] # 0xeb6d - - "": [t: "pionowe przedłużenie harpuna z grotem w prawo"] # 0xeb6e - - "": [t: "prawy harpun przez lewy harpun prawy"] # 0xeb6f - - "": [t: "prawy harpun przez lewy harpun lewy"] # 0xeb70 - - "": [t: "lewy harpun przez prawy harpun prawy"] # 0xeb71 - - "": [t: "lewy harpun przez prawy harpun lewy"] # 0xeb72 - - "": [t: "strzałka w lewo od kreski z grotem strzałki"] # 0xeb73 - - "": [t: "przedłużenie strzałki w prawo od lewej kreski"] # 0xeb74 - - "": [t: "strzałka w lewo od kreski ogon"] # 0xeb75 - - "": [t: "strzałka w prawo od kreski ogon"] # 0xeb76 - - "": [t: "strzałka w prawo od kreski z grotem strzałki"] # 0xeb77 - - "": [t: "górny harpun od kreski z lewym grotem strzałki"] # 0xeb78 - - "": [t: "strzałka w prawo nad strzałką w lewo prawy"] # 0xeb79 - - "": [t: "strzałka w prawo nad strzałką w lewo lewy"] # 0xeb7a - - "": [t: "strzałka w lewo nad strzałką w prawo prawy"] # 0xeb7b - - "": [t: "strzałka w lewo nad strzałką w prawo lewy"] # 0xeb7c - - "": [t: "strzałka w górę od kreski z grotem strzałki"] # 0xeb7d - - "": [t: "strzałka w górę od kreski ogon"] # 0xeb7e - - "": [t: "strzałka w dół od kreski ogon"] # 0xeb7f - - "": [t: "strzałka w dół od kreski z grotem strzałki"] # 0xeb80 - - "": [t: "dolny harpun od kreski z prawym grotem strzałki"] # 0xeb81 - - "": [t: "górny harpun w lewo z dolnym harpunem dolny"] # 0xeb82 - - "": [t: "przedłużenie górnego harpuna w lewo i dolnego harpuna"] # 0xeb83 - - "": [t: "dolny harpun w lewo z górnym harpunem górny"] # 0xeb84 - - "": [t: "górny harpun w lewo z dolnym harpunem górny"] # 0xeb85 - - "": [t: "przedłużenie dolnego harpuna w lewo i górnego harpuna"] # 0xeb86 - - "": [t: "dolny harpun w lewo z górnym harpunem dolny"] # 0xeb87 - - "": [t: "strzałka w górę po lewej i strzałka w dół dolny"] # 0xeb88 - - "": [t: "strzałka w dół po lewej i strzałka w górę górny"] # 0xeb89 - - "": [t: "strzałka w górę po lewej i strzałka w dół górny"] # 0xeb8a - - "": [t: "strzałka w dół po lewej i strzałka w górę dolny"] # 0xeb8b - - "": [t: "przedłużenie strzałki w lewo i w prawo"] # 0xeb8c - - "": [t: "przedłużenie strzałki północno-wschodniej"] # 0xeb8d - - "": [t: "przedłużenie strzałki północno-zachodniej"] # 0xeb8e - - "": [t: "lewa część dolnego nawiasu klamrowego"] # 0xec00 - - "": [t: "środkowa część dolnego nawiasu klamrowego"] # 0xec01 - - "": [t: "prawa część dolnego nawiasu klamrowego"] # 0xec02 - - "": [t: "poziome przedłużenie nawiasu klamrowego"] # 0xec03 - - "": [t: "lewa część górnego nawiasu klamrowego"] # 0xec04 - - "": [t: "środkowa część górnego nawiasu klamrowego"] # 0xec05 - - "": [t: "prawa część górnego nawiasu klamrowego"] # 0xec06 - - "": [t: "lewa pionowa kreska"] # 0xec07 - - "": [t: "prawa pionowa kreska"] # 0xec08 - - "": [t: "lewa podwójna pionowa kreska"] # 0xec09 - - "": [t: "prawa podwójna pionowa kreska"] # 0xec0a - - "": [t: "poziome przedłużenie nawiasu kwadratowego"] # 0xec0b - - "": [t: "dolny nawias kwadratowy"] # 0xec0c - - "⎵": [t: "dolny nawias kwadratowy"] # 0x23b5 - - "": [t: "górny nawias kwadratowy"] # 0xec0d - - "⎴": [t: "górny nawias kwadratowy"] # 0x23b4 - - "": [t: "pod nawias kwadratowy lewy"] # 0xec0e - - "": [t: "pod nawias kwadratowy prawy"] # 0xec0f - - "": [t: "przez nawias kwadratowy lewy"] # 0xec10 - - "": [t: "przez nawias kwadratowy prawy"] # 0xec11 - - "": [t: "lewy nawias okrągły 1"] # 0xec12 - - "": [t: "lewy nawias okrągły 2"] # 0xec13 - - "": [t: "lewy nawias okrągły 3"] # 0xec14 - - "": [t: "lewy nawias okrągły 4"] # 0xec15 - - "": [t: "prawy nawias okrągły 1"] # 0xec16 - - "": [t: "prawy nawias okrągły 2"] # 0xec17 - - "": [t: "prawy nawias okrągły 3"] # 0xec18 - - "": [t: "prawy nawias okrągły 4"] # 0xec19 - - "": [t: "znak pierwiastka 1"] # 0xec1a - - "": [t: "znak pierwiastka 2"] # 0xec1b - - "": [t: "znak pierwiastka 3"] # 0xec1c - - "": [t: "znak pierwiastka 4"] # 0xec1d - - "": [t: "znak pierwiastka 5"] # 0xec1e - - "": [t: "dolna część znaku pierwiastka"] # 0xec1f - - "": [t: "pionowe przedłużenie znaku pierwiastka"] # 0xec20 - - "": [t: "górna część znaku pierwiastka"] # 0xec21 - - "": [t: "lewy biały nawias kwadratowy górny"] # 0xec22 - - "": [t: "przedłużenie lewego białego nawiasu kwadratowego"] # 0xec23 - - "": [t: "lewy biały nawias kwadratowy dolny"] # 0xec24 - - "": [t: "prawy biały nawias kwadratowy górny"] # 0xec25 - - "": [t: "przedłużenie prawego białego nawiasu kwadratowego"] # 0xec26 - - "": [t: "prawy biały nawias kwadratowy dolny"] # 0xec27 - - "": [t: "lewy biały zakrzywiony nawias kwadratowy"] # 0xec30 - - "": [t: "prawy biały zakrzywiony nawias kwadratowy"] # 0xec31 - - "": [t: "znak dzielenia pisemnego"] # 0xec32 - - "": [t: "przedłużenie znaku dzielenia pisemnego"] # 0xec33 - - "": [t: "krótkie dzielenie"] # 0xec34 - - "": [t: "podwójne wiązanie em od południowego zachodu do północnego wschodu"] # 0xec40 - - "": [t: "podwójne wiązanie em od północnego zachodu do południowego wschodu"] # 0xec41 - - "": [t: "pojedyncze poziome wiązanie em"] # 0xec42 - - "": [t: "podwójne poziome wiązanie em"] # 0xec43 - - "": [t: "potrójne poziome wiązanie em"] # 0xec44 - - "": [t: "pojedyncze pionowe wiązanie em"] # 0xec45 - - "": [t: "podwójne pionowe wiązanie em"] # 0xec46 - - "": [t: "potrójne pionowe wiązanie em"] # 0xec47 - - "": [t: "wiązanie em mniejsze niż"] # 0xec48 - - "": [t: "wiązanie em większe niż"] # 0xec49 - - "": [t: "pojedyncze poziome wiązanie en"] # 0xec4a - - "": [t: "podwójne poziome wiązanie en"] # 0xec4b - - "": [t: "potrójne poziome wiązanie en"] # 0xec4c - - "": [t: "górny lewy prostokąt"] # 0xec80 - - "": [t: "dolny lewy prostokąt"] # 0xec81 - - "": [t: "górny prawy prostokąt"] # 0xec90 - - "": [t: "dolny prawy prostokąt"] # 0xec91 - - "": [t: "narożnik dzielenia syntetycznego"] # 0xec92 - - "": [t: "poziome przedłużenie dzielenia syntetycznego"] # 0xec93 - - "": [t: "pionowe przedłużenie dzielenia syntetycznego"] # 0xec94 - - "": [t: "lewy przedłużacz sufitu i podłogi"] # 0xec95 - - "": [t: "prawy przedłużacz sufitu i podłogi"] # 0xec96 - - "": [t: "przedłużenie przez nawias kwadratowy"] # 0xec97 - - "": [t: "pionowe przedłużenie kreski"] # 0xec98 - - "": [t: "lewy podwójny pionowe przedłużenie kreski"] # 0xec99 - - "": [t: "poziome przedłużenie kreski"] # 0xec9a - - "": [t: "przedłużenie pod nawiasem kwadratowym"] # 0xec9c - - "": [t: "prawa część dolnego nawiasu"] # 0xec9d - - "": [t: "przedłużenie dolnego nawiasu"] # 0xec9e - - "": [t: "lewa część dolnego nawiasu"] # 0xec9f - - "": [t: "przedłużenie górnego nawiasu klamrowego"] # 0xeca0 - - "": [t: "lewa część górnego nawiasu"] # 0xeca1 - - "": [t: "przedłużenie górnego nawiasu"] # 0xeca2 - - "": [t: "prawa część górnego nawiasu"] # 0xeca3 - - "": [t: "przedłużenie dolnego nawiasu klamrowego"] # 0xeca4 - - "": [t: "stała Plancka przez dwa pi kreska"] # 0xed00 - - "": [t: "lustrzane g"] # 0xed01 - - "": [t: "j bez kropki"] # 0xed02 + - "㏘": [T: "pikometry"] # 0x33d8 + - "㏙": [T: "części na milion"] # 0x33d9 + - "㏚": [T: "petarentgeny"] # 0x33da + - "㏛": [T: "steradiany"] # 0x33db + - "㏜": [T: "siwerty"] # 0x33dc + - "㏝": [T: "webery"] # 0x33dd + - "㏞": [T: "wolty na metr"] # 0x33de + - "㏟": [T: "ampery na metr"] # 0x33df + - "㏿": [T: "galony"] # 0x33ff + - "": [T: "równa się z daszkiem pod"] # 0xe900 + - "": [T: "równa się z plusem nad"] # 0xe901 + - "": [T: "równa się z plusem pod"] # 0xe902 + - "": [T: "tylda z plusem nad"] # 0xe903 + - "": [T: "tylda z plusem pod"] # 0xe904 + - "": [T: "równe podwójny przez większe niż"] # 0xe908 + - "": [T: "równe podwójny przez mniejsze niż"] # 0xe909 + - "": [T: "zawiera lub równe"] # 0xe90a + - "": [T: "nadzbiór lub równy"] # 0xe90b + - "": [T: "podzbiór lub równy"] # 0xe90c + - "": [T: "równe przez mniejsze niż"] # 0xe90d + - "": [T: "należy do lub równe"] # 0xe912 + - "": [T: "równe lub większe niż"] # 0xe913 + - "": [T: "przybliżone nadzbiór"] # 0xe914 + - "": [T: "przybliżone podzbiór"] # 0xe915 + - "": [T: "nadzbiór z kropką zawiera jako relację indeksu dolnego"] # 0xe916 + - "": [T: "podzbiór z kropką jest zawarty jako relacja indeksu dolnego"] # 0xe917 + - "": [T: "równe z kropką pod"] # 0xe918 + - "": [T: "lewy kropka nad minus przez prawy kropka"] # 0xe919 + - "": [T: "prawy kropka nad minus przez lewy kropka"] # 0xe91a + - "": [T: "w przybliżeniu równe minus"] # 0xe91f + - "": [T: "podwójna kwadratowa suma zbiorów"] # 0xe920 + - "": [T: "podwójny kwadrat wielka"] # 0xe921 + - "": [T: "mniejsze niż równe lub większe niż"] # 0xe922 + - "": [T: "tylda z kropką"] # 0xe924 + - "": [T: "tylda z dwiema kropkami"] # 0xe925 + - "": [T: "mniejsze niż większe lub równe"] # 0xe926 + - "": [T: "większe niż mniejsze lub równe"] # 0xe927 + - "": [T: "Równoważne lub mniejsze niż"] # 0xe928 + - "": [T: "Równoważne lub większe niż"] # 0xe929 + - "": [T: "lewy otwórz ramka operator"] # 0xe92a + - "": [T: "prawy otwórz ramka operator"] # 0xe92b + - "": [T: "identyczne z kropką"] # 0xe92c + - "": [T: "większe niż równe lub mniejsze niż"] # 0xe92d + - "": [T: "kreska operator"] # 0xe92e + - "": [T: "podwójny kreska operator"] # 0xe92f + - "": [T: "potrójny kreska operator"] # 0xe930 + - "": [T: "mniejsze niż lub w przybliżeniu równe"] # 0xe932 + - "": [T: "większe niż lub w przybliżeniu równe"] # 0xe933 + - "": [T: "zagnieżdżone mniejsze niż"] # 0xe936 + - "": [T: "zagnieżdżone większe niż"] # 0xe937 + - "": [T: "poprzedza lub Równoważne"] # 0xe93a + - "": [T: "następuje po lub Równoważne"] # 0xe93b + - "": [T: "poprzedza nad równe"] # 0xe940 + - "": [T: "następuje po nad równe"] # 0xe941 + - "": [T: "mniejsze niż nad ukośnie równe nad większe niż"] # 0xe942 + - "": [T: "większe niż nad ukośnie równe nad mniejsze niż"] # 0xe943 + - "": [T: "spełnione przez"] # 0xe948 + - "": [T: "leniwe s"] # 0xe949 + - "": [T: "nie asercja"] # 0xe94a + - "": [T: "podwójny równe"] # 0xe94b + - "": [T: "potrójny równe"] # 0xe94c + - "": [T: "reguła opóźniona"] # 0xe94d + - "": [T: "alias ogranicznika"] # 0xe94e + - "": [T: "normalna podgrupa z kreską"] # 0xe950 + - "": [T: "zawiera jako normalny podgrupa z kreską"] # 0xe951 + - "": [T: "zaokrąglone implikuje"] # 0xe954 + - "": [T: "uśmiech pod kreską"] # 0xe955 + - "": [T: "smutek przez kreskę"] # 0xe956 + - "": [T: "nadzbiór lub w przybliżeniu równe"] # 0xe957 + - "": [T: "podzbiór lub w przybliżeniu równe"] # 0xe958 + - "": [T: "większe niż w przybliżeniu równe lub mniejsze niż"] # 0xe959 + - "": [T: "mniejsze niż w przybliżeniu równe lub większe niż"] # 0xe95a + - "": [T: "podwójny logiczne lub"] # 0xe95c + - "": [T: "podwójna koniunkcja logiczna"] # 0xe95d + - "": [T: "alternatywa logiczna z podwójną kreską pod"] # 0xe95e + - "": [T: "logiczne lub z kreską pod"] # 0xe95f + - "": [T: "w przybliżeniu równe nad równe"] # 0xe962 + - "": [T: "trójkąt skierowany w lewo z kreską dzielącą"] # 0xe964 + - "": [T: "trójkąt skierowany w prawo z kreską dzielącą"] # 0xe965 + - "": [T: "równa się z kropkowaną górną linią"] # 0xe966 + - "": [T: "poprzedza z dwukropkiem"] # 0xe967 + - "": [T: "następuje po z dwukropkiem"] # 0xe968 + - "": [T: "mniejsze niż lub ukośnie równe"] # 0xe969 + - "": [T: "większe niż lub ukośnie równe"] # 0xe96a + - "": [T: "zagnieżdżone bardzo znacznie mniejsze niż"] # 0xe96b + - "": [T: "zagnieżdżone bardzo znacznie większe niż"] # 0xe96c + - "": [T: "wariant różnicy między"] # 0xe96d + - "": [T: "mniejsze niż większe niż nakładka"] # 0xe96e + - "": [T: "alternatywa logiczna z nałożoną koniunkcją logiczną"] # 0xe96f + - "": [T: "nadzbiór przez nadzbiór"] # 0xe970 + - "": [T: "podzbiór przez podzbiór"] # 0xe971 + - "": [T: "nadzbiór przez podzbiór"] # 0xe972 + - "": [T: "podzbiór przez nadzbiór"] # 0xe973 + - "": [T: "potrójna pionowa kreska"] # 0xe979 + - "": [T: "sparowane poczwórne pionowe kropki"] # 0xe97a + - "": [T: "prostopadłe przez kreskę"] # 0xe97b + - "": [T: "lewy znak dedukcji z podwójną pionową kreską"] # 0xe97c + - "": [T: "podwójny lewy znak dedukcji z podwójną pionową kreską"] # 0xe97d + - "": [T: "prostopadłe przez odwrócony prostopadłe"] # 0xe97e + - "": [T: "podwójny lewy znak dedukcji z pionową kreską"] # 0xe97f + - "": [T: "kąt sferyczny otwarty w górę"] # 0xe980 + - "": [T: "podwójny ukośnik"] # 0xe981 + - "": [T: "kąt prosty z narożnikiem"] # 0xe982 + - "": [T: "pionowa kreska w kółku"] # 0xe984 + - "": [T: "znak dzielenia w kółku"] # 0xe985 + - "": [T: "kreskowany ukośnik"] # 0xe986 + - "": [T: "kreskowany ukośnik odwrotny"] # 0xe987 + - "": [T: "kreskowana linia środkowa"] # 0xe988 + - "": [T: "kreskowana pionowa kreska"] # 0xe989 + - "": [T: "prostopadłe z s"] # 0xe98a + - "": [T: "kąt z s"] # 0xe98b + - "": [T: "kąt sferyczny otwarty w lewo"] # 0xe98c + - "": [T: "kąt otwarty w lewo"] # 0xe98d + - "": [T: "pionowa kreska z podwójnym haczykiem"] # 0xe98e + - "": [T: "operator średniej kropki wolnego rodnika"] # 0xe98f + - "": [T: "biały trójkąt skierowany w górę nad kreską"] # 0xe990 + - "": [T: "identyczne i równoległe do"] # 0xe991 + - "": [T: "iloczyn spłaszczony"] # 0xe992 + - "": [T: "potrójny operator kreski z kreską poziomą"] # 0xe993 + - "": [T: "identyczne z podwójnym ukośnikiem"] # 0xe994 + - "": [T: "potrójne skrzyżowane kreski"] # 0xe995 + - "": [T: "pionowa kreska przez okrąg"] # 0xe996 + - "": [T: "pionowy proporcjonalne do"] # 0xe997 + - "": [T: "czarna ostatnia kwadra księżyca"] # 0xe998 + - "": [T: "czarna pierwsza kwadra księżyca"] # 0xe999 + - "": [T: "ujemna fala sinusoidalna"] # 0xe9a0 + - "": [T: "kropka w nawiasach"] # 0xe9a1 + - "": [T: "nawiasy"] # 0xe9a2 + - "": [T: "biały uśmiech"] # 0xe9a3 + - "": [T: "biały smutek"] # 0xe9a4 + - "": [T: "sześciokąt"] # 0xe9a5 + - "": [T: "Równoważne nad plus"] # 0xe9a6 + - "": [T: "plus przez Równoważne"] # 0xe9a7 + - "": [T: "część wspólna z szeryfami"] # 0xe9b0 + - "": [T: "suma zbiorów z szeryfami"] # 0xe9b1 + - "": [T: "kwadratowa część wspólna z szeryfami"] # 0xe9b2 + - "": [T: "kwadratowa suma zbiorów z szeryfami"] # 0xe9b3 + - "": [T: "poprzedza Równoważne lub następuje po"] # 0xe9e0 + - "": [T: "następuje po Równoważne lub poprzedza"] # 0xe9e1 + - "": [T: "poprzedza w przybliżeniu równe lub następuje po"] # 0xe9e2 + - "": [T: "następuje po w przybliżeniu równe lub poprzedza"] # 0xe9e3 + - "": [T: "mniejsze niż Równoważne lub większe niż"] # 0xe9f0 + - "": [T: "większe niż Równoważne lub mniejsze niż"] # 0xe9f1 + - "": [T: "pionowo przekreślone znacznie mniejsze niż"] # 0xea00 + - "": [T: "pionowo przekreślone znacznie większe niż"] # 0xea01 + - "": [T: "nie jest znacznie mniejsze niż, wariant"] # 0xea02 + - "": [T: "nie jest znacznie większe niż, wariant"] # 0xea03 + - "": [T: "mniejsze niż z pionową kreską i nie podwójne równe"] # 0xea04 + - "": [T: "większe niż z pionową kreską i nie podwójne równe"] # 0xea05 + - "": [T: "nie mniejsze lub równe"] # 0xea06 + - "": [T: "nie większe lub równe"] # 0xea07 + - "": [T: "ani równe, ani mniejsze niż"] # 0xea09 + - "": [T: "nie zawiera lub równe"] # 0xea0a + - "": [T: "ani nadzbiór, ani równe"] # 0xea0b + - "": [T: "ani podzbiór, ani równe"] # 0xea0c + - "": [T: "ukośnik odwrotny z podzbiorem"] # 0xea0d + - "": [T: "ani równe, ani większe niż"] # 0xea0e + - "": [T: "nie minus operator tyldy"] # 0xea0f + - "": [T: "ani równe, ani mniejsze niż"] # 0xea10 + - "": [T: "nie operator tyldy"] # 0xea11 + - "": [T: "nie jest elementem zbioru lub równe"] # 0xea12 + - "": [T: "ani równe, ani większe niż"] # 0xea13 + - "": [T: "nie w przybliżeniu równe"] # 0xea14 + - "": [T: "nie następuje po podobne"] # 0xea15 + - "": [T: "mniejsze niż lub ukośnie równe z ukośnikiem"] # 0xea16 + - "": [T: "większe niż lub ukośnie równe z ukośnikiem"] # 0xea17 + - "": [T: "nadzbiór ukośnik"] # 0xea1a + - "": [T: "nie zawiera"] # 0xea1b + - "": [T: "nie mniejsze lub równe"] # 0xea1d + - "": [T: "nie większe lub równe"] # 0xea1e + - "": [T: "nie w przybliżeniu równe minus"] # 0xea1f + - "": [T: "zanegowana przynależność do zbioru z kropką nad"] # 0xea22 + - "": [T: "nie kąt pionowy"] # 0xea2c + - "": [T: "nie ukośnie równoległe"] # 0xea2d + - "": [T: "nie kreska operator"] # 0xea2e + - "": [T: "nie podwójny kreska operator"] # 0xea2f + - "": [T: "nie potrójny kreska operator"] # 0xea30 + - "": [T: "mniejsze niż ale nie w przybliżeniu równe"] # 0xea32 + - "": [T: "większe niż ale nie w przybliżeniu równe"] # 0xea33 + - "": [T: "mniejsze niż lub nie równa się"] # 0xea34 + - "": [T: "większe niż lub nie równa się"] # 0xea35 + - "": [T: "nie zagnieżdżone mniejsze niż"] # 0xea36 + - "": [T: "nie zagnieżdżone większe niż"] # 0xea37 + - "": [T: "nie jest znacznie mniejsze niż"] # 0xea38 + - "": [T: "nie jest znacznie większe niż"] # 0xea39 + - "": [T: "poprzedza ale nie Równoważne"] # 0xea3a + - "": [T: "następuje po ale nie Równoważne"] # 0xea3b + - "": [T: "poprzedza ale nie równa się"] # 0xea3c + - "": [T: "następuje po ale nie równa się"] # 0xea3d + - "": [T: "nie równa się ani nie poprzedza"] # 0xea3e + - "": [T: "nie równa się ani nie następuje po"] # 0xea3f + - "": [T: "poprzedza ale nie równa się"] # 0xea40 + - "": [T: "następuje po ale nie równa się"] # 0xea41 + - "": [T: "ani podzbiór, ani równe"] # 0xea42 + - "": [T: "ani nadzbiór, ani równe"] # 0xea43 + - "": [T: "podzbiór lub nie równa się"] # 0xea44 + - "": [T: "nadzbiór lub nie równa się"] # 0xea45 + - "": [T: "ani podzbiór, ani równe"] # 0xea46 + - "": [T: "ani nadzbiór, ani równe"] # 0xea47 + - "": [T: "nie potrójny mniejsze niż"] # 0xea48 + - "": [T: "nie potrójny większe niż"] # 0xea49 + - "": [T: "nie poprzedza równa się"] # 0xea4c + - "": [T: "nie następuje po równa się"] # 0xea4d + - "": [T: "nie normalna podgrupa z kreską"] # 0xea50 + - "": [T: "nie zawiera jako normalnej podgrupy z kreską"] # 0xea51 + - "": [T: "nie różnica między"] # 0xea52 + - "": [T: "nie geometrycznie równoważne"] # 0xea53 + - "": [T: "nie pionowo podobne"] # 0xea54 + - "": [T: "nie równe lub podobne"] # 0xea55 + - "": [T: "nie pionowo przybliżone"] # 0xea56 + - "": [T: "nie w przybliżeniu identyczne z"] # 0xea57 + - "": [T: "nie wyboiście równe"] # 0xea58 + - "": [T: "nie wyboiście pojedynczo równe"] # 0xea59 + - "": [T: "nie równe kropka"] # 0xea5a + - "": [T: "odwrotne nie równoważne"] # 0xea5b + - "": [T: "nie kwadrat podzbiór"] # 0xea60 + - "": [T: "nie kwadrat nadzbiór"] # 0xea61 + - "": [T: "nie w przybliżeniu równe nad znakiem równości"] # 0xea62 + - "": [T: "nie ściśle równoważne"] # 0xea63 + - "": [T: "nie przystające z kropką"] # 0xea64 + - "": [T: "odwrotnie nie równe"] # 0xea65 + - "": [T: "nie pionowy lewy trójkąt równa się"] # 0xea70 + - "": [T: "nie pionowy prawy trójkąt równa się"] # 0xea71 + - "": [T: "nie cząstkowe"] # 0xea80 + - "": [T: "ozdobnik przedłużenia strzałki"] # 0xeb00 + - "": [T: "strzałka prawy przeze strzałką lewy"] # 0xeb01 + - "": [T: "strzałka prawy przeze strzałką lewy"] # 0xeb02 + - "": [T: "harpun prawy przez harpun lewy"] # 0xeb03 + - "": [T: "harpun prawy przez harpun lewy"] # 0xeb04 + - "": [T: "podwójna strzałka północny wschód południowy zachód"] # 0xeb05 + - "": [T: "podwójna strzałka północny zachód południowy wschód"] # 0xeb06 + - "": [T: "poziome przedłużenie harpuna"] # 0xeb07 + - "": [T: "łuk ze strzałką w lewo przeciwnie do ruchu wskazówek zegara"] # 0xeb08 + - "": [T: "łuk ze strzałką w prawo przeciwnie do ruchu wskazówek zegara"] # 0xeb09 + - "": [T: "duży strzałka w prawo akcent"] # 0xeb0b + - "": [T: "duży strzałka w lewo akcent"] # 0xeb0c + - "": [T: "lewy grot strzałki"] # 0xeb0d + - "": [T: "prawy grot strzałki"] # 0xeb0e + - "": [T: "duża strzałka w prawo z lewym przekreśleniem"] # 0xeb0f + - "": [T: "poziome przedłużenie podwójnej strzałki"] # 0xeb10 + - "": [T: "duża podwójna strzałka w lewo i prawo z przekreśleniem"] # 0xeb11 + - "": [T: "strzałka w dół po lewej i strzałka w górę"] # 0xeb12 + - "": [T: "strzałka w lewo z dolnym narożnikiem"] # 0xeb13 + - "": [T: "strzałka w prawo z górnym narożnikiem"] # 0xeb14 + - "": [T: "strzałka w lewo z górnym narożnikiem"] # 0xeb15 + - "": [T: "strzałka po górnym półokręgu przeciwnie do ruchu wskazówek zegara z plusem"] # 0xeb16 + - "": [T: "strzałka po górnym półokręgu zgodnie z ruchem wskazówek zegara z minusem"] # 0xeb17 + - "": [T: "strzałka w prawo z ogonem i przekreśleniem"] # 0xeb18 + - "": [T: "prawy harpun dolny"] # 0xeb19 + - "": [T: "lewy harpun dolny"] # 0xeb1a + - "": [T: "lewy prawy harpun dolny"] # 0xeb1b + - "": [T: "lewy prawy harpun górny"] # 0xeb1c + - "": [T: "górny dolny harpun lewy"] # 0xeb1d + - "": [T: "górny dolny harpun prawy"] # 0xeb1e + - "": [T: "strzałka w górę w prawo ze strzałką w dół"] # 0xeb1f + - "": [T: "lewy harpun do kreski z grotem górnym"] # 0xeb20 + - "": [T: "prawy harpun do kreski z grotem górnym"] # 0xeb21 + - "": [T: "lewy harpun do kreski z grotem dolnym"] # 0xeb22 + - "": [T: "prawy harpun do kreski z grotem dolnym"] # 0xeb23 + - "": [T: "lewy harpun od kreski z grotem górnym"] # 0xeb24 + - "": [T: "prawy harpun od kreski z grotem górnym"] # 0xeb25 + - "": [T: "lewy harpun od kreski z grotem dolnym"] # 0xeb26 + - "": [T: "prawy harpun od kreski z grotem dolnym"] # 0xeb27 + - "": [T: "górny harpun do kreski z grotem lewym"] # 0xeb28 + - "": [T: "dolny harpun do kreski z grotem lewym"] # 0xeb29 + - "": [T: "górny harpun do kreski z grotem prawym"] # 0xeb2a + - "": [T: "dolny harpun do kreski z grotem prawym"] # 0xeb2b + - "": [T: "górny harpun od kreski z grotem lewym"] # 0xeb2c + - "": [T: "dolny harpun od kreski z grotem lewym"] # 0xeb2d + - "": [T: "górny harpun od kreski z grotem prawym"] # 0xeb2e + - "": [T: "dolny harpun od kreski z grotem prawym"] # 0xeb2f + - "": [T: "strzałka w górę do kreski"] # 0xeb30 + - "": [T: "strzałka w dół do kreski"] # 0xeb31 + - "": [T: "górny harpun w lewo z dolnym harpunem"] # 0xeb32 + - "": [T: "górny harpun w prawo z dolnym harpunem"] # 0xeb33 + - "": [T: "górny grot strzałki"] # 0xeb34 + - "": [T: "dolny grot strzałki"] # 0xeb35 + - "": [T: "podwójny harpun z lewym grotem dolnym i prawym grotem górnym"] # 0xeb36 + - "": [T: "podwójny harpun z lewym grotem górnym i prawym grotem dolnym"] # 0xeb37 + - "": [T: "strzałka w lewo przez kreskę"] # 0xeb38 + - "": [T: "strzałka w prawo przez kreskę"] # 0xeb39 + - "": [T: "strzałka w lewo pod kreski"] # 0xeb3a + - "": [T: "strzałka w prawo pod kreski"] # 0xeb3b + - "": [T: "lewy prawy potrójny strzałka"] # 0xeb3c + - "": [T: "podwójna strzałka północny wschód południowy wschód"] # 0xeb3f + - "": [T: "strzałka po lewym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0xeb40 + - "": [T: "strzałka po lewym półokręgu zgodnie z ruchem wskazówek zegara"] # 0xeb41 + - "": [T: "lewy otwarty okrąg lewy strzałka w prawo"] # 0xeb42 + - "": [T: "strzałka w prawo przez tylda"] # 0xeb44 + - "": [T: "strzałka w lewo przez tylda"] # 0xeb45 + - "": [T: "lewy harpun przez kreskę"] # 0xeb48 + - "": [T: "prawy harpun przez kreskę"] # 0xeb49 + - "": [T: "lewy harpun pod kreski"] # 0xeb4a + - "": [T: "prawy harpun pod kreski"] # 0xeb4b + - "": [T: "krótka czarna strzałka w lewo"] # 0xeb4c + - "": [T: "strzałka po prawym półokręgu zgodnie z ruchem wskazówek zegara"] # 0xeb50 + - "": [T: "strzałka po prawym półokręgu przeciwnie do ruchu wskazówek zegara"] # 0xeb51 + - "": [T: "lewy otwarty okrąg lewy prawy harpun"] # 0xeb52 + - "": [T: "strzałka w górę lewy z pionową kreską"] # 0xeb58 + - "": [T: "strzałka w dół lewy z pionową kreską"] # 0xeb59 + - "": [T: "strzałka w górę prawy z pionową kreską"] # 0xeb5a + - "": [T: "strzałka w dół prawy z pionową kreską"] # 0xeb5b + - "": [T: "strzałka w prawo z wydłużonym dolnym hakiem"] # 0xeb5c + - "": [T: "strzałka w lewo z wydłużonym hakiem"] # 0xeb5d + - "": [T: "strzałka w lewo z wydłużonym dolnym hakiem"] # 0xeb5e + - "": [T: "strzałka w prawo z wydłużonym hakiem"] # 0xeb5f + - "": [T: "nie strzałka w prawo falista"] # 0xeb60 + - "": [T: "nie strzałka w prawo zakrzywiony"] # 0xeb61 + - "": [T: "górny harpun lewy z pionową kreską"] # 0xeb68 + - "": [T: "dolny harpun lewy z pionową kreską"] # 0xeb69 + - "": [T: "górny harpun prawy z pionową kreską"] # 0xeb6a + - "": [T: "dolny harpun prawy z pionową kreską"] # 0xeb6b + - "": [T: "pionowe przedłużenie podwójnej strzałki"] # 0xeb6c + - "": [T: "pionowe przedłużenie harpuna z grotem w lewo"] # 0xeb6d + - "": [T: "pionowe przedłużenie harpuna z grotem w prawo"] # 0xeb6e + - "": [T: "prawy harpun przez lewy harpun prawy"] # 0xeb6f + - "": [T: "prawy harpun przez lewy harpun lewy"] # 0xeb70 + - "": [T: "lewy harpun przez prawy harpun prawy"] # 0xeb71 + - "": [T: "lewy harpun przez prawy harpun lewy"] # 0xeb72 + - "": [T: "strzałka w lewo od kreski z grotem strzałki"] # 0xeb73 + - "": [T: "przedłużenie strzałki w prawo od lewej kreski"] # 0xeb74 + - "": [T: "strzałka w lewo od kreski ogon"] # 0xeb75 + - "": [T: "strzałka w prawo od kreski ogon"] # 0xeb76 + - "": [T: "strzałka w prawo od kreski z grotem strzałki"] # 0xeb77 + - "": [T: "górny harpun od kreski z lewym grotem strzałki"] # 0xeb78 + - "": [T: "strzałka w prawo nad strzałką w lewo prawy"] # 0xeb79 + - "": [T: "strzałka w prawo nad strzałką w lewo lewy"] # 0xeb7a + - "": [T: "strzałka w lewo nad strzałką w prawo prawy"] # 0xeb7b + - "": [T: "strzałka w lewo nad strzałką w prawo lewy"] # 0xeb7c + - "": [T: "strzałka w górę od kreski z grotem strzałki"] # 0xeb7d + - "": [T: "strzałka w górę od kreski ogon"] # 0xeb7e + - "": [T: "strzałka w dół od kreski ogon"] # 0xeb7f + - "": [T: "strzałka w dół od kreski z grotem strzałki"] # 0xeb80 + - "": [T: "dolny harpun od kreski z prawym grotem strzałki"] # 0xeb81 + - "": [T: "górny harpun w lewo z dolnym harpunem dolny"] # 0xeb82 + - "": [T: "przedłużenie górnego harpuna w lewo i dolnego harpuna"] # 0xeb83 + - "": [T: "dolny harpun w lewo z górnym harpunem górny"] # 0xeb84 + - "": [T: "górny harpun w lewo z dolnym harpunem górny"] # 0xeb85 + - "": [T: "przedłużenie dolnego harpuna w lewo i górnego harpuna"] # 0xeb86 + - "": [T: "dolny harpun w lewo z górnym harpunem dolny"] # 0xeb87 + - "": [T: "strzałka w górę po lewej i strzałka w dół dolny"] # 0xeb88 + - "": [T: "strzałka w dół po lewej i strzałka w górę górny"] # 0xeb89 + - "": [T: "strzałka w górę po lewej i strzałka w dół górny"] # 0xeb8a + - "": [T: "strzałka w dół po lewej i strzałka w górę dolny"] # 0xeb8b + - "": [T: "przedłużenie strzałki w lewo i w prawo"] # 0xeb8c + - "": [T: "przedłużenie strzałki północno-wschodniej"] # 0xeb8d + - "": [T: "przedłużenie strzałki północno-zachodniej"] # 0xeb8e + - "": [T: "lewa część dolnego nawiasu klamrowego"] # 0xec00 + - "": [T: "środkowa część dolnego nawiasu klamrowego"] # 0xec01 + - "": [T: "prawa część dolnego nawiasu klamrowego"] # 0xec02 + - "": [T: "poziome przedłużenie nawiasu klamrowego"] # 0xec03 + - "": [T: "lewa część górnego nawiasu klamrowego"] # 0xec04 + - "": [T: "środkowa część górnego nawiasu klamrowego"] # 0xec05 + - "": [T: "prawa część górnego nawiasu klamrowego"] # 0xec06 + - "": [T: "lewa pionowa kreska"] # 0xec07 + - "": [T: "prawa pionowa kreska"] # 0xec08 + - "": [T: "lewa podwójna pionowa kreska"] # 0xec09 + - "": [T: "prawa podwójna pionowa kreska"] # 0xec0a + - "": [T: "poziome przedłużenie nawiasu kwadratowego"] # 0xec0b + - "": [T: "dolny nawias kwadratowy"] # 0xec0c + - "⎵": [T: "dolny nawias kwadratowy"] # 0x23b5 + - "": [T: "górny nawias kwadratowy"] # 0xec0d + - "⎴": [T: "górny nawias kwadratowy"] # 0x23b4 + - "": [T: "pod nawias kwadratowy lewy"] # 0xec0e + - "": [T: "pod nawias kwadratowy prawy"] # 0xec0f + - "": [T: "przez nawias kwadratowy lewy"] # 0xec10 + - "": [T: "przez nawias kwadratowy prawy"] # 0xec11 + - "": [T: "lewy nawias okrągły 1"] # 0xec12 + - "": [T: "lewy nawias okrągły 2"] # 0xec13 + - "": [T: "lewy nawias okrągły 3"] # 0xec14 + - "": [T: "lewy nawias okrągły 4"] # 0xec15 + - "": [T: "prawy nawias okrągły 1"] # 0xec16 + - "": [T: "prawy nawias okrągły 2"] # 0xec17 + - "": [T: "prawy nawias okrągły 3"] # 0xec18 + - "": [T: "prawy nawias okrągły 4"] # 0xec19 + - "": [T: "znak pierwiastka 1"] # 0xec1a + - "": [T: "znak pierwiastka 2"] # 0xec1b + - "": [T: "znak pierwiastka 3"] # 0xec1c + - "": [T: "znak pierwiastka 4"] # 0xec1d + - "": [T: "znak pierwiastka 5"] # 0xec1e + - "": [T: "dolna część znaku pierwiastka"] # 0xec1f + - "": [T: "pionowe przedłużenie znaku pierwiastka"] # 0xec20 + - "": [T: "górna część znaku pierwiastka"] # 0xec21 + - "": [T: "lewy biały nawias kwadratowy górny"] # 0xec22 + - "": [T: "przedłużenie lewego białego nawiasu kwadratowego"] # 0xec23 + - "": [T: "lewy biały nawias kwadratowy dolny"] # 0xec24 + - "": [T: "prawy biały nawias kwadratowy górny"] # 0xec25 + - "": [T: "przedłużenie prawego białego nawiasu kwadratowego"] # 0xec26 + - "": [T: "prawy biały nawias kwadratowy dolny"] # 0xec27 + - "": [T: "lewy biały zakrzywiony nawias kwadratowy"] # 0xec30 + - "": [T: "prawy biały zakrzywiony nawias kwadratowy"] # 0xec31 + - "": [T: "znak dzielenia pisemnego"] # 0xec32 + - "": [T: "przedłużenie znaku dzielenia pisemnego"] # 0xec33 + - "": [T: "krótkie dzielenie"] # 0xec34 + - "": [T: "podwójne wiązanie em od południowego zachodu do północnego wschodu"] # 0xec40 + - "": [T: "podwójne wiązanie em od północnego zachodu do południowego wschodu"] # 0xec41 + - "": [T: "pojedyncze poziome wiązanie em"] # 0xec42 + - "": [T: "podwójne poziome wiązanie em"] # 0xec43 + - "": [T: "potrójne poziome wiązanie em"] # 0xec44 + - "": [T: "pojedyncze pionowe wiązanie em"] # 0xec45 + - "": [T: "podwójne pionowe wiązanie em"] # 0xec46 + - "": [T: "potrójne pionowe wiązanie em"] # 0xec47 + - "": [T: "wiązanie em mniejsze niż"] # 0xec48 + - "": [T: "wiązanie em większe niż"] # 0xec49 + - "": [T: "pojedyncze poziome wiązanie en"] # 0xec4a + - "": [T: "podwójne poziome wiązanie en"] # 0xec4b + - "": [T: "potrójne poziome wiązanie en"] # 0xec4c + - "": [T: "górny lewy prostokąt"] # 0xec80 + - "": [T: "dolny lewy prostokąt"] # 0xec81 + - "": [T: "górny prawy prostokąt"] # 0xec90 + - "": [T: "dolny prawy prostokąt"] # 0xec91 + - "": [T: "narożnik dzielenia syntetycznego"] # 0xec92 + - "": [T: "poziome przedłużenie dzielenia syntetycznego"] # 0xec93 + - "": [T: "pionowe przedłużenie dzielenia syntetycznego"] # 0xec94 + - "": [T: "lewy przedłużacz sufitu i podłogi"] # 0xec95 + - "": [T: "prawy przedłużacz sufitu i podłogi"] # 0xec96 + - "": [T: "przedłużenie przez nawias kwadratowy"] # 0xec97 + - "": [T: "pionowe przedłużenie kreski"] # 0xec98 + - "": [T: "lewy podwójny pionowe przedłużenie kreski"] # 0xec99 + - "": [T: "poziome przedłużenie kreski"] # 0xec9a + - "": [T: "przedłużenie pod nawiasem kwadratowym"] # 0xec9c + - "": [T: "prawa część dolnego nawiasu"] # 0xec9d + - "": [T: "przedłużenie dolnego nawiasu"] # 0xec9e + - "": [T: "lewa część dolnego nawiasu"] # 0xec9f + - "": [T: "przedłużenie górnego nawiasu klamrowego"] # 0xeca0 + - "": [T: "lewa część górnego nawiasu"] # 0xeca1 + - "": [T: "przedłużenie górnego nawiasu"] # 0xeca2 + - "": [T: "prawa część górnego nawiasu"] # 0xeca3 + - "": [T: "przedłużenie dolnego nawiasu klamrowego"] # 0xeca4 + - "": [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 @@ -3004,8 +3004,8 @@ - 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: "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 @@ -3015,30 +3015,30 @@ - "": [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 - - "": [t: "przedłużenie ozdobnika statusu połączenia"] # 0xee10 - - "": [t: "całka z pętlą"] # 0xee11 - - "": [t: "podwójna całka z pętlą"] # 0xee12 - - "": [t: "potrójna całka z pętlą"] # 0xee13 - - "": [t: "rozszerzająca się podwójna całka z pętlą"] # 0xee15 - - "": [t: "rozszerzająca się potrójna całka z pętlą"] # 0xee16 + - "": [T: "ozdobnik statusu połączenia"] # 0xee0d + - "": [T: "lewy ozdobnik statusu połączenia"] # 0xee0e + - "": [T: "prawy ozdobnik statusu połączenia"] # 0xee0f + - "": [T: "przedłużenie ozdobnika statusu połączenia"] # 0xee10 + - "": [T: "całka z pętlą"] # 0xee11 + - "": [T: "podwójna całka z pętlą"] # 0xee12 + - "": [T: "potrójna całka z pętlą"] # 0xee13 + - "": [T: "rozszerzająca się podwójna całka z pętlą"] # 0xee15 + - "": [T: "rozszerzająca się potrójna całka z pętlą"] # 0xee16 - "": [T: "akcent asymptotycznie równy"] # 0xee17 - - "": [t: "akcent znaku równości"] # 0xee18 - - "": [t: "poczwórny prim"] # 0xee19 - - "": [t: "kreska akcent z otwartym okręgiem po lewej"] # 0xee1a - - "": [t: "kreska akcent z zamkniętym okręgiem po lewej"] # 0xee1b - - "": [t: "kreska akcent z otwartym okręgiem po prawej"] # 0xee1c - - "": [t: "kreska akcent z przekreśloną kropką"] # 0xee1d - - "": [t: "kreska akcent z kropką pod spodem"] # 0xee1e - - "": [t: "kreska akcent z podwójnie przekreśloną kropką"] # 0xee1f - - "": [t: "kreska akcent z podwójną kropką pod spodem"] # 0xee20 - - "": [t: "kreska akcent z daszkiem"] # 0xee21 - - "": [t: "gruby akcent kreski dolnej"] # 0xee22 - - "": [t: "kreska akcent z zamkniętym okręgiem po prawej"] # 0xee23 - - "": [t: "duży kropka nad"] # 0xee24 - - "": [t: "znak wyrównania"] # 0xef00 + - "": [T: "akcent znaku równości"] # 0xee18 + - "": [T: "poczwórny prim"] # 0xee19 + - "": [T: "kreska akcent z otwartym okręgiem po lewej"] # 0xee1a + - "": [T: "kreska akcent z zamkniętym okręgiem po lewej"] # 0xee1b + - "": [T: "kreska akcent z otwartym okręgiem po prawej"] # 0xee1c + - "": [T: "kreska akcent z przekreśloną kropką"] # 0xee1d + - "": [T: "kreska akcent z kropką pod spodem"] # 0xee1e + - "": [T: "kreska akcent z podwójnie przekreśloną kropką"] # 0xee1f + - "": [T: "kreska akcent z podwójną kropką pod spodem"] # 0xee20 + - "": [T: "kreska akcent z daszkiem"] # 0xee21 + - "": [T: "gruby akcent kreski dolnej"] # 0xee22 + - "": [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 @@ -3057,110 +3057,110 @@ - "": [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 - - "": [t: "całka z ukośnikiem"] # 0xef82 - - "": [t: "odwrócony całka"] # 0xef83 - - "": [t: "podwójny zero przez podwójny zero"] # 0xef90 - - "": [t: "zero z ukośnikiem"] # 0xef91 + - "": [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 + - "": [T: "całka z ukośnikiem"] # 0xef82 + - "": [T: "odwrócony całka"] # 0xef83 + - "": [T: "podwójny zero przez podwójny zero"] # 0xef90 + - "": [T: "zero z ukośnikiem"] # 0xef91 # 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: "fraktura" + - T: "fraktura" - spell: "translate('.', '𝔄𝔅𝔆𝔇𝔈𝔉𝔊𝔋𝔌𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔𝔕𝔖𝔗𝔘𝔙𝔚𝔛𝔜', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - "-": # 0xf000 - 0xf018 - - t: "fraktura" + - T: "fraktura" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXY')" - "𝔞-𝔷": # 0x1d51e - 0x1d537 - - t: "fraktura" + - T: "fraktura" - spell: "translate('.', '𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf01a - 0xf033 - - t: "fraktura" + - T: "fraktura" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝕬-𝖅": # 0x1D56C - 0x1D585 - - t: "fraktura" - - t: "pogrubione" + - T: "fraktura" + - T: "pogrubione" - spell: "translate('.', '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf040 - 0xf059 - - t: "fraktura" - - t: "pogrubione" + - T: "fraktura" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝖆-𝖟": # 0x1d586 - 0x1d59f - - t: "fraktura" - - t: "pogrubione" + - T: "fraktura" + - T: "pogrubione" - spell: "translate('.', '𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf05a - 0xf073 - - t: "fraktura" - - t: "pogrubione" + - T: "fraktura" + - T: "pogrubione" - 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: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '𝔸𝔹𝔺𝔻𝔼𝔽𝔾𝔿𝕀𝕁𝕂𝕃𝕄𝕅𝕆𝕇𝕈𝕉𝕊𝕋𝕌𝕍𝕎𝕏𝕐', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf080 - 0xf098 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝕒-𝕫": # 0x1d552 - 0x1d56b - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf09a - 0xf0b3 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝟘-𝟡": # 0x1d7d8 - 0x1d7e1 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡', '0123456789')" - "-": # 0xf0c0 - 0xf0c9 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', '0123456789')" - - "": [t: "dwukreskowe nabla"] # 0xf0ca - - "": [t: "dwukreskowa stała Eulera"] # 0xf0cb + - "": [T: "dwukreskowe nabla"] # 0xf0ca + - "": [T: "dwukreskowa stała Eulera"] # 0xf0cb # script chars in math alphabetic block and also MathType private use area - "𝒜-𝒵": # 0x1d49c - 0x1d4b5 - - t: "pisane" + - T: "pisane" - spell: "translate('.', '𝒜𝒝𝒞𝒟𝒠𝒡𝒢𝒣𝒤𝒥𝒦𝒧𝒨𝒩𝒪𝒫𝒬𝒭𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf100 - 0xf119 - - t: "pisane" + - T: "pisane" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝒶-𝓏": # 0x1d4b6 - 0x1d4cf - - t: "pisane" + - T: "pisane" - spell: "translate('.', '𝒶𝒷𝒸𝒹𝒺𝒻𝒼𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝓄𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf11a - 0xf133 - - t: "pisane" + - T: "pisane" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" # bold script chars in math alphabetic block and also MathType private use area - "𝓐-𝓩": # 0x1d4d0 - 0x1d4e9 - - t: "pisane" - - t: "pogrubione" + - T: "pisane" + - T: "pogrubione" - spell: "translate('.', '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf140 - 0xf159 - - t: "pisane" - - t: "pogrubione" + - T: "pisane" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝓪-𝔃": # 0x1d4ea - 0x1d503 - - t: "pisane" - - t: "pogrubione" + - T: "pisane" + - T: "pogrubione" - spell: "translate('.', '𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf15a - 0xf173 - - t: "pisane" - - t: "pogrubione" + - T: "pisane" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf180 - 0xf199 @@ -3179,11 +3179,11 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" - replace: [t: "ligatura ae"] + replace: [T: "ligatura ae"] - "": # 0xf19b - test: if: "$CapitalLetters_Beep" @@ -3197,11 +3197,11 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" - replace: [t: "eszett"] + replace: [T: "eszett"] - "": # 0xf19c - test: if: "$CapitalLetters_Beep" @@ -3215,38 +3215,38 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" - replace: [t: "o z kreską"] + replace: [T: "o z kreską"] # MathType only has a few of the cap Greek letters in PUA - "": # 0xf201 - 0xf209 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', 'ΔΨΛΠΣΘΓΩΥ')" - "-": # 0xf220 - 0xf236 - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - - "": [t: "dwukreskowe sigma końcowa"] # 0xf237 - - "": [t: "dwukreskowe ro"] # 0xf250 - - "": [t: "dwukreskowe fi"] # 0xf251 + - "": [T: "dwukreskowe sigma końcowa"] # 0xf237 + - "": [T: "dwukreskowe ro"] # 0xf250 + - "": [T: "dwukreskowe fi"] # 0xf251 - "𝐀-𝐙": # 0x1d400 - 0x1d419 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf260 - 0xf279 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝐚-𝐳": # 0x1d41a - 0x1d433 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf27a - 0xf293 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝐴-𝑍": # 0x1d434 - 0x1d44d @@ -3262,23 +3262,23 @@ - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝑨-𝒁": # 0x1d468 - 0x1d481 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝑨𝑩𝑪𝑫𝑬𝑭𝑮𝑯𝑰𝑱𝑲𝑳𝑴𝑵𝑶𝑷𝑸𝑹𝑺𝑻𝑼𝑽𝑾𝑿𝒀𝒁', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf2c8 - 0xf2e1 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝒂-𝒛": # 0x1d482 - 0x1d49b - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝒂𝒃𝒄𝒅𝒆𝒇𝒈𝒉𝒊𝒋𝒌𝒍𝒎𝒏𝒐𝒑𝒒𝒓𝒔𝒕𝒖𝒗𝒘𝒙𝒚𝒛', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf2e2 - 0xf2fb - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝖠-𝖹": # 0x1d5a0 - 0x1d5b9 @@ -3294,53 +3294,53 @@ - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝗔-𝗭": # 0x1d5d4 - 0x1d5ed - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf334 - 0xf34d - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝗮-𝘇": # 0x1d5ee - 0x1d607 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf34e - 0xf367 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝘈-𝘡": # 0x1d608 - 0x1d621 - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf368 - 0xf381 - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝘢-𝘻": # 0x1d622 - 0x1d63b - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf382 - 0xf39b - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝘼-𝙕": # 0x1d63c - 0x1d655 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "-": # 0xf39c - 0xf3b5 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" - "𝙖-𝙯": # 0x1d656 - 0x1d66f - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯', 'abcdefghijklmnopqrstuvwxyz')" - "-": # 0xf3b6 - 0xf3cf - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - "𝙰-𝚉": # 0x1d670 - 0x1d689 @@ -3355,170 +3355,170 @@ - "-": # 0xf3ea - 0xf403 - spell: "translate('.', '', 'abcdefghijklmnopqrstuvwxyz')" - - "": [t: "bez kropki I"] # 0xf404 - - "𝚤": [t: "bez kropki I"] # 0x1d6a4 - - "𝚥": [t: "j bez kropki"] # 0x1d6a5 + - "": [T: "bez kropki I"] # 0xf404 + - "𝚤": [T: "bez kropki I"] # 0x1d6a4 + - "𝚥": [T: "j bez kropki"] # 0x1d6a5 - "𝚨-𝛀": # 0x1d6a8 - 0x1d6c0 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝚨𝚩𝚪𝚫𝚬𝚭𝚮𝚯𝚰𝚱𝚲𝚳𝚴𝚵𝚶𝚷𝚸𝚹𝚺𝚻𝚼𝚽𝚾𝚿𝛀', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf408 - 0xf420 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝛂-𝛚": # 0x1d6c2 - 0x1d6da - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝛂𝛃𝛄𝛅𝛆𝛇𝛈𝛉𝛊𝛋𝛌𝛍𝛎𝛏𝛐𝛑𝛒𝛓𝛔𝛕𝛖𝛗𝛘𝛙𝛚', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf422 - 0xf43a - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - "": [t: "pogrubiona nabla"] # 0xf421 - - "𝛁": [t: "pogrubiona nabla"] # 0x1d6c1 + - "": [T: "pogrubiona nabla"] # 0xf421 + - "𝛁": [T: "pogrubiona nabla"] # 0x1d6c1 - "𝛛𝛜𝛝𝛞𝛟𝛠𝛡": # 0x1D6DB - 0x1D6E1 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝛛𝛜𝛝𝛞𝛟𝛠𝛡', '∂εθκφρπ')" - "": # 0xF43C - 0xF441 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', '∂εθκφρπ')" - "𝛢-𝛺": # 0x1d6e2 - 0x1d6fa - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝛢𝛣𝛤𝛥𝛦𝛧𝛨𝛩𝛪𝛫𝛬𝛭𝛮𝛯𝛰𝛱𝛲𝛳𝛴𝛵𝛶𝛷𝛸𝛹𝛺', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf442 - 0xf45a - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝛼-𝜔": # 0x1d6fc - 0x1d714 - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf45c - 0xf474 - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - - "": [t: "kursywa nabla"] # 0xf45b - - "𝛻": [t: "kursywa nabla"] # 0x1d6fb + - "": [T: "kursywa nabla"] # 0xf45b + - "𝛻": [T: "kursywa nabla"] # 0x1d6fb - "𝜕𝜖𝜗𝜘𝜙𝜚𝜛": # 0x1d715 - 0x1d71b - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '𝜕𝜖𝜗𝜘𝜙𝜚𝜛', '∂εθκφρπ')" - "": # 0xf475 - 0xf47b - # - t: "kursywa" + # - T: "kursywa" - spell: "translate('.', '', '∂εθκφρπ')" - "𝜜-𝜴": # 0x1d71c - 0x1d734 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝜜𝜝𝜞𝜟𝜠𝜡𝜢𝜣𝜤𝜥𝜦𝜧𝜨𝜩𝜪𝜫𝜬𝜭𝜮𝜯𝜰𝜱𝜲𝜳𝜴', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf47c - 0xf494 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝜶-𝝎": # 0x1d736 - 0x1d74e - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝜶𝜷𝜸𝜹𝜺𝜻𝜼𝜽𝜾𝜿𝝀𝝁𝝂𝝃𝝄𝝅𝝆𝝇𝝈𝝉𝝊𝝋𝝌𝝍𝝎', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf496 - 0xf4ae - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝝏𝝐𝝑𝝒𝝓𝝔𝝕": # 0x1d74f - 0x1d755 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝝏𝝐𝝑𝝒𝝓𝝔𝝕', '∂εθκφρπ')" - "": # 0xf422 - 0xf43a - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', '∂εθκφρπ')" - - "𝜵": [t: "pogrubiona pochylona nabla"] # 0x1d735 - - "": [t: "pogrubiona pochylona nabla"] # 0xf495 + - "𝜵": [T: "pogrubiona pochylona nabla"] # 0x1d735 + - "": [T: "pogrubiona pochylona nabla"] # 0xf495 - "𝝖-𝝮": # 0x1d756 - 0x1d76e - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝝖𝝗𝝘𝝙𝝚𝝛𝝜𝝝𝝞𝝟𝝠𝝡𝝢𝝣𝝤𝝥𝝦𝝧𝝨𝝩𝝪𝝫𝝬𝝭𝝮', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf4b6 - 0xf4ce - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝝰-𝞈": # 0x1d770 - 0x1d788 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝝰𝝱𝝲𝝳𝝴𝝵𝝶𝝷𝝸𝝹𝝺𝝻𝝼𝝽𝝾𝝿𝞀𝞁𝞂𝞃𝞄𝞅𝞆𝞇𝞈', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf4d0 - 0xf4e8 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝞉𝞊𝞋𝞌𝞍𝞎𝞏": # 0x1d789 - 0x1d78f - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝞉𝞊𝞋𝞌𝞍𝞎𝞏', '∂εθκφρπ')" - "": # 0xf4e9 - 0xf4ef - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', '∂εθκφρπ')" - - "": [t: "pogrubiona nabla"] # 0xf4cf - - "𝝯": [t: "pogrubiona nabla"] # 0x1d76f + - "": [T: "pogrubiona nabla"] # 0xf4cf + - "𝝯": [T: "pogrubiona nabla"] # 0x1d76f - "𝞐-𝞨": # 0x1d790 - 0x1d7a8 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝞐𝞑𝞒𝞓𝞔𝞕𝞖𝞗𝞘𝞙𝞚𝞛𝞜𝞝𝞞𝞟𝞠𝞡𝞢𝞣𝞤𝞥𝞦𝞧𝞨', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "-": # 0xf4f0 - 0xf508 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ')" - "𝞪-𝟂": # 0x1d7aa - 0x1d7c2 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝞪𝞫𝞬𝞭𝞮𝞯𝞰𝞱𝞲𝞳𝞴𝞵𝞶𝞷𝞸𝞹𝞺𝞻𝞼𝞽𝞾𝞿𝟀𝟁𝟂', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "-": # 0xf50a - 0xf522 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', 'αβγδεζηθικλμνξοπρςστυφχψω')" - "𝟃𝟄𝟅𝟆𝟇𝟈𝟉": # 0x1d7c3 - 0x1d7c9 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '𝟃𝟄𝟅𝟆𝟇𝟈𝟉', '∂εθκφρπ')" - "": # 0xf523 - 0xf529 - # - t: "pogrubiona kursywa" - - t: "pogrubione" + # - T: "pogrubiona kursywa" + - T: "pogrubione" - spell: "translate('.', '', '∂εθκφρπ')" - - "": [t: "pogrubiona nabla"] # 0xf509 - - "𝞩": [t: "pogrubiona nabla"] # 0x1d7a9 + - "": [T: "pogrubiona nabla"] # 0xf509 + - "𝞩": [T: "pogrubiona nabla"] # 0x1d7a9 - "-": # 0xf52e - 0xf537 (old MathType) - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', '0123456789')" - "𝟎-𝟗": # 0x1d7ce - 0x1d7d7 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗', '0123456789')" - "-": # 0xf52e - 0xf537 (old MathType) - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '', '0123456789')" - "𝟬-𝟵": # 0x1D7EC - 0x1D7F5 - - t: "pogrubione" + - T: "pogrubione" - spell: "translate('.', '𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟵', '0123456789')" - "-": # 0xf556 - 0xf55f (old MathType) @@ -3532,37 +3532,37 @@ - spell: "translate('.', '𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿', '0123456789')" - - "": [t: "nieznany znak"] # 0xf700 - - "": [t: "dolny prawy i dolny lewy trójkąt"] # 0xf726 - - "": [t: "poziome przedłużenie wielokropka"] # 0xf72d - - "": [t: "poziome przedłużenie wielokropka w linii środkowej"] # 0xf72e - - "": [t: "przedłużenie znaku pierwiastka"] # 0xf8e5 - - "": [t: "pionowy strzałka przedłużenie"] # 0xf8e6 - - "": [t: "poziomy strzałka przedłużenie"] # 0xf8e7 - - "": [t: "bezszeryfowy znak zastrzeżony"] # 0xf8e8 - - "": [t: "znak praw autorskich znak bezszeryfowe"] # 0xf8e9 - - "": [t: "bezszeryfowy znak towarowy"] # 0xf8ea - - "": [t: "lewy nawias górny"] # 0xf8eb - - "": [t: "lewy nawias przedłużenie"] # 0xf8ec - - "": [t: "lewy nawias dolny"] # 0xf8ed - - "": [t: "lewy nawias kwadratowy górny"] # 0xf8ee - - "": [t: "lewy nawias kwadratowy przedłużenie"] # 0xf8ef - - "": [t: "lewy nawias kwadratowy dolny"] # 0xf8f0 - - "": [t: "lewy nawias klamrowy górny"] # 0xf8f1 - - "": [t: "lewy nawias klamrowy środkowy"] # 0xf8f2 - - "": [t: "lewy nawias klamrowy dolny"] # 0xf8f3 - - "": [t: "nawias klamrowy przedłużenie"] # 0xf8f4 - - "": [t: "całka przedłużenie"] # 0xf8f5 - - "": [t: "prawy nawias górny"] # 0xf8f6 - - "": [t: "prawy nawias przedłużenie"] # 0xf8f7 - - "": [t: "prawy nawias dolny"] # 0xf8f8 - - "": [t: "prawy nawias kwadratowy górny"] # 0xf8f9 - - "": [t: "prawy nawias kwadratowy przedłużenie"] # 0xf8fa - - "": [t: "prawy nawias kwadratowy dolny"] # 0xf8fb - - "": [t: "prawy nawias klamrowy górny"] # 0xf8fc - - "": [t: "prawy nawias klamrowy środkowy"] # 0xf8fd - - "": [t: "prawy nawias klamrowy dolny"] # 0xf8fe - - "": [t: "logo jabłka"] # 0xf8ff + - "": [T: "nieznany znak"] # 0xf700 + - "": [T: "dolny prawy i dolny lewy trójkąt"] # 0xf726 + - "": [T: "poziome przedłużenie wielokropka"] # 0xf72d + - "": [T: "poziome przedłużenie wielokropka w linii środkowej"] # 0xf72e + - "": [T: "przedłużenie znaku pierwiastka"] # 0xf8e5 + - "": [T: "pionowy strzałka przedłużenie"] # 0xf8e6 + - "": [T: "poziomy strzałka przedłużenie"] # 0xf8e7 + - "": [T: "bezszeryfowy znak zastrzeżony"] # 0xf8e8 + - "": [T: "znak praw autorskich znak bezszeryfowe"] # 0xf8e9 + - "": [T: "bezszeryfowy znak towarowy"] # 0xf8ea + - "": [T: "lewy nawias górny"] # 0xf8eb + - "": [T: "lewy nawias przedłużenie"] # 0xf8ec + - "": [T: "lewy nawias dolny"] # 0xf8ed + - "": [T: "lewy nawias kwadratowy górny"] # 0xf8ee + - "": [T: "lewy nawias kwadratowy przedłużenie"] # 0xf8ef + - "": [T: "lewy nawias kwadratowy dolny"] # 0xf8f0 + - "": [T: "lewy nawias klamrowy górny"] # 0xf8f1 + - "": [T: "lewy nawias klamrowy środkowy"] # 0xf8f2 + - "": [T: "lewy nawias klamrowy dolny"] # 0xf8f3 + - "": [T: "nawias klamrowy przedłużenie"] # 0xf8f4 + - "": [T: "całka przedłużenie"] # 0xf8f5 + - "": [T: "prawy nawias górny"] # 0xf8f6 + - "": [T: "prawy nawias przedłużenie"] # 0xf8f7 + - "": [T: "prawy nawias dolny"] # 0xf8f8 + - "": [T: "prawy nawias kwadratowy górny"] # 0xf8f9 + - "": [T: "prawy nawias kwadratowy przedłużenie"] # 0xf8fa + - "": [T: "prawy nawias kwadratowy dolny"] # 0xf8fb + - "": [T: "prawy nawias klamrowy górny"] # 0xf8fc + - "": [T: "prawy nawias klamrowy środkowy"] # 0xf8fd + - "": [T: "prawy nawias klamrowy dolny"] # 0xf8fe + - "": [T: "logo jabłka"] # 0xf8ff - "ff": [T: "ff"] # 0xfb00 - "fi": [t: "fi"] # 0xfb01 - "fl": [T: "fl"] # 0xfb02 @@ -3570,31 +3570,31 @@ - "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 - - "︢": [t: "podwójny tylda lewa połowa ozdobnik"] # 0xfe22 - - "︣": [t: "podwójny tylda prawa połowa ozdobnik"] # 0xfe23 - - "︤": [t: "makron lewa połowa ozdobnik"] # 0xfe24 - - "︥": [t: "makron prawa połowa ozdobnik"] # 0xfe25 - - "︦": [t: "łączący ozdobnik makronu"] # 0xfe26 - - "︵": [t: "przez nawias"] # 0xfe35 - - "︶": [t: "pod nawias"] # 0xfe36 - - "︷": [t: "przez nawias klamrowy"] # 0xfe37 - - "︸": [t: "pod nawias klamrowy"] # 0xfe38 - - "︿": [t: "przez kąt nawias kwadratowy"] # 0xfe3f - - "﹀": [t: "pod kąt nawias kwadratowy"] # 0xfe40 - - "﹡": [t: "mały gwiazdka"] # 0xfe61 - - "﹢": [t: "mały plus"] # 0xfe62 - - "﹣": [t: "mały minus"] # 0xfe63 - - "﹤": [t: "mały mniejsze niż"] # 0xfe64 - - "﹥": [t: "mały większe niż"] # 0xfe65 - - "﹦": [t: "mały równa się"] # 0xfe66 - - "+": [t: "pełnoszeroki znak plus"] # 0xff0b + - "﬩": [T: "hebrajska litera alternatywny znak plus"] # 0xfb29 + - "︠": [T: "lewa połowa ligatury, ozdobnik"] # 0xfe20 + - "︡": [T: "prawa połowa ligatury, ozdobnik"] # 0xfe21 + - "︢": [T: "podwójny tylda lewa połowa ozdobnik"] # 0xfe22 + - "︣": [T: "podwójny tylda prawa połowa ozdobnik"] # 0xfe23 + - "︤": [T: "makron lewa połowa ozdobnik"] # 0xfe24 + - "︥": [T: "makron prawa połowa ozdobnik"] # 0xfe25 + - "︦": [T: "łączący ozdobnik makronu"] # 0xfe26 + - "︵": [T: "przez nawias"] # 0xfe35 + - "︶": [T: "pod nawias"] # 0xfe36 + - "︷": [T: "przez nawias klamrowy"] # 0xfe37 + - "︸": [T: "pod nawias klamrowy"] # 0xfe38 + - "︿": [T: "przez kąt nawias kwadratowy"] # 0xfe3f + - "﹀": [T: "pod kąt nawias kwadratowy"] # 0xfe40 + - "﹡": [T: "mały gwiazdka"] # 0xfe61 + - "﹢": [T: "mały plus"] # 0xfe62 + - "﹣": [T: "mały minus"] # 0xfe63 + - "﹤": [T: "mały mniejsze niż"] # 0xfe64 + - "﹥": [T: "mały większe niż"] # 0xfe65 + - "﹦": [T: "mały równa się"] # 0xfe66 + - "+": [T: "pełnoszeroki znak plus"] # 0xff0b - "<": [T: "mniejsze niż"] # 0xff1c - "=": [T: "równa się"] # 0xff1d - ">": [T: "większe niż"] # 0xff1e - - "\": [t: "ukośnik odwrotny"] # 0xff3c + - "\": [T: "ukośnik odwrotny"] # 0xff3c - "^": [T: "daszek"] # 0xff3e - "|": # 0xff5c # note: for ClearSpeak and SimpleSpeak, "|" inside of sets is handled at the mrow level, same for 'sets' @@ -3616,21 +3616,21 @@ - else: [T: "dzieli"] - "~": [T: "tylda"] # 0xff5e - "¬": [T: "nie"] # 0xffe2 - - "←": [t: "strzałka w lewo"] # 0xffe9 - - "↑": [t: "strzałka w górę"] # 0xffea - - "→": [t: "strzałka w prawo"] # 0xffeb - - "↓": [t: "strzałka w dół"] # 0xffec - - "": [t: "nieznany lub brakujący obiekt"] # 0xfffc - - "�": [t: "nieznany lub brakujący znak"] # 0xfffd + - "←": [T: "strzałka w lewo"] # 0xffe9 + - "↑": [T: "strzałka w górę"] # 0xffea + - "→": [T: "strzałka w prawo"] # 0xffeb + - "↓": [T: "strzałka w dół"] # 0xffec + - "": [T: "nieznany lub brakujący obiekt"] # 0xfffc + - "�": [T: "nieznany lub brakujący znak"] # 0xfffd - - "🣑": [t: "jest w równowadze z"] # 0x1F8D1 - - "🣒": [t: "jest w równowadze przesuniętej w prawo z"] # 0x1F8D2 - - "🣓": [t: "jest w równowadze przesuniętej w lewo z"] # 0x1F8D3 + - "🣑": [T: "jest w równowadze z"] # 0x1F8D1 + - "🣒": [T: "jest w równowadze przesuniętej w prawo z"] # 0x1F8D2 + - "🣓": [T: "jest w równowadze przesuniętej w lewo z"] # 0x1F8D3 # MathJax v4 has adopted these PUA values for some partial chem bonds that aren't in Unicode - - "\uE410": [t: "wiązanie cząstkowe"] # 0xe410 - - "\uE411": [t: "podwójne wiązanie cząstkowe"] # 0xe411 - - "\uE412": [t: "potrójne wiązanie cząstkowe"] # 0xe412 + - "\uE410": [T: "wiązanie cząstkowe"] # 0xe410 + - "\uE411": [T: "podwójne wiązanie cząstkowe"] # 0xe411 + - "\uE412": [T: "potrójne wiązanie cząstkowe"] # 0xe412 # MathJax v4 also adopted these PUA values for some arrows thar are in Unicode # Hopefully these will be exported properly in future versions of MathJax diff --git a/Rules/Languages/pl/unicode.yaml b/Rules/Languages/pl/unicode.yaml index bd3ee353a..c67b5cc8a 100644 --- a/Rules/Languages/pl/unicode.yaml +++ b/Rules/Languages/pl/unicode.yaml @@ -5,12 +5,12 @@ - "a": - test: if: "$TTS='none'" - then: [t: "a"] # long "a" sound in all speech engines I tested (espeak, MS SAPI, eloquence, + then: [T: "a"] # long "a" sound in all speech engines I tested (espeak, MS SAPI, eloquence, else: [spell: "'a'"] # AWS Polly, ReadSpeaker, NaturalReader, google cloud, nuance, ibm watson) - "b-z": - test: if: "$TTS='none'" - then: [t: "."] + then: [T: "."] else: [spell: "'.'"] # Capital letters are a little tricky: users can pick their favorite word (something that was requested) and @@ -30,14 +30,14 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" replace: - test: if: "$TTS='none'" - then: [t: "a"] + then: [T: "a"] else: [spell: "'a'"] - "B-Z": @@ -53,7 +53,7 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] else: [x: "$SpeechOverrides_CapitalLetters"] - pitch: value: "$CapitalLetters_Pitch" @@ -73,12 +73,12 @@ else: [T: "wykrzyknik"] # 0x21 else: [T: "silnia"] # 0x21 - - "\"": [t: "cudzysłów"] # 0x22 - - "#": [t: "numer"] # 0x23 - - "$": [t: "dolary"] # 0x24 + - "\"": [T: "cudzysłów"] # 0x22 + - "#": [T: "numer"] # 0x23 + - "$": [T: "dolary"] # 0x24 - "%": [T: "procent"] # 0x25 - - "&": [t: "znak et"] # 0x26 - - "'": [t: "apostrof"] # 0x27 + - "&": [T: "znak et"] # 0x26 + - "'": [T: "apostrof"] # 0x27 - "(": # 0x28 - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' @@ -105,7 +105,7 @@ then: [T: "gwiazdkowa"] # 0x2a (norma 'gwiazdkowa' - * jako indeks normy) else_test: if: "parent::*[name(.)='msup' or name(.)='msubsup' or name(.)='skip-super']" - then: [t: "gwiazda"] # 0x2a + then: [T: "gwiazda"] # 0x2a else: [T: "razy"] # 0x2a - "+": [T: "plus"] # 0x2b - ",": # 0x2c @@ -157,7 +157,7 @@ then: [T: "jest"] - T: "większe niż" - "?": [T: "znak zapytania"] # 0x3f - - "@": [t: "małpa"] # 0x40 + - "@": [T: "małpa"] # 0x40 - "[": # 0x5b - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' @@ -173,9 +173,9 @@ - test: if: "parent::m:modified-variable or parent::m:mover" then: [T: "daszek"] - else: [t: "daszek"] - - "_": [t: "pod kreska"] # 0x5f - - "`": [t: "grawis"] # 0x60 + else: [T: "daszek"] + - "_": [T: "pod kreska"] # 0x5f + - "`": [T: "grawis"] # 0x60 - "{": # 0x7b - test: if: $SpeechStyle = 'ClearSpeak' or $SpeechStyle = 'SimpleSpeak' @@ -226,7 +226,7 @@ then: [T: "stopni"] else: [T: "stopień"] - "±": [T: "plus minus"] # 0xb1 - - "´": [t: "akut"] # 0xb4 + - "´": [T: "akut"] # 0xb4 - "·": # 0xB7 - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')] or not($SpeechStyle = 'ClearSpeak' and $ClearSpeak_MultSymbolDot = 'Auto')" @@ -240,21 +240,21 @@ then: [T: "razy"] - else_if: "$ClearSpeak_MultSymbolX = 'By'" then: [T: "na"] - else: [t: "krzyż"] + else: [T: "krzyż"] else_test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "krzyż"] + then: [T: "krzyż"] else: [T: "razy"] - "÷": [T: "podzielone przez"] # 0xf7 - - "̀": [t: "ozdobnik akcentu grawis"] # 0x300 - - "́": [t: "ozdobnik akcentu ostrego"] # 0x301 - - "̂": [t: "ozdobnik daszka"] # 0x302 - - "̃": [t: "ozdobnik tyldy"] # 0x303 - - "̄": [t: "ozdobnik makronu"] # 0x304 - - "̅": [t: "ozdobnik kreski górnej"] # 0x305 - - "̆": [t: "znak krótkości"] # 0x306 - - "̇": [t: "ozdobnik kropki nad"] # 0x307 + - "̀": [T: "ozdobnik akcentu grawis"] # 0x300 + - "́": [T: "ozdobnik akcentu ostrego"] # 0x301 + - "̂": [T: "ozdobnik daszka"] # 0x302 + - "̃": [T: "ozdobnik tyldy"] # 0x303 + - "̄": [T: "ozdobnik makronu"] # 0x304 + - "̅": [T: "ozdobnik kreski górnej"] # 0x305 + - "̆": [T: "znak krótkości"] # 0x306 + - "̇": [T: "ozdobnik kropki nad"] # 0x307 # Note: ClearSpeak has pref TriangleSymbol for "Δ", but that is wrong - "Α-Ω": @@ -270,47 +270,47 @@ if: "$SpeechOverrides_CapitalLetters = ''" then_test: if: "$Impairment = 'Blindness'" - then: [t: "wielka"] + then: [T: "wielka"] 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('.', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩ', 'αβγδεζηθικλμνξοπρςστυφχψω')"] - - "α": [t: "alfa"] # 0x3b1 + - "α": [T: "alfa"] # 0x3b1 - "β": [t: "beta"] # 0x3b2 - "γ": [t: "gamma"] # 0x3b3 - "δ": [t: "delta"] # 0x3b4 - "ε": [t: "epsilon"] # 0x3b5 - - "ζ": [t: "dzeta"] # 0x3b6 + - "ζ": [T: "dzeta"] # 0x3b6 - "η": [t: "eta"] # 0x3b7 - "θ": [t: "theta"] # 0x3b8 - - "ι": [t: "jota"] # 0x3b9 + - "ι": [T: "jota"] # 0x3b9 - "κ": [t: "kappa"] # 0x3ba - "λ": [t: "lambda"] # 0x3bb - - "μ": [t: "mi"] # 0x3bc - - "ν": [t: "ni"] # 0x3bd - - "ξ": [t: "ksi"] # 0x3be - - "ο": [t: "omikron"] # 0x3bf + - "μ": [T: "mi"] # 0x3bc + - "ν": [T: "ni"] # 0x3bd + - "ξ": [T: "ksi"] # 0x3be + - "ο": [T: "omikron"] # 0x3bf - "π": [t: "pi"] # 0x3c0 - - "ρ": [t: "ro"] # 0x3c1 - - "ς": [t: "sigma końcowa"] # 0x3c2 + - "ρ": [T: "ro"] # 0x3c1 + - "ς": [T: "sigma końcowa"] # 0x3c2 - "σ": [t: "sigma"] # 0x3c3 - "τ": [t: "tau"] # 0x3c4 - - "υ": [t: "ypsilon"] # 0x3c5 - - "φ": [t: "fi"] # 0x3c6 + - "υ": [T: "ypsilon"] # 0x3c5 + - "φ": [T: "fi"] # 0x3c6 - "χ": [t: "chi"] # 0x3c7 - "ψ": [t: "psi"] # 0x3c8 - "ω": [t: "omega"] # 0x3c9 - - "ϕ": [t: "fi"] # 0x3d5 + - "ϕ": [T: "fi"] # 0x3d5 - "ϖ": [t: "pi"] # 0x3d6 - "ϵ": [t: "epsilon"] # 0x3f5 - - "϶": [t: "odwrócony epsilon"] # 0x3f6 + - "϶": [T: "odwrócony epsilon"] # 0x3f6 - - "–": [t: "półpauza"] # 0x2013 - - "—": [t: "pauza"] # 0x2014 - - "―": [t: "kreska pozioma"] # 0x2015 - - "‖": [t: "podwójna pionowa kreska"] # 0x2016 + - "–": [T: "półpauza"] # 0x2013 + - "—": [T: "pauza"] # 0x2014 + - "―": [T: "kreska pozioma"] # 0x2015 + - "‖": [T: "podwójna pionowa kreska"] # 0x2016 - "…": # 0x2026 test: if: @@ -318,11 +318,11 @@ # must be ClearSpeak and $ClearSpeak_Ellipses = 'AndSoOn' # speak '…' as 'and so on...' unless expr starts with '…' - "../*[1][.='…']" - then: [t: "trzy kropki"] + then: [T: "trzy kropki"] else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn' if: "count(following-sibling::*) = 0" - then: [t: "i tak dalej"] - else: [t: "i tak dalej aż do"] + then: [T: "i tak dalej"] + else: [T: "i tak dalej aż do"] - "⁡": # 0x2061 - test: @@ -340,55 +340,55 @@ - "⁢": [T: ""] # 0x2062 - "⁣": [T: ""] # 0x2063 - "⁤": [T: "i"] # 0x2064 - - "′": [t: "prim"] # 0x2032 - - "″": [t: "podwójny prim"] # 0x2033 - - "‴": [t: "potrójny prim"] # 0x2034 + - "′": [T: "prim"] # 0x2032 + - "″": [T: "podwójny prim"] # 0x2033 + - "‴": [T: "potrójny prim"] # 0x2034 - "ℂℕℚℝℤ": # here we rely on this running through the table again to speak "cap xxx" - - t: "dwukreskowe" + - T: "dwukreskowe" - spell: "translate('.', 'ℂℕℚℝℤ', 'CNQRZ')" - - "℃": [t: "stopnie Celsjusza"] # 0x2103 - - "℉": [t: "stopnie Fahrenheita"] # 0x2109 + - "℃": [T: "stopnie Celsjusza"] # 0x2103 + - "℉": [T: "stopnie Fahrenheita"] # 0x2109 - "ℋℛℓ": # 0x210b - - t: "pisane" + - T: "pisane" - spell: "translate('.', 'ℋℛℓ', 'HRl')" - - "ℎ": [t: "stała Plancka"] # 0x210e + - "ℎ": [T: "stała Plancka"] # 0x210e - "ℜ": # 0x211c - - t: "fraktura" + - T: "fraktura" - spell: "'R'" - - "Ω": [t: "omy"] # 0x2126 - - "K": [t: "kelwin"] # 0x212a - - "Å": [t: "angstremy"] # 0x212b + - "Ω": [T: "omy"] # 0x2126 + - "K": [T: "kelwin"] # 0x212a + - "Å": [T: "angstremy"] # 0x212b - "ⅆⅇⅈⅉ": # 0x2146-9 - - t: "dwukreskowa kursywa" + - T: "dwukreskowa kursywa" - spell: "translate('.', 'ⅆⅇⅈⅉ', 'deij')" - - "←": [t: "strzałka w lewo"] # 0x2190 - - "↑": [t: "strzałka w górę"] # 0x2191 + - "←": [T: "strzałka w lewo"] # 0x2190 + - "↑": [T: "strzałka w górę"] # 0x2191 - "→": # 0x2192 - test: if: "ancestor::*[2][self::m:limit or self::m:limit-sup or self::m:limit-inf]" - then: [t: "dąży do"] + then: [T: "dąży do"] else_test: if: "parent::*[self::m:mrow]/parent::*[self::m:subscripted-norm]" - then: [t: "do"] # indeks normy operatorowej ‖·‖_{p→q}: → czyta sie "do" - else: [t: "strzałka w prawo"] + then: [T: "do"] # indeks normy operatorowej ‖·‖_{p→q}: → czyta sie "do" + else: [T: "strzałka w prawo"] - - "↓": [t: "strzałka w dół"] # 0x2193 + - "↓": [T: "strzałka w dół"] # 0x2193 - "⇒": [T: "implikuje"] # 0x21d2 - - "∀": [t: "dla każdego"] # 0x2200 + - "∀": [T: "dla każdego"] # 0x2200 - "∂": # 0x2202 - test: if: "$Verbosity='Terse'" - then: [t: "cząstkowe"] - else: [t: "pochodna cząstkowa"] - - "∃": [t: "istnieje"] # 0x2203 - - "∄": [t: "nie istnieje"] # 0x2204 + then: [T: "cząstkowe"] + else: [T: "pochodna cząstkowa"] + - "∃": [T: "istnieje"] # 0x2203 + - "∄": [T: "nie istnieje"] # 0x2204 - "∅": [T: "zbiór pusty"] # 0x2205 - "∆": # 0x2206 - - t: "laplasjan" + - T: "laplasjan" - "∈": # 0x2208 - test: if: "$SpeechStyle != 'ClearSpeak'" @@ -396,7 +396,7 @@ - test: if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" then: [T: "jest"] - - t: "elementem zbioru" + - T: "elementem zbioru" # 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 @@ -404,43 +404,43 @@ - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "element zbioru"] + then: [T: "element zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "należy do"] - - else: [t: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "należy do"] - - else: [t: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - "∉": # 0x2209 # rule is identical to 0x2208 - test: if: "$SpeechStyle != 'ClearSpeak'" then: - - t: "nie jest elementem zbioru" + - T: "nie jest elementem zbioru" # 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: "nie należy do"] + then: [T: "nie należy do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "nie jest elementem zbioru"] - - else: [t: "nienależące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "nie jest elementem zbioru"] + - else: [T: "nienależące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "nie jest elementem zbioru"] + then: [T: "nie jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "nie należy do"] - - else: [t: "nie należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "nie należy do"] + - else: [T: "nie należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - "∊": # 0x220a - test: if: "$SpeechStyle != 'ClearSpeak'" @@ -448,7 +448,7 @@ - test: if: "$Verbosity!='Terse' and not(ancestor::*[self::m:set])" # "the set x is an element of ..." sounds bad" then: [T: "jest"] - - t: "element zbioru" + - T: "element zbioru" # 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 @@ -456,20 +456,20 @@ - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In' then: [T: "do"] - else_if: $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "element zbioru"] + then: [T: "element zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "należy do"] - - else: [t: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należące do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' else_test: - if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'Element' - then: [t: "jest elementem zbioru"] + then: [T: "jest elementem zbioru"] - else_if: $ClearSpeak_SetMemberSymbol = 'In' - then: [t: "należy do"] - - else: [t: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' + then: [T: "należy do"] + - else: [T: "należy do"] # $ClearSpeak_SetMemberSymbol = 'Belongs' - "∏": [T: "iloczyn"] # 0x220f - - "∐": [t: "koprodukt"] # 0x2210 + - "∐": [T: "koprodukt"] # 0x2210 - "∑": [T: "suma"] # 0x2211 - "−": [T: "minus"] # 0x2212 - "∓": [T: "minus plus"] # 0x2213 @@ -481,60 +481,60 @@ - "parent::*[name(.)='msubsup' and *[1][self::m:mo and .='∥']] and count(preceding-sibling::*)=1" then: [T: "gwiazdkowa"] # norma ‖·‖_* -> "norma gwiazdkowa" else: [T: "razy"] # 0x2217 - - "∘": [t: "złożone z"] # 0x2218 + - "∘": [T: "złożone z"] # 0x2218 - "√": # 0x221a - - t: "pierwiastek kwadratowy z" + - T: "pierwiastek kwadratowy z" - "∝": # 0x221d - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "proporcjonalne do" + - T: "proporcjonalne do" - "∞": - test: if: "ancestor::*[self::m:limit or self::m:limit-sup or self::m:limit-inf or self::m:large-op] or parent::*[self::m:subscripted-norm] or parent::*[self::m:mrow]/parent::*[self::m:subscripted-norm]" then: [T: "nieskończoności"] else: [T: "nieskończoność"] # 0x221e - - "∟": [t: "kąt prosty"] # 0x221f - - "∠": [t: "kąt"] # 0x2220 - - "∡": [t: "kąt mierzony"] # 0x2221 + - "∟": [T: "kąt prosty"] # 0x221f + - "∠": [T: "kąt"] # 0x2220 + - "∡": [T: "kąt mierzony"] # 0x2221 - "∣": [T: "dzieli"] # 0x2223 - - "∤": [t: "nie dzieli"] # 0x2224 + - "∤": [T: "nie dzieli"] # 0x2224 - "∥": # 0x2225 - test: if: "ancestor-or-self::*[contains(@data-intent-property, ':literal:')]" - then: [t: "podwójna pionowa kreska"] + then: [T: "podwójna pionowa kreska"] else: - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "równoległe do" + - T: "równoległe do" - "∦": # 0x2226 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "nierównoległe do" + - T: "nierównoległe do" - "∧": [T: "i"] # 0x2227 - "∨": [T: "lub"] # 0x2228 - "∩": [T: "przecięcie"] # 0x2229 - "∪": [T: "suma zbiorów"] # 0x222a - "∫": [T: "całka"] # 0x222b - - "∬": [t: "całka podwójna"] # 0x222c - - "∭": [t: "całka potrójna"] # 0x222d - - "∮": [t: "całka krzywoliniowa"] # 0x222e + - "∬": [T: "całka podwójna"] # 0x222c + - "∭": [T: "całka potrójna"] # 0x222d + - "∮": [T: "całka krzywoliniowa"] # 0x222e - "∶": # 0x2236 - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "do" - - "∷": [t: "jako"] # 0x2237 - - "∼": [t: "tylda"] # 0x223c - - "∽": [t: "odwrócona tylda"] # 0x223d + - "∷": [T: "jako"] # 0x2237 + - "∼": [T: "tylda"] # 0x223c + - "∽": [T: "odwrócona tylda"] # 0x223d - "∾": # 0x223e - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "most dodatnie" - - "∿": [t: "fala sinusoidalna"] # 0x223f + - T: "most dodatnie" + - "∿": [T: "fala sinusoidalna"] # 0x223f - "≠": # 0x2260 - test: if: "$Verbosity!='Terse'" @@ -544,7 +544,7 @@ - test: if: "$Verbosity!='Terse'" then: [T: "jest"] - - t: "identyczne z" + - T: "identyczne z" - "≤": # 0x2264 - test: if: "$Verbosity!='Terse'" @@ -555,31 +555,31 @@ if: "$Verbosity!='Terse'" then: [T: "jest"] - T: "większe lub równe" - - "≦": [t: "mniejsze nad równe"] # 0x2266 - - "≧": [t: "większe nad równe"] # 0x2267 - - "≺": [t: "poprzedza"] # 0x227a - - "≻": [t: "następuje po"] # 0x227b + - "≦": [T: "mniejsze nad równe"] # 0x2266 + - "≧": [T: "większe nad równe"] # 0x2267 + - "≺": [T: "poprzedza"] # 0x227a + - "≻": [T: "następuje po"] # 0x227b - "⊂": # 0x2282 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "podzbiorem" + then: [T: "jest"] + - T: "podzbiorem" - "⊃": # 0x2283 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "nadzbiorem" + then: [T: "jest"] + - T: "nadzbiorem" - "⊄": # 0x2284 - - t: "nie jest podzbiorem" + - T: "nie jest podzbiorem" - "⊅": # 0x2285 - - t: "nie jest nadzbiorem" + - T: "nie jest nadzbiorem" - "⊆": # 0x2286 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "podzbiorem lub równym" + then: [T: "jest"] + - T: "podzbiorem lub równym" - "⊇": # 0x2287 - test: if: "$Verbosity!='Terse'" - then: [t: "jest"] - - t: "nadzbiorem lub równym" + then: [T: "jest"] + - T: "nadzbiorem lub równym" diff --git a/tests/Languages/pl.rs b/tests/Languages/pl.rs index 44016ff5b..c9423ea9f 100644 --- a/tests/Languages/pl.rs +++ b/tests/Languages/pl.rs @@ -2,6 +2,8 @@ // Existing hand-written Polish tests (norms, degrees, relations, etc.) mod pl; +mod number_sets; +mod unit_plurals; // Tests mirrored from the English suite, with expected speech localized to Polish. mod ClearSpeak { diff --git a/tests/Languages/pl/ClearSpeak/mfrac.rs b/tests/Languages/pl/ClearSpeak/mfrac.rs index f7197bcb2..a53bba559 100644 --- a/tests/Languages/pl/ClearSpeak/mfrac.rs +++ b/tests/Languages/pl/ClearSpeak/mfrac.rs @@ -86,7 +86,7 @@ fn frac_with_units() -> Result<()> { "; - test("pl", "ClearSpeak", expr, "62 milas na godzina")?; + test("pl", "ClearSpeak", expr, "62 mile na godzina")?; return Ok(()); } diff --git a/tests/Languages/pl/SimpleSpeak/mfrac.rs b/tests/Languages/pl/SimpleSpeak/mfrac.rs index 2e84dc987..a07f0592b 100644 --- a/tests/Languages/pl/SimpleSpeak/mfrac.rs +++ b/tests/Languages/pl/SimpleSpeak/mfrac.rs @@ -164,7 +164,7 @@ fn frac_with_units() -> Result<()> { "; - test("pl", "SimpleSpeak", expr, "62 milas na godzina")?; + test("pl", "SimpleSpeak", expr, "62 mile na godzina")?; return Ok(()); } @@ -198,7 +198,7 @@ fn number_in_numerator_with_units() -> Result<()> { mi "; - test("pl", "SimpleSpeak", expr, "3 galons na mila")?; + test("pl", "SimpleSpeak", expr, "3 galony na mila")?; return Ok(()); } @@ -212,7 +212,7 @@ fn units_with_powers() -> Result<()> { s2 "; - test("pl", "SimpleSpeak", expr, "3 metrs na sekunda do kwadratu")?; + test("pl", "SimpleSpeak", expr, "3 metry na sekunda do kwadratu")?; return Ok(()); } diff --git a/tests/Languages/pl/number_sets.rs b/tests/Languages/pl/number_sets.rs new file mode 100644 index 000000000..6d672447b --- /dev/null +++ b/tests/Languages/pl/number_sets.rs @@ -0,0 +1,69 @@ +/// Number sets: ℂ ℕ ℚ ℝ ℤ, on their own and with a dimension (ℝ³). +/// +/// These rules had no Polish test at all, which is how the earlier defects in +/// this file were able to sit unnoticed: a rule with no test in a given +/// language is not "known good", it is "never looked at". +use crate::common::*; +use anyhow::Result; + +/// A bare number set is spoken as a full Polish phrase. +#[test] +fn simple_number_sets() -> Result<()> { + let expr = r#" + ℂ, + ℕ, + ℚ, + ℝ, + ℤ + "#; + test("pl", "SimpleSpeak", expr, "liczby zespolone przecinek, liczby naturalne przecinek, liczby wymierne przecinek, liczby rzeczywiste, przecinek, liczby całkowite")?; + Ok(()) +} + +/// With a dimension the letter itself is spoken, as in every language except +/// Hungarian: "R 3", not "liczby rzeczywiste 3". +#[test] +fn dimension_number_sets() -> Result<()> { + let expr = r#" + ℝ3, + ℂ2, + ℕ4 + "#; + test("pl", "SimpleSpeak", expr, "R 3 przecinek, C 2 przecinek, N 4")?; + Ok(()) +} + +/// A non-numeric exponent is not a dimension, so the full phrase comes back. +/// This is the negative control for the rule above: it fires on `count(*)=2` +/// with a digit, and must not swallow every superscript. +#[test] +fn number_set_with_variable_exponent() -> Result<()> { + let expr = r#" + ℤn + "#; + test("pl", "SimpleSpeak", expr, "liczby całkowite do potęgi n")?; + Ok(()) +} + +/// Positive and negative variants (ℝ⁺, ℤ⁻) are a separate rule again. +#[test] +fn pos_neg_number_sets() -> Result<()> { + let expr = r#" + ℝ+, + ℤ- + "#; + test("pl", "SimpleSpeak", expr, "plus liczby rzeczywiste, przecinek; minus liczby całkowite")?; + Ok(()) +} + +/// ClearSpeak must agree with SimpleSpeak here - the rules live in +/// SharedRules, so a divergence would mean one of them stopped matching. +#[test] +fn number_sets_clearspeak_matches() -> Result<()> { + let expr = r#" + ℝ, + ℝ3 + "#; + test("pl", "ClearSpeak", expr, "liczby rzeczywiste, przecinek, R 3")?; + Ok(()) +} diff --git a/tests/Languages/pl/unit_plurals.rs b/tests/Languages/pl/unit_plurals.rs new file mode 100644 index 000000000..a3a6ec5b8 --- /dev/null +++ b/tests/Languages/pl/unit_plurals.rs @@ -0,0 +1,86 @@ +/// Polish unit plurals: the noun form follows the numeral, not just "is it one". +/// 1 metr | 2, 3, 4 metry (nominative plural) | 5+ metrów (genitive plural) +/// The teens are the exception that breaks the naive rule: 12, 13, 14 metrów. +use crate::common::*; +use anyhow::Result; + +/// The three numeral classes on a single unit, including the teens exception. +#[test] +fn unit_plural_numeral_classes() -> Result<()> { + let expr = r#" + 1m,2m, + 3m,4m, + 5m,11m, + 12m,13m, + 14m,22m, + 101m,102m, + 112m + "#; + test("pl", "SimpleSpeak", expr, "1 metr, przecinek; 2 metry, przecinek; 3 metry, przecinek; 4 metry, przecinek; 5 metrów, przecinek; 11 metrów, przecinek; 12 metrów, przecinek; 13 metrów, przecinek; 14 metrów, przecinek; 22 metry, przecinek; 101 metrów, przecinek; 102 metry, przecinek; 112 metrów")?; + Ok(()) +} + +/// SI base units: previously all of these took the English "s". +#[test] +fn unit_plural_si_base() -> Result<()> { + let expr = r#" + 2g,5g, + 2s,5s, + 2A,5A, + 2K,5K, + 2mol,5mol, + 2cd,5cd + "#; + test("pl", "SimpleSpeak", expr, "2 gramy, przecinek; 5 gramów, przecinek; 2 sekundy, przecinek; 5 sekund, przecinek; 2 ampery, przecinek; 5 amperów, przecinek; 2 kelwiny, przecinek; 5 kelwinów, przecinek; 2 mole, przecinek; 5 moli, przecinek; 2 kandele, przecinek; 5 kandeli")?; + Ok(()) +} + +/// With an SI prefix the unit goes through a different branch of the rule. +#[test] +fn unit_plural_with_prefix() -> Result<()> { + let expr = r#" + 2km,5km, + 2mg,5mg, + 2daA,5daA + "#; + test("pl", "SimpleSpeak", expr, "2 kilo-metry, przecinek; 5 kilo-metrów, przecinek; 2 mili-gramy, przecinek; 5 mili-gramów, przecinek; 2 deka-ampery, przecinek; 5 deka-amperów")?; + Ok(()) +} + +/// Irregular nouns: the plural cannot be derived from the ending. +#[test] +fn unit_plural_irregular() -> Result<()> { + let expr = r#" + 2d,5d, + 2w,5w, + 2yr,5yr, + 2ft,5ft + "#; + test("pl", "SimpleSpeak", expr, "2 dni, przecinek, 5 dni, przecinek; 2 tygodnie, przecinek; 5 tygodni, przecinek; 2 lata, przecinek, 5 lat, przecinek; 2 stopy, przecinek; 5 stóp")?; + Ok(()) +} + +/// Units whose base form was itself wrong (plural used as singular). +#[test] +fn unit_singular_forms_fixed() -> Result<()> { + let expr = r#" + 1Hz,2Hz, + 5Hz, + 1hp,2hp, + 1℧ + "#; + test("pl", "SimpleSpeak", expr, "1 herc, przecinek; 2 herce, przecinek; 5 herców, przecinek; 1 koń mechaniczny, przecinek; 2 konie mechaniczne, przecinek, 1 mho")?; + Ok(()) +} + +/// Multi-word units inflect the head noun and keep the dependent word's case. +#[test] +fn unit_plural_multiword() -> Result<()> { + let expr = r#" + 2ly,5ly, + 2au,5au, + 2arcmin,5arcmin + "#; + test("pl", "SimpleSpeak", expr, "2 lata świetlne, przecinek; 5 lat świetlnych, przecinek; 2 jednostki astronomiczne, przecinek; 5 jednostek astronomicznych; przecinek; 2 minuty łuku, przecinek; 5 minut łuku")?; + Ok(()) +} diff --git a/tests/Languages/pl/units.rs b/tests/Languages/pl/units.rs index 1676cf8ae..591e2eaff 100644 --- a/tests/Languages/pl/units.rs +++ b/tests/Languages/pl/units.rs @@ -40,7 +40,7 @@ fn prefix_sweep() -> Result<()> { qg "#; test("pl", "SimpleSpeak", expr, - "kwetta-grams, przecinek; ronna-grams, przecinek; jotta-grams, przecinek; zetta-grams, przecinek; eksa-grams, przecinek; peta-grams, przecinek; tera-grams, przecinek; giga-grams, przecinek; mega-grams, przecinek; kilo-grams, przecinek; hekto-grams, przecinek; deka-grams, przecinek; decy-grams, przecinek; centy-grams, przecinek; mili-grams, przecinek; mikro-grams, przecinek; nano-grams, przecinek; piko-grams, przecinek; femto-grams, przecinek; atto-grams, przecinek; zepto-grams, przecinek; jokto-grams, przecinek; ronto-grams, przecinek; kwekto-grams")?; + "kwetta-gramów, przecinek; ronna-gramów, przecinek; jotta-gramów, przecinek; zetta-gramów, przecinek; eksa-gramów, przecinek; peta-gramów, przecinek; tera-gramów, przecinek; giga-gramów, przecinek; mega-gramów, przecinek; kilo-gramów, przecinek; hekto-gramów, przecinek; deka-gramów, przecinek; decy-gramów, przecinek; centy-gramów, przecinek; mili-gramów, przecinek; mikro-gramów, przecinek; nano-gramów, przecinek; piko-gramów, przecinek; femto-gramów, przecinek; atto-gramów, przecinek; zepto-gramów, przecinek; jokto-gramów, przecinek; ronto-gramów, przecinek; kwekto-gramów")?; return Ok(()); } @@ -61,7 +61,7 @@ fn si_base() -> Result<()> { 1sec,2sec "#; test("pl", "SimpleSpeak", expr, - "1 amper, przecinek; 2 ampers, przecinek; 1 kandela, przecinek; 2 kandelas, przecinek; 1 kelwin, przecinek; 2 kelwins, przecinek; 1 kelwin, przecinek; 2 kelwins, przecinek; 1 gram, przecinek; 2 grams, przecinek; 1 metr, przecinek; 2 metrs, przecinek, 1 mol, przecinek; 2 mols, przecinek; 1 sekunda, przecinek; 2 sekundas, przecinek; 1 sekunda, przecinek; 2 sekundas, przecinek; 1 sekunda, przecinek; 2 sekundas, przecinek; 1 sekunda, przecinek; 2 sekundas")?; + "1 amper, przecinek; 2 ampery, przecinek; 1 kandela, przecinek; 2 kandele, przecinek; 1 kelwin, przecinek; 2 kelwiny, przecinek; 1 kelwin, przecinek; 2 kelwiny, przecinek; 1 gram, przecinek; 2 gramy, przecinek; 1 metr, przecinek; 2 metry, przecinek, 1 mol, przecinek; 2 mole, przecinek; 1 sekunda, przecinek; 2 sekundy, przecinek; 1 sekunda, przecinek; 2 sekundy, przecinek; 1 sekunda, przecinek; 2 sekundy, przecinek; 1 sekunda, przecinek; 2 sekundy")?; return Ok(()); } @@ -80,7 +80,7 @@ fn si_base_with_prefixes() -> Result<()> { 1nsec,2psec "#; test("pl", "SimpleSpeak", expr, - "1 kwetta-amper, przecinek; 2 ronna-ampers, przecinek; 1 jotta-kandela, przecinek; 2 zetta-kandelas; przecinek; 1 eksa-kelwin, przecinek; 2 peta-kelwins, przecinek; 1 tera-kelwin, przecinek; 2 giga-kelwins, przecinek; 1 mega-gram, przecinek; 2 kilo-grams, przecinek; 1 hekto-metr, przecinek; 2 deka-metrs, przecinek; 1 decy-mol, przecinek; 2 centy-mols, przecinek; 1 mili-sekunda, przecinek; 2 mikro-sekundas; przecinek; 1 nano-sekunda, przecinek; 2 piko-sekundas")?; + "1 kwetta-amper, przecinek; 2 ronna-ampery, przecinek; 1 jotta-kandela, przecinek; 2 zetta-kandele, przecinek; 1 eksa-kelwin, przecinek; 2 peta-kelwiny, przecinek; 1 tera-kelwin, przecinek; 2 giga-kelwiny, przecinek; 1 mega-gram, przecinek; 2 kilo-gramy, przecinek; 1 hekto-metr, przecinek; 2 deka-metry, przecinek; 1 decy-mol, przecinek; 2 centy-mole, przecinek; 1 mili-sekunda, przecinek; 2 mikro-sekundy, przecinek; 1 nano-sekunda, przecinek; 2 piko-sekundy")?; return Ok(()); } @@ -103,7 +103,7 @@ fn si_derived_1() -> Result<()> { 1lx,2lx "#; test("pl", "SimpleSpeak", expr, - "1 bekerel, przecinek; 2 bekerels, przecinek; 1 kulomb, przecinek; 2 kulombs, przecinek; 1 stopień Celsjusza, przecinek; 2 stopnie Celsjusza, przecinek; 1 stopień Celsjusza, przecinek; 2 stopnie Celsjusza, przecinek; 1 farad, przecinek; 2 farads, przecinek; 1 grej, przecinek; 2 grejs, przecinek; 1 henr, przecinek; 2 henry, przecinek; 1 herce, przecinek; 2 herces, przecinek; 1 dżul, przecinek; 2 dżuls, przecinek; 1 katal, przecinek; 2 katals, przecinek; 1 lumen, przecinek; 2 lumens, przecinek; 1 luks, przecinek; 2 luksy")?; + "1 bekerel, przecinek; 2 bekerele, przecinek; 1 kulomb, przecinek; 2 kulomby, przecinek; 1 stopień Celsjusza, przecinek; 2 stopnie Celsjusza, przecinek; 1 stopień Celsjusza, przecinek; 2 stopnie Celsjusza, przecinek; 1 farad, przecinek; 2 farady, przecinek; 1 grej, przecinek; 2 greje, przecinek; 1 henr, przecinek; 2 henry, przecinek; 1 herc, przecinek; 2 herce, przecinek; 1 dżul, przecinek; 2 dżule, przecinek; 1 katal, przecinek; 2 katale, przecinek; 1 lumen, przecinek; 2 lumeny, przecinek; 1 luks, przecinek; 2 luksy")?; return Ok(()); } @@ -125,7 +125,7 @@ fn si_derived_1_with_prefixes() -> Result<()> { 1p℃,2n℃ "#; test("pl", "SimpleSpeak", expr, - "1 kwetta-bekerel, przecinek; 2 ronna-bekerels; przecinek; 1 jotta-kulomb, przecinek; 2 zetta-kulombs; przecinek; 1 eksa-farad, przecinek; 2 peta-farads, przecinek; 1 tera-grej, przecinek; 2 giga-grejs, przecinek; 1 mega-henr, przecinek; 2 kilo-henry, przecinek; 1 deka-herce, przecinek; 2 decy-herces, przecinek; 1 centy-dżul, przecinek; 2 mili-dżuls, przecinek; 1 mikro-katal, przecinek; 2 nano-katals, przecinek; 1 piko-lumen, przecinek; 2 femto-lumens, przecinek; 1 atto-luks, przecinek; 2 zepto-luksy, przecinek; 1 mili-stopień Celsjusza; przecinek; 2 mikro-stopnie Celsjusza; przecinek; 1 piko-stopień Celsjusza; przecinek; 2 nano-stopnie Celsjusza")?; + "1 kwetta-bekerel, przecinek; 2 ronna-bekerele, przecinek; 1 jotta-kulomb, przecinek; 2 zetta-kulomby, przecinek; 1 eksa-farad, przecinek; 2 peta-farady, przecinek; 1 tera-grej, przecinek; 2 giga-greje, przecinek; 1 mega-henr, przecinek; 2 kilo-henry, przecinek; 1 deka-herc, przecinek; 2 decy-herce, przecinek; 1 centy-dżul, przecinek; 2 mili-dżule, przecinek; 1 mikro-katal, przecinek; 2 nano-katale, przecinek; 1 piko-lumen, przecinek; 2 femto-lumeny, przecinek; 1 atto-luks, przecinek; 2 zepto-luksy, przecinek; 1 mili-stopień Celsjusza; przecinek; 2 mikro-stopnie Celsjusza; przecinek; 1 piko-stopień Celsjusza; przecinek; 2 nano-stopnie Celsjusza")?; return Ok(()); } @@ -145,7 +145,7 @@ fn si_derived_2() -> Result<()> { 1Wb,2Wb "#; test("pl", "SimpleSpeak", expr, - "1 niuton, przecinek; 2 niutons, przecinek, 1 om przecinek; 2 oms, przecinek, 1 om przecinek; 2 oms, przecinek; 1 paskal, przecinek; 2 paskals, przecinek; 1 siemens, przecinek; 2 siemens, przecinek; 1 siwert, przecinek; 2 siwerts, przecinek; 1 tesla, przecinek; 2 teslas, przecinek; 1 wolt, przecinek; 2 wolty, przecinek, 1 wat, przecinek; 2 waty, przecinek; 1 weber, przecinek; 2 webers")?; + "1 niuton, przecinek; 2 niutony, przecinek, 1 om przecinek, 2 omy, przecinek, 1 om przecinek, 2 omy, przecinek; 1 paskal, przecinek; 2 paskale, przecinek; 1 siemens, przecinek; 2 siemensy, przecinek; 1 siwert, przecinek; 2 siwerty, przecinek; 1 tesla, przecinek; 2 tesle, przecinek; 1 wolt, przecinek; 2 wolty, przecinek, 1 wat, przecinek; 2 waty, przecinek; 1 weber, przecinek; 2 webery")?; return Ok(()); } @@ -165,7 +165,7 @@ fn si_derived_2_with_prefixes() -> Result<()> { 1PWb,2EWb "#; test("pl", "SimpleSpeak", expr, - "1 kwekto-niuton, przecinek; 2 ronto-niutons; przecinek; 1 jokto-om, przecinek; 2 zepto-oms, przecinek; 1 atto-om, przecinek; 2 femto-oms, przecinek; 1 piko-paskal, przecinek; 2 nano-paskals, przecinek; 1 mikro-siemens, przecinek; 2 mili-siemens, przecinek; 1 centy-siwert, przecinek; 2 decy-siwerts, przecinek; 1 deka-tesla, przecinek; 2 hekto-teslas, przecinek; 1 kilo-wolt, przecinek; 2 mega-wolty, przecinek; 1 giga-wat, przecinek; 2 tera-waty, przecinek; 1 peta-weber, przecinek; 2 eksa-webers")?; + "1 kwekto-niuton, przecinek; 2 ronto-niutony, przecinek; 1 jokto-om, przecinek; 2 zepto-omy, przecinek; 1 atto-om, przecinek; 2 femto-omy, przecinek; 1 piko-paskal, przecinek; 2 nano-paskale, przecinek; 1 mikro-siemens, przecinek; 2 mili-siemensy, przecinek; 1 centy-siwert, przecinek; 2 decy-siwerty, przecinek; 1 deka-tesla, przecinek; 2 hekto-tesle, przecinek; 1 kilo-wolt, przecinek; 2 mega-wolty, przecinek; 1 giga-wat, przecinek; 2 tera-waty, przecinek; 1 peta-weber, przecinek; 2 eksa-webery")?; return Ok(()); } @@ -191,7 +191,7 @@ fn si_accepted() -> Result<()> { 1Bd,2Bd "#; test("pl", "SimpleSpeak", expr, - "1 litr, przecinek; 2 litrs, przecinek; 1 litr, przecinek; 2 litrs, przecinek; 1 litr, przecinek; 2 litrs, przecinek; 1 tona, przecinek; 2 tonas, przecinek; 1 dalton, przecinek; 2 daltons, przecinek; 1 neper, przecinek; 2 nepers, przecinek; 1 jednostka masy atomowej, przecinek; 2 jednostka masy atomowejs; przecinek; 1 elektronowolt, przecinek; 2 elektronowolts, przecinek; 1 radian, przecinek; 2 radians, przecinek; 1 steradian, przecinek; 2 steradians, przecinek, 1 rok, przecinek; 2 roks, przecinek; 1 sekunda łuku, przecinek; 2 sekunda łukus, przecinek, 1 bit, przecinek; 2 bits, przecinek; 1 bajt, przecinek; 2 bajts, przecinek, 1 bod, przecinek; 2 bods")?; + "1 litr, przecinek; 2 litry, przecinek; 1 litr, przecinek; 2 litry, przecinek; 1 litr, przecinek; 2 litry, przecinek; 1 tona, przecinek; 2 tony, przecinek; 1 dalton, przecinek; 2 daltony, przecinek; 1 neper, przecinek; 2 nepery, przecinek; 1 jednostka masy atomowej, przecinek; 2 jednostki masy atomowej, przecinek; 1 elektronowolt, przecinek; 2 elektronowolty, przecinek; 1 radian, przecinek; 2 radiany, przecinek; 1 steradian, przecinek; 2 steradiany, przecinek, 1 rok, przecinek; 2 lata, przecinek; 1 sekunda łuku, przecinek; 2 sekundy łuku, przecinek, 1 bit, przecinek; 2 bity, przecinek; 1 bajt, przecinek; 2 bajty, przecinek, 1 bod, przecinek; 2 body")?; return Ok(()); } @@ -216,7 +216,7 @@ fn si_accepted_with_prefixes() -> Result<()> { 1TBd,2EBd "#; test("pl", "SimpleSpeak", expr, - "1 kwetta-litr, przecinek; 2 ronna-litrs, przecinek; 1 jotta-litr, przecinek; 2 zetta-litrs, przecinek; 1 eksa-litr, przecinek; 2 peta-litrs, przecinek; 1 tera-tona, przecinek; 2 giga-tonas, przecinek; 1 mega-dalton, przecinek; 2 kilo-daltons, przecinek; 1 decy-neper, przecinek; 2 centy-nepers, przecinek; 1, hekto-jednostka masy atomowej; przecinek; 2, deka-jednostka masy atomowejs; przecinek; 1 mili-elektronowolt; przecinek; 2 mikro-elektronowolts; przecinek; 1 nano-radian, przecinek; 2 piko-radians, przecinek; 1 femto-steradian, przecinek; 2 atto-steradians; przecinek; 1 giga-rok, przecinek; 2 mega-roks, przecinek; 1 zepto-sekunda łuku; przecinek; 2 jokto-sekunda łukus; przecinek; 1 kilo-bit, przecinek; 2 mega-bits, przecinek; 1 giga-bajt, przecinek; 2 tera-bajts, przecinek; 1 tera-bod, przecinek; 2 eksa-bods")?; + "1 kwetta-litr, przecinek; 2 ronna-litry, przecinek; 1 jotta-litr, przecinek; 2 zetta-litry, przecinek; 1 eksa-litr, przecinek; 2 peta-litry, przecinek; 1 tera-tona, przecinek; 2 giga-tony, przecinek; 1 mega-dalton, przecinek; 2 kilo-daltony, przecinek; 1 decy-neper, przecinek; 2 centy-nepery, przecinek; 1, hekto-jednostka masy atomowej; przecinek; 2, deka-jednostki masy atomowej; przecinek; 1 mili-elektronowolt; przecinek; 2 mikro-elektronowolty; przecinek; 1 nano-radian, przecinek; 2 piko-radiany, przecinek; 1 femto-steradian, przecinek; 2 atto-steradiany, przecinek; 1 giga-rok, przecinek; 2 mega-lata, przecinek; 1 zepto-sekunda łuku; przecinek; 2 jokto-sekundy łuku; przecinek; 1 kilo-bit, przecinek; 2 mega-bity, przecinek; 1 giga-bajt, przecinek; 2 tera-bajty, przecinek; 1 tera-bod, przecinek; 2 eksa-body")?; return Ok(()); } @@ -240,7 +240,7 @@ fn without_prefix_time() -> Result<()> { 1yr,2yr "#; test("pl", "SimpleSpeak", expr, - "1 sekunda, przecinek; 2 sekundas, przecinek; 1 sekunda, przecinek; 2 sekundas, przecinek; 1 minuta, przecinek; 2 minutas, przecinek; 1 minuta, przecinek; 2 minutas, przecinek; 1 minuta, przecinek; 2 minutas, przecinek; 1 godzina, przecinek; 2 godzinas, przecinek; 1 godzina, przecinek; 2 godzinas, przecinek; 1 godzina, przecinek; 2 godzinas, przecinek; 1 dzień, przecinek; 2 dzieńs, przecinek; 1 dzień, przecinek; 2 dzieńs, przecinek; 1 tydzień, przecinek; 2 tydzieńs, przecinek; 1 tydzień, przecinek; 2 tydzieńs, przecinek, 1 rok, przecinek; 2 roks, przecinek, 1 rok, przecinek; 2 roks")?; + "1 sekunda, przecinek; 2 sekundy, przecinek; 1 sekunda, przecinek; 2 sekundy, przecinek; 1 minuta, przecinek; 2 minuty, przecinek; 1 minuta, przecinek; 2 minuty, przecinek; 1 minuta, przecinek; 2 minuty, przecinek; 1 godzina, przecinek; 2 godziny, przecinek; 1 godzina, przecinek; 2 godziny, przecinek; 1 godzina, przecinek; 2 godziny, przecinek; 1 dzień, przecinek, 2 dni, przecinek; 1 dzień, przecinek, 2 dni, przecinek; 1 tydzień, przecinek; 2 tygodnie, przecinek; 1 tydzień, przecinek; 2 tygodnie, przecinek, 1 rok, przecinek; 2 lata, przecinek, 1 rok, przecinek; 2 lata")?; return Ok(()); } @@ -258,7 +258,7 @@ fn without_prefix_angles() -> Result<()> { 1asec,2asec "#; test("pl", "SimpleSpeak", expr, - "1 stopień, przecinek; 2 stopnie, przecinek; 1 stopień, przecinek; 2 stopnie, przecinek; 1 minuta łuku, przecinek; 2 minuta łukus, przecinek; 1 minuta łuku, przecinek; 2 minuta łukus, przecinek; 1 minuta łuku, przecinek; 2 minuta łukus, przecinek; 1 minuta łuku, przecinek; 2 minuta łukus, przecinek; 1 sekunda łuku, przecinek; 2 sekunda łukus, przecinek; 1 sekunda łuku, przecinek; 2 sekunda łukus")?; + "1 stopień, przecinek; 2 stopnie, przecinek; 1 stopień, przecinek; 2 stopnie, przecinek; 1 minuta łuku, przecinek; 2 minuty łuku, przecinek; 1 minuta łuku, przecinek; 2 minuty łuku, przecinek; 1 minuta łuku, przecinek; 2 minuty łuku, przecinek; 1 minuta łuku, przecinek; 2 minuty łuku, przecinek; 1 sekunda łuku, przecinek; 2 sekundy łuku, przecinek; 1 sekunda łuku, przecinek; 2 sekundy łuku")?; return Ok(()); } @@ -274,7 +274,7 @@ fn without_prefix_distance() -> Result<()> { 1fm,2fm "#; test("pl", "SimpleSpeak", expr, - "1 jednostka astronomiczna, przecinek; 2 jednostka astronomicznas; przecinek; 1 rok świetlny, przecinek; 2 rok świetlnys, przecinek; 1 parsek, przecinek; 2 parseks, przecinek; 1 angstrem, przecinek; 2 angstrems, przecinek; 1 angstrem, przecinek; 2 angstrems, przecinek; 1 fermi, przecinek; 2 fermis")?; + "1 jednostka astronomiczna, przecinek; 2 jednostki astronomiczne, przecinek; 1 rok świetlny, przecinek; 2 lata świetlne, przecinek; 1 parsek, przecinek; 2 parseki, przecinek; 1 angstrem, przecinek; 2 angstremy, przecinek; 1 angstrem, przecinek; 2 angstremy, przecinek; 1 fermi, przecinek; 2 fermi")?; return Ok(()); } @@ -299,7 +299,7 @@ fn without_prefix_other() -> Result<()> { 1erg,2erg "#; test("pl", "SimpleSpeak", expr, - "1 hektar, przecinek; 2 hektars, przecinek; 1 decybel, przecinek; 2 decybels, przecinek; 1 atmosfera, przecinek; 2 atmosferas, przecinek; 1 jednostka masy atomowej, przecinek; 2 jednostka masy atomowejs; przecinek, 1 bar, przecinek; 2 bars, przecinek; 1 kaloria, przecinek; 2 kalorias, przecinek; 1 kiur, przecinek; 2 kiurs, przecinek; 1 grad, przecinek; 2 grads, przecinek; 1 molowy, przecinek; 2 molowys, przecinek; 1 rentgen, przecinek; 2 rentgens, przecinek; 1 obrót na minutę, przecinek; 2 obroty na minutę, przecinek; 1 drachma płynu, przecinek; 2 drachma płynus, przecinek; 1 M h o, przecinek; 2 M h os, przecinek; 1 dyna, przecinek; 2 dynas, przecinek, 1 erg, przecinek; 2 ergs")?; + "1 hektar, przecinek; 2 hektary, przecinek; 1 decybel, przecinek; 2 decybele, przecinek; 1 atmosfera, przecinek; 2 atmosfery, przecinek; 1 jednostka masy atomowej, przecinek; 2 jednostki masy atomowej, przecinek, 1 bar, przecinek; 2 bary, przecinek; 1 kaloria, przecinek; 2 kalorie, przecinek; 1 kiur, przecinek; 2 kiury, przecinek; 1 grad, przecinek; 2 grady, przecinek; 1 molowy, przecinek; 2 molowe, przecinek; 1 rentgen, przecinek; 2 rentgeny, przecinek; 1 obrót na minutę, przecinek; 2 obroty na minutę, przecinek; 1 drachma płynu, przecinek; 2 drachmy płynu, przecinek, 1 mho, przecinek, 2 mho, przecinek; 1 dyna, przecinek; 2 dyny, przecinek, 1 erg, przecinek; 2 ergi")?; return Ok(()); } @@ -325,7 +325,7 @@ fn without_prefix_powers_of_2() -> Result<()> { 1YiB,2YiB "#; test("pl", "SimpleSpeak", expr, - "1 kibibit, przecinek; 2 kibibits, przecinek; 1 mebibit, przecinek; 2 mebibits, przecinek; 1 gibibit, przecinek; 2 gibibits, przecinek; 1 tebibit, przecinek; 2 tebibits, przecinek; 1 pebibit, przecinek; 2 pebibits, przecinek; 1 eksbibit, przecinek; 2 eksbibits, przecinek; 1 zebibit, przecinek; 2 zebibits, przecinek; 1 jobibit, przecinek; 2 jobibits, przecinek; 1 kibibajt, przecinek; 2 kibibajts, przecinek; 1 mebibajt, przecinek; 2 mebibajts, przecinek; 1 gibibajt, przecinek; 2 gibibajts, przecinek; 1 tebibajt, przecinek; 2 tebibajts, przecinek; 1 pebibajt, przecinek; 2 pebibajts, przecinek; 1 eksbibajt, przecinek; 2 eksbibajts, przecinek; 1 zebibajt, przecinek; 2 zebibajts, przecinek; 1 jobibajt, przecinek; 2 jobibajts")?; + "1 kibibit, przecinek; 2 kibibity, przecinek; 1 mebibit, przecinek; 2 mebibity, przecinek; 1 gibibit, przecinek; 2 gibibity, przecinek; 1 tebibit, przecinek; 2 tebibity, przecinek; 1 pebibit, przecinek; 2 pebibity, przecinek; 1 eksbibit, przecinek; 2 eksbibity, przecinek; 1 zebibit, przecinek; 2 zebibity, przecinek; 1 jobibit, przecinek; 2 jobibity, przecinek; 1 kibibajt, przecinek; 2 kibibajty, przecinek; 1 mebibajt, przecinek; 2 mebibajty, przecinek; 1 gibibajt, przecinek; 2 gibibajty, przecinek; 1 tebibajt, przecinek; 2 tebibajty, przecinek; 1 pebibajt, przecinek; 2 pebibajty, przecinek; 1 eksbibajt, przecinek; 2 eksbibajty, przecinek; 1 zebibajt, przecinek; 2 zebibajty, przecinek; 1 jobibajt, przecinek; 2 jobibajty")?; return Ok(()); } @@ -342,11 +342,11 @@ fn si_other_numbers() -> Result<()> { 2.5µsec, 32.34mol"#; test_prefs("pl", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, - "10 l przecinek, 20 m przecinek; x mili-sekundas; przecinek; y mikro-sekundas; przecinek; deka-grams, przecinek; 1235 deka-niutons; przecinek; 25 mikro-sekundas; przecinek; 3234 mols")?; + "10 l przecinek, 20 m przecinek; x mili-sekund, przecinek; y mikro-sekund, przecinek; deka-gramów, przecinek; 1235 deka-niutonów; przecinek; 25 mikro-sekundy, przecinek; 3234 mole")?; test_prefs("pl", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "10 litr, przecinek; 20 metrs, przecinek; x mili-sekundas; przecinek; y mikro-sekundas; przecinek; deka-grams, przecinek; 1235 deka-niutons; przecinek; 25 mikro-sekundas; przecinek; 3234 mols")?; + "10 litr, przecinek; 20 metry, przecinek; x mili-sekund, przecinek; y mikro-sekund, przecinek; deka-gramów, przecinek; 1235 deka-niutonów; przecinek; 25 mikro-sekundy, przecinek; 3234 mole")?; test_prefs("pl", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, - "10 litr, przecinek; 20 metrs, przecinek; x mili-sekundas; przecinek; y mikro-sekundas; przecinek; deka-grams, przecinek; 1235 deka-niutons; przecinek; 25 mikro-sekundas; przecinek; 3234 mols")?; + "10 litr, przecinek; 20 metry, przecinek; x mili-sekund, przecinek; y mikro-sekund, przecinek; deka-gramów, przecinek; 1235 deka-niutonów; przecinek; 25 mikro-sekundy, przecinek; 3234 mole")?; return Ok(()); } @@ -361,7 +361,7 @@ fn test_mtext_inference() -> Result<()> { 4.5mT ]"#; test("pl", "SimpleSpeak", expr, - "nawias kwadratowy otwierający; 1 tona, przecinek; 2 peta-ampers, przecinek; 3 paskals, przecinek; 45 mili-teslas; nawias kwadratowy zamykający")?; + "nawias kwadratowy otwierający; 1 tona, przecinek; 2 peta-ampery, przecinek; 3 paskale, przecinek; 45 mili-tesli; nawias kwadratowy zamykający")?; return Ok(()); } @@ -376,7 +376,7 @@ fn test_mtext_inference() -> Result<()> { mmin "#; test("pl", "SimpleSpeak", expr, - "3 metrs, przecinek; 1 kilo-metr, przecinek; 3 metrs, przecinek; 3 dziesiąte farads, przecinek; m indeks dolny minimum koniec indeksu dolnego")?; + "3 metry, przecinek; 1 kilo-metr, przecinek; 3 metry, przecinek; 3 dziesiąte faradów, przecinek; m indeks dolny minimum koniec indeksu dolnego")?; return Ok(()); } From 9f4721a517eb986c318f1f113531d9cc648e0882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Thu, 3 Sep 2026 13:15:05 +0200 Subject: [PATCH 07/23] pl: speak the unit after "na" in the accusative, not the nominative (#745) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * pl: mark the unicode translations as verified (t -> T) Mechanical change: 2435 text keys raised from t/ot/ct to T/OT/CT in the two unicode files. No text is touched. The Polish rules were written before the lowercase/uppercase convention was in use, so entries that have been translated all along still carried the "needs review" key. The audit tool therefore reported them as untranslated, which made the real gaps impossible to see: audit-translations pl, untranslated text: 3162 -> 727 The remaining 727 are in the rule files, where the entries need reading rather than a mechanical pass, so they are deliberately left alone. Every raised entry was checked to differ from the English source, i.e. it really is translated. Entries whose text legitimately equals English (Roman numerals, ligatures, proper names, whitespace) were handled separately in the previous PR; entries still holding English text are NOT raised, since that would assert a translation that does not exist. Verification: cargo test --test languages Languages::pl 609 passed, 0 failed diff: 2436 insertions, 2436 deletions, zero changes outside key case The last point is checked by normalising the key case in the diff and confirming no unpaired lines remain (without normalising, 4710 remain, so the check does discriminate). * pl: also mark the multi-line unicode entries as verified The previous commit raised the key on entries written on a single line (`- "±": [t: "..."]`), but not on entries whose body is a block: - "°": - test: if: "parent::*[name(.)='msup' ...]" then: [t: "stopni"] else: [t: "stopień"] Those are exactly the entries carrying inflection or a TTS condition, so 312 of the most deliberate translations in the file were left looking unreviewed. This raises them: 64 in unicode.yaml, 247 in unicode-full.yaml and one single-line entry (U+23E6) missed earlier. One entry is deliberately left with a lower-case key: `t: ""` for U+00A0, the else-branch of the `@data-empty-in-2D` test. That is silence rather than text, and an upper-case key means "a translator checked this wording" - there is no wording to check. English keeps a lower-case key there too. No content changes; only key case. `cargo test --test languages Languages::pl` gives 609 passed, 0 failed, which is the same result as before this commit, as expected for a change the engine treats as equivalent (src/speech.rs matches "t"|"T" in one match arm). * pl: raise the remaining rule-file keys and test the number-set rules Two loose ends in the Polish localization. **Rule-file keys.** 248 entries in the rule files still used a lower-case key while carrying translated Polish text. Content is untouched - every one of the 248 changed lines differs from its predecessor only in the case of the key name, verified line by line after normalizing the key. 17 entries are deliberately left lower-case: five are the letters C, N, Q, R, Z in `dimension-number-sets` (the letter itself is the wording, as in English); `ct: "s"`/`ct: "-"` in the unit rule are the plural suffix and prefix separator; `navigate.yaml:176` is a Polish euphony variant ("ze" before "st-"); the remaining seven are XPath expressions rather than speech. **Tests for the number-set rules.** These rules had no Polish test at all, in a file where two silent defects were already found. New `tests/Languages/pl/number_sets.rs` covers the bare symbols, the dimension form, both sign variants, and ClearSpeak agreeing with SimpleSpeak. The `number_set_with_variable_exponent` case is the negative control: `dimension-number-sets` fires on `count(*)=2`, so a non-numeric exponent must fall through to the full phrase ("liczby całkowite do potęgi n") rather than being read as a dimension. Without it, a rule that swallowed every superscript would still pass. Polish keeps the letter with a dimension ("R 3"), matching en, de, fr, nb, sv, fi and es; Hungarian is the only language that translates in that position too. Measured with the SAPI voice NVDA actually uses: "R 3" is byte-identical to a phonetic "er 3" and "N 4" to "en 4", so the letters are pronounced as their Polish names. cargo test --test languages Languages::pl 614 passed, 0 failed * pl: inflect unit names according to the numeral, not with an English "s" The `unit` rule appended `ct: "s"` whenever a unit had no entry in `PluralForms`, and the Polish `PluralForms` contained no SI base unit at all. Measured output of the engine before this change: 1 metr, 2 metrs, 5 metrs, 21 metrs, 2 grams, 2 sekundas, 2 ampers, 2 mols, 2 kilo-metrs So a Polish NVDA user heard an English plural ending on essentially every quantity. Hungarian avoids this with `CT: ""` (it appends nothing); French and German legitimately use "s"; Russian, whose plurals work like Polish, does not rely on a suffix at all and fills in `PluralForms` instead. Polish was in the wrong group. Polish does not have one plural form. The noun follows the numeral: 1 metr | 2, 3, 4 metry (nominative plural) | 5 metrów (genitive plural) and the teens are the exception that breaks the naive rule: 12, 13, 14 metrów, likewise 112-114, while 22 and 102 take the nominative again. One extra plural column is therefore not enough, so this adds a second definition section, `PluralGenitive`, next to `PluralForms` (now the nominative plural). No Rust change is needed: `build_values` accepts any definition name as a hashmap. The `unit` rule (both the bare and the prefixed branch) and the `currency` rule now read the value of the numeral and pick the section accordingly. When the numeral cannot be determined - a variable coefficient, as in "x ms" - `$Coefficient` is 0 and the genitive is used, which is also what Polish uses for unknown quantities ("x mili-sekund"). Where no inflected form is known the singular is spoken rather than a guessed ending: a wrong ending is worse for a screen reader user than a missing one. Both sections cover all 131 unit and currency names that the Polish `SIUnits`, `UnitsWithoutPrefixes`, `EnglishUnits` and `CurrencySymbols` can produce. The forms are written out because Polish inflection cannot be derived from the ending: metr/metry but litr/litry, om/omy, dzień/dni, tydzień/tygodnie, rok/lata. Multi-word units inflect the head noun and keep the dependent word's case ("5 lat świetlnych", "5 minut łuku"). They were checked against hunspell pl_PL; the only words it does not know are the binary-prefix neologisms (kibibajt, gibibit, ...) whose singular forms already existed in the file. Three base forms were themselves wrong - plurals used as singulars, so the engine said "1 herce" and "1 konie mechaniczne": Hz herce -> herc hp konie mechaniczne -> koń mechaniczny ℧ M h o -> mho Every other language has a singular here (en hertz, ru герц, fi hertsi, es hercio; hp: ru "лошадиная сила", hu "lóerő", nb "hestekraft"; ℧: de/fr "mho"). Why this survived: the existing Polish expectations in tests/Languages/pl/units.rs recorded the broken output, so 609 tests passed while the speech was wrong ("2 dzieńs", "2 tydzieńs", "kwetta-grams"). Expectations harvested from real engine output are a good regression net but prove nothing about correctness unless they are read as a user would hear them. 21 test expectations are updated here, each difference reviewed word by word. Verification: cargo test --test languages Languages::pl 615 passed, 0 failed reverting general.yaml alone -> 6 of 6 new tests fail The new tests in tests/Languages/pl/unit_plurals.rs cover one class of phenomenon each: the three numeral classes including the teens exception, SI base units, the prefixed branch of the rule, irregular nouns, the corrected base forms, and multi-word units. * pl: speak the unit after "na" in the accusative, not the nominative The `per-fraction` rule speaks the denominator of a unit fraction after the preposition "na", which in Polish governs the accusative case. The unit was inserted in the nominative, so the engine said: 62 mile na godzina (should be "na godzinę") 5 metrów na sekunda (should be "na sekundę") 3 galony na mila (should be "na milę") 3 metry na sekunda do kwadratu Only feminine nouns change form here. For masculine inanimate and neuter names the accusative already equals the nominative, so "3 gramy na litr" and "1 dżul na mol" were correct and stay untouched. That narrows the work to 32 of the 131 unit and currency names, which is why `AccusativeCase` deliberately holds only those - a missing entry means "the form does not change". Why this lives in the `unit` rule rather than in `per-fraction`: Russian has the same problem and solves it inside `per-fraction` by testing the unit symbol and writing the inflected word inline (`милю`), which works because only one word is affected. Polish would need 32 such cases in the rule. Instead the `unit` rule asks whether it is being spoken as a fraction denominator, so the choice is made once, in one place, for every name. The denominator can also be raised to a power, as in m/s², and then the unit's parent is the `power` element rather than the fraction itself, so `IsFractionDenominator` tests both shapes. That second case was found only after the first fix: the existing expectation "3 metry na sekunda do kwadratu" was still passing green, because the list of failing tests shows only the cases whose output actually changed. Searching every Polish expectation for a nominative after "na" is what surfaced it. An adjective agrees with its noun ("na stopę kwadratową") while a dependent noun keeps its own case ("na minutę łuku", "na uncję płynu"), so the forms are written out rather than derived. Verification: cargo test --test languages Languages::pl 620 passed, 0 failed New tests in tests/Languages/pl/preposition_case.rs include two negative controls: masculine and neuter denominators must NOT change, and a unit standing on its own must stay in the nominative, so the accusative cannot leak outside the fraction denominator. --------- Co-authored-by: NSoiffer --- Rules/Languages/pl/SharedRules/general.yaml | 16 ++++- Rules/Languages/pl/definitions.yaml | 42 ++++++++++++ tests/Languages/pl.rs | 1 + tests/Languages/pl/ClearSpeak/mfrac.rs | 2 +- tests/Languages/pl/SimpleSpeak/mfrac.rs | 8 +-- tests/Languages/pl/preposition_case.rs | 71 +++++++++++++++++++++ 6 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 tests/Languages/pl/preposition_case.rs diff --git a/Rules/Languages/pl/SharedRules/general.yaml b/Rules/Languages/pl/SharedRules/general.yaml index f3d026f2b..e6c94a36a 100644 --- a/Rules/Languages/pl/SharedRules/general.yaml +++ b/Rules/Languages/pl/SharedRules/general.yaml @@ -293,6 +293,14 @@ # cannot be determined, which falls through to the genitive - the form # Polish uses with unknown or large quantities. - Coefficient: "IfThenElse($MRowForCoefficient, number($MRowForCoefficient/*[1][self::m:mn]), 0)" + # The 'per-fraction' rule speaks the denominator after the preposition "na", + # which governs the accusative: "na godzinę", not "na godzina". Only feminine + # nouns change form, so AccusativeCase holds just those; a missing entry + # means the accusative equals the nominative (as for "na litr", "na mol"). + # The second test covers a denominator raised to a power, as in m/s^2, where + # the unit's parent is the 'power' element rather than the fraction itself. + - IsFractionDenominator: "(parent::m:fraction and preceding-sibling::*) or + (parent::m:power and parent::*[parent::m:fraction and preceding-sibling::*])" - IsNominativePlural: "$Coefficient mod 10 >= 2 and $Coefficient mod 10 <= 4 and not($Coefficient mod 100 >= 12 and $Coefficient mod 100 <= 14)" - Prefix: "''" @@ -339,7 +347,9 @@ if: "$Prefix = ''" then: - test: - - if: "$IsSingular" + - if: "$IsSingular and $IsFractionDenominator and DefinitionValue($Word, 'Speech', 'AccusativeCase') != ''" + then: [x: "DefinitionValue($Word, 'Speech', 'AccusativeCase')"] + - else_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: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''" @@ -353,7 +363,9 @@ - x: "$Prefix" - ct: "-" - test: - - if: "$IsSingular" + - if: "$IsSingular and $IsFractionDenominator and DefinitionValue($Word, 'Speech', 'AccusativeCase') != ''" + then: [x: "concat('\uF8FE', DefinitionValue($Word, 'Speech', 'AccusativeCase'))"] + - else_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: "$IsNominativePlural and DefinitionValue($Word, 'Speech', 'PluralForms') != ''" diff --git a/Rules/Languages/pl/definitions.yaml b/Rules/Languages/pl/definitions.yaml index 18785562b..0f212c4e4 100644 --- a/Rules/Languages/pl/definitions.yaml +++ b/Rules/Languages/pl/definitions.yaml @@ -646,6 +646,48 @@ "łyżka stołowa": "łyżki stołowe" } +- AccusativeCase: { + # Accusative singular, used after the preposition "na" in the + # 'per-fraction' rule: "62 mile na godzinę", not "na godzina". + # Only feminine nouns differ from the nominative, so masculine and + # neuter names are deliberately absent - a missing entry means + # "the form does not change" (na litr, na mol, na metr). + # An adjective agrees with its noun (milę kwadratową), while a + # dependent noun keeps its own case (uncję płynu, minutę łuku). + "atmosfera": "atmosferę", + "baryłka": "baryłkę", + "drachma": "drachmę", + "drachma płynu": "drachmę płynu", + "dyna": "dynę", + "godzina": "godzinę", + "jednostka astronomiczna": "jednostkę astronomiczną", + "jednostka masy atomowej": "jednostkę masy atomowej", + "kaloria": "kalorię", + "kandela": "kandelę", + "kwarta": "kwartę", + "mila": "milę", + "mila kwadratowa": "milę kwadratową", + "mila na galon": "milę na galon", + "mila na godzinę": "milę na godzinę", + "minuta": "minutę", + "minuta łuku": "minutę łuku", + "pinta": "pintę", + "rupia": "rupię", + "sekunda": "sekundę", + "sekunda łuku": "sekundę łuku", + "stopa": "stopę", + "stopa deskowa": "stopę deskową", + "stopa kwadratowa": "stopę kwadratową", + "stopa sześcienna": "stopę sześcienną", + "tesla": "teslę", + "tona": "tonę", + "uncja": "uncję", + "uncja płynu": "uncję płynu", + "uncja trojańska": "uncję trojańską", + "łyżeczka": "łyżeczkę", + "łyżka stołowa": "łyżkę stołową" + } + - PluralGenitive: { # Genitive plural - after 5 and above, and after 12-14, 112-114. # Polish inflects the noun according to the numeral, so a single plural diff --git a/tests/Languages/pl.rs b/tests/Languages/pl.rs index c9423ea9f..8e4c56f37 100644 --- a/tests/Languages/pl.rs +++ b/tests/Languages/pl.rs @@ -4,6 +4,7 @@ mod pl; mod number_sets; mod unit_plurals; +mod preposition_case; // Tests mirrored from the English suite, with expected speech localized to Polish. mod ClearSpeak { diff --git a/tests/Languages/pl/ClearSpeak/mfrac.rs b/tests/Languages/pl/ClearSpeak/mfrac.rs index a53bba559..fff485696 100644 --- a/tests/Languages/pl/ClearSpeak/mfrac.rs +++ b/tests/Languages/pl/ClearSpeak/mfrac.rs @@ -86,7 +86,7 @@ fn frac_with_units() -> Result<()> { "; - test("pl", "ClearSpeak", expr, "62 mile na godzina")?; + test("pl", "ClearSpeak", expr, "62 mile na godzinę")?; return Ok(()); } diff --git a/tests/Languages/pl/SimpleSpeak/mfrac.rs b/tests/Languages/pl/SimpleSpeak/mfrac.rs index a07f0592b..3b421b0f2 100644 --- a/tests/Languages/pl/SimpleSpeak/mfrac.rs +++ b/tests/Languages/pl/SimpleSpeak/mfrac.rs @@ -164,7 +164,7 @@ fn frac_with_units() -> Result<()> { "; - test("pl", "SimpleSpeak", expr, "62 mile na godzina")?; + test("pl", "SimpleSpeak", expr, "62 mile na godzinę")?; return Ok(()); } @@ -181,7 +181,7 @@ fn singular_frac_with_units() -> Result<()> { "; - test("pl", "SimpleSpeak", expr, "1 galon na mila")?; + test("pl", "SimpleSpeak", expr, "1 galon na milę")?; return Ok(()); } @@ -198,7 +198,7 @@ fn number_in_numerator_with_units() -> Result<()> { mi "; - test("pl", "SimpleSpeak", expr, "3 galony na mila")?; + test("pl", "SimpleSpeak", expr, "3 galony na milę")?; return Ok(()); } @@ -212,7 +212,7 @@ fn units_with_powers() -> Result<()> { s2 "; - test("pl", "SimpleSpeak", expr, "3 metry na sekunda do kwadratu")?; + test("pl", "SimpleSpeak", expr, "3 metry na sekundę do kwadratu")?; return Ok(()); } diff --git a/tests/Languages/pl/preposition_case.rs b/tests/Languages/pl/preposition_case.rs new file mode 100644 index 000000000..92d1a4521 --- /dev/null +++ b/tests/Languages/pl/preposition_case.rs @@ -0,0 +1,71 @@ +/// Polish prepositions govern case: the denominator of a unit fraction is spoken +/// after "na", which requires the accusative - "na godzinę", not "na godzina". +use crate::common::*; +use anyhow::Result; + +/// Feminine denominators: these are the ones whose form actually changes. +#[test] +fn per_fraction_feminine_denominator() -> Result<()> { + let expr = r#" + 62mihr, + 5ms, + 2kmhr, + 7radmin, + 3Jt + "#; + test("pl", "SimpleSpeak", expr, "62 mile na godzinę, przecinek; 5 metrów na sekundę, przecinek; 2 kilo-metry na godzinę; przecinek; 7 radianów na minutę, przecinek; 3 dżule na tonę")?; + Ok(()) +} + +/// Masculine and neuter denominators must NOT change: their accusative already +/// equals the nominative. This is the negative control for the change. +#[test] +fn per_fraction_masculine_denominator_unchanged() -> Result<()> { + let expr = r#" + 3gl, + 1Jmol, + 5Nm, + 2VA + "#; + test("pl", "SimpleSpeak", expr, "3 gramy na litr, przecinek; 1 dżul na mol, przecinek; 5 niutonów na metr, przecinek; 2 wolty na amper")?; + Ok(()) +} + +/// A unit standing on its own keeps the nominative - the accusative must not +/// leak outside the fraction denominator. +#[test] +fn standalone_unit_stays_nominative() -> Result<()> { + let expr = r#" + 1hr, + 1s, + 1t, + 1min + "#; + test("pl", "SimpleSpeak", expr, "1 godzina, przecinek; 1 sekunda, przecinek; 1 tona, przecinek; 1 minuta")?; + Ok(()) +} + +/// Multi-word feminine units: the adjective agrees, a dependent noun does not. +#[test] +fn per_fraction_multiword_denominator() -> Result<()> { + let expr = r#" + 3gsq ft, + 2marcmin + "#; + test("pl", "SimpleSpeak", expr, "3 gramy na stopę kwadratową; przecinek; 2 metry na minutę łuku")?; + Ok(()) +} + +/// A denominator raised to a power, as in m/s^2: the unit's parent is the +/// 'power' element, not the fraction, so this needs its own test. +#[test] +fn per_fraction_denominator_with_power() -> Result<()> { + let expr = r#" + + 3m + s2 + + "#; + test("pl", "SimpleSpeak", expr, "3 metry na sekundę do kwadratu")?; + Ok(()) +} From 6a5170a57526ea1c873f4cb67f92a0b892c6087f Mon Sep 17 00:00:00 2001 From: mgros Date: Fri, 4 Sep 2026 01:59:00 +0200 Subject: [PATCH 08/23] Update: Add `Cargo.lock` file to track dependencies --- .gitignore | 1 - Cargo.lock | 2075 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2075 insertions(+), 1 deletion(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index fef5d915c..b2784f7e8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ target build.rs.orig Python/libmathcat.pyd -Cargo.lock src-pest.7z src.7z mp2.7z diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..50bccf29f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2075 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alsa" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" +dependencies = [ + "alsa-sys", + "bitflags 2.11.0", + "cfg-if", + "libc", +] + +[[package]] +name = "alsa-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "android_log-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" + +[[package]] +name = "android_logger" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3" +dependencies = [ + "android_log-sys", + "env_filter 0.1.4", + "log", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse 0.2.7", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse 1.0.0", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "bzip2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" +dependencies = [ + "libbz2-rs-sys", +] + +[[package]] +name = "cc" +version = "1.2.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "clap" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstream 1.0.0", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +dependencies = [ + "heck", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "coreaudio-rs" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aae284fbaf7d27aa0e292f7677dfbe26503b0d555026f702940805a630eac17" +dependencies = [ + "bitflags 1.3.2", + "libc", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "cpal" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd307f43cc2a697e2d1f8bc7a1d824b5269e052209e28883e5bc04d095aaa3f" +dependencies = [ + "alsa", + "coreaudio-rs", + "dasp_sample", + "jni", + "js-sys", + "libc", + "mach2", + "ndk", + "ndk-context", + "num-derive", + "num-traits", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.106", + "quote 1.0.45", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "dasp_sample" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn 2.0.117", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.11.0", + "objc2", +] + +[[package]] +name = "doc-comment" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_filter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_filter" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +dependencies = [ + "anstream 0.6.21", + "anstyle", + "env_filter 1.0.0", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "extended" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "miniz_oxide", + "zlib-rs", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hound" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" + +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "jiff" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c867c356cc096b33f4981825ab281ecba3db0acefe60329f044c1789d94c6543" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7946b4325269738f270bb55b3c19ab5c5040525f83fd625259422a9d25d9be5" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys 0.3.1", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "js-sys" +version = "0.3.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libbz2-rs-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" + +[[package]] +name = "libc" +version = "0.2.182" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" + +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.11.0", + "libc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +dependencies = [ + "libc", +] + +[[package]] +name = "mathcat" +version = "0.7.6-rc.4" +dependencies = [ + "android_logger", + "anyhow", + "bitflags 2.11.0", + "cfg-if", + "clap", + "dirs", + "env_logger", + "fastrand", + "html-escape", + "log", + "natural-tts", + "phf", + "radix_fmt", + "regex", + "roman-numerals-rs", + "strum", + "sxd-document-no-unsafe", + "sxd-xpath-no-unsafe", + "tempfile", + "unicode-script", + "yaml-rust", + "zip", +] + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "minreq" +version = "2.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05015102dad0f7d61691ca347e9d9d9006685a64aefb3d79eecf62665de2153d" +dependencies = [ + "rustls", + "rustls-webpki", + "webpki-roots", +] + +[[package]] +name = "natural-tts" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06ae31375ea7364dfadc29bbae70683fce13617e602c458898ebd2630fb1a89" +dependencies = [ + "derive_builder", + "hound", + "minreq", + "percent-encoding", + "rodio", + "serde", + "thiserror 2.0.18", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.11.0", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys 0.3.1", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-audio-toolbox" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6948501a91121d6399b79abaa33a8aa4ea7857fe019f341b8c23ad6e81b79b08" +dependencies = [ + "bitflags 2.11.0", + "libc", + "objc2", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-audio" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2" +dependencies = [ + "dispatch2", + "objc2", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-core-audio-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c" +dependencies = [ + "bitflags 2.11.0", + "objc2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.11.0", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "objc2", +] + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "peresil" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f658886ed52e196e850cfbbfddab9eaa7f6d90dd0929e264c31e5cec07e09e57" + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2 1.0.106", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "radix_fmt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426" + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rodio" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e40ecf59e742e03336be6a3d53755e789fd05a059fa22dfa0ed624722319e183" +dependencies = [ + "cpal", + "dasp_sample", + "num-rational", + "symphonia", +] + +[[package]] +name = "roman-numerals-rs" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8408ef3512d2c5d6876de3cf8f24751e19c5f2566e37e1d31ced56a1892f1e92" + +[[package]] +name = "rustc-demangle" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.11.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "snafu" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0bf93d08d6a44363b47d737f1f5bebbf5e6a1eaaa3d4c128ceeaca6b718292" +dependencies = [ + "backtrace", + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624e94bd38e471f67883b467711e7a7ad7dbe284f5fb7e661dc8a671fc5b26a0" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "sxd-document-no-unsafe" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c08c6a37e27fb1559e036ae8f45672faf06623f13c74c8de9719d50536981f5" +dependencies = [ + "peresil", + "typed-arena", +] + +[[package]] +name = "sxd-xpath-no-unsafe" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff5bfe9c78786014d5a76d9328ea6508b0b74b7dc4a7c4d9b881ace23ce50d" +dependencies = [ + "peresil", + "snafu", + "sxd-document-no-unsafe", +] + +[[package]] +name = "symphonia" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5773a4c030a19d9bfaa090f49746ff35c75dfddfa700df7a5939d5e076a57039" +dependencies = [ + "lazy_static", + "symphonia-bundle-flac", + "symphonia-bundle-mp3", + "symphonia-codec-aac", + "symphonia-codec-pcm", + "symphonia-codec-vorbis", + "symphonia-core", + "symphonia-format-isomp4", + "symphonia-format-ogg", + "symphonia-format-riff", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-bundle-flac" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91565e180aea25d9b80a910c546802526ffd0072d0b8974e3ebe59b686c9976" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-bundle-mp3" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4872dd6bb56bf5eac799e3e957aa1981086c3e613b27e0ac23b176054f7c57ed" +dependencies = [ + "lazy_static", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-codec-aac" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c263845aa86881416849c1729a54c7f55164f8b96111dba59de46849e73a790" +dependencies = [ + "lazy_static", + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-codec-pcm" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e89d716c01541ad3ebe7c91ce4c8d38a7cf266a3f7b2f090b108fb0cb031d95" +dependencies = [ + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-codec-vorbis" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f025837c309cd69ffef572750b4a2257b59552c5399a5e49707cc5b1b85d1c73" +dependencies = [ + "log", + "symphonia-core", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-core" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea00cc4f79b7f6bb7ff87eddc065a1066f3a43fe1875979056672c9ef948c2af" +dependencies = [ + "arrayvec", + "bitflags 1.3.2", + "bytemuck", + "lazy_static", + "log", +] + +[[package]] +name = "symphonia-format-isomp4" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243739585d11f81daf8dac8d9f3d18cc7898f6c09a259675fc364b382c30e0a5" +dependencies = [ + "encoding_rs", + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-format-ogg" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b4955c67c1ed3aa8ae8428d04ca8397fbef6a19b2b051e73b5da8b1435639cb" +dependencies = [ + "log", + "symphonia-core", + "symphonia-metadata", + "symphonia-utils-xiph", +] + +[[package]] +name = "symphonia-format-riff" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d7c3df0e7d94efb68401d81906eae73c02b40d5ec1a141962c592d0f11a96f" +dependencies = [ + "extended", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-metadata" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36306ff42b9ffe6e5afc99d49e121e0bd62fe79b9db7b9681d48e29fa19e6b16" +dependencies = [ + "encoding_rs", + "lazy_static", + "log", + "symphonia-core", +] + +[[package]] +name = "symphonia-utils-xiph" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27c85ab799a338446b68eec77abf42e1a6f1bb490656e121c6e27bfbab9f16" +dependencies = [ + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "typed-path" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e" + +[[package]] +name = "unicode-ident" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" + +[[package]] +name = "unicode-script" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "utf8-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +dependencies = [ + "quote 1.0.45", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +dependencies = [ + "bumpalo", + "proc-macro2 1.0.106", + "quote 1.0.45", + "syn 2.0.117", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "zip" +version = "8.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d04a6b5381502aa6087c94c669499eb1602eb9c5e8198e534de571f7154809b" +dependencies = [ + "bzip2", + "crc32fast", + "flate2", + "indexmap", + "memchr", + "typed-path", + "zopfli", +] + +[[package]] +name = "zlib-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] From a6b6af1592cf35c46a8d2309abdfd514c71e0115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Arborealis=20L=C3=B6tberg?= <143188129+TimArborealis@users.noreply.github.com> Date: Mon, 7 Sep 2026 13:34:39 +0200 Subject: [PATCH 09/23] Minor chemistry fix in Swedish Changed chemical arrow operator to read "reagerar och bildar" instead of "reaktion bildar", to make grammatical sense. --- Rules/Languages/sv/SharedRules/general.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules/Languages/sv/SharedRules/general.yaml b/Rules/Languages/sv/SharedRules/general.yaml index 192c11204..48676832d 100644 --- a/Rules/Languages/sv/SharedRules/general.yaml +++ b/Rules/Languages/sv/SharedRules/general.yaml @@ -1161,7 +1161,7 @@ then_test: if: "$Verbosity='Terse'" then: [{T: "bildar"}] # phrase(hydrogen and oxygen 'forms' water ) - else: [{T: "reaktion bildar"}] # phrase(hydrogen and oxygen 'reacts to form' water) + else: [{T: "reagerar och bildar"}] # phrase(hydrogen and oxygen 'reacts to form' water) - else_if: ".='⇌' or .='\u1f8d2'" then: [{T: "är i jämvikt med"}] # phrase(a reactant 'is in equilibrium with' a product) - else_if: ".='\u1f8d4'" From bd03fcd02cc69344b574e1d417ded032e40ed290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Tue, 8 Sep 2026 00:57:22 +0200 Subject: [PATCH 10/23] pl: mark the unicode translations as verified (t -> T) (#741) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * pl: mark the unicode translations as verified (t -> T) Mechanical change: 2435 text keys raised from t/ot/ct to T/OT/CT in the two unicode files. No text is touched. The Polish rules were written before the lowercase/uppercase convention was in use, so entries that have been translated all along still carried the "needs review" key. The audit tool therefore reported them as untranslated, which made the real gaps impossible to see: audit-translations pl, untranslated text: 3162 -> 727 The remaining 727 are in the rule files, where the entries need reading rather than a mechanical pass, so they are deliberately left alone. Every raised entry was checked to differ from the English source, i.e. it really is translated. Entries whose text legitimately equals English (Roman numerals, ligatures, proper names, whitespace) were handled separately in the previous PR; entries still holding English text are NOT raised, since that would assert a translation that does not exist. Verification: cargo test --test languages Languages::pl 609 passed, 0 failed diff: 2436 insertions, 2436 deletions, zero changes outside key case The last point is checked by normalising the key case in the diff and confirming no unpaired lines remain (without normalising, 4710 remain, so the check does discriminate). * pl: also mark the multi-line unicode entries as verified The previous commit raised the key on entries written on a single line (`- "±": [t: "..."]`), but not on entries whose body is a block: - "°": - test: if: "parent::*[name(.)='msup' ...]" then: [t: "stopni"] else: [t: "stopień"] Those are exactly the entries carrying inflection or a TTS condition, so 312 of the most deliberate translations in the file were left looking unreviewed. This raises them: 64 in unicode.yaml, 247 in unicode-full.yaml and one single-line entry (U+23E6) missed earlier. One entry is deliberately left with a lower-case key: `t: ""` for U+00A0, the else-branch of the `@data-empty-in-2D` test. That is silence rather than text, and an upper-case key means "a translator checked this wording" - there is no wording to check. English keeps a lower-case key there too. No content changes; only key case. `cargo test --test languages Languages::pl` gives 609 passed, 0 failed, which is the same result as before this commit, as expected for a change the engine treats as equivalent (src/speech.rs matches "t"|"T" in one match arm). * pl: raise the remaining rule-file keys and test the number-set rules Two loose ends in the Polish localization. **Rule-file keys.** 248 entries in the rule files still used a lower-case key while carrying translated Polish text. Content is untouched - every one of the 248 changed lines differs from its predecessor only in the case of the key name, verified line by line after normalizing the key. 17 entries are deliberately left lower-case: five are the letters C, N, Q, R, Z in `dimension-number-sets` (the letter itself is the wording, as in English); `ct: "s"`/`ct: "-"` in the unit rule are the plural suffix and prefix separator; `navigate.yaml:176` is a Polish euphony variant ("ze" before "st-"); the remaining seven are XPath expressions rather than speech. **Tests for the number-set rules.** These rules had no Polish test at all, in a file where two silent defects were already found. New `tests/Languages/pl/number_sets.rs` covers the bare symbols, the dimension form, both sign variants, and ClearSpeak agreeing with SimpleSpeak. The `number_set_with_variable_exponent` case is the negative control: `dimension-number-sets` fires on `count(*)=2`, so a non-numeric exponent must fall through to the full phrase ("liczby całkowite do potęgi n") rather than being read as a dimension. Without it, a rule that swallowed every superscript would still pass. Polish keeps the letter with a dimension ("R 3"), matching en, de, fr, nb, sv, fi and es; Hungarian is the only language that translates in that position too. Measured with the SAPI voice NVDA actually uses: "R 3" is byte-identical to a phonetic "er 3" and "N 4" to "en 4", so the letters are pronounced as their Polish names. cargo test --test languages Languages::pl 614 passed, 0 failed --------- Co-authored-by: NSoiffer From e1990813b058ff4c27671c244c0960983e78acae Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Tue, 8 Sep 2026 12:26:42 +1000 Subject: [PATCH 11/23] add PauseFactor to test initialization so that local changes don't affect the outcome. Also consolodate nav preference testing. --- src/interface.rs | 22 ++++++++++++++++++++++ src/navigate.rs | 8 +------- tests/Languages/en/navigate.rs | 15 +-------------- tests/Languages/nb/navigate.rs | 15 +-------------- tests/Languages/ru/navigate.rs | 15 +-------------- tests/common/mod.rs | 11 +++++++++++ 6 files changed, 37 insertions(+), 49 deletions(-) diff --git a/src/interface.rs b/src/interface.rs index 3177c22c8..157a895f1 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -540,6 +540,28 @@ pub fn do_navigate_command(command: impl AsRef) -> Result { return report_any_panic(result); } +/// Preferences shared by navigation unit and integration tests. +/// +/// Sets `PauseFactor` to 100 so local user prefs (e.g. AppData) cannot change +/// TTS:None pause punctuation (`,` vs `;`) in goldens. +/// `auto_zoom_out` is true for most `src/navigate.rs` tests and false for +/// `tests/Languages/*/navigate.rs`. +pub fn set_navigation_test_preferences( + language: impl AsRef, + nav_mode: impl AsRef, + auto_zoom_out: bool, +) -> Result<()> { + set_preference("NavMode", nav_mode)?; + set_preference("NavVerbosity", "Verbose")?; + set_preference("AutoZoomOut", if auto_zoom_out { "True" } else { "False" })?; + set_preference("Language", language)?; + set_preference("SpeechStyle", "SimpleSpeak")?; + set_preference("Verbosity", "Medium")?; + set_preference("PauseFactor", "100")?; + set_preference("Overview", "False")?; + return Ok(()); +} + /// Given an 'id' and an offset (for tokens), set the navigation node to that id. /// An error is returned if the 'id' doesn't exist pub fn set_navigation_node(id: impl AsRef, offset: usize) -> Result<()> { diff --git a/src/navigate.rs b/src/navigate.rs index 1fac4e766..d1444a86c 100644 --- a/src/navigate.rs +++ b/src/navigate.rs @@ -1030,13 +1030,7 @@ mod tests { init_panic_handler(); let result = catch_unwind(AssertUnwindSafe(|| { set_rules_dir(super::super::abs_rules_dir_path())?; - set_preference("NavMode", nav_mode_default)?; - set_preference("NavVerbosity", "Verbose")?; - set_preference("AutoZoomOut", "True")?; - set_preference("Language", language)?; - set_preference("SpeechStyle", "SimpleSpeak")?; - set_preference("Verbosity", "Medium")?; - set_preference("Overview", "False")?; + set_navigation_test_preferences(language, nav_mode_default, true)?; set_mathml(mathml)?; return Ok( () ); })); diff --git a/tests/Languages/en/navigate.rs b/tests/Languages/en/navigate.rs index abb317f18..6752f9773 100644 --- a/tests/Languages/en/navigate.rs +++ b/tests/Languages/en/navigate.rs @@ -8,23 +8,10 @@ use crate::common::*; use anyhow::Result; use std::panic::{catch_unwind, AssertUnwindSafe}; -fn init_nav(mathml: &str) -> Result<()> { - set_rules_dir(abs_rules_dir_path())?; - set_preference("Language", "en")?; - set_preference("SpeechStyle", "SimpleSpeak")?; - set_preference("Verbosity", "Medium")?; - set_preference("NavMode", "Enhanced")?; - set_preference("NavVerbosity", "Verbose")?; - set_preference("AutoZoomOut", "False")?; - set_preference("Overview", "False")?; - set_mathml(mathml)?; - Ok(()) -} - fn assert_zoom_in(command: &str, mathml: &str, expected: &str) -> Result<()> { init_panic_handler(); let result = catch_unwind(AssertUnwindSafe(|| { - init_nav(mathml)?; + init_nav("en", mathml)?; let speech = do_navigate_command(command)?; let trimmed_speech = speech.trim_end_matches([' ', ',', ';']).to_string(); assert_eq!(expected, trimmed_speech); diff --git a/tests/Languages/nb/navigate.rs b/tests/Languages/nb/navigate.rs index 4f1b8dbf2..fd254c6b3 100644 --- a/tests/Languages/nb/navigate.rs +++ b/tests/Languages/nb/navigate.rs @@ -8,23 +8,10 @@ use crate::common::*; use anyhow::Result; use std::panic::{catch_unwind, AssertUnwindSafe}; -fn init_nav(mathml: &str) -> Result<()> { - set_rules_dir(abs_rules_dir_path())?; - set_preference("Language", "nb")?; - set_preference("SpeechStyle", "SimpleSpeak")?; - set_preference("Verbosity", "Medium")?; - set_preference("NavMode", "Enhanced")?; - set_preference("NavVerbosity", "Verbose")?; - set_preference("AutoZoomOut", "False")?; - set_preference("Overview", "False")?; - set_mathml(mathml)?; - Ok(()) -} - fn assert_zoom_in(command: &str, mathml: &str, expected: &str) -> Result<()> { init_panic_handler(); let result = catch_unwind(AssertUnwindSafe(|| { - init_nav(mathml)?; + init_nav("nb", mathml)?; let speech = do_navigate_command(command)?; let trimmed_speech = speech.trim_end_matches([' ', ',', ';']).to_string(); assert_eq!(expected, trimmed_speech); diff --git a/tests/Languages/ru/navigate.rs b/tests/Languages/ru/navigate.rs index 690df9eff..0195f5bde 100644 --- a/tests/Languages/ru/navigate.rs +++ b/tests/Languages/ru/navigate.rs @@ -4,23 +4,10 @@ use crate::common::*; use anyhow::Result; use std::panic::{catch_unwind, AssertUnwindSafe}; -fn init_nav(mathml: &str) -> Result<()> { - set_rules_dir(abs_rules_dir_path())?; - set_preference("Language", "ru")?; - set_preference("SpeechStyle", "SimpleSpeak")?; - set_preference("Verbosity", "Medium")?; - set_preference("NavMode", "Enhanced")?; - set_preference("NavVerbosity", "Verbose")?; - set_preference("AutoZoomOut", "False")?; - set_preference("Overview", "False")?; - set_mathml(mathml)?; - Ok(()) -} - fn assert_zoom_in(mathml: &str, expected: &str) -> Result<()> { init_panic_handler(); let result = catch_unwind(AssertUnwindSafe(|| { - init_nav(mathml)?; + init_nav("ru", mathml)?; let speech = do_navigate_command("ZoomIn")?; let trimmed_speech = speech.trim_end_matches([' ', ',', ';']).to_string(); assert_eq!(expected, trimmed_speech); diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 6b42a25b8..837fca05b 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -75,6 +75,17 @@ fn set_default_speech_prefs() { prefs.set_user_prefs("Impairment", "Blindness").unwrap(); }); } + +/// Initialize navigation prefs + MathML for `tests/Languages/*/navigate.rs`. +/// Uses the same prefs as `src/navigate.rs` tests via [`set_navigation_test_preferences`], +/// except `AutoZoomOut` is false (language ZoomIn speech tests need that). +#[allow(dead_code)] // used in testing +pub fn init_nav(language: &str, mathml: &str) -> Result<()> { + set_rules_dir(abs_rules_dir_path())?; + set_navigation_test_preferences(language, "Enhanced", false)?; + set_mathml(mathml)?; + Ok(()) +} // Compare the result of speaking the mathml input to the output 'speech' // This uses default preferences #[allow(dead_code)] // used in testing From d3b7970e38fa073e1f187afb6537e37d6b9ab859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Tue, 8 Sep 2026 05:59:07 +0200 Subject: [PATCH 12/23] Fix pica unit parsing in spacing width conversion (#755) --- src/xpath_functions.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/xpath_functions.rs b/src/xpath_functions.rs index 97e1db5ee..17b6d360b 100644 --- a/src/xpath_functions.rs +++ b/src/xpath_functions.rs @@ -1408,9 +1408,10 @@ pub struct FontSizeGuess; /// "" // returns original node match isn't found impl FontSizeGuess { + /// Returns an estimated width in em units, using an assumed 12-point font for conversions. pub fn em_from_value(value_with_unit: &str) -> f64 { // match one or more digits followed by a unit -- there are many more units, but they tend to be large and rarer(?) - static FONT_VALUE: LazyLock = LazyLock::new(|| { Regex::new(r"(-?[0-9]*\.?[0-9]*)(px|cm|mm|Q|in|ppc|pt|ex|em|rem)").unwrap() }); + static FONT_VALUE: LazyLock = LazyLock::new(|| { Regex::new(r"(-?[0-9]*\.?[0-9]*)(px|cm|mm|Q|in|pc|pt|ex|em|rem)").unwrap() }); let cap = FONT_VALUE.captures(value_with_unit); if let Some(cap) = cap { if cap.len() == 3 { @@ -1784,6 +1785,16 @@ mod tests { return Ok( () ); } + // Pica widths must use the existing 12pt font estimate: 1pc, 12pt, and 1em are equivalent. + #[test] + fn font_size_guess_pica_widths() { + assert_eq!(FontSizeGuess::em_from_value("1pc"), 1.0); + assert_eq!(FontSizeGuess::em_from_value("0.5pc"), 0.5); + assert_eq!(FontSizeGuess::em_from_value("-1pc"), -1.0); + assert_eq!(FontSizeGuess::em_from_value("12pt"), 1.0); + assert_eq!(FontSizeGuess::em_from_value("1em"), 1.0); + } + #[test] fn ordinal_one_digit() -> Result<()> { return xpath_test(|| { From 07149291fde5258e24148f18139082d49ebf2016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Arborealis=20L=C3=B6tberg?= <143188129+TimArborealis@users.noreply.github.com> Date: Tue, 8 Sep 2026 09:34:46 +0200 Subject: [PATCH 13/23] Update chemistry.rs --- tests/Languages/sv/chemistry.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Languages/sv/chemistry.rs b/tests/Languages/sv/chemistry.rs index 6332997fc..09612bd26 100644 --- a/tests/Languages/sv/chemistry.rs +++ b/tests/Languages/sv/chemistry.rs @@ -160,9 +160,9 @@ fn beta_decay() -> Result<()> { test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "14, 6, versal c; bildar, 14, 7, versal n; plus 0, minus 1, e")?; test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "upphöjt 14, nedsänkt 6, versal c; reaktion bildar; upphöjt 14, nedsänkt 7, versal n; plus, upphöjt 0, nedsänkt minus 1, e")?; + "upphöjt 14, nedsänkt 6, versal c; reagerar och bildar; upphöjt 14, nedsänkt 7, versal n; plus, upphöjt 0, nedsänkt minus 1, e")?; test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, - "övre index 14, nedre index 6, versal c; reaktion bildar; övre index 14, nedre index 7, versal n; plus, övre index 0, nedre index minus 1, e")?; + "övre index 14, nedre index 6, versal c; reagerar och bildar; övre index 14, nedre index 7, versal n; plus, övre index 0, nedre index minus 1, e")?; return Ok(()); } @@ -426,9 +426,9 @@ fn mhchem_beta_decay() -> Result<()> { test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Terse")], expr, "14, 6, versal c; bildar, 14, 7, versal n; plus 0, minus 1, e")?; test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Medium")], expr, - "upphöjt 14, nedsänkt 6, versal c; reaktion bildar; upphöjt 14, nedsänkt 7, versal n; plus, upphöjt 0, nedsänkt minus 1, e")?; + "upphöjt 14, nedsänkt 6, versal c; reagerar och bildar; upphöjt 14, nedsänkt 7, versal n; plus, upphöjt 0, nedsänkt minus 1, e")?; test_prefs("sv", "ClearSpeak", vec![("Verbosity", "Verbose")], expr, - "övre index 14, nedre index 6, versal c; reaktion bildar; övre index 14, nedre index 7, versal n; plus, övre index 0, nedre index minus 1, e")?; + "övre index 14, nedre index 6, versal c; reagerar och bildar; övre index 14, nedre index 7, versal n; plus, övre index 0, nedre index minus 1, e")?; return Ok(()); } @@ -443,7 +443,7 @@ fn hcl_na_yields() -> Result<()> { "; test_prefs("sv", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, - "2, versal h, versal c l; plus 2 versal n a; reaktion bildar; 2, versal n a, versal c l; plus versal h, nedre index 2")?; + "2, versal h, versal c l; plus 2 versal n a; reagerar och bildar; 2, versal n a, versal c l; plus versal h, nedre index 2")?; return Ok(()); } From d5d1933c07396b84642e6839eb8d3569340d499d Mon Sep 17 00:00:00 2001 From: Jeff Witt <1848307+wittjeff@users.noreply.github.com> Date: Sun, 13 Sep 2026 07:37:39 -0400 Subject: [PATCH 14/23] Fix "TEMP NAME of" when a parenthesized matrix is raised to a power (#762) (#763) * fix(speech): flatten nested TEMP_NAME wrappers so a matrix raised to a power is not read as "TEMP NAME of" The mrow 'matrix' intent rule replaces with a bare `x: "*[2]"`, so its result is wrapped in the internal TEMP_NAME transport element; the parent `power` rule's `x: "*[1]"` wraps it again and lift_children only stripped one level. The leftover wrapper reached the generic function-intent speech rule, which spoke its name: "TEMP NAME of the 2 by 2 matrix; ...; squared" (#762). lift_children now flattens nested wrappers recursively. A leaf wrapper holding text is still only unwrapped as a direct child, matching the previous behavior. Two regression tests added to tests/Languages/en/mtable.rs; no goldens changed. Fixes #762 Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01U86v5m1m8oaLSy5UsNbBpc * Simplify condition in push_lifted function Fixes clippy warning * Fix indent and delete extra "}" I should have deleted on the last change --------- Co-authored-by: Claude Fable 5.1 Co-authored-by: NSoiffer --- src/speech.rs | 32 ++++++++++++++++++-------- tests/Languages/en/mtable.rs | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/speech.rs b/src/speech.rs index 100d5ff39..544ce35c7 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -709,24 +709,36 @@ impl Intent { /// "lift" up the children any "TEMP_NAME" child -- could short circuit when only one child + /// + /// TEMP_NAME is only ever a transport wrapper created by `replace_nodes_tree`, so wrappers can nest: + /// a rule whose replacement is a bare `x:` (e.g., the mrow 'matrix' rule returns `x: "*[2]"`) yields + /// TEMP_NAME(matrix), and the parent intent's `x: "*[1]"` wraps that again. Lifting only one level left + /// `power(TEMP_NAME(matrix), 2)`, spoken as "TEMP NAME of the 2 by 2 matrix ... squared" (issue #762). + /// Nested wrappers whose children are all elements are flattened; a leaf wrapper (text from a Text or + /// Attribute node) is only unwrapped when it is a direct child, matching the previous behavior. fn lift_children(result: Element) -> Element { // debug!("lift_children:\n{}", mml_to_string(result)); // most likely there will be the same number of new children as result has, but there could be more let mut new_children = Vec::with_capacity(2*result.children().len()); for child_of_element in result.children() { - match child_of_element { - ChildOfElement::Element(child) => { - if name(child) == "TEMP_NAME" { - new_children.append(&mut child.children()); // almost always just one - } else { - new_children.push(child_of_element); - } - }, - _ => new_children.push(child_of_element), // text() - } + push_lifted(child_of_element, &mut new_children, true); } result.replace_children(new_children); return result; + + fn push_lifted<'a>(child_of_element: ChildOfElement<'a>, new_children: &mut Vec>, is_direct_child: bool) { + if let ChildOfElement::Element(child) = child_of_element && name(child) == "TEMP_NAME" { + let grandchildren = child.children(); + let is_leaf_wrapper = grandchildren.iter().any(|gc| matches!(gc, ChildOfElement::Text(_))); + if is_direct_child || !is_leaf_wrapper { + for grandchild in grandchildren { + push_lifted(grandchild, new_children, false); + } + return; + } + } + new_children.push(child_of_element); + } } } } diff --git a/tests/Languages/en/mtable.rs b/tests/Languages/en/mtable.rs index 8a670988e..e2d063689 100644 --- a/tests/Languages/en/mtable.rs +++ b/tests/Languages/en/mtable.rs @@ -1390,3 +1390,47 @@ fn single_line_with_label() -> Result<()> { expr, "1 equation, with label 2; b equals 2")?; return Ok(()); } + +#[test] +fn matrix_raised_to_power() -> Result<()> { + // A parenthesized matrix as the base of msup must speak as "the matrix ... squared". + // Regression for #762: the mrow 'matrix' intent rule returns a bare `x:`, so the intent tree + // carried a nested TEMP_NAME wrapper into `power` and NVDA read "TEMP NAME of the 2 by 2 matrix ...". + let expr = " + ( + + 12 + 34 + + ) + 2 + "; + test("en", "ClearSpeak", expr, "the 2 by 2 matrix; row 1; 1, 2; row 2; 3, 4; squared") +} + +#[test] +fn matrix_raised_to_power_lualatex_spacing() -> Result<()> { + // The exact MathML from #762 (LuaLaTeX pmatrix output): negative-width mspace around the + // table and fence attributes on the parens. Canonicalization must fold the spacing away so + // the matrix is still recognized as the base of the power. + let expr = " + + + ( + + + + + 12 + 34 + + + + + ) + + 2 + + "; + test("en", "ClearSpeak", expr, "the 2 by 2 matrix; row 1; 1, 2; row 2; 3, 4; squared") +} From 8ef6ee1b134262b7f6db24851ca2da2588052b82 Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Tue, 15 Sep 2026 10:59:32 +1000 Subject: [PATCH 15/23] Fix typo in fallback --- src/speech.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/speech.rs b/src/speech.rs index 544ce35c7..6d5b252a7 100644 --- a/src/speech.rs +++ b/src/speech.rs @@ -293,7 +293,7 @@ pub fn process_include(current_file: &Path, new_file_name: &str, mut read_new // get the subdir ...Rules/Braille/en/... // could have ...Rules/Braille/definitions.yaml, so 'next()' doesn't exist in this case, but the file wasn't zipped up if let Some(subdir) = new_file.strip_prefix(unzip_dir).unwrap().iter().next() { - let default_lang = if unzip_dir.ends_with("Languages") {"en"} else {"UEB;"}; + let default_lang = if unzip_dir.ends_with("Languages") {"en"} else {"UEB"}; PreferenceManager::unzip_files(unzip_dir, subdir.to_str().unwrap(), Some(default_lang)).unwrap_or_default(); } } @@ -2868,8 +2868,6 @@ pub fn braille_replace_chars(str: &str, mathml: Element) -> Result { ), Err(e) => Err(e), } - - }) } From 87f4c590a497acaa5daeb2b9864493760e3b0f15 Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Tue, 15 Sep 2026 11:01:03 +1000 Subject: [PATCH 16/23] The word "of" was hard-coded into intents. This moves its value to definitions.yaml. This also cleans up some really old code that tried to figure out if what was read was a vector or hashmap/hashset. Fixes #739. --- Rules/Languages/en/definitions.yaml | 7 +++ src/definitions.rs | 69 +++++++++++++++++------------ src/infer_intent.rs | 17 ++++--- 3 files changed, 60 insertions(+), 33 deletions(-) diff --git a/Rules/Languages/en/definitions.yaml b/Rules/Languages/en/definitions.yaml index c71e10b89..9a720e7f4 100644 --- a/Rules/Languages/en/definitions.yaml +++ b/Rules/Languages/en/definitions.yaml @@ -363,6 +363,13 @@ "chemistry-concentration": "function= ; concentration: concentration of: the concentration of; end concentration", } + # The connector word to say for functional 'IntentMappings' (in English, "of") + # This is likely the word used for U+2061 in unicode.yaml, but for technical reasons needs to be defined here + # vector of length=1 because scalars not supported +- FunctionApplicationWord: [ + "of", "foo" + ] + # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) - TerseFunctionNames: { "divergence", "del:gradient", "curl" diff --git a/src/definitions.rs b/src/definitions.rs index 489c25b61..b7c45fca9 100644 --- a/src/definitions.rs +++ b/src/definitions.rs @@ -141,9 +141,20 @@ pub fn read_definitions_file(use_speech_defs: bool) -> Result> { let file_path = pref_manager.get_definitions_file(use_speech_defs); let definitions = if use_speech_defs {&SPEECH_DEFINITIONS} else {&BRAILLE_DEFINITIONS}; definitions.with( |defs| defs.borrow_mut().name_to_var_mapping.clear() ); - let mut new_files = vec![file_path.to_path_buf()]; - let mut files_read = read_one_definitions_file(use_speech_defs, file_path).with_context(|| format!("in file '{}", file_path.to_string_lossy()))?; - new_files.append(&mut files_read); + let mut files_read = read_one_definitions_file(use_speech_defs, file_path) + .with_context(|| format!("in file '{}'", file_path.to_string_lossy()))?; + let mut seen: HashSet = HashSet::with_capacity(files_read.len()); + let mut new_files: Vec = Vec::with_capacity(files_read.len()); + for p in files_read.drain(..) { + let canon = match crate::shim_filesystem::canonicalize_shim(&p) { + Ok(c) => c, + Err(_) => p, + }; + let key = canon.to_string_lossy().to_string(); + if seen.insert(key) { + new_files.push(canon); + } + } // merge the contents of `TrigFunctions` into a set that contains all the function names (from `AdditionalFunctionNames`). return definitions.with(|defs| { @@ -228,39 +239,21 @@ fn build_values(definition: &Yaml, use_speech_defs: bool, path: &Path) -> Result return Ok( Some(crate::speech::process_include(path, include_file_name, do_include_fn)?) ); } - let result; - if def_name.starts_with("Numbers") || def_name.ends_with("_vec") { - result = Contains::Vec( Rc::new( RefCell::new( get_vec_values(value.as_vec().unwrap())? ) ) ); + let result = if let Some(vec) = value.as_vec() { + Contains::Vec( Rc::new( RefCell::new( get_vec_values(vec)? ) ) ) } else { - // match value.as_vec() { - // Some(vec) => { - // result = Contains::Set( Rc::new( RefCell::new( get_set_values(vec)? ) ) ); }, - // None => { - // let dict = value.as_hash().ok_or_else(|| anyhow!("definition list value '{}' is not an array or dictionary", yaml_to_type(value)))?; - // result = Contains::Map( Rc::new( RefCell::new( get_map_values(dict) - // .chain_err(||format!("while reading value '{}'", def_name))? ) ) ); - - // }, - // } let dict = value.as_hash().ok_or_else(|| anyhow!("definition list value '{}' is not an array or dictionary", yaml_to_type(value)))?; if dict.is_empty() { - result = Contains::Set( Rc::new( RefCell::new( HashSet::with_capacity(0) ) ) ); + Contains::Set( Rc::new( RefCell::new( HashSet::with_capacity(0) ) ) ) } else { // peak and see if this is a set or a map let (_, entry_value) = dict.iter().next().unwrap(); if entry_value.is_null() { - result = Contains::Set( Rc::new( RefCell::new( get_set_values(dict) - .with_context(||format!("while reading value '{def_name}'"))? ) ) ); + Contains::Set( Rc::new( RefCell::new( get_set_values(dict) + .with_context(||format!("while reading value '{def_name}'"))? ) ) ) } else { - // peak and see if this is a set or a map - let (_, entry_value) = dict.iter().next().unwrap(); - if entry_value.is_null() { - result = Contains::Set( Rc::new( RefCell::new( get_set_values(dict) - .with_context(||format!("while reading value '{def_name}'"))? ) ) ); - } else { - result = Contains::Map( Rc::new( RefCell::new( get_map_values(dict) - .with_context(||format!("while reading value '{def_name}'"))? ) ) ); - } + Contains::Map( Rc::new( RefCell::new( get_map_values(dict) + .with_context(||format!("while reading value '{def_name}'"))? ) ) ) } } }; @@ -369,6 +362,26 @@ mod tests { }); } + #[test] + fn test_vec_not_numbers() { + let function_application_word = r#"[FunctionApplicationWord: ["of"]]"#; + let defs_build_fn = |variable_def_list: &Yaml| { + for variable_def in variable_def_list.as_vec().unwrap() { + if let Err(e) = build_values(variable_def, true, Path::new("")) { + bail!("{}", crate::interface::errors_to_string(&e.context(format!("in file {:?}", function_application_word)))); + } + } + return Ok(vec![]); + }; + compile_rule(function_application_word, defs_build_fn).unwrap(); + SPEECH_DEFINITIONS.with(|defs| { + let defs = defs.borrow(); + let word = defs.get_vec("FunctionApplicationWord"); + assert!(word.is_some()); + assert_eq!(word.unwrap().as_slice(), ["of"]); + }); + } + #[test] fn test_hashmap() { let units = r#"[Units: {"A": "amp", "g": "gram", "m": "meter", "sec": "second"}]"#; diff --git a/src/infer_intent.rs b/src/infer_intent.rs index 4dc0b3d2e..81cbb9933 100644 --- a/src/infer_intent.rs +++ b/src/infer_intent.rs @@ -314,19 +314,26 @@ pub fn intent_function_has_arity_match(intent_name: &str, fixity: &str, arg_coun /// Spoken glue immediately before argument `arg_index` (1-based) when using an arity template. /// Empty when not in a matching arity template (caller uses separator/`of` path instead). pub fn intent_function_glue_before(intent_name: &str, fixity: &str, arg_index: usize, arg_count: usize) -> String { - let Some(after_eq) = intent_mapping_for_fixity(intent_name, fixity) else { return String::new(); }; if !intent_function_is_arity_mode(intent_name, fixity) { return String::new(); } - let Some(words) = intent_function_arity_glue(&after_eq, arg_count) else { return String::new(); }; - // words has arg_count-1 entries for args 1..arg_count-1; last arg is preceded by "of" if arg_index == arg_count { - return "of".to_string(); + return crate::definitions::SPEECH_DEFINITIONS.with(|definitions| { + let definitions = definitions.borrow(); + let word_ref = definitions.get_vec("FunctionApplicationWord"); + if let Some(word) = word_ref && !word.is_empty() { + return word[0].clone(); + } + return String::new(); + }) } + let Some(after_eq) = intent_mapping_for_fixity(intent_name, fixity) else { return String::new(); }; + let Some(words) = intent_function_arity_glue(&after_eq, arg_count) else { return String::new(); }; + // words has arg_count-1 entries for args 1..arg_count-1; last arg is preceded by "of" if arg_index >= 1 && arg_index < arg_count { return words[arg_index - 1].to_string(); } - String::new() + return String::new(); } /// Separator between args when not using an arity template. From a74a6e2d45f1f0ca454091d75d56b4335c9a8e88 Mon Sep 17 00:00:00 2001 From: "U-rainshowers\\neils" Date: Tue, 15 Sep 2026 11:16:18 +1000 Subject: [PATCH 17/23] remove value used in debugging --- Rules/Languages/en/definitions.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Rules/Languages/en/definitions.yaml b/Rules/Languages/en/definitions.yaml index 9a720e7f4..bd3931549 100644 --- a/Rules/Languages/en/definitions.yaml +++ b/Rules/Languages/en/definitions.yaml @@ -366,9 +366,7 @@ # The connector word to say for functional 'IntentMappings' (in English, "of") # This is likely the word used for U+2061 in unicode.yaml, but for technical reasons needs to be defined here # vector of length=1 because scalars not supported -- FunctionApplicationWord: [ - "of", "foo" - ] +- FunctionApplicationWord: ["of"] # Names of functions that in terse mode don't say "of" (or it's equivalent in other languages) - TerseFunctionNames: { From 2622ee5b2ef2bc3294ee50b1a520e2d65e2f3f1f Mon Sep 17 00:00:00 2001 From: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Date: Sat, 19 Sep 2026 11:19:58 +0300 Subject: [PATCH 18/23] Fix audit-ignore rule scoping Adjust the audit-translations parser so `# audit-ignore` markers immediately above a rule apply to that rule, while still supporting existing inline markers inside a rule block. This also clarifies the documented behavior and adds regression tests for leading, inline, and first-item ignore cases. --- PythonScripts/audit_translations/README.md | 3 +- PythonScripts/audit_translations/parsers.py | 17 +++++-- .../audit_translations/tests/test_parsers.py | 47 +++++++++++++++++++ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/PythonScripts/audit_translations/README.md b/PythonScripts/audit_translations/README.md index 8aedf1265..fe391d49b 100644 --- a/PythonScripts/audit_translations/README.md +++ b/PythonScripts/audit_translations/README.md @@ -12,7 +12,8 @@ The tool analyzes rule files to detect the following issues: * **Rule Differences:** Structural changes (match expressions, conditions, variables, or test/replace layout) between the source and target translation. * **Definition Coverage:** Compares literal `definitions.yaml` entries by name and collection kind (`vector`, `set`, or `map`). -Add `# audit-ignore` to a rule block to suppress auditing that rule. +Add `# audit-ignore` on the line immediately before a rule to suppress auditing +that rule. Existing markers inside a rule block are also supported. --- diff --git a/PythonScripts/audit_translations/parsers.py b/PythonScripts/audit_translations/parsers.py index 11dfc5292..a96de8bef 100644 --- a/PythonScripts/audit_translations/parsers.py +++ b/PythonScripts/audit_translations/parsers.py @@ -149,13 +149,20 @@ def format_tag(tag_value: Any) -> str | None: def build_raw_blocks(lines: list[str], starts: list[int]) -> list[str]: - blocks = [] if not starts: - return blocks + return [] + + block_starts = starts.copy() for idx, start in enumerate(starts): - end = starts[idx + 1] if idx + 1 < len(starts) else len(lines) - blocks.append("\n".join(lines[start:end])) - return blocks + lower_bound = starts[idx - 1] + 1 if idx else 0 + while start > lower_bound and (not lines[start - 1].strip() or lines[start - 1].lstrip().startswith("#")): + start -= 1 + block_starts[idx] = start + + return [ + "\n".join(lines[start : block_starts[idx + 1] if idx + 1 < len(block_starts) else len(lines)]) + for idx, start in enumerate(block_starts) + ] def _extract_item_fields(item: Any, is_unicode: bool) -> tuple[str, str | None, str | None, Any] | None: diff --git a/PythonScripts/audit_translations/tests/test_parsers.py b/PythonScripts/audit_translations/tests/test_parsers.py index db7f31e1f..a8d1c36db 100644 --- a/PythonScripts/audit_translations/tests/test_parsers.py +++ b/PythonScripts/audit_translations/tests/test_parsers.py @@ -174,6 +174,53 @@ def test_detects_audit_ignore(self): rules = parse_rules_file(content, data) assert rules[0].audit_ignore + def test_assigns_leading_audit_ignore_to_following_rule(self): + """A marker directly above a rule suppresses that rule, not its neighbour.""" + content = """- name: first + tag: mo + match: "." + +# audit-ignore: the following placeholder intentionally differs +# from the source-language rule. +- name: second + tag: mi + match: "false()" +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert not rules[0].audit_ignore + assert rules[1].audit_ignore + + def test_keeps_audit_ignore_inside_rule(self): + """Existing markers within a rule block remain supported.""" + content = """- name: first + tag: mo + # audit-ignore + match: "." + +- name: second + tag: mi + match: "x" +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert rules[0].audit_ignore + assert not rules[1].audit_ignore + + def test_assigns_file_header_to_first_rule(self): + """A leading marker before the first item is included in its raw block.""" + content = """# audit-ignore +- name: first + tag: mo + match: "." +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert rules[0].audit_ignore + def test_handles_array_tag(self): """Ensure handles array tag.""" content = """- name: multi-tag From a6e65c80560ff302a82b6e821cd8758ce0aace03 Mon Sep 17 00:00:00 2001 From: dtsengchromium Date: Sat, 19 Sep 2026 04:39:38 -0700 Subject: [PATCH 19/23] Add in-memory virtual filesystem support to shim_filesystem (#760) * Add in-memory virtual filesystem support to shim_filesystem * Fix clippy warnings across codebase and tests --- src/prefs.rs | 14 +-- src/shim_filesystem.rs | 105 ++++++++++++++++---- tests/Languages/pt/ClearSpeak/sets.rs | 48 ++++----- tests/Languages/pt/SimpleSpeak/functions.rs | 30 +++--- tests/Languages/pt/escuta.rs | 12 +-- tests/Languages/pt/intent.rs | 25 +++-- tests/Languages/pt/shared.rs | 36 +++---- tests/Languages/pt/units.rs | 36 +++---- 8 files changed, 180 insertions(+), 126 deletions(-) diff --git a/src/prefs.rs b/src/prefs.rs index 4dc51c4bc..89748119f 100644 --- a/src/prefs.rs +++ b/src/prefs.rs @@ -261,17 +261,9 @@ impl PreferenceManager { // Note: if current_dir() also fails, unwrap_or_default yields an empty PathBuf, // and the result may remain relative. #[cfg(not(feature = "include-zip"))] - let rules_dir = match rules_dir.canonicalize() { - Err(_e) => { - if rules_dir.is_absolute() { - rules_dir - } else { - std::env::current_dir() - .unwrap_or_default() - .join(&rules_dir) - } - }, - Ok(rules_dir) => rules_dir, + let rules_dir = match canonicalize_shim(&rules_dir) { + Err(e) => bail!("set_rules_dir: could not canonicalize path {}: {}", rules_dir.display(), e), + Ok(rules_dir) => rules_dir, }; self.set_rules_dir(&rules_dir)?; diff --git a/src/shim_filesystem.rs b/src/shim_filesystem.rs index 14c5b26fb..d539a6300 100644 --- a/src/shim_filesystem.rs +++ b/src/shim_filesystem.rs @@ -281,15 +281,81 @@ cfg_if! { crate::interface::set_rules_dir("Rules").unwrap(); // force reinitialization after the change } } else { + use std::collections::{HashMap, HashSet}; + use std::sync::RwLock; + + static IN_MEMORY_FILES: RwLock>> = RwLock::new(None); + static IN_MEMORY_DIRS: RwLock>> = RwLock::new(None); + + pub fn add_in_memory_file(path: &str, content: &str) { + { + let mut files = IN_MEMORY_FILES.write().unwrap(); + files.get_or_insert_with(HashMap::new).insert(path.to_string(), content.to_string()); + } + + let path_obj = Path::new(path); + { + let mut dirs = IN_MEMORY_DIRS.write().unwrap(); + let dirs = dirs.get_or_insert_with(HashSet::new); + for parent in path_obj.ancestors().skip(1) { + let parent_str = parent.to_str().unwrap_or_default(); + if !parent_str.is_empty() { + dirs.insert(parent_str.to_string()); + } + } + } + } + + pub fn canonicalize_shim(path: &Path) -> std::io::Result { + use std::ffi::OsStr; + let dot = OsStr::new("."); + let dot_dot = OsStr::new(".."); + let mut result = PathBuf::new(); + for part in path.iter() { + if dot == part { + continue; + } else if dot_dot == part { + result.pop(); + } else { + result.push(part); + } + } + return Ok(result); + } + + fn get_in_memory_key(path: &Path) -> String { + canonicalize_shim(path).unwrap_or_else(|_| path.to_path_buf()).to_str().unwrap_or_default().to_string() + } + pub fn is_file_shim(path: &Path) -> bool { + if IN_MEMORY_FILES.read().unwrap().as_ref().is_some_and(|f| f.contains_key(&get_in_memory_key(path))) { + return true; + } return path.is_file(); } pub fn is_dir_shim(path: &Path) -> bool { + if IN_MEMORY_DIRS.read().unwrap().as_ref().is_some_and(|d| d.contains(&get_in_memory_key(path))) { + return true; + } return path.is_dir(); } pub fn find_files_in_dir_that_ends_with_shim(dir: &Path, ending: &str) -> Vec { + let dir_name = get_in_memory_key(dir); + let mut answer = Vec::new(); + if let Some(files) = IN_MEMORY_FILES.read().unwrap().as_ref() { + for file_name in files.keys() { + if file_name.starts_with(&dir_name) && file_name.ends_with(ending) { + let name = Path::new(file_name).file_name().unwrap_or_default().to_str().unwrap_or_default(); + answer.push(name.to_string()); + } + } + } + if !answer.is_empty() { + return answer; + } + match dir.read_dir() { Err(_) => return vec![], // empty Ok(read_dir) => { @@ -340,27 +406,6 @@ cfg_if! { } } - /// Resolves the path to an absolute, canonical form using the OS. - /// If `canonicalize()` fails (e.g., ACCESS_DENIED in containers), falls back to: - /// - returning the path as-is if it is already absolute, - /// - prepending the current working directory if it is relative. - /// Note: the fallback does not resolve symlinks or normalize `..`/`.` segments. - pub fn canonicalize_shim(path: &Path) -> std::io::Result { - match path.canonicalize() { - Ok(p) => Ok(p), - Err(_) => { - if path.is_absolute() { - Ok(path.to_path_buf()) - } else { - // Prepend cwd to make the relative path absolute. - // unwrap_or_default yields an empty PathBuf if cwd is unavailable, - // in which case the returned path will still be relative. - Ok(std::env::current_dir().unwrap_or_default().join(path)) - } - } - } - } - // Tests extract language/braille zips in parallel. During extraction, individual YAML // files can briefly exist in a partially-written state (created/truncated before the // full contents are flushed). Guard both extraction and YAML reads with the same lock @@ -379,6 +424,10 @@ cfg_if! { } pub fn read_to_string_shim(path: &Path) -> Result { + if let Some(content) = IN_MEMORY_FILES.read().unwrap().as_ref().and_then(|f| f.get(&get_in_memory_key(path)).cloned()) { + return Ok(content); + } + let path = match path.canonicalize() { Ok(path) => path, Err(_) => path.to_path_buf(), @@ -490,4 +539,18 @@ mod tests { assert_eq!("test-value", read_to_string_shim(&existing_file).unwrap()); assert!(read_to_string_shim(&test_dir.path().join("does-not-exist.yaml")).is_err()); } + + #[test] + fn in_memory_filesystem_shim() { + add_in_memory_file("virtual/rules/Languages/en/test_Rules.yaml", "key: value"); + let file_path = Path::new("virtual/rules/Languages/en/test_Rules.yaml"); + let dir_path = Path::new("virtual/rules/Languages/en"); + + assert!(is_file_shim(file_path)); + assert!(is_dir_shim(dir_path)); + assert_eq!(read_to_string_shim(file_path).unwrap(), "key: value"); + + let found = find_files_in_dir_that_ends_with_shim(dir_path, "_Rules.yaml"); + assert_eq!(found, vec!["test_Rules.yaml".to_string()]); + } } diff --git a/tests/Languages/pt/ClearSpeak/sets.rs b/tests/Languages/pt/ClearSpeak/sets.rs index ff2ee45cd..87923aeac 100644 --- a/tests/Languages/pt/ClearSpeak/sets.rs +++ b/tests/Languages/pt/ClearSpeak/sets.rs @@ -1,27 +1,27 @@ -/// Testes de conjuntos e pertinência — pt-BR, ClearSpeak e SimpleSpeak. -/// -/// POR QUE ESTE ARQUIVO EXISTE -/// O par ∈ / ∊ falou "é membro de" com as preferências padrão durante duas -/// rodadas inteiras sem ninguém notar, porque o pt não tinha NENHUM teste de -/// pertinência — nem ClearSpeak, nem SimpleSpeak. O ∉ foi corrigido sozinho -/// numa rodada e os outros dois ficaram para trás. Ver ACHADOS 7.8. -/// -/// A invariante que este arquivo trava: **∈ (0x2208) e ∊ (0x220a) são -/// variantes de forma do mesmo símbolo e devem falar igual em todos os ramos** -/// — nas cinco preferências de ClearSpeak_SetMemberSymbol, dentro e fora de -/// um conjunto, nos dois estilos de fala. -/// -/// COMO AS EXPECTATIVAS FORAM ESCRITAS -/// Todas saíram da saída real do motor, nunca de tradução do inglês. O método -/// é o do cabeçalho de tests/Languages/pt/shared.rs: rodar, comparar `left` -/// com `right`, e se o gerado estiver certo em português, copiá-lo; se estiver -/// errado, consertar a REGRA, nunca o teste. -/// -/// Cada teste de pertinência fixa ClearSpeak_SetMemberSymbol explicitamente, -/// inclusive no caso 'Auto'. Isso é de propósito: as preferências de -/// ClearSpeak não são reinicializadas entre testes na mesma thread, então um -/// teste que dependesse do padrão implícito poderia passar ou falhar conforme -/// a ordem de execução. +//! Testes de conjuntos e pertinência — pt-BR, ClearSpeak e SimpleSpeak. +//! +//! POR QUE ESTE ARQUIVO EXISTE +//! O par ∈ / ∊ falou "é membro de" com as preferências padrão durante duas +//! rodadas inteiras sem ninguém notar, porque o pt não tinha NENHUM teste de +//! pertinência — nem ClearSpeak, nem SimpleSpeak. O ∉ foi corrigido sozinho +//! numa rodada e os outros dois ficaram para trás. Ver ACHADOS 7.8. +//! +//! A invariante que este arquivo trava: **∈ (0x2208) e ∊ (0x220a) são +//! variantes de forma do mesmo símbolo e devem falar igual em todos os ramos** +//! — nas cinco preferências de ClearSpeak_SetMemberSymbol, dentro e fora de +//! um conjunto, nos dois estilos de fala. +//! +//! COMO AS EXPECTATIVAS FORAM ESCRITAS +//! Todas saíram da saída real do motor, nunca de tradução do inglês. O método +//! é o do cabeçalho de tests/Languages/pt/shared.rs: rodar, comparar `left` +//! com `right`, e se o gerado estiver certo em português, copiá-lo; se estiver +//! errado, consertar a REGRA, nunca o teste. +//! +//! Cada teste de pertinência fixa ClearSpeak_SetMemberSymbol explicitamente, +//! inclusive no caso 'Auto'. Isso é de propósito: as preferências de +//! ClearSpeak não são reinicializadas entre testes na mesma thread, então um +//! teste que dependesse do padrão implícito poderia passar ou falhar conforme +//! a ordem de execução. use crate::common::*; use anyhow::Result; diff --git a/tests/Languages/pt/SimpleSpeak/functions.rs b/tests/Languages/pt/SimpleSpeak/functions.rs index a656c2da0..1429d1447 100644 --- a/tests/Languages/pt/SimpleSpeak/functions.rs +++ b/tests/Languages/pt/SimpleSpeak/functions.rs @@ -1,18 +1,18 @@ -/// TESTES DO IDIOMA pt — como reconciliar com as regras -/// -/// As strings esperadas abaixo foram escritas para refletir a intenção -/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam -/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira -/// execução. Método do guia oficial de tradutores: -/// 1. rode `cargo test Languages::pt` -/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) -/// 3. se o GERADO estiver correto em português, copie-o para o teste; -/// se estiver errado, conserte a REGRA, nunca o teste. -/// -/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes -/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a -/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). -/// Não herde strings esperadas de es/ sem conferir. +//! TESTES DO IDIOMA pt — como reconciliar com as regras +//! +//! As strings esperadas abaixo foram escritas para refletir a intenção +//! das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +//! PAUSAS inseridas pelo motor e podem divergir levemente na primeira +//! execução. Método do guia oficial de tradutores: +//! 1. rode `cargo test Languages::pt` +//! 2. para cada falha, compare `left` (esperado) com `right` (gerado) +//! 3. se o GERADO estiver correto em português, copie-o para o teste; +//! se estiver errado, conserte a REGRA, nunca o teste. +//! +//! ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +//! que não refletiam as regras (ex.: esperava "logaritmo natural" com a +//! regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +//! Não herde strings esperadas de es/ sem conferir. use crate::common::*; use anyhow::Result; diff --git a/tests/Languages/pt/escuta.rs b/tests/Languages/pt/escuta.rs index 812be28be..661cf4c85 100644 --- a/tests/Languages/pt/escuta.rs +++ b/tests/Languages/pt/escuta.rs @@ -2,12 +2,12 @@ use crate::common::*; fn falar(estilo: &str, verbosidade: &str, mathml: &str) -> String { set_rules_dir(abs_rules_dir_path()).unwrap(); - set_preference("Language", "pt".to_string()).unwrap(); - set_preference("SpeechStyle", estilo.to_string()).unwrap(); - set_preference("Verbosity", verbosidade.to_string()).unwrap(); - set_preference("SpeechOverrides_CapitalLetters", "".to_string()).unwrap(); - set_preference("ClearSpeak_SetMemberSymbol", "Auto".to_string()).unwrap(); - match set_mathml(mathml.to_string()) { + set_preference("Language", "pt").unwrap(); + set_preference("SpeechStyle", estilo).unwrap(); + set_preference("Verbosity", verbosidade).unwrap(); + set_preference("SpeechOverrides_CapitalLetters", "").unwrap(); + set_preference("ClearSpeak_SetMemberSymbol", "Auto").unwrap(); + match set_mathml(mathml) { Ok(_) => match get_spoken_text() { Ok(fala) => regex::Regex::new(r" +").unwrap().replace_all(&fala, " ").to_string(), Err(e) => format!("[ERRO ao falar: {}]", errors_to_string(&e)), diff --git a/tests/Languages/pt/intent.rs b/tests/Languages/pt/intent.rs index df164bc1b..cd43e0251 100644 --- a/tests/Languages/pt/intent.rs +++ b/tests/Languages/pt/intent.rs @@ -1,17 +1,16 @@ -/// TESTES DO IDIOMA pt — como reconciliar com as regras -/// -/// As strings esperadas abaixo foram escritas para refletir a intenção -/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam -/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira -/// execução. Método do guia oficial de tradutores: -/// 1. rode `cargo test Languages::pt` -/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) -/// 3. se o GERADO estiver correto em português, copie-o para o teste; -/// se estiver errado, conserte a REGRA, nunca o teste. -/// +//! TESTES DO IDIOMA pt — como reconciliar com as regras +//! +//! As strings esperadas abaixo foram escritas para refletir a intenção +//! das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +//! PAUSAS inseridas pelo motor e podem divergir levemente na primeira +//! execução. Método do guia oficial de tradutores: +//! 1. rode `cargo test Languages::pt` +//! 2. para cada falha, compare `left` (esperado) com `right` (gerado) +//! 3. se o GERADO estiver correto em português, copie-o para o teste; +//! se estiver errado, conserte a REGRA, nunca o teste. -/// Tests for rules shared between various speech styles: -/// * this has tests focused on the various alphabets +// Tests for rules shared between various speech styles: +// * this has tests focused on the various alphabets use crate::common::*; use anyhow::Result; diff --git a/tests/Languages/pt/shared.rs b/tests/Languages/pt/shared.rs index cf860236b..50a28d49a 100644 --- a/tests/Languages/pt/shared.rs +++ b/tests/Languages/pt/shared.rs @@ -1,21 +1,21 @@ -/// TESTES DO IDIOMA pt — como reconciliar com as regras -/// -/// As strings esperadas abaixo foram escritas para refletir a intenção -/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam -/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira -/// execução. Método do guia oficial de tradutores: -/// 1. rode `cargo test Languages::pt` -/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) -/// 3. se o GERADO estiver correto em português, copie-o para o teste; -/// se estiver errado, conserte a REGRA, nunca o teste. -/// -/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes -/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a -/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). -/// Não herde strings esperadas de es/ sem conferir. - -/// Tests for rules shared between various speech styles: -/// * modified var +//! TESTES DO IDIOMA pt — como reconciliar com as regras +//! +//! As strings esperadas abaixo foram escritas para refletir a intenção +//! das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +//! PAUSAS inseridas pelo motor e podem divergir levemente na primeira +//! execução. Método do guia oficial de tradutores: +//! 1. rode `cargo test Languages::pt` +//! 2. para cada falha, compare `left` (esperado) com `right` (gerado) +//! 3. se o GERADO estiver correto em português, copie-o para o teste; +//! se estiver errado, conserte a REGRA, nunca o teste. +//! +//! ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +//! que não refletiam as regras (ex.: esperava "logaritmo natural" com a +//! regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +//! Não herde strings esperadas de es/ sem conferir. + +// Tests for rules shared between various speech styles: +// * modified var use crate::common::*; use anyhow::Result; diff --git a/tests/Languages/pt/units.rs b/tests/Languages/pt/units.rs index 47bd73056..cf0048f0d 100644 --- a/tests/Languages/pt/units.rs +++ b/tests/Languages/pt/units.rs @@ -1,21 +1,21 @@ -/// TESTES DO IDIOMA pt — como reconciliar com as regras -/// -/// As strings esperadas abaixo foram escritas para refletir a intenção -/// das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam -/// PAUSAS inseridas pelo motor e podem divergir levemente na primeira -/// execução. Método do guia oficial de tradutores: -/// 1. rode `cargo test Languages::pt` -/// 2. para cada falha, compare `left` (esperado) com `right` (gerado) -/// 3. se o GERADO estiver correto em português, copie-o para o teste; -/// se estiver errado, conserte a REGRA, nunca o teste. -/// -/// ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes -/// que não refletiam as regras (ex.: esperava "logaritmo natural" com a -/// regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). -/// Não herde strings esperadas de es/ sem conferir. - -/// Tests for rules shared between various speech styles: -/// * modified var +//! TESTES DO IDIOMA pt — como reconciliar com as regras +//! +//! As strings esperadas abaixo foram escritas para refletir a intenção +//! das regras em Rules/Languages/pt. Vírgulas e ponto-e-vírgula marcam +//! PAUSAS inseridas pelo motor e podem divergir levemente na primeira +//! execução. Método do guia oficial de tradutores: +//! 1. rode `cargo test Languages::pt` +//! 2. para cada falha, compare `left` (esperado) com `right` (gerado) +//! 3. se o GERADO estiver correto em português, copie-o para o teste; +//! se estiver errado, conserte a REGRA, nunca o teste. +//! +//! ATENÇÃO ao histórico: o arquivo espanhol equivalente continha testes +//! que não refletiam as regras (ex.: esperava "logaritmo natural" com a +//! regra dizendo "natural log") e dano de busca-e-troca (ex.: "eigh"→"8"). +//! Não herde strings esperadas de es/ sem conferir. + +// Tests for rules shared between various speech styles: +// * modified var use crate::common::*; use anyhow::Result; From 49de6d67c802f0f516cef11eef8f2528339f2a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Sat, 19 Sep 2026 13:45:17 +0200 Subject: [PATCH 20/23] Refactor: Simplify match return logic and improve string interpolation readability (#774) --- src/bin/package_rules.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bin/package_rules.rs b/src/bin/package_rules.rs index 900af235f..971e95175 100644 --- a/src/bin/package_rules.rs +++ b/src/bin/package_rules.rs @@ -37,7 +37,7 @@ fn main() -> ExitCode { return ExitCode::from(1); } - match package_rules( + return match package_rules( &cli.source, &cli.output, cli.minimize, @@ -45,15 +45,15 @@ fn main() -> ExitCode { ) { Ok(minimized) => { let label = if cli.minimize { "minimized" } else { "standard" }; - println!("Created {} archive: {}", label, cli.output.display()); + println!("Created {label} archive: {}", cli.output.display()); if cli.minimize { - println!(" minimized YAML files: {}", minimized); + println!(" minimized YAML files: {minimized}"); } - return ExitCode::SUCCESS; + ExitCode::SUCCESS } Err(e) => { - eprintln!("error: {}", e); - return ExitCode::from(1); + eprintln!("error: {e}"); + ExitCode::from(1) } } } From 015c595ef7399d8921c49fa2f10a19191409a208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yasunori=20Morishima=EF=BC=88=E7=9B=9B=E5=B3=B6=E5=BA=B7?= =?UTF-8?q?=E5=BE=B3=EF=BC=89?= Date: Sat, 19 Sep 2026 23:08:24 +0900 Subject: [PATCH 21/23] ja: the phrases that were carried over word for word MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each of these was translated token by token, in English order, so the Japanese carries the words and not the meaning. Where a phrase is split across several `t:` entries the fix moves material between them, which is what the merged navigation work (#752, #773) already did; the en `phrase(...)` comments are left alone. {x | x > 2} 集合 すべて x そのようなこと x は 大なり 2 -> 集合 すべての x ただし x は 大なり 2 そのようなこと is "such a thing": it translates the words of "such that" and none of its work, which is to attach a condition to what was just named. ただし is what Japanese mathematical prose uses. 集合 stays in front of the variable rather than moving to the head-noun position Japanese would normally give it, because in a speech stream it tells the listener what they are about to hear, and the first argument can be long ({x ∈ ℤ : x > 5}). P(A | B) A 与えられた B -> A 条件は B 与えられた is the past participle "given", which in Japanese modifies the noun after it, so B was being described rather than named as the condition. a labelled row 行 1 ラベルを使って 第1式 -> 行 1 ラベルは 第1式 ラベルを使って is "using a label", which says the row does something with one. The label is simply what the row is called. f|_a^b f 評価される b 同じ式が評価されるマイナス a -> f 次の点で評価 b マイナス 同じ式を次の点で評価 a 評価される is the passive "is evaluated" with nothing to say where, and the minus came last, so the subtraction arrived after the thing subtracted. round() ラウンド値 ("round" in katakana + 値) -> 丸めた値 fenced-group フェンスグループ, an English term in katakana -> 括弧のまとまり Each phrase is swept across every file that carries it, including the sibling branches: unicode.yaml has two more `given`s, general.yaml a second `evaluated at`, and definitions.yaml the intent mappings for such-that, given and conditional-probability. The copy of `such that` in unicode-full.yaml is left alone, since that file is waiting on a MathPlayer seed. audit-translations ja: untranslated 3415 -> 3400, which is exactly the number of rule lines promoted; rule differences unchanged at 30; missing, extra and definition counts unchanged at 0. definitions.yaml entries carry no case marker, so they do not move that count. Tests: five new in ja.rs and one updated, since set_builder_member_symbol had pinned the old reading. Reverting the readings and nothing else turns exactly those six red. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01XzNYYoiVRzKGnDEWTJnuHh --- Rules/Languages/ja/ClearSpeak_Rules.yaml | 10 ++-- Rules/Languages/ja/SharedRules/default.yaml | 2 +- Rules/Languages/ja/SharedRules/general.yaml | 8 +-- Rules/Languages/ja/SimpleSpeak_Rules.yaml | 4 +- Rules/Languages/ja/definitions.yaml | 10 ++-- Rules/Languages/ja/unicode.yaml | 6 +- tests/Languages/ja/ja.rs | 61 ++++++++++++++++++++- 7 files changed, 79 insertions(+), 22 deletions(-) diff --git a/Rules/Languages/ja/ClearSpeak_Rules.yaml b/Rules/Languages/ja/ClearSpeak_Rules.yaml index c1bb4683e..d3f811bf1 100644 --- a/Rules/Languages/ja/ClearSpeak_Rules.yaml +++ b/Rules/Languages/ja/ClearSpeak_Rules.yaml @@ -487,12 +487,12 @@ - test: if: "$Verbosity!='Terse'" then: [t: ""] # phrase('the' set of all integers) - - t: "集合" # phrase(this is a 'set of' numbers) + - T: "集合" # phrase(this is a 'set of' numbers) - test: if: "$ClearSpeak_Sets != 'woAll'" - then: [t: "すべて"] # phrase(the set of 'all' integers) + then: [T: "すべての"] # phrase(the set of 'all' integers) - x: "*[1]/*[1]" - - t: "そのようなこと" # phrase(the set S 'such that' x is less than y) + - T: "ただし" # phrase(the set S 'such that' x is less than y) - x: "*[1]/*[3]" else: - test: @@ -572,7 +572,7 @@ - test: if: ".[self::m:mlabeledtr]" then: - - t: "ラベルを使って" # phrase(the line 'with label' first equation) + - T: "ラベルは" # phrase(the line 'with label' first equation) - x: "*[1]/*" - pause: short - pause: medium @@ -658,7 +658,7 @@ - test: if: "self::m:mlabeledtr" then: - - t: "ラベルを使って" # phrase(the diagram is complete 'with label') + - T: "ラベルは" # phrase(the diagram is complete 'with label') - x: "*[1]/*" - test: - if: "$ClearSpeak_MultiLineLabel='None'" diff --git a/Rules/Languages/ja/SharedRules/default.yaml b/Rules/Languages/ja/SharedRules/default.yaml index 185756e97..df3e03cf9 100644 --- a/Rules/Languages/ja/SharedRules/default.yaml +++ b/Rules/Languages/ja/SharedRules/default.yaml @@ -456,7 +456,7 @@ - test: if: "self::m:mlabeledtr" then: - - t: "ラベルを使って" # phrase(the line 'with label' first equation) + - T: "ラベルは" # phrase(the line 'with label' first equation) - x: "*[1]/*" - pause: short - pause: medium diff --git a/Rules/Languages/ja/SharedRules/general.yaml b/Rules/Languages/ja/SharedRules/general.yaml index 955aa585d..74e5997de 100644 --- a/Rules/Languages/ja/SharedRules/general.yaml +++ b/Rules/Languages/ja/SharedRules/general.yaml @@ -89,7 +89,7 @@ replace: - x: "*[1]" - pause: auto - - t: "評価される" # phrase(results were 'evaluated at' a given point) + - T: "次の点で評価" # phrase(results were 'evaluated at' a given point) - pause: auto - x: "*[2]" @@ -99,10 +99,10 @@ replace: - x: "*[1]" - pause: auto - - t: "評価される" # phrase(results were 'evaluated at' this point) + - T: "次の点で評価" # phrase(results were 'evaluated at' this point) - pause: auto - x: "*[3]" - - t: "同じ式が評価されるマイナス" # phrase(this result is 'minus the same expression evaluated at' an earlier point) + - T: "マイナス 同じ式を次の点で評価" # phrase(this result is 'minus the same expression evaluated at' an earlier point) - x: "*[2]" - name: permutation # audit-ignore @@ -530,7 +530,7 @@ - test: if: "self::m:mlabeledtr" then: - - t: "ラベルを使って" # phrase(the diagram is complete 'with label') + - T: "ラベルは" # phrase(the diagram is complete 'with label') - x: "*[1]/*" - test: if: "not(contains(@data-intent-property, ':continued-row:'))" diff --git a/Rules/Languages/ja/SimpleSpeak_Rules.yaml b/Rules/Languages/ja/SimpleSpeak_Rules.yaml index 237ac9e45..4aa27a290 100644 --- a/Rules/Languages/ja/SimpleSpeak_Rules.yaml +++ b/Rules/Languages/ja/SimpleSpeak_Rules.yaml @@ -284,9 +284,9 @@ - test: if: "$Verbosity!='Terse'" then: [t: ""] # phrase('the' set of all integers) - - t: "すべての集合" # phrase(the 'set of all' positive integers less than 10) + - T: "集合 すべての" # phrase(the 'set of all' positive integers less than 10) - x: "*[1]/*[1]" - - t: "そのようなこと" # phrase(x 'such that' x is less than y) + - T: "ただし" # phrase(x 'such that' x is less than y) - x: "*[1]/*[3]" else: - test: diff --git a/Rules/Languages/ja/definitions.yaml b/Rules/Languages/ja/definitions.yaml index 95f9c262b..fd65d4c04 100644 --- a/Rules/Languages/ja/definitions.yaml +++ b/Rules/Languages/ja/definitions.yaml @@ -104,7 +104,7 @@ "coordinate":"function=座標", "floor":"function=床関数", "ceiling":"function=天井関数", - "round":"function=ラウンド値", + "round":"function=丸めた値", "fractional-part":"function=小数部分", @@ -175,7 +175,7 @@ "median":"function=中央値", "mode":"function=最頻値", - "conditional-probability":"function=確率 | 与えられた", + "conditional-probability":"function=確率 | 条件は", ### Linear Algebra @@ -219,7 +219,7 @@ "time-separator":"infix=", ### General Concepts - "fenced-group":"function=フェンスグループ", # appears both under general concepts and grouping + "fenced-group":"function=括弧のまとまり", # appears both under general concepts and grouping # NOTE: in site mentions "the pair x and y", due to being defined as function, needs the "of" keyword "ordered-pair": "function=ペア |", # Needs to be tested # Simple last arg: "x sub k". Complex: "… end sub" (terse/medium) / "end subscript" (verbose) via infix-intent. @@ -285,7 +285,7 @@ "equals": "infix=イコール", "equivalent-to": "infix=と同等の", "evaluates-to": "infix=評価する", - "given": "infix=与えられた", + "given": "infix=条件は", "greater-than": "infix=大なり", "greater-than-or-equal-to": "infix=大なり オア イコール", "identically-equals": "infix=恒等的に等しい", @@ -320,7 +320,7 @@ "subset": "infix=部分集合オブ", "subset-or-equal": "infix=部分集合オブ オア イコール", "succeeds": "infix=に後続する", - "such-that": "infix=そのようなこと", + "such-that": "infix=ただし", "superset": "infix=上位集合オブ", "superset-or-equal": "infix=上位集合オブ オア イコール", "tilde": "infix=チルダ", diff --git a/Rules/Languages/ja/unicode.yaml b/Rules/Languages/ja/unicode.yaml index 2fb44f2da..521514cc2 100644 --- a/Rules/Languages/ja/unicode.yaml +++ b/Rules/Languages/ja/unicode.yaml @@ -186,7 +186,7 @@ - else_if: "$SpeechStyle != 'ClearSpeak'" then_test: - if: "$DefaultToGiven" - then: [t: "与えられた"] + then: [T: "条件は"] - 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: "割り切る"] @@ -194,9 +194,9 @@ - else_if: "not(preceding-sibling::*) or not(following-sibling::*)" then: [t: "縦線"] - else_if: "$ClearSpeak_VerticalLine = 'SuchThat'" - then: [t: "そのようなこと"] + then: [T: "ただし"] - else_if: "$ClearSpeak_VerticalLine = 'Given' or $DefaultToGiven" - then: [t: "与えられた"] + then: [T: "条件は"] - else: [t: "割り切る"] - "}": # 0x7d diff --git a/tests/Languages/ja/ja.rs b/tests/Languages/ja/ja.rs index 3be2103bf..c8c4bc10b 100644 --- a/tests/Languages/ja/ja.rs +++ b/tests/Languages/ja/ja.rs @@ -302,9 +302,9 @@ fn set_builder_member_symbol() -> Result<()> { "{{x{ch}ℤ: x>5}}" ); test_ClearSpeak("ja", "ClearSpeak_SetMemberSymbol", "In", &expr, - "集合 すべて x イン 整数 そのようなこと x は 大なり 5")?; + "集合 すべての x イン 整数 ただし x は 大なり 5")?; test_ClearSpeak("ja", "ClearSpeak_SetMemberSymbol", "Element", &expr, - "集合 すべて x 要素オブ 整数 そのようなこと x は 大なり 5")?; + "集合 すべての x 要素オブ 整数 ただし x は 大なり 5")?; } return Ok(()); } @@ -1005,3 +1005,60 @@ fn coordinate_point() -> Result<()> { test("ja", "ClearSpeak", coordinate, "点 1 コンマ 2")?; return Ok(()); } + +/// そのようなこと is "such a thing": it translates the words of "such that" and +/// none of its work, which is to attach a condition to what was just named. +/// ただし is the word Japanese mathematical prose uses for that. 集合 stays in +/// front of the variable, where a listener learns what they are hearing before +/// the first argument runs long. +#[test] +fn set_builder_says_the_condition_is_a_condition() -> Result<()> { + let expr = "{x|x>2}"; + test("ja", "SimpleSpeak", expr, "集合 すべての x ただし x は 大なり 2")?; + return Ok(()); +} + +/// 与えられた is the past participle "given", which in Japanese modifies the noun +/// after it -- so P(A | B) came out as "A, given B" with B as the thing being +/// described rather than the condition. +#[test] +fn the_vertical_line_names_the_condition() -> Result<()> { + let expr = "1|2"; + test_ClearSpeak("ja", "ClearSpeak_VerticalLine", "Given", expr, "1 条件は 2")?; + return Ok(()); +} + +/// ラベルを使って is "using a label", which says the row does something with a +/// label. The label is simply what the row is called. +#[test] +fn a_labelled_row_names_its_label() -> Result<()> { + let expr = "1x"; + test("ja", "ClearSpeak", expr, "array オブ; 行 1 ラベルは 1; 列 1; x")?; + return Ok(()); +} + +/// 評価される is the passive "is evaluated", with nothing to say what it is +/// evaluated at, and 同じ式が評価されるマイナス put the minus last, so the +/// subtraction arrived after the thing being subtracted. +#[test] +fn an_evaluation_bar_says_where_it_is_evaluated() -> Result<()> { + let two = "f1"; + test("ja", "ClearSpeak", two, "f 次の点で評価 1")?; + let three = "f12"; + test("ja", "ClearSpeak", three, "f 次の点で評価 2 マイナス 同じ式を次の点で評価 1")?; + return Ok(()); +} + +/// ラウンド値 is "round" in katakana with 値 stuck on the end, and +/// フェンスグループ is an English term that has no Japanese meaning at all. +#[test] +fn the_function_names_are_japanese_words() -> Result<()> { + for (intent, expected) in [ + ("round", "丸めた値 オブ x"), + ("fenced-group", "括弧のまとまり オブ x"), + ] { + let expr = format!("x"); + test("ja", "ClearSpeak", &expr, expected)?; + } + return Ok(()); +} From 5c8117e99041f74aeb4f322593ec11d1e3766d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwisz?= Date: Sun, 20 Sep 2026 09:21:16 +0200 Subject: [PATCH 22/23] de, el: use $CommandOffset instead of string-length($Prefix) in navigate.yaml (#766) Ports ec36e057 to the two remaining languages that still cut the direction word out of $NavCommand with the length of the SPOKEN prefix. $NavCommand is always English (ZoomIn, MoveNext), while $Prefix is the translated word, so string-length($Prefix)+1 only lands on the right offset while the prefix happens to match the English stem. In de and el the prefixes are still the untranslated zoom/move/read/describe, so all 18 branches work today by coincidence; localizing those strings -- the obvious thing for a translator to do -- silently kills every direction word. This is a no-op right now, which is exactly why it is a good time to do it: substring($NavCommand, $CommandOffset) returns the same value as before for every one of the 15 navigation commands with the current prefixes. Verified on the engine, not only on paper: Languages::de is 209/209 both with and without this change. Greek has no tests at all (tests/Languages/el exists but is not declared in tests/languages.rs), so el rests on the structural check: offsets and the list of 9 branches are now identical to en. Refs #740. --- Rules/Languages/de/navigate.yaml | 26 +++++++++++++------------- Rules/Languages/el/navigate.yaml | 26 +++++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Rules/Languages/de/navigate.yaml b/Rules/Languages/de/navigate.yaml index 4ff42e67a..0b5ea83e8 100644 --- a/Rules/Languages/de/navigate.yaml +++ b/Rules/Languages/de/navigate.yaml @@ -54,37 +54,37 @@ else: - test: - if: "starts-with($NavCommand, 'Zoom')" - then: [set_variables: [Prefix: "'zoom'"]] # phrase('zoom' in to see more details) + then: [set_variables: [Prefix: "'zoom'", CommandOffset: "5"]] # phrase('zoom' in to see more details) - else_if: "starts-with($NavCommand, 'Move')" - then: [set_variables: [Prefix: "'move'"]] # phrase('move' to next entry in table) + then: [set_variables: [Prefix: "'move'", CommandOffset: "5"]] # phrase('move' to next entry in table) - else_if: "starts-with($NavCommand, 'Read')" - then: [set_variables: [Prefix: "'read'"]] # phrase('read' to next entry in table) + then: [set_variables: [Prefix: "'read'", CommandOffset: "5"]] # phrase('read' to next entry in table) - else_if: "starts-with($NavCommand, 'Describe')" - then: [set_variables: [Prefix: "'describe'"]] # phrase('describe' to next entry in table) + then: [set_variables: [Prefix: "'describe'", CommandOffset: "9"]] # phrase('describe' to next entry in table) - test: if: "$Prefix != ''" then: - x: "$Prefix" - test: - - if: "substring($NavCommand, string-length($Prefix)+1) = 'In'" + - if: "substring($NavCommand, $CommandOffset) = 'In'" then: [T: "in"] # phrase(zoom 'in' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'InAll'" + - 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: "den ganzen weg"] # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Out'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Out'" then: [T: "raus"] # phrase(zoom 'out' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'OutAll'" + - 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: "den ganzen weg"] # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Next'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Next'" then: [T: "rechten"] # phrase(move to the 'right') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Previous'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Previous'" then: [T: "linken"] # phrase(move to the 'left') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Current'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Current'" then: [T: "aktuelle"] # phrase(who is the 'current' president) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineStart'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineStart'" then: [T: "start der linie"] # phrase(move 'to start of line') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineEnd'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineEnd'" then: [T: "bis zum ende der linie"] # phrase(move 'to end of line') - pause: "medium" - set_variables: [MatchCounter: "1"] diff --git a/Rules/Languages/el/navigate.yaml b/Rules/Languages/el/navigate.yaml index 2466efd8c..1cbfcc6f5 100644 --- a/Rules/Languages/el/navigate.yaml +++ b/Rules/Languages/el/navigate.yaml @@ -54,37 +54,37 @@ else: - test: - if: "starts-with($NavCommand, 'Zoom')" - then: [set_variables: [Prefix: "'zoom'"]] # phrase('zoom' in to see more details) + then: [set_variables: [Prefix: "'zoom'", CommandOffset: "5"]] # phrase('zoom' in to see more details) - else_if: "starts-with($NavCommand, 'Move')" - then: [set_variables: [Prefix: "'move'"]] # phrase('move' to next entry in table) + then: [set_variables: [Prefix: "'move'", CommandOffset: "5"]] # phrase('move' to next entry in table) - else_if: "starts-with($NavCommand, 'Read')" - then: [set_variables: [Prefix: "'read'"]] # phrase('read' to next entry in table) + then: [set_variables: [Prefix: "'read'", CommandOffset: "5"]] # phrase('read' to next entry in table) - else_if: "starts-with($NavCommand, 'Describe')" - then: [set_variables: [Prefix: "'describe'"]] # phrase('describe' to next entry in table) + then: [set_variables: [Prefix: "'describe'", CommandOffset: "9"]] # phrase('describe' to next entry in table) - test: if: "$Prefix != ''" then: - x: "$Prefix" - test: - - if: "substring($NavCommand, string-length($Prefix)+1) = 'In'" + - if: "substring($NavCommand, $CommandOffset) = 'In'" then: [t: "εντός"] # phrase(zoom 'in' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'InAll'" + - 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: "\uF8FEed πλήρως"] #theodora. check # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Out'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Out'" then: [t: "εκτός"] # phrase(zoom 'out' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'OutAll'" + - 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: "\uF8FEed πλήρως"] #theodora. check # phrase(zoom 'out all the way' to see more details) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Next'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Next'" then: [t: "δεξιά"] # phrase(move to the 'right') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Previous'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Previous'" then: [t: "αριστερά"] # phrase(move to the 'left') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'Current'" + - else_if: "substring($NavCommand, $CommandOffset) = 'Current'" then: [t: "τρέχον"] # phrase(who is the 'current' president) - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineStart'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineStart'" then: [t: "στην αρχή της γραμμής"] # phrase(move 'to start of line') - - else_if: "substring($NavCommand, string-length($Prefix)+1) = 'LineEnd'" + - else_if: "substring($NavCommand, $CommandOffset) = 'LineEnd'" then: [t: "στο τέλος της γραμμής"] # phrase(move 'to end of line') - pause: "medium" - set_variables: [MatchCounter: "$MatchCounter + 1"] From 600180b4291f0f5a5797d443e84dfb41337d29d5 Mon Sep 17 00:00:00 2001 From: Danil <81031453+Kostenkov-2021@users.noreply.github.com> Date: Sun, 20 Sep 2026 10:41:20 +0300 Subject: [PATCH 23/23] Fix audit-ignore parsing around comments This change fixes how audit_translations YAML blocks are split when comments or blank lines appear around list items. It keeps introductory comments with the correct rule, preserves explicit audit-ignore markers inside a rule, and avoids incorrectly attaching comment-only lines to neighboring items. --- PythonScripts/audit_translations/README.md | 4 +- PythonScripts/audit_translations/parsers.py | 35 ++++++++++++--- .../audit_translations/tests/test_parsers.py | 44 +++++++++++++++++-- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/PythonScripts/audit_translations/README.md b/PythonScripts/audit_translations/README.md index fe391d49b..241a500d2 100644 --- a/PythonScripts/audit_translations/README.md +++ b/PythonScripts/audit_translations/README.md @@ -12,8 +12,8 @@ The tool analyzes rule files to detect the following issues: * **Rule Differences:** Structural changes (match expressions, conditions, variables, or test/replace layout) between the source and target translation. * **Definition Coverage:** Compares literal `definitions.yaml` entries by name and collection kind (`vector`, `set`, or `map`). -Add `# audit-ignore` on the line immediately before a rule to suppress auditing -that rule. Existing markers inside a rule block are also supported. +After a blank line, add `# audit-ignore` immediately before a rule to suppress +auditing that rule. Existing markers inside a rule block are also supported. --- diff --git a/PythonScripts/audit_translations/parsers.py b/PythonScripts/audit_translations/parsers.py index a96de8bef..bcbdd0027 100644 --- a/PythonScripts/audit_translations/parsers.py +++ b/PythonScripts/audit_translations/parsers.py @@ -154,15 +154,36 @@ def build_raw_blocks(lines: list[str], starts: list[int]) -> list[str]: block_starts = starts.copy() for idx, start in enumerate(starts): - lower_bound = starts[idx - 1] + 1 if idx else 0 - while start > lower_bound and (not lines[start - 1].strip() or lines[start - 1].lstrip().startswith("#")): + if idx == 0: + while start > 0 and (not lines[start - 1].strip() or lines[start - 1].lstrip().startswith("#")): + start -= 1 + block_starts[idx] = start + continue + + lower_bound = starts[idx - 1] + 1 + dash_line = re.fullmatch(r"\s*-\s*(?:#.*)?", lines[start - 1]) if start > lower_bound else None + if dash_line: start -= 1 - block_starts[idx] = start + block_starts[idx] = start + continue - return [ - "\n".join(lines[start : block_starts[idx + 1] if idx + 1 < len(block_starts) else len(lines)]) - for idx, start in enumerate(block_starts) - ] + comment_start = start + while comment_start > lower_bound and lines[comment_start - 1].lstrip().startswith("#"): + comment_start -= 1 + + # A separating blank makes the comment run introductory text for this + # item. Without one, leave the run with the preceding rule. + if comment_start > lower_bound and not lines[comment_start - 1].strip(): + start = comment_start - 1 + while start > lower_bound and not lines[start - 1].strip(): + start -= 1 + block_starts[idx] = start + + blocks = [] + for idx, start in enumerate(block_starts): + end = block_starts[idx + 1] if idx + 1 < len(block_starts) else len(lines) + blocks.append("\n".join(lines[start:end])) + return blocks def _extract_item_fields(item: Any, is_unicode: bool) -> tuple[str, str | None, str | None, Any] | None: diff --git a/PythonScripts/audit_translations/tests/test_parsers.py b/PythonScripts/audit_translations/tests/test_parsers.py index a8d1c36db..6714f3581 100644 --- a/PythonScripts/audit_translations/tests/test_parsers.py +++ b/PythonScripts/audit_translations/tests/test_parsers.py @@ -176,7 +176,8 @@ def test_detects_audit_ignore(self): def test_assigns_leading_audit_ignore_to_following_rule(self): """A marker directly above a rule suppresses that rule, not its neighbour.""" - content = """- name: first + content = """ +- name: first tag: mo match: "." @@ -194,7 +195,8 @@ def test_assigns_leading_audit_ignore_to_following_rule(self): def test_keeps_audit_ignore_inside_rule(self): """Existing markers within a rule block remain supported.""" - content = """- name: first + content = """ +- name: first tag: mo # audit-ignore match: "." @@ -209,9 +211,45 @@ def test_keeps_audit_ignore_inside_rule(self): assert rules[0].audit_ignore assert not rules[1].audit_ignore + def test_keeps_touching_comment_with_preceding_rule(self): + """A comment without a separating blank remains part of the preceding rule.""" + content = """ +- name: first + tag: mo + match: "." +# audit-ignore: this comment documents the first rule +- name: second + tag: mi + match: "x" +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert rules[0].audit_ignore + assert not rules[1].audit_ignore + + def test_includes_comment_on_item_dash_line(self): + """A comment attached to an item's dash belongs to that item.""" + content = """ +- name: first + tag: mo + match: "." + +- # second rule introduction + name: second + tag: mi + match: "x" +""" + yaml = YAML() + data = yaml.load(content) + rules = parse_rules_file(content, data) + assert "second rule introduction" not in rules[0].raw_content + assert "second rule introduction" in rules[1].raw_content + def test_assigns_file_header_to_first_rule(self): """A leading marker before the first item is included in its raw block.""" - content = """# audit-ignore + content = """ +# audit-ignore - name: first tag: mo match: "."