texlang_stdlib/
mathchardef.rs

1//! The `\mathchardef` primitive.
2use texlang::prelude as txl;
3use texlang::traits::*;
4use texlang::*;
5
6/// Get the `\mathchardef` command.
7pub fn get_mathchardef<S: TexlangState>() -> command::BuiltIn<S> {
8    command::BuiltIn::new_execution(mathchardef_primitive_fn)
9}
10
11fn mathchardef_primitive_fn<S: TexlangState>(
12    _: token::Token,
13    input: &mut vm::ExecutionInput<S>,
14) -> txl::Result<()> {
15    let scope = TexlangState::variable_assignment_scope_hook(input.state_mut());
16    // TeX.2021.1224: unlike `\mathcode`, the value is a 15-bit integer so `"8000` is not valid.
17    let (cmd_ref_or, _, c) = <(
18        Option<token::CommandRef>,
19        parse::OptionalEquals,
20        parse::Uint<32768>,
21    )>::parse(input)?;
22    let c = types::MathCode(c.0.try_into().unwrap());
23    if let Some(cmd_ref) = cmd_ref_or {
24        input
25            .commands_map_mut()
26            .insert(cmd_ref, command::Command::MathCharacter(c), scope);
27    }
28    Ok(())
29}
30
31#[cfg(test)]
32mod test {
33    use super::*;
34    use crate::the;
35    use std::collections::HashMap;
36    use texlang_testing::*;
37
38    fn built_in_commands() -> HashMap<&'static str, command::BuiltIn<State>> {
39        HashMap::from([
40            ("mathchardef", get_mathchardef()),
41            ("the", the::get_the()),
42            ("i", TestingComponent::get_integer()),
43        ])
44    }
45
46    test_suite![
47        expansion_equality_tests(
48            (
49                basic_case,
50                r"\mathchardef\Hello = `\+ \Hello",
51                "MathCode(43)"
52            ),
53            (
54                basic_case_with_the,
55                r"\mathchardef\Hello = 123 \the\Hello",
56                "123"
57            ),
58            (
59                parsable_as_number,
60                r"\mathchardef\Hello = 13 \i=\Hello x\the\i",
61                "x13"
62            ),
63            (
64                parsable_as_number_negative,
65                r"\mathchardef\Hello = 13 \i=-\Hello x\the\i",
66                "x-13"
67            ),
68        ),
69        serde_tests((basic_case, r"\mathchardef\Hello = `\+ ", r"\Hello"),),
70        recoverable_failure_tests((
71            value_too_large,
72            r#"\mathchardef\Hello = "8000 \the\Hello"#,
73            "0"
74        ),),
75    ];
76}