#!/usr/bin/perl -w
######################################################################
#                                                                    #
# Code2HTML                                                          #
# ---------                                                          #
#                                                                    #
# Code2Html, version 0.8.7d, Nov 1999, ppalfrad@cosy.sbg.ac.at       #
#                                                                    #
# AUTHOR                                                             #
#        Peter  Palfrader,  computer   science   student   at   the  #
#        University  of Salzburg/Austria. Written in 1999.           #
#        A lot of other people. See contributers below               #
#                                                                    #
# DESCRIPTION                                                        #
#        code2html is a  perlscript  which  converts  a  program     #
#        source  code  to syntax highlighted HTML by applying a set  #
#        of   regular   expressions   depending   on  the  language  #
#        the source code is written.                                 #
#                                                                    #
# LICENSE                                                            #
#        Copyright (c) 1999 by Peter Palfrader & others.             #
#        Not derived from licensed software.                         #
#                                                                    #
#        Permission is granted to anyone to use this  software  for  #
#        any purpose on any computer system, and to redistribute it  #
#        in any way, subject to the following restrictions:          #
#                                                                    #
#        1. The author is not responsible for the  consequences  of  #
#           use of this software, no matter how awful, even if they  #
#           arise from defects in it.                                #
#        2. The origin of this software must not be misrepresented,  #
#           either by explicit claim or by omission.                 #
#        3. Altered  versions  must  be plainly marked as such, and  #
#           must  not  be  misrepresented  (by  explicit  claim  or  #
#           omission) as being the original software.                #
#        3a. It would be nice if I got  a  copy  of  your  improved  #
#            version  sent to ppalfrad@cosy.sbg.ac.at. However this  #
#            is not obligatory.                                      #
#        4. This notice must not be removed or altered.              #
#                                                                    #
#        Thanks to Henry Spencer for this wonderful license :).      #
#                                                                    #
#        Some of the regular expressions found in the default        #
#        database have been taken from NEdit and are public domain   #
#        according to Mark Edel <edel@ltx.com> who does the support  #
#        of NEdit.                                                   #
#                                                                    #
######################################################################
#                                                                    #
# HISTORY                                                            #
#                                                                    #
# 0.8.7d - OCTOBER 1997                                              #
#  * langmode is not case insensitive                                #
#                                                                    #
# 0.8.7c - OCTOBER 1997                                              #
#  * line numbers AGAIN :/ (this time everything schould work :)     #
#                                                                    #
# 0.8.7b - OCTOBER 1997                                              #
#  * line numbers AGAIN :/                                           #
#                                                                    #
# 0.8.7a - OCTOBER 1997                                              #
#  * declared result in putout, so code2html runs with use strict    #
#  * patching works with stdin to stdout too.                        #
#                                                                    #
# 0.8.7 - OCTOBER 1997                                               #
#  * the newslines where missing with lin[ke]numbers. Fixed (PP)     #
#  * fixed patchmode. TNX to "Brad M. Garcia" <bgarcia@fore.com>     #
#    for the bug report (PP)                                         #
#                                                                    #
# 0.8.6 - OCTOBER 1999                                               #
#  * changed some perl patterns, faster & smaller html (PP)          #
#  * replaced (abc|Abc|ABC) style patterns with (?i)abc (PP)         #
#  * changed config file layout; using a data structure now (PP)     #
#  * speed                                                           #
#    o create_snippets tweaking (BS)                                 #
#    o Pod::Text not used but required (BS)                          #
#    o _new_ _improved_ (great words, eh?) perl patterns (BS)        #
#  * checkTab in again (PP)                                          #
#                                                                    #
# 0.8.5 - AUGUST 1999                                                #
#  * fixed linenumbers.                                              #
#  * html patching now also has an outputfile.                       #
#     (Daniel Winkelmann <winkelma@chemie.fu-berlin.de>)             #
#  * html patching failed when refering to external files. this is   #
#    fixed now. TNX to Daniel Winkelmann for the bug report          #
#  * code2html in CGI mode now encodes the output as bz2/gz/Z if     #
#    the program is on the server and the format is accepted by      #
#    the client (HTTP_ACCEPT_ENCODING).                              #
#    TNX to Matty <mattpratt@yahoo.com> for the idea.                #
#                                                                    #
# 0.8.4 - AUGUST 1999                                                #
#  * Barrie Slaymaker <barries@slaysys.com> sent a different         #
#    approach for finding & inserting tags. the hidechar way is no   #
#    longer needed. It is quite fast and needs not that much         #
#    memory.                                                         #
#                                                                    #
# 0.8.3 - AUGUST 1999                                                #
#  * removed 'use HTML::Entities' line. it HTML::Entities was not    #
#    used anyway.                                                    #
#                                                                    #
# 0.8.2 - AUGUST 1999                                                #
#  * John Douglas Rowell <me@jdrowell.com> submitted some perl       #
#    tweaks to correctly parse <<"-x-"; and =begin/=end blocks.      #
#  * anchors are not used any more when no line numbers are wanted.  #
#  * John Interrante <interran@crd.ge.com> patched a typo that       #
#    made the html footer even printed if noheader was spezified.    #
#  * new option -T=s, --title=s; suggested by Harald Fielker         #
#    <fielker@informatik.fh-augsburg.de> as well as Barrie Slaymaker #
#    <barries@slaysys.com>.                                          #
#  * significantly reduced memory usage                              #
#  * Barrie Slaymaker <barries@slaysys.com> sent a patch to speed up #
#    insert_tags. I already had a not that bad version some time ago #
#    but somehow it got lost. Anyway Barrie's way is _a_lot_ faster  #
#    than mine.                                                      #
#                                                                    #
# 0.8.1 - AUGUST 1999                                                #
#  * Joor Loohuis <joor@casema.net> updated the documentation.       #
#                                                                    #
# 0.8.0 - AUGUST 1999                                                #
#  * Joor Loohuis <joor@casema.net> converted the long help text to  #
#    pod (plain old documentation, see perlpod(1)). The major        #
#    advantage is that the documentation can now simply be           #
#    converted to html, man, LaTeX or plain text, by using one of    #
#    the filters from the standard Perl POD module.                  #
#  * Joor Loohuis also contributed an example of automatic           #
#    language recognition. I adapted it and it is now part of        #
#    code2html. As a result the syntax has changed. langmode is no   #
#    longer obligatory but optional with -l <langmode>               #
#  * Joel Andersson <joel@post.netlink.se> sent me the patterns for  #
#    awl, m4, groff.                                                 #
#  * perl tweaks; again :/                                           #
#  * regular expressions in config files are now checked for         #
#    correctness. code2html fails gracefully if a regex is wrong.    #
#                                                                    #
# 0.7.1 - August 1999                                                #
#  * corrected (hopefully) a gotcha in the perl patterns (again...)  #
#  * added one item to the changelog of 0.7.0                        #
#  * --replace_tabs no longer replaces every tab with the given      #
#   amount of spaces but instead it now replaces it with the right   #
#   number to go to the next tabstop. the parameter given to         #
#   replace_tabs gives the width of tabstops.                        #
#   TNX to T. Jahn <tjahn@crosswinds.net> for providing an example   #
#   of how to do this in one of his programs. If I had known it      #
#   was that easy I'ld have done it earlier :)                       #
#                                                                    #
# 0.7.0 - August 1999                                                #
# * No longer need for that stupid fatal_error sub. I now use perl's #
#   handlers for __DIE__ and __WARN__                                #
# * complete rewrite of the option and parameter fetching sub. I     #
#   now use Getopt::Long. TNX to Barrie for the pointer. As a        #
#   the number for --replace_tabs / -t is no longer optional.        #
# * Added HTML patching: code2html now also allows you to have       #
#   inline source code in an html file. It can then take this html   #
#   file and insert the syntax highlighted code.                     #
#   Look in the help. It's very usefull ( at least for me )          #
# * the CGI mode got a forth way to pass the input file. If the      #
#   input_selector parameter is set to REDIRECT_URL the file is      #
#   taken from ENV{'DOCUMENT_ROOT'}.$ENV{'REDIRECT_URL'}.            #
#   Kevin Burton <burton@relativity.yi.org> suggested this so that   #
#   it is possible to configure Apache with an action directive      #
#   to automatically print java files syntax highlighted.            #
#                                                                    #
# 0.6.6 - July 1999                                                  #
# * added sql - it is still very poor since I don't know all the     #
#   keywords etc. If you know, tell me.                              #
# * Martynov Andrew <root@tn.energo.ru> pointed me to the qq, qx,    #
#   etc operators in perl. They should now no longer cause problems  #
# * Wayne Roberts <wroberts1@cx983858-b.orng1.occa.home.com>         #
#   reported a problem with C strings like "\\". It should be fixed  #
#   too.                                                             #
# * I changed the operator with which the default language base      #
#   is assigned to a variable, so there's no need for \\\\\\\\\\     #
#   quotes anymore :)                                                #
#                                                                    #
# 0.6.5 - June 1999                                                  #
# * tweaking Perl regular expressions (TNX to Barrie Slaymaker       #
#   <rbs@telerama.com>)                                              #
# * if a language mode cannot be found the error message now tells   #
#   you which lang you requested.                                    #
# * new --fallback <lang> option. This language mode is used if the  #
#   given mode by parameter #1 is not available. This feature was    #
#   requested by Barrie Slaymaker <rbs@telerama.com>                 #
# * changed 'is called as CGI' heuristics.                           #
#                                                                    #
# 0.6.4 - May 1999                                                   #
# * the name attribute in the line numbers was wrong. there should   #
#   be no # in it. TNX to <stifle33@hotmail.com>                     #
# * linking to line numbers now works from the command line too      #
#                                                                    #
# 0.6.3 - May 1999                                                   #
# * fixed C character constant regex. TNX to Jesse                   #
#   <jesse@lmscadsi.com>                                             #
# * line numbers now can link to themselves                          #
# * line numbers now have a constant width                           #
#                                                                    #
# 0.6.2 - May 1999                                                   #
# * fixed something in HTML lang                                     #
#                                                                    #
# 0.6.1 - May 1999                                                   #
# * added 'plain' language mode                                      #
# * cgi support improoved. should now also handle                    #
#   enctype="multipart/form-data" forms                              #
#                                                                    #
# 0.6.0 - May 1999                                                   #
# * fixed Substitution loop at ./code2html.pl (5.2) line 627         #
# * changed string regular expressions: \" is no longer a problem    #
# * default locations for the language files have changed:           #
#   first all the files listed in the enviroment variable            #
#   CODE2HTML_CONFIG (seperated by colons (:)) will be checked,      #
#   then, if HOME set, $HOME/.code2html.config and finally           #
#   /etc/code2html.config                                            #
#   TNX to Eric Brandwine <ebrandwi@UU.NET> for the hint.            #
# * new: --no_header does not print the <html><head>... stuff        #
# * new: --content_type prints Content-Type: text/html;              #
# * C/C++: in preprocessor lines: strings are highlighted now        #
# * -n now also names the lines with <a name="line<nr>">..</a>       #
# * script may now be run as a CGI script. see the CGI section       #
#   in the help                                                      #
# * get_config_file was rewritten because it was _ugly_              #
#                                                                    #
# 0.5.2 - May 1999                                                   #
# * fixed Makefile dependency line bug. (a * in regexp instead a +)  #
#                                                                    #
# 0.5.1 - May 1999                                                   #
# * clarified copyright questions on regular expressions             #
# * changed -dumb_default_lang to -dump_default_lang :)              #
#                                                                    #
# 0.5.0 - Apr 1999                                                   #
# * changed find_all_matches__create_taglist__insert_placeholders    #
#   so that it works around a bug in earlier perl versions, in which #
#   pos() is not set if the return value of m//g is not used.        #
# * changed a regex in get_config_file                               #
#                                                                    #
# 0.4.1 - Mar 1999                                                   #
# * changed JavaScript regexps slightly                              #
# * changed find_all_matches_.. slightly                             #
#                                                                    #
# 0.4.0 - Mar 1999                                                   #
# * script no longer needs $' and $` thus beeing faster. $& is still #
#   needed                                                           #
# * regexps for perl changed slightly                                #
# * find_all_matches has been completly rewritten. verify is no      #
#   longer needed. taglist is built while searching.                 #
#   May take a bit longer now, but otherwhise a bug could not have   #
#   been fixed.                                                      #
# * changed (fixed?) start of language_def_block pos evaluation      #
#                                                                    #
# 0.3.3 - Feb 1999                                                   #
# * fixed STDIN/STDOUT parameters when passed a - the scrpit though  #
#   options would follow and didn't tread this as a handle for STDIN #
# * added -V as shortcut to --version                                #
#                                                                    #
# 0.3.2 - Feb 1999                                                   #
# * removed -T from 1st line so activePerl will run the script       #
#   without any modifications                                        #
# * changed perl string regexps. run now faster and better           #
#   (and run at all under win)                                       #
# * added --replace_tabs                                             #
#                                                                    #
# 0.3.1 - Feb 1999                                                   #
# * fixed language files bug (<space>lang_mode<space> no longer      #
#         starts langmode)                                           #
# * fixed empty html tag bug when reading lang specs                 #
# * added languages: Makefile, Java, JavaScript, Perl                #
# * added --modes                                                    #
#                                                                    #
# 0.3.0 - Feb 1999                                                   #
# * added linenumbers                                                #
# * added <head> and <title> tag in html output                      #
# * fixed crlf switch works now                                      #
#                                                                    #
# 0.2.0 - Feb 1999                                                   #
# * first official release                                           #
#                                                                    #
######################################################################
#                                                                    #
# CONTRIBUTORS                                                       #
#                                                                    #
# Joel Andersson <joel@post.netlink.se> JA: awk, groff, m4 patterns  #
#                                                                    #
# John Douglas Rowell <me@jdrowell.com> : perl tweaks                #
#                                                                    #
# John Interrante <interran@crd.ge.com> patched a typo               #
#                                                                    #
# Joor Loohuis <joor@casema.net> JL: POD help                        #
#     also showed a way for lang autodetect                          #
#                                                                    #
# Barrie Slaymaker <rbs@telerama.com> BS: many hints & suggestions   #
#     patches to improve speed                                       #
#                                                                    #
# if you feel your name should be here too, mail me!                 #
# errare humanum est!                                                #
#                                                                    #
######################################################################

