--- a
+++ b/syntax/ocaml.jsf.in
@@ -0,0 +1,476 @@
+# JOE syntax highlight file for OCaml
+
+# A (deterministic) state machine which performs lexical analysis of OCaml.
+# (This is the "assembly language" of syntax highlighting.  A separate
+# program could be used to convert a regular expression NFA syntax into this
+# format).
+
+# Each state begins with ':<name> <color-name>'
+# <color-name> is the color used for characters eaten by the state
+# (really a symbol for a user definable color).
+
+# The first state defined is the initial state.
+
+# Within a state, define transitions (jumps) to other states.  Each
+# jump has the form: <character-list> <target-state> [<option>s]
+
+# There are two ways to specify <character-list>s, either * for any
+# character not otherwise specified, or a literal list of characters within
+# quotes (ranges and escape sequences allows).  When the next character
+# matches any in the list, a jump to the target-state is taken and the
+# character is eaten (we advance to the next character of the file to be
+# colored).
+#
+# The * transition should be the first transition specified in the state.
+#
+# There are several options:
+#   noeat     	do not eat the character, instead feed it to the next state
+#             	(this tends to make the states smaller, but be careful: you
+#		can make infinite loops).  'noeat' implies 'recolor=-1'.
+#
+#   recolor=-N	Recolor the past N characters with the color of the
+#		target-state.  For example once /* is recognized as the
+#		start of C comment, you want to color the /* with the C
+#		comment color.
+#
+#   buffer    	start copying characters to a buffer, beginning with this
+#		one (it's ok to not terminate buffering with a matching
+#		'strings' option- the buffer is limited to leading 19
+#		characters).
+#
+#   strings	A list of strings follows.  If the buffer matches any of the
+#		given strings, a jump to the target-state in the string list
+#		is taken instead of the normal jump.
+#
+#   istrings	Same as strings, but case is ignored.
+#
+#   hold        Stop buffering string- a future 'strings' or 'istrings' will
+#               look at contents of buffer at this point.  Useful for distinguishing
+#               commands and function calls in some languages 'write 7' is a command
+#               'write (' is a function call- hold lets us stop at the space and delay
+#               the string lookup until the ( or 7.
+#
+#   The format of the string list is:
+#
+#      "string"   <target-state> [<options>s]
+#      "string"   <target-state> [<options>s]
+#      done
+#
+#   (all of the options above are allowed except "strings", "istrings" and "noeat".  noeat is
+#    always implied after a matched string).
+#
+# Weirdness: only states have colors, not transitions.  This means that you
+# sometimes have to make dummy states with '* next-state noeat' just to get
+# a color specification.
+
+# Define no. sync lines
+# You can say:
+# -200     means 200 lines
+# -        means always start parsing from beginning of file when we lose sync
+#          if nothing is specified, the default is -50
+
+# Define colors
+#
+# bold inverse blink dim underline
+# white cyan magenta blue yellow green red black
+# bg_white bg_cyan bg_magenta bg_blue bg_yellow bg_green bg_red bg_black
+
+=Expr
+=Bad		bold red
+=Comment 	green
+=Literal 	cyan
+=Escape 	bold cyan
+=Type 		bold
+=Keyword 	bold
+=Operator	blue
+=Control	magenta
+=CapId		blue
+=LowId
+=Stdlib		bold blue
+
+# Bugs:
+# = in some contexts is a control, not an operator (let, etc)
+# "type" keyword introduces a type = type
+
+:expr Expr
+	*		expr
+	"#.,)];"	control		recolor=-1
+	"!?"		prefixop	recolor=-1
+	"=<>@^&+*/$%"	infixop		recolor=-1
+	"\-"		minus		recolor=-1
+	"~"		tilde		recolor=-1
+	"["		brace		recolor=-1
+	"|"		pipe		recolor=-1
+	":"		colon		recolor=-1
+	"("		bracket		recolor=-1
+	"0"		zero		recolor=-1
+	"1-9"		decimal		recolor=-1
+	"\""		string		recolor=-1
+	"\'"		char		recolor=-1
+	"a-z_"		lowid		buffer recolor=-1
+	"A-Z`"		capid		buffer recolor=-1
+
+:bad Bad
+	*		expr
+
+:control Control
+	*		expr		noeat
+
+:prefixop Operator
+	*		operator	noeat
+
+:infixop Operator
+	*		operator	noeat
+
+:operator Operator
+	*		expr 		noeat
+	"!?~=<>@^|&+*/$%.:\-"	operator
+
+:minus Operator
+	*		operator	noeat
+	"0"		zero		recolor=-2
+	"1-9"		decimal		recolor=-2
+
+:tilde Operator
+	*		prefixop	noeat
+	"a-z"		opparam		noeat
+
+:opparam LowId
+	*		expr		noeat
+	"a-zA-Z0-9_'"	opparam
+	":"		control
+
+:brace Control
+	*		expr		noeat
+	"|"		expr
+
+:pipe Operator
+	*		infixop		noeat
+	"]"		pipeclose	recolor=-2
+
+:pipeclose Control
+	*		expr		noeat	
+
+:colon Operator
+	*		type1		noeat
+	"="		assign		recolor=-2
+
+:assign Operator
+	*		expr		noeat
+
+:bracket Control
+	*		expr		noeat
+	"*"		comment1	recolor=-2
+
+:zero Literal
+	*		expr		noeat
+	"0-9_"		decimal
+	"b"		binaryl		buffer
+	"B"		binaryh		buffer
+	"o"		octall		buffer
+	"O"		octalh		buffer
+	"x"		hexl		buffer
+	"X"		hexh		buffer
+	"e"		epartl		buffer
+	"E"		eparth		buffer
+	"."		float
+
+:decimal Literal
+	*		expr		noeat
+	"0-9_"		decimal
+	"."		float
+	"e"		epartl		buffer
+	"E"		eparth		buffer
+
+:binaryl Literal
+	*		lowid		noeat recolor=-2
+	"01"		binary
+:binaryh Literal
+	*		capid		noeat recolor=-2
+	"01"		binary
+:binary Literal
+	*		expr		noeat
+	"01_"		binary
+
+:octall Literal
+	*		lowid		noeat recolor=-2
+	"0-7"		octal
+:octalh Literal
+	*		capid		noeat recolor=-2
+	"0-7"		octal
+:octal Literal
+	*		expr		noeat
+	"0-7_"		octal
+
+:hexl Literal
+	*		lowid		noeat recolor=-2
+	"0-9a-fA-F"	hex
+:hexh Literal
+	*		capid		noeat recolor=-2
+	"0-9a-fA-F"	hex
+:hex Literal
+	*		expr		noeat
+	"0-9a-fA-F_"	hex
+
+:float Literal
+	*		expr		noeat
+	"0-9_"		float
+	"e"		epartl		buffer
+	"E"		eparth		buffer
+
+:epartl Literal
+	*		lowid		noeat recolor=-2
+	"0-9"		enum
+	"+\-"		enum1
+:eparth Literal
+	*		capid		noeat recolor=-2
+	"0-9"		enum
+	"+\-"		enum1
+
+:enum1 Literal
+	*		bad		noeat
+	"0-9_"		enum
+:enum Literal
+	*		expr		noeat
+	"0-9_"		enum
+
+:string	Literal
+	*		string
+	"\""		expr
+	"\\"		string_escape	recolor=-1
+	"%"		string_control	recolor=-1
+
+:string_escape Escape
+	*		string
+	"x"		string_hex1
+	"0-7"		string_octal2
+
+: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
+	"\""		string		noeat
+	"diouxXeEfFgGaAcspn%SC"	string
+
+:char Literal
+	*		charend
+	"\\"		char_escape	recolor=-1
+
+:charend Literal
+	*		bad		noeat
+	"\'"		expr
+
+:char_escape Escape
+	*		charend
+	"x"		char_hex1
+	"0-7"		char_octal2
+
+:char_hex1 Escape
+	*		bad		noeat
+	"0-9a-fA-F"	char_hex2
+
+:char_hex2 Escape
+	*		charend		noeat
+	"0-9a-fA-F"	charend
+
+:char_octal2 Escape
+	*		charend		noeat
+	"0-7"		char_octal3
+
+:char_octal3 Escape
+	*		charend		noeat
+	"0-7"		charend
+
+:lowid LowId
+	*		expr		noeat strings
+	"_"		kw
+	"and"		kw
+	"as"		kw
+	"assert"	kw
+	"begin"		kw
+	"class"		kw
+	"constraint"	kw
+	"do"		kw
+	"done"		kw
+	"downto"	kw
+	"else"		kw
+	"end"		kw
+	"exception"	kw
+	"external"	kw
+	"false"		kw
+	"for"		kw
+	"fun"		kw
+	"function"	kw
+	"functor"	kw
+	"if"		kw
+	"in"		kw
+	"include"	kw
+	"inherit"	kw
+	"initializer"	kw
+	"lazy"		kw
+	"let"		kw
+	"match"		kw
+	"method"	kw
+	"module"	kw
+	"mutable"	kw
+	"new"		kw
+	"object"	kw
+	"of"		kw
+	"open"		kw
+	"private"	kw
+	"raise"		kw # technically not, but ...
+	"rec"		kw
+	"sig"		kw
+	"struct"	kw
+	"then"		kw
+	"to"		kw
+	"true"		kw
+	"try"		kw
+	"type"		kw
+	"val"		kw
+	"virtual"	kw
+	"when"		kw
+	"while"		kw
+	"with"		kw
+	"asr"		operatorkw
+	"land"		operatorkw
+	"lor"		operatorkw
+	"lsl"		operatorkw
+	"lsr"		operatorkw
+	"lxor"		operatorkw
+	"mod"		operatorkw
+	"or"		operatorkw
+done
+	"a-zA-Z0-9_'"	lowid
+
+:kw Keyword
+	*		expr		noeat
+
+:operatorkw Operator
+	*		expr		noeat
+
+:capid CapId
+	*		expr		noeat strings
+	"Arg"		stdlib
+	"Array"		stdlib
+	"ArrayLabels"	stdlib
+	"Buffer"	stdlib
+	"Callback"	stdlib
+	"Char"		stdlib
+	"Complex"	stdlib
+	"Digest"	stdlib
+	"Filename"	stdlib
+	"Format"	stdlib
+	"Gc"		stdlib
+	"Genlex"	stdlib
+	"Hashtbl"	stdlib
+	"Int32"		stdlib
+	"Int64"		stdlib
+	"Lazy"		stdlib
+	"Lexing"	stdlib
+	"List"		stdlib
+	"ListLabels"	stdlib
+	"Map"		stdlib
+	"Marshal"	stdlib
+	"MoreLabels"	stdlib
+	"Nativeint"	stdlib
+	"Oo"		stdlib
+	"Parsing"	stdlib
+	"Printexc"	stdlib
+	"Printf"	stdlib
+	"Queue"		stdlib
+	"Random"	stdlib
+	"Scanf"		stdlib
+	"Set"		stdlib
+	"Sort"		stdlib
+	"Stack"		stdlib
+	"StdLabels"	stdlib
+	"Stream"	stdlib
+	"String"	stdlib
+	"StringLabels"	stdlib
+	"Sys"		stdlib
+	"Weak"		stdlib
+done
+	"a-zA-Z0-9_'"	capid
+
+:stdlib Stdlib
+	*		expr		noeat
+
+:type1	Type
+	*		expr		noeat
+	"a-z *>'\t\-"	type1
+	"("		type2
+
+:type2	Type
+	*		expr		noeat
+	"a-z *>'\t\-"	type2
+	"("		type3
+	")"		type1
+
+:type3	Type
+	*		expr		noeat
+	"a-z *>'\t\-"	type3
+	"("		type4
+	")"		type2
+
+:type4	Type
+	*		expr		noeat
+	"a-z *>'\t\-"	type4
+	"("		expr 				# too deep nesting
+	")"		type2
+
+:comment1 Comment
+	*		comment1
+	"("		nestcomment1
+	"*"		endcomment1
+
+:nestcomment1 Comment
+	*		comment1
+	"*"		comment2
+
+:endcomment1 Comment
+	*		comment1
+	")"		expr
+	"*"		endcomment1
+
+:comment2 Comment
+	*		comment2
+	"("		nestcomment2
+	"*"		endcomment2
+
+:nestcomment2 Comment
+	*		comment2
+	"*"		comment3
+
+:endcomment2 Comment
+	*		comment2
+	")"		comment1
+	"*"		endcomment2
+
+:comment3 Comment
+	*		comment3
+	"("		nestcomment3
+	"*"		endcomment3
+
+:nestcomment3 Comment
+	*		comment3
+	"*"		expr				# too deep nesting
+
+:endcomment3 Comment
+	*		comment3
+	")"		comment2
+	"*"		endcomment3