ratex_parser/functions/
href.rs1use std::collections::HashMap;
2
3use crate::error::{ParseError, ParseResult};
4use crate::functions::{define_function_full, ArgType, FunctionContext, FunctionSpec};
5use crate::parse_node::ParseNode;
6
7pub fn register(map: &mut HashMap<&'static str, FunctionSpec>) {
8 define_function_full(
9 map,
10 &["\\href"],
11 "href",
12 2,
13 0,
14 Some(vec![ArgType::Url, ArgType::Original]),
15 false,
16 true,
17 true,
18 false,
19 false,
20 handle_href,
21 );
22
23 define_function_full(
24 map,
25 &["\\url"],
26 "href",
27 1,
28 0,
29 Some(vec![ArgType::Url]),
30 false,
31 true,
32 true,
33 false,
34 false,
35 handle_url,
36 );
37}
38
39fn handle_href(
40 ctx: &mut FunctionContext,
41 args: Vec<ParseNode>,
42 _opt_args: Vec<Option<ParseNode>>,
43) -> ParseResult<ParseNode> {
44 let mut args = args.into_iter();
45 let url_arg = args.next().unwrap();
46 let body_arg = args.next().unwrap();
47
48 let href = match url_arg {
49 ParseNode::Url { url, .. } => url,
50 _ => return Err(ParseError::msg("Expected URL")),
51 };
52
53 Ok(ParseNode::Href {
54 mode: ctx.parser.mode,
55 href,
56 body: ParseNode::ord_argument(body_arg),
57 loc: None,
58 })
59}
60
61fn handle_url(
62 ctx: &mut FunctionContext,
63 args: Vec<ParseNode>,
64 _opt_args: Vec<Option<ParseNode>>,
65) -> ParseResult<ParseNode> {
66 let url_arg = args.into_iter().next().unwrap();
67
68 let url = match &url_arg {
69 ParseNode::Url { url, .. } => url.clone(),
70 _ => return Err(ParseError::msg("Expected URL")),
71 };
72
73 let chars: Vec<ParseNode> = url
74 .chars()
75 .map(|c| ParseNode::TextOrd {
76 mode: crate::parse_node::Mode::Text,
77 text: c.to_string(),
78 loc: None,
79 })
80 .collect();
81
82 let text_node = ParseNode::Text {
83 mode: ctx.parser.mode,
84 body: chars,
85 font: Some("\\texttt".to_string()),
86 loc: None,
87 };
88
89 Ok(ParseNode::Href {
90 mode: ctx.parser.mode,
91 href: url,
92 body: vec![text_node],
93 loc: None,
94 })
95}