use strict;
use Getopt::Long;

my $FILES_DISALLOWED_IN_CGI = 0;
# you may set this to true to disallow file reading from your hd in 
# cgi mode. This may be good if your httpd runs as 'root' (yes, I've
# seen this!) and so any user could with some knowledge easily read
# your /etc/shadow for example!
my $FILES_REDIRECT_DISALLOWED = 0;
my $LANG_TEST_LENGTH = 1024;


# PP: I think Compress::Zlib could be nice for this. but it's not very widespread :(
# PP: A hash would be nicer but then it would not possible to get the keys in this very order (AFAIK)
# PP: If names contain meta characters, then those must be metaquoted (if you don't want the meta chars to be meta chars of course)
my @CGI_ENCODING = (
		    ['bzip2'     , '/usr/bin/bzip2'    , '--stdout' ],
		    ['gzip'      , '/bin/gzip'         , '--stdout' ],
		    ['compress'  , '/usr/bin/compress' , '-c' ]
		   );





my $vernr = "0.8.7d ";
my $monthshort = "Nov";
my $monthlong = "November";

my $pure_version_message = "Code2Html, version $vernr, $monthshort 1999, ppalfrad\@cosy.sbg.ac.at";
my $version_message = "$pure_version_message\n\n";

# JL:
# embedded pod documentation, don't start pod with =head1, since some
# parsers will miss NAME then
=pod

=head1 NAME

code2html - Converts a program source code to HTML

=head1 SYNOPSIS

=over 4

=item (1) 

code2html [options] [input_file [output_file]]

=item (2)

code2html C<-p> [file]

=item (3)

code2html (as a CGI script: see CGI section below)

=back

=head1 DESCRIPTION

code2html is a  perlscript  which  converts  a  program source 
code to syntax highlighted HTML.

=over 4

=item (1) OPTIONS

=over 4

=item input_file

Is the file which contains the program source  code
to be formatted. If not specified or a minus (-) is
given, the code will be read from STDIN.

=item output_file

Is the file to write the formatted code to. If  not
specified or a minus (-) is given, the code will be
written to STDOUT.

=item -l, --language_mode

Specify the set  of  regular  expressions  to  use.
These  have  to  be  defined  in  a  language file
(see FILES below). To find out which language modes
are defined, issue a code2html.pl C<--modes>.

This input is treated case-insensitive.

If not given,  some  heuristics  will  be  used  to
determine the file language.

=item -v, --verbose

Prints progress information to STDERR. You will not
need this.

=item -n, --linenumbers

Print out the source code with line numbers.

=item -N, --linknumbers

Print out the source code with line numbers.
The linenumbers  will  link  to  themselves,  which
makes it easy to send links to lines.

=item -t, --replace_tabs  <TABSTOP WIDTH>

Replace each occurence of a  <TAB>  character  with
the  right  amount  of  spaces  to  get to the next
TABSTOP.
can be changed by an optional argument.

=item -L, --language_file  <FILE>

Specify an alternate languages  file  to  take  the
regular expressions from (see FILES below).

=item -m, --modes

Print all defined modes currently defined to STDOUT
and exit succesfully.  Also  prints  modes  from  a
given language_file if applicable.

=item --fallback <LANG>

If the language mode givin with the first parameter
(language_mode) cannot be found then use this mode.
Usefull  when code2html is called from a script to
ensure output is created: C<--fallback plain>

=item --dump_default_lang

Write default language  file  to  STDOUT  and  exit
succesfully.

=item -h, -? --help

Print this text and exit succesfully.

=item -V --version

Print the program version and exit succesfully.

=item -c --content_type

Prints "Content-Type: text/html\n\n" prior  to  the
html file. Usefull if the script is  ivoked   as  a
cgi script.

=item -H --no_header

do not print the  <html>,  <head>,  <body>,  <pre>
stuff. Usefull if this script is only  a  part  in
a  bigger program.

=item -T --title

Set the title of the produced HTML file.

=back

=item (2) code2html.pl -p [infile [outfile]]

code2html now also allows you to have inline source code
in an html file. It can then  take this  html  file  and
insert the syntax highlighted code.

If no file is given,  code2html  reads  from  STDIN  and
writes to STDOUT. If just one file is given it replaces
this file with the output.

To  use  this feature, just insert a like like this into
your html file:

    <!-- code2html add [options] <file> -->

the syntax highlighted file will  be  inserted  at  this
position enclosed in <pre> tags.

All  options  that  can be given  on  the  command  line
like  C<--linenumbers>  etc.  work.  C<--help> and  C<--version>
etc. work too  however  it  is  not  very
intelligent to use them :). C<--content_type> is ignored.

You  may  also  write the program's source code directly
in the html file with the following syntax:

    <!-- code2html add [options]

    <your program source code here>

    -->

It is usually a good idea to at least give the C<-l> option
to specify the language.

This is a very new feature, so if you have  problems  or
questions,  please  let me know. An example can be found
at my homepage: http://www.cosy.sbg.ac.at/~ppalfrad

=item (3) CGI

If   the   the   script   is   used   as   a   CGI  script
(GATEWAY_INTERFACE environment  set  and  no  command  line
arguments given) code2html reads the arguments either from
the query string or from stdin. (methods POST and GET).

--content_type is switched on automatically and the output
always goes to STDOUT.

The following parameters/options are accepted:

=over 4

=item language_mode - optional

'c', 'cc', 'pas', etc.

if not given, some heuristics are used  to  find  out  the
language.

=item fallback - optional

'plain', 'c', etc.
if language_mode cannot be found, use this one

=item input_selector - optional

either 'file', 'cgi_input1', 'cgi_input2', or 
'REDIRECT_URL'
default: file

=item filename

file to read from if input_selector is 'file'

=item cgi_input1

the source code to syntax highlight
for example from a <textarea> or from a upload.
see input_selector

=item cgi_input2

the source code to syntax highlight
for example from a <textarea> or from a upload.
see input_selector

=item line_numbers - optional

'yes', 'no' or 'link'
default: no

=item replace_tabs - optional

if 0 then tabs are not replaced, if larger then each
tab is replaced by that many spaces.
default: 0

=item title - optional

Set's the title of the HTML file.

=item no_encoding - optional

By default code2html tries to encode the output as either
bz2/gz/Z if the client supports this (HTTP_ACCEPT_ENCODING)
and the needed program is available on the server.
You may need to modify @CGI_ENCODING in the script to match
your program locations.

If no_encoding is defined and true code2html does not try to
encode the output.

=back

Why  two  cgi_inputs  you  may  ask: This is to allow your
users to choose vie a <form> interface whether  they  want
to  insert their file into a <textarea> or user a <browse>
button to select their file. See the example on  my  home-
page.

