OSDN Git Service

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