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. LuaTeX's
48 /// direction parameters (`\pardirection`, `\pardir`, …) come after
49 /// `max_internal` but are read as quantities too (observed).
50 #[inline]
51 pub fn is_internal(self) -> bool {
52 (self >= Cmd::MIN_INTERNAL && self <= Cmd::MAX_INTERNAL)
53 || matches!(self, Cmd::AssignDirection | Cmd::AssignDir)
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn ranges_are_ordered() {
63 assert!(Cmd::MAX_CHAR_CODE < Cmd::CharNum);
64 assert!(Cmd::MIN_INTERNAL <= Cmd::MAX_NON_PREFIXED);
65 assert!(Cmd::MAX_NON_PREFIXED < Cmd::ToksRegister);
66 assert!(Cmd::MAX_INTERNAL < Cmd::Advance);
67 assert!(Cmd::MAX_COMMAND < Cmd::UndefinedCs);
68 assert!(Cmd::UndefinedCs.is_expandable());
69 assert!(!Cmd::SetFontId.is_expandable());
70 assert!(Cmd::LongOuterCall.is_call());
71 assert_eq!(Cmd::from_u8(147), Cmd::Call);
72 }
73}