highlighter_core/language.rs
1use regex::Error;
2
3use crate::lexer::LexerContext;
4
5/// The scope of a token.
6#[derive(Clone, Copy, Debug, PartialEq)]
7pub enum Scope {
8 /// A comment token, such as:
9 ///
10 /// ```
11 /// // Hello, world!
12 /// /* Hello, world! */
13 /// ```
14 /// ```html
15 /// <!-- Hello, world! -->
16 /// ```
17 Comment,
18
19 /// A numeric constant token.
20 ///
21 /// ```
22 /// 1234;
23 /// 1.3f32;
24 /// 0x42;
25 /// ```
26 ConstantNumber,
27
28 /// A character constant token.
29 ///
30 /// ```
31 /// 'A';
32 /// ```
33 ConstantChar,
34
35 /// A language constant token.
36 ///
37 /// ```
38 /// true;
39 /// false;
40 /// ```
41 ///
42 /// ```c
43 /// nullptr
44 /// ```
45 ///
46 /// ```lua
47 /// nil
48 /// ```
49 ConstantLanguage,
50
51 /// Any other constant.
52 ConstantOther,
53
54 /// A function name token.
55 ///
56 /// ```c
57 /// main();
58 /// ```
59 NameFunction,
60
61 /// A type name token.
62 ///
63 /// ```c
64 /// typedef struct Name {
65 /// int member;
66 /// } Name;
67 /// ```
68 NameType,
69
70 /// The name of a tag.
71 ///
72 /// ```html
73 /// <name></name>
74 /// ```
75 NameTag,
76
77 /// The name of a tag.
78 ///
79 /// ```markdown
80 /// ## Header
81 /// ```
82 ///
83 /// ```latex
84 /// \chapter{Chapter}
85 /// ```
86 NameSection,
87
88 /// An invalid token.
89 Invalid,
90
91 /// A deprecated case.
92 Deprecated,
93
94 /// A storage type keyword, such as `class`, `function` or `var`.
95 ///
96 /// ```c++
97 /// class MyClass {
98 /// public:
99 /// // ...
100 /// }
101 /// ```
102 ///
103 /// ```
104 /// fn main() {
105 /// println!("Hello, world!");
106 /// }
107 /// ```
108 StorageType,
109
110 /// A storage modifier keyword, such as `static`, `mut`, `final`, etc.
111 StorageModifier,
112
113 /// A quoted string token.
114 StringQuoted,
115
116 /// A string that is evaluated, such as JavaScript template strings.
117 StringEvaluated,
118
119 /// A regex string.
120 ///
121 /// ```js
122 /// /([a-zA-Z])+/g
123 /// ```
124 StringRegex,
125
126 /// Any other kind of string.
127 StringOther,
128
129 /// A function provided by the language or standard library.
130 SupportFunction,
131
132 /// A type (class, struct, etc.) provided by the language or standard library.
133 SupportType,
134
135 /// A constant provided by the language or standard library.
136 SupportConstant,
137
138 /// A variable provided by the language or standard library.
139 SupportVar,
140
141 /// Any other supporting value.
142 SupportOther,
143
144 /// A variable declared as a function parameter.
145 VariableParameter,
146
147 /// A special variable such as `super` or `this`.
148 VariableLanguage,
149
150 /// Any other variable names.
151 VariableOther,
152
153 /// A controlling keyword, such as `if`, `break`, `return`, `while`, etc.
154 KeywordControl,
155
156 /// An operator keyword, such as `instanceof`, `as`, `instance`, `or`, etc.
157 KeywordOperator,
158
159 /// An other keyword.
160 KeywordOther,
161
162 /// No scope matches this token.
163 None,
164}
165
166impl Scope {
167 /// Converts the [`Scope`]'s name to a snake case string.
168 pub fn snake_case(&self) -> &str {
169 match self {
170 Self::Comment => "comment",
171 Self::ConstantNumber => "constant_number",
172 Self::ConstantChar => "constant_char",
173 Self::ConstantLanguage => "constant_language",
174 Self::ConstantOther => "constant_other",
175 Self::NameFunction => "name_function",
176 Self::NameType => "name_type",
177 Self::NameTag => "name_tag",
178 Self::NameSection => "name_section",
179 Self::Invalid => "invalid",
180 Self::Deprecated => "deprecated",
181 Self::StorageType => "storage_type",
182 Self::StorageModifier => "storage_modifier",
183 Self::StringQuoted => "string_quoted",
184 Self::StringEvaluated => "string_evaluated",
185 Self::StringRegex => "string_regex",
186 Self::StringOther => "string_other",
187 Self::SupportFunction => "support_function",
188 Self::SupportType => "support_type",
189 Self::SupportConstant => "support_constant",
190 Self::SupportVar => "support_var",
191 Self::SupportOther => "support_other",
192 Self::VariableParameter => "variable_parameter",
193 Self::VariableLanguage => "variable_language",
194 Self::VariableOther => "variable_other",
195 Self::KeywordControl => "keyword_control",
196 Self::KeywordOperator => "keyword_operator",
197 Self::KeywordOther => "keyword_other",
198 Self::None => "none",
199 }
200 }
201
202 /// Converts the [`Scope`]'s name to a kebab case string.
203 pub fn kebab_case(&self) -> &str {
204 match self {
205 Self::Comment => "comment",
206 Self::ConstantNumber => "constant-number",
207 Self::ConstantChar => "constant-char",
208 Self::ConstantLanguage => "constant-language",
209 Self::ConstantOther => "constant-other",
210 Self::NameFunction => "name-function",
211 Self::NameType => "name-type",
212 Self::NameTag => "name-tag",
213 Self::NameSection => "name-section",
214 Self::Invalid => "invalid",
215 Self::Deprecated => "deprecated",
216 Self::StorageType => "storage-type",
217 Self::StorageModifier => "storage-modifier",
218 Self::StringQuoted => "string-quoted",
219 Self::StringEvaluated => "string-evaluated",
220 Self::StringRegex => "string-regex",
221 Self::StringOther => "string-other",
222 Self::SupportFunction => "support-function",
223 Self::SupportType => "support-type",
224 Self::SupportConstant => "support-constant",
225 Self::SupportVar => "support-var",
226 Self::SupportOther => "support-other",
227 Self::VariableParameter => "variable-parameter",
228 Self::VariableLanguage => "variable-language",
229 Self::VariableOther => "variable-other",
230 Self::KeywordControl => "keyword-control",
231 Self::KeywordOperator => "keyword-operator",
232 Self::KeywordOther => "keyword-other",
233 Self::None => "none",
234 }
235 }
236}
237
238/// A language implementation for Highlighter.
239pub trait Language {
240
241 /// Returns the name of the programming language.
242 fn name(&self) -> String;
243
244 /// Returns all of the aliases of the programming language.
245 ///
246 /// For example:
247 /// ```
248 /// vec!["js".to_owned(), "javascript".to_owned(), "jscript".to_owned(), "es".to_owned(), "ecmascript".to_owned()];
249 /// ```
250 fn names(&self) -> Vec<String> {
251 vec![self.name()]
252 }
253
254 /// Initializes the programming language.
255 fn init(&self, x: &mut LexerContext) -> Result<(), Error>;
256}