#!/usr/bin/perl -w ###################################################################### # # # Code2HTML # # --------- # # # # Code2Html, version 0.8.3, Aug 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. # # 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 who does the support # # of NEdit. # # # ###################################################################### # # # HISTORY # # # # 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 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 patched a typo that # # made the html footer even printed if noheader was spezified. # # * new option -T=s, --title=s; suggested by Harald Fielker # # as well as Barrie Slaymaker # # . # # * significantly reduced memory usage # # * Barrie Slaymaker 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 updated the documentation. # # # # 0.8.0 - AUGUST 1999 # # * Joor Loohuis 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 # # * Joel Andersson 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 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 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 pointed me to the qq, qx, # # etc operators in perl. They should now no longer cause problems # # * Wayne Roberts # # 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 # # ) # # * if a language mode cannot be found the error message now tells # # you which lang you requested. # # * new --fallback option. This language mode is used if the # # given mode by parameter #1 is not available. This feature was # # requested by Barrie Slaymaker # # * 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 # # * linking to line numbers now works from the command line too # # # # 0.6.3 - May 1999 # # * fixed C character constant regex. TNX to Jesse # # # # * 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 for the hint. # # * new: --no_header does not print the ... 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 .. # # * 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 (lang_mode 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 and 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> : many hints & suggestions # # some patches to improve speed # # # # if you feel your name should be here too, mail me! # # errare humanum est! # # # ###################################################################### use strict; use Getopt::Long; # 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 use Pod::Text; 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; my $vernr = "0.8.3"; my $monthshort = "Aug"; my $monthlong = "August"; 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 --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: --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 [file] 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. 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 --linenumbers etc. work. --help, --version and --dump_default_lang work too however it is not very intelligent to use them :). --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 -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. =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 B<$CODE2HTML_CONFIG>, seperated by colons =item * F<$HOME/.code2html.config> =item * F</etc/code2html.config> =item * built in default languages =back These databases will be searched in that order for the set of regular expressions specified by the language_mode parameter. The first set of regular expression which is found will be taken. The files must have the following structure: =over 4 =item Empty lines are ignored. =item Every line beginning with a pound sign (#) is a comment. Note that a line actually must start with this character (apart from tabs and spaces) in order to be a comment. =item A language starts with the name of it's section in brackets. Aliases may be defined withing the same brackets seperated by a comma (,). Examples: [c] [c++,cpp,cc] =item Then the default background and text colours may be set. If not defined they default to #ffffff (white) for the background and #000000 (black) for the text. bgcolor=#ffffff textcolor=#000000 =item Spaces and Tabs before and after the equals-sign (=) are allowed. The first non whitespace after the = sign until the end of line will then be copied to the bgcolor and the text options in the HTMLs body tag. =item Next, language recognition criteria can be specified, in the form of a regular expression that is applied to either the name of the file that is to be processed, or the content of the file. These are identified by field names 'filename' and 'regex'. Any amount of recognition criteria can be specified, and will be applied in order of appearance. For example: filename=\.pl$ filename=\.pm$ filename=\.p5$ regex=^\s*#\s*![^\s]*perl =item As a third step the regular expressions must be defined: A line defining this consist of three parts: The html tag to insert at the start of the pattern's occurance, one to insert at the end and the pattern itself. All three parts must be enclosed in double quotes(\") and are seperated by commas (,). If one of those parts contains a double quote, this must be escaped with a backshlash (\\). Example: \"<i>\", \"</i>\", \"\\\".*?\\\"\" This line prints all strings enclosed by double quotes italic. =item If a line starts with a minus (-) then this pattern is applied to the matched part of the previos line that had no minus in front. So you can highlight for example escape characters in strings. - \"<strong>\", \"</strong>\", \"\\\\.\" =back 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 If the input file contains all 256 possible characters then all character values of 255 will be changed to values of 254. I don't think this is a problem and so I will not try to find a other way to code this stuff. If however this is a problem for you, let me know and I will rethink my strategy. 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. =head1 LICENSE Copyright (c) 1999 by Peter Palfrader. 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: =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 been taken from NEdit and were then slightly modified by me. 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 #' work around xemacs 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; 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 %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()}; my $hidechar = ""; # a character that must not exist in the code and which is used as a placeholder will be set in $code; my $bgcolor = "#ffffff"; #default value only. will be set in parse_config_part my $textcolor = "#000000"; #default value only. will be set in parse_config_part my @CONFIG_FILES; push @CONFIG_FILES, split(/:/,$params{'langfile'}) if defined($params{'langfile'}); push @CONFIG_FILES, split(/:/,$ENV{'CODE2HTML_CONFIG'}) if ($ENV{'CODE2HTML_CONFIG'}); push @CONFIG_FILES, $ENV{'HOME'}."/.code2html.config" if (defined($ENV{'HOME'})); push @CONFIG_FILES, "/etc/code2html.config"; my $code_ref; if ((!defined($params{'modes'})) || (!$params{'modes'})) { print STDERR "loading input file...\n" if ($params{'verbose'}); $code_ref = &get_input_file(\%params, \@CONFIG_FILES ,$hidechar, $params{'langmode'}, $params{'alt_langmode'}); }; print STDERR "parsing config file...\n" if ($params{'verbose'}); my $regexps_ref = &parse_config_part( &get_config_file(\@CONFIG_FILES, \%params) , $bgcolor, $textcolor); print STDERR "finding all matches, inserting placeholders, creating taglist...\n" if ($params{'verbose'}); my $taglist_ref = &create_taglist($regexps_ref, $code_ref, $hidechar); print STDERR "converting source code to HTML...\n" if ($params{'verbose'}); convert_code_2_html($code_ref); print STDERR "replacing placeholders with appropriate HTML tags...\n" if ($params{'verbose'}); &insert_tags($taglist_ref, $code_ref, $hidechar); print STDERR "outputting file...\n" if ($params{'verbose'}); &put_output(\%params, $code_ref, $bgcolor, $textcolor); return $ {$code_ref}; } sub patch_html { my %params = %{shift()}; my $code; open(FILEHANDLE, $params{'infile'}) || die("While opening '$params{'infile'}' for input: ".$!."\n"); undef $/; $code = <FILEHANDLE>; 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; 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{'infile'}) || die("While opening '$params{'infile'}' 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 ($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 furhter help\n"; exit 1; }; if ($help) { print $IN_POD = 1; 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'} = '-' }; $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; }; ################################################################################ ####################### guess_lang ############################################# ################################################################################ sub guess_lang { #in: @config file #in: filename #in: start of file #out langmode my @lines = @{shift()}; my ($filename, $code) = @_; my $langmode; my $current_langmode = ''; for (@lines) { $_ =~ s/\n|\r//g; $_ =~ s/^[ \t]*(.*)[ \t]*/$1/; #remove beginning and trailing spaces / tabs if ($_ =~ m/^\[(.*?)[, \]]/i) { $current_langmode=$1; next; }; if ($_ =~ s/^filename[ \t]*=[ \t]*(.*?)[ \t]*$//i) { if ($filename =~ /$1/) { $langmode=$current_langmode; last; }; }; if ($_ =~ s/^regex[ \t]*=[ \t]*(.*?)[ \t]*$//i) { if ($code =~ /$1/) { $langmode=$current_langmode; last; }; }; }; return $langmode; }; ################################################################################ ####################### get_input_file ######################################### ################################################################################ sub get_input_file { # in : \%params # in : \@config_files # out : hidechar # in/out : $langmode; # in/out : $alt_langmode; # returns: input file my %PARAMS = %{$_[0]}; my @CONFIG_FILES = @{$_[1]}; my $langmode = $_[3]; my $alt_langmode = $_[4]; my $code; my $hidechar = ""; 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"); undef $/; $code = <FILEHANDLE>; close(FILEHANDLE); }; if ($PARAMS{'replacetabs'} != 0) { my @lines = split(/\n/, $code); for (@lines) { $_ = &checkTabulator($_, $PARAMS{'replacetabs'}); }; $code = join("\n", @lines); }; #find a character that does not exist in $code foreach $a (0..255) { my $n = quotemeta(chr($a)); if (!($code =~ s/$n/$n/g)) { $hidechar = chr($a); last; }; }; if ($hidechar eq "") # if no character - which does not exist in $code - was found then be brute { $code =~ s/\xff/\xfe/g; $hidechar = "\xff"; } if ((!defined($langmode)) || ($langmode eq '')) { my $test_code = substr($code, 0, $LANG_TEST_LENGTH); warn("language mode not given. guessing...\n"); my $result=''; for (@CONFIG_FILES) { open(FILEHANDLE, "<$_") || next; my @lines = <FILEHANDLE>; $result = &guess_lang(\@lines, $PARAMS{'infile'}, $test_code); close FILEHANDLE; if ($result ne "") {last;}; }; if ($result eq "") { my @lines = split(/\n/,&get_default_database); $result = &guess_lang(\@lines, $PARAMS{'infile'}, $test_code); }; if ($result 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 { $langmode = $result; warn("using '$result'\n"); }; }; $_[2] = $hidechar; $_[3] = $langmode; $_[4] = $alt_langmode; return \$code; }; ################################################################################ ####################### get_config_lines ####################################### ################################################################################ sub get_config_lines { #in : \@lines #in : metaquoted $langmode #in : $modes #returns config file as string my @lines = @{shift()}; my ($lm, $modes) = @_; my $result = ""; if ($modes) { for (@lines) { $_ =~ s/\n|\r//g; $_ =~ s/^[ \t]*(.*)[ \t]*/$1/; #remove beginning and trailing spaces / tabs print " ".$_."\n" if (substr($_,0,1) eq "["); } } else { my $waiting = 1; for (@lines) { if ($waiting) { $_ =~ s/\n|\r//g; $_ =~ s/^[ \t]*(.*)[ \t]*/$1/; #remove beginning and trailing spaces / tabs if ($_ =~ m/^\[(.*?[, ])?$lm([, ].*?)?\]/i) {$waiting = 0;}; } else { $_ =~ s/\n|\r//g; $_ =~ s/^[ \t]*(.*)[ \t]*/$1/; #remove beginning and trailing spaces / tabs last if (substr($_,0,1) eq "["); #new language mode if (($_ ne "")&&(substr($_, 0, 1) ne "#")) { $_ =~ /^(.*)$/; # untaint input $result .= $1."\n"; } } }; }; return $result; }; ################################################################################ ####################### get_one_config_file #################################### ################################################################################ sub get_one_config_file { #in: filename #in: langmode already meta quoted. #in: modes; #returns config file as string my ($filename, $langmode, $modes) = @_; open(FILEHANDLE, "<$filename") || return ""; my @lines = <FILEHANDLE>; my $result = get_config_lines(\@lines, $langmode, $modes); close FILEHANDLE; return $result; }; ################################################################################ ####################### get_config_file ######################################## ################################################################################ sub get_config_file { #in : @config_files #in : %params #returns config file as string my @CONFIG_FILES = @{shift()}; my %PARAMS = %{shift()}; #Apply language mode my $result = ""; if ($PARAMS{'modes'}) { print "\n\nDefined language modes:\n"; print "-----------------------\n"; print "(You may use any of the names seperated\n"; print "by commas to refer to a certain mode.)\n\n"; }; for (@CONFIG_FILES) { print "in file $_:\n" if $PARAMS{'modes'}; $result = &get_one_config_file($_, quotemeta($PARAMS{'langmode'}), $PARAMS{'modes'}); if ($result ne "") {last;}; }; if ($result eq "") { print "in default database:\n" if $PARAMS{'modes'}; my @lines = split(/\n/,&get_default_database); $result = &get_config_lines(\@lines, quotemeta($PARAMS{'langmode'}), $PARAMS{'modes'}); } if ($PARAMS{'modes'}) { print "-----------------------\n"; print "That's it\n\n\n"; exit; }; if ($result eq "") { if ($PARAMS{'alt_langmode'} ne "") { warn("Given language mode '".$PARAMS{'langmode'}."' was not found in config files. Falling back to '".$PARAMS{'alt_langmode'}."'.\n"); $PARAMS{'langmode' } = $PARAMS{'alt_langmode'}; $PARAMS{'alt_langmode'} = ""; $result = get_config_file(\@CONFIG_FILES, \%PARAMS); } else { die("Given language mode '".$PARAMS{'langmode'}."' was not found in config files.\n"); }; } return $result; }; ################################################################################ ####################### parse_config_part ###################################### ################################################################################ sub parse_config_part { #in: string: config data #in: string: bgcolor #in: string: textcolor #returns \@regexps my ($configdata, $bgcolor, $textcolor) = @_; my @regexps = (); my @null_array; while ($configdata =~ /(^[^\-].*?$)/gms) # ) { my $us = $1; my $after = substr($configdata, pos($configdata)); if ($us =~ /^"/) #";# xemacs :) { my %t = (); my $tmp = ""; my $child_ref = \@null_array; $us =~ s/([ \t]*("([^"]|\\")*")[ \t]*,)//m; $tmp = $1; $tmp =~ m/("(.*[^\\])?")/; $tmp = $1; $tmp =~ s/"(.*)"/$1/g; $tmp =~ s/\\"/"/g; $t{"html1"} = $tmp; $us =~ s/([ \t]*("([^"]|\\")*")[ \t]*,)//m; $tmp = $1; $tmp =~ m/("(.*[^\\])?")/; $tmp = $1; $tmp =~ s/"(.*)"/$1/g; $tmp =~ s/\\"/"/g; $t{"html2"} = $tmp; $us =~ s/([ \t]*("([^"]|\\")*")[ \t]*$)//m; $tmp = $1; $tmp =~ m/("(.*[^\\])?")/; $tmp = $1; $tmp =~ s/"(.*)"/$1/g; $tmp =~ s/\\"/"/g; $t{"regex"} = $tmp; my $old_die = $SIG{__DIE__}; $SIG{'__DIE__'} = sub{ $SIG{'__DIE__'} = $old_die; my $error = $_[0]; $error =~ s/ at \(eval.*?\) line .*?\./\./; die('The following error occured in this regular expression: '.$error. 'Check your language configuration file!'."\n"); }; eval ('my $dummy = "HAllo"; $dummy =~ /$t{"regex"}/gms'); $SIG{'__DIE__'} = $old_die; if ($after =~ /(^\n\-.*?($|\n[^\-]))/s) { $tmp = $1; $tmp =~ s/^\n//; $tmp =~ s/\n.$//; $tmp =~ s/^-[ \t]*//mg; $child_ref = &parse_config_part($tmp."\n"); }; $t{"childregex"} = $child_ref; push @regexps, \%t; } else { if ($us =~ s/^bgcolor[ \t]*=[ \t]*//i) { $_[1] = $us; } elsif ($us =~ s/^textcolor[ \t]*=[ \t]*//i) { $_[2] = $us; } }; }; return \@regexps; }; ################################################################################ ####################### create_taglist ######################################### ################################################################################ sub create_taglist { # in: regexps_ref # in: code_ref # in : hidechar # returns: @taglist; my ($regexps_ref, $code_ref, $hidechar) = @_; my @taglist; if (!@{$regexps_ref}) {return \@taglist}; #if there are no regexps, then there are not hits. my $over_length = length($ {$code_ref})+1; my $index=0; my @regexps_occurence; for (@ {$regexps_ref}) { my %t; $t{"index"} = $index++; $t{"regex"} = $$_{"regex"}; $t{"html1"} = $$_{"html1"}; $t{"html2"} = $$_{"html2"}; pos($ {$code_ref}) = 0; if ($ {$code_ref} =~ /$t{"regex"}/gms) { $t{"first_occurence"} = pos($ {$code_ref}) - length($&) } else { $t{"first_occurence"} = $over_length; }; push @regexps_occurence, \%t; }; @regexps_occurence = sort { $$a{"first_occurence"} <=> $$b{"first_occurence"} || $$a{"index"} <=> $$b{"index"} } @regexps_occurence; while (${$regexps_occurence[0]}{"first_occurence"} < $over_length) { my %t; pos($ {$code_ref}) = ${$regexps_occurence[0]}{"first_occurence"} + scalar(@taglist); my $dummy = $ {$code_ref} =~ /$regexps_occurence[0]->{"regex"}/gms; my $match = $&; my $matchend = pos($ {$code_ref}); my $matchlength = length($match); my $delta_offset = 0; push @taglist, \$regexps_occurence[0]->{"html1"}; #push beginning html tag # my @m = @{ ${ %{$regexps_ref->[$regexps_occurence[0]->{"index"}]} }{"childregex"} }; # my @m = @{ $regexps_ref->[$regexps_occurence[0]->{"index"}]->{'childregex'} }; my @m = @{ ${ %{$regexps_ref->[$regexps_occurence[0]->{"index"}]} }{"childregex"} }; if (@m) { my $newtaglist_ref = &create_taglist( \@m, \$match, $hidechar); $delta_offset = scalar(@ {$newtaglist_ref}); push @taglist, @ {$newtaglist_ref}; }; $ {$code_ref} = join ('', substr($ {$code_ref}, 0, $matchend-$matchlength), $hidechar, $match, $hidechar, substr($ {$code_ref}, $matchend)); push @taglist, \$regexps_occurence[0]->{"html2"}; #push ending html tag for (@regexps_occurence) { if (${$_}{"first_occurence"} < $matchend+2+$delta_offset - scalar(@taglist)) { pos($ {$code_ref}) = $matchend+2+$delta_offset; if ($ {$code_ref} =~ /${$_}{"regex"}/gms) { ${$_}{"first_occurence"} = pos($ {$code_ref}) - length($&) - scalar(@taglist); } else { ${$_}{"first_occurence"} = $over_length; }; } else { last; } } @regexps_occurence = sort { $$a{"first_occurence"} <=> $$b{"first_occurence"} || $$a{"index"} <=> $$b{"index"} } @regexps_occurence; }; return \@taglist; }; ################################################################################ ####################### convert_code_2_html #################################### ################################################################################ sub convert_code_2_html { # in/out: code_ref $ {$_[0]} =~ s/&/&/g; $ {$_[0]} =~ s/>/>/g; $ {$_[0]} =~ s/</</g; $ {$_[0]} =~ s/"/"/g; # "# just because xemacs syntax highlighting messes things up }; ################################################################################ ####################### insert_tags ############################################ ################################################################################ sub insert_tags { my ($taglist_ref, $code_ref, $hidechar) = @_; my $i = 0; $ {$code_ref} =~ s{$hidechar}{ $ {$taglist_ref->[$i++]}; }ge; }; ################################################################################ ####################### put_output ############################################# ################################################################################ sub put_output { my %PARAMS = %{shift()}; my ($code_ref, $bgcolor, $textcolor) = @_; my $header = ''; $header .= "Content-Type: text/html;\n\n" if ($PARAMS{'content_type'}); $header .= "<html><head><title>". $PARAMS{'title'}. "
\n"          if (!$PARAMS{'noheader'});

      if ($PARAMS{'linenumbers'} eq 'link')
	{
	    my @lines = split(/\n/,$ {$code_ref});
	    my $lengthofnr = length(scalar(@lines));
	    my $prefix = ''; $prefix = $PARAMS{'line_number_prefix'}.'_' if defined $PARAMS{'line_number_prefix'};
	    
	    my $nr=1;
	    $ {$code_ref} = join(
			         '',
				 map {
				     sprintf( qq{%$lengthofnr$_\n}, $nr )
				 }
				 @lines
				 
			);
	}
      elsif ($PARAMS{'linenumbers'} eq 'yes')
	{
	    my @lines = split(/\n/,$ {$code_ref});
	    my $lengthofnr = length(scalar(@lines));
	    my $prefix = ''; $prefix = $PARAMS{'line_number_prefix'}.'_' if defined $PARAMS{'line_number_prefix'};
	    
	    my $nr=1;
	    $ {$code_ref} = join(
				 '',
				 map {
				     # /methinks ( " " x ( $lengthofnr - length( $nr ) ) ) is faster than sprintf( "%$lengthofnrs", $nr++ )
				     sprintf( qq{%$lengthofnr$_\n}, $nr )
				 }
				 @lines
				);
	};
     

      
      $ {$code_ref} .= "
