]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/lexers/LexLout.cxx
1 // Scintilla source code edit control
3 ** Lexer for the Basser Lout (>= version 3) typesetting language
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.
16 #include "Scintilla.h"
20 #include "LexAccessor.h"
22 #include "StyleContext.h"
23 #include "CharacterSet.h"
24 #include "LexerModule.h"
27 using namespace Scintilla
;
30 static inline bool IsAWordChar(const int ch
) {
31 return (ch
< 0x80) && (isalpha(ch
) || ch
== '@' || ch
== '_');
34 static inline bool IsAnOther(const int ch
) {
35 return (ch
< 0x80) && (ch
== '{' || ch
== '}' ||
36 ch
== '!' || ch
== '$' || ch
== '%' || ch
== '&' || ch
== '\'' ||
37 ch
== '(' || ch
== ')' || ch
== '*' || ch
== '+' || ch
== ',' ||
38 ch
== '-' || ch
== '.' || ch
== '/' || ch
== ':' || ch
== ';' ||
39 ch
== '<' || ch
== '=' || ch
== '>' || ch
== '?' || ch
== '[' ||
40 ch
== ']' || ch
== '^' || ch
== '`' || ch
== '|' || ch
== '~');
43 static void ColouriseLoutDoc(unsigned int startPos
, int length
, int initStyle
,
44 WordList
*keywordlists
[], Accessor
&styler
) {
46 WordList
&keywords
= *keywordlists
[0];
47 WordList
&keywords2
= *keywordlists
[1];
48 WordList
&keywords3
= *keywordlists
[2];
51 int firstWordInLine
= 0;
52 int leadingAtSign
= 0;
54 StyleContext
sc(startPos
, length
, initStyle
, styler
);
56 for (; sc
.More(); sc
.Forward()) {
58 if (sc
.atLineStart
&& (sc
.state
== SCE_LOUT_STRING
)) {
59 // Prevent SCE_LOUT_STRINGEOL from leaking back to previous line
60 sc
.SetState(SCE_LOUT_STRING
);
63 // Determine if the current state should terminate.
64 if (sc
.state
== SCE_LOUT_COMMENT
) {
66 sc
.SetState(SCE_LOUT_DEFAULT
);
69 } else if (sc
.state
== SCE_LOUT_NUMBER
) {
70 if (!IsADigit(sc
.ch
) && sc
.ch
!= '.') {
71 sc
.SetState(SCE_LOUT_DEFAULT
);
73 } else if (sc
.state
== SCE_LOUT_STRING
) {
75 if (sc
.chNext
== '\"' || sc
.chNext
== '\\') {
78 } else if (sc
.ch
== '\"') {
79 sc
.ForwardSetState(SCE_LOUT_DEFAULT
);
80 } else if (sc
.atLineEnd
) {
81 sc
.ChangeState(SCE_LOUT_STRINGEOL
);
82 sc
.ForwardSetState(SCE_LOUT_DEFAULT
);
85 } else if (sc
.state
== SCE_LOUT_IDENTIFIER
) {
86 if (!IsAWordChar(sc
.ch
)) {
88 sc
.GetCurrent(s
, sizeof(s
));
91 if (keywords
.InList(s
)) {
92 sc
.ChangeState(SCE_LOUT_WORD
);
94 sc
.ChangeState(SCE_LOUT_WORD4
);
96 } else if (firstWordInLine
&& keywords3
.InList(s
)) {
97 sc
.ChangeState(SCE_LOUT_WORD3
);
99 sc
.SetState(SCE_LOUT_DEFAULT
);
101 } else if (sc
.state
== SCE_LOUT_OPERATOR
) {
102 if (!IsAnOther(sc
.ch
)) {
104 sc
.GetCurrent(s
, sizeof(s
));
106 if (keywords2
.InList(s
)) {
107 sc
.ChangeState(SCE_LOUT_WORD2
);
109 sc
.SetState(SCE_LOUT_DEFAULT
);
113 // Determine if a new state should be entered.
114 if (sc
.state
== SCE_LOUT_DEFAULT
) {
116 sc
.SetState(SCE_LOUT_COMMENT
);
117 } else if (sc
.ch
== '\"') {
118 sc
.SetState(SCE_LOUT_STRING
);
119 } else if (IsADigit(sc
.ch
) ||
120 (sc
.ch
== '.' && IsADigit(sc
.chNext
))) {
121 sc
.SetState(SCE_LOUT_NUMBER
);
122 } else if (IsAWordChar(sc
.ch
)) {
123 firstWordInLine
= (visibleChars
== 0);
124 leadingAtSign
= (sc
.ch
== '@');
125 sc
.SetState(SCE_LOUT_IDENTIFIER
);
126 } else if (IsAnOther(sc
.ch
)) {
127 sc
.SetState(SCE_LOUT_OPERATOR
);
132 // Reset states to begining of colourise so no surprises
133 // if different sets of lines lexed.
136 if (!IsASpace(sc
.ch
)) {
143 static void FoldLoutDoc(unsigned int startPos
, int length
, int, WordList
*[],
146 unsigned int endPos
= startPos
+ length
;
147 int visibleChars
= 0;
148 int lineCurrent
= styler
.GetLine(startPos
);
149 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
150 int levelCurrent
= levelPrev
;
151 char chNext
= styler
[startPos
];
152 bool foldCompact
= styler
.GetPropertyInt("fold.compact", 1) != 0;
153 int styleNext
= styler
.StyleAt(startPos
);
156 for (unsigned int i
= startPos
; i
< endPos
; i
++) {
158 chNext
= styler
.SafeGetCharAt(i
+ 1);
159 int style
= styleNext
;
160 styleNext
= styler
.StyleAt(i
+ 1);
161 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
163 if (style
== SCE_LOUT_WORD
) {
165 for (unsigned int j
= 0; j
< 8; j
++) {
166 if (!IsAWordChar(styler
[i
+ j
])) {
169 s
[j
] = styler
[i
+ j
];
172 if (strcmp(s
, "@Begin") == 0) {
174 } else if (strcmp(s
, "@End") == 0) {
178 } else if (style
== SCE_LOUT_OPERATOR
) {
181 } else if (ch
== '}') {
187 if (visibleChars
== 0 && foldCompact
) {
188 lev
|= SC_FOLDLEVELWHITEFLAG
;
190 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0)) {
191 lev
|= SC_FOLDLEVELHEADERFLAG
;
193 if (lev
!= styler
.LevelAt(lineCurrent
)) {
194 styler
.SetLevel(lineCurrent
, lev
);
197 levelPrev
= levelCurrent
;
200 if (!isspacechar(ch
))
203 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
204 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
205 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
208 static const char * const loutWordLists
[] = {
209 "Predefined identifiers",
210 "Predefined delimiters",
211 "Predefined keywords",
215 LexerModule
lmLout(SCLEX_LOUT
, ColouriseLoutDoc
, "lout", FoldLoutDoc
, loutWordLists
);