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 = "";
+ 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 = "";
+ 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("")?;
+ 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!("");
+ 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!("");
+ 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!("");
+ 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 = "";
+ test("ja", "ClearSpeak", over, "数量 x プラス 1 付き z 上")?;
+ let both = "";
+ 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 = "";
+ test("ja", "ClearSpeak", expr, "2 ノルム の x")?;
+ return Ok(());
+}
+
+/// A matrix has 成分, not エントリー.
+#[test]
+fn matrix_entry() -> Result<()> {
+ let matrix = "";
+ 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 = "";
+ test("ja", "ClearSpeak", coordinate, "点 1 コンマ 2")?;
+ return Ok(());
+}