summaryrefslogtreecommitdiff
path: root/support/texlab/src/syntax/language.rs
blob: 3618a079fd8a3cac5eacb342a04346b175641f0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexEnvironmentCommand {
    pub name: String,
    pub index: usize,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexCitationCommand {
    pub name: String,
    pub index: usize,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum LatexLabelReferenceSource {
    Everything,
    Math,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum LatexLabelKind {
    Definition,
    Reference(LatexLabelReferenceSource),
}

impl LatexLabelKind {
    pub fn is_reference(self) -> bool {
        match self {
            LatexLabelKind::Definition => false,
            LatexLabelKind::Reference(_) => true,
        }
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexLabelCommand {
    pub name: String,
    pub index: usize,
    pub kind: LatexLabelKind,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexSectionCommand {
    pub name: String,
    pub index: usize,
    pub level: i32,
    pub prefix: String,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum LatexIncludeKind {
    Package,
    Class,
    Latex,
    Bibliography,
    Image,
    Svg,
    Pdf,
    Everything,
}

impl LatexIncludeKind {
    pub fn extensions(self) -> Option<&'static [&'static str]> {
        match self {
            LatexIncludeKind::Package => Some(&["sty"]),
            LatexIncludeKind::Class => Some(&["cls"]),
            LatexIncludeKind::Latex => Some(&["tex"]),
            LatexIncludeKind::Bibliography => Some(&["bib"]),
            LatexIncludeKind::Image => Some(&["pdf", "png", "jpg", "jpeg", "bmp"]),
            LatexIncludeKind::Svg => Some(&["svg"]),
            LatexIncludeKind::Pdf => Some(&["pdf"]),
            LatexIncludeKind::Everything => None,
        }
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexIncludeCommand {
    pub name: String,
    pub index: usize,
    pub kind: LatexIncludeKind,
    pub include_extension: bool,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexCommandDefinitionCommand {
    pub name: String,
    pub definition_index: usize,
    pub argument_count_index: usize,
    pub implementation_index: usize,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexMathOperatorCommand {
    pub name: String,
    pub definition_index: usize,
    pub implementation_index: usize,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexTheoremDefinitionCommand {
    pub name: String,
    pub index: usize,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexColorCommand {
    pub name: String,
    pub index: usize,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexColorModelCommand {
    pub name: String,
    pub index: usize,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum LatexGlossaryEntryKind {
    General,
    Acronym,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexGlossaryEntryDefinitionCommand {
    pub name: String,
    pub label_index: usize,
    pub kind: LatexGlossaryEntryKind,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LatexGlossaryEntryReferenceCommand {
    pub name: String,
    pub index: usize,
    pub kind: LatexGlossaryEntryKind,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum BibtexEntryTypeCategory {
    Misc,
    String,
    Article,
    Book,
    Collection,
    Part,
    Thesis,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BibtexEntryTypeDoc {
    pub name: String,
    pub category: BibtexEntryTypeCategory,
    pub documentation: Option<String>,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BibtexFieldDoc {
    pub name: String,
    pub documentation: String,
}

#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LanguageData {
    pub environment_commands: Vec<LatexEnvironmentCommand>,
    pub citation_commands: Vec<LatexCitationCommand>,
    pub label_commands: Vec<LatexLabelCommand>,
    pub section_commands: Vec<LatexSectionCommand>,
    pub include_commands: Vec<LatexIncludeCommand>,
    pub command_definition_commands: Vec<LatexCommandDefinitionCommand>,
    pub math_operator_commands: Vec<LatexMathOperatorCommand>,
    pub theorem_definition_commands: Vec<LatexTheoremDefinitionCommand>,
    pub colors: Vec<String>,
    pub color_commands: Vec<LatexColorCommand>,
    pub color_model_commands: Vec<LatexColorModelCommand>,
    pub glossary_entry_definition_commands: Vec<LatexGlossaryEntryDefinitionCommand>,
    pub glossary_entry_reference_commands: Vec<LatexGlossaryEntryReferenceCommand>,
    pub entry_types: Vec<BibtexEntryTypeDoc>,
    pub fields: Vec<BibtexFieldDoc>,
    pub pgf_libraries: Vec<String>,
    pub tikz_libraries: Vec<String>,
    pub math_environments: Vec<String>,
    pub enum_environments: Vec<String>,
}

impl LanguageData {
    pub fn find_entry_type(&self, name: &str) -> Option<&BibtexEntryTypeDoc> {
        let name = name.to_lowercase();
        self.entry_types
            .iter()
            .find(|ty| ty.name.to_lowercase() == name)
    }

    pub fn entry_type_documentation(&self, name: &str) -> Option<&str> {
        self.find_entry_type(name)
            .and_then(|ty| ty.documentation.as_ref().map(AsRef::as_ref))
    }

    pub fn field_documentation(&self, name: &str) -> Option<&str> {
        self.fields
            .iter()
            .find(|field| field.name.to_lowercase() == name.to_lowercase())
            .map(|field| field.documentation.as_ref())
    }
}

pub static LANGUAGE_DATA: Lazy<LanguageData> = Lazy::new(|| {
    const JSON: &str = include_str!("language.json");
    serde_json::from_str(JSON).expect("Failed to deserialize language.json")
});