\n" if (!$PARAMS{'noheader'}); if (defined($PARAMS{'outfile'})) { open (FILEHANDLE, '>'.$params{'outfile'}) || die("While opening '$params{'outfile'}' for output: ".$!."\n"); print FILEHANDLE join('', $header, $ {$code_ref}); close (FILEHANDLE); }; }; ################################################################################ ####################### get_default_database ################################### ################################################################################ sub get_default_database { # last evaluated value will be returned my $tmp = <<'EODB'; ###################################################################### ################################# Plain ############################## ###################################################################### [plain] bgcolor=#ffffff textcolor=#000000 ###################################################################### ################################# Ada 95 ############################# ###################################################################### [ada,ada95] bgcolor=#ffffff textcolor=#000000 filename=\.ada$ filename=\.ad$ filename=\.ads$ filename=\.adb$ filename=\.a$ #Comments "", "", "--.*?$" #String Literals "", "", "\".*?(\"|$)" #Character Literals "", "", "'.'" #Ada Attibutes "", "", "'[a-zA-Z][a-zA-Z_]+\b" #Numeric Literals "", "", "(((2|8|10|16)#[_0-9a-fA-F]*#)|[0-9.]+)" #Withs Pragmas Use "", "", "\b(([wW]ith|WITH|[pP]ragma|PRAGMA|[uU]se|USE)[ \t\n\f\r]+[a-zA-Z0-9_.]+;)+\b" #Predefined Types "", "", "\b([bB]oolean|BOOLEAN|[cC]haracter|CHARACTER|[cC]ount|COUNT|[dD]uration|DURATION|[fF]loat|FLOAT|[iI]nteger|INTEGER|[lL]ong_[fF]loat|LONG_FLOAT|[lL]ong_[iI]nteger|LONG_INTEGER|[pP]riority|PRIORITY|[sS]hort_[fF]loat|SHORT_FLOAT|[sS]hort_[iI]nteger|SHORT_INTEGER|[sS]tring|STRING)\b" #Predefined Subtypes "", "", "\b([fF]ield|FIELD|[nN]atural|NATURAL|[nN]umber_[bB]ase|NUMBER_BASE|[pP]ositive|POSITIVE|[pP]riority|PRIORITY)\b" #Reserved Words "", "", "\b([aA]bort|ABORT|[aA]bs|ABS|[aA]ccept|ACCEPT|[aA]ccess|ACCESS|[aA]nd|AND|[aA]rray|ARRAY|[aA][tT]|[bB]egin|BEGIN|[bB]ody|BODY|[cC]ase|CASE|[cC]onstant|CONSTANT|[dD]eclare|DECLARE|[dD]elay|DELAY|[dD]elta|DELTA|[dD]igits|DIGITS|[dD][oO]|[eE]lse|ELSE|[eE]lsif|ELSIF|[eE]nd|END|[eE]ntry|ENTRY|[eE]xception|EXCEPTION|[eE]xit|EXIT|[fF]or|FOR|[fF]unction|FUNCTION|[gG]eneric|GENERIC|[gG]oto|GOTO|[iI][fF]|[iI][nN]|[iI][sS]|[lL]imited|LIMITED|[lL]oop|LOOP|[mM]od|MOD|[nN]ew|NEW|[nN]ot|NOT|[nN]ull|NULL|[oO][fF]|[oO][rR]|[oO]thers|OTHERS|[oO]ut|OUT|[pP]ackage|PACKAGE|[pP]ragma|PRAGMA|[pP]rivate|PRIVATE|[pP]rocedure|PROCEDURE|[rR]aise|RAISE|[rR]ange|RANGE|[rR]ecord|RECORD|[rR]em|REM|[rR]enames|RENAMES|[rR]eturn|RETURN|[rR]everse|REVERSE|[sS]elect|SELECT|[sS]eparate|SEPARATE|[sS]ubtype|SUBTYPE|[tT]ask|TASK|[tT]erminate|TERMINATE|[tT]hen|THEN|[tT]ype|TYPE|[uU]se|USE|[wW]hen|WHEN|[wW]hile|WHILE|[wW]ith|WITH|[xX]or|XOR)\b" #Ada 95 Only "", "", "\b([aA]bstract|ABSTRACT|[tT]agged|TAGGED|[aA]ll|ALL|[pP]rotected|PROTECTED|[aA]liased|ALIASED|[rR]equeue|REQUEUE|[uU]ntil|UNTIL)\b" #Identifiers "", "", "\b[a-zA-Z][a-zA-Z0-9_]*\b" #Dot All "", "", "\.[aA][lL][lL]\b" ###################################################################### ################################# C ################################## ###################################################################### [c] bgcolor=#ffffff textcolor=#000000 filename=\.c$ filename=\.h$ #comment "", "", "/\*.*?\*/" #string "", "", "((\"\")|(\"\\\\\")|(\"[^\"\\]\")|(\"[^\"].*?[^\\]\"))" #esc character - "", "", "\\." #preprocessor line "", "", "^[ \t]*#.*?$" #string - "", "", "((\"\")|(\"\\\\\")|(\"[^\"\\]\")|(\"[^\"].*?[^\\]\"))" #esc character -- "", "", "\\." # - "", "", "<.*?>" #comment - "", "", "[^/]/\*.*?\*/" #character constant "", "", "'(\\)?.'" #esc character - "", "", "\\." #numeric constant "", "", "\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" #storage keyword "", "", "\b(const|extern|auto|register|static|unsigned|signed|volatile|char|double|float|int|long|short|void|typedef|struct|union|enum)\b" #keyword "", "", "\b(return|goto|if|else|case|default|switch|break|continue|while|do|for|sizeof)\b" #braces "", "", "[\{\}]" #symbols "", "", "([\*\-\+=:;%&\|<>\(\)\[\]!])" #identifiers "", "", "([a-zA-Z_][a-zA-Z_0-9]*)" ###################################################################### ################################# C ++ ############################### ###################################################################### [c++,cpp,cc] bgcolor=#ffffff textcolor=#000000 filename=\.cc$ filename=\.hh$ filename=\.C$ filename=\.H$ filename=\.i$ filename=\.cxx$ #comment "", "", "/\*.*?\*/" #cplus comment "", "", "//.*?$" #string "", "", "((\"\")|(\"\\\\\")|(\"[^\"\\]\")|(\"[^\"].*?[^\\]\"))" #esc character - "", "", "\\." #preprocessor line "", "", "^[ \t]*#.*?$" #string - "", "", "((\"\")|(\"[^\"\\]\")|(\"[^\"].*?[^\\]\"))" #esc character -- "", "", "\\." # - "", "", "<.*?>" #comment - "", "", "[^/]/\*.*?\*/" #cplus comment - "", "", "//.*?$" #character constant "", "", "'(\\)?.'" #esc character - "", "", "\\." #numeric constant "", "", "\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" #storage keyword "", "", "\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" #keyword "", "", "\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" #braces "", "", "[\{\}]" #symbols "", "", "([\*\-\+=:;%&\|<>\(\)\[\]!])" #identifiers "", "", "([a-zA-Z_][a-zA-Z_0-9]*)" ###################################################################### ################################# HTML ############################### ###################################################################### [html] bgcolor=#ffffff textcolor=#000000 filename=\.html?$ #comment "", "", "" #special chars "", "", "\&[-.a-zA-Z0-9#]*;?" #tag "", "", "<(/|!)?[-.a-zA-Z0-9]*.*?>" #double quote string - "", "", "\".*?\"" #single quote string - "", "", "'.*?'" #brackets - "", "", "[<>]" #attribute - "", "", "[^'\"]+?" ###################################################################### ################################# Java ############################### ###################################################################### [java] bgcolor=#ffffff textcolor=#000000 filename=\.java$ #doc comment "", "", "/\*\*.*?\*/" #comment "", "", "/\*.*?\*/" #cplus comment "", "", "//.*?$" #string "", "", "((\"\")|(\"\\\\\")|(\"[^\"\\]\")|(\"[^\"].*?[^\\]\"))" #esc character - "", "", "\\." #single quoted "", "", "'([^\\]|\\[^'])*?'" #numeric constant "", "", "\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" #include "", "", "\b(import|package)\b.*?$" #esc character - "", "", "\\(.|\n)" #comment - "", "", "[^/]/\*.*?\*/" #storage keyword "", "", "\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" #keyword "", "", "\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" #braces and parens "", "", "[\{\}\(\)\[\]]" #Identifiers "", "", "\b[a-zA-Z_][a-zA-Z0-9_]*\b" #symbols "", "", "([\*\-\+=:;%&\|<>!])" ###################################################################### ################################# JavaScript ######################### ###################################################################### [js,javascipt] bgcolor=#ffffff textcolor=#000000 filename=\.js$ #comment "", "", "/\*.*?\*/" #cplus comment "", "", "//.*?$" #numeric constant "", "", "\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" #events "", "", "\b(onAbort|onBlur|onClick|onChange|onDblClick|onDragDrop|onError|onFocus|onKeyDown|onKeyPress|onLoad|onMouseDown|onMouseMove|onMouseOut|onMouseOver|onMouseUp|onMove|onResize|onSelect|onSubmit|onUnload)\b" #braces "", "", "[\{\}]" #statements "", "", "\b(break|continue|else|for|if|in|new|return|this|typeof|var|while|with)\b" #function "", "", "function[\t ]+([a-zA-Z0-9_]+)[\t \(]+.*?[\n{]" #function args - "", "", "\(.*?\)" #function name - "", "", "[\t ][a-zA-Z0-9_]+" #built in object type "", "", "\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" #string "", "", "\".*?(\"|$)" #Colors - "", "", "(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])" #string "", "", "'.*?('|$)" #Colors - "", "", "(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])" #event capturing "", "", "\b(captureEvents|releaseEvents|routeEvent|handleEvent)\b.*?(\)|$)" #predefined methods "", "", "\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" #properties "", "", "\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" #operators "", "", "([=;->/&|])" ###################################################################### ################################# Makefile ########################### ###################################################################### [make,makefile] bgcolor=#ffffff textcolor=#000000 filename=^Makefile\.? filename=^makefile\.? #comment "", "", "#.*?$" #Assignment "", "", "^( *| [ \t]*)[A-Za-z0-9_+]*[ \t]*(\+|:)?=" #Dependency Line "", "", "^ *([A-Za-z0-9./$(){} _%+-]|\n)*::?" #Dependency Target - "", "", "[A-Za-z0-9./$(){} _%+-]+" #Dependency continuation - "", "", "\\\n" #comment - "", "", "#.*?$" #macro - "", "", "\$([A-Za-z0-9_]|\([^)]*\)|{[^}]*})" #int macro - "", "", "\$([<@*?%]|\$@)" #Continuation "", "", "\\$" #Macro "", "", "\$([A-Za-z0-9_]|\([^)]*\)|{[^}]*})" #Internal Macro "", "", "\$([<@*?%]|\$@)" #Escaped Dollar "", "", "\$\$" #Include "", "", "^include[ \t]" ###################################################################### ################################# Pascal ############################# ###################################################################### [pas,pascal] bgcolor=#ffffff textcolor=#000000 filename=\.p$ filename=\.pas$ #comment1 (* *) "", "", "\(\*.*?\*\)" #comment1 { } "", "", "\{.*?\}" #string "", "", "'.*?('|$)" #preprocessor line "", "", "^[ \t]*#.*?$" #comment1 (* *) - "", "", "\(\*.*?\*\)" #comment1 { } - "", "", "\{.*?\}" #character constant "", "", "'.'" #numeric constant "", "", "\b((0(x|X)[0-9a-fA-F]*)|[0-9.]+((e|E)(\+|-)?)?[0-9]*)(L|l|UL|ul|u|U|F|f)?\b" #storage and ops "", "", "\b(and|AND|array|const|div|export|file|function|import|in|IN|label|mod|module|nil|not|NOT|only|or|OR|packed|pow|pragma|procedure|program|protected|qualified|record|restricted|set|type|var)\b" #keywords "", "", "\b(begin|case|do|downto|else|end|for|goto|if|of|otherwise|repeat|then|to|until|while|with)\b" #symbols "", "", "([\*\-\+=:;<>\(\)\[\]!]|[^/]/[^/])" #identifiers "", "", "([a-zA-Z_][a-zA-Z_0-9.^]*[a-zA-Z_0-9]|[a-zA-Z_][a-zA-Z_0-9]*)" #dot, carret(sp?) - "", "", "(\.|\^)+" ###################################################################### ################################# Perl ############################### ###################################################################### [perl] bgcolor=#ffffff textcolor=#000000 filename=\.pl$ filename=\.pm$ filename=\.p5$ filename=\.pod$ regex=^\s*#\s*![^\s]*perl #comment "", "", "#.*?$" #variables "", "", "[$@%]\$?({[^}]*}|[^a-zA-Z0-9_/\t\n\.,\\[\\{\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?" #string; so this part realy is weird, but it works! "", "", "((\"\")|(\"\\\\\")|(\"[^\"\\]\")|(\"[^\"].*?[^\\]\"))" #esc character - "", "", "\\." #variables - "", "", "[$@%]\$?({[^}]*}|[^a-zA-Z0-9_/\t\n\.,\\[\\{\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?" #string; so this part realy is weird, but it works! "", "", "(('')|('\\\\')|('[^'\\]')|('[^'].*?[^\\]'))" #esc character - "", "", "\\." #more strings - q// qw// "", "", "(?:\b| )(?:q|qw)(\W)(\\\1|[^\1\n])*(\1)" #esc character - "", "", "\\." #more strings qq// qx// "", "", "(?:\b| )(?:qq|qx)(\W)(\\\1|[^\1\n])*(\1)" #esc character - "", "", "\\." #variables - "", "", "[$@%]\$?({[^}]*}|[^a-zA-Z0-9_/\t\n\.,\\[\\{\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?" #subroutine header "", "", "sub[\t ]+([a-zA-Z0-9_]+)[\t \n]*(\{|\n)" #subr header coloring - "", "", "[\t ]([a-zA-Z0-9_]+)" #ignore escaped chars # "", "", "\\[#"'\$msytq]" #regex matching # "", "", "(\b| )((m|q|qq)?/)(\\/|[^/\n])*(/[gimsox]*)" "", "", "(\b| )?(/)(\\/|[^/\n])*(/[gimsox]*)" # "", "", "(?:\b| )(?:(?:m|q|qq)(\W))(\\\1|[^\1\n])*(\1[gimsox]*)" "", "", "(?:\b| )(?:(?:m|q|qq)([!\"#$%&'*+-/]))(\\\1|[^\1\n])*(\1[gimsox]*)" #regex substitution # "", "", "(\b| )((s|y|tr)/)(\\/|[^/\n])*(/)[^/\n]*(/[gimsox]*)" # "", "", "(?:\b| )?(?:s(\W))(?:\\\1|[^\1\n])*?(\1)[^(\1)\n]*?(\1[gimsox]*)" "", "", "(?:\b| )?(?:s([!\"#$%&'*+-/]))(?:\\\1|[^\1\n])*?(\1)[^(\1)\n]*?(\1[gimsox]*)" #translate "", "", "(?:\b| )(?:(?:tr|y)(\W))(?:\\\1|[^\1\n])*?(\1)[^(\1)\n]*?(\1[gimsox]*)" #keywords "", "", "\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" #library fns "", "", "\b(abs|accept|alarm|atan2|bind|binmode|bless|caller|chdir|chmod|chomp|chop|chr|chroot|chown|closedir|close|connect|cos|crypt|dbmclose|dbmopen|defined|delete|die|dump|each|endgrent|endhostent|endnetent|endprotoent|endpwent|endservent|eof|exec|exists|exp|fctnl|fileno|flock|fork|format|formline|getc|getgrent|getgrgid|getgrnam|gethostbyaddr|gethostbyname|gethostent|getlogin|getnetbyaddr|getnetbyname|getnetent|getpeername|getpgrp|getppid|getpriority|getprotobyname|getprotobynumber|getprotoent|getpwent|getpwnam|getpwuid|getservbyname|getservbyport|getservent|getsockname|getsockopt|glob|gmtime|grep|hex|import|index|int|ioctl|join|keys|kill|lcfirst|lc|length|link|listen|log|localtime|lstat|map|mkdir|msgctl|msgget|msgrcv|no|oct|opendir|open|ord|pack|pipe|pop|pos|printf|print|push|quotemeta|rand|readdir|read|readlink|recv|ref|rename|reset|reverse|rewinddir|rindex|rmdir|scalar|seekdir|seek|select|semctl|semget|semop|send|setgrent|sethostent|setnetent|setpgrp|setpriority|setprotoent|setpwent|setsockopt|shift|shmctl|shmget|shmread|shmwrite|shutdown|sin|sleep|socket|socketpair|sort|splice|split|sprintf|sqrt|srand|stat|study|substr|symlink|syscall|sysopen|sysread|system|syswrite|telldir|tell|tie|tied|time|times|truncate|uc|ucfirst|umask|undef|unlink|unpack|unshift|untie|utime|values|vec|wait|waitpid|wantarray|warn|write|qw|-[rwxoRWXOezsfdlpSbctugkTBMAC])\b" #braces and parens "", "", "[\[\]\{\}\(\)]" #<< stuff "", "", "<<'([^\n]*)';.*?^\1$" "", "", "<<\"([^\n]*)\";.*?^\1$" "", "", "<<([^\n]*).*?^\1$" #POD "", "", "(^=pod|^=head).*?^=cut" "", "", "(^=begin).*?^=end" ###################################################################### ################################# sql ################################ ###################################################################### [sql] bgcolor=#ffffff textcolor=#000000 filename=\.sql$ #keywords "", "", ",|%|<|>|:=|=|\(|\)|\b(SELECT|ON|FROM|ORDER BY|DESC|WHERE|AND|OR|NOT|NULL|TRUE|FALSE|select|on|from|order by|desc|where|and|or|not|null|true|false|Select|On|From|Order By|Desc|Where|And|Or|Not|Null|True|False)\b" #comment "", "", "--.*?$" #comment "", "", "/\*.*?\*/" #string; so this part realy is weird, but it works! "", "", "(('')|('[^'\\]')|('[^'].*?[^\\]'))" #keywords "", "", "END IF;|End If;|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|create|replace|begin|end|function|return|fetch|open|close|into|is|in|when|others|grant|on|to|exception|show|set|out|pragma|as|package|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" #keywords "", "", "\b(ALTER|Alter|alter)\b" #datatypes "", "", "\b(INTEGER|Integer|integer|BLOB|Blob|blobl|DATE|Date|date|NUMERIC|Numeric|numeric|CHARACTER|Character|character|VARYING|Varying|varying|VARCHAR|Varchar|varchar|CHAR|Char|char)\b" #st "", "", "\b(CONSTRAINT|Constraint|constraint|KEY|Key|key|CONSTRAINT|Constraint|constraint|REFERENCES|References|references|PRIMARY|Primary|primary|TABLE|Table|table|FOREIGN|Foreign|foreign|ADD|Add|add|INSERT|Insert|insert|GROUP BY|Group By|group by)\b" ###################################################################### ## contributed by JA ########################################################################### ## AWK ########################################################################### [awk] bgcolor=#ffffff textcolor=#000000 filename=\.awk$ ## COMMENT "", "", "#.*?$" ## VARIABLES # ## STRING (""); so this part really is weird, but it works! "", "", "((\"\")|(\"\\\\\")|(\"[^\"\\]\")|(\"[^\"].*?[^\\]\"))" ## ESC CHARACTER - "", "", "\\." ## VARIABLES # - "", "", "[$@%]\$?({[^}]*}|[^a-zA-Z0-9_/\t\n\.,\\[\\{\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?" ## STRING (''); so this part realy is weird, but it works! "", "", "(('')|('\\\\')|('[^'\\]')|('[^'].*?[^\\]'))" ## ESC CHARACTER - "", "", "\\." ## FUNCTION HEADER "", "", "function[\t ]+([a-zA-Z0-9_]+)[\t \n]*(\{|\n)" ## FUNCTION COLORING - "", "", "[\t ]([a-zA-Z0-9_]+)" ## REGEX MATCHING "", "", "(\b| )?(/)(\\/|[^/\n])*(/[gimsox]*)" # "", "", "(?:\b| )(?:(?:m|q|qq)(\W))(\\\1|[^\1\n])*(\1[gimsox]*)" "", "", "(?:\b| )(?:(?:m|q|qq)([!\"#$%&'*+-/]))(\\\1|[^\1\n])*(\1[gimsox]*)" ## REGEX SUBSTITUTION # "", "", "(?:\b| )?(?:s(\W))(?:\\\1|[^\1\n])*?(\1)[^(\1)\n]*?(\1[gimsox]*)" "", "", "(?:\b| )?(?:s([!\"#$%&'*+-/]))(?:\\\1|[^\1\n])*?(\1)[^(\1)\n]*?(\1[gimsox]*)" ## TRANSLATE "", "", "(?:\b| )(?:(?:tr|y)(\W))(?:\\\1|[^\1\n])*?(\1)[^(\1)\n]*?(\1[gimsox]*)" ## KEYWORDS "", "", "\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" "", "", "\b(if|while|do|for|in|break|continue|delete|exit|next|nextfile|function)\b" ## LIBRARY FNS "", "", "\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" ## BRACES AND PARENS "", "", "[\[\]\{\}\(\)]" ## << STUFF "", "", "<<'([^\n]*)';.*?^\1$" "", "", "<<([^\n]*).*?^\1$" ## contributed by JA ########################################################################### ## M4 ########################################################################### [m4] bgcolor=#ffffff textcolor=#000000 filename=\.m4$ ## COMMENT "", "", "dnl.*?$" "", "", "#.*?$" ## KEYWORDS; "","","\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" "","","\b(ifdef|ifelse|loops)\b" ## STRING (`'); ## CURRENTLY NOT WORKING! # "","","(`[A-Za-z0-9_]*')" # "","","(`\\\\')|(`[^'\\]')" # "","","(`[^`].*?[^\\]''*)" # "","","(`.*?(?>`.*')')" ## MACRO ARGUMENT SUBSTITUTION - "", "", "[$]\$?({[^}]*}|[^a-zA-Z0-9_/\t\n\.,\\[\\{\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?" ## contributed by JA ########################################################################### ## Groff ########################################################################### [groff] bgcolor=#ffffff textcolor=#000000 filename=\.groff$ ## COMMENT ('\"') "","","\\\".*?$" ## KEYWORDS # "","","^[\.\\][]A-Za-z0-9_{}()$[]+" EODB ; };