## 04_highlighting.dpatch by Michael Fedrowitz <michaelf@debian.org>
## DP: highlighting rules fixes and improvements
--- a/states/hl/changelog.st
+++ b/states/hl/changelog.st
@@ -43,7 +43,7 @@
   }
 
   /* File descriptions without function names. */
-  /(^\t\* )([^ :]+)(:)/ {
+  /(^\t\* )([^:]+)(:)/ {
     language_print ($1);
 
     function_name_face (true);
--- /dev/null
+++ b/states/hl/dylan.st
@@ -0,0 +1,124 @@
+/**
+ * Name: dylan
+ * Description: Dylan Programming Language template for Enscript.
+ * Author: Brent Fulgham <bfulgham@debian.org>
+ * (based on the Scheme version by Markku Rossi <mtr@iki.fi>)
+ */
+
+dylan_mod_re =
+/* Definition Modifiers
+  (build-re '(abstract block concrete constant class domain exception exclude
+  export function functional generic handler import inherited inline
+  instance interface library macro method open primary sealed sideways
+  singleton slot subclass variable virtual))
+  */
+  /\b(subclass|abstract|block|c(on(crete|stant)|lass)|domain\
+|ex(c(eption|lude)|port)|f(unction(|al))|generic|handler\
+|i(n(herited|line|stance|terface)|mport)|library|m(acro|ethod)\
+|open|primary|sealed|si(deways|ngleton)|slot\
+|v(ariable|irtual))\b/;
+
+state dylan extends HighlightEntry
+{
+  BEGIN {
+    /*
+     * Modify regexp character syntax so that we can distinguish all
+     * dylan symbols.
+     */
+    extras = list ('!', '$', '%', '&', '*', '/', ':', 
+		   '=', '?', '~', '^', '.', '+', '-');
+    for (i = 0; i < length (extras); i = i + 1)
+      regexp_syntax (extras[i], 'w');
+  }
+
+  /* Modifiers */
+  dylan_mod_re {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+
+  /* Types */
+  /<\w+>/ {
+    type_face (true);
+    language_print ($0);
+    type_face (false);
+  }
+
+  /* Symbols */
+  /#\"/ {
+    string_face (true);
+    language_print ($0);
+    call (c_string);
+    string_face (false);
+  }
+
+  /* Comments. */
+  /\/\// {
+    comment_face (true);
+    language_print ($0);
+    call (eat_one_line);
+    comment_face (false);
+  }
+  /\/\*/ {
+    comment_face (true);
+    language_print ($0);
+    call (eat_one_line);
+    comment_face (false);
+  }
+
+  /* String constants. */
+  /\"/ {
+    string_face (true);
+    language_print ($0);
+    call (c_string);
+    string_face (false);
+  }
+
+  /* Character constants. */
+  /'.*'/ {
+    string_face (true);
+    language_print ($0);
+    string_face (false);
+  }
+    
+  /* Keywords.
+     "=>" +
+     (build-re '(above afterwards begin below by case cleanup create
+     define end else elseif finally for from if in let local otherwise rename
+     select signal then to unless until use variable virtual when while
+   */
+  /=>|\b(a(bove|fterwards)|b(e(gin|low)|y)|c(ase|leanup|reate)\
+|define|else(|if)|end|f(inally|or|rom)|i[fn]|l(et|ocal)|otherwise\
+|rename|s(elect|ignal)|t(hen|o)|u(n(less|til)|se)|wh(en|ile))\b/ {
+    keyword_face (true);
+    language_print ($0);
+    keyword_face (false);
+  }
+
+  /* ':'-names, Emacs highlights these, so do we. */
+  /([ \t])([!\$%&\*\/:<=>\?~_^a-zA-Z0-9.+\-]*:)/ {
+    language_print ($1);
+    reference_face (true);
+    language_print ($2);
+    reference_face (false);
+  }
+
+  /* Function faces */
+  /([ \t]*)(\w+[^:])([ \t]*\([ \t]*)/ {
+    language_print ($1);
+    function_name_face(true);
+    face_on(face_bold_italic);
+    language_print ($2);
+    face_off(face_bold_italic);
+    function_name_face(false);
+    language_print ($3);
+  }
+}
+
+
+/*
+Local variables:
+mode: c
+End:
+*/
--- /dev/null
+++ b/states/hl/eiffel.st
@@ -0,0 +1,132 @@
+/**
+ * Name: eiffel
+ * Description: Eiffel programming language.
+ * Author: Julien Lemoine <speedblue@happycoders.org>
+ *         Brent Fulgham <bfulgham@debian.org>
+ */
+
+eiffel_types =
+/* Types */
+  /\b(ABSTRACT_(FRACTION|INTEGER)|ANY|AR(GUMENTS|RAY(|2|3|ED_COLLECTION))\
+|BASIC_(DIRECTORY|TIME)|BINARY_FILE_(READ|WRITE)|BIT_(N|STRING)|BOOLEAN\
+|CHARACTER(|_CONSTANTS)|CLOCK|COLLECTION(|2|3|_SORTER)|COMPARABLE\
+|COUNTER|DICTIONARY(|_NODE)|D(IRECTORY|OUBLE)|EXCEPTIONS|FILE(|_TOOLS)\
+|FIXED_ARRAY(|2|3)|GE(NERAL|N_RAND)|HASH(ABLE|_TABLE_SIZE)|INPUT_STREAM\
+|INTEGER(|_8|_16|_32|_64|_FRACTION|_GENERAL)\
+|ITERATOR(|_ON_(COLLECTION|DICTIONARY(_ITEMS|_KEYS)|LINKED_LIST|SET\
+|STRING|TWO_WAY_LINKED_LIST|UNICODE_STRING))\
+|LARGE(|_NEGATIVE|_POSITIVE)_INTEGER|LINK(|2|ED(_COLLECTION|_LIST))\
+|MATH_CONSTANTS|MEMO(|RY)|MICROSECOND_TIME|MINI_PARSER_BUFFER\
+|MIN_STAND|MUTABLE_BIG_INTEGER|NATIVE_ARRAY|NULL_(INPUT|OUTPUT)\
+|NUMBER(|_FRACTION|_TOOLS)|NUMERIC|OUTPUT_STREAM|PLATFORM|POINTER\
+|REAL|REVERSE_COLLECTION_SORTER|SAFE_EQUAL|SCOOP_UTILITIES|SET(|_NODE)\
+|SMALL_INTEGER|STD_(ERROR|FILE_(READ|READ_WRITE|WRITE)|INPUT(|_OUTPUT)\
+|OUTPUT|RAND)|STRING(|_HANDLER)|SYSTEM|TIME(|_IN_(ENGLISH|FRENCH|GERMAN\
+|ITALIAN|SOME_LANGUAGE|SPANISH))|TWO_WAY_LINKED_LIST\
+|UNICODE_STRING(|_HANDLER)|UTF8_PARSER)\b/;
+
+eiffel_keywords =
+/* Keywords */
+  /\b(agent|a(ll|lias)|and|as(|sign)|check|class|convert|create|Current|debug\
+|deferred|do|else(|if)|en(d|sure)|ex(panded|port|ternal)|False\
+|feature|fro(m|zen)|if|implies|in(dexing|fix|herit|spect|variant)\
+|is|like|local|loop|not|o(r|bsolete|ld|nce)|prefix|Precursor|pure\
+|re(define|ference|name|quire|scue|try)|Result|separate|then|True\
+|TUPLE|un(define|til)|creation)\b/;
+
+state eiffel extends HighlightEntry
+{
+
+  /* One line comments. */
+  /\-\-/ {
+    comment_face (true);
+    language_print ($0);
+    call (eat_one_line);
+    comment_face (false);
+  }
+
+  /* Keywords. */
+  eiffel_keywords {
+    keyword_face (true);
+    language_print ($0);
+    keyword_face (false);
+  }
+
+  /* Types. */
+  eiffel_types {
+    type_face (true);
+    language_print ($0);
+    type_face (false);
+  } 
+
+  /* String constants. */
+  /\"/ {
+    string_face (true);
+    language_print ($0);
+    call (c_string);
+    string_face (false);
+  }
+
+  /* Character constants. */
+  /'.'|'\\\\.'/ {
+    string_face (true);
+    language_print ($0);
+    string_face (false);
+  }
+
+  /* Symbols, etc. */
+  /:=|==|<=|>=|=|!=|\/=|!|!!/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+
+  /* Type declarations */
+  /([ \t])*([a-zA-Z]+[, \ta-zA-Z0-9_]*):[^=]/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+  
+
+  /*
+   * Function definitions, with args
+   * fct_name (args...) is
+   */
+  /^([ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*)(\([ \t]*[ \ta-z,A-Z_0-9]+)(:[ \ta-zA-Z0-9_\[\]]+)?(\)[ \t]*)(:[ \ta-zA-Z0-9_\[\]]+)?([ \t]+is)[ \t]*$/ {
+    function_name_face (true);
+    face_on(face_bold_italic);
+    language_print ($1);
+    face_off(face_bold_italic);
+    function_name_face (false);
+    language_print ($2);
+    type_face (true);
+    language_print ($3);
+    type_face (false);
+    language_print ($4);
+    type_face (true);
+    language_print ($5);
+    type_face (false);
+    keyword_face (true);
+    language_print ($6);
+    keyword_face (false);
+    language_print ($7);
+  }
+
+  /*
+   * Function definitions, without args
+   * fct_name is
+   */
+  /^([ \t]*[a-zA-Z_][a-zA-Z_0-9]*)([ \t]*)(is)[ \t]*$/ {
+    function_name_face (true);
+    face_on(face_bold_italic);
+    language_print ($1);
+    face_off(face_bold_italic);
+    function_name_face (false);
+    language_print(" ");
+    keyword_face (true);
+    language_print ($3);
+    keyword_face (false);
+  }
+
+}
--- a/states/hl/enscript.st
+++ b/states/hl/enscript.st
@@ -472,12 +472,17 @@
   /\.m$/					matlab;
   /\.(mpl|mp|maple)$/				maple;
   /\.(scm|scheme)$/				scheme;
+  /\.e$/					eiffel;
+  /\.erl$/					erlang;
   /\b\.emacs$|\.el$/				elisp;
   /\.ad(s|b|a)$/				ada;
   /\.[Ss]$/					asm;
+  /\.sml$/					sml;
   /\.st$/					states;
+  /\.lua$/					lua;
   /(M|m)akefile.*/				makefile;
   /\.(MOD|DEF|mi|md)$/				modula_2;
+  /\.oz$/					oz;
   /\.tcl$/					tcl;
   /\.(v|vh)$/					verilog;
   /\.html?$/					html;
--- /dev/null
+++ b/states/hl/erlang.st
@@ -0,0 +1,161 @@
+/**
+  * Name: erlang
+  * Description: Erlang programming language.
+  * Author: Sean Hinde 
+  */
+
+
+/* Erlang atom: ([a-z][a-zA-Z0-9_]*|\'[^\n]*\') */
+
+state erlang extends HighlightEntry
+{
+   /* Comments */
+   /%/ {
+     comment_face (true);
+     language_print ($0);
+     call (eat_one_line);
+     comment_face (false);
+   }
+
+   /* String constants. */
+   /\"/ {
+     string_face (true);
+     language_print ($0);
+     call (c_string);
+     string_face (false);
+   }
+
+   /* Special -record(rec_name, {}).  pre-processor case */
+   /(-record)(\([ \t]*)([a-z][a-zA-Z0-9_]*|\'[^\n]*\')/ {
+     reference_face (true);
+     language_print ($1);
+     reference_face (false);
+     language_print ($2);
+     type_face (true);
+     language_print ($3);
+     type_face (false);
+   }
+
+   /* Special -define(Alter, "Hello").  pre-processor case */
+   /(-define)(\([ 
+\t]*)([a-z][a-zA-Z0-9_]*|\'[^\n]*\'|[A-Z_][a-zA-Z0-9_]*)/ {
+     reference_face (true);
+     language_print ($1);
+     reference_face (false);
+     language_print ($2);
+     builtin_face (true);
+     language_print ($3);
+     builtin_face (false);
+   }
+
+   /* Pre-processor lines. */
+   /^-([a-z][a-zA-Z0-9_]*)/ {
+     reference_face (true);
+     language_print ($0);
+     reference_face (false);
+   }
+
+   /* Defines */
+   /(\?)([a-z][a-zA-Z0-9_]*|\'[^\n]*\'|[A-Z_][a-zA-Z0-9_]*)/ {
+     language_print ($1);
+     builtin_face (true);
+     language_print ($2);
+     builtin_face (false);
+   }
+
+   /* Records */
+   /(#)([a-z][a-zA-Z0-9_]*|\'[^\n]*\')/ {
+     language_print ($1);
+     type_face (true);
+     language_print ($2);
+     type_face (false);
+   }
+
+   /* Keywords.
+      '(after begin case try catch end fun if of receive when)
+      Regexp taken from emacs Erlang mode R9C
+   */
+   /\b(a(fter|ndalso)|begin|c(atch|ase)\
+|end|fun|if|o(f|relse)|receive|try|when\
+|query)\b/ {
+     keyword_face (true);
+     language_print ($0);
+     keyword_face (false);
+   }
+
+   /* Guards.
+    Regexp taken from emacs Erlang mode R9C
+   */
+   /\b((is_)*(atom|function|binary|constant|float\
+|integer|list|number|p(id|ort)\
+|re(ference|cord)|tuple))\b/ {
+     builtin_face (true);
+     language_print ($0);
+     builtin_face (false);
+   }
+
+   /* Built in functions */
+
+/\b(a(bs|live|pply|tom_to_list)\
+|binary_to_(list|term)\
+|concat_binary|d(ate|isconnect_node)\
+|e(lement|rase|xit)\
+|float(|_to_list)\
+|g(arbage_collect|et(|_keys)|roup_leader)\
+|h(alt|d)\
+|i(nte(ger_to_list|rnal_bif)|s_alive)\
+|l(ength|i(nk|st_to_(atom|binary|float|integer\
+|pid|tuple)))\
+|make_ref|no(de(|_(link|unlink)|s)|talive)\
+|open_port\
+|p(id_to_list|rocess(_(flag|info)|es)|ut)\
+|r(egister(|ed)|ound)\
+|s(e(lf|telement)|ize\
+|p(awn(|_link)|lit_binary)|tatistics)\
+|t(erm_to_binary|hrow|ime|l\
+|r(ace|unc)|uple_to_list)\
+|un(link|register)|whereis)\b/ {
+     keyword_face (true);
+     language_print ($0);
+     keyword_face (false);
+   }
+
+   /*
+    * Function definitions.
+    */
+   /^([a-z][a-zA-Z0-9_]*|'[^\n]*')/ {
+     function_name_face (true);
+     language_print ($1);
+     function_name_face (false);
+     language_print ($2);
+   }
+
+   /* Atom like strings */
+   /('[^\n]*')/ {
+     string_face (true);
+     language_print ($0);
+     string_face (false);
+   }
+
+   /* Characters */
+   /(\$.)/ {
+     string_face (true);
+     language_print ($0);
+     string_face (false);
+   }
+
+   /* Variable Names */
+   /*  /([\{\(\,\[ \t]+)([A-Z_][a-zA-Z0-9_]*)/ { */
+   /([^a-z0-9_\"])([A-Z_][a-zA-Z0-9_]*)/ {
+     language_print ($1);
+     variable_name_face (true);
+     language_print ($2);
+     variable_name_face (false);
+   }
+}
+
+/*
+Local variables:
+mode: erlang
+End:
+*/
--- /dev/null
+++ b/states/hl/forth.st
@@ -0,0 +1,96 @@
+/**
+ * Name: forth
+ * Description: Forth Programming Language.
+ * Author: Brent Fulgham <bfulgham@debian.org>
+ */
+
+forth_builtins =
+/* builtins */
+  /\b(abort|bye|c(atch|o(ld|ntext))|d(rop|up)|f(d(rop|up)|nip|o(r(get|th)|ver)|rot\
+|s(eal|wap)|tuck)|include|l(ink|oad)|n(ip|eeds)|o(rder|ver)|pick|ro(ll|t)|swap|t(hrow|uck)\
+|within|2(drop|nip|dup|over|tuck|swap|rot)|3dup|4dup\
+)\b/;
+
+forth_types =
+/* types */
+  /\b(base|c(ell|har)|decimal|float|hex)\b/;
+  
+forth_keywords =
+/* keywords */
+  /\b(a(bs|gain|head|lso|nd)|begin|c(ase|onstant)|d(abs|efinitions|m(ax|in)|negate|o(|ne))\
+|e(lse|nd(|case|if|of)|xit)|f(a(bs|cos(|h)|log|sin(|h)|tan(|2|h))|cos(|h)|exp(|m1)|l(n(|p1)\
+|o(g|or)|s(in(|cos|h)|qrt)|tan(|h))|m(ax|in)|negate|or|round|sqrt)|h(ere|old)|i(f|nvert)\
+|l(eave|oop)|m(ax|in|od)|n(e(gate|xt)|ot)|o(f|nly|r)|r(epeat|oot)|s(eal|ign)|then\
+|un(til|loop)|v(ariable|oc(abulary|s))|while|xor\
+)\b/;
+
+state forth extends HighlightEntry
+{
+  /* Comments. */
+  /\\\\/ {
+    comment_face (true);
+    language_print ($0);
+    call (eat_one_line);
+    comment_face (false);
+  }
+
+  /* keywords. */
+  forth_keywords {
+    keyword_face (true);
+    language_print ($0);
+    keyword_face (false);
+  }
+
+  /* Types. */
+  forth_types {
+    type_face (true);
+    language_print ($0);
+    type_face (false);
+  }
+
+  /* Builtins support */
+  forth_builtins {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  } 
+
+  /* String constants. */
+  /\"/ {
+    string_face (true);
+    language_print ($0);
+    call (c_string);
+    string_face (false);
+  }
+
+  /* character constants. */
+  /'.'|'\\\\.'/ {
+    string_face (true);
+    language_print ($0);
+    string_face (false);
+  }
+
+  /* symbols, etc. */
+  />|>=|<=|<>|!|\+|\-|\^|\/|\*|\|/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+
+  /*
+   * function definitions, with args
+   * fct_name (args...) is
+   */
+  /^(:[ \t]+)([^ ^\t]+)([ \t]*)/ {
+    keyword_face (true);
+    language_print ($1);
+    keyword_face (false);
+    function_name_face (true);
+    face_on(face_bold_italic);
+    language_print ($2);
+    face_off(face_bold_italic);
+    function_name_face (false);
+    language_print ($3);
+  }
+}
+
--- /dev/null
+++ b/states/hl/icon.st
@@ -0,0 +1,93 @@
+/**
+ * Name: icon
+ * Description: Icon Programming Language.
+ * Author: Brent Fulgham <bfulgham@debian.org>
+ */
+
+icon_builtins =
+/* Builtins */
+  /\b(break|create|default|fail|initial|l(ink|ocal)|not|s(tatic|uspend))\b/;
+
+icon_types =
+/* Types */
+  /\b(char|error|function|integer|proc|procedure|real|variable)\b/;
+  
+icon_keywords =
+/* Keywords */
+  /\b(a(bs|cos|ny|rgs|sin|tan)|b(al|y)|c(a(llout|se)|enter|hdir|lose|o(llect|py|s)|set)\
+|d(e(lay|lete|tab|isplay|tor)|o)|e(lse|n(d|tab)|rrorclear|very|xit|xp)|f(ind|lush)\
+|get(|ch|che|env)|i(and|com|f|mage|nsert|or|shift|xor)|k(bhit|ey)|l(eft|ist|o(adfunc|g))\
+|m(a(ny|p|tch)|ember|ove)|n(ame|ext|umeric)|o(f|pen|rd)|p(op|os|ull|ush|ut)\
+|r(e(ad(|s)|move|name|p(eat|l)|turn|verse)|ight|tod|unerr)|s(ave|eek|eq|et|in|ort(|f)\
+|qrt|top|tring|ystem)|t(a(b(|le)|n)|hen|o|rim|ype)|u(ntil|pto)|w(h(ere|ile)|rite(|s))\
+)\b/;
+
+state icon extends HighlightEntry
+{
+  /* Comments. */
+  /#/ {
+    comment_face (true);
+    language_print ($0);
+    call (eat_one_line);
+    comment_face (false);
+  }
+
+  /* Keywords. */
+  icon_keywords {
+    keyword_face (true);
+    language_print ($0);
+    keyword_face (false);
+  }
+
+  /* Types. */
+  icon_types {
+    type_face (true);
+    language_print ($0);
+    type_face (false);
+  }
+
+  /* Structure support */
+  icon_builtins {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  } 
+
+  /* String constants. */
+  /\"/ {
+    string_face (true);
+    language_print ($0);
+    call (c_string);
+    string_face (false);
+  }
+
+  /* Character constants. */
+  /'.'|'\\\\.'/ {
+    string_face (true);
+    language_print ($0);
+    string_face (false);
+  }
+
+  /* Symbols, etc. */
+  />|>=|:=|<=|#|=+|!|::|\+|\-|\^|\/|\*|\|/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+
+  /*
+   * Function definitions, with args
+   * fct_name (args...) is
+   */
+  /([ \t]*procedure[ \t]+)(\w+)([ \t]*)/ {
+    keyword_face (true);
+    language_print ($1);
+    keyword_face (false);
+    function_name_face (true);
+    face_on(face_bold_italic);
+    language_print ($2);
+    face_off(face_bold_italic);
+    function_name_face (false);
+    language_print ($3);
+  }
+}
--- /dev/null
+++ b/states/hl/lua.st
@@ -0,0 +1,91 @@
+/**
+ * Name: lua
+ * Description: Lua Programming Language template for Enscript.
+ * Author: Brent Fulgham <bfulgham@debian.org>
+ */
+
+lua_builtins =
+/* Builtins */
+  /\b(assert|call|foreach|globals|print|require|to(number|string))\b/;
+
+lua_keywords =
+/* Keywords */
+  /\b(and|break|do|e(nd|lse(|if))|f(alse|or|unction)|i(f|n)|local\
+|or|n(il|ot)|re(peat|turn)|t(hen|rue)|until|while\
+)\b/;
+  
+state lua extends HighlightEntry
+{
+
+  /* One line comments. */
+  /\-\-|^#!/ {
+    comment_face (true);
+    language_print ($0);
+    call (eat_one_line);
+    comment_face (false);
+  }
+
+  /* Keywords. */
+  lua_keywords {
+    keyword_face (true);
+    language_print ($0);
+    keyword_face (false);
+  }
+
+  /* Types. */
+  lua_builtins {
+    type_face (true);
+    language_print ($0);
+    type_face (false);
+  } 
+
+  /* String constants. */
+  /\"/ {
+    string_face (true);
+    language_print ($0);
+    call (c_string);
+    string_face (false);
+  }
+
+  /* Character constants. */
+  /'.'|'\\\\.'/ {
+    string_face (true);
+    language_print ($0);
+    string_face (false);
+  }
+
+  /* Symbols, etc. */
+  /+|-|\*|=|!=|==|<|>|<=|>=|~=|!/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+
+  /* Class references */
+  /([ \t])*([a-zA-Z]+[, \ta-zA-Z0-9_]*):[^=]/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+  
+  /*
+   * Function definitions, with args
+   * function fct_name (args...)
+   */
+  /^([ \t]*function[ \t]+)([a-zA-Z_][a-zA-Z_:0-9]*)([ \t]*)(\([^)]*\)[ \t]*)[ \t]*$/ {
+    keyword_face (true);
+    language_print ($1);
+    keyword_face (false);
+    function_name_face (true);
+    face_on(face_bold_italic);
+    language_print ($2);
+    face_off(face_bold_italic);
+    function_name_face (false);
+    language_print(" ");
+    language_print ($3);
+    keyword_face (true);
+    language_print ($4);
+    keyword_face (false);
+  }
+
+}
--- /dev/null
+++ b/states/hl/oberon2.st
@@ -0,0 +1,111 @@
+/**
+ * Name: oberon2
+ * Description: Oberon 2 Programming Language.
+ * Author: Brent Fulgham <bfulgham@debian.org>
+ */
+
+oberon2_builtins =
+/* Builtins */
+  /\b(CONST|IMPORT)\b/;
+
+oberon2_types =
+/* Types */
+  /\b(ARRAY|B(OOLEAN|YTE)|CHAR|INTEGER|LONG(|INT|REAL)|MODULE|NIL\
+|P(OINTER|ROCEDURE)|RE(AL|CORD)|SHORT(|INT))\b/;
+  
+oberon2_keywords =
+/* Keywords */
+  /\b(A(BS|ND|SH)|BEGIN|C(A(P|SE)|HR)|D(O|EC|IV)\
+|E(LS(E|IF)|N(D|TIER)|X(CL|IT))|F(ALSE|OR)|HALT|I(F|S|N(|C(|L)))\
+|L(EN|OOP)|M(AX|IN|OD)|NEW|O(F|DD|R(|D))|S(ET|IZE)|T(HEN|O|RUE|YPE)\
+|UNTIL|RE(PEAT|TURN)|VAR|W(HILE|ITH))\b/;
+
+state oberon2_comment extends Highlight
+{
+  /\*\)/ {
+    language_print ($0);
+    return;
+  }
+}
+
+state oberon2 extends HighlightEntry
+{
+  /* Comments. */
+  /\(\*/ {
+    comment_face (true);
+    language_print ($0);
+    call (oberon2_comment);
+    comment_face (false);
+  }
+
+  /* Keywords. */
+  oberon2_keywords {
+    keyword_face (true);
+    language_print ($0);
+    keyword_face (false);
+  }
+
+  /* Types. */
+  oberon2_types {
+    type_face (true);
+    language_print ($0);
+    type_face (false);
+  }
+
+  /* Structure support */
+  oberon2_builtins {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  } 
+
+  /* String constants. */
+  /\"/ {
+    string_face (true);
+    language_print ($0);
+    call (c_string);
+    string_face (false);
+  }
+
+  /* Character constants. */
+  /'.'|'\\\\.'/ {
+    string_face (true);
+    language_print ($0);
+    string_face (false);
+  }
+
+  /* Symbols, etc. */
+  /\->|>|>=|:=|<=|#|=|!|::|\+|\-|\^|\/|\*|\|/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+
+  /*
+   * Function definitions, with args
+   * fct_name (args...) is
+   */
+  /([ \t]*PROCEDURE[ \t]+)(\w+)([ \t]*)/ {
+    keyword_face (true);
+    language_print ($1);
+    keyword_face (false);
+    function_name_face (true);
+    face_on(face_bold_italic);
+    language_print ($2);
+    face_off(face_bold_italic);
+    function_name_face (false);
+    language_print ($3);
+  }
+
+  /([ \t]*END[ \t]+)(\w+)([ \t]*[;\.])/ {
+    keyword_face (true);
+    language_print ($1);
+    keyword_face (false);
+    function_name_face (true);
+    face_on(face_bold_italic);
+    language_print ($2);
+    face_off(face_bold_italic);
+    function_name_face (false);
+    language_print ($3);
+  }
+}
--- /dev/null
+++ b/states/hl/oz.st
@@ -0,0 +1,89 @@
+/**
+ * Name: oz
+ * Description: Mozart/Oz Programming Language.
+ * Author: Brent Fulgham <bfulgham@debian.org>
+ */
+
+oz_builtins =
+/* Builtins */
+  /\b(export|import|local|require)\b/;
+
+oz_types =
+/* Types */
+  /\b(attr|c(lass|atch)|f(eat|unctor)|nil|prop|raise|try)\b/;
+  
+oz_keywords =
+/* Keywords */
+  /\b(at|c(ase|hoice|ond)|d(e(clare|fine)|o|is)|e(lse(|case|if|of)|nd)\
+|f(inally|or|rom|un)|i(f|n)|lock|meth|not|o(f|r)|p(repare|roc)|then\
+|thread)\b/;
+  
+state oz extends HighlightEntry
+{
+
+  /* Comments. */
+  /%/ {
+    comment_face (true);
+    language_print ($0);
+    call (eat_one_line);
+    comment_face (false);
+  }
+
+  /* Keywords. */
+  oz_keywords {
+    keyword_face (true);
+    language_print ($0);
+    keyword_face (false);
+  }
+
+  /* Types. */
+  oz_types {
+    type_face (true);
+    language_print ($0);
+    type_face (false);
+  }
+
+  /* Structure support */
+  oz_builtins {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  } 
+
+  /* String constants. */
+  /\"/ {
+    string_face (true);
+    language_print ($0);
+    call (c_string);
+    string_face (false);
+  }
+
+  /* Character constants. */
+  /'.'|'\\\\.'/ {
+    string_face (true);
+    language_print ($0);
+    string_face (false);
+  }
+
+  /* Symbols, etc. */
+  /\.\.|=[=]|<\-|\\=|\|/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+
+  /*
+   * Function definitions, with args
+   * fct_name (args...) is
+   */
+  /([ \t]*\{)(\w+)([\. \t]*)/ {
+    language_print ($1);
+    function_name_face (true);
+    face_on(face_bold_italic);
+    language_print ($2);
+    face_off(face_bold_italic);
+    function_name_face (false);
+    language_print ($3);
+  }
+
+}
--- a/states/hl/perl.st
+++ b/states/hl/perl.st
@@ -60,6 +60,11 @@
 
 state perl extends HighlightEntry
 {
+  /* stuff after $# is a variable, not a comment */
+  /\$#\w+/ {
+    language_print ($0);
+  }
+
   /* Comments. */
   /#.*$/ {
     comment_face (true);
