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