2009-04-24 23:35:41 +00:00
// Scintilla source code edit control
/** @file LexHTML.cxx
* * Lexer for HTML .
* */
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
# include <stdlib.h>
# include <string.h>
# include <stdio.h>
# include <stdarg.h>
2010-08-21 23:59:56 +00:00
# include <assert.h>
# include <ctype.h>
2009-04-24 23:35:41 +00:00
2010-08-21 23:59:56 +00:00
# include "ILexer.h"
# include "Scintilla.h"
# include "SciLexer.h"
2009-04-24 23:35:41 +00:00
2010-08-21 23:59:56 +00:00
# include "WordList.h"
# include "LexAccessor.h"
2009-04-24 23:35:41 +00:00
# include "Accessor.h"
# include "StyleContext.h"
# include "CharacterSet.h"
2010-08-21 23:59:56 +00:00
# include "LexerModule.h"
2009-04-24 23:35:41 +00:00
# ifdef SCI_NAMESPACE
using namespace Scintilla ;
# endif
# define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START)
# define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START)
# define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START)
2009-04-25 23:38:15 +00:00
enum script_type { eScriptNone = 0 , eScriptJS , eScriptVBS , eScriptPython , eScriptPHP , eScriptXML , eScriptSGML , eScriptSGMLblock , eScriptComment } ;
2009-04-24 23:35:41 +00:00
enum script_mode { eHtml = 0 , eNonHtmlScript , eNonHtmlPreProc , eNonHtmlScriptPreProc } ;
static inline bool IsAWordChar ( const int ch ) {
return ( ch < 0x80 ) & & ( isalnum ( ch ) | | ch = = ' . ' | | ch = = ' _ ' ) ;
}
static inline bool IsAWordStart ( const int ch ) {
return ( ch < 0x80 ) & & ( isalnum ( ch ) | | ch = = ' _ ' ) ;
}
inline bool IsOperator ( int ch ) {
if ( isascii ( ch ) & & isalnum ( ch ) )
return false ;
// '.' left out as it is used to make up numbers
if ( ch = = ' % ' | | ch = = ' ^ ' | | ch = = ' & ' | | ch = = ' * ' | |
ch = = ' ( ' | | ch = = ' ) ' | | ch = = ' - ' | | ch = = ' + ' | |
ch = = ' = ' | | ch = = ' | ' | | ch = = ' { ' | | ch = = ' } ' | |
ch = = ' [ ' | | ch = = ' ] ' | | ch = = ' : ' | | ch = = ' ; ' | |
ch = = ' < ' | | ch = = ' > ' | | ch = = ' , ' | | ch = = ' / ' | |
ch = = ' ? ' | | ch = = ' ! ' | | ch = = ' . ' | | ch = = ' ~ ' )
return true ;
return false ;
}
static void GetTextSegment ( Accessor & styler , unsigned int start , unsigned int end , char * s , size_t len ) {
2013-08-28 00:44:27 +00:00
unsigned int i = 0 ;
2009-04-24 23:35:41 +00:00
for ( ; ( i < end - start + 1 ) & & ( i < len - 1 ) ; i + + ) {
s [ i ] = static_cast < char > ( MakeLowerCase ( styler [ start + i ] ) ) ;
}
s [ i ] = ' \0 ' ;
}
2010-07-12 22:19:51 +00:00
static const char * GetNextWord ( Accessor & styler , unsigned int start , char * s , size_t sLen ) {
2013-08-28 00:44:27 +00:00
unsigned int i = 0 ;
2010-07-12 22:19:51 +00:00
for ( ; i < sLen - 1 ; i + + ) {
char ch = static_cast < char > ( styler . SafeGetCharAt ( start + i ) ) ;
if ( ( i = = 0 ) & & ! IsAWordStart ( ch ) )
break ;
if ( ( i > 0 ) & & ! IsAWordChar ( ch ) )
break ;
s [ i ] = ch ;
}
s [ i ] = ' \0 ' ;
return s ;
}
2009-04-24 23:35:41 +00:00
static script_type segIsScriptingIndicator ( Accessor & styler , unsigned int start , unsigned int end , script_type prevValue ) {
char s [ 100 ] ;
GetTextSegment ( styler , start , end , s , sizeof ( s ) ) ;
//Platform::DebugPrintf("Scripting indicator [%s]\n", s);
//if (strstr(s, "src")) // External script
//return eScriptNone;
if ( strstr ( s , " vbs " ) )
return eScriptVBS ;
if ( strstr ( s , " pyth " ) )
return eScriptPython ;
if ( strstr ( s , " javas " ) )
return eScriptJS ;
if ( strstr ( s , " jscr " ) )
return eScriptJS ;
if ( strstr ( s , " php " ) )
return eScriptPHP ;
if ( strstr ( s , " xml " ) ) {
const char * xml = strstr ( s , " xml " ) ;
for ( const char * t = s ; t < xml ; t + + ) {
if ( ! IsASpace ( * t ) ) {
return prevValue ;
}
}
return eScriptXML ;
}
return prevValue ;
}
static int PrintScriptingIndicatorOffset ( Accessor & styler , unsigned int start , unsigned int end ) {
int iResult = 0 ;
char s [ 100 ] ;
GetTextSegment ( styler , start , end , s , sizeof ( s ) ) ;
if ( 0 = = strncmp ( s , " php " , 3 ) ) {
iResult = 3 ;
}
return iResult ;
}
static script_type ScriptOfState ( int state ) {
if ( ( state > = SCE_HP_START ) & & ( state < = SCE_HP_IDENTIFIER ) ) {
return eScriptPython ;
} else if ( ( state > = SCE_HB_START ) & & ( state < = SCE_HB_STRINGEOL ) ) {
return eScriptVBS ;
} else if ( ( state > = SCE_HJ_START ) & & ( state < = SCE_HJ_REGEX ) ) {
return eScriptJS ;
} else if ( ( state > = SCE_HPHP_DEFAULT ) & & ( state < = SCE_HPHP_COMMENTLINE ) ) {
return eScriptPHP ;
} else if ( ( state > = SCE_H_SGML_DEFAULT ) & & ( state < SCE_H_SGML_BLOCK_DEFAULT ) ) {
return eScriptSGML ;
} else if ( state = = SCE_H_SGML_BLOCK_DEFAULT ) {
return eScriptSGMLblock ;
} else {
return eScriptNone ;
}
}
static int statePrintForState ( int state , script_mode inScriptType ) {
int StateToPrint = state ;
if ( state > = SCE_HJ_START ) {
if ( ( state > = SCE_HP_START ) & & ( state < = SCE_HP_IDENTIFIER ) ) {
StateToPrint = state + ( ( inScriptType = = eNonHtmlScript ) ? 0 : SCE_HA_PYTHON ) ;
} else if ( ( state > = SCE_HB_START ) & & ( state < = SCE_HB_STRINGEOL ) ) {
StateToPrint = state + ( ( inScriptType = = eNonHtmlScript ) ? 0 : SCE_HA_VBS ) ;
} else if ( ( state > = SCE_HJ_START ) & & ( state < = SCE_HJ_REGEX ) ) {
StateToPrint = state + ( ( inScriptType = = eNonHtmlScript ) ? 0 : SCE_HA_JS ) ;
}
}
return StateToPrint ;
}
static int stateForPrintState ( int StateToPrint ) {
int state ;
if ( ( StateToPrint > = SCE_HPA_START ) & & ( StateToPrint < = SCE_HPA_IDENTIFIER ) ) {
state = StateToPrint - SCE_HA_PYTHON ;
} else if ( ( StateToPrint > = SCE_HBA_START ) & & ( StateToPrint < = SCE_HBA_STRINGEOL ) ) {
state = StateToPrint - SCE_HA_VBS ;
} else if ( ( StateToPrint > = SCE_HJA_START ) & & ( StateToPrint < = SCE_HJA_REGEX ) ) {
state = StateToPrint - SCE_HA_JS ;
} else {
state = StateToPrint ;
}
return state ;
}
static inline bool IsNumber ( unsigned int start , Accessor & styler ) {
return IsADigit ( styler [ start ] ) | | ( styler [ start ] = = ' . ' ) | |
( styler [ start ] = = ' - ' ) | | ( styler [ start ] = = ' # ' ) ;
}
static inline bool isStringState ( int state ) {
bool bResult ;
switch ( state ) {
case SCE_HJ_DOUBLESTRING :
case SCE_HJ_SINGLESTRING :
case SCE_HJA_DOUBLESTRING :
case SCE_HJA_SINGLESTRING :
case SCE_HB_STRING :
case SCE_HBA_STRING :
case SCE_HP_STRING :
case SCE_HP_CHARACTER :
case SCE_HP_TRIPLE :
case SCE_HP_TRIPLEDOUBLE :
case SCE_HPA_STRING :
case SCE_HPA_CHARACTER :
case SCE_HPA_TRIPLE :
case SCE_HPA_TRIPLEDOUBLE :
case SCE_HPHP_HSTRING :
case SCE_HPHP_SIMPLESTRING :
case SCE_HPHP_HSTRING_VARIABLE :
case SCE_HPHP_COMPLEX_VARIABLE :
bResult = true ;
break ;
default :
bResult = false ;
break ;
}
return bResult ;
}
static inline bool stateAllowsTermination ( int state ) {
bool allowTermination = ! isStringState ( state ) ;
if ( allowTermination ) {
switch ( state ) {
case SCE_HB_COMMENTLINE :
case SCE_HPHP_COMMENT :
case SCE_HP_COMMENTLINE :
case SCE_HPA_COMMENTLINE :
allowTermination = false ;
}
}
return allowTermination ;
}
// not really well done, since it's only comments that should lex the %> and <%
static inline bool isCommentASPState ( int state ) {
bool bResult ;
switch ( state ) {
case SCE_HJ_COMMENT :
case SCE_HJ_COMMENTLINE :
case SCE_HJ_COMMENTDOC :
case SCE_HB_COMMENTLINE :
case SCE_HP_COMMENTLINE :
case SCE_HPHP_COMMENT :
case SCE_HPHP_COMMENTLINE :
bResult = true ;
break ;
default :
bResult = false ;
break ;
}
return bResult ;
}
static void classifyAttribHTML ( unsigned int start , unsigned int end , WordList & keywords , Accessor & styler ) {
bool wordIsNumber = IsNumber ( start , styler ) ;
char chAttr = SCE_H_ATTRIBUTEUNKNOWN ;
if ( wordIsNumber ) {
chAttr = SCE_H_NUMBER ;
} else {
char s [ 100 ] ;
GetTextSegment ( styler , start , end , s , sizeof ( s ) ) ;
if ( keywords . InList ( s ) )
chAttr = SCE_H_ATTRIBUTE ;
}
if ( ( chAttr = = SCE_H_ATTRIBUTEUNKNOWN ) & & ! keywords )
// No keywords -> all are known
chAttr = SCE_H_ATTRIBUTE ;
styler . ColourTo ( end , chAttr ) ;
}
static int classifyTagHTML ( unsigned int start , unsigned int end ,
WordList & keywords , Accessor & styler , bool & tagDontFold ,
2009-04-25 23:38:15 +00:00
bool caseSensitive , bool isXml , bool allowScripts ) {
2013-08-28 00:44:27 +00:00
char withSpace [ 30 + 2 ] = " " ;
const char * s = withSpace + 1 ;
2009-04-24 23:35:41 +00:00
// Copy after the '<'
2013-08-28 00:44:27 +00:00
unsigned int i = 1 ;
2009-04-24 23:35:41 +00:00
for ( unsigned int cPos = start ; cPos < = end & & i < 30 ; cPos + + ) {
char ch = styler [ cPos ] ;
if ( ( ch ! = ' < ' ) & & ( ch ! = ' / ' ) ) {
2013-08-28 00:44:27 +00:00
withSpace [ i + + ] = caseSensitive ? ch : static_cast < char > ( MakeLowerCase ( ch ) ) ;
2009-04-24 23:35:41 +00:00
}
}
//The following is only a quick hack, to see if this whole thing would work
//we first need the tagname with a trailing space...
2013-08-28 00:44:27 +00:00
withSpace [ i ] = ' ' ;
withSpace [ i + 1 ] = ' \0 ' ;
2009-04-24 23:35:41 +00:00
// if the current language is XML, I can fold any tag
// if the current language is HTML, I don't want to fold certain tags (input, meta, etc.)
//...to find it in the list of no-container-tags
2013-08-28 00:44:27 +00:00
tagDontFold = ( ! isXml ) & & ( NULL ! = strstr ( " area base basefont br col command embed frame hr img input isindex keygen link meta param source track wbr " , withSpace ) ) ;
2009-04-24 23:35:41 +00:00
//now we can remove the trailing space
2013-08-28 00:44:27 +00:00
withSpace [ i ] = ' \0 ' ;
2009-04-24 23:35:41 +00:00
2009-04-25 23:38:15 +00:00
// No keywords -> all are known
2009-04-24 23:35:41 +00:00
char chAttr = SCE_H_TAGUNKNOWN ;
if ( s [ 0 ] = = ' ! ' ) {
chAttr = SCE_H_SGML_DEFAULT ;
2009-06-24 19:09:31 +00:00
} else if ( ! keywords | | keywords . InList ( s ) ) {
2009-04-24 23:35:41 +00:00
chAttr = SCE_H_TAG ;
}
styler . ColourTo ( end , chAttr ) ;
2009-04-25 23:38:15 +00:00
if ( chAttr = = SCE_H_TAG ) {
if ( allowScripts & & 0 = = strcmp ( s , " script " ) ) {
2009-06-24 19:09:31 +00:00
// check to see if this is a self-closing tag by sniffing ahead
bool isSelfClose = false ;
2013-08-28 00:44:27 +00:00
for ( unsigned int cPos = end ; cPos < = end + 200 ; cPos + + ) {
2009-06-24 19:09:31 +00:00
char ch = styler . SafeGetCharAt ( cPos , ' \0 ' ) ;
if ( ch = = ' \0 ' | | ch = = ' > ' )
break ;
else if ( ch = = ' / ' & & styler . SafeGetCharAt ( cPos + 1 , ' \0 ' ) = = ' > ' ) {
isSelfClose = true ;
break ;
}
}
// do not enter a script state if the tag self-closed
if ( ! isSelfClose )
chAttr = SCE_H_SCRIPT ;
2009-04-25 23:38:15 +00:00
} else if ( ! isXml & & 0 = = strcmp ( s , " comment " ) ) {
chAttr = SCE_H_COMMENT ;
}
}
return chAttr ;
2009-04-24 23:35:41 +00:00
}
static void classifyWordHTJS ( unsigned int start , unsigned int end ,
WordList & keywords , Accessor & styler , script_mode inScriptType ) {
2011-07-17 22:30:49 +00:00
char s [ 30 + 1 ] ;
unsigned int i = 0 ;
for ( ; i < end - start + 1 & & i < 30 ; i + + ) {
s [ i ] = styler [ start + i ] ;
}
s [ i ] = ' \0 ' ;
2009-04-24 23:35:41 +00:00
char chAttr = SCE_HJ_WORD ;
2011-07-17 22:30:49 +00:00
bool wordIsNumber = IsADigit ( s [ 0 ] ) | | ( ( s [ 0 ] = = ' . ' ) & & IsADigit ( s [ 1 ] ) ) ;
if ( wordIsNumber ) {
2009-04-24 23:35:41 +00:00
chAttr = SCE_HJ_NUMBER ;
2011-07-17 22:30:49 +00:00
} else if ( keywords . InList ( s ) ) {
chAttr = SCE_HJ_KEYWORD ;
2009-04-24 23:35:41 +00:00
}
styler . ColourTo ( end , statePrintForState ( chAttr , inScriptType ) ) ;
}
static int classifyWordHTVB ( unsigned int start , unsigned int end , WordList & keywords , Accessor & styler , script_mode inScriptType ) {
char chAttr = SCE_HB_IDENTIFIER ;
bool wordIsNumber = IsADigit ( styler [ start ] ) | | ( styler [ start ] = = ' . ' ) ;
if ( wordIsNumber )
chAttr = SCE_HB_NUMBER ;
else {
char s [ 100 ] ;
GetTextSegment ( styler , start , end , s , sizeof ( s ) ) ;
if ( keywords . InList ( s ) ) {
chAttr = SCE_HB_WORD ;
if ( strcmp ( s , " rem " ) = = 0 )
chAttr = SCE_HB_COMMENTLINE ;
}
}
styler . ColourTo ( end , statePrintForState ( chAttr , inScriptType ) ) ;
if ( chAttr = = SCE_HB_COMMENTLINE )
return SCE_HB_COMMENTLINE ;
else
return SCE_HB_DEFAULT ;
}
2013-08-28 00:44:27 +00:00
static void classifyWordHTPy ( unsigned int start , unsigned int end , WordList & keywords , Accessor & styler , char * prevWord , script_mode inScriptType , bool isMako ) {
2009-04-24 23:35:41 +00:00
bool wordIsNumber = IsADigit ( styler [ start ] ) ;
char s [ 30 + 1 ] ;
unsigned int i = 0 ;
for ( ; i < end - start + 1 & & i < 30 ; i + + ) {
s [ i ] = styler [ start + i ] ;
}
s [ i ] = ' \0 ' ;
char chAttr = SCE_HP_IDENTIFIER ;
if ( 0 = = strcmp ( prevWord , " class " ) )
chAttr = SCE_HP_CLASSNAME ;
else if ( 0 = = strcmp ( prevWord , " def " ) )
chAttr = SCE_HP_DEFNAME ;
else if ( wordIsNumber )
chAttr = SCE_HP_NUMBER ;
else if ( keywords . InList ( s ) )
chAttr = SCE_HP_WORD ;
2013-08-28 00:44:27 +00:00
else if ( isMako & & 0 = = strcmp ( s , " block " ) )
chAttr = SCE_HP_WORD ;
2009-04-24 23:35:41 +00:00
styler . ColourTo ( end , statePrintForState ( chAttr , inScriptType ) ) ;
strcpy ( prevWord , s ) ;
}
// Update the word colour to default or keyword
// Called when in a PHP word
static void classifyWordHTPHP ( unsigned int start , unsigned int end , WordList & keywords , Accessor & styler ) {
char chAttr = SCE_HPHP_DEFAULT ;
bool wordIsNumber = IsADigit ( styler [ start ] ) | | ( styler [ start ] = = ' . ' & & start + 1 < = end & & IsADigit ( styler [ start + 1 ] ) ) ;
if ( wordIsNumber )
chAttr = SCE_HPHP_NUMBER ;
else {
char s [ 100 ] ;
GetTextSegment ( styler , start , end , s , sizeof ( s ) ) ;
if ( keywords . InList ( s ) )
chAttr = SCE_HPHP_WORD ;
}
styler . ColourTo ( end , chAttr ) ;
}
static bool isWordHSGML ( unsigned int start , unsigned int end , WordList & keywords , Accessor & styler ) {
char s [ 30 + 1 ] ;
unsigned int i = 0 ;
for ( ; i < end - start + 1 & & i < 30 ; i + + ) {
s [ i ] = styler [ start + i ] ;
}
s [ i ] = ' \0 ' ;
return keywords . InList ( s ) ;
}
static bool isWordCdata ( unsigned int start , unsigned int end , Accessor & styler ) {
char s [ 30 + 1 ] ;
unsigned int i = 0 ;
for ( ; i < end - start + 1 & & i < 30 ; i + + ) {
s [ i ] = styler [ start + i ] ;
}
s [ i ] = ' \0 ' ;
return ( 0 = = strcmp ( s , " [CDATA[ " ) ) ;
}
// Return the first state to reach when entering a scripting language
static int StateForScript ( script_type scriptLanguage ) {
int Result ;
switch ( scriptLanguage ) {
2011-07-17 22:30:49 +00:00
case eScriptJS :
2009-04-24 23:35:41 +00:00
Result = SCE_HJ_START ;
break ;
case eScriptPython :
Result = SCE_HP_START ;
break ;
case eScriptPHP :
Result = SCE_HPHP_DEFAULT ;
break ;
case eScriptXML :
Result = SCE_H_TAGUNKNOWN ;
break ;
case eScriptSGML :
Result = SCE_H_SGML_DEFAULT ;
break ;
2009-04-25 23:38:15 +00:00
case eScriptComment :
Result = SCE_H_COMMENT ;
break ;
2009-04-24 23:35:41 +00:00
default :
2010-09-16 23:09:05 +00:00
Result = SCE_HB_START ;
2009-04-24 23:35:41 +00:00
break ;
}
return Result ;
}
static inline bool issgmlwordchar ( int ch ) {
return ! isascii ( ch ) | |
( isalnum ( ch ) | | ch = = ' . ' | | ch = = ' _ ' | | ch = = ' : ' | | ch = = ' ! ' | | ch = = ' # ' | | ch = = ' [ ' ) ;
}
static inline bool IsPhpWordStart ( int ch ) {
return ( isascii ( ch ) & & ( isalpha ( ch ) | | ( ch = = ' _ ' ) ) ) | | ( ch > = 0x7f ) ;
}
static inline bool IsPhpWordChar ( int ch ) {
return IsADigit ( ch ) | | IsPhpWordStart ( ch ) ;
}
static bool InTagState ( int state ) {
return state = = SCE_H_TAG | | state = = SCE_H_TAGUNKNOWN | |
state = = SCE_H_SCRIPT | |
state = = SCE_H_ATTRIBUTE | | state = = SCE_H_ATTRIBUTEUNKNOWN | |
state = = SCE_H_NUMBER | | state = = SCE_H_OTHER | |
state = = SCE_H_DOUBLESTRING | | state = = SCE_H_SINGLESTRING ;
}
static bool IsCommentState ( const int state ) {
return state = = SCE_H_COMMENT | | state = = SCE_H_SGML_COMMENT ;
}
static bool IsScriptCommentState ( const int state ) {
return state = = SCE_HJ_COMMENT | | state = = SCE_HJ_COMMENTLINE | | state = = SCE_HJA_COMMENT | |
state = = SCE_HJA_COMMENTLINE | | state = = SCE_HB_COMMENTLINE | | state = = SCE_HBA_COMMENTLINE ;
}
static bool isLineEnd ( int ch ) {
return ch = = ' \r ' | | ch = = ' \n ' ;
}
2010-07-12 22:19:51 +00:00
static bool isMakoBlockEnd ( const int ch , const int chNext , const char * blockType ) {
if ( strlen ( blockType ) = = 0 ) {
return ( ( ch = = ' % ' ) & & ( chNext = = ' > ' ) ) ;
} else if ( ( 0 = = strcmp ( blockType , " inherit " ) ) | |
( 0 = = strcmp ( blockType , " namespace " ) ) | |
( 0 = = strcmp ( blockType , " include " ) ) | |
( 0 = = strcmp ( blockType , " page " ) ) ) {
return ( ( ch = = ' / ' ) & & ( chNext = = ' > ' ) ) ;
} else if ( 0 = = strcmp ( blockType , " % " ) ) {
2013-08-28 00:44:27 +00:00
if ( ch = = ' / ' & & isLineEnd ( chNext ) )
return 1 ;
else
return isLineEnd ( ch ) ;
2010-07-12 22:19:51 +00:00
} else if ( 0 = = strcmp ( blockType , " { " ) ) {
return ch = = ' } ' ;
} else {
return ( ch = = ' > ' ) ;
}
}
static bool isDjangoBlockEnd ( const int ch , const int chNext , const char * blockType ) {
if ( strlen ( blockType ) = = 0 ) {
return 0 ;
} else if ( 0 = = strcmp ( blockType , " % " ) ) {
return ( ( ch = = ' % ' ) & & ( chNext = = ' } ' ) ) ;
} else if ( 0 = = strcmp ( blockType , " { " ) ) {
return ( ( ch = = ' } ' ) & & ( chNext = = ' } ' ) ) ;
} else {
return 0 ;
}
}
2009-04-24 23:35:41 +00:00
static bool isPHPStringState ( int state ) {
return
( state = = SCE_HPHP_HSTRING ) | |
( state = = SCE_HPHP_SIMPLESTRING ) | |
( state = = SCE_HPHP_HSTRING_VARIABLE ) | |
( state = = SCE_HPHP_COMPLEX_VARIABLE ) ;
}
2009-04-25 23:38:15 +00:00
static int FindPhpStringDelimiter ( char * phpStringDelimiter , const int phpStringDelimiterSize , int i , const int lengthDoc , Accessor & styler , bool & isSimpleString ) {
2009-04-24 23:35:41 +00:00
int j ;
2009-04-25 23:38:15 +00:00
const int beginning = i - 1 ;
bool isValidSimpleString = false ;
2009-04-24 23:35:41 +00:00
while ( i < lengthDoc & & ( styler [ i ] = = ' ' | | styler [ i ] = = ' \t ' ) )
i + + ;
2009-04-25 23:38:15 +00:00
char ch = styler . SafeGetCharAt ( i ) ;
const char chNext = styler . SafeGetCharAt ( i + 1 ) ;
if ( ! IsPhpWordStart ( ch ) ) {
if ( ch = = ' \' ' & & IsPhpWordStart ( chNext ) ) {
i + + ;
ch = chNext ;
isSimpleString = true ;
} else {
phpStringDelimiter [ 0 ] = ' \0 ' ;
return beginning ;
}
}
phpStringDelimiter [ 0 ] = ch ;
i + + ;
for ( j = i ; j < lengthDoc & & ! isLineEnd ( styler [ j ] ) ; j + + ) {
if ( ! IsPhpWordChar ( styler [ j ] ) ) {
if ( isSimpleString & & ( styler [ j ] = = ' \' ' ) & & isLineEnd ( styler . SafeGetCharAt ( j + 1 ) ) ) {
isValidSimpleString = true ;
j + + ;
break ;
} else {
phpStringDelimiter [ 0 ] = ' \0 ' ;
return beginning ;
}
}
2009-04-24 23:35:41 +00:00
if ( j - i < phpStringDelimiterSize - 2 )
phpStringDelimiter [ j - i + 1 ] = styler [ j ] ;
else
i + + ;
}
2009-04-25 23:38:15 +00:00
if ( isSimpleString & & ! isValidSimpleString ) {
phpStringDelimiter [ 0 ] = ' \0 ' ;
return beginning ;
}
phpStringDelimiter [ j - i + 1 - ( isSimpleString ? 1 : 0 ) ] = ' \0 ' ;
return j - 1 ;
2009-04-24 23:35:41 +00:00
}
static void ColouriseHyperTextDoc ( unsigned int startPos , int length , int initStyle , WordList * keywordlists [ ] ,
Accessor & styler , bool isXml ) {
WordList & keywords = * keywordlists [ 0 ] ;
WordList & keywords2 = * keywordlists [ 1 ] ;
WordList & keywords3 = * keywordlists [ 2 ] ;
WordList & keywords4 = * keywordlists [ 3 ] ;
WordList & keywords5 = * keywordlists [ 4 ] ;
WordList & keywords6 = * keywordlists [ 5 ] ; // SGML (DTD) keywords
// Lexer for HTML requires more lexical states (8 bits worth) than most lexers
styler . StartAt ( startPos , static_cast < char > ( STYLE_MAX ) ) ;
char prevWord [ 200 ] ;
prevWord [ 0 ] = ' \0 ' ;
char phpStringDelimiter [ 200 ] ; // PHP is not limited in length, we are
phpStringDelimiter [ 0 ] = ' \0 ' ;
int StateToPrint = initStyle ;
int state = stateForPrintState ( StateToPrint ) ;
2010-07-12 22:19:51 +00:00
char makoBlockType [ 200 ] ;
makoBlockType [ 0 ] = ' \0 ' ;
2013-08-28 00:44:27 +00:00
int makoComment = 0 ;
2010-07-12 22:19:51 +00:00
char djangoBlockType [ 2 ] ;
djangoBlockType [ 0 ] = ' \0 ' ;
2009-04-24 23:35:41 +00:00
2013-08-28 00:44:27 +00:00
// If inside a tag, it may be a script tag, so reread from the start of line starting tag to ensure any language tags are seen
2009-04-24 23:35:41 +00:00
if ( InTagState ( state ) ) {
while ( ( startPos > 0 ) & & ( InTagState ( styler . StyleAt ( startPos - 1 ) ) ) ) {
2013-08-28 00:44:27 +00:00
int backLineStart = styler . LineStart ( styler . GetLine ( startPos - 1 ) ) ;
length + = startPos - backLineStart ;
startPos = backLineStart ;
2009-04-24 23:35:41 +00:00
}
state = SCE_H_DEFAULT ;
}
2009-04-25 23:38:15 +00:00
// String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
if ( isPHPStringState ( state ) ) {
while ( startPos > 0 & & ( isPHPStringState ( state ) | | ! isLineEnd ( styler [ startPos - 1 ] ) ) ) {
startPos - - ;
length + + ;
state = styler . StyleAt ( startPos ) ;
}
if ( startPos = = 0 )
state = SCE_H_DEFAULT ;
2009-04-24 23:35:41 +00:00
}
styler . StartAt ( startPos , static_cast < char > ( STYLE_MAX ) ) ;
int lineCurrent = styler . GetLine ( startPos ) ;
int lineState ;
if ( lineCurrent > 0 ) {
2010-09-05 22:56:27 +00:00
lineState = styler . GetLineState ( lineCurrent - 1 ) ;
2009-04-24 23:35:41 +00:00
} else {
// Default client and ASP scripting language is JavaScript
lineState = eScriptJS < < 8 ;
2009-06-24 19:09:31 +00:00
2010-07-12 22:19:51 +00:00
// property asp.default.language
// Script in ASP code is initially assumed to be in JavaScript.
2009-06-24 19:09:31 +00:00
// To change this to VBScript set asp.default.language to 2. Python is 3.
2009-04-24 23:35:41 +00:00
lineState | = styler . GetPropertyInt ( " asp.default.language " , eScriptVBS ) < < 4 ;
}
script_mode inScriptType = script_mode ( ( lineState > > 0 ) & 0x03 ) ; // 2 bits of scripting mode
bool tagOpened = ( lineState > > 2 ) & 0x01 ; // 1 bit to know if we are in an opened tag
bool tagClosing = ( lineState > > 3 ) & 0x01 ; // 1 bit to know if we are in a closing tag
bool tagDontFold = false ; //some HTML tags should not be folded
script_type aspScript = script_type ( ( lineState > > 4 ) & 0x0F ) ; // 4 bits of script name
script_type clientScript = script_type ( ( lineState > > 8 ) & 0x0F ) ; // 4 bits of script name
int beforePreProc = ( lineState > > 12 ) & 0xFF ; // 8 bits of state
script_type scriptLanguage = ScriptOfState ( state ) ;
2009-04-25 23:38:15 +00:00
// If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment
if ( inScriptType = = eNonHtmlScript & & state = = SCE_H_COMMENT ) {
scriptLanguage = eScriptComment ;
}
2010-07-12 22:19:51 +00:00
script_type beforeLanguage = ScriptOfState ( beforePreProc ) ;
2009-04-24 23:35:41 +00:00
2010-07-12 22:19:51 +00:00
// property fold.html
// Folding is turned on or off for HTML and XML files with this option.
2009-06-24 19:09:31 +00:00
// The fold option must also be on for folding to occur.
2009-04-24 23:35:41 +00:00
const bool foldHTML = styler . GetPropertyInt ( " fold.html " , 0 ) ! = 0 ;
2009-06-24 19:09:31 +00:00
2009-04-24 23:35:41 +00:00
const bool fold = foldHTML & & styler . GetPropertyInt ( " fold " , 0 ) ;
2009-06-24 19:09:31 +00:00
2010-07-12 22:19:51 +00:00
// property fold.html.preprocessor
// Folding is turned on or off for scripts embedded in HTML files with this option.
2009-06-24 19:09:31 +00:00
// The default is on.
2009-04-24 23:35:41 +00:00
const bool foldHTMLPreprocessor = foldHTML & & styler . GetPropertyInt ( " fold.html.preprocessor " , 1 ) ;
2009-06-24 19:09:31 +00:00
2009-04-24 23:35:41 +00:00
const bool foldCompact = styler . GetPropertyInt ( " fold.compact " , 1 ) ! = 0 ;
2009-06-24 19:09:31 +00:00
2010-07-12 22:19:51 +00:00
// property fold.hypertext.comment
// Allow folding for comments in scripts embedded in HTML.
// The default is off.
2009-04-25 23:38:15 +00:00
const bool foldComment = fold & & styler . GetPropertyInt ( " fold.hypertext.comment " , 0 ) ! = 0 ;
2009-06-24 19:09:31 +00:00
2010-07-12 22:19:51 +00:00
// property fold.hypertext.heredoc
// Allow folding for heredocs in scripts embedded in HTML.
// The default is off.
2009-04-25 23:38:15 +00:00
const bool foldHeredoc = fold & & styler . GetPropertyInt ( " fold.hypertext.heredoc " , 0 ) ! = 0 ;
2009-06-24 19:09:31 +00:00
2010-07-12 22:19:51 +00:00
// property html.tags.case.sensitive
// For XML and HTML, setting this property to 1 will make tags match in a case
// sensitive way which is the expected behaviour for XML and XHTML.
2009-04-24 23:35:41 +00:00
const bool caseSensitive = styler . GetPropertyInt ( " html.tags.case.sensitive " , 0 ) ! = 0 ;
2009-06-24 19:09:31 +00:00
2010-07-12 22:19:51 +00:00
// property lexer.xml.allow.scripts
// Set to 0 to disable scripts in XML.
2009-04-25 23:38:15 +00:00
const bool allowScripts = styler . GetPropertyInt ( " lexer.xml.allow.scripts " , 1 ) ! = 0 ;
2009-04-24 23:35:41 +00:00
2010-07-12 22:19:51 +00:00
// property lexer.html.mako
// Set to 1 to enable the mako template language.
const bool isMako = styler . GetPropertyInt ( " lexer.html.mako " , 0 ) ! = 0 ;
// property lexer.html.django
// Set to 1 to enable the django template language.
const bool isDjango = styler . GetPropertyInt ( " lexer.html.django " , 0 ) ! = 0 ;
2009-04-24 23:35:41 +00:00
const CharacterSet setHTMLWord ( CharacterSet : : setAlphaNum , " .-_:!# " , 0x80 , true ) ;
const CharacterSet setTagContinue ( CharacterSet : : setAlphaNum , " .-_:!#[ " , 0x80 , true ) ;
const CharacterSet setAttributeContinue ( CharacterSet : : setAlphaNum , " .-_:!#/ " , 0x80 , true ) ;
2013-08-28 00:44:27 +00:00
// TODO: also handle + and - (except if they're part of ++ or --) and return keywords
const CharacterSet setOKBeforeJSRE ( CharacterSet : : setNone , " ([{=,:;!%^&*|?~ " ) ;
2009-04-24 23:35:41 +00:00
int levelPrev = styler . LevelAt ( lineCurrent ) & SC_FOLDLEVELNUMBERMASK ;
int levelCurrent = levelPrev ;
int visibleChars = 0 ;
2010-07-12 22:19:51 +00:00
int lineStartVisibleChars = 0 ;
2009-04-24 23:35:41 +00:00
int chPrev = ' ' ;
int ch = ' ' ;
int chPrevNonWhite = ' ' ;
// look back to set chPrevNonWhite properly for better regex colouring
if ( scriptLanguage = = eScriptJS & & startPos > 0 ) {
int back = startPos ;
int style = 0 ;
while ( - - back ) {
style = styler . StyleAt ( back ) ;
if ( style < SCE_HJ_DEFAULT | | style > SCE_HJ_COMMENTDOC )
// includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE
break ;
}
if ( style = = SCE_HJ_SYMBOLS ) {
chPrevNonWhite = static_cast < unsigned char > ( styler . SafeGetCharAt ( back ) ) ;
}
}
styler . StartSegment ( startPos ) ;
const int lengthDoc = startPos + length ;
for ( int i = startPos ; i < lengthDoc ; i + + ) {
const int chPrev2 = chPrev ;
chPrev = ch ;
if ( ! IsASpace ( ch ) & & state ! = SCE_HJ_COMMENT & &
state ! = SCE_HJ_COMMENTLINE & & state ! = SCE_HJ_COMMENTDOC )
chPrevNonWhite = ch ;
ch = static_cast < unsigned char > ( styler [ i ] ) ;
int chNext = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 1 ) ) ;
const int chNext2 = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 2 ) ) ;
// Handle DBCS codepages
if ( styler . IsLeadByte ( static_cast < char > ( ch ) ) ) {
chPrev = ' ' ;
i + = 1 ;
continue ;
}
if ( ( ! IsASpace ( ch ) | | ! foldCompact ) & & fold )
visibleChars + + ;
2010-07-12 22:19:51 +00:00
if ( ! IsASpace ( ch ) )
lineStartVisibleChars + + ;
2009-04-24 23:35:41 +00:00
// decide what is the current state to print (depending of the script tag)
StateToPrint = statePrintForState ( state , inScriptType ) ;
// handle script folding
if ( fold ) {
switch ( scriptLanguage ) {
case eScriptJS :
case eScriptPHP :
//not currently supported case eScriptVBS:
if ( ( state ! = SCE_HPHP_COMMENT ) & & ( state ! = SCE_HPHP_COMMENTLINE ) & & ( state ! = SCE_HJ_COMMENT ) & & ( state ! = SCE_HJ_COMMENTLINE ) & & ( state ! = SCE_HJ_COMMENTDOC ) & & ( ! isStringState ( state ) ) ) {
//Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
//if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
2011-03-22 00:16:49 +00:00
if ( ch = = ' # ' ) {
int j = i + 1 ;
while ( ( j < lengthDoc ) & & IsASpaceOrTab ( styler . SafeGetCharAt ( j ) ) ) {
j + + ;
}
if ( styler . Match ( j , " region " ) | | styler . Match ( j , " if " ) ) {
levelCurrent + + ;
} else if ( styler . Match ( j , " end " ) ) {
levelCurrent - - ;
}
2011-07-17 22:30:49 +00:00
} else if ( ( ch = = ' { ' ) | | ( ch = = ' } ' ) | | ( foldComment & & ( ch = = ' / ' ) & & ( chNext = = ' * ' ) ) ) {
levelCurrent + = ( ( ( ch = = ' { ' ) | | ( ch = = ' / ' ) ) ? 1 : - 1 ) ;
2009-04-24 23:35:41 +00:00
}
2009-04-25 23:38:15 +00:00
} else if ( ( ( state = = SCE_HPHP_COMMENT ) | | ( state = = SCE_HJ_COMMENT ) ) & & foldComment & & ( ch = = ' * ' ) & & ( chNext = = ' / ' ) ) {
levelCurrent - - ;
2009-04-24 23:35:41 +00:00
}
break ;
case eScriptPython :
2013-08-28 00:44:27 +00:00
if ( state ! = SCE_HP_COMMENTLINE & & ! isMako ) {
2009-04-24 23:35:41 +00:00
if ( ( ch = = ' : ' ) & & ( ( chNext = = ' \n ' ) | | ( chNext = = ' \r ' & & chNext2 = = ' \n ' ) ) ) {
levelCurrent + + ;
} else if ( ( ch = = ' \n ' ) & & ! ( ( chNext = = ' \r ' ) & & ( chNext2 = = ' \n ' ) ) & & ( chNext ! = ' \n ' ) ) {
// check if the number of tabs is lower than the level
int Findlevel = ( levelCurrent & ~ SC_FOLDLEVELBASE ) * 8 ;
for ( int j = 0 ; Findlevel > 0 ; j + + ) {
char chTmp = styler . SafeGetCharAt ( i + j + 1 ) ;
if ( chTmp = = ' \t ' ) {
Findlevel - = 8 ;
} else if ( chTmp = = ' ' ) {
Findlevel - - ;
} else {
break ;
}
}
if ( Findlevel > 0 ) {
levelCurrent - = Findlevel / 8 ;
if ( Findlevel % 8 )
levelCurrent - - ;
}
}
}
break ;
default :
break ;
}
}
if ( ( ch = = ' \r ' & & chNext ! = ' \n ' ) | | ( ch = = ' \n ' ) ) {
// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
// Avoid triggering two times on Dos/Win
// New line -> record any line state onto /next/ line
if ( fold ) {
int lev = levelPrev ;
if ( visibleChars = = 0 )
lev | = SC_FOLDLEVELWHITEFLAG ;
if ( ( levelCurrent > levelPrev ) & & ( visibleChars > 0 ) )
lev | = SC_FOLDLEVELHEADERFLAG ;
styler . SetLevel ( lineCurrent , lev ) ;
visibleChars = 0 ;
levelPrev = levelCurrent ;
}
styler . SetLineState ( lineCurrent ,
( ( inScriptType & 0x03 ) < < 0 ) |
( ( tagOpened & 0x01 ) < < 2 ) |
( ( tagClosing & 0x01 ) < < 3 ) |
( ( aspScript & 0x0F ) < < 4 ) |
( ( clientScript & 0x0F ) < < 8 ) |
( ( beforePreProc & 0xFF ) < < 12 ) ) ;
2010-09-05 22:56:27 +00:00
lineCurrent + + ;
lineStartVisibleChars = 0 ;
2009-04-24 23:35:41 +00:00
}
2013-08-28 00:44:27 +00:00
// handle start of Mako comment line
if ( isMako & & ch = = ' # ' & & chNext = = ' # ' ) {
makoComment = 1 ;
}
// handle end of Mako comment line
else if ( isMako & & makoComment & & ( ch = = ' \r ' | | ch = = ' \n ' ) ) {
makoComment = 0 ;
styler . ColourTo ( i , SCE_HP_COMMENTLINE ) ;
state = SCE_HP_DEFAULT ;
}
2010-07-12 22:19:51 +00:00
// Allow falling through to mako handling code if newline is going to end a block
if ( ( ( ch = = ' \r ' & & chNext ! = ' \n ' ) | | ( ch = = ' \n ' ) ) & &
( ! isMako | | ( 0 ! = strcmp ( makoBlockType , " % " ) ) ) ) {
}
2009-04-24 23:35:41 +00:00
// generic end of script processing
else if ( ( inScriptType = = eNonHtmlScript ) & & ( ch = = ' < ' ) & & ( chNext = = ' / ' ) ) {
// Check if it's the end of the script tag (or any other HTML tag)
switch ( state ) {
// in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!)
case SCE_H_DOUBLESTRING :
case SCE_H_SINGLESTRING :
case SCE_HJ_COMMENT :
case SCE_HJ_COMMENTDOC :
//case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
// the end of script marker from some JS interpreters.
case SCE_HB_COMMENTLINE :
case SCE_HBA_COMMENTLINE :
case SCE_HJ_DOUBLESTRING :
case SCE_HJ_SINGLESTRING :
case SCE_HJ_REGEX :
case SCE_HB_STRING :
case SCE_HBA_STRING :
case SCE_HP_STRING :
case SCE_HP_TRIPLE :
case SCE_HP_TRIPLEDOUBLE :
2009-04-25 23:38:15 +00:00
case SCE_HPHP_HSTRING :
case SCE_HPHP_SIMPLESTRING :
case SCE_HPHP_COMMENT :
case SCE_HPHP_COMMENTLINE :
2009-04-24 23:35:41 +00:00
break ;
default :
// check if the closing tag is a script tag
2009-04-25 23:38:15 +00:00
if ( const char * tag =
state = = SCE_HJ_COMMENTLINE | | isXml ? " script " :
state = = SCE_H_COMMENT ? " comment " : 0 ) {
int j = i + 2 ;
int chr ;
do {
chr = static_cast < int > ( * tag + + ) ;
} while ( chr ! = 0 & & chr = = MakeLowerCase ( styler . SafeGetCharAt ( j + + ) ) ) ;
if ( chr ! = 0 ) break ;
2009-04-24 23:35:41 +00:00
}
// closing tag of the script (it's a closing HTML tag anyway)
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_H_TAGUNKNOWN ;
inScriptType = eHtml ;
scriptLanguage = eScriptNone ;
clientScript = eScriptJS ;
i + = 2 ;
visibleChars + = 2 ;
tagClosing = true ;
continue ;
}
}
/////////////////////////////////////
// handle the start of PHP pre-processor = Non-HTML
else if ( ( state ! = SCE_H_ASPAT ) & &
! isPHPStringState ( state ) & &
( state ! = SCE_HPHP_COMMENT ) & &
2010-08-21 23:59:56 +00:00
( state ! = SCE_HPHP_COMMENTLINE ) & &
2009-04-24 23:35:41 +00:00
( ch = = ' < ' ) & &
( chNext = = ' ? ' ) & &
2011-07-17 22:30:49 +00:00
! IsScriptCommentState ( state ) ) {
beforeLanguage = scriptLanguage ;
2012-06-29 19:21:49 +00:00
scriptLanguage = segIsScriptingIndicator ( styler , i + 2 , i + 6 , isXml ? eScriptXML : eScriptPHP ) ;
2013-08-28 00:44:27 +00:00
if ( ( scriptLanguage ! = eScriptPHP ) & & ( isStringState ( state ) | | ( state = = SCE_H_COMMENT ) ) ) continue ;
2009-04-24 23:35:41 +00:00
styler . ColourTo ( i - 1 , StateToPrint ) ;
beforePreProc = state ;
i + + ;
visibleChars + + ;
2009-04-25 23:38:15 +00:00
i + = PrintScriptingIndicatorOffset ( styler , styler . GetStartSegment ( ) + 2 , i + 6 ) ;
2009-04-24 23:35:41 +00:00
if ( scriptLanguage = = eScriptXML )
styler . ColourTo ( i , SCE_H_XMLSTART ) ;
else
styler . ColourTo ( i , SCE_H_QUESTION ) ;
state = StateForScript ( scriptLanguage ) ;
if ( inScriptType = = eNonHtmlScript )
inScriptType = eNonHtmlScriptPreProc ;
else
inScriptType = eNonHtmlPreProc ;
// Fold whole script, but not if the XML first tag (all XML-like tags in this case)
if ( foldHTMLPreprocessor & & ( scriptLanguage ! = eScriptXML ) ) {
levelCurrent + + ;
}
// should be better
ch = static_cast < unsigned char > ( styler . SafeGetCharAt ( i ) ) ;
continue ;
}
2010-07-12 22:19:51 +00:00
// handle the start Mako template Python code
else if ( isMako & & scriptLanguage = = eScriptNone & & ( ( ch = = ' < ' & & chNext = = ' % ' ) | |
( lineStartVisibleChars = = 1 & & ch = = ' % ' ) | |
2013-08-28 00:44:27 +00:00
( lineStartVisibleChars = = 1 & & ch = = ' / ' & & chNext = = ' % ' ) | |
2010-07-12 22:19:51 +00:00
( ch = = ' $ ' & & chNext = = ' { ' ) | |
( ch = = ' < ' & & chNext = = ' / ' & & chNext2 = = ' % ' ) ) ) {
2013-08-28 00:44:27 +00:00
if ( ch = = ' % ' | | ch = = ' / ' )
2010-07-12 22:19:51 +00:00
strcpy ( makoBlockType , " % " ) ;
else if ( ch = = ' $ ' )
strcpy ( makoBlockType , " { " ) ;
else if ( chNext = = ' / ' )
GetNextWord ( styler , i + 3 , makoBlockType , sizeof ( makoBlockType ) ) ;
else
GetNextWord ( styler , i + 2 , makoBlockType , sizeof ( makoBlockType ) ) ;
styler . ColourTo ( i - 1 , StateToPrint ) ;
beforePreProc = state ;
if ( inScriptType = = eNonHtmlScript )
inScriptType = eNonHtmlScriptPreProc ;
else
inScriptType = eNonHtmlPreProc ;
if ( chNext = = ' / ' ) {
i + = 2 ;
visibleChars + = 2 ;
} else if ( ch ! = ' % ' ) {
i + + ;
visibleChars + + ;
}
state = SCE_HP_START ;
scriptLanguage = eScriptPython ;
styler . ColourTo ( i , SCE_H_ASP ) ;
2013-08-28 00:44:27 +00:00
if ( ch ! = ' % ' & & ch ! = ' $ ' & & ch ! = ' / ' ) {
i + = static_cast < int > ( strlen ( makoBlockType ) ) ;
visibleChars + = static_cast < int > ( strlen ( makoBlockType ) ) ;
2010-07-12 22:19:51 +00:00
if ( keywords4 . InList ( makoBlockType ) )
styler . ColourTo ( i , SCE_HP_WORD ) ;
else
styler . ColourTo ( i , SCE_H_TAGUNKNOWN ) ;
}
ch = static_cast < unsigned char > ( styler . SafeGetCharAt ( i ) ) ;
continue ;
}
2011-07-17 22:30:49 +00:00
// handle the start/end of Django comment
else if ( isDjango & & state ! = SCE_H_COMMENT & & ( ch = = ' { ' & & chNext = = ' # ' ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
beforePreProc = state ;
beforeLanguage = scriptLanguage ;
if ( inScriptType = = eNonHtmlScript )
inScriptType = eNonHtmlScriptPreProc ;
else
inScriptType = eNonHtmlPreProc ;
i + = 1 ;
visibleChars + = 1 ;
scriptLanguage = eScriptComment ;
state = SCE_H_COMMENT ;
styler . ColourTo ( i , SCE_H_ASP ) ;
ch = static_cast < unsigned char > ( styler . SafeGetCharAt ( i ) ) ;
continue ;
} else if ( isDjango & & state = = SCE_H_COMMENT & & ( ch = = ' # ' & & chNext = = ' } ' ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
i + = 1 ;
visibleChars + = 1 ;
styler . ColourTo ( i , SCE_H_ASP ) ;
state = beforePreProc ;
if ( inScriptType = = eNonHtmlScriptPreProc )
inScriptType = eNonHtmlScript ;
else
inScriptType = eHtml ;
scriptLanguage = beforeLanguage ;
continue ;
}
2010-07-12 22:19:51 +00:00
// handle the start Django template code
else if ( isDjango & & scriptLanguage ! = eScriptPython & & ( ch = = ' { ' & & ( chNext = = ' % ' | | chNext = = ' { ' ) ) ) {
if ( chNext = = ' % ' )
strcpy ( djangoBlockType , " % " ) ;
else
strcpy ( djangoBlockType , " { " ) ;
styler . ColourTo ( i - 1 , StateToPrint ) ;
beforePreProc = state ;
if ( inScriptType = = eNonHtmlScript )
inScriptType = eNonHtmlScriptPreProc ;
else
inScriptType = eNonHtmlPreProc ;
i + = 1 ;
visibleChars + = 1 ;
state = SCE_HP_START ;
beforeLanguage = scriptLanguage ;
scriptLanguage = eScriptPython ;
styler . ColourTo ( i , SCE_H_ASP ) ;
ch = static_cast < unsigned char > ( styler . SafeGetCharAt ( i ) ) ;
continue ;
}
2009-04-24 23:35:41 +00:00
// handle the start of ASP pre-processor = Non-HTML
2010-07-12 22:19:51 +00:00
else if ( ! isMako & & ! isDjango & & ! isCommentASPState ( state ) & & ( ch = = ' < ' ) & & ( chNext = = ' % ' ) & & ! isPHPStringState ( state ) ) {
2009-04-24 23:35:41 +00:00
styler . ColourTo ( i - 1 , StateToPrint ) ;
beforePreProc = state ;
if ( inScriptType = = eNonHtmlScript )
inScriptType = eNonHtmlScriptPreProc ;
else
inScriptType = eNonHtmlPreProc ;
if ( chNext2 = = ' @ ' ) {
i + = 2 ; // place as if it was the second next char treated
visibleChars + = 2 ;
state = SCE_H_ASPAT ;
} else if ( ( chNext2 = = ' - ' ) & & ( styler . SafeGetCharAt ( i + 3 ) = = ' - ' ) ) {
styler . ColourTo ( i + 3 , SCE_H_ASP ) ;
state = SCE_H_XCCOMMENT ;
scriptLanguage = eScriptVBS ;
continue ;
} else {
if ( chNext2 = = ' = ' ) {
i + = 2 ; // place as if it was the second next char treated
visibleChars + = 2 ;
} else {
i + + ; // place as if it was the next char treated
visibleChars + + ;
}
state = StateForScript ( aspScript ) ;
}
scriptLanguage = eScriptVBS ;
styler . ColourTo ( i , SCE_H_ASP ) ;
// fold whole script
if ( foldHTMLPreprocessor )
levelCurrent + + ;
// should be better
ch = static_cast < unsigned char > ( styler . SafeGetCharAt ( i ) ) ;
continue ;
}
/////////////////////////////////////
// handle the start of SGML language (DTD)
else if ( ( ( scriptLanguage = = eScriptNone ) | | ( scriptLanguage = = eScriptXML ) ) & &
( chPrev = = ' < ' ) & &
( ch = = ' ! ' ) & &
( StateToPrint ! = SCE_H_CDATA ) & &
( ! IsCommentState ( StateToPrint ) ) & &
2011-07-17 22:30:49 +00:00
( ! IsScriptCommentState ( StateToPrint ) ) ) {
2009-04-24 23:35:41 +00:00
beforePreProc = state ;
styler . ColourTo ( i - 2 , StateToPrint ) ;
if ( ( chNext = = ' - ' ) & & ( chNext2 = = ' - ' ) ) {
state = SCE_H_COMMENT ; // wait for a pending command
styler . ColourTo ( i + 2 , SCE_H_COMMENT ) ;
i + = 2 ; // follow styling after the --
} else if ( isWordCdata ( i + 1 , i + 7 , styler ) ) {
state = SCE_H_CDATA ;
} else {
styler . ColourTo ( i , SCE_H_SGML_DEFAULT ) ; // <! is default
scriptLanguage = eScriptSGML ;
state = SCE_H_SGML_COMMAND ; // wait for a pending command
}
// fold whole tag (-- when closing the tag)
2013-08-28 00:44:27 +00:00
if ( foldHTMLPreprocessor | | state = = SCE_H_COMMENT | | state = = SCE_H_CDATA )
2009-04-24 23:35:41 +00:00
levelCurrent + + ;
continue ;
}
2010-07-12 22:19:51 +00:00
// handle the end of Mako Python code
else if ( isMako & &
( ( inScriptType = = eNonHtmlPreProc ) | | ( inScriptType = = eNonHtmlScriptPreProc ) ) & &
( scriptLanguage ! = eScriptNone ) & & stateAllowsTermination ( state ) & &
isMakoBlockEnd ( ch , chNext , makoBlockType ) ) {
if ( state = = SCE_H_ASPAT ) {
aspScript = segIsScriptingIndicator ( styler ,
styler . GetStartSegment ( ) , i - 1 , aspScript ) ;
}
if ( state = = SCE_HP_WORD ) {
2013-08-28 00:44:27 +00:00
classifyWordHTPy ( styler . GetStartSegment ( ) , i - 1 , keywords4 , styler , prevWord , inScriptType , isMako ) ;
2010-07-12 22:19:51 +00:00
} else {
styler . ColourTo ( i - 1 , StateToPrint ) ;
}
if ( 0 ! = strcmp ( makoBlockType , " % " ) & & ( 0 ! = strcmp ( makoBlockType , " { " ) ) & & ch ! = ' > ' ) {
i + + ;
visibleChars + + ;
}
2013-08-28 00:44:27 +00:00
else if ( 0 = = strcmp ( makoBlockType , " % " ) & & ch = = ' / ' ) {
i + + ;
visibleChars + + ;
}
if ( 0 ! = strcmp ( makoBlockType , " % " ) | | ch = = ' / ' ) {
2010-07-12 22:19:51 +00:00
styler . ColourTo ( i , SCE_H_ASP ) ;
}
state = beforePreProc ;
if ( inScriptType = = eNonHtmlScriptPreProc )
inScriptType = eNonHtmlScript ;
else
inScriptType = eHtml ;
scriptLanguage = eScriptNone ;
continue ;
}
// handle the end of Django template code
else if ( isDjango & &
( ( inScriptType = = eNonHtmlPreProc ) | | ( inScriptType = = eNonHtmlScriptPreProc ) ) & &
( scriptLanguage ! = eScriptNone ) & & stateAllowsTermination ( state ) & &
isDjangoBlockEnd ( ch , chNext , djangoBlockType ) ) {
if ( state = = SCE_H_ASPAT ) {
aspScript = segIsScriptingIndicator ( styler ,
styler . GetStartSegment ( ) , i - 1 , aspScript ) ;
}
if ( state = = SCE_HP_WORD ) {
2013-08-28 00:44:27 +00:00
classifyWordHTPy ( styler . GetStartSegment ( ) , i - 1 , keywords4 , styler , prevWord , inScriptType , isMako ) ;
2010-07-12 22:19:51 +00:00
} else {
styler . ColourTo ( i - 1 , StateToPrint ) ;
}
i + = 1 ;
visibleChars + = 1 ;
styler . ColourTo ( i , SCE_H_ASP ) ;
state = beforePreProc ;
if ( inScriptType = = eNonHtmlScriptPreProc )
inScriptType = eNonHtmlScript ;
else
inScriptType = eHtml ;
scriptLanguage = beforeLanguage ;
continue ;
}
2009-04-24 23:35:41 +00:00
// handle the end of a pre-processor = Non-HTML
2010-07-12 22:19:51 +00:00
else if ( ( ! isMako & & ! isDjango & & ( ( inScriptType = = eNonHtmlPreProc ) | | ( inScriptType = = eNonHtmlScriptPreProc ) ) & &
( ( ( scriptLanguage ! = eScriptNone ) & & stateAllowsTermination ( state ) ) ) & &
( ( ( ch = = ' % ' ) | | ( ch = = ' ? ' ) ) & & ( chNext = = ' > ' ) ) ) | |
2009-04-24 23:35:41 +00:00
( ( scriptLanguage = = eScriptSGML ) & & ( ch = = ' > ' ) & & ( state ! = SCE_H_SGML_COMMENT ) ) ) {
if ( state = = SCE_H_ASPAT ) {
aspScript = segIsScriptingIndicator ( styler ,
styler . GetStartSegment ( ) , i - 1 , aspScript ) ;
}
// Bounce out of any ASP mode
switch ( state ) {
case SCE_HJ_WORD :
classifyWordHTJS ( styler . GetStartSegment ( ) , i - 1 , keywords2 , styler , inScriptType ) ;
break ;
case SCE_HB_WORD :
classifyWordHTVB ( styler . GetStartSegment ( ) , i - 1 , keywords3 , styler , inScriptType ) ;
break ;
case SCE_HP_WORD :
2013-08-28 00:44:27 +00:00
classifyWordHTPy ( styler . GetStartSegment ( ) , i - 1 , keywords4 , styler , prevWord , inScriptType , isMako ) ;
2009-04-24 23:35:41 +00:00
break ;
case SCE_HPHP_WORD :
classifyWordHTPHP ( styler . GetStartSegment ( ) , i - 1 , keywords5 , styler ) ;
break ;
case SCE_H_XCCOMMENT :
styler . ColourTo ( i - 1 , state ) ;
break ;
default :
styler . ColourTo ( i - 1 , StateToPrint ) ;
break ;
}
if ( scriptLanguage ! = eScriptSGML ) {
i + + ;
visibleChars + + ;
}
if ( ch = = ' % ' )
styler . ColourTo ( i , SCE_H_ASP ) ;
else if ( scriptLanguage = = eScriptXML )
styler . ColourTo ( i , SCE_H_XMLEND ) ;
else if ( scriptLanguage = = eScriptSGML )
styler . ColourTo ( i , SCE_H_SGML_DEFAULT ) ;
else
styler . ColourTo ( i , SCE_H_QUESTION ) ;
state = beforePreProc ;
if ( inScriptType = = eNonHtmlScriptPreProc )
inScriptType = eNonHtmlScript ;
else
inScriptType = eHtml ;
// Unfold all scripting languages, except for XML tag
if ( foldHTMLPreprocessor & & ( scriptLanguage ! = eScriptXML ) ) {
levelCurrent - - ;
}
2011-07-17 22:30:49 +00:00
scriptLanguage = beforeLanguage ;
2009-04-24 23:35:41 +00:00
continue ;
}
/////////////////////////////////////
switch ( state ) {
case SCE_H_DEFAULT :
if ( ch = = ' < ' ) {
// in HTML, fold on tag open and unfold on tag close
tagOpened = true ;
tagClosing = ( chNext = = ' / ' ) ;
styler . ColourTo ( i - 1 , StateToPrint ) ;
if ( chNext ! = ' ! ' )
state = SCE_H_TAGUNKNOWN ;
} else if ( ch = = ' & ' ) {
styler . ColourTo ( i - 1 , SCE_H_DEFAULT ) ;
state = SCE_H_ENTITY ;
}
break ;
case SCE_H_SGML_DEFAULT :
case SCE_H_SGML_BLOCK_DEFAULT :
// if (scriptLanguage == eScriptSGMLblock)
// StateToPrint = SCE_H_SGML_BLOCK_DEFAULT;
if ( ch = = ' \" ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_H_SGML_DOUBLESTRING ;
} else if ( ch = = ' \' ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_H_SGML_SIMPLESTRING ;
} else if ( ( ch = = ' - ' ) & & ( chPrev = = ' - ' ) ) {
if ( static_cast < int > ( styler . GetStartSegment ( ) ) < = ( i - 2 ) ) {
styler . ColourTo ( i - 2 , StateToPrint ) ;
}
state = SCE_H_SGML_COMMENT ;
} else if ( isascii ( ch ) & & isalpha ( ch ) & & ( chPrev = = ' % ' ) ) {
styler . ColourTo ( i - 2 , StateToPrint ) ;
state = SCE_H_SGML_ENTITY ;
} else if ( ch = = ' # ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_H_SGML_SPECIAL ;
} else if ( ch = = ' [ ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
scriptLanguage = eScriptSGMLblock ;
state = SCE_H_SGML_BLOCK_DEFAULT ;
} else if ( ch = = ' ] ' ) {
if ( scriptLanguage = = eScriptSGMLblock ) {
styler . ColourTo ( i , StateToPrint ) ;
scriptLanguage = eScriptSGML ;
} else {
styler . ColourTo ( i - 1 , StateToPrint ) ;
styler . ColourTo ( i , SCE_H_SGML_ERROR ) ;
}
state = SCE_H_SGML_DEFAULT ;
} else if ( scriptLanguage = = eScriptSGMLblock ) {
if ( ( ch = = ' ! ' ) & & ( chPrev = = ' < ' ) ) {
styler . ColourTo ( i - 2 , StateToPrint ) ;
styler . ColourTo ( i , SCE_H_SGML_DEFAULT ) ;
state = SCE_H_SGML_COMMAND ;
} else if ( ch = = ' > ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
styler . ColourTo ( i , SCE_H_SGML_DEFAULT ) ;
}
}
break ;
case SCE_H_SGML_COMMAND :
if ( ( ch = = ' - ' ) & & ( chPrev = = ' - ' ) ) {
styler . ColourTo ( i - 2 , StateToPrint ) ;
state = SCE_H_SGML_COMMENT ;
} else if ( ! issgmlwordchar ( ch ) ) {
if ( isWordHSGML ( styler . GetStartSegment ( ) , i - 1 , keywords6 , styler ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_H_SGML_1ST_PARAM ;
} else {
state = SCE_H_SGML_ERROR ;
}
}
break ;
case SCE_H_SGML_1ST_PARAM :
// wait for the beginning of the word
if ( ( ch = = ' - ' ) & & ( chPrev = = ' - ' ) ) {
if ( scriptLanguage = = eScriptSGMLblock ) {
styler . ColourTo ( i - 2 , SCE_H_SGML_BLOCK_DEFAULT ) ;
} else {
styler . ColourTo ( i - 2 , SCE_H_SGML_DEFAULT ) ;
}
state = SCE_H_SGML_1ST_PARAM_COMMENT ;
} else if ( issgmlwordchar ( ch ) ) {
if ( scriptLanguage = = eScriptSGMLblock ) {
styler . ColourTo ( i - 1 , SCE_H_SGML_BLOCK_DEFAULT ) ;
} else {
styler . ColourTo ( i - 1 , SCE_H_SGML_DEFAULT ) ;
}
// find the length of the word
int size = 1 ;
while ( setHTMLWord . Contains ( static_cast < unsigned char > ( styler . SafeGetCharAt ( i + size ) ) ) )
size + + ;
styler . ColourTo ( i + size - 1 , StateToPrint ) ;
i + = size - 1 ;
visibleChars + = size - 1 ;
ch = static_cast < unsigned char > ( styler . SafeGetCharAt ( i ) ) ;
if ( scriptLanguage = = eScriptSGMLblock ) {
state = SCE_H_SGML_BLOCK_DEFAULT ;
} else {
state = SCE_H_SGML_DEFAULT ;
}
continue ;
}
break ;
case SCE_H_SGML_ERROR :
if ( ( ch = = ' - ' ) & & ( chPrev = = ' - ' ) ) {
styler . ColourTo ( i - 2 , StateToPrint ) ;
state = SCE_H_SGML_COMMENT ;
}
case SCE_H_SGML_DOUBLESTRING :
if ( ch = = ' \" ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_H_SGML_DEFAULT ;
}
break ;
case SCE_H_SGML_SIMPLESTRING :
if ( ch = = ' \' ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_H_SGML_DEFAULT ;
}
break ;
case SCE_H_SGML_COMMENT :
if ( ( ch = = ' - ' ) & & ( chPrev = = ' - ' ) ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_H_SGML_DEFAULT ;
}
break ;
case SCE_H_CDATA :
if ( ( chPrev2 = = ' ] ' ) & & ( chPrev = = ' ] ' ) & & ( ch = = ' > ' ) ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_H_DEFAULT ;
levelCurrent - - ;
}
break ;
case SCE_H_COMMENT :
2009-04-25 23:38:15 +00:00
if ( ( scriptLanguage ! = eScriptComment ) & & ( chPrev2 = = ' - ' ) & & ( chPrev = = ' - ' ) & & ( ch = = ' > ' ) ) {
2009-04-24 23:35:41 +00:00
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_H_DEFAULT ;
levelCurrent - - ;
}
break ;
case SCE_H_SGML_1ST_PARAM_COMMENT :
if ( ( ch = = ' - ' ) & & ( chPrev = = ' - ' ) ) {
styler . ColourTo ( i , SCE_H_SGML_COMMENT ) ;
state = SCE_H_SGML_1ST_PARAM ;
}
break ;
case SCE_H_SGML_SPECIAL :
if ( ! ( isascii ( ch ) & & isupper ( ch ) ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
if ( isalnum ( ch ) ) {
state = SCE_H_SGML_ERROR ;
} else {
state = SCE_H_SGML_DEFAULT ;
}
}
break ;
case SCE_H_SGML_ENTITY :
if ( ch = = ' ; ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_H_SGML_DEFAULT ;
} else if ( ! ( isascii ( ch ) & & isalnum ( ch ) ) & & ch ! = ' - ' & & ch ! = ' . ' ) {
styler . ColourTo ( i , SCE_H_SGML_ERROR ) ;
state = SCE_H_SGML_DEFAULT ;
}
break ;
case SCE_H_ENTITY :
if ( ch = = ' ; ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_H_DEFAULT ;
}
if ( ch ! = ' # ' & & ! ( isascii ( ch ) & & isalnum ( ch ) ) // Should check that '#' follows '&', but it is unlikely anyway...
& & ch ! = ' . ' & & ch ! = ' - ' & & ch ! = ' _ ' & & ch ! = ' : ' ) { // valid in XML
2009-08-23 02:24:48 +00:00
if ( ! isascii ( ch ) ) // Possibly start of a multibyte character so don't allow this byte to be in entity style
styler . ColourTo ( i - 1 , SCE_H_TAGUNKNOWN ) ;
else
styler . ColourTo ( i , SCE_H_TAGUNKNOWN ) ;
2009-04-24 23:35:41 +00:00
state = SCE_H_DEFAULT ;
}
break ;
case SCE_H_TAGUNKNOWN :
if ( ! setTagContinue . Contains ( ch ) & & ! ( ( ch = = ' / ' ) & & ( chPrev = = ' < ' ) ) ) {
int eClass = classifyTagHTML ( styler . GetStartSegment ( ) ,
2009-04-25 23:38:15 +00:00
i - 1 , keywords , styler , tagDontFold , caseSensitive , isXml , allowScripts ) ;
if ( eClass = = SCE_H_SCRIPT | | eClass = = SCE_H_COMMENT ) {
2009-04-24 23:35:41 +00:00
if ( ! tagClosing ) {
inScriptType = eNonHtmlScript ;
2009-04-25 23:38:15 +00:00
scriptLanguage = eClass = = SCE_H_SCRIPT ? clientScript : eScriptComment ;
2009-04-24 23:35:41 +00:00
} else {
scriptLanguage = eScriptNone ;
}
2009-04-25 23:38:15 +00:00
eClass = SCE_H_TAG ;
2009-04-24 23:35:41 +00:00
}
if ( ch = = ' > ' ) {
styler . ColourTo ( i , eClass ) ;
if ( inScriptType = = eNonHtmlScript ) {
state = StateForScript ( scriptLanguage ) ;
} else {
state = SCE_H_DEFAULT ;
}
tagOpened = false ;
2009-04-25 23:38:15 +00:00
if ( ! tagDontFold ) {
2009-04-24 23:35:41 +00:00
if ( tagClosing ) {
levelCurrent - - ;
} else {
levelCurrent + + ;
}
}
tagClosing = false ;
} else if ( ch = = ' / ' & & chNext = = ' > ' ) {
if ( eClass = = SCE_H_TAGUNKNOWN ) {
styler . ColourTo ( i + 1 , SCE_H_TAGUNKNOWN ) ;
} else {
styler . ColourTo ( i - 1 , StateToPrint ) ;
styler . ColourTo ( i + 1 , SCE_H_TAGEND ) ;
}
i + + ;
ch = chNext ;
state = SCE_H_DEFAULT ;
tagOpened = false ;
} else {
if ( eClass ! = SCE_H_TAGUNKNOWN ) {
if ( eClass = = SCE_H_SGML_DEFAULT ) {
state = SCE_H_SGML_DEFAULT ;
} else {
state = SCE_H_OTHER ;
}
}
}
}
break ;
case SCE_H_ATTRIBUTE :
if ( ! setAttributeContinue . Contains ( ch ) ) {
if ( inScriptType = = eNonHtmlScript ) {
int scriptLanguagePrev = scriptLanguage ;
clientScript = segIsScriptingIndicator ( styler , styler . GetStartSegment ( ) , i - 1 , scriptLanguage ) ;
scriptLanguage = clientScript ;
if ( ( scriptLanguagePrev ! = scriptLanguage ) & & ( scriptLanguage = = eScriptNone ) )
inScriptType = eHtml ;
}
classifyAttribHTML ( styler . GetStartSegment ( ) , i - 1 , keywords , styler ) ;
if ( ch = = ' > ' ) {
styler . ColourTo ( i , SCE_H_TAG ) ;
if ( inScriptType = = eNonHtmlScript ) {
state = StateForScript ( scriptLanguage ) ;
} else {
state = SCE_H_DEFAULT ;
}
tagOpened = false ;
2009-04-25 23:38:15 +00:00
if ( ! tagDontFold ) {
if ( tagClosing ) {
2009-04-24 23:35:41 +00:00
levelCurrent - - ;
} else {
levelCurrent + + ;
}
}
tagClosing = false ;
} else if ( ch = = ' = ' ) {
styler . ColourTo ( i , SCE_H_OTHER ) ;
state = SCE_H_VALUE ;
} else {
state = SCE_H_OTHER ;
}
}
break ;
case SCE_H_OTHER :
if ( ch = = ' > ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
styler . ColourTo ( i , SCE_H_TAG ) ;
if ( inScriptType = = eNonHtmlScript ) {
state = StateForScript ( scriptLanguage ) ;
} else {
state = SCE_H_DEFAULT ;
}
tagOpened = false ;
2009-04-25 23:38:15 +00:00
if ( ! tagDontFold ) {
if ( tagClosing ) {
2009-04-24 23:35:41 +00:00
levelCurrent - - ;
} else {
levelCurrent + + ;
}
}
tagClosing = false ;
} else if ( ch = = ' \" ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_H_DOUBLESTRING ;
} else if ( ch = = ' \' ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_H_SINGLESTRING ;
} else if ( ch = = ' = ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_H_VALUE ;
} else if ( ch = = ' / ' & & chNext = = ' > ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
styler . ColourTo ( i + 1 , SCE_H_TAGEND ) ;
i + + ;
ch = chNext ;
state = SCE_H_DEFAULT ;
tagOpened = false ;
} else if ( ch = = ' ? ' & & chNext = = ' > ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
styler . ColourTo ( i + 1 , SCE_H_XMLEND ) ;
i + + ;
ch = chNext ;
state = SCE_H_DEFAULT ;
} else if ( setHTMLWord . Contains ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_H_ATTRIBUTE ;
}
break ;
case SCE_H_DOUBLESTRING :
if ( ch = = ' \" ' ) {
if ( inScriptType = = eNonHtmlScript ) {
scriptLanguage = segIsScriptingIndicator ( styler , styler . GetStartSegment ( ) , i , scriptLanguage ) ;
}
styler . ColourTo ( i , SCE_H_DOUBLESTRING ) ;
state = SCE_H_OTHER ;
}
break ;
case SCE_H_SINGLESTRING :
if ( ch = = ' \' ' ) {
if ( inScriptType = = eNonHtmlScript ) {
scriptLanguage = segIsScriptingIndicator ( styler , styler . GetStartSegment ( ) , i , scriptLanguage ) ;
}
styler . ColourTo ( i , SCE_H_SINGLESTRING ) ;
state = SCE_H_OTHER ;
}
break ;
case SCE_H_VALUE :
if ( ! setHTMLWord . Contains ( ch ) ) {
if ( ch = = ' \" ' & & chPrev = = ' = ' ) {
// Should really test for being first character
state = SCE_H_DOUBLESTRING ;
} else if ( ch = = ' \' ' & & chPrev = = ' = ' ) {
state = SCE_H_SINGLESTRING ;
} else {
if ( IsNumber ( styler . GetStartSegment ( ) , styler ) ) {
styler . ColourTo ( i - 1 , SCE_H_NUMBER ) ;
} else {
styler . ColourTo ( i - 1 , StateToPrint ) ;
}
if ( ch = = ' > ' ) {
styler . ColourTo ( i , SCE_H_TAG ) ;
if ( inScriptType = = eNonHtmlScript ) {
state = StateForScript ( scriptLanguage ) ;
} else {
state = SCE_H_DEFAULT ;
}
tagOpened = false ;
2009-04-25 23:38:15 +00:00
if ( ! tagDontFold ) {
if ( tagClosing ) {
2009-04-24 23:35:41 +00:00
levelCurrent - - ;
} else {
levelCurrent + + ;
}
}
tagClosing = false ;
} else {
state = SCE_H_OTHER ;
}
}
}
break ;
case SCE_HJ_DEFAULT :
case SCE_HJ_START :
case SCE_HJ_SYMBOLS :
if ( IsAWordStart ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_WORD ;
} else if ( ch = = ' / ' & & chNext = = ' * ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
if ( chNext2 = = ' * ' )
state = SCE_HJ_COMMENTDOC ;
else
state = SCE_HJ_COMMENT ;
2013-08-28 00:44:27 +00:00
if ( chNext2 = = ' / ' ) {
// Eat the * so it isn't used for the end of the comment
i + + ;
}
2009-04-24 23:35:41 +00:00
} else if ( ch = = ' / ' & & chNext = = ' / ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_COMMENTLINE ;
2013-08-28 00:44:27 +00:00
} else if ( ch = = ' / ' & & setOKBeforeJSRE . Contains ( chPrevNonWhite ) ) {
2009-04-24 23:35:41 +00:00
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_REGEX ;
} else if ( ch = = ' \" ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_DOUBLESTRING ;
} else if ( ch = = ' \' ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_SINGLESTRING ;
} else if ( ( ch = = ' < ' ) & & ( chNext = = ' ! ' ) & & ( chNext2 = = ' - ' ) & &
styler . SafeGetCharAt ( i + 3 ) = = ' - ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_COMMENTLINE ;
} else if ( ( ch = = ' - ' ) & & ( chNext = = ' - ' ) & & ( chNext2 = = ' > ' ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_COMMENTLINE ;
i + = 2 ;
} else if ( IsOperator ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
styler . ColourTo ( i , statePrintForState ( SCE_HJ_SYMBOLS , inScriptType ) ) ;
state = SCE_HJ_DEFAULT ;
} else if ( ( ch = = ' ' ) | | ( ch = = ' \t ' ) ) {
if ( state = = SCE_HJ_START ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_DEFAULT ;
}
}
break ;
case SCE_HJ_WORD :
if ( ! IsAWordChar ( ch ) ) {
classifyWordHTJS ( styler . GetStartSegment ( ) , i - 1 , keywords2 , styler , inScriptType ) ;
//styler.ColourTo(i - 1, eHTJSKeyword);
state = SCE_HJ_DEFAULT ;
if ( ch = = ' / ' & & chNext = = ' * ' ) {
if ( chNext2 = = ' * ' )
state = SCE_HJ_COMMENTDOC ;
else
state = SCE_HJ_COMMENT ;
} else if ( ch = = ' / ' & & chNext = = ' / ' ) {
state = SCE_HJ_COMMENTLINE ;
} else if ( ch = = ' \" ' ) {
state = SCE_HJ_DOUBLESTRING ;
} else if ( ch = = ' \' ' ) {
state = SCE_HJ_SINGLESTRING ;
} else if ( ( ch = = ' - ' ) & & ( chNext = = ' - ' ) & & ( chNext2 = = ' > ' ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_COMMENTLINE ;
i + = 2 ;
} else if ( IsOperator ( ch ) ) {
styler . ColourTo ( i , statePrintForState ( SCE_HJ_SYMBOLS , inScriptType ) ) ;
state = SCE_HJ_DEFAULT ;
}
}
break ;
case SCE_HJ_COMMENT :
case SCE_HJ_COMMENTDOC :
if ( ch = = ' / ' & & chPrev = = ' * ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HJ_DEFAULT ;
ch = ' ' ;
}
break ;
case SCE_HJ_COMMENTLINE :
if ( ch = = ' \r ' | | ch = = ' \n ' ) {
styler . ColourTo ( i - 1 , statePrintForState ( SCE_HJ_COMMENTLINE , inScriptType ) ) ;
state = SCE_HJ_DEFAULT ;
ch = ' ' ;
}
break ;
case SCE_HJ_DOUBLESTRING :
if ( ch = = ' \\ ' ) {
if ( chNext = = ' \" ' | | chNext = = ' \' ' | | chNext = = ' \\ ' ) {
i + + ;
}
} else if ( ch = = ' \" ' ) {
styler . ColourTo ( i , statePrintForState ( SCE_HJ_DOUBLESTRING , inScriptType ) ) ;
state = SCE_HJ_DEFAULT ;
} else if ( ( inScriptType = = eNonHtmlScript ) & & ( ch = = ' - ' ) & & ( chNext = = ' - ' ) & & ( chNext2 = = ' > ' ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_COMMENTLINE ;
i + = 2 ;
} else if ( isLineEnd ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_STRINGEOL ;
}
break ;
case SCE_HJ_SINGLESTRING :
if ( ch = = ' \\ ' ) {
if ( chNext = = ' \" ' | | chNext = = ' \' ' | | chNext = = ' \\ ' ) {
i + + ;
}
} else if ( ch = = ' \' ' ) {
styler . ColourTo ( i , statePrintForState ( SCE_HJ_SINGLESTRING , inScriptType ) ) ;
state = SCE_HJ_DEFAULT ;
} else if ( ( inScriptType = = eNonHtmlScript ) & & ( ch = = ' - ' ) & & ( chNext = = ' - ' ) & & ( chNext2 = = ' > ' ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_COMMENTLINE ;
i + = 2 ;
} else if ( isLineEnd ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
2010-09-05 22:56:27 +00:00
if ( chPrev ! = ' \\ ' & & ( chPrev2 ! = ' \\ ' | | chPrev ! = ' \r ' | | ch ! = ' \n ' ) ) {
state = SCE_HJ_STRINGEOL ;
}
2009-04-24 23:35:41 +00:00
}
break ;
case SCE_HJ_STRINGEOL :
if ( ! isLineEnd ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HJ_DEFAULT ;
} else if ( ! isLineEnd ( chNext ) ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HJ_DEFAULT ;
}
break ;
case SCE_HJ_REGEX :
if ( ch = = ' \r ' | | ch = = ' \n ' | | ch = = ' / ' ) {
if ( ch = = ' / ' ) {
while ( isascii ( chNext ) & & islower ( chNext ) ) { // gobble regex flags
i + + ;
ch = chNext ;
chNext = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 1 ) ) ;
}
}
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HJ_DEFAULT ;
} else if ( ch = = ' \\ ' ) {
// Gobble up the quoted character
if ( chNext = = ' \\ ' | | chNext = = ' / ' ) {
i + + ;
ch = chNext ;
chNext = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 1 ) ) ;
}
}
break ;
case SCE_HB_DEFAULT :
case SCE_HB_START :
if ( IsAWordStart ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HB_WORD ;
} else if ( ch = = ' \' ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HB_COMMENTLINE ;
} else if ( ch = = ' \" ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HB_STRING ;
} else if ( ( ch = = ' < ' ) & & ( chNext = = ' ! ' ) & & ( chNext2 = = ' - ' ) & &
styler . SafeGetCharAt ( i + 3 ) = = ' - ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HB_COMMENTLINE ;
} else if ( IsOperator ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
styler . ColourTo ( i , statePrintForState ( SCE_HB_DEFAULT , inScriptType ) ) ;
state = SCE_HB_DEFAULT ;
} else if ( ( ch = = ' ' ) | | ( ch = = ' \t ' ) ) {
if ( state = = SCE_HB_START ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HB_DEFAULT ;
}
}
break ;
case SCE_HB_WORD :
if ( ! IsAWordChar ( ch ) ) {
state = classifyWordHTVB ( styler . GetStartSegment ( ) , i - 1 , keywords3 , styler , inScriptType ) ;
if ( state = = SCE_HB_DEFAULT ) {
if ( ch = = ' \" ' ) {
state = SCE_HB_STRING ;
} else if ( ch = = ' \' ' ) {
state = SCE_HB_COMMENTLINE ;
} else if ( IsOperator ( ch ) ) {
styler . ColourTo ( i , statePrintForState ( SCE_HB_DEFAULT , inScriptType ) ) ;
state = SCE_HB_DEFAULT ;
}
}
}
break ;
case SCE_HB_STRING :
if ( ch = = ' \" ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HB_DEFAULT ;
} else if ( ch = = ' \r ' | | ch = = ' \n ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HB_STRINGEOL ;
}
break ;
case SCE_HB_COMMENTLINE :
if ( ch = = ' \r ' | | ch = = ' \n ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HB_DEFAULT ;
}
break ;
case SCE_HB_STRINGEOL :
if ( ! isLineEnd ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HB_DEFAULT ;
} else if ( ! isLineEnd ( chNext ) ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HB_DEFAULT ;
}
break ;
case SCE_HP_DEFAULT :
case SCE_HP_START :
if ( IsAWordStart ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HP_WORD ;
} else if ( ( ch = = ' < ' ) & & ( chNext = = ' ! ' ) & & ( chNext2 = = ' - ' ) & &
styler . SafeGetCharAt ( i + 3 ) = = ' - ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HP_COMMENTLINE ;
} else if ( ch = = ' # ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HP_COMMENTLINE ;
} else if ( ch = = ' \" ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
if ( chNext = = ' \" ' & & chNext2 = = ' \" ' ) {
i + = 2 ;
state = SCE_HP_TRIPLEDOUBLE ;
ch = ' ' ;
chPrev = ' ' ;
chNext = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 1 ) ) ;
} else {
// state = statePrintForState(SCE_HP_STRING,inScriptType);
state = SCE_HP_STRING ;
}
} else if ( ch = = ' \' ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
if ( chNext = = ' \' ' & & chNext2 = = ' \' ' ) {
i + = 2 ;
state = SCE_HP_TRIPLE ;
ch = ' ' ;
chPrev = ' ' ;
chNext = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 1 ) ) ;
} else {
state = SCE_HP_CHARACTER ;
}
} else if ( IsOperator ( ch ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
styler . ColourTo ( i , statePrintForState ( SCE_HP_OPERATOR , inScriptType ) ) ;
} else if ( ( ch = = ' ' ) | | ( ch = = ' \t ' ) ) {
if ( state = = SCE_HP_START ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HP_DEFAULT ;
}
}
break ;
case SCE_HP_WORD :
if ( ! IsAWordChar ( ch ) ) {
2013-08-28 00:44:27 +00:00
classifyWordHTPy ( styler . GetStartSegment ( ) , i - 1 , keywords4 , styler , prevWord , inScriptType , isMako ) ;
2009-04-24 23:35:41 +00:00
state = SCE_HP_DEFAULT ;
if ( ch = = ' # ' ) {
state = SCE_HP_COMMENTLINE ;
} else if ( ch = = ' \" ' ) {
if ( chNext = = ' \" ' & & chNext2 = = ' \" ' ) {
i + = 2 ;
state = SCE_HP_TRIPLEDOUBLE ;
ch = ' ' ;
chPrev = ' ' ;
chNext = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 1 ) ) ;
} else {
state = SCE_HP_STRING ;
}
} else if ( ch = = ' \' ' ) {
if ( chNext = = ' \' ' & & chNext2 = = ' \' ' ) {
i + = 2 ;
state = SCE_HP_TRIPLE ;
ch = ' ' ;
chPrev = ' ' ;
chNext = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 1 ) ) ;
} else {
state = SCE_HP_CHARACTER ;
}
} else if ( IsOperator ( ch ) ) {
styler . ColourTo ( i , statePrintForState ( SCE_HP_OPERATOR , inScriptType ) ) ;
}
}
break ;
case SCE_HP_COMMENTLINE :
if ( ch = = ' \r ' | | ch = = ' \n ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HP_DEFAULT ;
}
break ;
case SCE_HP_STRING :
if ( ch = = ' \\ ' ) {
if ( chNext = = ' \" ' | | chNext = = ' \' ' | | chNext = = ' \\ ' ) {
i + + ;
ch = chNext ;
chNext = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 1 ) ) ;
}
} else if ( ch = = ' \" ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HP_DEFAULT ;
}
break ;
case SCE_HP_CHARACTER :
if ( ch = = ' \\ ' ) {
if ( chNext = = ' \" ' | | chNext = = ' \' ' | | chNext = = ' \\ ' ) {
i + + ;
ch = chNext ;
chNext = static_cast < unsigned char > ( styler . SafeGetCharAt ( i + 1 ) ) ;
}
} else if ( ch = = ' \' ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HP_DEFAULT ;
}
break ;
case SCE_HP_TRIPLE :
if ( ch = = ' \' ' & & chPrev = = ' \' ' & & chPrev2 = = ' \' ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HP_DEFAULT ;
}
break ;
case SCE_HP_TRIPLEDOUBLE :
if ( ch = = ' \" ' & & chPrev = = ' \" ' & & chPrev2 = = ' \" ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HP_DEFAULT ;
}
break ;
///////////// start - PHP state handling
case SCE_HPHP_WORD :
if ( ! IsAWordChar ( ch ) ) {
classifyWordHTPHP ( styler . GetStartSegment ( ) , i - 1 , keywords5 , styler ) ;
if ( ch = = ' / ' & & chNext = = ' * ' ) {
i + + ;
state = SCE_HPHP_COMMENT ;
} else if ( ch = = ' / ' & & chNext = = ' / ' ) {
i + + ;
state = SCE_HPHP_COMMENTLINE ;
} else if ( ch = = ' # ' ) {
state = SCE_HPHP_COMMENTLINE ;
} else if ( ch = = ' \" ' ) {
state = SCE_HPHP_HSTRING ;
strcpy ( phpStringDelimiter , " \" " ) ;
} else if ( styler . Match ( i , " <<< " ) ) {
2009-04-25 23:38:15 +00:00
bool isSimpleString = false ;
i = FindPhpStringDelimiter ( phpStringDelimiter , sizeof ( phpStringDelimiter ) , i + 3 , lengthDoc , styler , isSimpleString ) ;
if ( strlen ( phpStringDelimiter ) ) {
state = ( isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING ) ;
if ( foldHeredoc ) levelCurrent + + ;
}
2009-04-24 23:35:41 +00:00
} else if ( ch = = ' \' ' ) {
state = SCE_HPHP_SIMPLESTRING ;
2009-04-25 23:38:15 +00:00
strcpy ( phpStringDelimiter , " \' " ) ;
2009-04-24 23:35:41 +00:00
} else if ( ch = = ' $ ' & & IsPhpWordStart ( chNext ) ) {
state = SCE_HPHP_VARIABLE ;
} else if ( IsOperator ( ch ) ) {
state = SCE_HPHP_OPERATOR ;
} else {
state = SCE_HPHP_DEFAULT ;
}
}
break ;
case SCE_HPHP_NUMBER :
// recognize bases 8,10 or 16 integers OR floating-point numbers
if ( ! IsADigit ( ch )
& & strchr ( " .xXabcdefABCDEF " , ch ) = = NULL
& & ( ( ch ! = ' - ' & & ch ! = ' + ' ) | | ( chPrev ! = ' e ' & & chPrev ! = ' E ' ) ) ) {
styler . ColourTo ( i - 1 , SCE_HPHP_NUMBER ) ;
if ( IsOperator ( ch ) )
state = SCE_HPHP_OPERATOR ;
else
state = SCE_HPHP_DEFAULT ;
}
break ;
case SCE_HPHP_VARIABLE :
2009-04-25 23:38:15 +00:00
if ( ! IsPhpWordChar ( chNext ) ) {
styler . ColourTo ( i , SCE_HPHP_VARIABLE ) ;
state = SCE_HPHP_DEFAULT ;
2009-04-24 23:35:41 +00:00
}
break ;
case SCE_HPHP_COMMENT :
if ( ch = = ' / ' & & chPrev = = ' * ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HPHP_DEFAULT ;
}
break ;
case SCE_HPHP_COMMENTLINE :
if ( ch = = ' \r ' | | ch = = ' \n ' ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HPHP_DEFAULT ;
}
break ;
case SCE_HPHP_HSTRING :
if ( ch = = ' \\ ' & & ( phpStringDelimiter [ 0 ] = = ' \" ' | | chNext = = ' $ ' | | chNext = = ' { ' ) ) {
// skip the next char
i + + ;
} else if ( ( ( ch = = ' { ' & & chNext = = ' $ ' ) | | ( ch = = ' $ ' & & chNext = = ' { ' ) )
& & IsPhpWordStart ( chNext2 ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HPHP_COMPLEX_VARIABLE ;
} else if ( ch = = ' $ ' & & IsPhpWordStart ( chNext ) ) {
styler . ColourTo ( i - 1 , StateToPrint ) ;
state = SCE_HPHP_HSTRING_VARIABLE ;
} else if ( styler . Match ( i , phpStringDelimiter ) ) {
2009-04-25 23:38:15 +00:00
if ( phpStringDelimiter [ 0 ] = = ' \" ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HPHP_DEFAULT ;
} else if ( isLineEnd ( chPrev ) ) {
2013-08-28 00:44:27 +00:00
const int psdLength = static_cast < int > ( strlen ( phpStringDelimiter ) ) ;
2009-04-25 23:38:15 +00:00
const char chAfterPsd = styler . SafeGetCharAt ( i + psdLength ) ;
const char chAfterPsd2 = styler . SafeGetCharAt ( i + psdLength + 1 ) ;
if ( isLineEnd ( chAfterPsd ) | |
( chAfterPsd = = ' ; ' & & isLineEnd ( chAfterPsd2 ) ) ) {
i + = ( ( ( i + psdLength ) < lengthDoc ) ? psdLength : lengthDoc ) - 1 ;
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HPHP_DEFAULT ;
if ( foldHeredoc ) levelCurrent - - ;
}
}
2009-04-24 23:35:41 +00:00
}
break ;
case SCE_HPHP_SIMPLESTRING :
2009-04-25 23:38:15 +00:00
if ( phpStringDelimiter [ 0 ] = = ' \' ' ) {
if ( ch = = ' \\ ' ) {
// skip the next char
i + + ;
} else if ( ch = = ' \' ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HPHP_DEFAULT ;
}
} else if ( isLineEnd ( chPrev ) & & styler . Match ( i , phpStringDelimiter ) ) {
2013-08-28 00:44:27 +00:00
const int psdLength = static_cast < int > ( strlen ( phpStringDelimiter ) ) ;
2009-04-25 23:38:15 +00:00
const char chAfterPsd = styler . SafeGetCharAt ( i + psdLength ) ;
const char chAfterPsd2 = styler . SafeGetCharAt ( i + psdLength + 1 ) ;
if ( isLineEnd ( chAfterPsd ) | |
( chAfterPsd = = ' ; ' & & isLineEnd ( chAfterPsd2 ) ) ) {
i + = ( ( ( i + psdLength ) < lengthDoc ) ? psdLength : lengthDoc ) - 1 ;
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HPHP_DEFAULT ;
if ( foldHeredoc ) levelCurrent - - ;
}
2009-04-24 23:35:41 +00:00
}
break ;
case SCE_HPHP_HSTRING_VARIABLE :
2009-04-25 23:38:15 +00:00
if ( ! IsPhpWordChar ( chNext ) ) {
styler . ColourTo ( i , StateToPrint ) ;
2009-04-24 23:35:41 +00:00
state = SCE_HPHP_HSTRING ;
}
break ;
case SCE_HPHP_COMPLEX_VARIABLE :
if ( ch = = ' } ' ) {
styler . ColourTo ( i , StateToPrint ) ;
state = SCE_HPHP_HSTRING ;
}
break ;
case SCE_HPHP_OPERATOR :
case SCE_HPHP_DEFAULT :
styler . ColourTo ( i - 1 , StateToPrint ) ;
if ( IsADigit ( ch ) | | ( ch = = ' . ' & & IsADigit ( chNext ) ) ) {
state = SCE_HPHP_NUMBER ;
} else if ( IsAWordStart ( ch ) ) {
state = SCE_HPHP_WORD ;
} else if ( ch = = ' / ' & & chNext = = ' * ' ) {
i + + ;
state = SCE_HPHP_COMMENT ;
} else if ( ch = = ' / ' & & chNext = = ' / ' ) {
i + + ;
state = SCE_HPHP_COMMENTLINE ;
} else if ( ch = = ' # ' ) {
state = SCE_HPHP_COMMENTLINE ;
} else if ( ch = = ' \" ' ) {
state = SCE_HPHP_HSTRING ;
strcpy ( phpStringDelimiter , " \" " ) ;
} else if ( styler . Match ( i , " <<< " ) ) {
2009-04-25 23:38:15 +00:00
bool isSimpleString = false ;
i = FindPhpStringDelimiter ( phpStringDelimiter , sizeof ( phpStringDelimiter ) , i + 3 , lengthDoc , styler , isSimpleString ) ;
if ( strlen ( phpStringDelimiter ) ) {
state = ( isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING ) ;
if ( foldHeredoc ) levelCurrent + + ;
}
2009-04-24 23:35:41 +00:00
} else if ( ch = = ' \' ' ) {
state = SCE_HPHP_SIMPLESTRING ;
2009-04-25 23:38:15 +00:00
strcpy ( phpStringDelimiter , " \' " ) ;
2009-04-24 23:35:41 +00:00
} else if ( ch = = ' $ ' & & IsPhpWordStart ( chNext ) ) {
state = SCE_HPHP_VARIABLE ;
} else if ( IsOperator ( ch ) ) {
state = SCE_HPHP_OPERATOR ;
} else if ( ( state = = SCE_HPHP_OPERATOR ) & & ( IsASpace ( ch ) ) ) {
state = SCE_HPHP_DEFAULT ;
}
break ;
///////////// end - PHP state handling
}
// Some of the above terminated their lexeme but since the same character starts
// the same class again, only reenter if non empty segment.
bool nonEmptySegment = i > = static_cast < int > ( styler . GetStartSegment ( ) ) ;
if ( state = = SCE_HB_DEFAULT ) { // One of the above succeeded
if ( ( ch = = ' \" ' ) & & ( nonEmptySegment ) ) {
state = SCE_HB_STRING ;
} else if ( ch = = ' \' ' ) {
state = SCE_HB_COMMENTLINE ;
} else if ( IsAWordStart ( ch ) ) {
state = SCE_HB_WORD ;
} else if ( IsOperator ( ch ) ) {
styler . ColourTo ( i , SCE_HB_DEFAULT ) ;
}
} else if ( state = = SCE_HBA_DEFAULT ) { // One of the above succeeded
if ( ( ch = = ' \" ' ) & & ( nonEmptySegment ) ) {
state = SCE_HBA_STRING ;
} else if ( ch = = ' \' ' ) {
state = SCE_HBA_COMMENTLINE ;
} else if ( IsAWordStart ( ch ) ) {
state = SCE_HBA_WORD ;
} else if ( IsOperator ( ch ) ) {
styler . ColourTo ( i , SCE_HBA_DEFAULT ) ;
}
} else if ( state = = SCE_HJ_DEFAULT ) { // One of the above succeeded
if ( ch = = ' / ' & & chNext = = ' * ' ) {
if ( styler . SafeGetCharAt ( i + 2 ) = = ' * ' )
state = SCE_HJ_COMMENTDOC ;
else
state = SCE_HJ_COMMENT ;
} else if ( ch = = ' / ' & & chNext = = ' / ' ) {
state = SCE_HJ_COMMENTLINE ;
} else if ( ( ch = = ' \" ' ) & & ( nonEmptySegment ) ) {
state = SCE_HJ_DOUBLESTRING ;
} else if ( ( ch = = ' \' ' ) & & ( nonEmptySegment ) ) {
state = SCE_HJ_SINGLESTRING ;
} else if ( IsAWordStart ( ch ) ) {
state = SCE_HJ_WORD ;
} else if ( IsOperator ( ch ) ) {
styler . ColourTo ( i , statePrintForState ( SCE_HJ_SYMBOLS , inScriptType ) ) ;
}
}
}
2009-04-25 23:38:15 +00:00
switch ( state ) {
case SCE_HJ_WORD :
classifyWordHTJS ( styler . GetStartSegment ( ) , lengthDoc - 1 , keywords2 , styler , inScriptType ) ;
break ;
case SCE_HB_WORD :
classifyWordHTVB ( styler . GetStartSegment ( ) , lengthDoc - 1 , keywords3 , styler , inScriptType ) ;
break ;
case SCE_HP_WORD :
2013-08-28 00:44:27 +00:00
classifyWordHTPy ( styler . GetStartSegment ( ) , lengthDoc - 1 , keywords4 , styler , prevWord , inScriptType , isMako ) ;
2009-04-25 23:38:15 +00:00
break ;
case SCE_HPHP_WORD :
classifyWordHTPHP ( styler . GetStartSegment ( ) , lengthDoc - 1 , keywords5 , styler ) ;
break ;
default :
StateToPrint = statePrintForState ( state , inScriptType ) ;
2013-08-28 00:44:27 +00:00
if ( static_cast < int > ( styler . GetStartSegment ( ) ) < lengthDoc )
styler . ColourTo ( lengthDoc - 1 , StateToPrint ) ;
2009-04-25 23:38:15 +00:00
break ;
}
2009-04-24 23:35:41 +00:00
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
if ( fold ) {
int flagsNext = styler . LevelAt ( lineCurrent ) & ~ SC_FOLDLEVELNUMBERMASK ;
styler . SetLevel ( lineCurrent , levelPrev | flagsNext ) ;
}
}
static void ColouriseXMLDoc ( unsigned int startPos , int length , int initStyle , WordList * keywordlists [ ] ,
Accessor & styler ) {
// Passing in true because we're lexing XML
2009-04-25 23:38:15 +00:00
ColouriseHyperTextDoc ( startPos , length , initStyle , keywordlists , styler , true ) ;
2009-04-24 23:35:41 +00:00
}
static void ColouriseHTMLDoc ( unsigned int startPos , int length , int initStyle , WordList * keywordlists [ ] ,
Accessor & styler ) {
// Passing in false because we're notlexing XML
2009-04-25 23:38:15 +00:00
ColouriseHyperTextDoc ( startPos , length , initStyle , keywordlists , styler , false ) ;
2009-04-24 23:35:41 +00:00
}
static void ColourisePHPScriptDoc ( unsigned int startPos , int length , int initStyle , WordList * keywordlists [ ] ,
2009-04-25 23:38:15 +00:00
Accessor & styler ) {
if ( startPos = = 0 )
initStyle = SCE_HPHP_DEFAULT ;
ColouriseHTMLDoc ( startPos , length , initStyle , keywordlists , styler ) ;
2009-04-24 23:35:41 +00:00
}
static const char * const htmlWordListDesc [ ] = {
" HTML elements and attributes " ,
" JavaScript keywords " ,
" VBScript keywords " ,
" Python keywords " ,
" PHP keywords " ,
" SGML and DTD keywords " ,
0 ,
} ;
static const char * const phpscriptWordListDesc [ ] = {
" " , //Unused
" " , //Unused
" " , //Unused
" " , //Unused
" PHP keywords " ,
" " , //Unused
0 ,
} ;
LexerModule lmHTML ( SCLEX_HTML , ColouriseHTMLDoc , " hypertext " , 0 , htmlWordListDesc , 8 ) ;
LexerModule lmXML ( SCLEX_XML , ColouriseXMLDoc , " xml " , 0 , htmlWordListDesc , 8 ) ;
LexerModule lmPHPSCRIPT ( SCLEX_PHPSCRIPT , ColourisePHPScriptDoc , " phpscript " , 0 , phpscriptWordListDesc , 8 ) ;