# JOE syntax highlight file for JavaScript

# the real one - not a pimped Java file...
# just getting this idea seams crazy...

# TODO: regex escape highlighter ignored \x (and other?) sequences

=Idle		
=Comment	green
=CommentLabel	bold green
=Constant	cyan
=Escape		bold cyan
=Type		bold
=Keyword	bold
=Operator	bold
=Bad		inverse bold red
=Brace		magenta
=Control	

# additional classes not present everywhere but useful
=Methods
=Number		cyan #fg_520 # orange

# from html.jsf to support <?php?>
=TagEdge	green

:begin Idle
	*		begin		noeat call=.js()

.subr js

:idle Idle
	*		idle
	"\n"		idle
	"/"		slash
	"0"		first_digit	recolor=-1
	"1-9"		decimal		recolor=-1
	"."		maybe_float
	"\""		string		recolor=-1
	"'"		char		recolor=-1
	"a-zA-Z_"	ident		mark buffer
	"{}"		brace		recolor=-1
.ifdef html
	",:;=()>[]*&|!?~+\-%^"	control	recolor=-1
	"<"		maybe_done	recolor=-1
.else
.ifdef php
	",:;=()>[]*&|!?~+\-%^"	control	recolor=-1
	"<"		maybe_done	recolor=-1
.else
	",:;=()><[]*&|!?~+\-%^"	control recolor=-1
.endif
.endif

# / / regex not allowed after terms
# class Control to handle ')' right
:after_term Control
	*		idle		noeat
	" \t)"		after_term
	"%"		control		recolor=-1
	"/"		after_term_slash

:maybe_done TagEdge
	*		idle		noeat
	"/"		idle		noeat return recolor=-2
.ifdef php
	"?%"		rtn_php		call=php.php()
.endif

# this state allows php and perl to recolor the ?> %> or &> properly.
:rtn_php TagEdge
	*		idle		noeat

:brace Brace
	*		idle		noeat

:control Control
	*		idle		noeat

:slash Idle
	*		regex		noeat recolor=-2
	"*"		comment		recolor=-2
	"/"		line_comment	recolor=-2

# allow // and /* after terms
:after_term_slash Idle
	*		idle		noeat
	"*"		comment		recolor=-2
	"/"		line_comment	recolor=-2

:comment Comment
	*		comment
	# might be TODO label
	"BFHNTX"	comment		noeat call=.comment_todo()
	"*"		maybe_end_comment

:maybe_end_comment Comment
	*		comment		noeat
	"/"		idle
	"*"		maybe_end_comment

:line_comment Comment
	*		line_comment
	# might be TODO label
	"BFHNTX"	line_comment	noeat call=.comment_todo()
	"\n"		idle

:regex Constant
	*		regex
	"\\"		regex_quote	recolor=-1
	"/"		regex_mod

:regex_quote Escape
	*		regex

:regex_mod Constant
	*		after_term	noeat
	"igm"		regex_mod

:first_digit Number
	*		after_term	noeat
	"xX"		hex
	"."		float
	"eE"		epart
	"0-7"		octal
	"89"		bad_number	recolor=-1

:bad_number Bad
	*		after_term	noeat
	"0-9"		bad_number

:octal Number
	*		after_term	noeat
	"0-7"		octal
	"89"		bad_number	recolor=-1

:hex Number
	*		after_term	noeat
	"0-9A-Fa-f"	hex

:decimal Number
	*		after_term	noeat
	"0-9"		decimal
	"eE"		epart
	"."		float

:maybe_float Number
	*		after_term	recolor=-2 noeat
	"0-9"		float		recolor=-2

:float Number
	*		after_term	noeat
	"eE"		epart
	"0-9"		float

:epart Number
	*		after_term	noeat
	"0-9+\-"	enum

:enum Number
	*		after_term	noeat
	"0-9"		enum

:string	Constant
	*		string
	"\""		after_term
	"\\"		string_escape	recolor=-1
	"%"		string_control	recolor=-1

:string_escape Escape
	*		string
	"x"		string_hex1
	"0-7"		string_octal2
	"\n"		string		recolor=-2

:string_hex1 Escape
	*		string		noeat
	"0-9a-fA-F"	string_hex2

:string_hex2 Escape
	*		string		noeat
	"0-9a-fA-F"	string

:string_octal2 Escape
	*		string		noeat
	"0-7"		string_octal3

:string_octal3 Escape
	*		string		noeat
	"0-7"		string

:string_control Escape
	*		string_control
	"\n"		reset
	"diouxXeEfFgGaAcspn%SC"	string

:char Constant
	*		char
	"\n"		reset
	"'"		after_term
	"\\"		char_escape	recolor=-1

:char_escape	Escape
	*		char
	"x"		char_hex1
	"0-7"		char_octal2
	"\n"		char		recolor=-2

:char_hex1 Escape
	*		char		noeat
	"0-9a-fA-F"	char_hex2

:char_hex2 Escape
	*		char		noeat
	"0-9a-fA-F"	char

:char_octal2 Escape
	*		char		noeat
	"0-7"		char_octal3

:char_octal3 Escape
	*		char		noeat
	"0-7"		char

:ident Idle
	*		ident_end	noeat markend strings
	"arguments"	kw
	"Array"		type
	"break"		kw
	"Boolean"	type
	"case"		kw
	"catch"		kw
	"continue"	kw
	"default"	kw
	"delete"	operator
	"do"		kw
	"Date"		type
	"else"		kw
	"false"		lit
	"finally"	kw
	"for"		kw
	"function"	kw
	"Function"	type
	"if"		kw
	"in"		kw
	"instanceof"	operator
	"let"		kw
	"new"		operator
	"null"		lit
	"Number"	type
	"Object"	type
	"return"	kw
	"RegExp"	type
	"switch"	kw
	"String"	type
	"this"		kw
	"throw"		kw
	"true"		lit
	"try"		kw
	"typeof"	operator
	"undefined"	lit
	"var"		kw
	"void"		kw
	"while"		kw
	"with"		kw
	# quasi-keywords
	"prototype"	kw
done
	"a-zA-Z0-9_"	ident

:type Type
	*		after_term	noeat

:kw Keyword
	*		idle		noeat

:lit Constant
	*		after_term	noeat

:operator Operator
	*		idle		noeat

:ident_end Idle
	*		after_term	noeat
	" "		ident_end
	"("		method_end	noeat recolormark

:method_end Methods
	*		idle		noeat

.end

.subr comment_todo
# initial state
:comment_todo_init Comment
	*		comment_todo_guess	buffer

# highlight common TODO labels
:comment_todo_guess Comment
	*		comment_todo_unknown	noeat strings
	"BUG"		comment_todo
	"FIXME"		comment_todo
	"HACK"		comment_todo
	"NOTE"		comment_todo
	"TODO"		comment_todo
	"XXX"		comment_todo
done
	"A-Z"		comment_todo_guess

:comment_todo_unknown Comment
	*		NULL		noeat return

:comment_todo CommentLabel
	*		NULL		noeat return
.end