# JOE syntax highlight file for Python

=Idle
=Comment 	green
=Docstring	cyan
=DocEscape	bold cyan
=Constant 	cyan
=Escape 	bold cyan
=Keyword 	bold
=Type		bold blue

:idle Idle
	*		idle
	"#"		comment		recolor=-1
	"0-9"		first_digit	recolor=-1
	"'"		string_sq_1	recolor=-1
	"\""		string_dq_1	recolor=-1
	"a-zA-Z_"	ident		buffer

:comment Comment
	*		comment
	"\n"		idle

:first_digit Constant
	*		idle	noeat
	"xX"		hex
	"."		float
	"eE"		epart
	"0-9"		first_number

:hex Constant
	*		idle	noeat
	"0-9A-Fa-f"	hex

:first_number Constant
	*		idle	noeat
	"0-9"		first_number
	"."		float

:maybe_float Constant
	*		idle	recolor=-2	noeat
	"0-9"		float		recolor=-2

:float Constant
	*		idle	noeat
	"eE"		epart
	"0-9"		float

:epart Constant
	*		idle	noeat
	"0-9+\-"	enum

:enum Constant
	*		idle	noeat
	"0-9"		enum

:ident Idle
	*		idle		noeat strings
	"and"		kw
	"as"		kw
	"assert"	kw
	"break"		kw
	"class"		defkw
	"continue"	kw
	"def"		defkw
	"del"		kw
	"elif"		kw
	"else"		kw
	"except"	kw
	"exec"		kw
	"finally"	kw
	"for"		kw
	"from"		kw
	"global"	kw
	"if"		kw
	"import"	kw
	"in"		kw
	"is"		kw
	"lambda"	kw
	"not"		kw
	"or"		kw
	"pass"		kw
	"print"		kw
	"raise"		kw
	"return"	kw
	"try"		kw
	"while"		kw
	"with"		kw
	"yield"		kw
	
	"True"		constkw
	"False"		constkw
	"None"		constkw
done
	"'\""		idle noeat istrings
	"u"		string_pre
	"b"		string_pre
	"r"		string_raw_pre
	"br"		string_raw_pre
	"rb"		string_raw_pre
done
	"a-zA-Z0-9_"	ident

:kw Keyword
	*	idle	noeat

:constkw Constant
	*		idle noeat recolor=-1
	"a-zA-Z"	constkw

:defkw Keyword
	*		idle noeat recolor=-1
	"a-zA-Z"	defkw	# This is still the keyword.
	" \t"		defname

:defname Type
	*		idle noeat recolor=-1
	"a-zA-Z0-9_"	defname

# Handle string prefixes up to the string itself.
:string_pre Constant
	*		idle noeat
	"\""		string_dq_1
	"'"		string_sq_1

:string_raw_pre Constant
	*		idle noeat
	"\""		string_dq_raw_1
	"'"		string_sq_raw_1

# Differentiate between docstrings and regular strings, carrying with it raw state
:string_dq_1 Constant
	*		idle call=.string(dquote) noeat
	"\""		string_dq_2

:string_dq_2 Constant
	*		idle noeat
	"\""		idle call=.string(dquote docstring) recolor=-3

:string_sq_1 Constant
	*		idle call=.string(squote) noeat
	"'"		string_sq_2

:string_sq_2 Constant
	*		idle noeat
	"'"		idle call=.string(squote docstring) recolor=-3

:string_dq_raw_1 Constant
	*		idle call=.string(dquote raw)
	"\""		string_dq_raw_2

:string_dq_raw_2 Constant
	*		idle noeat
	"\""		idle call=.string(dquote docstring raw) recolor=-3

:string_sq_raw_1 Constant
	*		idle call=.string(squote raw)
	"'"		string_sq_raw_2

:string_sq_raw_2 Constant
	*		idle noeat
	"'"		idle call=.string(squote docstring raw) recolor=-3

.subr string

.ifdef docstring	# Long strings
:string Docstring
	*		string
.ifdef raw
.else
	"\\"		string_esc mark
.endif
.ifdef squote
	"'"		doc_end_1
.else
	"\""		doc_end_1
.endif

:doc_end_1 Docstring
	*		string noeat
.ifdef squote
	"'"		doc_end_2
.else
	"\""		doc_end_2
.endif

:doc_end_2 Docstring
	*		string noeat
.ifdef squote
	"'"		string return
.else
	"\""		string return
.endif

.else			# Short strings

:string Constant
	*		string
	"\n"		string return
.ifdef raw
.else
	"\\"		string_esc mark
.endif
.ifdef squote
	"'"		string return
.else
	"\""		string return
.endif

.endif

:string_esc Constant
	*		string_esc_done
	"x"		string_hex2
	"u"		string_hex4
	"U"		string_hex8
	"0-7"		string_octal2
	"\n"		string_esc_done

# Recolor whole escape sequence based on whether this is a docstring.
:string_esc_done Constant
	*		string_esc_really_done noeat markend recolormark

.ifdef docstring
:string_esc_really_done DocEscape
	*		string noeat
.else
:string_esc_really_done Escape
	*		string noeat
.endif

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

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

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

:string_hex4 Escape
	*		string_esc_done		noeat
	"0-9a-fA-F"	string_hex3

:string_hex5 Escape
	*		string_esc_done		noeat
	"0-9a-fA-F"	string_hex4

:string_hex6 Escape
	*		string_esc_done		noeat
	"0-9a-fA-F"	string_hex5

:string_hex7 Escape
	*		string_esc_done		noeat
	"0-9a-fA-F"	string_hex6

:string_hex8 Escape
	*		string_esc_done		noeat
	"0-9a-fA-F"	string_hex7

:string_octal1 Escape
	*		string_esc_done		noeat
	"0-7"		string_esc_done

:string_octal2 Escape
	*		string_esc_done		noeat
	"0-7"		string_octal1

.end