Note that by default it is possbile for your users to read
all the files the httpd can read (if you don't run a  cgi-
wrapper  or  something  like  this . You may disallow file
reading via cgi with setting FILES_DISALLOWED_IN_CGI  to 1
at the top of the script.

The   input   selector   REDIRECT_URL   needs   a  special
explaination.  The  file  name  is  formed  from  the  two
enviroment variables DOCUMENT_ROOT and REDIRECET_URL.

Kevin Burton  <burton@relativity.yi.org>  will  tell  you
what you need this for:

    > So I had a problem where  I  wanted  all  my  Java files
    > automatically  converted  to  html  and displayed. But I
    > didn't  want  to  write  any  crazy  web  interface  for
    > code2html.
    > So what I did was this.
    >
    > Configured Apache with an "Action" directive in srm.conf
    > like this:
    >
    > Action text/java
    > /cgi-bin/code2html?language_mode=java&input_selector=REDIRECT_URL
    >
    > Works great!
    >
    > It is more powerfull if you use it in an Apache
    > <Directory> tag
    >
    > <Directory /source>
    >
    >   #with your Action tag here... this way you can 
    >   #still have regular .java files on your server.
    >
    > </Directory>
    >

=back

=head1 EXAMPLE

assuming code2html.pl is in the current directory, you may
type

   code2html.pl -l perl code2html.pl code2html.html

to convert the script into a html file.

=head1 FILES

=over 4

=item *

file specified by C<-L> or --language_file if any

=item *

files specified in the evironment variable F<CODE2HTML_CONFIG>,
seperated by colons

=item *

F<$HOME/.code2html.config>

=item *

F</etc/code2html.config>

=item *

built in default languages

=back

Entries in a file that is mentioned earlier in this list
override rules from later files.

The file structure must be valid perl code. 

The global variable %LANGUAGE is already defined, so you
should not redeclare it using "my".

It is probably the best idea to look at the definition
you can see at the bottom of code2html. 

If your pattern includes back references like a lot patterns
do in perl for example, then you have to use \2 instead of \1
\3 instead of \2 and so on. I really don't like this hack but
it is a lot faster. 
Example:

     <<([^\n]*).*?^\2$

In this example the perl << stuff is matched, i.e. everything
from a << until a line that consists of exactly the same
string as behind the << was. The \2 references the matched
chars in the parentenses.


If you ever write languages files yourself, I'ld be  happy
if  you  could  send be them, so I put them on my homepage
with full credits of course.
Before you do so you might also have a look at my site  to
check  wheter  someone  has  written  the  file  for  your
language already.

=head1 NOTES

The language recognition mechanism relies on specific patterns within
the name and content of a file that is to be highlighted, such as
extensions and shebangs (#!). This means that if an  unnamed or
incomplete file is to be filtered, typical for patch and CGI modes,
the language name should be specified using the C<-l> command line
parameter.

=head1 BUGS

Please   report   bugs  to  ppalfrad@cosy.sbg.ac.at.  This
program is still in beta so you might find some. Also have
a look at my web-site, perhaps a new version is  available
already: http://www.cosy.sbg.ac.at/~ppalfrad/

=head1 AUTHOR

Peter Palfrader,  computer   science   student   at   the
University  of Salzburg/Austria.
A lot of other people. See contributers in the file itself.

=head1 LICENSE

Copyright (c) 1999 by Peter Palfrader & others.
Not derived from licensed software.

A lot of other people. See contributers in the file itself.

Permission is granted to anyone to use this  software  for
any purpose on any computer system, and to redistribute it
in any way, subject to the following restrictions:

=over 4

=item 1. 

The author is not responsible for the  consequences  of
use of this software, no matter how awful, even if they
arise from defects in it.

=item 2.

The origin of this software must not be misrepresented,
either by explicit claim or by omission.

=item 3.

Altered  versions  must  be plainly marked as such, and
must  not  be  misrepresented  (by  explicit  claim  or
omission) as being the original software.

=item 3a.

It would be nice if I got  a  copy  of  your  improved
version  sent to ppalfrad@cosy.sbg.ac.at. However this
is not obligatory.

=item 4.

This notice must not be removed or altered.

=back

Thanks to Henry Spencer for this wonderful license :).

The regular expressions found in the default database  are
are  not subject to  this  license. They  have either been
taken from NEdit and were then modified by others or me or
they were released by their authors into Public Domain.

According to Mark Edel <edel@ltx.com> who does the support
of NEdit they are public domain and so  you  may  do  with
them whatever you want.

=cut

#'#"emacs highlighting....


my $short_help = "
$pure_version_message

NAME
       code2html.pl - Converts a program source code to HTML

SYNOPSIS
       code2html.pl language_mode [input_file [output_file]]
         [options]

DESCRIPTION
       code2html.pl is a  perlscript  which  converts  a  program
       source  code  to syntax highlighted HTML by applying a set
       of   regular   expressions   depending   on  the  language
       the source code is written.
";





my $USE_CGI_FOR_ERRORS      = 0; # is switched on in parse params if necessary
my $IN_POD                  = 0; # used to switch off warnings in POD
$SIG{'__DIE__'} = 
  sub {
    if ($USE_CGI_FOR_ERRORS) { print "Content-Type: text/plain\n\n", $0, ': ', $_[0], "\n"; }
    else                     { print STDERR $0, ': ', $_[0];                                };
    exit 1;
  };

$SIG{'__WARN__'} = 
  sub {
    if (!$USE_CGI_FOR_ERRORS && !$IN_POD) { print STDERR $0.': '.$_[0]; };
  };





my $ENTITIES = '[<>&"]';
my %ENTITIES;
$ENTITIES{'&'} = '&amp;' ;
$ENTITIES{'<'} = '&lt;' ;
$ENTITIES{'>'} = '&gt;' ;
$ENTITIES{'"'} = '&quot;' ;








my %params = &parse_params;
if    ($params{'what_to_do'} eq 'patch_html') { &patch_html(\%params) }
elsif ($params{'what_to_do'} eq 'normal'    ) { &main(\%params)       }
else  { die("I don't know what to do :(\n") };










sub main
  {
      my %params = %{shift()};


      print STDERR "getting patterns...\n"                      if ($params{'verbose'});
      # building up the database
      # newer entries overwrite old ones
      my @CONFIG_FILES;
      push @CONFIG_FILES, "/etc/code2html.config";
      push @CONFIG_FILES, $ENV{'HOME'}."/.code2html.config"   if (defined($ENV{'HOME'}));
      push @CONFIG_FILES, split(/:/,$ENV{'CODE2HTML_CONFIG'}) if ($ENV{'CODE2HTML_CONFIG'});
      push @CONFIG_FILES, split(/:/,$params{'langfile'})      if defined($params{'langfile'});
     

      my %LANGUAGE = %{ &get_default_database };
      for (@CONFIG_FILES) {
	  if ( -r $_){
	      unless (do $_) {
		  warn "couldn't parse $_: $@" if $@;
	      };
	  };
      };




      if (defined($params{'modes'}) && $params{'modes'})
	{
	    print "Defined modes: ";
	    print join( ', ', sort keys %LANGUAGE ), "\n" ;
	    exit;
	};


      


      my $code_ref;
      print STDERR "loading input file...\n"                    if ($params{'verbose'});
      $code_ref = &get_input_file(\%params, \%LANGUAGE, $params{'langmode'}, $params{'alt_langmode'});

      print STDERR "outputting headers...\n"                    if ($params{'verbose'});
      &put_headers(\%params, \%LANGUAGE);

      my $snippetlist_ref = [] ;
      print STDERR "creating snippet-list...\n"                 if $params{'verbose'};
      &create_snippetlist($LANGUAGE{ lc($params{'langmode'}) }->{'patterns'}, $$code_ref, $snippetlist_ref);

      print STDERR "outputting file...\n"                       if $params{'verbose'};
      return &put_output(\%params, $snippetlist_ref);
}





sub patch_html
  {
      my %params = %{shift()};
      my $code;

      open(FILEHANDLE, $params{'infile'}) || die("While opening '$params{'infile'}' for input: ".$!."\n");
      my $bak_input_sep = $/; undef $/; $code = <FILEHANDLE>; $/ = $bak_input_sep;
      close(FILEHANDLE);
      
      $code =~ s/<!-- code2html delete start -->.*?<!-- code2html delete stop -->//gs;
      my $counter=0;
      my @chunks = split ( /(<!-- code2html add.*?-->)/s , $code);

      $code = '';
      for (@chunks)
	{
	    $code .= $_;
    	    if ($_ =~ /<!-- code2html add(.*?)(\n.*?)?-->/s)
	      {
		  my $cmdline = $1; 
		  my $input   = $2;
		  $cmdline =~ s/^[ \t]*//g;
		  $cmdline =~ s/[ \t]*$//g;
		  @ARGV = split ( / / , $cmdline);
		  my %new_params = &parse_params;


		  $new_params{'input'} = $input  if ($new_params{'infile'} eq "-");


		  undef $new_params{'outfile'};
		  $new_params{'line_number_prefix'} = ++$counter;

		  $new_params{'verbose'} = $params{'verbose'};

		  my $no_header = $new_params{'noheader'};
		  $new_params{'noheader'} = 1;
		  $new_params{'dont_print_output'} = 1;

		  if ($no_header)
		    {
			$code .= '<!-- code2html delete start -->'..
			  &main(\%new_params).
			    '<!-- code2html delete stop -->';
		    }
		  else
		    {
			$code .= '<!-- code2html delete start --><pre>'.
			  &main(\%new_params).
			    '</pre><!-- code2html delete stop -->';
		    };
	      };
	};


      open(FILEHANDLE, '>'.$params{'outfile'}) || die("While opening '$params{'outfile'}' for output: ".$!."\n");
      print FILEHANDLE $code;
      close(FILEHANDLE);
  };






#####################################################################
################### get_input_data ##################################
#####################################################################
# Reads the input data for the cgi script.
# in : nothing
# out: a hash with the input data
sub get_input_data
  {
    my $input_data;
    my %f;
    if($ENV{'REQUEST_METHOD'} eq 'GET')  { $input_data = $ENV{'QUERY_STRING'}; }
    else {  read(STDIN, $input_data, $ENV{'CONTENT_LENGTH'}); };
    
    
    if ($ENV{'CONTENT_TYPE'} =~ m/^multipart\/form-data; boundary=(.*)$/i)
      {
        my $boundary = quotemeta($1);
        my @blocks = split(/$boundary/, $input_data);
        
        for (@blocks)
          {
            if (my $dummy = m/name="(.*?)"/i) 
              {
                my $name = $1;
                $_ =~ s/\r\n/\n/g;
                m/\n\n(.*)\n/s;
                my $value = $1;
                $f{$name}=$value;
              };
          };
      }
    elsif ($ENV{'CONTENT_TYPE'} =~ m/^multipart\/form-data;$/i) # if the boundary is not in the enviroment variable we'll guess
      {
        my $dummy = $input_data =~ m/^(.*?)(\n|\r)/;
        my $boundary = $1;

        my @blocks = split(/$boundary/, $input_data);

        for (@blocks)
          {
            if (my $dummy = m/name="(.*?)"/i)
              {
                my $name = $1;
                $_ =~ s/\r\n/\n/g;
                m/\n\n(.*)\n/s;
                my $value = $1;
                $f{$name}=$value;
              };
          };
      }
    else
      {
        my @form_fields = split(/&/, $input_data);
        
        for (@form_fields)
          {
            my ($name, $value) = split(/=/, $_);
            $value =~ tr/+/ /;
            $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
            
            $f{$name} = $value;
          }
      };

    return %f;
  };

################################################################################
####################### parse_params ###########################################
################################################################################
sub parse_params
  {
      my %RESULT;
      
      if (defined($ENV{'GATEWAY_INTERFACE'}) && (!scalar(@ARGV))) # if there is a CGI enviroment and no parameters/options given
	{
	    $USE_CGI_FOR_ERRORS = 1;
	    $RESULT{'content-type'} = 1;
	    $RESULT{'what_to_do'} = 'normal';
	    
	    my %input = &get_input_data;
	    if ($input{'input_selector'} eq "cgi_input1")
	      {
		  if (!defined($input{'cgi_input1'})) {die('CGI parse error: cgi_input1 does not exist!')};
		  $RESULT{'input'} = $input{'cgi_input1'};
		  $RESULT{'title'} = 'code2html result of cgi input form';
	      }
	    elsif ($input{'input_selector'} eq "cgi_input2")
	      {
		  if (!defined($input{'cgi_input2'})) {die('CGI parse error: cgi_input2 does not exist!')};
		  $RESULT{'input'} = $input{'cgi_input2'};
		  $RESULT{'title'} = 'code2html result of cgi input form';
	      }
	    elsif ($input{'input_selector'} eq "file")
	      {
		  if ($FILES_DISALLOWED_IN_CGI) {die('CGI parse error: option not supported due to security reasons!')};
		  if (!defined($input{'filename'})) {die('CGI parse error: filename not defined!')};
		  $RESULT{'infile'} = $input{'filename'};
		  $RESULT{'title'} = $RESULT{'infile'};
	      }
	    elsif ($input{'input_selector'} eq "REDIRECT_URL")
	      {
		  if ($FILES_REDIRECT_DISALLOWED) {die('CGI parse error: option not supported due to security reasons!')};
		  if (!defined($ENV{'REDIRECT_URL'})) {die('CGI parse error: ENV: REDIRECT_URL not defined!')};
		  $RESULT{'infile'} = $ENV{'DOCUMENT_ROOT'}.$ENV{'REDIRECT_URL'};
		  $RESULT{'title'} = $RESULT{'infile'};
	      }
	    else
	      {
		  die('CGI parse error: input selector not given!');
	      };
	    
	    if ((!defined ($input{'no_encoding'})) || $input{'no_encoding'})
	      {
		  for (@CGI_ENCODING)
		    {
			if ( ($ENV{'HTTP_ACCEPT_ENCODING'} =~ m/\b $_->[0] \b/x)  &&  # PP: if supported by the browser
			     (-x $_->[1]) )                                           # PP: and executable by the script
			  {
			      $RESULT{'encoding'} = $_->[0];
			      $RESULT{'encoder' } = $_->[1] .' '. $_->[2];
			      last;
			  };
		    }
	      };

	    if ($input{'line_numbers'} eq "yes")  { $RESULT{'linenumbers'} = 'yes'; };
	    if ($input{'line_numbers'} eq "link") { $RESULT{'linenumbers'} = 'link'; };
	    if (defined($input{'replace_tabs'}))  { $RESULT{'replacetabs'} = $input{'replace_tabs'} };
	    if (defined($input{'fallback'}))      { $RESULT{'alt_langmode'} = $input{'fallback'} };
	    if (defined($input{'language_mode'})) { $RESULT{'langmode'} = $input{'language_mode'} };
	    if (defined($input{'title'}))         { $RESULT{'title'} = $input{'title'} };

	    $RESULT{'content_type'} = 1;
	    $RESULT{'outfile'}      = '-';
	}
      else
	{
	    my $verbose           = 0;
	    my $linenumbers       = 0;
	    my $linknumbers       = 0;
	    my $replace_tabs      = 0;
	    my $language_file     = '';
	    my $language_mode     = '';
	    my $modes             = 0;
	    my $fallback          = '';
	    my $dump_default_lang = 0;
	    my $help              = 0;
	    my $version           = 0;
	    my $content_type      = 0;
	    my $no_header         = 0;
	    my $title             = '__NOTHING__'; # some magix ;(

	    my $patch_html;

	    Getopt::Long::config('bundling');
	    if (! GetOptions( "--verbose"               , \$verbose              , 
		              "-v"                      , \$verbose            ,
			      
			      "--linenumbers"           , \$linenumbers          , 
			      "-n"                      , \$linenumbers        , 
			      
			      "--linknumbers"           , \$linknumbers          , 
			      "-N"                      , \$linknumbers        , 
			      
			      "--replace_tabs=i"        , \$replace_tabs         , 
			      "-t=i"                    , \$replace_tabs       , 
			      
			      "--language_file=s"       , \$language_file        , 
			      "-L=s"                    , \$language_file        , 

			      "--language_mode=s"       , \$language_mode        , 
			      "-l=s"                    , \$language_mode        ,
 
			      "--title=s"               , \$title                , 
			      "-T=s"                    , \$title                ,
 
			      "--modes"                 , \$modes                , 
			      "-m"                      , \$modes                , 

			      "--fallback=s"            , \$fallback             , 
			      
			      "--dump_default_lang"     , \$dump_default_lang    , 

			      "--help"                  , \$help                 , 
			      "-s"                      , \$help                 , 
			      "-h"                      , \$help                 , 

			      "--version"               , \$version              , 
			      "-V"                      , \$version              , 
			      
			      "--content_type"          , \$content_type         , 
			      "-c"                      , \$content_type         , 
			      
			      "--no_header"             , \$no_header            ,
			      "-H"                      , \$no_header            ,

			    
			      "--patch_html"            , \$patch_html           ,
			      "-p"                      , \$patch_html           )
	       )
	      {
		  print STDERR $short_help;
		  print STDERR "\n\nrun code2html --help for further help\n";
		  exit 1;
	      };

	    # added JL, 1999/08/05, get built-in doc parsed; downside: pod2text generates a lot of warnings
	    # update PP, 1999/08/14, warnings by pod2text no longer get displayed
	    # update BS/PP, 1999/09/23, requiring speeds this up in most cases
	    if ($help)              { $IN_POD = 1; require Pod::Text ; Pod::Text::pod2text( __FILE__ ) ;     exit 0; };
	    if ($version)           { print $version_message;      exit 0; };
	    if ($dump_default_lang) { print &get_default_database; exit 0; };

	    if ($patch_html)
	      {
		  $RESULT{'what_to_do'} = 'patch_html';
		  $RESULT{'verbose'}    = $verbose;

		  if (!defined ($RESULT{'infile'}        = shift(@ARGV))) { $RESULT{'infile'} = '-' };
		  if (!defined ($RESULT{'outfile'}       = shift(@ARGV))) { $RESULT{'outfile'} = $RESULT{'infile'}};
	      }
	    else
	      {
		  $RESULT{'what_to_do'} = 'normal';

		  $RESULT{'verbose'}        = $verbose;
		  if    ($linknumbers) { $RESULT{'linenumbers'}    = 'link' }
		  elsif ($linenumbers) { $RESULT{'linenumbers'}    = 'yes' }
		  else                 { $RESULT{'linenumbers'}    = 'no' };
		  $RESULT{'replacetabs'}    = $replace_tabs;
		  $RESULT{'langfile'}       = $language_file;
		  $RESULT{'modes'}          = $modes;
		  $RESULT{'alt_langmode'}   = $fallback;
		  $RESULT{'content_type'}   = $content_type;
		  $RESULT{'noheader'}       = $no_header;
		  $RESULT{'langmode'}       = $language_mode;

		  if (!defined ($RESULT{'infile'}          = shift(@ARGV))) { $RESULT{'infile'} = '-'};
		  if (!defined ($RESULT{'outfile'}         = shift(@ARGV))) { $RESULT{'outfile'} = '-'};
		  if (defined (shift(@ARGV))) { print STDERR  "too many parameters!\n";
						print STDERR $short_help;
						print STDERR "\n\nrun code2html --help for furhter help\n";
						exit 1;
					    };
	      };
	      #the magix again
	    $RESULT{'title'} = $title eq  '__NOTHING__' ? ($RESULT{'infile'} eq '-' ? 'STDIN' : $RESULT{'infile'}) : $title;
	};

      return %RESULT;
  };


################################################################################
####################### checkTabulator #########################################
################################################################################
sub checkTabulator
{
    my ($line, $TABSTOP) = @_;
    
    while ((my $at = index($line, "\t")) != -1)
      {
	  my $cnt = ($TABSTOP - ($at % $TABSTOP));
	  my $replace_with = ' ' x $cnt if ($cnt);
	  $line =~ s/\t/$replace_with/;
      };

    return $line;
}

################################################################################
####################### get_input_file #########################################
################################################################################
sub get_input_file
  {

    # in  : \%params
    # in : \%LANGUAGE;
    # in/out : $langmode;
    # in/out : $alt_langmode;
    # returns: input file
    
      my %PARAMS       = %{$_[0]};
      my %LANGUAGE     = %{$_[1]};
      my $langmode     = $_[2];
      my $alt_langmode  = $_[3];
      my $code;

      
      if (defined($PARAMS{'input'}) && ($PARAMS{'input'} ne ""))
	{
	    $code = $PARAMS{'input'};
	    $code =~ s/\r//g;
	}
      else
	{
	    open(FILEHANDLE, $PARAMS{'infile'}) || die("While opening '$PARAMS{'infile'}' for input: ".$!."\n");
	    my $bak_input_sep = $/; undef $/; $code = <FILEHANDLE>; $/ = $bak_input_sep;
	    close(FILEHANDLE);
	};
      
      if ($PARAMS{'replacetabs'} != 0)
	{
	    $code = join (
			  "\n",
			  map{
			      &checkTabulator($_, $PARAMS{'replacetabs'})
			  }
			  my @dummy = split(/\n/, $code)
			 );
	};
      

      
      if ((!defined($langmode)) || ($langmode eq ''))
	{
	    my $test_code = substr($code, 0, $LANG_TEST_LENGTH);
	    warn("language mode not given. guessing...\n");

	    $langmode = '';

	    for (keys %LANGUAGE)
	      {
		  if (  (($LANGUAGE{$_}->{'filename'} ne '') && ($PARAMS{'infile'} =~  m/$LANGUAGE{$_}->{filename}/))  ||
		        (($LANGUAGE{$_}->{'regex'}    ne '') && ($test_code        =~  m/$LANGUAGE{$_}->{regex}/   ))   )
		    {
			$langmode = $_;
			last;
		    };
	      };

	    if ($langmode eq '')
	      {
		  if ((defined($alt_langmode)) && ($alt_langmode ne ''))
		    {
			warn("Guessing language mode failed. Using fallback mode: '$alt_langmode'\n");
			$langmode = $alt_langmode;
			$alt_langmode = '';
		    }
		  else
		    {
			die("Guessing language mode failed.\n")
		    };
	      }
	    else
	      {
		  warn("using '$langmode'\n");
	      };
	};
      
      $_[2] = $langmode;
      $_[3] = $alt_langmode;
      return \$code;
  };


################################################################################
####################### put_headers ############################################
################################################################################
sub put_headers
{	
      my %PARAMS = %{shift()};
      my $LANGUAGE_REF = shift();

      my $header = '';

      $header .= "<html><head><title>".
        	 $PARAMS{'title'}.
	         "</title></head><body bgcolor=\"".$LANGUAGE_REF->{$PARAMS{'langmode'}}->{'bgcolor'}.
                 "\" text=\"".$LANGUAGE_REF->{$PARAMS{'langmode'}}->{'textcolor'}."\"><pre>\n"          if (!$PARAMS{'noheader'});

      if (defined($PARAMS{'outfile'}))
	{
	    unless ($PARAMS{'outfile'} eq '-'){
		open(SAVEOUT, ">&STDOUT");             print SAVEOUT '';  # so perl does not typo warn
		open (STDOUT, '>'.$PARAMS{'outfile'}) || die("While redirecting STDOUT to '$PARAMS{'outfile'}' for output: ".$!."\n");
	    };

	    if (defined $PARAMS{'encoding'}) 
	      {
		  $|=1; # PP: so the header is written before the data!
		        # PP: this took me hours of debugging :(
		  print "Content-Type: text/html\n"                                                    if ($PARAMS{'content_type'});
		  print "Content-Encoding: $PARAMS{'encoding'}\n\n";
		  open (FILEHANDLE, "|$PARAMS{'encoder'}") || die("While opening '$PARAMS{'encoder'}': ".$!."\n");
	      }
	    else
	      {
		  open( FILEHANDLE, ">&STDOUT" ) ;
		  print FILEHANDLE "Content-Type: text/html\n\n"                                        if ($PARAMS{'content_type'});
	      };
	       
	     print FILEHANDLE $header ;
        }
};

################################################################################
####################### create_snippetlist #####################################
################################################################################
sub create_snippetlist
  {
    my ( $regexps_ref, $code, $snippetlist_ref ) = @_ ;
    my $length = length( $code );

    ## An array of regular expression sturctures, each of which is an
    ## array.  @res is kept sorted by starting position of the RExen and
    ## then by the position of the regex in the language file.  This allows
    ## us to just evaluate $res[0], and to hand write fast code that typically
    ## handles 90% of the cases without resorting to the _big_ guns.
    ##
    ## FWIW, I pronounce '@res' REEZE, as in the plural of '$re'.
    ##
    my @res ;
    
    my $pos ;
    
    for ( @$regexps_ref ) {
	pos( $code ) = 0 ;
#++$m ;
	next unless $code =~ m/($_->{regex})/gms ;

	$pos = pos( $code ) ;
	$res[@res] = [ 
		      $_->{regex},
		      $_->{starttag},
		      $_->{endtag},
		      $_->{childregex},
		      $pos - length( $1 ),
		      $pos,
		      scalar( @res ),
		     ] ;
    }
    
    ## 90% of all child regexes end up with 0 or 1 regex that needs to be
    ## worried about. Trimming out the 0's speeds things up a bit and
    ## makes the below loop simpler, since there's always at least
    ## 1 regexp.  It donsn't speed things up much by itself: the percentage 
    ## of times this fires is really small.  But it does simplify the loop
    ## below and speed it up.
    unless ( @res ) {
	$code =~ s/($ENTITIES)/$ENTITIES{$1}/ge ;
	push @$snippetlist_ref, $code ;
	return ;
    }
    
    @res = sort { $a->[4] <=> $b->[4] || $a->[6] <=> $b->[6] } @res ;
    
    ## Add a dummy at the end, which makes the logic below simpler / faster.
    $res[@res] = [
		  undef,
		  undef,
		  undef,
		  undef,
		  $length,
		  $length,
		  scalar( @res ),
		 ] ;
    
    ## These are declared here for (minor) speed improvement.
    my $re ;
    my $match_spos ;
    my $match_pos ;
    my $re_spos ;
    my $re_pos ;
    my $re_num ;
    my $prefix ;
    my $snippet ;
    my $rest ;
    my $i ;
    my $l ;
    
my @changed_res ;
my $j ;

    $pos = 0 ;
MAIN:
    while ( $pos < $length ) {
	$re = $res[0] ;
	
	$match_spos = $re->[4] ;
	$match_pos  = $re->[5] ;
	
	if ( $match_spos > $pos ) {
	    $prefix  = substr( $code, $pos, $match_spos - $pos ) ;
	    $prefix  =~ s/($ENTITIES)/$ENTITIES{$1}/ge ;
	    push @$snippetlist_ref, $prefix ;
	}
	
	if ( $match_pos > $match_spos ) {
	    $snippet = substr( $code, $match_spos, $match_pos - $match_spos ) ;
	    if ( @{$re->[3]} ) {
		push @$snippetlist_ref, $re->[1] ;
		create_snippetlist( $re->[3], $snippet, $snippetlist_ref ) ;
		push @$snippetlist_ref, $re->[2] ;
	    }
	    else {
		$snippet =~ s/($ENTITIES)/$ENTITIES{$1}/ge ;
		push @$snippetlist_ref, $re->[1], $snippet, $re->[2];
	    }
	}
	
	$pos = $match_pos ;
	
	##
	## Hand coded optimizations.  Luckily, the cases that arise most often
	## are the easiest to tune.
	##

# =pod

	if ( $res[1]->[4] >= $pos ) {
	    ## Only first regex needs to be moved, 2nd and later are still valid.
	    ## This is often 90% of the cases for Perl or C (others not tested,
	    ## just uncomment the $n, $o, and $p lines and try it yourself).
#++$n{1} ;
#++$m ;
	    pos( $code ) = $pos ;
	    unless ( $code =~ m/($re->[0])/gms ) {
#++$o{'0'} ;
		if ( @res == 2 ) {
		    ## If the only regexp left is the dummy, we're done.
		    $rest = substr( $code, $pos ) ;
		    $rest =~ s/($ENTITIES)/$ENTITIES{$1}/ge ;
		    push @$snippetlist_ref, $rest ;
		    last ;
		}
		shift @res ;
	    }
	    else {
		$re->[5] = $re_pos  = pos( $code ) ;
		$re->[4] = $re_spos = $re_pos - length( $1 ) ;
		
		## Walk down the array looking for $re's new home.
		## The first few loop iterations are unrolled and done manually 
		## for speed, which handles 85 to 90% of the cases where only
		## $re needs to be moved.
		##
		## Here's where that dummy regexp at the end of the array comes
		## in handy: we don't need to worry about array size here, since
		## it will always be after $re no matter what.  The unrolled
		## loop stuff is outdented to make the conditionals fit on one
		## 80 char line.
		## Element 4 in @{$res[x]} is the start position of the match.
		## Element 6 is the order in which it was declared in the lang file.
		$re_num = $re->[6] ;
		if ( ( $re_spos <=> $res[1]->[4] || $re_num <=> $res[1]->[6] ) <= 0 ) {
#++$o{'1'} ;
		    next 
		}
		$res[0] = $res[1] ;

#++$o{'2'} ;
		if ( ( $re_spos <=> $res[2]->[4] || $re_num <=> $res[2]->[6] ) <= 0 ) {
		    $res[1] = $re ;
		    next ;
		}
		$res[1] = $res[2] ;
		
		if ( ( $re_spos <=> $res[3]->[4] || $re_num <=> $res[3]->[6] ) <= 0 ) {
#++$o{'3'} ;
		    $res[2] = $re ;
		    next ;
		}
		$res[2] = $res[3] ;
		
		if ( ( $re_spos <=> $res[4]->[4] || $re_num <=> $res[4]->[6] ) <= 0 ) {
#++$o{'3'} ;
		    $res[3] = $re ;
		    next ;
		}
		$res[3] = $res[4] ;
		
		if ( ( $re_spos <=> $res[5]->[4] || $re_num <=> $res[5]->[6] ) <= 0 ) {
#++$o{'4'} ;
		    $res[4] = $re ;
		    next ;
		}
		$res[4] = $res[5] ;

#++$o{'ugh'} ;
		$i = 6 ;
		$l = $#res ;
		for ( ; $i < $l ; ++$i ) {
		    last
		      if ( 
			  ( $re_spos <=> $res[$i]->[4] || $re_num <=> $res[$i]->[6] )
			  <= 0
			 ) ;
		    $res[$i-1] = $res[$i] ;
		}
#++$p{sprintf( "%2d", $i )} ;
		$res[$i-1] = $re ;
	    }
	    
	    next ;
	}
	
# =cut

	##
	## End optimizations.  You can comment them all out and this net
	## does all the work, just more slowly.  If you do that, then
	## you also need to comment out the code below that deals with
	## the second entry in @res.
	##

#my $ni = 0 ;
	## First re always needs to be tweaked
#++$m ;
#++$ni ;
	pos( $code ) = $pos ;
	unless ( $code =~ m/($re->[0])/gms ) {
	    if ( @res == 2 ) {
		## If the only regexp left is the dummy, we're done.
		$rest = substr( $code, $pos ) ;
		$rest =~ s/($ENTITIES)/$ENTITIES{$1}/ge ;
		push @$snippetlist_ref, $rest ;
		last ;
	    }
	    shift @res ;
	    @changed_res = () ;
	    $i = 0 ;
	}
	else {
	    $re->[5] = $re_pos  = pos( $code ) ;
	    $re->[4] = $re_pos - length( $1 ) ;
	    @changed_res = ( $re ) ;
	    $i = 1 ;
	}
	
	## If the optimizations above are in, the second one always
	## needs to be tweaked, too.
	$re = $res[$i] ;
#++$m ;
#++$ni ;
	pos( $code ) = $pos ;
	unless ( $code =~ m/($re->[0])/gms ) {
	    if ( @res == 2 ) {
		## If the only regexp left is the dummy, we're done.
		$rest = substr( $code, $pos ) ;
		$rest =~ s/($ENTITIES)/$ENTITIES{$1}/ge ;
		push @$snippetlist_ref, $rest ;
		last ;
	    }
	    shift @res ;
	}
	else {
	    $re->[5] = $re_pos  = pos( $code ) ;
	    $re->[4] = $re_spos = $re_pos - length( $1 ) ;
	    if ( @changed_res &&
		 ( $changed_res[0]->[4] <=> $re_spos || 
		   $changed_res[0]->[6] <=> $re->[6]
		 ) > 0
	       ) {
		unshift @changed_res, $re ;
	    }
	    else {
		$changed_res[$i] = $re ;
	    }
	    ++$i ;
	}
	
	for ( ; ; ++$i ) {
	    local $_ = $res[$i] ;
#++$m ;
	    last if $_->[4] >= $pos ;
#++$ni ;
#++$m ;
	    pos( $code ) = $pos ;
	    unless ( $code =~ m/($_->[0])/gms ) {
		if ( @res <= 2 ) {
		    $rest = substr( $code, $pos ) ;
		    $rest =~ s/($ENTITIES)/$ENTITIES{$1}/ge ;
		    push @$snippetlist_ref, $rest ;
		    last MAIN ;
		}
		## If this regex is no longer needed, remove it by not pushing it
		## on to @changed_res.  This means we need one less slot in @res.
		shift @res ;
		redo ;
	    }

	    $_->[5] = $re_pos  = pos( $code ) ;
	    $_->[4] = $re_spos = $re_pos - length( $1 ) ;
	    
	    ## Insertion sort in to @changed_res
	    $re_num = $_->[6] ;
	    for ( $j = $#changed_res ; $j > -1 ; --$j ) {
		last
		  if ( 
		      ( $changed_res[$j]->[4] <=> $re_spos || 
			$changed_res[$j]->[6] <=> $re_num 
		      ) < 0
		     ) ;
		$changed_res[$j+1] = $changed_res[$j] ; 
	    }
	    $changed_res[$j+1] = $_ ;
	}

	## Merge sort @changed_res and @res in to @res
	$j = 0 ;
	$l = $#res ;
	for ( @changed_res ) {
	    while (
		   $i < $l &&
		   ( $_->[4] <=> $res[$i]->[4] || $_->[6] <=> $res[$i]->[6] ) > 0
		  ) {
		$res[$j++] = $res[$i++] ;
	    }
	    $res[$j++] = $_ ;
	}
# =cut
    }
};

##################################################################################
######################### create_snippetlist #####################################
##################################################################################
##sub create_snippetlist
##  {
##    my ( $regexps_ref, $code, $snippetlist_ref ) = @_ ;

##    my $length = length( $code );
##    my @regexps;
##    $regexps[scalar(@$regexps_ref)] = undef;

##    my $head_ptr    = undef;
##    my $current_ptr;
##    my $help_ptr;

##    my $index       = 0;

##    for (@$regexps_ref)
##      {
##	  $current_ptr = $regexps[$index];  #0: start_ptr 1: length 2: next_ptr, 3: regex, 4:start, 5:end, 6: child    7: index
##	  $current_ptr->[7] = $index++;
##	  $current_ptr->[6] = $$_{'childregex'}; 
##	  $current_ptr->[5] = $$_{'endtag'}; 
##	  $current_ptr->[4] = $$_{'starttag'};
##	  $current_ptr->[3] = $$_{'regex'};


##	  pos( $code ) = 0;
##	  if ( $code =~ /($current_ptr->[3])/gms ) { $current_ptr->[0] = pos ($code) - length($1); $current_ptr->[1] = length($1); } else {next};

##	  if (!defined ($head_ptr)  ||  $current_ptr->[0] < $head_ptr->[0] )
##	    {
##		$current_ptr->[2] = $head_ptr;
##		$head_ptr         = $current_ptr;
##	    }
##	  else
##	    {
##		$help_ptr = $head_ptr;
##		$help_ptr = $help_ptr->[2]
##		  while (defined ( $help_ptr->[2] ) && ($current_ptr->[0] >= $help_ptr->[2]->[0]) ); #iow: while (defined help->next && current->pos <= help->next->pos)
		
##		$current_ptr->[2] = $help_ptr->[2];
##		$help_ptr->[2]    = $current_ptr;
##	    };
##      };
    

##    my $endpos = 0;
##    my $oldhead;

##    my %entities ;
##    $entities{'&'} = '&amp;' ;
##    $entities{'<'} = '&lt;' ;
##    $entities{'>'} = '&gt;' ;
##    $entities{'"'} = '&quot;' ;
    
##    my $snippet;
##    while (defined $head_ptr)
##      {
##	  if ($head_ptr->[0] - $endpos > 0) { 
##	      $snippet = substr($code, $endpos, $head_ptr->[0] - $endpos);
##	      $snippet =~ s/($ENTITIES)/$ENTITIES{$1}/ge;          #"]);
##	      push @$snippetlist_ref, $snippet;
##	  };
##	  push  @$snippetlist_ref, $head_ptr->[4];

##	  &create_snippetlist( $head_ptr->[6], substr($code, $head_ptr->[0], $head_ptr->[1]) , $snippetlist_ref);
##	  push  @$snippetlist_ref, $head_ptr->[5];
	  
##	  $endpos = $head_ptr->[0] + $head_ptr->[1];

##	  # update & repair list :

##	  $oldhead = $head_ptr;
##	  # 1) shift now invalid matches from list

##	  $help_ptr = $head_ptr;
##	  $help_ptr = $help_ptr->[2]
##	    while (defined ( $help_ptr->[2] ) && ($endpos > $help_ptr->[2]->[0]) );
##	  $head_ptr = $help_ptr->[2];
##	  $help_ptr->[2] = undef;

##	  # 2) rematch invalid matches and insert them into the list
	  
##	  while (defined $oldhead)
##	    {
##		$current_ptr = $oldhead;
##		$oldhead = $oldhead->[2];

##		pos( $code ) = $endpos;
##		if ( $code =~ /($current_ptr->[3])/gms ) { $current_ptr->[0] = pos ($code) - length($1); $current_ptr->[1] = length($1); } else {next};
##		if (!defined ($head_ptr) ||
##		    ($current_ptr->[0] < $head_ptr->[0]) ||
##		    (
##		     ( $current_ptr->[0] == $head_ptr->[0]) &&
##		     ( $current_ptr->[7] <  $head_ptr->[7])
##		    )		     
##		   )
##		  {
##		      $current_ptr->[2] = $head_ptr;
##		      $head_ptr         = $current_ptr;
##		  }
##		else
##		  {
##		      $help_ptr = $head_ptr;
##		      $help_ptr = $help_ptr->[2]
##			while (defined ( $help_ptr->[2] ) && 
##			       (
##				($current_ptr->[0] >  $help_ptr->[2]->[0]) || 
##				(
##				 ( $current_ptr->[0] == $help_ptr->[2]->[0]) &&
##				 ( $current_ptr->[7] >  $help_ptr->[2]->[7])
##				 )
##			       )
##			      ); #iow: while (defined help->next && current->pos <= help->next->pos)   # if two patterns match at the same pos
##		                                                                                       # the one that was declared earlier is taken
		      
##		      $current_ptr->[2] = $help_ptr->[2];
##		      $help_ptr->[2]    = $current_ptr;
##		  };
##	    };
	  
##	  # 3) done
##      };
      
##    $snippet = substr($code, $endpos); $snippet =~ s/($ENTITIES)/$ENTITIES{$1}/ge;        #"   ]);
##    push  @$snippetlist_ref, $snippet;
##  };



################################################################################
####################### put_output #############################################
################################################################################
sub put_output {
    my ( $params, $snippetlist_ref ) = @_ ;

    my $result;
    my $mode = $params->{'linenumbers'} ;
    if (defined $mode && ( $mode eq 'link' || $mode eq 'yes' ))
      {
	  my @lines = split ( /\n/, join ('', @$snippetlist_ref) );

	  my $lengthofnr = length(@lines);
	  my $nr = 1; 
	  my $prefix = ''; 
	  $prefix = $params->{'line_number_prefix'}.'_'  if defined $params->{'line_number_prefix'};

	  if ( $mode eq 'link' ) {
	      my $format = qq{<a name="${prefix}line%u" href="#${prefix}line%u">%${lengthofnr}u</a> %s\n} ;
	      $result = join ('', map (  sprintf ( $format , $nr, $nr, $nr++, $_ ), @lines));
          } else {
	      my $format = qq{<a name="${prefix}line%u">%${lengthofnr}u</a> %s\n} ;
	      $result = join ('', map (  sprintf ( $format , $nr, $nr++, $_ ), @lines));
          };
      }
    else
      {
	  $result = join ('', @$snippetlist_ref);
      };

    print FILEHANDLE $result unless (defined $params->{'dont_print_output'} && $params->{'dont_print_output'});
    print FILEHANDLE "</pre></body></html>\n"  unless $params->{'noheader'};
    

    unless ($params{'outfile'} eq '-'){
	close (FILEHANDLE);
	close (STDOUT);
	open (STDOUT, ">&SAVEOUT");
    };
    return $result;
};





################################################################################
####################### get_default_database ###################################
################################################################################
sub get_default_database
{

my %LANGUAGE;

$LANGUAGE{'plain'}      = {
                            'filename'   => '',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => []
                          };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
$LANGUAGE{'ada'}        = {
                            'filename'   => '\\.a(d[asb]?)?$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'Comments',
                                                'regex'      => '--.*?$',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => [],
                                              },
                                              {
                                                'name'       => 'String Literals',
                                                'regex'      => '".*?("|$)',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Character Literals',
                                                'regex'      => '\'.\'',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Ada Attributes',
                                                'regex'      => '\'[a-zA-Z][a-zA-Z_]+\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Numeric Literals',
                                                'regex'      => '(((2|8|10|16)#[_0-9a-fA-F]*#)|[0-9.]+)',
                                                'starttag'   => '<font color="#FF0000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Withs Pragmas Use',
                                                'regex'      => '\\b(?i)((with|pragma|use)[ \\t\\n\\f\\r]+[a-zA-Z0-9_.]+;)+\\b',
                                                'starttag'   => '<font color="#0000FF"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Predefined Types',
                                                'regex'      => '\\b(?i)(boolean|character|count|duration|float|integer|long_float|long_integer|priority|short_float|short_integer|string)\\b',
                                                'starttag'   => '<font color="#800000"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Predefined Subtypes',
                                                'regex'      => '\\b(?i)field|natural|number_base|positive|priority\\b',
                                                'starttag'   => '<font color="#800000"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Reserved Words',
                                                'regex'      => '\\b(?i)(abort|abs|accept|access|and|array|at|begin|body|case|constant|declare|delay|delta|digits|do|else|elsif|end|entry|exception|exit|for|function|generic|goto|if|in|is|limited|loop|mod|new|not|null|of|or|others|out|package|pragma|private|procedure|raise|range|record|rem|renames|return|reverse|select|separate|subtype|task|terminate|then|type|use|when|while|with|xor)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Ada 95 Only',
                                                'regex'      => '\\b(?i)(abstract|tagged|all|protected|aliased|requeue|until)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Identifiers',
                                                'regex'      => '\\b[a-zA-Z][a-zA-Z0-9_]*\\b',
                                                'starttag'   => '<font color="#800000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Dot All',
                                                'regex'      => '(?i)\\.all\\b',
                                                'starttag'   => '<font color="#800000"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              }
                                            ]
                          };
$LANGUAGE{'ada95'}      = $LANGUAGE{'ada'};















$LANGUAGE{'awk'}       =  {
                            'filename'   => '\\.awk$',
                            'regex'      => '^\\s*#\\s*![^\\s]*awk',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'comment',
                                                'regex'      => '#.*?$',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'string',
                                                'regex'      => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'string',
                                                'regex'      => '\'\'|\'\\\\\\\\\'|\'[^\'\\\\]\'|\'[^\'].*?[^\\\\]\'',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'fuction header',
                                                'regex'      => 'function[\\t ]+([a-zA-Z0-9_]+)[\\t \\n]*(\\{|\\n)',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'function coloring',
                                                                    'regex'      => '[\\t ]([a-zA-Z0-9_]+)',
                                                                    'starttag'   => '<font color="#ff0000">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'regex matching I 1',
                                                'regex'      => '(\\b| )?(/)(\\\\/|[^/\\n])*(/[gimsox]*)',
                                                'starttag'   => '<font color="#b000d0">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'regex matching I 2',
                                                'regex'      => '(?:\\b| )(?:(?:m|q|qq)([!"#$%&\'*+-/]))(\\\\\\2|[^\\2\\n])*(\\2[gimsox]*)',
                                                'starttag'   => '<font color="#b000d0">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'regex matching II',
                                                'regex'      => '(?:\\b| )?(?:s([!"#$%&\'*+-/]))(?:\\\\\\2|[^\\2\\n])*?(\\2)[^(\\2)\\n]*?(\\2[gimsox]*)',
                                                'starttag'   => '<font color="#b000d0">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'translate',
                                                'regex'      => '(?:\\b| )(?:(?:tr|y)(\\W))(?:\\\\\\2|[^\\2\\n])*?(\\2)[^(\\2)\\n]*?(\\2[gimsox]*)',
                                                'starttag'   => '<font color="#b000d0">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'keywords',
                                                'regex'      => '\\b(BEGIN|END|ARGC|ARGIND|ARGV|CONVFMT|ENVIRON|ERRNO|FIELDWIDTHS|FILENAME|FNR|FS|IGNORECASE|NF|NR|OFMT|OFS|ORS|RS|RT|RSTART|RLENGTH|SUBSEP)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'keywords 2',
                                                'regex'      => '\\b(if|while|do|for|in|break|continue|delete|exit|next|nextfile|function)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'library fns',
                                                'regex'      => '\\b(close|getline|print|printf|system|fflush|atan2|cos|exp|int|log|rand|sin|sqrt|srand|gensub|gsub|index|length|split|sprintf|sub|substr|tolower|toupper|systime|strftime)\\b',
                                                'starttag'   => '<font color="#a52a2a"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'braces and parens',
                                                'regex'      => '[\\[\\]\\{\\}\\(\\)]',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => '<< stuff',
                                                'regex'      => '<<\'([^\\n]*)\';.*?^\\2$',
                                                'starttag'   => '<i>',
                                                'endtag'     => '</i>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => '<< stuff',
                                                'regex'      => '<<([^\\n]*).*?^\\2$',
                                                'starttag'   => '<i>',
                                                'endtag'     => '</i>',
                                                'childregex' => []
                                              }
                                            ]
                           };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
