Skip to main content

latexml_post/
lex_math.rs

1//! Lexeme-based math processor.
2//!
3//! Port of `LaTeXML::Post::LexMath`.
4//! Trivial math post-processor that supplies the lexemes string
5//! from the `lexemes` attribute of the `ltx:Math` element.
6//! Requires `--preload=llamapun.sty` to populate that attribute.
7
8use libxml::tree::Node;
9
10use crate::{
11  document::PostDocument,
12  math_processor::{MathConversion, MathProcessor},
13  processor::{ProcessResult, Processor},
14};
15
16const LEX_MIMETYPE: &str = "application/x-llamapun";
17
18/// LexMath post-processor: supplies lexeme strings as a math representation.
19///
20/// Port of `LaTeXML::Post::LexMath`.
21pub struct LexMath {
22  name:         String,
23  is_secondary: bool,
24}
25
26impl Default for LexMath {
27  fn default() -> Self { Self::new() }
28}
29
30impl LexMath {
31  pub fn new() -> Self {
32    LexMath {
33      name:         "LexMath".to_string(),
34      is_secondary: false,
35    }
36  }
37}
38
39impl Processor for LexMath {
40  fn get_name(&self) -> &str { &self.name }
41
42  fn to_process(&self, doc: &PostDocument) -> Vec<Node> {
43    doc.findnodes("//ltx:Math[not(ancestor::ltx:Math)]")
44  }
45
46  fn process(&mut self, doc: PostDocument, _nodes: Vec<Node>) -> ProcessResult { Ok(vec![doc]) }
47}
48
49impl MathProcessor for LexMath {
50  fn convert_node(&self, _doc: &PostDocument, xmath: &Node) -> Option<MathConversion> {
51    let math = xmath.get_parent()?;
52    let lexemes = math.get_attribute("lexemes")?;
53    Some(MathConversion {
54      processor_name: self.name.clone(),
55      mimetype:       Some(LEX_MIMETYPE.to_string()),
56      xml:            None,
57      string:         Some(lexemes),
58      src:            None,
59      width:          None,
60      height:         None,
61      depth:          None,
62    })
63  }
64
65  fn raw_id_suffix(&self) -> &str { ".lm" }
66
67  fn is_secondary(&self) -> bool { self.is_secondary }
68}
69
70#[cfg(test)]
71mod tests {
72  use super::*;
73
74  #[test]
75  fn lex_math_new_has_default_name() {
76    let lm = LexMath::new();
77    assert_eq!(lm.get_name(), "LexMath");
78    assert!(!lm.is_secondary);
79  }
80
81  #[test]
82  fn lex_math_default_matches_new() {
83    let a = LexMath::default();
84    let b = LexMath::new();
85    assert_eq!(a.get_name(), b.get_name());
86    assert_eq!(a.is_secondary, b.is_secondary);
87  }
88
89  #[test]
90  fn lex_math_raw_id_suffix() {
91    let lm = LexMath::new();
92    assert_eq!(lm.raw_id_suffix(), ".lm");
93  }
94
95  #[test]
96  fn lex_math_is_secondary_false_by_default() {
97    let lm = LexMath::new();
98    assert!(!lm.is_secondary());
99  }
100
101  #[test]
102  fn lex_mimetype_is_llamapun() {
103    assert_eq!(LEX_MIMETYPE, "application/x-llamapun");
104  }
105}