*** empty log message ***
[anjuta-git-plugin.git] / scintilla / LexLout.cxx
blob9d1a45a028d5dfb4b372f51931811a92cb438ad4
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.
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <stdio.h>
12 #include <stdarg.h>
14 #include "Platform.h"
16 #include "PropSet.h"
17 #include "Accessor.h"
18 #include "StyleContext.h"
19 #include "KeyWords.h"
20 #include "Scintilla.h"
21 #include "SciLexer.h"
23 static inline bool IsAWordChar(const int ch) {
24 return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');
27 static inline bool IsAnOther(const int ch) {
28 return (ch < 0x80) && (ch == '{' || ch == '}' ||
29 ch == '!' || ch == '$' || ch == '%' || ch == '&' || ch == '\'' ||
30 ch == '(' || ch == ')' || ch == '*' || ch == '+' || ch == ',' ||
31 ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == ';' ||
32 ch == '<' || ch == '=' || ch == '>' || ch == '?' || ch == '[' ||
33 ch == ']' || ch == '^' || ch == '`' || ch == '|' || ch == '~');
36 static void ColouriseLoutDoc(unsigned int startPos, int length, int initStyle,
37 WordList *keywordlists[], Accessor &styler) {
39 WordList &keywords = *keywordlists[0];
40 WordList &keywords2 = *keywordlists[1];
41 WordList &keywords3 = *keywordlists[2];
43 int visibleChars = 0;
44 int firstWordInLine = 0;
45 int leadingAtSign = 0;
47 StyleContext sc(startPos, length, initStyle, styler);
49 for (; sc.More(); sc.Forward()) {
51 if (sc.atLineStart && (sc.state == SCE_LOUT_STRING)) {
52 // Prevent SCE_LOUT_STRINGEOL from leaking back to previous line
53 sc.SetState(SCE_LOUT_STRING);
56 // Determine if the current state should terminate.
57 if (sc.state == SCE_LOUT_COMMENT) {
58 if (sc.atLineEnd) {
59 sc.SetState(SCE_LOUT_DEFAULT);
60 visibleChars = 0;
62 } else if (sc.state == SCE_LOUT_NUMBER) {
63 if (!IsADigit(sc.ch) && sc.ch != '.') {
64 sc.SetState(SCE_LOUT_DEFAULT);
66 } else if (sc.state == SCE_LOUT_STRING) {
67 if (sc.ch == '\\') {
68 if (sc.chNext == '\"' || sc.chNext == '\\') {
69 sc.Forward();
71 } else if (sc.ch == '\"') {
72 sc.ForwardSetState(SCE_LOUT_DEFAULT);
73 } else if (sc.atLineEnd) {
74 sc.ChangeState(SCE_LOUT_STRINGEOL);
75 sc.ForwardSetState(SCE_LOUT_DEFAULT);
76 visibleChars = 0;
78 } else if (sc.state == SCE_LOUT_IDENTIFIER) {
79 if (!IsAWordChar(sc.ch)) {
80 char s[100];
81 sc.GetCurrent(s, sizeof(s));
83 if (leadingAtSign) {
84 if (keywords.InList(s)) {
85 sc.ChangeState(SCE_LOUT_WORD);
86 } else {
87 sc.ChangeState(SCE_LOUT_WORD4);
89 } else if (firstWordInLine && keywords3.InList(s)) {
90 sc.ChangeState(SCE_LOUT_WORD3);
92 sc.SetState(SCE_LOUT_DEFAULT);
94 } else if (sc.state == SCE_LOUT_OPERATOR) {
95 if (!IsAnOther(sc.ch)) {
96 char s[100];
97 sc.GetCurrent(s, sizeof(s));
99 if (keywords2.InList(s)) {
100 sc.ChangeState(SCE_LOUT_WORD2);
102 sc.SetState(SCE_LOUT_DEFAULT);
106 // Determine if a new state should be entered.
107 if (sc.state == SCE_LOUT_DEFAULT) {
108 if (sc.ch == '#') {
109 sc.SetState(SCE_LOUT_COMMENT);
110 } else if (sc.ch == '\"') {
111 sc.SetState(SCE_LOUT_STRING);
112 } else if (IsADigit(sc.ch) ||
113 (sc.ch == '.' && IsADigit(sc.chNext))) {
114 sc.SetState(SCE_LOUT_NUMBER);
115 } else if (IsAWordChar(sc.ch)) {
116 firstWordInLine = (visibleChars == 0);
117 leadingAtSign = (sc.ch == '@');
118 sc.SetState(SCE_LOUT_IDENTIFIER);
119 } else if (IsAnOther(sc.ch)) {
120 sc.SetState(SCE_LOUT_OPERATOR);
124 if (sc.atLineEnd) {
125 // Reset states to begining of colourise so no surprises
126 // if different sets of lines lexed.
127 visibleChars = 0;
129 if (!IsASpace(sc.ch)) {
130 visibleChars++;
133 sc.Complete();
136 static void FoldLoutDoc(unsigned int startPos, int length, int, WordList *[],
137 Accessor &styler) {
139 unsigned int endPos = startPos + length;
140 int visibleChars = 0;
141 int lineCurrent = styler.GetLine(startPos);
142 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
143 int levelCurrent = levelPrev;
144 char chNext = styler[startPos];
145 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
146 int styleNext = styler.StyleAt(startPos);
147 char s[10];
149 for (unsigned int i = startPos; i < endPos; i++) {
150 char ch = chNext;
151 chNext = styler.SafeGetCharAt(i + 1);
152 int style = styleNext;
153 styleNext = styler.StyleAt(i + 1);
154 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
156 if (style == SCE_LOUT_WORD) {
157 if (ch == '@') {
158 for (unsigned int j = 0; j < 8; j++) {
159 if (!IsAWordChar(styler[i + j])) {
160 break;
162 s[j] = styler[i + j];
163 s[j + 1] = '\0';
165 if (strcmp(s, "@Begin") == 0) {
166 levelCurrent++;
167 } else if (strcmp(s, "@End") == 0) {
168 levelCurrent--;
171 } else if (style == SCE_LOUT_OPERATOR) {
172 if (ch == '{') {
173 levelCurrent++;
174 } else if (ch == '}') {
175 levelCurrent--;
178 if (atEOL) {
179 int lev = levelPrev;
180 if (visibleChars == 0 && foldCompact) {
181 lev |= SC_FOLDLEVELWHITEFLAG;
183 if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
184 lev |= SC_FOLDLEVELHEADERFLAG;
186 if (lev != styler.LevelAt(lineCurrent)) {
187 styler.SetLevel(lineCurrent, lev);
189 lineCurrent++;
190 levelPrev = levelCurrent;
191 visibleChars = 0;
193 if (!isspacechar(ch))
194 visibleChars++;
196 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
197 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
198 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
201 static const char * const loutWordLists[] = {
202 "Predefined identifiers",
203 "Predefined delimiters",
204 "Predefined keywords",
208 LexerModule lmLout(SCLEX_LOUT, ColouriseLoutDoc, "lout", FoldLoutDoc, loutWordLists);