Not really meant to be public -- used by tests in some packages
(e: &Element)
| 413 | |
| 414 | /// Not really meant to be public -- used by tests in some packages |
| 415 | pub fn trim_element(e: &Element) { |
| 416 | // "<mtext>this is text</mtext" results in 3 text children |
| 417 | // these are combined into one child as it makes code downstream simpler |
| 418 | const WHITESPACE: &[char] = &[' ', '\u{0009}', '\u{000A}', '\u{000D}']; // Rust complains if I don't give this type (from an example) |
| 419 | |
| 420 | if is_leaf(*e) { |
| 421 | // Assume it is HTML inside of the leaf -- turn the HTML into a string |
| 422 | make_leaf_element(*e); |
| 423 | return; |
| 424 | } |
| 425 | |
| 426 | let mut single_text = "".to_string(); |
| 427 | for child in e.children() { |
| 428 | match child { |
| 429 | ChildOfElement::Element(c) => { |
| 430 | trim_element(&c); |
| 431 | }, |
| 432 | ChildOfElement::Text(t) => { |
| 433 | single_text += t.text(); |
| 434 | e.remove_child(child); |
| 435 | }, |
| 436 | _ => { |
| 437 | e.remove_child(child); |
| 438 | } |
| 439 | } |
| 440 | } |
| 441 | |
| 442 | // CSS considers only space, tab, linefeed, and carriage return as collapsable whitespace |
| 443 | let trimmed_text = single_text.trim_matches(WHITESPACE); |
| 444 | if !(is_leaf(*e) || name(e) == "intent-literal" || single_text.is_empty()) { // intent-literal comes from testing intent |
| 445 | // FIX: we have a problem -- what should happen??? |
| 446 | // FIX: For now, just keep the children and ignore the text and log an error -- shouldn't panic/crash |
| 447 | if !trimmed_text.is_empty() { |
| 448 | error!("trim_element: both element and textual children which shouldn't happen -- ignoring text '{}'", single_text); |
| 449 | } |
| 450 | return; |
| 451 | } |
| 452 | if e.children().is_empty() && !single_text.is_empty() { |
| 453 | // debug!("Combining text in {}: '{}' -> '{}'", e.name().local_part(), single_text, trimmed_text); |
| 454 | e.set_text(trimmed_text); |
| 455 | } |
| 456 | |
| 457 | fn make_leaf_element(mathml_leaf: Element) { |
| 458 | // MathML leaves like <mn> really shouldn't have non-textual content, but you could have embedded HTML |
| 459 | // Here, we take convert them to leaves by grabbing up all the text and making that the content |
| 460 | // Potentially, we leave them and let (default) rules do something, but it makes other parts of the code |
| 461 | // messier because checking the text of a leaf becomes Option<&str> rather than just &str |
| 462 | let children = mathml_leaf.children(); |
| 463 | if children.is_empty() { |
| 464 | return; |
| 465 | } |
| 466 | |
| 467 | // gather up the text |
| 468 | let mut text ="".to_string(); |
| 469 | let mut previous_element_was_text = false; |
| 470 | for child in children { |
| 471 | let (child_text, space) = match child { |
| 472 | ChildOfElement::Element(child) => { |