Skip to main content

retex_engine/
cmd.rs

1//! Command codes and their ranges.
2//!
3//! The numbering follows LuaTeX's `token.commands()`. TeX relies on the
4//! order of command codes: expandable commands come after `max_command`,
5//! internal quantities lie between `min_internal` and `max_internal`, and
6//! commands after `max_non_prefixed_command` are assignments.
7
8pub use crate::cmd_gen::Cmd;
9
10impl Cmd {
11    /// The largest category code of a character token (`max_char_code`).
12    pub const MAX_CHAR_CODE: Cmd = Cmd::DelimNum;
13    /// The smallest command that can follow `\the` (`min_internal`).
14    pub const MIN_INTERNAL: Cmd = Cmd::CharGiven;
15    /// The largest command that cannot be prefixed by `\global`.
16    pub const MAX_NON_PREFIXED: Cmd = Cmd::LastItem;
17    /// The largest command that can follow `\the` (`max_internal`).
18    pub const MAX_INTERNAL: Cmd = Cmd::Register;
19    /// The largest unexpandable command (`max_command`).
20    pub const MAX_COMMAND: Cmd = Cmd::SetFontId;
21
22    /// The command with numeric code `n`.
23    #[inline]
24    pub fn from_u8(n: u8) -> Cmd {
25        Cmd::ALL[n as usize]
26    }
27
28    /// Whether the command is expandable.
29    #[inline]
30    pub fn is_expandable(self) -> bool {
31        self > Cmd::MAX_COMMAND
32    }
33
34    /// Whether the command is a macro call (`call` … `long_outer_call`).
35    #[inline]
36    pub fn is_call(self) -> bool {
37        self >= Cmd::Call && self <= Cmd::LongOuterCall
38    }
39
40    /// Whether the command is an outer macro or a special outer marker
41    /// (`cur_cmd >= outer_call`).
42    #[inline]
43    pub fn is_outer_or_special(self) -> bool {
44        self >= Cmd::OuterCall
45    }
46
47    /// Whether the command denotes an internal quantity.
48    #[inline]
49    pub fn is_internal(self) -> bool {
50        self >= Cmd::MIN_INTERNAL && self <= Cmd::MAX_INTERNAL
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn ranges_are_ordered() {
60        assert!(Cmd::MAX_CHAR_CODE < Cmd::CharNum);
61        assert!(Cmd::MIN_INTERNAL <= Cmd::MAX_NON_PREFIXED);
62        assert!(Cmd::MAX_NON_PREFIXED < Cmd::ToksRegister);
63        assert!(Cmd::MAX_INTERNAL < Cmd::Advance);
64        assert!(Cmd::MAX_COMMAND < Cmd::UndefinedCs);
65        assert!(Cmd::UndefinedCs.is_expandable());
66        assert!(!Cmd::SetFontId.is_expandable());
67        assert!(Cmd::LongOuterCall.is_call());
68        assert_eq!(Cmd::from_u8(147), Cmd::Call);
69    }
70}