ratex_parser/functions/
char_cmd.rs1use std::collections::HashMap;
2
3use crate::error::{ParseError, 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 &["\\@char"],
11 "textord",
12 1,
13 0,
14 None,
15 false,
16 true,
17 true,
18 false,
19 false,
20 handle_at_char,
21 );
22}
23
24fn handle_at_char(
25 ctx: &mut FunctionContext,
26 args: Vec<ParseNode>,
27 _opt_args: Vec<Option<ParseNode>>,
28) -> ParseResult<ParseNode> {
29 let arg = args.into_iter().next().unwrap();
30 let body = ParseNode::ord_argument(arg);
31
32 let mut number_str = String::new();
33 for node in &body {
34 if let Some(text) = node.symbol_text() {
35 number_str.push_str(text);
36 }
37 }
38
39 let code: u32 = number_str
40 .parse()
41 .map_err(|_| ParseError::msg(format!("\\@char has non-numeric argument {}", number_str)))?;
42
43 let text = char::from_u32(code)
44 .ok_or_else(|| ParseError::msg(format!("\\@char with invalid code point {}", code)))?
45 .to_string();
46
47 Ok(ParseNode::TextOrd {
51 mode: ctx.parser.mode,
52 text,
53 loc: None,
54 })
55}