$LANGUAGE{'c'}          = {
                            'filename'   => '\\.[ch]$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'comment',
                                                'regex'      => '/\\*.*?\\*/',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'string',
                                                'regex'      => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'preprocessor line',
                                                'regex'      => '^[ \\t]*#.*?$',
                                                'starttag'   => '<font color="#0000FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'string',
                                                                    'regex'      => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"',
                                                                    'starttag'   => '<font color="#008000">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => [
                                                                                      {
                                                                                        'name'       => 'esc character',
                                                                                        'regex'      => '\\\\.',
                                                                                        'starttag'   => '<font color="#77dd77">',
                                                                                        'endtag'     => '</font>',
                                                                                        'childregex' => []
                                                                                      }
                                                                                    ]
                                                                  },
                                                                  {
                                                                    'name'       => '<files>',
                                                                    'regex'      => '<.*?>',
                                                                    'starttag'   => '<font color="#008000">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'comment',
                                                                    'regex'      => '[^/]/\\*.*?\\*/',
                                                                    'starttag'   => '<font color="#444444">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'character constant',
                                                'regex'      => '\'(\\\\)?.\'',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'numeric constant',
                                                'regex'      => '\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f)?\\b',
                                                'starttag'   => '<font color="#FF0000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'storage keyword',
                                                'regex'      => '\\b(const|extern|auto|register|static|unsigned|signed|volatile|char|double|float|int|long|short|void|typedef|struct|union|enum)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'keyword',
                                                'regex'      => '\\b(return|goto|if|else|case|default|switch|break|continue|while|do|for|sizeof)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'braces',
                                                'regex'      => '[\\{\\}]',
                                                'starttag'   => '<font color="#4444FF"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'symbols',
                                                'regex'      => '([\\*\\-\\+=:;%&\\|<>\\(\\)\\[\\]!])',
                                                'starttag'   => '<font color="#4444FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              { 
                                                'name'       => 'identifiers',
                                                'regex'      => '([a-zA-Z_][a-zA-Z_0-9]*)',
                                                'starttag'   => '<font color="#993333">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              }
                                            ]
                          };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
