ratex_parser/functions/
phantom.rs1use std::collections::HashMap;
2
3use crate::error::ParseResult;
4use crate::functions::{define_function_full, FunctionContext, FunctionSpec};
5use crate::parse_node::ParseNode;
6
7pub fn register(map: &mut HashMap<&'static str, FunctionSpec>) {
8 define_function_full(
9 map,
10 &["\\phantom"],
11 "phantom",
12 1, 0, None,
13 true, true, true, false, false,
14 handle_phantom,
15 );
16
17 define_function_full(
18 map,
19 &["\\vphantom"],
20 "vphantom",
21 1, 0, None,
22 true, true, true, false, false,
23 handle_vphantom,
24 );
25
26 define_function_full(
30 map,
31 &["\\smash"],
32 "smash",
33 1, 1, None,
34 true, true, true, false, false,
35 handle_smash,
36 );
37}
38
39fn handle_phantom(
40 ctx: &mut FunctionContext,
41 args: Vec<ParseNode>,
42 _opt_args: Vec<Option<ParseNode>>,
43) -> ParseResult<ParseNode> {
44 let body = ParseNode::ord_argument(args.into_iter().next().unwrap());
45 Ok(ParseNode::Phantom {
46 mode: ctx.parser.mode,
47 body,
48 loc: None,
49 })
50}
51
52fn handle_vphantom(
53 ctx: &mut FunctionContext,
54 args: Vec<ParseNode>,
55 _opt_args: Vec<Option<ParseNode>>,
56) -> ParseResult<ParseNode> {
57 Ok(ParseNode::VPhantom {
58 mode: ctx.parser.mode,
59 body: Box::new(args.into_iter().next().unwrap()),
60 loc: None,
61 })
62}
63
64fn handle_smash(
65 ctx: &mut FunctionContext,
66 args: Vec<ParseNode>,
67 opt_args: Vec<Option<ParseNode>>,
68) -> ParseResult<ParseNode> {
69 let mut smash_height = false;
70 let mut smash_depth = false;
71
72 if let Some(Some(ParseNode::OrdGroup { body, .. })) = opt_args.first() {
73 for node in body {
74 let text = node.symbol_text().unwrap_or("");
75 match text {
76 "t" => smash_height = true,
77 "b" => smash_depth = true,
78 _ => {
79 smash_height = false;
80 smash_depth = false;
81 break;
82 }
83 }
84 }
85 } else {
86 smash_height = true;
87 smash_depth = true;
88 }
89
90 Ok(ParseNode::Smash {
91 mode: ctx.parser.mode,
92 body: Box::new(args.into_iter().next().unwrap()),
93 smash_height,
94 smash_depth,
95 loc: None,
96 })
97}