]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexLout.cxx
492e4ed6d66230cbc17a5eb43dd2c9372f6b1f9b
[wxWidgets.git] / src / stc / scintilla / src / LexLout.cxx
1 // Scintilla source code edit control
2 /** @file LexLout.cxx
3 ** Lexer for the Basser Lout (>= version 3) typesetting language
4 **/
5 // Copyright 2003 by Kein-Hong Man <mkh@pl.jaring.my>
6 // The License.txt file describes the conditions under which this software may be distributed.
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <stdio.h>
12 #include <stdarg.h>
13
14 #include "Platform.h"
15
16 #include "PropSet.h"
17 #include "Accessor.h"
18 #include "StyleContext.h"
19 #include "KeyWords.h"
20 #include "Scintilla.h"
21 #include "SciLexer.h"
22
23 #ifdef SCI_NAMESPACE
24 using namespace Scintilla;
25 #endif
26
27 static inline bool IsAWordChar(const int ch) {
28 return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');
29 }
30
31 static inline bool IsAnOther(const int ch) {
32 return (ch < 0x80) && (ch == '{' || ch == '}' ||
33 ch == '!' || ch == '$' || ch == '%' || ch == '&' || ch == '\'' ||
34 ch == '(' || ch == ')' || ch == '*' || ch == '+' || ch == ',' ||
35 ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == ';' ||
36 ch == '<' || ch == '=' || ch == '>' || ch == '?' || ch == '[' ||
37 ch == ']' || ch == '^' || ch == '`' || ch == '|' || ch == '~');
38 }
39
40 static void ColouriseLoutDoc(unsigned int startPos, int length, int initStyle,
41 WordList *keywordlists[], Accessor &styler) {
42
43 WordList &keywords = *keywordlists[0];
44 WordList &keywords2 = *keywordlists[1];
45 WordList &keywords3 = *keywordlists[2];
46
47 int visibleChars = 0;
48 int firstWordInLine = 0;
49 int leadingAtSign = 0;
50
51 StyleContext sc(startPos, length, initStyle, styler);
52
53 for (; sc.More(); sc.Forward()) {
54
55 if (sc.atLineStart && (sc.state == SCE_LOUT_STRING)) {
56 // Prevent SCE_LOUT_STRINGEOL from leaking back to previous line
57 sc.SetState(SCE_LOUT_STRING);
58 }
59
60 // Determine if the current state should terminate.
61 if (sc.state == SCE_LOUT_COMMENT) {
62 if (sc.atLineEnd) {
63 sc.SetState(SCE_LOUT_DEFAULT);
64 visibleChars = 0;
65 }
66 } else if (sc.state == SCE_LOUT_NUMBER) {
67 if (!IsADigit(sc.ch) && sc.ch != '.') {
68 sc.SetState(SCE_LOUT_DEFAULT);
69 }
70 } else if (sc.state == SCE_LOUT_STRING) {
71 if (sc.ch == '\\') {
72 if (sc.chNext == '\"' || sc.chNext == '\\') {
73 sc.Forward();
74 }
75 } else if (sc.ch == '\"') {
76 sc.ForwardSetState(SCE_LOUT_DEFAULT);
77 } else if (sc.atLineEnd) {
78 sc.ChangeState(SCE_LOUT_STRINGEOL);
79 sc.ForwardSetState(SCE_LOUT_DEFAULT);
80 visibleChars = 0;
81 }
82 } else if (sc.state == SCE_LOUT_IDENTIFIER) {
83 if (!IsAWordChar(sc.ch)) {
84 char s[100];
85 sc.GetCurrent(s, sizeof(s));
86
87 if (leadingAtSign) {
88 if (keywords.InList(s)) {
89 sc.ChangeState(SCE_LOUT_WORD);
90 } else {
91 sc.ChangeState(SCE_LOUT_WORD4);
92 }
93 } else if (firstWordInLine && keywords3.InList(s)) {
94 sc.ChangeState(SCE_LOUT_WORD3);
95 }
96 sc.SetState(SCE_LOUT_DEFAULT);
97 }
98 } else if (sc.state == SCE_LOUT_OPERATOR) {
99 if (!IsAnOther(sc.ch)) {
100 char s[100];
101 sc.GetCurrent(s, sizeof(s));
102
103 if (keywords2.InList(s)) {
104 sc.ChangeState(SCE_LOUT_WORD2);
105 }
106 sc.SetState(SCE_LOUT_DEFAULT);
107 }
108 }
109
110 // Determine if a new state should be entered.
111 if (sc.state == SCE_LOUT_DEFAULT) {
112 if (sc.ch == '#') {
113 sc.SetState(SCE_LOUT_COMMENT);
114 } else if (sc.ch == '\"') {
115 sc.SetState(SCE_LOUT_STRING);
116 } else if (IsADigit(sc.ch) ||
117 (sc.ch == '.' && IsADigit(sc.chNext))) {
118 sc.SetState(SCE_LOUT_NUMBER);
119 } else if (IsAWordChar(sc.ch)) {
120 firstWordInLine = (visibleChars == 0);
121 leadingAtSign = (sc.ch == '@');
122 sc.SetState(SCE_LOUT_IDENTIFIER);
123 } else if (IsAnOther(sc.ch)) {
124 sc.SetState(SCE_LOUT_OPERATOR);
125 }
126 }
127
128 if (sc.atLineEnd) {
129 // Reset states to begining of colourise so no surprises
130 // if different sets of lines lexed.
131 visibleChars = 0;
132 }
133 if (!IsASpace(sc.ch)) {
134 visibleChars++;
135 }
136 }
137 sc.Complete();
138 }
139
140 static void FoldLoutDoc(unsigned int startPos, int length, int, WordList *[],
141 Accessor &styler) {
142
143 unsigned int endPos = startPos + length;
144 int visibleChars = 0;
145 int lineCurrent = styler.GetLine(startPos);
146 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
147 int levelCurrent = levelPrev;
148 char chNext = styler[startPos];
149 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
150 int styleNext = styler.StyleAt(startPos);
151 char s[10];
152
153 for (unsigned int i = startPos; i < endPos; i++) {
154 char ch = chNext;
155 chNext = styler.SafeGetCharAt(i + 1);
156 int style = styleNext;
157 styleNext = styler.StyleAt(i + 1);
158 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
159
160 if (style == SCE_LOUT_WORD) {
161 if (ch == '@') {
162 for (unsigned int j = 0; j < 8; j++) {
163 if (!IsAWordChar(styler[i + j])) {
164 break;
165 }
166 s[j] = styler[i + j];
167 s[j + 1] = '\0';
168 }
169 if (strcmp(s, "@Begin") == 0) {
170 levelCurrent++;
171 } else if (strcmp(s, "@End") == 0) {
172 levelCurrent--;
173 }
174 }
175 } else if (style == SCE_LOUT_OPERATOR) {
176 if (ch == '{') {
177 levelCurrent++;
178 } else if (ch == '}') {
179 levelCurrent--;
180 }
181 }
182 if (atEOL) {
183 int lev = levelPrev;
184 if (visibleChars == 0 && foldCompact) {
185 lev |= SC_FOLDLEVELWHITEFLAG;
186 }
187 if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
188 lev |= SC_FOLDLEVELHEADERFLAG;
189 }
190 if (lev != styler.LevelAt(lineCurrent)) {
191 styler.SetLevel(lineCurrent, lev);
192 }
193 lineCurrent++;
194 levelPrev = levelCurrent;
195 visibleChars = 0;
196 }
197 if (!isspacechar(ch))
198 visibleChars++;
199 }
200 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
201 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
202 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
203 }
204
205 static const char * const loutWordLists[] = {
206 "Predefined identifiers",
207 "Predefined delimiters",
208 "Predefined keywords",
209 0,
210 };
211
212 LexerModule lmLout(SCLEX_LOUT, ColouriseLoutDoc, "lout", FoldLoutDoc, loutWordLists);