22use strum_macros:: Display ;
33use sxd_document:: dom:: { Element , ChildOfElement } ;
44use sxd_document:: Package ;
5+ use sxd_document:: { as_str, as_opt_str} ;
56use crate :: definitions:: SPEECH_DEFINITIONS ;
67use crate :: errors:: * ;
78use crate :: pretty_print:: mml_to_string;
@@ -326,7 +327,8 @@ pub fn get_navigation_node_from_braille_position(mathml: Element, position: usiz
326327 /// find the navigation node that most tightly encapsulates the target position (0-based)
327328 /// 'node' is the current node we are on inside of 'mathml'
328329 fn find_navigation_node < ' e > ( mathml : Element < ' e > , node : Element < ' e > , target_position : usize ) -> Result < SearchState < ' e > > {
329- let node_id = match node. attribute_value ( "id" ) {
330+ let raw_node_id = node. attribute_value ( "id" ) ;
331+ let node_id = match as_opt_str ! ( raw_node_id) {
330332 Some ( id) => id,
331333 None => bail ! ( "'id' is not present on mathml: {}" , mml_to_string( node) ) ,
332334 } ;
@@ -444,7 +446,7 @@ pub fn get_navigation_node_from_braille_position(mathml: Element, position: usiz
444446 return BRAILLE_DEFINITIONS . with ( |definitions| {
445447 let definitions = definitions. borrow ( ) ;
446448 let comparison_operators = definitions. get_hashset ( "ComparisonOperators" ) . unwrap ( ) ;
447- return comparison_operators. contains ( as_text ( node) ) ;
449+ return comparison_operators. contains ( as_str ! ( as_text( node) ) ) ;
448450 } ) ;
449451 }
450452
@@ -478,7 +480,7 @@ pub fn get_navigation_node_from_braille_position(mathml: Element, position: usiz
478480
479481 fn estimate_braille_chars ( child : ChildOfElement , n_number_indicator : usize ) -> usize {
480482 let node = as_element ( child) ;
481- let leaf_name = name ( node) ;
483+ let leaf_name = as_str ! ( name( node) ) ;
482484 if is_leaf ( node) {
483485 let text = as_text ( node) ;
484486 // len() is close since mn's probably have ASCII digits and lower case vars are common (count as) and other chars need extra braille chars
@@ -2238,7 +2240,7 @@ impl NemethNestingChars {
22382240 max_value += repeat_char;
22392241 node. set_attribute_value ( NEMETH_FRAC_LEVEL , & max_value) ;
22402242 return max_value;
2241- } else if FIRST_CHILD_ONLY . contains ( & name) {
2243+ } else if FIRST_CHILD_ONLY . contains ( & as_str ! ( name) ) {
22422244 // only look at the base -- ignore scripts/index
22432245 return NemethNestingChars :: nemeth_frac_value ( as_element ( children[ 0 ] ) , repeat_char) ;
22442246 } else {
@@ -2273,11 +2275,11 @@ impl NemethNestingChars {
22732275 if let ParentOfChild :: Element ( e) = parent_of_child {
22742276 parent = e;
22752277 } else {
2276- return Err ( sxd_xpath:: function:: Error :: Other ( "Internal error in nemeth_root_value: didn't find 'math' tag" . to_string ( ) ) ) ;
2278+ return Err ( sxd_xpath:: function:: Error :: Other { what : "Internal error in nemeth_root_value: didn't find 'math' tag" . to_string ( ) } ) ;
22772279 }
22782280 }
22792281 }
2280- return Err ( XPathError :: Other ( "Internal error in nemeth_root_value: didn't find 'math' tag" . to_string ( ) ) ) ;
2282+ return Err ( XPathError :: Other { what : "Internal error in nemeth_root_value: didn't find 'math' tag" . to_string ( ) } ) ;
22812283 }
22822284}
22832285
@@ -2308,7 +2310,7 @@ impl Function for NemethNestingChars {
23082310 } else if name == "msqrt" || name == "mroot" {
23092311 return Ok ( Value :: String ( NemethNestingChars :: nemeth_root_value ( el, & repeat_char) ? ) ) ;
23102312 } else {
2311- return Err ( XPathError :: Other ( format ! ( "NestingChars chars should be used only on 'mfrac'. '{}' was passed in" , name) ) ) ;
2313+ return Err ( XPathError :: Other { what : format ! ( "NestingChars chars should be used only on 'mfrac'. '{}' was passed in" , name) } ) ;
23122314 }
23132315 } else {
23142316 // not an element, so nothing to do
@@ -2330,11 +2332,11 @@ impl BrailleChars {
23302332 "Vietnam" => BrailleChars :: get_braille_vietnam_chars ( node, text_range) ,
23312333 "Swedish" => BrailleChars :: get_braille_ueb_chars ( node, text_range) , // FIX: need to figure out what to implement
23322334 "Finnish" => BrailleChars :: get_braille_ueb_chars ( node, text_range) , // FIX: need to figure out what to implement
2333- _ => return Err ( sxd_xpath:: function:: Error :: Other ( format ! ( "get_braille_chars: unknown braille code '{code}'" ) ) )
2335+ _ => return Err ( sxd_xpath:: function:: Error :: Other { what : format ! ( "get_braille_chars: unknown braille code '{code}'" ) } )
23342336 } ;
23352337 return match result {
23362338 Ok ( string) => Ok ( make_quoted_string ( string) ) ,
2337- Err ( err) => return Err ( sxd_xpath:: function:: Error :: Other ( err. to_string ( ) ) ) ,
2339+ Err ( err) => return Err ( sxd_xpath:: function:: Error :: Other { what : err. to_string ( ) } ) ,
23382340 }
23392341 }
23402342
@@ -2346,8 +2348,8 @@ impl BrailleChars {
23462348 static PICK_APART_CHAR : LazyLock < Regex > = LazyLock :: new ( || {
23472349 Regex :: new ( r"(?P<face>[SB𝔹TIR]*)(?P<lang>[EDGVHU]?)(?P<cap>C?)(?P<letter>L?)(?P<num>[N]?)(?P<char>.)" ) . unwrap ( )
23482350 } ) ;
2349- let math_variant = node. attribute_value ( "mathvariant" ) ;
2350- // FIX: cover all the options -- use phf::Map
2351+ let raw_math_variant = node. attribute_value ( "mathvariant" ) ;
2352+ let math_variant = as_opt_str ! ( raw_math_variant ) ;
23512353 let attr_typeface = match math_variant {
23522354 None => "R" ,
23532355 Some ( variant) => match variant {
@@ -2360,7 +2362,7 @@ impl BrailleChars {
23602362 _ => "R" , // normal and unknown
23612363 } ,
23622364 } ;
2363- let text = BrailleChars :: substring ( as_text ( node) , & text_range) ;
2365+ let text = BrailleChars :: substring ( as_str ! ( as_text( node) ) , & text_range) ;
23642366 let braille_chars = braille_replace_chars ( & text, node) ?;
23652367 // debug!("Nemeth chars: text='{}', braille_chars='{}'", &text, &braille_chars);
23662368
@@ -2422,8 +2424,9 @@ impl BrailleChars {
24222424 Regex :: new ( r"(?P<bold>B??)(?P<italic>I??)(?P<face>[S𝔹TD]??)s??(?P<cap>C??)(?P<greek>G??)(?P<char>[NL].)" ) . unwrap ( )
24232425 } ) ;
24242426
2425- let math_variant = node. attribute_value ( "mathvariant" ) ;
2426- let text = BrailleChars :: substring ( as_text ( node) , & text_range) ;
2427+ let raw_math_variant = node. attribute_value ( "mathvariant" ) ;
2428+ let math_variant = as_opt_str ! ( raw_math_variant) ;
2429+ let text = BrailleChars :: substring ( as_str ! ( as_text( node) ) , & text_range) ;
24272430 let mut braille_chars = braille_replace_chars ( & text, node) ?;
24282431
24292432 // debug!("get_braille_ueb_chars: before/after unicode.yaml: '{}'/'{}'", text, braille_chars);
@@ -2475,8 +2478,9 @@ impl BrailleChars {
24752478 Regex :: new ( r"(?P<bold>B??)(?P<italic>I??)(?P<face>[S𝔹TD]??)s??(?P<cap>C??)(?P<greek>G??)(?P<char>[NL].)" ) . unwrap ( )
24762479 } ) ;
24772480
2478- let math_variant = node. attribute_value ( "mathvariant" ) ;
2479- let text = BrailleChars :: substring ( as_text ( node) , & text_range) ;
2481+ let raw_math_variant = node. attribute_value ( "mathvariant" ) ;
2482+ let math_variant = as_opt_str ! ( raw_math_variant) ;
2483+ let text = BrailleChars :: substring ( as_str ! ( as_text( node) ) , & text_range) ;
24802484 let text = add_separator ( text) ;
24812485
24822486 let braille_chars = braille_replace_chars ( & text, node) ?;
@@ -2609,13 +2613,14 @@ impl BrailleChars {
26092613 return false ;
26102614
26112615 fn child_meets_conditions ( node : Element ) -> bool {
2612- let name = name ( node) ;
2616+ let name = as_str ! ( name( node) ) ;
26132617 return match name {
26142618 "mi" | "mn" => true ,
26152619 "mo" => !crate :: canonicalize:: is_relational_op ( node) ,
26162620 "mtext" => {
2617- let text = as_text ( node) . trim ( ) ;
2618- return text=="?" || text=="-?-" || text. is_empty ( ) ; // various forms of "fill in missing content" (see also Nemeth_RULEs.yaml, "omissions")
2621+ let raw_text = as_text ( node) ;
2622+ let text = raw_text. trim ( ) ;
2623+ return text=="?" || text=="-?-" || text. is_empty ( ) ;
26192624 } ,
26202625 "mrow" => {
26212626 if IsBracketed :: is_bracketed ( node, "" , "" , false , false ) {
@@ -2630,7 +2635,7 @@ impl BrailleChars {
26302635 true
26312636 } ,
26322637 "menclose" => {
2633- if let Some ( notation) = node. attribute_value ( "notation" ) {
2638+ if let Some ( notation) = as_opt_str ! ( node. attribute_value( "notation" ) ) {
26342639 if notation != "bottom" || notation != "box" {
26352640 return false ;
26362641 }
@@ -2675,7 +2680,7 @@ impl Function for BrailleChars {
26752680 use crate :: canonicalize:: create_mathml_element;
26762681 let mut args = Args ( args) ;
26772682 if let Err ( e) = args. exactly ( 2 ) . or_else ( |_| args. exactly ( 4 ) ) {
2678- return Err ( XPathError :: Other ( format ! ( "BrailleChars requires 2 or 4 args: {e}" ) ) ) ;
2683+ return Err ( XPathError :: Other { what : format ! ( "BrailleChars requires 2 or 4 args: {e}" ) } ) ;
26792684 } ;
26802685
26812686 let range = if args. len ( ) == 4 {
@@ -2707,7 +2712,7 @@ impl Function for BrailleChars {
27072712 } ;
27082713
27092714 if !is_leaf ( node) {
2710- return Err ( XPathError :: Other ( format ! ( "BrailleChars called on non-leaf element '{}'" , mml_to_string( node) ) ) ) ;
2715+ return Err ( XPathError :: Other { what : format ! ( "BrailleChars called on non-leaf element '{}'" , mml_to_string( node) ) } ) ;
27112716 }
27122717 return Ok ( Value :: String ( BrailleChars :: get_braille_chars ( node, & braille_code, range) ? ) ) ;
27132718 }
@@ -2773,7 +2778,7 @@ impl NeedsToBeGrouped {
27732778 /// FIX: what needs to be implemented?
27742779 fn needs_grouping_for_finnish ( mathml : Element , is_base : bool ) -> bool {
27752780 use crate :: xpath_functions:: IsInDefinition ;
2776- let mut node_name = name ( mathml) ;
2781+ let mut node_name = as_str ! ( name( mathml) ) ;
27772782 if mathml. attribute_value ( "data-roman-numeral" ) . is_some ( ) {
27782783 node_name = "mi" ; // roman numerals don't follow number rules
27792784 }
@@ -2804,7 +2809,7 @@ impl NeedsToBeGrouped {
28042809 }
28052810 } ,
28062811 "mi" | "mo" | "mtext" => {
2807- let text = as_text ( mathml) ;
2812+ let text = as_str ! ( as_text( mathml) ) ;
28082813 let parent = get_parent ( mathml) ; // there is always a "math" node
28092814 let parent_name = name ( parent) ; // there is always a "math" node
28102815 if is_base && ( parent_name == "msub" || parent_name == "msup" || parent_name == "msubsup" ) && !text. contains ( [ ' ' , '\u{00A0}' ] ) {
@@ -2864,15 +2869,15 @@ impl NeedsToBeGrouped {
28642869 // if the number is irregular, return the ordinal form, otherwise return 'None'.
28652870 fn needs_grouping_for_swedish ( mathml : Element , is_base : bool ) -> bool {
28662871 use crate :: xpath_functions:: IsInDefinition ;
2867- let mut node_name = name ( mathml) ;
2872+ let mut node_name = as_str ! ( name( mathml) ) ;
28682873 if mathml. attribute_value ( "data-roman-numeral" ) . is_some ( ) {
28692874 node_name = "mi" ; // roman numerals don't follow number rules
28702875 }
28712876
28722877 match node_name {
28732878 "mn" => return false ,
28742879 "mi" | "mo" | "mtext" => {
2875- let text = as_text ( mathml) ;
2880+ let text = as_str ! ( as_text( mathml) ) ;
28762881 let parent = get_parent ( mathml) ; // there is always a "math" node
28772882 let parent_name = name ( parent) ; // there is always a "math" node
28782883 if is_base && ( parent_name == "msub" || parent_name == "msup" || parent_name == "msubsup" ) && !text. contains ( [ ' ' , '\u{00A0}' ] ) {
@@ -2931,7 +2936,7 @@ impl NeedsToBeGrouped {
29312936 // 8. If none of the foregoing apply, the item is simply the [this element's] individual symbol.
29322937
29332938 use crate :: xpath_functions:: IsInDefinition ;
2934- let mut node_name = name ( mathml) ;
2939+ let mut node_name = as_str ! ( name( mathml) ) ;
29352940 if mathml. attribute_value ( "data-roman-numeral" ) . is_some ( ) {
29362941 node_name = "mi" ; // roman numerals don't follow number rules
29372942 }
@@ -2960,7 +2965,7 @@ impl NeedsToBeGrouped {
29602965 }
29612966 } ,
29622967 "mi" | "mo" | "mtext" => {
2963- let text = as_text ( mathml) ;
2968+ let text = as_str ! ( as_text( mathml) ) ;
29642969 let parent = get_parent ( mathml) ; // there is always a "math" node
29652970 let parent_name = name ( parent) ; // there is always a "math" node
29662971 if is_base && ( parent_name == "msub" || parent_name == "msup" || parent_name == "msubsup" ) && !text. contains ( [ ' ' , '\u{00A0}' ] ) {
@@ -3016,12 +3021,12 @@ impl Function for NeedsToBeGrouped {
30163021 "UEB" => NeedsToBeGrouped :: needs_grouping_for_ueb ( e, is_base) ,
30173022 "Finnish" => NeedsToBeGrouped :: needs_grouping_for_finnish ( e, is_base) ,
30183023 "Swedish" => NeedsToBeGrouped :: needs_grouping_for_swedish ( e, is_base) ,
3019- _ => return Err ( XPathError :: Other ( format ! ( "NeedsToBeGrouped: braille code arg '{braille_code:?}' is not a known code ('UEB', 'CMU', or 'Swedish')" ) ) ) ,
3024+ _ => return Err ( XPathError :: Other { what : format ! ( "NeedsToBeGrouped: braille code arg '{braille_code:?}' is not a known code ('UEB', 'CMU', or 'Swedish')" ) } ) ,
30203025 } ;
30213026 return Ok ( Value :: Boolean ( answer ) ) ;
30223027 }
30233028
3024- return Err ( XPathError :: Other ( format ! ( "NeedsToBeGrouped: first arg '{node:?}' is not a node" ) ) ) ;
3029+ return Err ( XPathError :: Other { what : format ! ( "NeedsToBeGrouped: first arg '{node:?}' is not a node" ) } ) ;
30253030 }
30263031}
30273032
0 commit comments