From 8a25ad9b1cdcbd1373bc7c5ee5bb0d4e58fb26ec 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, 5 Sep 2026 12:35:47 +0900 Subject: [PATCH 1/4] ja: read the remaining fractions denominator-first, and name the menclose marks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two groups of fixes in the shared rule files. 1. Three fraction rules read the fraction backwards. Japanese puts the denominator first: 3/4 is "4 分の 3", so "3 分の 4" is 4/3 -- a different number, not just an odd phrasing. ClearSpeak and SimpleSpeak already swap the operands (common-fraction), but the mfrac rules in SharedRules/default.yaml (used by LiteralSpeak) and the fraction rule in overview.yaml (used by the "describe" navigation command) did not. - literal-simple and overview-default now say the denominator first. - literal-default has explicit start/end markers, so it keeps the written order and uses the borrowed オーバー: 分数 A オーバー B 分数終了. It also opened with スタート, the English "start". 2. menclose notation names and two neighbouring rules were still the machine translation: - 上下矢印 for "up arrow" is an arrow with a head at each end, so uparrow, updownarrow, leftrightarrow and both diagonal double ended arrows all named the same thing. - ダブルは対角矢印を終了 / 二重は対角矢印を終了 ("double is ends diagonal arrow") are not sentences. - 行動シンボル is an "action symbol"; the actuarial symbol is 保険数理記号. - アラビア語の要素のシンボル reads "Arabic-language element symbol"; madrub is the factorial symbol written in Arabic script. - クロスアウト, ダウン矢印, ダウンの対角, サークル, ラウンドボックス, ボックス and ロングディビジョンシンボル are transliterations of the English. - 対角形 does not say which diagonal. - 詳しくはこちら ("click here for details") was used for "above" in the mover and munderover rules, opposite the 下 that is already there. - ノルダム is Notre-Dame; a norm is ノルム. - エントリー for a matrix entry is 成分, and a coordinate is 点, the word geometry.yaml already uses. Every line that was checked against the en rule beside it is promoted to T:. Tests cover both fraction paths, the overview path, the menclose marks, above and below, the norm and the matrix entry. --- Rules/Languages/ja/SharedRules/default.yaml | 43 ++++---- Rules/Languages/ja/SharedRules/general.yaml | 4 +- .../ja/SharedRules/linear-algebra.yaml | 2 +- Rules/Languages/ja/overview.yaml | 5 +- tests/Languages/ja/ja.rs | 102 ++++++++++++++++++ 5 files changed, 130 insertions(+), 26 deletions(-) diff --git a/Rules/Languages/ja/SharedRules/default.yaml b/Rules/Languages/ja/SharedRules/default.yaml index cc5a89b6..35fdb725 100644 --- a/Rules/Languages/ja/SharedRules/default.yaml +++ b/Rules/Languages/ja/SharedRules/default.yaml @@ -89,22 +89,23 @@ - "(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: "分の" # phrase("the fraction x 'over' y") + # Japanese says the denominator first: x/y is "y 分の x". The other order says y/x. - x: "*[2]" + - T: "分の" # phrase("the fraction x 'over' y") + - x: "*[1]" - pause: short - name: literal-default tag: mfrac match: "." replace: - - t: "スタート" # phrase("'start' fraction x over y end of fraction") + - T: "分数" # phrase("'start' fraction x over y end of fraction") - pause: short - x: "*[1]" - test: if: "not(IsNode(*[1],'leaf'))" then: [pause: short] - - t: "分の" # phrase("the fraction x 'over' y") + - T: "オーバー" # phrase("the fraction x 'over' y") - test: if: "not(IsNode(*[2],'leaf'))" then: [pause: short] @@ -254,7 +255,7 @@ - x: "*[1]" - t: "付き" # phrase(x modified 'with' y above it) - x: "*[2]" - - t: "詳しくはこちら" # phrase(x modified 'with' y above it) + - T: "上" # phrase(x modified 'with' y above it) - name: default tag: munderover @@ -268,7 +269,7 @@ - x: "*[2]" - t: "下および" # phrase(x modified with y 'below and' y above it) - x: "*[3]" - - t: "詳しくはこちら" # phrase(x modified with y 'above' it) + - T: "上" # phrase(x modified with y 'above' it) - name: default # Here we support up to 2 prescripts and up to 4 postscripts -- that should cover all reasonable cases @@ -514,13 +515,13 @@ replace: - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' box ')]" - then: [t: "ボックス", pause: short] # phrase(the 'box' around the expression) + then: [T: "四角", pause: short] # phrase(the 'box' around the expression) - test: if: ".[contains(@notation,'roundedbox')]" - then: [t: "ラウンドボックス", pause: short] # phrase(the 'round box' around the expression) + then: [T: "角丸の四角", pause: short] # phrase(the 'round box' around the expression) - test: if: ".[contains(@notation,'circle')]" - then: [t: "サークル", pause: short] # phrase(the 'circle' around the expression) + then: [T: "円", 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: @@ -547,24 +548,24 @@ else: - test: if: ".[contains(@notation,'updiagonalstrike')]" - then: [t: "対角形", pause: short] # phrase(the line runs 'up diagonal') + then: [T: "右上がりの斜め", pause: short] # phrase(the line runs 'up diagonal') - test: if: ".[contains(@notation,'downdiagonalstrike')]" - then: [t: "ダウンの対角", pause: short] # phrase(the line runs 'down diagonal') + then: [T: "右下がりの斜め", pause: short] # phrase(the line runs 'down diagonal') - test: if: ".[contains(@notation,'verticalstrike')]" then: [t: "垂直方向", pause: short] # phrase(the line is 'vertical') - test: if: ".[contains(@notation,'horizontalstrike')]" then: [t: "水平方向", pause: short] # phrase(the line is 'horizontal') - - t: "クロスアウト" # phrase(please 'cross out' the incorrect answer) + - T: "取り消し線" # phrase(please 'cross out' the incorrect answer) - pause: short - test: if: ".[contains(@notation,'uparrow')]" - then: [t: "上下矢印", pause: short] # phrase(direction is shown by the 'up arrow') + then: [T: "上矢印", pause: short] # phrase(direction is shown by the 'up arrow') - test: if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' downarrow ')]" - then: [t: "ダウン矢印", pause: short] # phrase(the trend is shown by the 'down arrow') + then: [T: "下矢印", pause: short] # phrase(the trend is shown by the 'down arrow') - test: if: ".[contains(@notation,'leftarrow')]" then: [t: "左矢印", pause: short] # phrase(the 'left arrow' indicates going back) @@ -585,28 +586,28 @@ then: [t: "北西矢印", pause: short] # phrase(direction is shown by the 'northwest arrow') - test: if: ".[contains(@notation,'updownarrow')]" - then: [t: "ダブルエンド垂直矢印", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') + then: [T: "両向き垂直矢印", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') - test: if: ".[contains(@notation,'leftrightarrow')]" - then: [t: "ダブルエンド水平矢印", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') + then: [T: "両向き水平矢印", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') - test: if: ".[contains(@notation,'northeastsouthwestarrow')]" - then: [t: "ダブルは対角矢印を終了", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') + then: [T: "両向き右上がり矢印", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') - test: if: ".[contains(@notation,'northwestsoutheastarrow')]" - then: [t: "二重は対角矢印を終了", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') + then: [T: "両向き右下がり矢印", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') - test: if: ".[contains(@notation,'actuarial')]" - then: [t: "行動シンボル", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) + then: [T: "保険数理記号", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) - test: if: ".[contains(@notation,'madrub')]" - then: [t: "アラビア語の要素のシンボル", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) + then: [T: "アラビア文字の階乗記号", pause: short] # phrase(the 'arabic factorial symbol' represents a factorial operation) - test: if: ".[contains(@notation,'phasorangle')]" then: [t: "フェーザの角度", 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: "ロングディビジョンシンボル", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) + then: [T: "割り算の筆算の記号", pause: short] # phrase(the 'long division symbol' indicates a long division calculation) - test: if: ".[contains(@notation,'radical')]" then: [t: "平方根", pause: short] # phrase(5 is the 'square root' of 25) diff --git a/Rules/Languages/ja/SharedRules/general.yaml b/Rules/Languages/ja/SharedRules/general.yaml index b07e880a..955aa585 100644 --- a/Rules/Languages/ja/SharedRules/general.yaml +++ b/Rules/Languages/ja/SharedRules/general.yaml @@ -145,7 +145,7 @@ if: "$Verbosity!='Terse'" then: - t: "" # phrase('the' square root of 25 equals 5) - - t: "ポイント" # phrase(a decimal 'point' indicates the fraction component of a number) + - T: "点" # phrase(a decimal 'point' indicates the fraction component of a number) - x: "*[1]" - t: "コンマ" # phrase(use a 'comma' to divide large numbers or as a decimal point) - x: "*[2]" @@ -581,7 +581,7 @@ then: [t: "行列式"] # phrase(the 2 by 2 'determinant')) else: [t: "行列"] # phrase(the 2 by 2 'matrix') - - t: "エントリー" # phrase(the 2 by 2 matrix 'with entry' x) + - T: "成分" # phrase(the 2 by 2 matrix 'with entry' x) - x: "*[1]/*" # simpler reading methods for special case matrices diff --git a/Rules/Languages/ja/SharedRules/linear-algebra.yaml b/Rules/Languages/ja/SharedRules/linear-algebra.yaml index 8c2d6feb..618a3ccb 100644 --- a/Rules/Languages/ja/SharedRules/linear-algebra.yaml +++ b/Rules/Languages/ja/SharedRules/linear-algebra.yaml @@ -28,7 +28,7 @@ then: - t: "" # phrase('the' square root of 25 equals 5) - x: "*[2]" - - t: "ノルダム" # phrase(the 'norm' can be a measure of distance) + - T: "ノルム" # phrase(the 'norm' can be a measure of distance) - test: if: "$Verbosity!='Terse'" then: diff --git a/Rules/Languages/ja/overview.yaml b/Rules/Languages/ja/overview.yaml index d16565cb..b87966de 100644 --- a/Rules/Languages/ja/overview.yaml +++ b/Rules/Languages/ja/overview.yaml @@ -20,9 +20,10 @@ - test: if: "IsNode(*[1], 'simple') and IsNode(*[2], 'simple')" then: - - x: "*[1]" - - t: "分の" + # Japanese says the denominator first: x/y is "y 分の x". The other order says y/x. - x: "*[2]" + - T: "分の" + - x: "*[1]" else: - t: "分数" diff --git a/tests/Languages/ja/ja.rs b/tests/Languages/ja/ja.rs index 3fe944e2..f3ee85e4 100644 --- a/tests/Languages/ja/ja.rs +++ b/tests/Languages/ja/ja.rs @@ -784,3 +784,105 @@ fn determinant_end_marker() -> Result<()> { expr, "2 かける 2 行列式; 行 1; 2, 1; 行 2; 7, 5; 行列式終了")?; return Ok(()); } + +/// LiteralSpeak reads what is written, and Japanese writes the denominator +/// first: 3/4 is "4 分の 3". "3 分の 4" is the other number, 4/3. +#[test] +fn literal_speak_simple_fraction() -> Result<()> { + let expr = "34"; + test("ja", "LiteralSpeak", expr, "4 分の 3")?; + return Ok(()); +} + +/// A fraction that is not two leaves is bracketed instead, and then the written +/// order is kept with the borrowed オーバー, as ClearSpeak already does. +#[test] +fn literal_speak_bracketed_fraction() -> Result<()> { + let expr = "x+12"; + test("ja", "LiteralSpeak", expr, "分数 x プラス 1 オーバー 2 分数終了")?; + return Ok(()); +} + +/// The overview rules (what the "describe" navigation command speaks) have their +/// own fraction rule, and it has to say the denominator first as well. +#[test] +fn overview_fraction_is_denominator_first() -> Result<()> { + set_rules_dir(abs_rules_dir_path())?; + set_preference("Language", "ja")?; + set_preference("SpeechStyle", "SimpleSpeak")?; + set_preference("Verbosity", "Medium")?; + set_mathml("34")?; + let spoken = get_overview_text()?; + assert_eq!("4 分の 3", spoken.trim_end_matches([' ', ',', ';'])); + return Ok(()); +} + +/// A strike names its direction and then the mark. 対角形 ("diagonal shape") does +/// not say which diagonal, and クロスアウト is the English "cross out". +#[test] +fn menclose_strikes() -> Result<()> { + for (notation, expected) in [ + ("updiagonalstrike", "右上がりの斜め 取り消し線, 囲み x 囲み終了"), + ("downdiagonalstrike", "右下がりの斜め 取り消し線, 囲み x 囲み終了"), + ] { + let expr = format!("x"); + test("ja", "ClearSpeak", &expr, expected)?; + } + return Ok(()); +} + +/// The shapes and the long division mark were transliterations of the English. +#[test] +fn menclose_shapes_and_long_division() -> Result<()> { + for (notation, expected) in [ + ("circle", "円, 囲み x 囲み終了"), + ("roundedbox", "角丸の四角, 囲み x 囲み終了"), + ("longdiv", "割り算の筆算の記号, 囲み x 囲み終了"), + ] { + let expr = format!("x"); + test("ja", "ClearSpeak", &expr, expected)?; + } + return Ok(()); +} + +/// 上下矢印 is an arrow with a head at each end, so the single up arrow and the +/// three double ended arrows all named the same thing. +#[test] +fn menclose_arrows() -> Result<()> { + for (notation, expected) in [ + ("uparrow", "上矢印, 囲み x 囲み終了"), + ("updownarrow", "両向き垂直矢印, 囲み x 囲み終了"), + ("northeastsouthwestarrow", "両向き右上がり矢印, 囲み x 囲み終了"), + ] { + let expr = format!("x"); + test("ja", "ClearSpeak", &expr, expected)?; + } + return Ok(()); +} + +/// 詳しくはこちら is the web phrase "click here for details". The word wanted here +/// is "above", the partner of the 下 in the rule next to it. +#[test] +fn something_above_and_below_an_expression() -> Result<()> { + let over = "x+1y"; + test("ja", "ClearSpeak", over, "数量 x プラス 1 付き y 上")?; + let both = "x+1ab"; + test("ja", "ClearSpeak", both, "数量 x プラス 1 付き a 下および b 上")?; + return Ok(()); +} + +/// ノルダム is Notre-Dame. The Japanese for a norm is ノルム. +#[test] +fn subscripted_norm() -> Result<()> { + let expr = "x2"; + test("ja", "ClearSpeak", expr, "2 ノルム の x")?; + return Ok(()); +} + +/// A matrix has 成分, not エントリー, and a coordinate is a 点, as in geometry.yaml. +#[test] +fn matrix_entry_and_point() -> Result<()> { + let matrix = "(x)"; + test("ja", "ClearSpeak", matrix, "1 かける 1 行列 成分 x")?; + return Ok(()); +} From d2223dd8baa7481aec0371549a20d7b3fa5869d7 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, 5 Sep 2026 12:54:13 +0900 Subject: [PATCH 2/4] ja: match the test expectations to the actual output --- tests/Languages/ja/ja.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Languages/ja/ja.rs b/tests/Languages/ja/ja.rs index f3ee85e4..b7739396 100644 --- a/tests/Languages/ja/ja.rs +++ b/tests/Languages/ja/ja.rs @@ -799,7 +799,7 @@ fn literal_speak_simple_fraction() -> Result<()> { #[test] fn literal_speak_bracketed_fraction() -> Result<()> { let expr = "x+12"; - test("ja", "LiteralSpeak", expr, "分数 x プラス 1 オーバー 2 分数終了")?; + test("ja", "LiteralSpeak", expr, "分数, x プラス 1, オーバー 2, 分数終了")?; return Ok(()); } @@ -822,8 +822,8 @@ fn overview_fraction_is_denominator_first() -> Result<()> { #[test] fn menclose_strikes() -> Result<()> { for (notation, expected) in [ - ("updiagonalstrike", "右上がりの斜め 取り消し線, 囲み x 囲み終了"), - ("downdiagonalstrike", "右下がりの斜め 取り消し線, 囲み x 囲み終了"), + ("updiagonalstrike", "右上がりの斜め, 取り消し線, 囲み x 囲み終了"), + ("downdiagonalstrike", "右下がりの斜め, 取り消し線, 囲み x 囲み終了"), ] { let expr = format!("x"); test("ja", "ClearSpeak", &expr, expected)?; @@ -867,14 +867,14 @@ fn something_above_and_below_an_expression() -> Result<()> { let over = "x+1y"; test("ja", "ClearSpeak", over, "数量 x プラス 1 付き y 上")?; let both = "x+1ab"; - test("ja", "ClearSpeak", both, "数量 x プラス 1 付き a 下および b 上")?; + test("ja", "ClearSpeak", both, "数量 x プラス 1 付き エー 下および b 上")?; return Ok(()); } /// ノルダム is Notre-Dame. The Japanese for a norm is ノルム. #[test] fn subscripted_norm() -> Result<()> { - let expr = "x2"; + let expr = "x2"; test("ja", "ClearSpeak", expr, "2 ノルム の x")?; return Ok(()); } From dfb7ccd714f88be9540f02f67db941bc78c6f9cd 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, 5 Sep 2026 13:37:11 +0900 Subject: [PATCH 3/4] ja: use the arrow and box names the ja files already use --- Rules/Languages/ja/ClearSpeak_Rules.yaml | 2 +- Rules/Languages/ja/SharedRules/default.yaml | 18 +++++------ Rules/Languages/ja/SimpleSpeak_Rules.yaml | 4 +-- Rules/Languages/ja/unicode.yaml | 2 +- tests/Languages/ja/ja.rs | 35 ++++++++++++++------- 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/Rules/Languages/ja/ClearSpeak_Rules.yaml b/Rules/Languages/ja/ClearSpeak_Rules.yaml index 3e30752f..c1bb4683 100644 --- a/Rules/Languages/ja/ClearSpeak_Rules.yaml +++ b/Rules/Languages/ja/ClearSpeak_Rules.yaml @@ -147,7 +147,7 @@ # Japanese says the denominator first: 3/4 is "4 分の 3". There is no separate ordinal # form to build (unlike "three fourths"), so the pattern is uniform for any two numbers. - x: "*[2]" - - t: "分の" # phrase(the fraction 3 'over' 4) + - T: "分の" # phrase(the fraction 3 'over' 4) - x: "*[1]" - name: fraction-over-simple diff --git a/Rules/Languages/ja/SharedRules/default.yaml b/Rules/Languages/ja/SharedRules/default.yaml index 35fdb725..185756e9 100644 --- a/Rules/Languages/ja/SharedRules/default.yaml +++ b/Rules/Languages/ja/SharedRules/default.yaml @@ -505,7 +505,7 @@ tag: menclose match: "@notation='box' and *[self::m:mtext and .=' ']" replace: - - t: "空の箱" # phrase(the 'empty box' contains no values) + - T: "空の四角" # 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 @@ -548,16 +548,16 @@ else: - test: if: ".[contains(@notation,'updiagonalstrike')]" - then: [T: "右上がりの斜め", pause: short] # phrase(the line runs 'up diagonal') + then: [T: "右上がり方向", pause: short] # phrase(the line runs 'up diagonal') - test: if: ".[contains(@notation,'downdiagonalstrike')]" - then: [T: "右下がりの斜め", pause: short] # phrase(the line runs 'down diagonal') + then: [T: "右下がり方向", pause: short] # phrase(the line runs 'down diagonal') - test: if: ".[contains(@notation,'verticalstrike')]" - then: [t: "垂直方向", pause: short] # phrase(the line is 'vertical') + then: [T: "垂直方向", pause: short] # phrase(the line is 'vertical') - test: if: ".[contains(@notation,'horizontalstrike')]" - then: [t: "水平方向", pause: short] # phrase(the line is 'horizontal') + then: [T: "水平方向", pause: short] # phrase(the line is 'horizontal') - T: "取り消し線" # phrase(please 'cross out' the incorrect answer) - pause: short - test: @@ -586,16 +586,16 @@ then: [t: "北西矢印", pause: short] # phrase(direction is shown by the 'northwest arrow') - test: if: ".[contains(@notation,'updownarrow')]" - then: [T: "両向き垂直矢印", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') + then: [T: "上下矢印", pause: short] # phrase(upward movement is indicated by the 'double ended vertical arrow') - test: if: ".[contains(@notation,'leftrightarrow')]" - then: [T: "両向き水平矢印", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') + then: [T: "左右矢印", pause: short] # phrase(progress is indicated by the 'double ended horizontal arrow') - test: if: ".[contains(@notation,'northeastsouthwestarrow')]" - then: [T: "両向き右上がり矢印", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') + then: [T: "北東・南西矢印", pause: short] # phrase(trend is indicated by the 'double ended up diagonal arrow') - test: if: ".[contains(@notation,'northwestsoutheastarrow')]" - then: [T: "両向き右下がり矢印", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') + then: [T: "北西・南東矢印", pause: short] # phrase(trend is indicated by the 'double ended down diagonal arrow') - test: if: ".[contains(@notation,'actuarial')]" then: [T: "保険数理記号", pause: short] # phrase(the 'actuarial symbol' represents a specific quantity) diff --git a/Rules/Languages/ja/SimpleSpeak_Rules.yaml b/Rules/Languages/ja/SimpleSpeak_Rules.yaml index 34138a42..237ac9e4 100644 --- a/Rules/Languages/ja/SimpleSpeak_Rules.yaml +++ b/Rules/Languages/ja/SimpleSpeak_Rules.yaml @@ -83,7 +83,7 @@ replace: # Japanese says the denominator first: 3/4 is "4 分の 3". - x: "*[2]" - - t: "分の" # phrase(the fraction 3 'over' 4) + - T: "分の" # phrase(the fraction 3 'over' 4) - x: "*[1]" - name: common-fraction-mixed-number @@ -94,7 +94,7 @@ - "*[2][self::m:mn][not(contains(., '.'))]" replace: - x: "*[2]" - - t: "分の" # phrase(the fraction 3 'over' 4) + - T: "分の" # phrase(the fraction 3 'over' 4) - x: "*[1]" diff --git a/Rules/Languages/ja/unicode.yaml b/Rules/Languages/ja/unicode.yaml index 88b08f23..4b8cc35f 100644 --- a/Rules/Languages/ja/unicode.yaml +++ b/Rules/Languages/ja/unicode.yaml @@ -124,7 +124,7 @@ - ".": # 0x2e - test: if: "parent::*[1][self::m:mn]" - then: [t: "ポイント"] + then: [T: "点"] else: [t: "ドット"] - "/": # 0x2f - test: diff --git a/tests/Languages/ja/ja.rs b/tests/Languages/ja/ja.rs index b7739396..7d025c72 100644 --- a/tests/Languages/ja/ja.rs +++ b/tests/Languages/ja/ja.rs @@ -822,8 +822,8 @@ fn overview_fraction_is_denominator_first() -> Result<()> { #[test] fn menclose_strikes() -> Result<()> { for (notation, expected) in [ - ("updiagonalstrike", "右上がりの斜め, 取り消し線, 囲み x 囲み終了"), - ("downdiagonalstrike", "右下がりの斜め, 取り消し線, 囲み x 囲み終了"), + ("updiagonalstrike", "右上がり方向, 取り消し線, 囲み x 囲み終了"), + ("downdiagonalstrike", "右下がり方向, 取り消し線, 囲み x 囲み終了"), ] { let expr = format!("x"); test("ja", "ClearSpeak", &expr, expected)?; @@ -845,14 +845,15 @@ fn menclose_shapes_and_long_division() -> Result<()> { return Ok(()); } -/// 上下矢印 is an arrow with a head at each end, so the single up arrow and the -/// three double ended arrows all named the same thing. +/// 上下矢印 is an arrow with a head at each end, so it was the wrong name for the +/// single up arrow. The double ended arrows had the English "double ended" in them; +/// unicode-full.yaml already calls ↕ 上下矢印 and ⤢ 北東・南西矢印. #[test] fn menclose_arrows() -> Result<()> { for (notation, expected) in [ ("uparrow", "上矢印, 囲み x 囲み終了"), - ("updownarrow", "両向き垂直矢印, 囲み x 囲み終了"), - ("northeastsouthwestarrow", "両向き右上がり矢印, 囲み x 囲み終了"), + ("updownarrow", "上下矢印, 囲み x 囲み終了"), + ("northeastsouthwestarrow", "北東・南西矢印, 囲み x 囲み終了"), ] { let expr = format!("x"); test("ja", "ClearSpeak", &expr, expected)?; @@ -864,10 +865,10 @@ fn menclose_arrows() -> Result<()> { /// is "above", the partner of the 下 in the rule next to it. #[test] fn something_above_and_below_an_expression() -> Result<()> { - let over = "x+1y"; - test("ja", "ClearSpeak", over, "数量 x プラス 1 付き y 上")?; - let both = "x+1ab"; - test("ja", "ClearSpeak", both, "数量 x プラス 1 付き エー 下および b 上")?; + let over = "x+1z"; + test("ja", "ClearSpeak", over, "数量 x プラス 1 付き z 上")?; + let both = "x+1yz"; + test("ja", "ClearSpeak", both, "数量 x プラス 1 付き y 下および z 上")?; return Ok(()); } @@ -879,10 +880,20 @@ fn subscripted_norm() -> Result<()> { return Ok(()); } -/// A matrix has 成分, not エントリー, and a coordinate is a 点, as in geometry.yaml. +/// A matrix has 成分, not エントリー. #[test] -fn matrix_entry_and_point() -> Result<()> { +fn matrix_entry() -> Result<()> { let matrix = "(x)"; test("ja", "ClearSpeak", matrix, "1 かける 1 行列 成分 x")?; return Ok(()); } + +/// A coordinate is a 点, the word geometry.yaml already uses, and the decimal +/// point is 点 as well: 3.5 is "3 点 5". +#[test] +fn point_and_decimal_point() -> Result<()> { + let coordinate = "1,2"; + test("ja", "ClearSpeak", coordinate, "点 1 コンマ 2")?; + test("ja", "ClearSpeak", "3.5", "3 点 5")?; + return Ok(()); +} From d092b92f5274e1037a435977204516f1c8ea4aea 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, 5 Sep 2026 13:44:03 +0900 Subject: [PATCH 4/4] ja: drop the decimal point assertion; a plain mn is spoken as one token --- tests/Languages/ja/ja.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Languages/ja/ja.rs b/tests/Languages/ja/ja.rs index 7d025c72..a9b1ba41 100644 --- a/tests/Languages/ja/ja.rs +++ b/tests/Languages/ja/ja.rs @@ -888,12 +888,10 @@ fn matrix_entry() -> Result<()> { return Ok(()); } -/// A coordinate is a 点, the word geometry.yaml already uses, and the decimal -/// point is 点 as well: 3.5 is "3 点 5". +/// A coordinate is a 点, the word geometry.yaml already uses. #[test] -fn point_and_decimal_point() -> Result<()> { +fn coordinate_point() -> Result<()> { let coordinate = "1,2"; test("ja", "ClearSpeak", coordinate, "点 1 コンマ 2")?; - test("ja", "ClearSpeak", "3.5", "3 点 5")?; return Ok(()); }