@@ -127,7 +132,6 @@
 
   /* Variables */
   /[$%@&]+\w+/ {
-    keyword_face (false);
     language_print ($0);
   }
 
--- /dev/null
+++ b/states/hl/smalltalk.st
@@ -0,0 +1,80 @@
+/**
+ * Name: Smalltalk
+ * Description: Smalltalk Programming Language.
+ * Author: Brent Fulgham <bfulgham@debian.org>
+ */
+
+smalltalk_keywords =
+/* Keywords */
+  /\b(class|false|inspect|isNil|new|nil|not(|Nil)|out|s(elf|uper)|true\
+|do|whileTrue|whileFalse|ifTrue|ifFalse|put|to|at|add|new\
+|for)\b/ ;
+
+state smalltalk_quot_string extends Highlight
+{
+  /\\\\./ {
+    language_print ($0);
+  }
+  /[\']/ {
+    language_print ($0);
+    return;
+  }
+}
+
+state smalltalk extends HighlightEntry
+{
+
+  /* Comments. */
+  /\"/ {
+    comment_face (true);
+    language_print ($0);
+    call (c_string);
+    comment_face (false);
+  }
+
+  /* Keywords. */
+  smalltalk_keywords {
+    keyword_face (true);
+    language_print ($0);
+    keyword_face (false);
+  }
+
+  /* Declarations */
+  /[ \t]*\|.*\|/ {
+    type_face (true);
+    language_print ($0);
+    type_face (false);
+  }
+
+  /* String constants. */
+  /[\']/ {
+    string_face (true);
+    language_print ($0);
+    call (smalltalk_quot_string);
+    string_face (false);
+  } 
+
+  /* Symbols, etc. */
+  /:=|>|>=|==|<=|<>|=|!|::|@|\+|\-|\^|\/|\*|\||\[|\]/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+
+  /*
+   * Function definitions, with args
+   * fct_name (args...) is
+   */
+  /([ \t]*)(\w+)(:[ \t]*)/ {
+    keyword_face (true);
+    language_print ($1);
+    keyword_face (false);
+    function_name_face (true);
+    face_on(face_bold);
+    language_print ($2);
+    face_off(face_bold);
+    function_name_face (false);
+    language_print ($3);
+  }
+
+}
--- /dev/null
+++ b/states/hl/sml.st
@@ -0,0 +1,101 @@
+/**
+ * Name: sml
+ * Description: Standard ML Programming Language.
+ * Author: Brent Fulgham <bfulgham@debian.org>
+ */
+
+sml_builtins =
+/* Builtins */
+  /\b(functor|lambda|s(ig(|nature)|truct(|ure))|NONE|SOME)\b/;
+
+sml_types =
+/* Types */
+  /\b(\'(a|b|c|d)|array|bool|char|int|list|real|string|unit|vector|word)\b/;
+  
+sml_keywords =
+/* Keywords */
+  /\b(a(bs(traction|type)|nd(|also)|s|toi)|before|c(ase|oncat)|d(o|atatype)\
+|e(lse|nd|qtype|xception)|f(n|un(|sig))|handle|i(f|n(|clude|fix|fixr))\
+|l(et|ocal)|nonfix|o(|f|p(|en)|relse|verload)|print|r(aise|ec|ef)|sharing\
+|t(hen|ype)|val|w(h(ere|ile)|ith(|type)))\b/ ;
+
+state sml_comment extends Highlight
+{
+  /\*\)/ {
+    language_print ($0);
+    return;
+  }
+}
+
+state sml extends HighlightEntry
+{
+
+  /* Comments. */
+  /\(\*/ {
+    comment_face (true);
+    language_print ($0);
+    call (sml_comment);
+    comment_face (false);
+  }
+
+  /* Keywords. */
+  sml_keywords {
+    keyword_face (true);
+    language_print ($0);
+    keyword_face (false);
+  }
+
+  /* Types. */
+  sml_types {
+    type_face (true);
+    language_print ($0);
+    type_face (false);
+  }
+
+  /* Structure support */
+  sml_builtins {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  } 
+
+  /* String constants. */
+  /\"/ {
+    string_face (true);
+    language_print ($0);
+    call (c_string);
+    string_face (false);
+  }
+
+  /* Character constants. */
+  /'.'|'\\\\.'/ {
+    string_face (true);
+    language_print ($0);
+    string_face (false);
+  }
+
+  /* Symbols, etc. */
+  /:=|>|>=|==|<=|<>|=|!|::|@|\+|\-|\^|\/|\*|\||\b(quot|rem|div|mod\
+|hd|tl)\b/ {
+    reference_face (true);
+    language_print ($0);
+    reference_face (false);
+  }
+
+  /*
+   * Function definitions, with args
+   * fct_name (args...) is
+   */
+  /([ \t]*f[u]n[ \t]+)(\w+)([ \t]*)/ {
+    keyword_face (true);
+    language_print ($1);
+    keyword_face (false);
+    function_name_face (true);
+    face_on(face_bold_italic);
+    language_print ($2);
+    face_off(face_bold_italic);
+    function_name_face (false);
+    language_print ($3);
+  }
+
+}
--- a/states/hl/tcl.st
+++ b/states/hl/tcl.st
@@ -128,7 +128,7 @@
 |e(ntry|of|rror|v(al|ent)|x(ec|it|pr))\
 |f(blocked|configure|ile(|event|name)|lush|o(cus|nt|r(|each|mat))|rame)\
 |g(ets|lob(|al)|r(ab|id))|history|i(f|mage|n(cr|fo|terp))|join\
-|l(a(bel|ppend)|i(brary|n(dex|sert)|st(|box))|length|o(ad|se|wer)\
+|l(a(bel|ppend|st)|i(brary|n(dex|sert)|st(|box))|length|o(ad|se|wer)\
 |r(ange|eplace)|s(earch|ort))\
 |me(nu(|button)|ssage)|op(en|tion(|s))\
 |p(ack(|age)|hoto|id|kg_mkIndex|lace|roc|uts|wd)\
--- a/states/hl/Makefile.am
+++ b/states/hl/Makefile.am
@@ -36,7 +36,8 @@
 matlab.st nroff.st objc.st outline.st pascal.st passthrough.st perl.st	\
 postscript.st python.st pyrex.st rfc.st scheme.st sh.st skill.st	\
 sql.st states.st synopsys.st tcl.st tcsh.st tex.st vba.st verilog.st	\
-vhdl.st vrml.st wmlscript.st zsh.st
+vhdl.st vrml.st wmlscript.st zsh.st eiffel.st erlang.st dylan.st oz.st	\
+lua.st oberon2.st icon.st smalltalk.st forth.st sml.st
 
 hldir = $(pkgdatadir)/hl
 dist_hl_DATA = $(misc) $(styles) $(languages) $(highlightings)