$LANGUAGE{'c++'}        = {
                            'filename'   => '\\.(cc|hh|[iCH]|cxx)$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'comment',
                                                'regex'      => '/\\*.*?\\*/',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'cplus comment',
                                                'regex'      => '//.*?$',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'string',
                                                'regex'      => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'preprocessor line',
                                                'regex'      => '^[ \\t]*#.*?$',
                                                'starttag'   => '<font color="#0000FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'string',
                                                                    'regex'      => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"',
                                                                    'starttag'   => '<font color="#008000">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => [
                                                                                      {
                                                                                        'name'       => 'esc character',
                                                                                        'regex'      => '\\\\.',
                                                                                        'starttag'   => '<font color="#77dd77">',
                                                                                        'endtag'     => '</font>',
                                                                                        'childregex' => []
                                                                                      }
                                                                                    ]
                                                                  },
                                                                  {
                                                                    'name'       => '<files>',
                                                                    'regex'      => '<.*?>',
                                                                    'starttag'   => '<font color="#008000">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'comment',
                                                                    'regex'      => '[^/]/\\*.*?\\*/',
                                                                    'starttag'   => '<font color="#444444">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'cplus comment',
                                                                    'regex'      => '//.*?$',
                                                                    'starttag'   => '<font color="#444444">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'character constant',
                                                'regex'      => '\'(\\\\)?.\'',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'numeric constant',
                                                'regex'      => '\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f)?\\b',
                                                'starttag'   => '<font color="#FF0000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'storage keyword',
                                                'regex'      => '\\b(class|typename|typeid|template|friend|virtual|inline|explicit|operator|overload|public|private|protected|const|extern|auto|register|static|mutable|unsigned|signed|volatile|char|double|float|int|long|short|bool|wchar_t|void|typedef|struct|union|enum)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => [],
                                              },
                                              {
                                                'name'       => 'keyword',
                                                'regex'      => '\\b(new|delete|this|return|goto|if|else|case|default|switch|break|continue|while|do|for|catch|throw|sizeof|true|false|namespace|using|dynamic_cast|static_cast|reinterpret_cast)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'braces',
                                                'regex'      => '[\\{\\}]',
                                                'starttag'   => '<font color="#4444FF"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'symbols',
                                                'regex'      => '([\\*\\-\\+=:;%&\\|<>\\(\\)\\[\\]!])',
                                                'starttag'   => '<font color="#4444FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'identifiers',
                                                'regex'      => '([a-zA-Z_][a-zA-Z_0-9]*)',
                                                'starttag'   => '<font color="#993333">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              }
                                            ]
                          };
