aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/LexMetapost.cxx352
1 files changed, 168 insertions, 184 deletions
diff --git a/src/LexMetapost.cxx b/src/LexMetapost.cxx
index c158f7362..b7d482c0f 100644
--- a/src/LexMetapost.cxx
+++ b/src/LexMetapost.cxx
@@ -2,7 +2,7 @@
// File: LexMetapost.cxx - general context conformant metapost coloring scheme
// Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com
-// Version: August 18, 2003
+// Version: September 28, 2003
// Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
@@ -23,6 +23,7 @@
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"
+#include "StyleContext.h"
// val SCE_METAPOST_DEFAULT = 0
// val SCE_METAPOST_SPECIAL = 1
@@ -57,24 +58,24 @@ static inline bool endOfLine(Accessor &styler, unsigned int i) {
(styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')) ;
}
-static inline bool isMETAPOSTcomment(char ch, char pc) {
+static inline bool isMETAPOSTcomment(int ch) {
return
- (ch == '%') && (pc != '\\') ;
+ (ch == '%') ;
}
-static inline bool isMETAPOSTone(char ch) {
+static inline bool isMETAPOSTone(int ch) {
return
(ch == '[') || (ch == ']') || (ch == '(') || (ch == ')') ||
(ch == ':') || (ch == '=') || (ch == '<') || (ch == '>') ||
- (ch == '{') || (ch == '}') || (ch == '\'') ; // || (ch == '\"') ;
+ (ch == '{') || (ch == '}') || (ch == '\'') || (ch == '\"') ;
}
-static inline bool isMETAPOSTtwo(char ch) {
+static inline bool isMETAPOSTtwo(int ch) {
return
(ch == ';') || (ch == '$') || (ch == '@') || (ch == '#');
}
-static inline bool isMETAPOSTthree(char ch) {
+static inline bool isMETAPOSTthree(int ch) {
return
(ch == '.') || (ch == '-') || (ch == '+') || (ch == '/') ||
(ch == '*') || (ch == ',') || (ch == '|') || (ch == '`') ||
@@ -82,189 +83,46 @@ static inline bool isMETAPOSTthree(char ch) {
(ch == '%') ;
}
-static inline bool isMETAPOSTidentifier(char ch) {
+static inline bool isMETAPOSTidentifier(int ch) {
return
((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||
(ch == '_') ;
}
-static inline bool isMETAPOSTnumber(char ch) {
+static inline bool isMETAPOSTnumber(int ch) {
return
(ch >= '0') && (ch <= '9') ;
}
-static inline bool isMETAPOSTstring(char ch) {
+static inline bool isMETAPOSTstring(int ch) {
return
(ch == '\"') ;
}
-
-// Coloring functions:
-
-bool ColourMETAPOSTRange(
- unsigned int metapostMode,
- bool texMode,
- char *key,
- unsigned int endPos,
- WordList *keywordlists[],
- int currentInterface,
- Accessor &styler) {
-
- // 0 no keyword highlighting
- // 1 metapost keyword hightlighting
- // 2+ metafun keyword hightlighting
-
- int extraInterface = 0 ;
-
- if (currentInterface != 0) {
- extraInterface = currentInterface ;
- }
-
- WordList &keywords = *keywordlists[0] ;
- WordList &keywords2 = *keywordlists[extraInterface-1] ;
-
- switch (metapostMode) {
- case 0 : // comment mode
- styler.ColourTo(endPos, SCE_METAPOST_DEFAULT) ;
- break ;
- case 1 : // special characters mode
- if (! texMode)
- { styler.ColourTo(endPos, SCE_METAPOST_SPECIAL) ; }
- else
- { styler.ColourTo(endPos, SCE_METAPOST_DEFAULT) ; }
- break ;
- case 2 : // (kind of) group mode
- if (! texMode)
- { styler.ColourTo(endPos, SCE_METAPOST_GROUP) ; }
- else
- { styler.ColourTo(endPos, SCE_METAPOST_DEFAULT) ; }
- break ;
- case 3 : // (more or less) symbol mode
- if (! texMode)
- { styler.ColourTo(endPos, SCE_METAPOST_SYMBOL) ; }
- else
- { styler.ColourTo(endPos, SCE_METAPOST_DEFAULT) ; }
- break ;
- case 4 : // command and/or keyword mode
- if (currentInterface == 0) {
- styler.ColourTo(endPos, SCE_METAPOST_TEXT) ;
- } else if (texMode) {
- if (0 == strcmp(key,"etex")) {
- styler.ColourTo(endPos, SCE_METAPOST_COMMAND) ;
- return false ;
- } else {
- styler.ColourTo(endPos, SCE_METAPOST_DEFAULT) ;
- }
- } else if ((0 == strcmp(key,"btex")) || (0 == strcmp(key,"verbatimtex"))) {
- styler.ColourTo(endPos, SCE_METAPOST_COMMAND) ;
- return true ;
- } else if (keywords && keywords.InList(key)) {
- styler.ColourTo(endPos, SCE_METAPOST_COMMAND) ;
- } else if (keywords2 && keywords2.InList(key)) {
- styler.ColourTo(endPos, SCE_METAPOST_EXTRA) ;
- } else {
- styler.ColourTo(endPos, SCE_METAPOST_TEXT) ;
- }
- break ;
- case 5 : // text mode
- if (! texMode)
- { styler.ColourTo(endPos, SCE_METAPOST_TEXT) ; }
- else
- { styler.ColourTo(endPos, SCE_METAPOST_DEFAULT) ; }
- break ;
- case 6 : // string mode
- styler.ColourTo(endPos, SCE_METAPOST_DEFAULT) ;
- break ;
- }
- return texMode ;
+static inline bool isMETAPOSTcolon(int ch) {
+ return
+ (ch == ':') ;
}
-static void ColouriseMETAPOSTLine(
- char *lineBuffer,
- unsigned int lengthLine,
- unsigned int startPos,
- WordList *keywordlists[],
- int currentInterface,
- Accessor &styler) {
-
- char ch = ' ' ;
- char pc;
- unsigned int offset = 0 ;
- unsigned int mode = 5 ;
- unsigned int k = 0 ;
- char key[1024] ; // length check in calling routine
- unsigned int start = startPos-1 ;
-
- bool comment = (styler.GetPropertyInt("lexer.metapost.comment.process", 0) == 0) ;
- bool tex = false ;
-
- // we may safely assume that pc is either on the same line or a \n \r token
- // we use a cheap append to key method, ugly, but fast and ok
-
- while (offset < lengthLine) {
-
- pc = ch ;
- ch = lineBuffer[offset] ;
-
- if (!tex && (mode == 6)) {
- if (isMETAPOSTstring(ch)) {
- // we've run into the end of the string
- tex = ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ; k = 0 ;
- mode = 5 ;
- } else {
- // we're still in the string, comment is valid
- }
- } else if ((comment) && ((mode == 0) || (isMETAPOSTcomment(ch,pc)))) {
- tex = ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ; k = 0 ;
- mode = 0 ;
- } else if (isMETAPOSTstring(ch)) {
- if (mode != 6) { tex = ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ; k = 0 ; }
- mode = 6 ;
- } else if (isMETAPOSTone(ch)) {
- if (mode != 1) { tex = ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ; k = 0 ; }
- mode = 1 ;
- } else if (isMETAPOSTtwo(ch)) {
- if (mode != 2) { tex = ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ; k = 0 ; }
- mode = 2 ;
- } else if (isMETAPOSTthree(ch)) {
- if (mode != 3) { tex = ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ; k = 0 ; }
- mode = 3 ;
- } else if (isMETAPOSTidentifier(ch)) {
- if (mode != 4) { tex = ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ; k = 0 ; }
- mode = 4 ; key[k] = ch ; ++k ; key[k] = '\0' ;
- } else if (isMETAPOSTnumber(ch)) {
- // rather redundant since for the moment we don't handle numbers
- if (mode != 5) { tex = ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ; k = 0 ; }
- mode = 5 ;
- } else {
- if (mode != 5) { tex = ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ; k = 0 ; }
- mode = 5 ;
- }
-
- ++offset ;
- ++start ;
-
- }
-
- ColourMETAPOSTRange(mode,tex,key,start,keywordlists,currentInterface,styler) ;
-
+static inline bool isMETAPOSTequal(int ch) {
+ return
+ (ch == '=') ;
}
static int CheckMETAPOSTInterface(
unsigned int startPos,
int length,
- Accessor &styler) {
+ Accessor &styler,
+ int defaultInterface) {
char lineBuffer[1024] ;
unsigned int linePos = 0 ;
- int defaultInterface = styler.GetPropertyInt("lexer.metapost.interface.default", 1) ;
-
// some day we can make something lexer.metapost.mapping=(none,0)(metapost,1)(mp,1)(metafun,2)...
if (styler.SafeGetCharAt(0) == '%') {
for (unsigned int i = 0; i < startPos + length; i++) {
- lineBuffer[linePos++] = styler[i];
+ lineBuffer[linePos++] = styler.SafeGetCharAt(i) ;
if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
lineBuffer[linePos] = '\0';
if (strstr(lineBuffer, "interface=none")) {
@@ -286,43 +144,169 @@ static int CheckMETAPOSTInterface(
return defaultInterface ;
}
-// Main handler:
-//
-// The lexer works on a per line basis. I'm not familiar with the internals of scintilla, but
-// since the lexer does not look back or forward beyond the current view, some optimization can
-// be accomplished by providing just the viewport. The following code is more or less copied
-// from the LexOthers.cxx file.
-
static void ColouriseMETAPOSTDoc(
unsigned int startPos,
int length,
- int /*initStyle*/,
+ int,
WordList *keywordlists[],
Accessor &styler) {
styler.StartAt(startPos) ;
styler.StartSegment(startPos) ;
- int currentInterface = CheckMETAPOSTInterface(startPos,length,styler) ;
+ bool processComment = styler.GetPropertyInt("lexer.metapost.comment.process", 0) == 1 ;
+ int defaultInterface = styler.GetPropertyInt("lexer.metapost.interface.default", 1) ;
- char lineBuffer[1024] ;
- unsigned int linePos = 0 ;
+ int currentInterface = CheckMETAPOSTInterface(startPos,length,styler,defaultInterface) ;
- for (unsigned int i = startPos; i < startPos + length; i++) {
- lineBuffer[linePos++] = styler[i] ;
- if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
- // End of line (or of line buffer) met, colourise it
- lineBuffer[linePos] = '\0' ;
- ColouriseMETAPOSTLine(lineBuffer, linePos, i-linePos+1, keywordlists, currentInterface, styler) ;
- linePos = 0 ;
- }
+ // 0 no keyword highlighting
+ // 1 metapost keyword hightlighting
+ // 2+ metafun keyword hightlighting
+
+ int extraInterface = 0 ;
+
+ if (currentInterface != 0) {
+ extraInterface = currentInterface ;
}
- if (linePos > 0) {
- // Last line does not have ending characters
- ColouriseMETAPOSTLine(lineBuffer, linePos, startPos+length-linePos, keywordlists, currentInterface, styler) ;
+ WordList &keywords = *keywordlists[0] ;
+ WordList &keywords2 = *keywordlists[extraInterface-1] ;
+
+ StyleContext sc(startPos, length, SCE_METAPOST_TEXT, styler) ;
+
+ char key[100] ;
+
+ bool inTeX = false ;
+ bool inComment = false ;
+ bool inString = false ;
+ bool inClause = false ;
+
+ bool going = sc.More() ; // needed because of a fuzzy end of file state
+
+ for (; going; sc.Forward()) {
+
+ if (! sc.More()) { going = false ; } // we need to go one behind the end of text
+
+ if (inClause) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ inClause = false ;
+ }
+
+ if (inComment) {
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ inTeX = false ;
+ inComment = false ;
+ inClause = false ;
+ inString = false ; // not correct but we want to stimulate one-lines
+ }
+ } else if (inString) {
+ if (isMETAPOSTstring(sc.ch)) {
+ sc.SetState(SCE_METAPOST_SPECIAL) ;
+ sc.ForwardSetState(SCE_METAPOST_TEXT) ;
+ inString = false ;
+ } else if (sc.atLineEnd) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ inTeX = false ;
+ inComment = false ;
+ inClause = false ;
+ inString = false ; // not correct but we want to stimulate one-lines
+ }
+ } else {
+ if ((! isMETAPOSTidentifier(sc.ch)) && (sc.LengthCurrent() > 0)) {
+ if (sc.state == SCE_METAPOST_COMMAND) {
+ sc.GetCurrent(key, sizeof(key)) ;
+ if ((strcmp(key,"btex") == 0) || (strcmp(key,"verbatimtex") == 0)) {
+ sc.ChangeState(SCE_METAPOST_GROUP) ;
+ inTeX = true ;
+ } else if (inTeX) {
+ if (strcmp(key,"etex") == 0) {
+ sc.ChangeState(SCE_METAPOST_GROUP) ;
+ inTeX = false ;
+ } else {
+ sc.ChangeState(SCE_METAPOST_TEXT) ;
+ }
+ } else {
+ if (keywords && keywords.InList(key)) {
+ sc.ChangeState(SCE_METAPOST_COMMAND) ;
+ } else if (keywords2 && keywords2.InList(key)) {
+ sc.ChangeState(SCE_METAPOST_EXTRA) ;
+ } else {
+ sc.ChangeState(SCE_METAPOST_TEXT) ;
+ }
+ }
+ }
+ }
+ if (isMETAPOSTcomment(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_SYMBOL) ;
+ sc.ForwardSetState(SCE_METAPOST_DEFAULT) ;
+ inComment = ! processComment ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTstring(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_SPECIAL) ;
+ if (! isMETAPOSTstring(sc.chNext)) {
+ sc.ForwardSetState(SCE_METAPOST_TEXT) ;
+ }
+ inString = true ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTcolon(sc.ch)) {
+ if (! inTeX) {
+ if (! isMETAPOSTequal(sc.chNext)) {
+ sc.SetState(SCE_METAPOST_COMMAND) ;
+ inClause = true ;
+ } else {
+ sc.SetState(SCE_METAPOST_SPECIAL) ;
+ }
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTone(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_SPECIAL) ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTtwo(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_GROUP) ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTthree(sc.ch)) {
+ if (! inTeX) {
+ sc.SetState(SCE_METAPOST_SYMBOL) ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ } else if (isMETAPOSTidentifier(sc.ch)) {
+ if (sc.state != SCE_METAPOST_COMMAND) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ sc.ChangeState(SCE_METAPOST_COMMAND) ;
+ }
+ } else if (isMETAPOSTnumber(sc.ch)) {
+ // rather redundant since for the moment we don't handle numbers
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ } else if (sc.atLineEnd) {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ inTeX = false ;
+ inComment = false ;
+ inClause = false ;
+ inString = false ;
+ } else {
+ sc.SetState(SCE_METAPOST_TEXT) ;
+ }
+ }
+
}
+ sc.Complete();
+
}
// Hooks info the system: