Skip to main content

ratex_parser/functions/
spacing.rs

1use std::collections::HashMap;
2
3use crate::error::ParseResult;
4use crate::functions::{define_function_full, FunctionContext, FunctionSpec};
5use crate::parse_node::{Measurement, ParseNode};
6
7pub fn register(map: &mut HashMap<&'static str, FunctionSpec>) {
8    define_function_full(
9        map,
10        &[
11            "\\quad",
12            "\\qquad",
13            "\\enspace",
14            "\\thinspace",
15            "\\medspace",
16            "\\thickspace",
17            "\\negthinspace",
18            "\\negmedspace",
19            "\\negthickspace",
20            "\\nobreakspace",
21        ],
22        "spacing",
23        0,
24        0,
25        None,
26        true, // allowed_in_argument
27        true, // allowed_in_text
28        true,
29        false,
30        false,
31        handle_spacing,
32    );
33
34    define_function_full(
35        map,
36        &["\\hspace"],
37        "kern",
38        1,
39        0,
40        Some(vec![crate::functions::ArgType::Size]),
41        false,
42        true,
43        true,
44        false,
45        false,
46        handle_hspace,
47    );
48
49    // \hfill — produces a kern that fills available space
50    define_function_full(
51        map,
52        &["\\hfill"],
53        "spacing",
54        0,
55        0,
56        None,
57        false,
58        true,
59        true,
60        false,
61        false,
62        handle_spacing,
63    );
64}
65
66fn handle_spacing(
67    ctx: &mut FunctionContext,
68    _args: Vec<ParseNode>,
69    _opt_args: Vec<Option<ParseNode>>,
70) -> ParseResult<ParseNode> {
71    Ok(ParseNode::SpacingNode {
72        mode: ctx.parser.mode,
73        text: ctx.func_name.clone(),
74        loc: None,
75    })
76}
77
78fn handle_hspace(
79    ctx: &mut FunctionContext,
80    args: Vec<ParseNode>,
81    _opt_args: Vec<Option<ParseNode>>,
82) -> ParseResult<ParseNode> {
83    let dimension = if let ParseNode::Size { value, .. } = &args[0] {
84        value.clone()
85    } else {
86        Measurement {
87            number: 0.0,
88            unit: "em".to_string(),
89        }
90    };
91
92    Ok(ParseNode::Kern {
93        mode: ctx.parser.mode,
94        dimension,
95        loc: None,
96    })
97}