$LANGUAGE{'cc'}         = $LANGUAGE{'c++'};
$LANGUAGE{'cpp'}        = $LANGUAGE{'c++'};
$LANGUAGE{'cxx'}        = $LANGUAGE{'c++'};















$LANGUAGE{'groff'}      = {
                            'filename'   => '\\.groff$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'comment',
                                                'regex'      => '\\\\".*?$',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              }
                                            ]
                          };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
$LANGUAGE{'html'}       = {
                            'filename'   => '\\.html?$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'comment',
                                                'regex'      => '<!--.*?-->',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'entity',
                                                'regex'      => '\\&[-.a-zA-Z0-9#]*;?',
                                                'starttag'   => '<font color="#FF0000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'tag',
                                                'regex'      => '<(/|!)?[-.a-zA-Z0-9]*.*?>',
                                                'starttag'   => '<font color="#993333">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'double quote string',
                                                                    'regex'      => '".*?"',
                                                                    'starttag'   => '<font color="#008000">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'single quote string',
                                                                    'regex'      => '\'.*?\'',
                                                                    'starttag'   => '<font color="#008000">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'brackets',
                                                                    'regex'      => '[<>]',
                                                                    'starttag'   => '<font color="#0000aa"><strong>',
                                                                    'endtag'     => '</strong></font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'attribute',
                                                                    'regex'      => '[^\'"]+?',
                                                                    'starttag'   => '<font color="#0000ff">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              }
                                            ]
                       };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
