]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexOthers.cxx
7010591430fff612b4c3c718115287f638cdf89d
[wxWidgets.git] / src / stc / scintilla / src / LexOthers.cxx
1 // Scintilla source code edit control
2 /** @file LexOthers.cxx
3 ** Lexers for batch files, diff results, properties files, make files and error lists.
4 ** Also lexer for LaTeX documents.
5 **/
6 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
7 // The License.txt file describes the conditions under which this software may be distributed.
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <stdarg.h>
14
15 #include "Platform.h"
16
17 #include "PropSet.h"
18 #include "Accessor.h"
19 #include "KeyWords.h"
20 #include "Scintilla.h"
21 #include "SciLexer.h"
22
23 static inline bool AtEOL(Accessor &styler, unsigned int i) {
24 return (styler[i] == '\n') ||
25 ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
26 }
27
28 static void ColouriseBatchLine(
29 char *lineBuffer,
30 unsigned int lengthLine,
31 unsigned int startLine,
32 unsigned int endPos,
33 WordList &keywords,
34 Accessor &styler) {
35
36 unsigned int i = 0;
37 unsigned int state = SCE_BAT_DEFAULT;
38
39 while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip initial spaces
40 i++;
41 }
42 if (lineBuffer[i] == '@') { // Hide command (ECHO OFF)
43 styler.ColourTo(startLine + i, SCE_BAT_HIDE);
44 i++;
45 while ((i < lengthLine) && isspacechar(lineBuffer[i])) { // Skip next spaces
46 i++;
47 }
48 }
49 if (lineBuffer[i] == ':') {
50 // Label
51 if (lineBuffer[i + 1] == ':') {
52 // :: is a fake label, similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm
53 styler.ColourTo(endPos, SCE_BAT_COMMENT);
54 } else { // Real label
55 styler.ColourTo(endPos, SCE_BAT_LABEL);
56 }
57 } else {
58 // Check if initial word is a keyword
59 char wordBuffer[21];
60 unsigned int wbl = 0, offset = i;
61 // Copy word in buffer
62 for (; offset < lengthLine && wbl < 20 &&
63 !isspacechar(lineBuffer[offset]); wbl++, offset++) {
64 wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));
65 }
66 wordBuffer[wbl] = '\0';
67 // Check if it is a comment
68 if (CompareCaseInsensitive(wordBuffer, "rem") == 0) {
69 styler.ColourTo(endPos, SCE_BAT_COMMENT);
70 return ;
71 }
72 // Check if it is in the list
73 if (keywords.InList(wordBuffer)) {
74 styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); // Regular keyword
75 } else {
76 // Search end of word (can be a long path)
77 while (offset < lengthLine &&
78 !isspacechar(lineBuffer[offset])) {
79 offset++;
80 }
81 styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); // External command / program
82 }
83 // Remainder of the line: colourise the variables.
84
85 while (offset < lengthLine) {
86 if (state == SCE_BAT_DEFAULT && lineBuffer[offset] == '%') {
87 styler.ColourTo(startLine + offset - 1, state);
88 if (isdigit(lineBuffer[offset + 1])) {
89 styler.ColourTo(startLine + offset + 1, SCE_BAT_IDENTIFIER);
90 offset += 2;
91 } else if (lineBuffer[offset + 1] == '%' &&
92 !isspacechar(lineBuffer[offset + 2])) {
93 // Should be safe, as there is CRLF at the end of the line...
94 styler.ColourTo(startLine + offset + 2, SCE_BAT_IDENTIFIER);
95 offset += 3;
96 } else {
97 state = SCE_BAT_IDENTIFIER;
98 }
99 } else if (state == SCE_BAT_IDENTIFIER && lineBuffer[offset] == '%') {
100 styler.ColourTo(startLine + offset, state);
101 state = SCE_BAT_DEFAULT;
102 } else if (state == SCE_BAT_DEFAULT &&
103 (lineBuffer[offset] == '*' ||
104 lineBuffer[offset] == '?' ||
105 lineBuffer[offset] == '=' ||
106 lineBuffer[offset] == '<' ||
107 lineBuffer[offset] == '>' ||
108 lineBuffer[offset] == '|')) {
109 styler.ColourTo(startLine + offset - 1, state);
110 styler.ColourTo(startLine + offset, SCE_BAT_OPERATOR);
111 }
112 offset++;
113 }
114 // if (endPos > startLine + offset - 1) {
115 styler.ColourTo(endPos, SCE_BAT_DEFAULT); // Remainder of line, currently not lexed
116 // }
117 }
118
119 }
120 // ToDo: (not necessarily at beginning of line) GOTO, [IF] NOT, ERRORLEVEL
121 // IF [NO] (test) (command) -- test is EXIST (filename) | (string1)==(string2) | ERRORLEVEL (number)
122 // FOR %%(variable) IN (set) DO (command) -- variable is [a-zA-Z] -- eg for %%X in (*.txt) do type %%X
123 // ToDo: %n (parameters), %EnvironmentVariable% colourising
124 // ToDo: Colourise = > >> < | "
125
126 static void ColouriseBatchDoc(
127 unsigned int startPos,
128 int length,
129 int /*initStyle*/,
130 WordList *keywordlists[],
131 Accessor &styler) {
132
133 char lineBuffer[1024];
134 WordList &keywords = *keywordlists[0];
135
136 styler.StartAt(startPos);
137 styler.StartSegment(startPos);
138 unsigned int linePos = 0;
139 unsigned int startLine = startPos;
140 for (unsigned int i = startPos; i < startPos + length; i++) {
141 lineBuffer[linePos++] = styler[i];
142 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
143 // End of line (or of line buffer) met, colourise it
144 lineBuffer[linePos] = '\0';
145 ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywords, styler);
146 linePos = 0;
147 startLine = i + 1;
148 }
149 }
150 if (linePos > 0) { // Last line does not have ending characters
151 ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1,
152 keywords, styler);
153 }
154 }
155
156 static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
157 // It is needed to remember the current state to recognize starting
158 // comment lines before the first "diff " or "--- ". If a real
159 // difference starts then each line starting with ' ' is a whitespace
160 // otherwise it is considered a comment (Only in..., Binary file...)
161 if (0 == strncmp(lineBuffer, "diff ", 3)) {
162 styler.ColourTo(endLine, SCE_DIFF_COMMAND);
163 } else if (0 == strncmp(lineBuffer, "--- ", 3)) {
164 styler.ColourTo(endLine, SCE_DIFF_HEADER);
165 } else if (0 == strncmp(lineBuffer, "+++ ", 3)) {
166 styler.ColourTo(endLine, SCE_DIFF_HEADER);
167 } else if (0 == strncmp(lineBuffer, "***", 3)) {
168 styler.ColourTo(endLine, SCE_DIFF_HEADER);
169 } else if (lineBuffer[0] == '@') {
170 styler.ColourTo(endLine, SCE_DIFF_POSITION);
171 } else if (lineBuffer[0] == '-') {
172 styler.ColourTo(endLine, SCE_DIFF_DELETED);
173 } else if (lineBuffer[0] == '+') {
174 styler.ColourTo(endLine, SCE_DIFF_ADDED);
175 } else if (lineBuffer[0] != ' ') {
176 styler.ColourTo(endLine, SCE_DIFF_COMMENT);
177 } else {
178 styler.ColourTo(endLine, SCE_DIFF_DEFAULT);
179 }
180 }
181
182 static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
183 char lineBuffer[1024];
184 styler.StartAt(startPos);
185 styler.StartSegment(startPos);
186 unsigned int linePos = 0;
187 for (unsigned int i = startPos; i < startPos + length; i++) {
188 lineBuffer[linePos++] = styler[i];
189 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
190 // End of line (or of line buffer) met, colourise it
191 lineBuffer[linePos] = '\0';
192 ColouriseDiffLine(lineBuffer, i, styler);
193 linePos = 0;
194 }
195 }
196 if (linePos > 0) { // Last line does not have ending characters
197 ColouriseDiffLine(lineBuffer, startPos + length - 1, styler);
198 }
199 }
200
201 static void ColourisePropsLine(
202 char *lineBuffer,
203 unsigned int lengthLine,
204 unsigned int startLine,
205 unsigned int endPos,
206 Accessor &styler) {
207
208 unsigned int i = 0;
209 while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
210 i++;
211 if (i < lengthLine) {
212 if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {
213 styler.ColourTo(endPos, SCE_PROPS_COMMENT);
214 } else if (lineBuffer[i] == '[') {
215 styler.ColourTo(endPos, SCE_PROPS_SECTION);
216 } else if (lineBuffer[i] == '@') {
217 styler.ColourTo(startLine + i, SCE_PROPS_DEFVAL);
218 if (lineBuffer[++i] == '=')
219 styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
220 styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
221 } else {
222 // Search for the '=' character
223 while ((i < lengthLine) && (lineBuffer[i] != '='))
224 i++;
225 if ((i < lengthLine) && (lineBuffer[i] == '=')) {
226 styler.ColourTo(startLine + i - 1, SCE_PROPS_DEFAULT);
227 styler.ColourTo(startLine + i, 3);
228 styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
229 } else {
230 styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
231 }
232 }
233 } else {
234 styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
235 }
236 }
237
238 static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
239 char lineBuffer[1024];
240 styler.StartAt(startPos);
241 styler.StartSegment(startPos);
242 unsigned int linePos = 0;
243 unsigned int startLine = startPos;
244 for (unsigned int i = startPos; i < startPos + length; i++) {
245 lineBuffer[linePos++] = styler[i];
246 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
247 // End of line (or of line buffer) met, colourise it
248 lineBuffer[linePos] = '\0';
249 ColourisePropsLine(lineBuffer, linePos, startLine, i, styler);
250 linePos = 0;
251 startLine = i + 1;
252 }
253 }
254 if (linePos > 0) { // Last line does not have ending characters
255 ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
256 }
257 }
258
259 static void ColouriseMakeLine(
260 char *lineBuffer,
261 unsigned int lengthLine,
262 unsigned int startLine,
263 unsigned int endPos,
264 Accessor &styler) {
265
266 unsigned int i = 0;
267 unsigned int lastNonSpace = 0;
268 unsigned int state = SCE_MAKE_DEFAULT;
269 bool bSpecial = false;
270 // Skip initial spaces
271 while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
272 i++;
273 }
274 if (lineBuffer[i] == '#') { // Comment
275 styler.ColourTo(endPos, SCE_MAKE_COMMENT);
276 return;
277 }
278 if (lineBuffer[i] == '!') { // Special directive
279 styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
280 return;
281 }
282 while (i < lengthLine) {
283 if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
284 styler.ColourTo(startLine + i - 1, state);
285 state = SCE_MAKE_IDENTIFIER;
286 } else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
287 styler.ColourTo(startLine + i, state);
288 state = SCE_MAKE_DEFAULT;
289 }
290 if (!bSpecial) {
291 if (lineBuffer[i] == ':') {
292 // We should check that no colouring was made since the beginning of the line,
293 // to avoid colouring stuff like /OUT:file
294 styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
295 styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
296 styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
297 bSpecial = true; // Only react to the first ':' of the line
298 state = SCE_MAKE_DEFAULT;
299 } else if (lineBuffer[i] == '=') {
300 styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
301 styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
302 styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
303 bSpecial = true; // Only react to the first '=' of the line
304 state = SCE_MAKE_DEFAULT;
305 }
306 }
307 if (!isspacechar(lineBuffer[i])) {
308 lastNonSpace = i;
309 }
310 i++;
311 }
312 if (state == SCE_MAKE_IDENTIFIER) {
313 styler.ColourTo(endPos, SCE_MAKE_IDEOL); // Error, variable reference not ended
314 } else {
315 styler.ColourTo(endPos, SCE_MAKE_DEFAULT);
316 }
317 }
318
319 static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
320 char lineBuffer[1024];
321 styler.StartAt(startPos);
322 styler.StartSegment(startPos);
323 unsigned int linePos = 0;
324 unsigned int startLine = startPos;
325 for (unsigned int i = startPos; i < startPos + length; i++) {
326 lineBuffer[linePos++] = styler[i];
327 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
328 // End of line (or of line buffer) met, colourise it
329 lineBuffer[linePos] = '\0';
330 ColouriseMakeLine(lineBuffer, linePos, startLine, i, styler);
331 linePos = 0;
332 startLine = i + 1;
333 }
334 }
335 if (linePos > 0) { // Last line does not have ending characters
336 ColouriseMakeLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
337 }
338 }
339
340 static void ColouriseErrorListLine(
341 char *lineBuffer,
342 unsigned int lengthLine,
343 // unsigned int startLine,
344 unsigned int endPos,
345 Accessor &styler) {
346 if (lineBuffer[0] == '>') {
347 // Command or return status
348 styler.ColourTo(endPos, SCE_ERR_CMD);
349 } else if (lineBuffer[0] == '!') {
350 styler.ColourTo(endPos, SCE_ERR_DIFF_CHANGED);
351 } else if (lineBuffer[0] == '+') {
352 styler.ColourTo(endPos, SCE_ERR_DIFF_ADDITION);
353 } else if (lineBuffer[0] == '-' && lineBuffer[1] == '-' && lineBuffer[2] == '-') {
354 styler.ColourTo(endPos, SCE_ERR_DIFF_MESSAGE);
355 } else if (lineBuffer[0] == '-') {
356 styler.ColourTo(endPos, SCE_ERR_DIFF_DELETION);
357 } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) {
358 styler.ColourTo(endPos, SCE_ERR_PYTHON);
359 } else if (0 == strncmp(lineBuffer, "Error ", strlen("Error "))) {
360 // Borland error message
361 styler.ColourTo(endPos, SCE_ERR_BORLAND);
362 } else if (0 == strncmp(lineBuffer, "Warning ", strlen("Warning "))) {
363 // Borland warning message
364 styler.ColourTo(endPos, SCE_ERR_BORLAND);
365 } else if (strstr(lineBuffer, "at line " ) &&
366 (strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) &&
367 strstr(lineBuffer, "file ") &&
368 (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
369 // Lua error message
370 styler.ColourTo(endPos, SCE_ERR_LUA);
371 } else if (strstr(lineBuffer, " at " ) &&
372 (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) &&
373 strstr(lineBuffer, " line ") &&
374 (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine))) {
375 // perl error message
376 styler.ColourTo(endPos, SCE_ERR_PERL);
377 } else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
378 strstr(lineBuffer, ":line ")) {
379 // A .NET traceback
380 styler.ColourTo(endPos, SCE_ERR_NET);
381 } else {
382 // Look for <filename>:<line>:message
383 // Look for <filename>(line)message
384 // Look for <filename>(line,pos)message
385 int state = 0;
386 for (unsigned int i = 0; i < lengthLine; i++) {
387 if ((state == 0) && (lineBuffer[i] == ':') && isdigit(lineBuffer[i + 1])) {
388 state = 1;
389 } else if ((state == 0) && (lineBuffer[i] == '(')) {
390 state = 10;
391 } else if ((state == 0) && (lineBuffer[i] == '\t')) {
392 state = 20;
393 } else if ((state == 1) && isdigit(lineBuffer[i])) {
394 state = 2;
395 } else if ((state == 2) && (lineBuffer[i] == ':')) {
396 state = 3;
397 break;
398 } else if ((state == 2) && !isdigit(lineBuffer[i])) {
399 state = 99;
400 } else if ((state == 10) && isdigit(lineBuffer[i])) {
401 state = 11;
402 } else if ((state == 11) && (lineBuffer[i] == ',')) {
403 state = 14;
404 } else if ((state == 11) && (lineBuffer[i] == ')')) {
405 state = 12;
406 } else if ((state == 12) && (lineBuffer[i] == ':')) {
407 state = 13;
408 } else if ((state == 14) && (lineBuffer[i] == ')')) {
409 state = 15;
410 break;
411 } else if (((state == 11) || (state == 14)) && !((lineBuffer[i] == ' ') || isdigit(lineBuffer[i]))) {
412 state = 99;
413 } else if ((state == 20) && isdigit(lineBuffer[i])) {
414 state = 24;
415 break;
416 } else if ((state == 20) && ((lineBuffer[i] == '/') && (lineBuffer[i+1] == '^'))) {
417 state = 21;
418 } else if ((state == 21) && ((lineBuffer[i] == '$') && (lineBuffer[i+1] == '/'))) {
419 state = 22;
420 break;
421 }
422 }
423 if (state == 3) {
424 styler.ColourTo(endPos, SCE_ERR_GCC);
425 } else if ((state == 13) || (state == 14) || (state == 15)) {
426 styler.ColourTo(endPos, SCE_ERR_MS);
427 } else if (((state == 22) || (state == 24)) && (lineBuffer[0] != '\t')) {
428 styler.ColourTo(endPos, SCE_ERR_CTAG);
429 } else {
430 styler.ColourTo(endPos, SCE_ERR_DEFAULT);
431 }
432 }
433 }
434
435 static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
436 char lineBuffer[1024];
437 styler.StartAt(startPos);
438 styler.StartSegment(startPos);
439 unsigned int linePos = 0;
440 for (unsigned int i = startPos; i < startPos + length; i++) {
441 lineBuffer[linePos++] = styler[i];
442 if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
443 // End of line (or of line buffer) met, colourise it
444 lineBuffer[linePos] = '\0';
445 ColouriseErrorListLine(lineBuffer, linePos, i, styler);
446 linePos = 0;
447 }
448 }
449 if (linePos > 0) { // Last line does not have ending characters
450 ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler);
451 }
452 }
453
454 static int isSpecial(char s) {
455 return (s == '\\') || (s == ',') || (s == ';') || (s == '\'') || (s == ' ') ||
456 (s == '\"') || (s == '`') || (s == '^') || (s == '~');
457 }
458
459 static int isTag(int start, Accessor &styler) {
460 char s[6];
461 unsigned int i = 0, e = 1;
462 while (i < 5 && e) {
463 s[i] = styler[start + i];
464 i++;
465 e = styler[start + i] != '{';
466 }
467 s[i] = '\0';
468 return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0);
469 }
470
471 static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
472 WordList *[], Accessor &styler) {
473
474 styler.StartAt(startPos);
475
476 int state = initStyle;
477 char chNext = styler[startPos];
478 styler.StartSegment(startPos);
479 int lengthDoc = startPos + length;
480
481 for (int i = startPos; i < lengthDoc; i++) {
482 char ch = chNext;
483 chNext = styler.SafeGetCharAt(i + 1);
484
485 if (styler.IsLeadByte(ch)) {
486 chNext = styler.SafeGetCharAt(i + 2);
487 i++;
488 continue;
489 }
490 switch (state) {
491 case SCE_L_DEFAULT :
492 switch (ch) {
493 case '\\' :
494 styler.ColourTo(i - 1, state);
495 if (isSpecial(styler[i + 1])) {
496 styler.ColourTo(i + 1, SCE_L_COMMAND);
497 i++;
498 chNext = styler.SafeGetCharAt(i + 1);
499 } else {
500 if (isTag(i + 1, styler))
501 state = SCE_L_TAG;
502 else
503 state = SCE_L_COMMAND;
504 }
505 break;
506 case '$' :
507 styler.ColourTo(i - 1, state);
508 state = SCE_L_MATH;
509 if (chNext == '$') {
510 i++;
511 chNext = styler.SafeGetCharAt(i + 1);
512 }
513 break;
514 case '%' :
515 styler.ColourTo(i - 1, state);
516 state = SCE_L_COMMENT;
517 break;
518 }
519 break;
520 case SCE_L_COMMAND :
521 if (chNext == '[' || chNext == '{' || chNext == '}' ||
522 chNext == ' ' || chNext == '\r' || chNext == '\n') {
523 styler.ColourTo(i, state);
524 state = SCE_L_DEFAULT;
525 i++;
526 chNext = styler.SafeGetCharAt(i + 1);
527 }
528 break;
529 case SCE_L_TAG :
530 if (ch == '}') {
531 styler.ColourTo(i, state);
532 state = SCE_L_DEFAULT;
533 }
534 break;
535 case SCE_L_MATH :
536 if (ch == '$') {
537 if (chNext == '$') {
538 i++;
539 chNext = styler.SafeGetCharAt(i + 1);
540 }
541 styler.ColourTo(i, state);
542 state = SCE_L_DEFAULT;
543 }
544 break;
545 case SCE_L_COMMENT :
546 if (ch == '\r' || ch == '\n') {
547 styler.ColourTo(i - 1, state);
548 state = SCE_L_DEFAULT;
549 }
550 }
551 }
552 styler.ColourTo(lengthDoc, state);
553 }
554
555 LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch");
556 LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff");
557 LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props");
558 LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile");
559 LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist");
560 LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex");