Skip to content

Commit

Permalink
More support for LiteralSpeak along with fixes for :literal.
Browse files Browse the repository at this point in the history
Added tests for both.
Really fixes #135.
  • Loading branch information
NSoiffer committed Jan 8, 2025
1 parent e54813e commit 1fb4914
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 11 deletions.
11 changes: 8 additions & 3 deletions Rules/Languages/en/SharedRules/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,16 @@
match: count(*)>0
replace:
- x: "translate(name(.), '-_', ' ')"
- t: "of" # phrase(sine 'of' 5)
- pause: short
- test:
if: "not(contains(@data-intent-property, ':literal:'))"
then: [t: "of", pause: short] # phrase(sine 'of' 5)
- insert:
nodes: "*"
replace: [t: "comma", pause: auto] # phrase(f of x 'comma' y)
replace:
- test:
if: "not(contains(@data-intent-property, ':literal:'))"
then: [t: "comma"] # phrase(f of x 'comma' y)
- pause: auto

- name: default-text
# unknown leaf -- just speak the text -- could be a literal intent
Expand Down
1 change: 1 addition & 0 deletions src/infer_intent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ mod tests {
crate::interface::set_rules_dir(super::super::abs_rules_dir_path()).unwrap();
// crate::speech::SpeechRules::initialize_all_rules().unwrap();
set_preference("IntentErrorRecovery".to_string(), intent_error_recovery.to_string()).unwrap();
set_preference("SpeechStyle".to_string(), "SimpleSpeak".to_string()).unwrap(); // avoids possibility of "LiteralSpeak"
let package1 = &parser::parse(mathml).expect("Failed to parse test input");
let mathml = get_element(package1);
trim_element(&mathml);
Expand Down
1 change: 0 additions & 1 deletion src/navigate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1921,7 +1921,6 @@ mod tests {

#[test]
fn absolute_value() -> Result<()> {
init_logger();
let mathml_str = "<math id='math'>
<mrow id='expr'>
<mn id='2'>2</mn>
Expand Down
24 changes: 21 additions & 3 deletions src/speech.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,33 @@ fn intent_rules<'m>(rules: &'static std::thread::LocalKey<RefCell<SpeechRules>>,
rules.borrow_mut().read_files()?;
let rules = rules.borrow();
// debug!("intent_rules:\n{}", mml_to_string(&mathml));
let should_set_literal_intent = rules.pref_manager.borrow().pref_to_string("SpeechStyle").as_str() == "LiteralSpeak";
let original_intent = mathml.attribute_value("intent");
if should_set_literal_intent {
if let Some(intent) = original_intent {
let intent = if intent.contains('(') {intent.replace('(', ":literal(")} else {intent.to_string() + ":literal"};
mathml.set_attribute_value("intent", &intent);
} else {
mathml.set_attribute_value("intent", ":literal");
};
}
let mut rules_with_context = SpeechRulesWithContext::new(&rules, doc, nav_node_id);
let intent = rules_with_context.match_pattern::<Element<'m>>(mathml)
.chain_err(|| "Pattern match/replacement failure!")?;
if name(&intent) == "TEMP_NAME" { // unneeded extra layer
let answer = if name(&intent) == "TEMP_NAME" { // unneeded extra layer
assert_eq!(intent.children().len(), 1);
return Ok( as_element(intent.children()[0]) );
as_element(intent.children()[0])
} else {
return Ok(intent);
intent
};
if should_set_literal_intent {
if let Some(original_intent) = original_intent {
mathml.set_attribute_value("intent", original_intent);
} else {
mathml.remove_attribute("intent");
}
}
return Ok(answer);
})
}

Expand Down
82 changes: 78 additions & 4 deletions tests/Languages/en/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,17 +368,91 @@ fn gradient() {
fn literal_speak() {
let expr = r#"<math data-latex='\vec{A} \perp \vec{B}' display='block'>
<mrow data-changed='added'>
<mover data-latex='\vec{A}' data-mjx-texclass='ORD'>
<mover data-latex='\vec{A}'>
<mi data-latex='A'>A</mi>
<mo stretchy='false'>→</mo>
</mover>
<mo intent='perpendicular-to'>⊥</mo>
<mover data-latex='\vec{B}' data-mjx-texclass='ORD'>
<mover data-latex='\vec{B}'>
<mi data-latex='B'>B</mi>
<mo stretchy='false'>→</mo>
</mover>
</mrow>
</math>"#;
// may want to change this for another language
</math>"#;
test("en", "LiteralSpeak", expr, "cap eigh right arrow, perpendicular to, cap b right arrow");
}

#[test]
fn literal_speak_with_name() {
let expr = r#"<math intent='forced($x)'>
<mrow arg="x">
<mi>f</mi>
<mo data-changed='added'>&#x2061;</mo>
<mrow data-changed='added'>
<mo>(</mo>
<mrow data-changed='added'>
<mi>x</mi>
<mo>!</mo>
</mrow>
<mo>)</mo>
</mrow>
</mrow>
</math>"#;
test("en", "LiteralSpeak", expr, "forced f, left paren x exclamation point, right paren");
}

#[test]
fn literal_speak_with_property() {
let expr = r#"<math intent=':prefix'>
<mrow arg="x">
<mi>f</mi>
<mo data-changed='added'>&#x2061;</mo>
<mrow data-changed='added'>
<mo>(</mo>
<mrow data-changed='added'>
<mi>x</mi>
<mo>!</mo>
</mrow>
<mo>)</mo>
</mrow>
</mrow>
</math>"#;
test("en", "LiteralSpeak", expr, "f, left paren x exclamation point, right paren");
}

#[test]
fn literal_intent_property() {
let expr = r#"<math data-latex='\vec{A} \perp \vec{B}' display='block'>
<mrow intent=":literal">
<mover data-latex='\vec{A}'>
<mi data-latex='A'>A</mi>
<mo stretchy='false'>→</mo>
</mover>
<mo intent='perpendicular-to'>⊥</mo>
<mover data-latex='\vec{B}'>
<mi data-latex='B'>B</mi>
<mo stretchy='false'>→</mo>
</mover>
</mrow>
</math>"#;
test("en", "SimpleSpeak", expr, "cap eigh right arrow, perpendicular to, cap b right arrow");
}

#[test]
fn literal_intent_property_with_name() {
let expr = r#"<math intent='forced:literal($x)'>
<mrow arg="x">
<mi>f</mi>
<mo data-changed='added'>&#x2061;</mo>
<mrow data-changed='added'>
<mo>(</mo>
<mrow data-changed='added'>
<mi>x</mi>
<mo>!</mo>
</mrow>
<mo>)</mo>
</mrow>
</mrow>
</math>"#;
test("en", "SimpleSpeak", expr, "forced f, open paren x exclamation point, close paren");
}
1 change: 1 addition & 0 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ pub fn test_intent(mathml: &str, target: &str, test_prefs: Vec<(&str, &str)>) {

// crate::speech::SpeechRules::initialize_all_rules().unwrap();
set_preference("IntentErrorRecovery".to_string(), "Error".to_string()).unwrap();
set_preference("SpeechStyle".to_string(), "SimpleSpeak".to_string()).unwrap(); // avoids possibility of "LiteralSpeak"
for (pref_name, pref_value) in test_prefs.clone() {
set_preference(pref_name.to_string(), pref_value.to_string()).unwrap();
};
Expand Down

0 comments on commit 1fb4914

Please sign in to comment.