$LANGUAGE{'java'}       = {
                            'filename'   => '\\.java$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'doc comment',
                                                'regex'      => '/\\*\\*.*?\\*/',
                                                'starttag'   => '<font color="#444444"><i>',
                                                'endtag'     => '</i></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'comment',
                                                'regex'      => '/\\*.*?\\*/',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'cplus comment',
                                                'regex'      => '//.*?$',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'string',
                                                'regex'      => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'single quoted',
                                                'regex'      => '\'\'|\'\\\\\\\\\'|\'[^\'\\\\]\'|\'[^\'].*?[^\\\\]\'',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'numeric constant',
                                                'regex'      => '\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f)?\\b',
                                                'starttag'   => '<font color="#FF0000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'include',
                                                'regex'      => '\\b(import|package)\\b.*?$',
                                                'starttag'   => '<font color="#0000FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\(.|\\n)',
                                                                    'starttag'   => '<font color="#3333FF">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'comment',
                                                                    'regex'      => '[^/]/\\*.*?\\*/',
                                                                    'starttag'   => '<font color="#444444">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'storage keyword',
                                                'regex'      => '\\b(abstract|boolean|byte|char|class|double|extends|final|float|int|interface|long|native|private|protected|public|short|static|transient|synchronized|void|volatile|implements)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'keyword',
                                                'regex'      => '\\b(break|case|catch|continue|default|do|else|false|finally|for|if|instanceof|new|null|return|super|switch|this|throw|throws|true|try|while)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'braces and parens',
                                                'regex'      => '[\\{\\}\\(\\)\\[\\]]',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Identifiers',
                                                'regex'      => '\\b[a-zA-Z_][a-zA-Z0-9_]*\\b',
                                                'starttag'   => '<font color="#800000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'symbols',
                                                'regex'      => '([\\*\\-\\+=:;%&\\|<>!])',
                                                'starttag'   => '<font color="#4444FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              }
                                            ]
                          };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
$LANGUAGE{'javascript'} = {
                            'filename'   => '\\.js$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'comment',
                                                'regex'      => '/\\*.*?\\*/',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'cplus comment',
                                                'regex'      => '//.*?$',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'numeric constant',
                                                'regex'      => '\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f)?\\b',
                                                'starttag'   => '<font color="#FF0000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'events',
                                                'regex'      => '\\b(onAbort|onBlur|onClick|onChange|onDblClick|onDragDrop|onError|onFocus|onKeyDown|onKeyPress|onLoad|onMouseDown|onMouseMove|onMouseOut|onMouseOver|onMouseUp|onMove|onResize|onSelect|onSubmit|onUnload)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'braces',
                                                'regex'      => '[\\{\\}]',
                                                'starttag'   => '<font color="#4444FF"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'statements',
                                                'regex'      => '\\b(break|continue|else|for|if|in|new|return|this|typeof|var|while|with)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'function',
                                                'regex'      => 'function[\\t ]+([a-zA-Z0-9_]+)[\\t \\(]+.*?[\\n{]',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'function args',
                                                                    'regex'      => '\\(.*?\\)',
                                                                    'starttag'   => '<font color="#2040a0">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'function name',
                                                                    'regex'      => '[\\t ][a-zA-Z0-9_]+',
                                                                    'starttag'   => '<font color="#a52a2a">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },  
                                              {
                                                'name'       => 'built in object type',
                                                'regex'      => '\\b(anchor|Applet|Area|Array|button|checkbox|Date|document|elements|FileUpload|form|frame|Function|hidden|history|Image|link|location|Math|navigator|Option|password|Plugin|radio|reset|select|string|submit|text|textarea|window)\\b',
                                                'starttag'   => '<font color="#a52a2a"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'string',
                                                'regex'      => '".*?("|$)',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'colors',
                                                                    'regex'      => '(aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|#008000|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|#[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9])',
                                                                    'starttag'   => '<font color="#4682B4">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'string',
                                                'regex'      => '\'.*?(\'|$)',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'colors',
                                                                    'regex'      => '(aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|#008000|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|#[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9])',
                                                                    'starttag'   => '<font color="#4682B4">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => [],
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'event capturing',
                                                'regex'      => '\\b(captureEvents|releaseEvents|routeEvent|handleEvent)\\b.*?(\\)|$)',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'predefined methods',
                                                'regex'      => '\\b(abs|acos|alert|anchor|asin|atan|atan2|back|big|blink|blur|bold|ceil|charAt|clear|clearTimeout|click|close|confirm|cos|escape|eval|exp|fixed|floor|focus|fontcolor|fontsize|forward|getDate|getDay|getHours|getMinutes|getMonth|getSeconds|getTime|getTimezoneOffset|getYear|go|indexOf|isNaN|italics|javaEnabled|join|lastIndexOf|link|log|max|min|open|parse|parseFloat|parseInt|pow|prompt|random|reload|replace|reset|reverse|round|scroll|select|setDate|setHours|setMinutes|setMonth|setSeconds|setTimeout|setTime|setYear|sin|small|sort|split|sqrt|strike|sub|submit|substring|sup|taint|tan|toGMTString|toLocaleString|toLowerCase|toString|toUpperCase|unescape|untaint|UTC|write|writeln)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'properties',
                                                'regex'      => '\\b(action|alinkColor|anchors|appCodeName|appName|appVersion|bgColor|border|checked|complete|cookie|defaultChecked|defaultSelected|defaultStatus|defaultValue|description|E|elements|enabledPlugin|encoding|fgColor|filename|forms|frames|hash|height|host|hostname|href|hspace|index|lastModified|length|linkColor|links|LN2|LN10|LOG2E|LOG10E|lowsrc|method|name|opener|options|parent|pathname|PI|port|protocol|prototype|referrer|search|selected|selectedIndex|self|SQRT1_2|SQRT2|src|status|target|text|title|top|type|URL|userAgent|value|vlinkColor|vspace|width|window)\\b',
                                                'starttag'   => '<font color="#a52a2a"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'operators',
                                                'regex'      => '([=;->/&|])',
                                                'starttag'   => '<font color="#4444FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              }
                                            ]
                          };
$LANGUAGE{'js'}         = $LANGUAGE{'javascript'};















$LANGUAGE{'m4'}         = {
                            'filename'   => '\\.m4$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns' => [
                                            {
                                              'regex'      => 'dnl.*?$',
                                              'starttag'   => '<font color="#444444">',
                                              'endtag'     => '</font>',
                                              'childregex' => []
                                            },
                                            {
                                              'regex'      => '#.*?$',
                                              'starttag'   => '<font color="#444444"><i>',
                                              'endtag'     => '</i></font>',
                                              'childregex' => []
                                            },
                                            {
                                              'regex'      => '\\b(define|undefine|defn|pushdef|popdef|indir|builtin|changequote|changecom|changeword|m4wrap|m4exit|include|sinclude|divert|undivert|divnum|cleardiv|shift|dumpdef|traceon|traceoff|debugfile|debugmode|len|index|regexp|substr|translit|patsubst|format|incr|decr|syscmd|esyscmd|sysval|maketemp|errprint)\\b',
                                              'starttag'   => '<strong>',
                                              'endtag'     => '</strong>',
                                              'childregex' => []
                                            },
                                            {
                                              'regex'      => '\\b(ifdef|ifelse|loops)\\b',
                                              'starttag'   => '<strong>',
                                              'endtag'     => '</strong>',
                                              'childregex' => [
                                                                {
                                                                  'regex'      => '[$]\\$?({[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?',
                                                                  'starttag'   => '<font color="2040a0">',
                                                                  'endtag'     => '</font>',
                                                                  'childregex' => []
                                                                }
                                                              ]
                                            }
                                          ]
                          };















