tectonic_xetex_format/
catcodes.rs

1// Copyright 2021 the Tectonic Project
2// Licensed under the MIT License.
3
4//! Character category codes.
5
6use std::fmt;
7use tectonic_errors::prelude::*;
8
9/// A character category code.
10///
11/// You can cast category codes as integers with a simple `c as i32` (e.g.).
12#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
13pub enum CatCode {
14    Escape = 0,
15    BeginGroup = 1,
16    EndGroup = 2,
17    MathShift = 3,
18    Tab = 4,
19    CarriageReturn = 5,
20    MacroParam = 6,
21    Superscript = 7,
22    Subscript = 8,
23    Ignored = 9,
24    Space = 10,
25    Letter = 11,
26    Other = 12,
27    Active = 13,
28    Comment = 14,
29    Invalid = 15,
30}
31
32impl CatCode {
33    pub fn abbrev(&self) -> &'static str {
34        match self {
35            CatCode::Escape => "esc",
36            CatCode::BeginGroup => "bgr",
37            CatCode::EndGroup => "egr",
38            CatCode::MathShift => "mth",
39            CatCode::Tab => "tab",
40            CatCode::CarriageReturn => "car",
41            CatCode::MacroParam => "mac",
42            CatCode::Superscript => "sup",
43            CatCode::Subscript => "sub",
44            CatCode::Ignored => "ign",
45            CatCode::Space => "spc",
46            CatCode::Letter => "let",
47            CatCode::Other => "oth",
48            CatCode::Active => "act",
49            CatCode::Comment => "com",
50            CatCode::Invalid => "inv",
51        }
52    }
53
54    pub fn description(&self) -> &'static str {
55        match self {
56            CatCode::Escape => "control-sequence escape",
57            CatCode::BeginGroup => "begin group",
58            CatCode::EndGroup => "end group",
59            CatCode::MathShift => "math shift",
60            CatCode::Tab => "tab separator",
61            CatCode::CarriageReturn => "carriage return",
62            CatCode::MacroParam => "macro parameter",
63            CatCode::Superscript => "superscript",
64            CatCode::Subscript => "subscript",
65            CatCode::Ignored => "ignored",
66            CatCode::Space => "space",
67            CatCode::Letter => "letter",
68            CatCode::Other => "other",
69            CatCode::Active => "active character",
70            CatCode::Comment => "comment",
71            CatCode::Invalid => "invalid",
72        }
73    }
74
75    pub fn from_i32(n: i32) -> Result<Self> {
76        match n {
77            0 => Ok(CatCode::Escape),
78            1 => Ok(CatCode::BeginGroup),
79            2 => Ok(CatCode::EndGroup),
80            3 => Ok(CatCode::MathShift),
81            4 => Ok(CatCode::Tab),
82            5 => Ok(CatCode::CarriageReturn),
83            6 => Ok(CatCode::MacroParam),
84            7 => Ok(CatCode::Superscript),
85            8 => Ok(CatCode::Subscript),
86            9 => Ok(CatCode::Ignored),
87            10 => Ok(CatCode::Space),
88            11 => Ok(CatCode::Letter),
89            12 => Ok(CatCode::Other),
90            13 => Ok(CatCode::Active),
91            14 => Ok(CatCode::Comment),
92            15 => Ok(CatCode::Invalid),
93            _ => {
94                bail!(
95                    "category codes must be between 0 and 15 (inclusive); got {}",
96                    n
97                );
98            }
99        }
100    }
101}
102
103impl fmt::Display for CatCode {
104    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105        write!(f, "{}", self.abbrev())
106    }
107}