Skip to main content

panache_parser/syntax/
raw_tex.rs

1//! Raw TeX AST node wrappers.
2
3use super::{AstNode, PanacheLanguage, SyntaxKind, SyntaxNode};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub struct TexBlock(SyntaxNode);
7
8impl AstNode for TexBlock {
9    type Language = PanacheLanguage;
10
11    fn can_cast(kind: SyntaxKind) -> bool {
12        kind == SyntaxKind::TEX_BLOCK
13    }
14
15    fn cast(syntax: SyntaxNode) -> Option<Self> {
16        Self::can_cast(syntax.kind()).then(|| Self(syntax))
17    }
18
19    fn syntax(&self) -> &SyntaxNode {
20        &self.0
21    }
22}
23
24impl TexBlock {
25    pub fn text(&self) -> String {
26        self.0.text().to_string()
27    }
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, Hash)]
31pub struct LatexCommand(SyntaxNode);
32
33impl AstNode for LatexCommand {
34    type Language = PanacheLanguage;
35
36    fn can_cast(kind: SyntaxKind) -> bool {
37        kind == SyntaxKind::LATEX_COMMAND
38    }
39
40    fn cast(syntax: SyntaxNode) -> Option<Self> {
41        Self::can_cast(syntax.kind()).then(|| Self(syntax))
42    }
43
44    fn syntax(&self) -> &SyntaxNode {
45        &self.0
46    }
47}
48
49impl LatexCommand {
50    pub fn text(&self) -> String {
51        self.0.text().to_string()
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58    use crate::parse;
59
60    #[test]
61    fn tex_block_wrapper_casts_and_exposes_text() {
62        let tree = parse("\\newcommand{\\foo}{bar}\n", None);
63        let block = tree
64            .descendants()
65            .find_map(TexBlock::cast)
66            .expect("tex block");
67        assert!(block.text().contains("\\newcommand"));
68    }
69
70    #[test]
71    fn latex_command_wrapper_casts_and_exposes_text() {
72        let tree = parse("Inline \\cite{ref} text\n", None);
73        let cmd = tree
74            .descendants()
75            .find_map(LatexCommand::cast)
76            .expect("latex command");
77        assert_eq!(cmd.text(), "\\cite{ref}");
78    }
79}