$LANGUAGE{'make'}       = {
                            'filename'   => '[Mm]akefile.*',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'Comment',
                                                'regex'      => '#.*?$',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Assignment',
                                                'regex'      => '^( *| [ \\t]*)[A-Za-z0-9_+]*[ \\t]*(\\+|:)?=',
                                                'starttag'   => '<font color="#2040a0">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Dependency Line',
                                                'regex'      => '^ *([A-Za-z0-9./$(){} _%+-]|\\n)*::?',
                                                'starttag'   => '<font color="#8b2252">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'Dependency Target',
                                                                    'regex'      => '[A-Za-z0-9./$(){} _%+-]+',
                                                                    'starttag'   => '<strong>',
                                                                    'endtag'     => '</strong>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'Dependency Continuation',
                                                                    'regex'      => '\\\\\\n',
                                                                    'starttag'   => '><strong>',
                                                                    'endtag'     => '</strong></font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'comment',
                                                                    'regex'      => '#.*?$',
                                                                    'starttag'   => '<font color="#444444">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'macro',
                                                                    'regex'      => '\\$([A-Za-z0-9_]|\\([^)]*\\)|{[^}]*})',
                                                                    'starttag'   => '<font color="#2040a0">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'int macro',
                                                                    'regex'      => '\\$([<@*?%]|\\$@)',
                                                                    'starttag'   => '<font color="#4080ff">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'Continuation',
                                                'regex'      => '\\\\$',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Macro',
                                                'regex'      => '\\$([A-Za-z0-9_]|\\([^)]*\\)|{[^}]*})',
                                                'starttag'   => '<font color="#2040a0">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Internal Macro',
                                                'regex'      => '\\$([<@*?%]|\\$@)',
                                                'starttag'   => '<font color="#4080FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Escaped $$$',
                                                'regex'      => '\\$\\$',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'Include',
                                                'regex'      => '^include[ \\t]',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              }
                                            ]
                          };
$LANGUAGE{'makefile'} = $LANGUAGE{'make'};















$LANGUAGE{'pas'}        = {
                            'filename'   => '\\.p(as)?$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'comment1 (*    *)',
                                                'regex'      => '\\(\\*.*?\\*\\)',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'comment2 {    }',
                                                'regex'      => '\\{.*?\\}',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'string',
                                                'regex'      => '\'.*?(\'|$)',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'preprocessor line',
                                                'regex'      => '^[ \\t]*#.*?$',
                                                'starttag'   => '<font color="#0000FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'comment1 (*    *)',
                                                                    'regex'      => '\\(\\*.*?\\*\\)',
                                                                    'starttag'   => '<font color="#444444">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'comment2 {    }',
                                                                    'regex'      => '\\{.*?\\}',
                                                                    'starttag'   => '<font color="#444444">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'character constant',
                                                'regex'      => '\'.\'',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'numeric constant',
                                                'regex'      => '\\b((0(x|X)[0-9a-fA-F]*)|[0-9.]+((e|E)(\\+|-)?)?[0-9]*)(L|l|UL|ul|u|U|F|f)?\\b',
                                                'starttag'   => '<font color="#FF0000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'storage and ops',
                                                'regex'      => '\\b(?i)(and|array|const|div|export|file|function|import|in|label|mod|module|nil|not|only|or|packed|pow|pragma|procedure|program|protected|qualified|record|restricted|set|type|var)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'keywords',
                                                'regex'      => '\\b(?i)(begin|case|do|downto|else|end|for|goto|if|of|otherwise|repeat|then|to|until|while|with)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'sumbols',
                                                'regex'      => '([\\*\\-\\+=:;<>\\(\\)\\[\\]!]|[^/]/[^/])',
                                                'starttag'   => '<font color="#4444FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'identifiers',
                                                'regex'      => '([a-zA-Z_][a-zA-Z_0-9.^]*[a-zA-Z_0-9]|[a-zA-Z_][a-zA-Z_0-9]*)',
                                                'starttag'   => '<font color="#993333">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'regex'      => '(\\.|\\^)+',
                                                                    'starttag'   => '<font color="#4444FF">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              }
                                            ],
                          };
$LANGUAGE{'pascal'}     = $LANGUAGE{'pas'};

 
 
 
 
 
 
 
 
 
 
 
 
 
 
$LANGUAGE{'perl'}       = {
                            'filename'   => '\\.p([lm5]|od)$',
                            'regex'      => '^\\s*#\\s*![^\\s]*perl',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'comment',
                                                'regex'      => '(?:#.*?(?:\r?\n\s*)+)+',
                                                'starttag'   => '<font color="#444444">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'variables',
                                                'regex'      => '[\\$@%]\\$?(?:{[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?',
                                                'starttag'   => '<font color="2040a0">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => '"" string',
                                                'regex'      => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'variables',
                                                                    'regex'      => '[\\$@%]\\$?(?:{[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?',
                                                                    'starttag'   => '<font color="2040a0">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => '\'\' string',
                                                'regex'      => '\'\'|\'\\\\\\\\\'|\'[^\'\\\\]\'|\'[^\'].*?[^\\\\]\'',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'more strings - q// qw//',
                                                'regex'      => '(?:\\b| )(?:q|qw)(\\W)(?:\\\\\\2|[^\\2\\n])*\\2',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'more strings - qq// qx//',
                                                'regex'      => '(?:\\b| )(?:qq|qx)(\\W)(?:\\\\\\2|[^\\2\\n])*\\2',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'starttag'   => '<font color="#77dd77">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'variables',
                                                                    'regex'      => '[\\$@%]\\$?(?:{[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?',
                                                                    'starttag'   => '<font color="2040a0">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'subroutine header',
                                                'regex'      => 'sub[\\t ]+(?:[a-zA-Z0-9_]+)[\\t \\n]*(?:\\{|\\n)',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'subroutine header coloring',
                                                                    'regex'      => '[\\t ][a-zA-Z0-9_]+',
                                                                    'starttag'   => '<font color="#ff0000">',
                                                                    'endtag'     => '</font>',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'regex matching I',
                                                'regex'      => '(?:\\b| )?(?:/(?:\\\\/|[^/\\n])*(?:/[gimsox]*)|s(\\W)(?:\\\\\\2|[^\\2\\n])*?(\\2)[^(\\2)\\n]*?(\\2[gimsox]*))',
                                                'starttag'   => '<font color="#b000d0">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'regex matching II',
                                                'regex'      => '(?:\\b| )(?:m|qq?|tr|y)(\\W)(?:\\\\\\2|[^\\2\\n])*(?:\\2[gimsox]*)',
                                                'starttag'   => '<font color="#b000d0">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'keywords',
                                                'regex'      => '\\b(my|local|new|if|until|while|elsif|else|eval|unless|for|foreach|continue|exit|die|last|goto|next|redo|return|local|exec|do|use|require|package|eval|BEGIN|END|eq|ne|not|\\|\\||\\&\\&|and|or)\\b',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'library functions',
                                                'regex'      => '\\b(?:a(?:bs|ccept|larm|tan2)|b(?:ind|inmode|less)|c(?:aller|hdir|hmod|homp|hop|hr|hroot|hown|losedir|lose|onnect|os|rypt)|d(?:bmclose|bmopen|efined|elete|ie|ump)|e(?:ach|nd(?:grent|hostent|netent|protoent|pwent|servent)|of|xec|xists|xp)|f(?:ctnl|ileno|lock|ork|ormat|ormline)|g(?:et(?:c|grent|grgid|grnam|hostbyaddr|hostbyname|hostent|login|netbyaddr|netbyname|netent|peername|pgrp|ppid|priority|protobyname|protobynumber|protoent|pwent|pwnam|pwuid|servbyname|servbyport|servent|sockname|sockopt)|lob|mtime|rep)|hex|i(?:mport|ndex|nt|octl)|join|keys|kill|l(?:cfirst|c|ength|ink|isten|og|ocaltime|stat)|m(?:ap|kdir|sgctl|sgget|sgrcv)|no|o(?:ct|pendir|pen|rd)|p(?:ack|ipe|op|os|rintf|rint|ush)|quotemeta|r(?:and|eaddir|ead|eadlink|ecv|ef|ename|eset|everse|ewinddir|index|mdir)|s(?:calar|eekdir|eek|elect|emctl|emget|emop|end|et(?:grent|hostent|netent|pgrp|priority|protoent|pwent|sockopt)|hift|hmctl|hmget|hmread|hmwrite|hutdown|in|leep|ocket|ocketpair|ort|plice|plit|printf|qrt|rand|tat|tudy|ubstr|ymlink|yscall|ysopen|ysread|ystem|yswrite)|t(?:elldir|ell|ie|ied|ime|imes|runcate)|u(?:c|cfirst|mask|ndef|nlink|npack|nshift|ntie|time)|values|vec|w(?:ait|aitpid|antarray|arn|rite)|qw|-[rwxoRWXOezsfdlpSbctugkTBMAC])\\b',
                                                'starttag'   => '<font color="a52a2a"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'braces, parens and brakets',
                                                'regex'      => '[\\[\\]\\{\\}\\(\\)]',
                                                'starttag'   => '<strong>',
                                                'endtag'     => '</strong>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => '<< stuff',
                                                'regex'      => '<<(?:("|\')([^\\n]*)\\2|\\w*).*?^\\3$',
                                                'starttag'   => '<i>',
                                                'endtag'     => '</i>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'POD',
                                                'regex'      => '^=.*?^(?:=cut|\\Z)',
                                                'starttag'   => '<i>',
                                                'endtag'     => '</i>',
                                                'childregex' => []
                                              }
                                            ]
                          };
 














$LANGUAGE{'sql'}        = {
                            'filename'   => '\\.sql$',
                            'regex'      => '',
                            'bgcolor'    => '#FFFFFF',
                            'textcolor'  => '#000000',
                            'patterns'   => [
                                              {
                                                'name'       => 'keywords I',
                                                'regex'      => '(?i)(,|%|<|>|:=|=|\\(|\\)|\\bselect|on|from|order by|desc|where|and|or|not|null|true|false)\\b',
                                                'starttag'   => '<font color="#0000FF"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'comment I',
                                                'regex'      => '--.*?$',
                                                'starttag'   => '<font color="#444444"><i>',
                                                'endtag'     => '</i></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'comment II',
                                                'regex'      => '/\\*.*?\\*/',
                                                'starttag'   => '<font color="#444444"><i>',
                                                'endtag'     => '</i></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'string',
                                                'regex'      => '(\'\'|\'[^\'\\\\]\'|\'[^\'].*?[^\\\\]\')',
                                                'starttag'   => '<font color="#008000">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'keywords II',
                                                'regex'      => '(?i)end if;|\\b(create|replace|begin|end|function|return|fetch|open|close|into|is|in|when|others|grant|on|to|exception|show|set|out|pragma|as|package)\\b',
                                                'starttag'   => '<font color="#0000FF"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'keywords III',
                                                'regex'      => '(?i)\\balter\\b',
                                                'starttag'   => '<font color="#0000FF"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'datatypes',
                                                'regex'      => '(?i)\\b(integer|blol|date|numeric|character|varying|varchar|char)\\b',
                                                'starttag'   => '<font color="#8800FF">',
                                                'endtag'     => '</font>',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'words',
                                                'regex'      => '(?i)\\b(constraint|key|references|primary|table|foreign|add|insert|group by)\\b',
                                                'starttag'   => '<font color="#0000FF"><strong>',
                                                'endtag'     => '</strong></font>',
                                                'childregex' => []
                                              }
                                            ]
                            };
   
 


return \%LANGUAGE;

};