diff --git a/Rules/Braille/Russian/Russian_Rules.yaml b/Rules/Braille/Russian/Russian_Rules.yaml index 4ab7154a..a691101e 100644 --- a/Rules/Braille/Russian/Russian_Rules.yaml +++ b/Rules/Braille/Russian/Russian_Rules.yaml @@ -93,6 +93,17 @@ - x: "*[1]" - t: "⠹" +- + name: nested-fraction + tag: mfrac + match: "parent::m:mfrac" + replace: + - t: "⠆" + - x: "*[1]" + - t: "⠀⠳" + - x: "*[2]" + - t: "⠰" + - name: simple-numeric tag: mfrac @@ -267,6 +278,41 @@ - t: "#" - x: "*[1]" +- + name: signed-integer-number + tag: [msub, munder] + match: "*[2][self::m:mn and (substring(., 1, 1)='-' or substring(., 1, 1)='−' or substring(., 1, 1)='+') and translate(substring(., 2), '0123456789', '')='']" + replace: + - x: "*[1]" + - test: + if: "self::m:munder" + then: [t: "⠨⠡"] + else: [t: "⠡"] + - test: + if: "substring(*[2], 1, 1)='+'" + then: [t: "⠖"] + else: [t: "⠤"] + - x: "BrailleChars(translate(substring(*[2], 2), '0123456789', '\ue000\ue001\ue002\ue003\ue004\ue005\ue006\ue007\ue008\ue009'), 'Russian')" + +- + name: signed-integer + tag: [msub, munder] + match: + - "*[2][self::m:mrow and count(*)=2 and" + - " *[1][self::m:mo][.='-' or .='−' or .='+'] and" + - " *[2][self::m:mn and translate(., '0123456789', '')='']]" + replace: + - x: "*[1]" + - test: + if: "self::m:munder" + then: [t: "⠨⠡"] + else: [t: "⠡"] + - test: + if: "*[2]/*[1][.='+']" + then: [t: "⠖"] + else: [t: "⠤"] + - x: "BrailleChars(translate(*[2]/*[2], '0123456789', '\ue000\ue001\ue002\ue003\ue004\ue005\ue006\ue007\ue008\ue009'), 'Russian')" + - name: integer tag: [msub, munder] @@ -289,9 +335,47 @@ if: "self::m:munder" then: [t: "⠨⠡"] else: [t: "⠡"] + - test: + if: "*[2][self::m:mrow[m:mo[.='+']] or self::m:mfrac]" + then: [t: "⠐"] - x: "*[2]" - t: "⠱" +- + name: signed-integer-number + tag: [msup, mover] + match: "*[2][self::m:mn and (substring(., 1, 1)='-' or substring(., 1, 1)='−' or substring(., 1, 1)='+') and translate(substring(., 2), '0123456789', '')='']" + replace: + - x: "*[1]" + - test: + if: "self::m:mover" + then: [t: "⠨⠌"] + else: [t: "⠌"] + - test: + if: "substring(*[2], 1, 1)='+'" + then: [t: "⠖"] + else: [t: "⠤"] + - x: "BrailleChars(translate(substring(*[2], 2), '0123456789', '\ue000\ue001\ue002\ue003\ue004\ue005\ue006\ue007\ue008\ue009'), 'Russian')" + +- + name: signed-integer + tag: [msup, mover] + match: + - "*[2][self::m:mrow and count(*)=2 and" + - " *[1][self::m:mo][.='-' or .='−' or .='+'] and" + - " *[2][self::m:mn and translate(., '0123456789', '')='']]" + replace: + - x: "*[1]" + - test: + if: "self::m:mover" + then: [t: "⠨⠌"] + else: [t: "⠌"] + - test: + if: "*[2]/*[1][.='+']" + then: [t: "⠖"] + else: [t: "⠤"] + - x: "BrailleChars(translate(*[2]/*[2], '0123456789', '\ue000\ue001\ue002\ue003\ue004\ue005\ue006\ue007\ue008\ue009'), 'Russian')" + - name: chemistry-repeated-charge tag: msup @@ -457,6 +541,9 @@ if: "self::m:munderover" then: [t: "⠨⠡"] else: [t: "⠡"] + - test: + if: "*[2][self::m:mrow[m:mo[.='+']] or self::m:mfrac]" + then: [t: "⠐"] - x: "*[2]" - test: if: "self::m:munderover" diff --git a/tests/braille/Russian/russian.rs b/tests/braille/Russian/russian.rs index 859d230a..4d2f9c83 100644 --- a/tests/braille/Russian/russian.rs +++ b/tests/braille/Russian/russian.rs @@ -1,6 +1,108 @@ use crate::common::*; use anyhow::Result; +#[test] +fn script_grouping_regressions() -> Result<()> { + let cases = vec![ + ("sup_x", r#"ax"#), + ("sup_zero", r#"x0"#), + ("sup_ten", r#"x10"#), + ("sup_minus_x", r#"a-x"#), + ("sup_minus_2", r#"a-2"#), + ("sup_x_plus_1", r#"ax+1"#), + ("sup_sub_x2", r#"ax2"#), + ("sup_nested", r#"ax2"#), + ("sup_frac", r#"a12"#), + ("sup_sqrt", r#"ax"#), + ("sup_follow_letter", r#"x2y"#), + ("sup_follow_number", r#"x23"#), + ("sub_x", r#"ax"#), + ("sub_zero", r#"x0"#), + ("sub_ten", r#"x10"#), + ("sub_minus_x", r#"a-x"#), + ("sub_minus_2", r#"a-2"#), + ("sub_x_plus_1", r#"ax+1"#), + ("sub_nested", r#"ax2"#), + ("sub_follow_letter", r#"x2y"#), + ("sub_follow_number", r#"x23"#), + ("subsup_numeric", r#"x12"#), + ("subsup_i_n", r#"xin"#), + ("subsup_grouped_sub", r#"xi+12"#), + ("subsup_grouped_sup", r#"x0n-1"#), + ("subsup_nested_sup", r#"x0n2"#), + ("negative_base_sup", r#"-x2"#), + ("paren_base_sup", r#"(x+1)2"#), + ("frac_base_sup", r#"1x2"#), + ("root_base_sup", r#"x2"#), + ("sup_on_function", r#"sin2x"#), + ("log_sub_sup", r#"log23x"#), + ("root_index_group", r#"xn+1"#), + ("root_index_sub", r#"xn2"#), + ("frac_num_group", r#"x+1y"#), + ("frac_den_group", r#"xy+1"#), + ("nested_frac", r#"1x1y"#), + ("sup_after_fraction", r#"x+1y-12"#), + ("sub_after_fraction", r#"x+1y-1i"#), + ("tensor_like", r#"Tijxjk"#), + ("pre_negative_power", r#"2x-1"#), + ("power_of_power_follow", r#"x23y"#), + ("subscripted_power_follow", r#"x23y"#), + ("power_subscript_follow", r#"x23y"#), + ]; + + let expected = std::collections::HashMap::from([ + ("sup_x", "⠠⠁⠌⠭⠱"), + ("sup_zero", "⠠⠭⠌⠴"), + ("sup_ten", "⠠⠭⠌⠂⠴"), + ("sup_minus_x", "⠠⠁⠌⠀⠤⠭⠱"), + ("sup_minus_2", "⠠⠁⠌⠤⠆"), + ("sup_x_plus_1", "⠠⠁⠌⠭⠀⠖⠼⠁⠱"), + ("sup_sub_x2", "⠠⠁⠌⠭⠡⠆⠱"), + ("sup_nested", "⠠⠁⠌⠭⠌⠆⠱"), + ("sup_frac", "⠠⠁⠌⠼⠁⠆⠱"), + ("sup_sqrt", "⠠⠁⠌⠩⠱⠭⠹⠱"), + ("sup_follow_letter", "⠠⠭⠌⠆⠽"), + ("sup_follow_number", "⠠⠭⠌⠆⠼⠉"), + ("sub_x", "⠠⠁⠡⠭⠱"), + ("sub_zero", "⠠⠭⠡⠴"), + ("sub_ten", "⠠⠭⠡⠂⠴"), + ("sub_minus_x", "⠠⠁⠡⠀⠤⠭⠱"), + ("sub_minus_2", "⠠⠁⠡⠤⠆"), + ("sub_x_plus_1", "⠠⠁⠡⠐⠭⠀⠖⠼⠁⠱"), + ("sub_nested", "⠠⠁⠡⠭⠡⠆⠱"), + ("sub_follow_letter", "⠠⠭⠡⠆⠽"), + ("sub_follow_number", "⠠⠭⠡⠆⠼⠉"), + ("subsup_numeric", "⠠⠭⠡⠼⠁⠌⠼⠃⠱"), + ("subsup_i_n", "⠠⠭⠡⠊⠌⠝⠱"), + ("subsup_grouped_sub", "⠠⠭⠡⠐⠊⠀⠖⠼⠁⠌⠼⠃⠱"), + ("subsup_grouped_sup", "⠠⠭⠡⠼⠚⠌⠠⠝⠀⠤⠼⠁⠱"), + ("subsup_nested_sup", "⠠⠭⠡⠼⠚⠌⠠⠝⠌⠆⠱"), + ("negative_base_sup", "⠤⠠⠭⠌⠆"), + ("paren_base_sup", "⠣⠠⠭⠀⠖⠼⠁⠜⠌⠆"), + ("frac_base_sup", "⠼⠁⠳⠠⠭⠌⠆"), + ("root_base_sup", "⠩⠱⠠⠭⠹⠌⠆"), + ("sup_on_function", "⠫⠎⠌⠆⠠⠭"), + ("log_sub_sup", "⠫⠇⠡⠼⠃⠌⠼⠉⠱⠠⠭"), + ("root_index_group", "⠩⠠⠝⠀⠖⠼⠁⠱⠠⠭⠹"), + ("root_index_sub", "⠩⠠⠝⠡⠆⠱⠭⠹"), + ("frac_num_group", "⠆⠠⠭⠀⠖⠼⠁⠀⠳⠠⠽⠰"), + ("frac_den_group", "⠆⠠⠭⠀⠳⠽⠀⠖⠼⠁⠰"), + ("nested_frac", "⠆⠆⠼⠁⠀⠳⠠⠭⠰⠀⠳⠆⠼⠁⠀⠳⠠⠽⠰⠰"), + ("sup_after_fraction", "⠆⠠⠭⠀⠖⠼⠁⠀⠳⠠⠽⠀⠤⠼⠁⠰⠌⠆"), + ("sub_after_fraction", "⠆⠠⠭⠀⠖⠼⠁⠀⠳⠠⠽⠀⠤⠼⠁⠰⠡⠠⠊⠱"), + ("tensor_like", "⠨⠞⠡⠠⠊⠌⠚⠱⠭⠡⠚⠌⠅⠱"), + ("pre_negative_power", "⠼⠃⠠⠭⠌⠤⠂"), + ("power_of_power_follow", "⠠⠭⠌⠆⠌⠒⠽"), + ("subscripted_power_follow", "⠠⠭⠡⠆⠌⠒⠽"), + ("power_subscript_follow", "⠠⠭⠌⠆⠡⠒⠽"), + ]); + + for (label, expr) in cases { + test_braille("Russian", expr, expected[label])?; + } + return Ok(()); +} + #[test] fn numbers_and_operators() -> Result<()> { let expr = r#"5+12=17"#;