latexml_core/document/
helpers.rs1use libxml::tree::Node;
2
3use super::{Document, get_node_qname};
4use crate::common::{error::*, xml::XML_NS};
5
6pub fn prune_empty_para(document: &mut Document, node: &mut Node) -> Result<()> {
9 let children = node.get_child_elements();
10 if children.is_empty() {
11 let prev_is_para = match node.get_prev_element_sibling() {
12 None => false,
13 Some(prev) => {
14 if prev.get_name() == "_spilled_" {
15 prev.get_attribute("last").as_deref() == Some("ltx:para")
19 } else {
20 get_node_qname(&prev) == crate::pin!("ltx:para")
21 }
22 },
23 };
24 if !prev_is_para {
25 document.add_class(&mut node.get_parent().unwrap(), "ltx_pruned_first")?;
27 }
28 if let Some(id) = node.get_attribute_ns("id", XML_NS) {
31 if let Some(pos) = id.rfind('.') {
33 let suffix = &id[pos + 1..];
34 let prefix: String = suffix.chars().take_while(|c| !c.is_ascii_digit()).collect();
35 let ctrkey = if prefix.is_empty() {
38 "_ID_counter_".to_string()
39 } else {
40 format!("_ID_counter_{}_", prefix)
41 };
42 if let Some(mut ancestor) = node.get_parent()
43 && let Some(ctr_str) = ancestor.get_attribute(&ctrkey)
44 && let Ok(ctr) = ctr_str.parse::<u32>()
45 && ctr > 0
46 {
47 ancestor.set_attribute(&ctrkey, &(ctr - 1).to_string())?;
48 }
49 } else {
50 let prefix: String = id.chars().take_while(|c| !c.is_ascii_digit()).collect();
52 let ctrkey = if prefix.is_empty() {
55 "_ID_counter_".to_string()
56 } else {
57 format!("_ID_counter_{}_", prefix)
58 };
59 if let Some(root) = document.get_document().get_root_element() {
61 let mut root = root;
62 if let Some(ctr_str) = root.get_attribute(&ctrkey)
63 && let Ok(ctr) = ctr_str.parse::<u32>()
64 && ctr > 0
65 {
66 root.set_attribute(&ctrkey, &(ctr - 1).to_string())?;
67 }
68 }
69 }
70 document.unrecord_id(&id);
71 }
72 node.unlink();
73 }
74 Ok(())
75}