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 cc5a89b6..185756e9 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 @@ -504,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 @@ -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') + 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) + then: [T: "水平方向", pause: short] # phrase(the line is 'horizontal') + - 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/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/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/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 3fe944e2..a9b1ba41 100644 --- a/tests/Languages/ja/ja.rs +++ b/tests/Languages/ja/ja.rs @@ -784,3 +784,114 @@ 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 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 囲み終了"), + ] { + 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+1z"; + test("ja", "ClearSpeak", over, "数量 x プラス 1 付き z 上")?; + let both = "x+1yz"; + test("ja", "ClearSpeak", both, "数量 x プラス 1 付き y 下および z 上")?; + 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 エントリー. +#[test] +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. +#[test] +fn coordinate_point() -> Result<()> { + let coordinate = "1,2"; + test("ja", "ClearSpeak", coordinate, "点 1 コンマ 2")?; + return Ok(()); +}