@@ -1840,40 +1840,61 @@ impl CanonicalizeContext {
18401840 return ;
18411841 }
18421842
1843- let mut i = 1 ; // we look back at previous child if we detect appropriate mtext -- prev child will always exist
1844- let mut previous_child = as_element ( children [ 0 ] ) ;
1845- let mut is_previous_child_whitespace = name ( previous_child ) == "mtext" && as_text ( previous_child ) == " \u{00A0} " ;
1843+ let mut i = 0 ;
1844+ let mut previous_mtext_with_width : Option < Element < ' _ > > = None ; // prefer to spacing on previous mtext
1845+ let mut whitespace : Option < f64 > = None ;
18461846 while i < children. len ( ) {
18471847 let child = as_element ( children[ i] ) ;
18481848 let is_child_whitespace = name ( child) == "mtext" && as_text ( child) == "\u{00A0} " ;
1849- // debug!("merge_whitespace: {}", mml_to_string(child));
1850- if is_child_whitespace && is_previous_child_whitespace {
1851- // grab the width of the previous and current child, add them together
1852- let previous_width = previous_child. attribute_value ( "data-width" ) . unwrap_or ( "0" ) ;
1853- let child_width = child. attribute_value ( "data-width" ) . unwrap_or ( "0" ) ;
1854- let width = previous_width. parse :: < f64 > ( ) . unwrap_or ( 0.0 )
1855- + child_width. parse :: < f64 > ( ) . unwrap_or ( 0.0 ) ;
1856- // set the combined width on the previous child and remove the current child (don't inc 'i')
1857- previous_child. set_attribute_value ( "data-width" , & width. to_string ( ) ) ;
1858- children. remove ( i) ;
1859- // previous child is unchanged
1860- } else if is_previous_child_whitespace {
1849+ debug ! ( "merge_whitespace: i={}, whitespace={:?}, mtext set={} {}" ,
1850+ i, whitespace, previous_mtext_with_width. is_some( ) , mml_to_string( child) ) ;
1851+ if is_child_whitespace {
1852+ // update the running total of whitespace
1853+ let child_width = child. attribute_value ( "data-width" ) . unwrap_or ( "0" )
1854+ . parse :: < f64 > ( ) . unwrap_or ( 0.0 ) ;
1855+ whitespace = match whitespace {
1856+ None => Some ( child_width) ,
1857+ Some ( w) => Some ( w + child_width) ,
1858+ } ;
1859+ if children. len ( ) == 1 {
1860+ i += 1 ; // don't remove only child
1861+ } else {
1862+ children. remove ( i) ; // remove the current child (don't inc 'i')
1863+ }
1864+ } else if let Some ( ws) = whitespace {
18611865 // done with sequence of whitespaces
1862- child. set_attribute_value ( "data-previous-space-width" , previous_child. attribute_value ( "data-width" ) . unwrap ( ) ) ;
1863- children. remove ( i-1 ) ;
1864- previous_child = child;
1865- is_previous_child_whitespace = false ;
1866+ if let Some ( prev_mtext) = previous_mtext_with_width {
1867+ // prefer to set on previous mtext
1868+ prev_mtext. set_attribute_value ( "data-following-space-width" , ( ws) . to_string ( ) . as_str ( ) ) ;
1869+ previous_mtext_with_width = None ;
1870+ } else {
1871+ child. set_attribute_value ( "data-previous-space-width" , ws. to_string ( ) . as_str ( ) ) ;
1872+ if name ( child) == "mtext" {
1873+ previous_mtext_with_width = Some ( child) ;
1874+ }
1875+ }
1876+ whitespace = None ;
1877+ i += 1 ;
18661878 } else {
18671879 i += 1 ;
1868- previous_child = child;
1869- is_previous_child_whitespace = is_child_whitespace;
1880+ previous_mtext_with_width = None ;
18701881 }
18711882 }
1872- if children. len ( ) > 1 && is_previous_child_whitespace {
1873- // last child in mrow (= previous_child) is white space -- mark space *after*
1874- let non_space_child = as_element ( children[ children. len ( ) -2 ] ) ;
1875- non_space_child. set_attribute_value ( "data-following-space-width" , previous_child. attribute_value ( "data-width" ) . unwrap ( ) ) ;
1876- children. remove ( children. len ( ) -1 ) ;
1883+ debug ! ( " after loop: whitespace={:?}, {}" , whitespace, mml_to_string( as_element( children[ children. len( ) -1 ] ) ) ) ;
1884+ if let Some ( mut ws) = whitespace {
1885+ // last child in mrow is white space -- mark with space *after*
1886+ if children. len ( ) == 1 {
1887+ // only child -- check to see if we need to set the space-width
1888+ let child = as_element ( children[ 0 ] ) ;
1889+ let child_width = child. attribute_value ( "data-width" ) . unwrap_or ( "0" ) . parse :: < f64 > ( ) . unwrap_or ( 0.0 ) ;
1890+ if ( child_width - ws) . abs ( ) > 0.001 {
1891+ ws += child_width;
1892+ child. set_attribute_value ( "data-following-space-width" , ws. to_string ( ) . as_str ( ) ) ;
1893+ }
1894+ } else {
1895+ let non_space_child = as_element ( children[ children. len ( ) -1 ] ) ;
1896+ non_space_child. set_attribute_value ( "data-following-space-width" , ws. to_string ( ) . as_str ( ) ) ;
1897+ }
18771898 }
18781899 }
18791900
@@ -5572,7 +5593,7 @@ mod canonicalize_tests {
55725593 <mrow data-changed='added'>
55735594 <mi>cos</mi>
55745595 <mo data-changed='added'>⁡</mo>
5575- <mi data-previous-space-width='0.700 '>x</mi>
5596+ <mi data-previous-space-width='0.7 '>x</mi>
55765597 </mrow>
55775598 </math>" ;
55785599 assert ! ( are_strs_canonically_equal( test_str, target_str, & [ ] ) ) ;
0 commit comments