A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.
1 #!/usr/bin/perl -w 2 my $vernr = "0.9.1"; 3 my $monthshort = "Jan"; 4 my $monthlong = "Jan"; 5 my $year = "2002"; 6 ######################################################################## 7 # # 8 # Code2HTML # 9 # --------- # 10 # # 11 # Code2Html, peter@palfrader.org # 12 # # 13 # $Date: 2002/01/12 21:17:02 $ 14 # $Revision: 1.13 $ 15 # $Id: code2html,v 1.13 2002/01/12 21:17:02 weaselp Exp $ 16 # # 17 # AUTHOR # 18 # Peter Palfrader. Written in 1999, 2000, 2001, 2002. # 19 # A lot of other people. See CREDITS file. # 20 # # 21 # DESCRIPTION # 22 # code2html is a perlscript which converts a program # 23 # source code to syntax highlighted HTML by applying a set # 24 # of regular expressions depending on the language # 25 # the source code is written. # 26 # # 27 # see the man-page for details, # 28 # # 29 ######################################################################## 30 31 use strict; 32 use Getopt::Long; 33 34 my $FILES_DISALLOWED_IN_CGI = 1; 35 # you may set this to false to allow file reading from your hd in 36 # cgi mode. This may be not good if your httpd runs as 'root' (yes, I've 37 # seen this!) and so any user could with some knowledge easily read 38 # your /etc/shadow for example! 39 my $FILES_REDIRECT_DISALLOWED = 1; 40 my $LANG_TEST_LENGTH = 1024; 41 42 43 # PP: I think Compress::Zlib could be nice for this. but it's not very widespread :( 44 # PP: A hash would be nicer but then it would not possible to get the keys in this very order (AFAIK) 45 # 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) 46 my @CGI_ENCODING = ( 47 ['bzip2' , '/usr/bin/bzip2' , '--stdout' ], 48 ['gzip' , '/bin/gzip' , '--stdout' ], 49 ['compress' , '/usr/bin/compress' , '-c' ] 50 ); 51 52 53 54 # undefine the input record separator so everything gets loaded in one turn 55 undef $/; 56 57 58 59 my $pure_version_message = "Code2Html, version $vernr, $monthshort $year, peter\@palfrader.org"; 60 my $version_message = "$pure_version_message\n"; 61 62 my $short_short_help = "Try `code2html --help' for more information.\n"; 63 my $short_help = 64 "$pure_version_message 65 Usage: code2html [options] [input_file [output_file]] 66 67 Convert a program source to syntax highlighted HTML, 68 or any other format for wich rules are defined. 69 70 -l, --language-mode set language mode 71 --fallback LANG fallback language mode 72 -v, --verbose prints progress information to STDER 73 -n, --linenumbers print out the source code with line numbers 74 -P, --prefix optional prefix to use for linenumber anchors 75 -N, --linknumbers linenumbers will link to themselves 76 -t, --replace-tabs[=TABSTOP-WIDTH] 77 replace <tabs> with spaces 78 -L, --language-file=LANGUAGE-FILE 79 specify an alternate file for definitions 80 -m, --modes print all available modes 81 -h, --help print this message 82 -V, --version print version 83 -c, --content-type prints a Content-Type header 84 -o, --output-format selects the output-format 85 -H, --no-header don't use the template 86 --template=FILE override template 87 -T, --title set title 88 89 -w, --linewidth max characters per line 90 -b, --linebreakprefix prefix of the new lines 91 92 see the man-page code2html for further help 93 "; 94 95 96 97 98 99 my $USE_CGI_FOR_ERRORS = 0; # is switched on in parse params if necessary 100 $SIG{'__DIE__'} = 101 sub { 102 if ($USE_CGI_FOR_ERRORS) { print "Content-Type: text/plain\n\n", $0, ': ', $_[0], "\n"; } 103 else { print STDERR $0, ': ', $_[0]; }; 104 exit 1; 105 }; 106 107 $SIG{'__WARN__'} = 108 sub { 109 unless ($USE_CGI_FOR_ERRORS) { print STDERR $0.': '.$_[0]; }; 110 }; 111 112 113 114 115 116 117 118 119 120 my $DEFAULT_OUTPUTFORMAT='html'; 121 my $DEFAULT_OUTPUTFORMAT_IN_CGI='html'; 122 my $ENTITIES; 123 my %ENTITIES; 124 125 126 my %params = &parse_params; 127 if ($params{'what_to_do'} eq 'patch_html') { &patch_html(\%params) } 128 elsif ($params{'what_to_do'} eq 'normal' ) { &main(\%params) } 129 else { die("I don't know what to do :(\n") }; 130 131 132 133 134 135 136 137 138 139 140 sub main 141 { 142 my %params = %{shift()}; 143 144 145 print STDERR "getting patterns...\n" if ($params{'verbose'}); 146 # building up the database 147 # newer entries overwrite old ones 148 my @CONFIG_FILES; 149 push @CONFIG_FILES, "/etc/code2html.config"; 150 push @CONFIG_FILES, $ENV{'HOME'}."/.code2html.config" if (defined($ENV{'HOME'})); 151 push @CONFIG_FILES, split(/:/,$ENV{'CODE2HTML_CONFIG'}) if ($ENV{'CODE2HTML_CONFIG'}); 152 push @CONFIG_FILES, split(/:/,$params{'langfile'}) if defined($params{'langfile'}); 153 154 my %STYLESHEET = %{ &get_default_stylesheet } ; 155 my %LANGUAGE = %{ &get_default_database } ; 156 157 for (@CONFIG_FILES) { 158 if ( -r $_){ 159 # if I use `do $_` instead of scalar eval... %LANGUAGE is not exported and imported correctly (read: at all) (PP) 160 unless (scalar eval `cat $_`) { 161 warn "couldn't parse $_: $@" if $@; 162 }; 163 }; 164 }; 165 166 167 168 169 if (defined($params{'modes'}) && $params{'modes'}) 170 { 171 print "Defined modes: "; 172 print join( ', ', sort keys %LANGUAGE ), ".\n" ; 173 print "Defined outputformats: "; 174 print join( ', ', sort keys %STYLESHEET ), ".\n" ; 175 exit; 176 }; 177 178 179 180 181 182 # set outputformat 183 die "Outputformat $params{'outputformat'} not defined" unless defined $STYLESHEET{$params{'outputformat'}}; 184 my %STYLE = % { $STYLESHEET{$params{'outputformat'}} }; 185 186 # load alternate template if given 187 if (($params{'template'} ne "") && ( ! $params{'noheader'} )) { 188 open (FILE, $params{'template'}) || die ("Could not open template file $params{'template'}: $!"); 189 $STYLE{'template'} = <FILE>; 190 close (FILE); 191 }; 192 193 # set up the global ENTITIES variables ( the scalar and the hash ) from the STYLE definition 194 $ENTITIES = $ { $STYLE{'entities'} }{'listofchars'}; 195 %ENTITIES = % { $ { $STYLE{'entities'} }{'replace_by' } }; 196 197 # modify the header and footer so that the template variables are set correcly 198 unless ($STYLE{'template'} =~ /^(.*)%%code%%(.*)$/s) { 199 die "template does not contain a %%code%% variable"; 200 }; 201 $STYLE{'header'} = $1; 202 $STYLE{'footer'} = $2; 203 $STYLE{'header'} =~ s/%%title%%/$params{'title'}/g; 204 $STYLE{'footer'} =~ s/%%title%%/$params{'title'}/g; 205 $STYLE{'header'} =~ s/%%version%%/$vernr/g; 206 $STYLE{'footer'} =~ s/%%version%%/$vernr/g; 207 208 209 210 # load the input file and set params{'langmode'} if it is not already. this is done by probing a 211 # set of rules defined in %LANGUAGE 212 my $code_ref; 213 print STDERR "loading input file...\n" if ($params{'verbose'}); 214 $code_ref = &get_input_file(\%params, \%LANGUAGE, $params{'langmode'}, $params{'alt_langmode'}); 215 216 # select the rules for out language. 217 my $language_rules_ref = $LANGUAGE{ lc($params{'langmode'}) }->{'patterns'}; 218 219 print STDERR "applying stylesheet...\n" if ($params{'verbose'}); 220 # Apply the Stylesheets 221 # set 'starttag' and 'endtag' for every rule according to its 'style' value 222 # the tags are defined in the stylesheet 223 &apply_stylesheets_to_rules( $language_rules_ref, \%STYLE ); 224 225 print STDERR "outputting headers...\n" if ($params{'verbose'}); 226 &put_headers(\%params, \%STYLE); 227 228 my $snippetlist_ref = [] ; 229 print STDERR "creating snippet-list...\n" if $params{'verbose'}; 230 &create_snippetlist( $language_rules_ref, $$code_ref, $snippetlist_ref, \%STYLE); 231 232 print STDERR "outputting file...\n" if $params{'verbose'}; 233 return &put_output(\%params, $snippetlist_ref, \%STYLE); 234 } 235 236 237 238 239 240 sub patch_html 241 { 242 my %params = %{shift()}; 243 my $code; 244 245 open(FILEHANDLE, $params{'infile'}) || die("While opening '$params{'infile'}' for input: ".$!."\n"); 246 $code = <FILEHANDLE>; 247 close(FILEHANDLE); 248 249 $code =~ s/<!-- code2html delete start -->.*?<!-- code2html delete stop -->//gs; 250 my $counter=0; 251 my @chunks = split ( /(<!-- code2html add.*?-->)/s , $code); 252 253 $code = ''; 254 for (@chunks) 255 { 256 $code .= $_; 257 if ($_ =~ /<!-- code2html add(.*?)(\n.*?)?-->/s) 258 { 259 my $cmdline = $1; 260 my $input = $2; 261 $cmdline =~ s/^[ \t]*//g; 262 $cmdline =~ s/[ \t]*$//g; 263 @ARGV = split ( / / , $cmdline); 264 my %new_params = &parse_params; 265 266 267 $new_params{'input'} = $input if ($new_params{'infile'} eq "-"); 268 269 270 undef $new_params{'outfile'}; 271 ++$counter; 272 $new_params{'line_number_prefix'} = $counter unless (defined $new_params{'line_number_prefix'}); 273 274 $new_params{'verbose'} = $params{'verbose'}; 275 276 my $no_header = $new_params{'noheader'}; 277 $new_params{'noheader'} = 1; 278 $new_params{'dont_print_output'} = 1; 279 280 if ($no_header) 281 { 282 $code .= '<!-- code2html delete start -->'.. 283 &main(\%new_params). 284 '<!-- code2html delete stop -->'; 285 } 286 else 287 { 288 $code .= '<!-- code2html delete start --><pre>'. 289 &main(\%new_params). 290 '</pre><!-- code2html delete stop -->'; 291 }; 292 }; 293 }; 294 295 296 open(FILEHANDLE, '>'.$params{'outfile'}) || die("While opening '$params{'outfile'}' for output: ".$!."\n"); 297 print FILEHANDLE $code; 298 close(FILEHANDLE); 299 }; 300 301 302 303 304 305 306 ##################################################################### 307 ################### get_input_data ################################## 308 ##################################################################### 309 # Reads the input data for the cgi script. 310 # in : nothing 311 # out: a hash with the input data 312 sub get_input_data 313 { 314 my $input_data; 315 my %f; 316 if($ENV{'REQUEST_METHOD'} eq 'GET') { $input_data = $ENV{'QUERY_STRING'}; } 317 else { read(STDIN, $input_data, $ENV{'CONTENT_LENGTH'}); }; 318 319 320 if ($ENV{'CONTENT_TYPE'} =~ m/^multipart\/form-data; boundary=(.*)$/i) 321 { 322 my $boundary = quotemeta($1); 323 my @blocks = split(/$boundary/, $input_data); 324 325 for (@blocks) 326 { 327 if (my $dummy = m/name="(.*?)"/i) 328 { 329 my $name = $1; 330 $_ =~ s/\r\n/\n/g; 331 m/\n\n(.*)\n/s; 332 my $value = $1; 333 $f{$name}=$value; 334 }; 335 }; 336 } 337 elsif ($ENV{'CONTENT_TYPE'} =~ m/^multipart\/form-data;$/i) # if the boundary is not in the enviroment variable we'll guess 338 { 339 my $dummy = $input_data =~ m/^(.*?)(\n|\r)/; 340 my $boundary = $1; 341 342 my @blocks = split(/$boundary/, $input_data); 343 344 for (@blocks) 345 { 346 if (my $dummy = m/name="(.*?)"/i) 347 { 348 my $name = $1; 349 $_ =~ s/\r\n/\n/g; 350 m/\n\n(.*)\n/s; 351 my $value = $1; 352 $f{$name}=$value; 353 }; 354 }; 355 } 356 else 357 { 358 my @form_fields = split(/&/, $input_data); 359 360 for (@form_fields) 361 { 362 my ($name, $value) = split(/=/, $_); 363 $value =~ tr/+/ /; 364 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; 365 366 $f{$name} = $value; 367 } 368 }; 369 370 return %f; 371 }; 372 373 ################################################################################ 374 ####################### parse_params ########################################### 375 ################################################################################ 376 sub parse_params 377 { 378 my %RESULT; 379 380 if (defined($ENV{'GATEWAY_INTERFACE'}) && (!scalar(@ARGV))) # if there is a CGI enviroment and no parameters/options given 381 { 382 $USE_CGI_FOR_ERRORS = 1; 383 $RESULT{'content-type'} = 1; 384 $RESULT{'what_to_do'} = 'normal'; 385 386 my %input = &get_input_data; 387 388 $input{'input-selector'} = $input{'input_selector'} unless (defined $input{'input-selector'}); 389 $input{'no-encoding'} = $input{'no_encoding'} unless (defined $input{'no-encoding'}); 390 $input{'line-numbers'} = $input{'line_numbers'} unless (defined $input{'line-numbers'}); 391 $input{'replace-tabs'} = $input{'replace_tabs'} unless (defined $input{'replace-tabs'}); 392 $input{'language-mode'} = $input{'language_mode'} unless (defined $input{'language-mode'}); 393 $input{'cgi-input1'} = $input{'cgi_input1'} unless (defined $input{'cgi-input1'}); 394 $input{'cgi-input2'} = $input{'cgi_input2'} unless (defined $input{'cgi-input2'}); 395 396 if ($input{'input-selector'} =~ /^cgi[-_]input[12]$/ ) 397 { 398 my $input_selector = $input{'input-selector'}; 399 die("CGI parse error: $input_selector does not exist!") unless (defined $input{$input_selector}); 400 $RESULT{'input'} = $input{$input_selector}; 401 $RESULT{'title'} = 'code2html result of cgi input form'; 402 } 403 elsif ($input{'input-selector'} eq "file") 404 { 405 die('CGI parse error: option not supported due to security reasons!') if ($FILES_DISALLOWED_IN_CGI); 406 die('CGI parse error: filename not defined!') unless (defined $input{'filename'}); 407 $RESULT{'infile'} = $input{'filename'}; 408 $RESULT{'title'} = $RESULT{'infile'}; 409 } 410 elsif ($input{'input-selector'} eq "REDIRECT_URL") 411 { 412 die('CGI parse error: option not supported due to security reasons!') if ($FILES_REDIRECT_DISALLOWED); 413 die('CGI parse error: ENV: REDIRECT_URL not defined!') unless (defined $ENV{'REDIRECT_URL'}); 414 $RESULT{'infile'} = $ENV{'DOCUMENT_ROOT'}.$ENV{'REDIRECT_URL'}; 415 $RESULT{'title'} = $RESULT{'infile'}; 416 } 417 else 418 { 419 die('CGI parse error: input selector not given!'); 420 }; 421 422 if ((!defined ($input{'no-encoding'})) || $input{'no-encoding'}) 423 { 424 for (@CGI_ENCODING) 425 { 426 if ( ($ENV{'HTTP_ACCEPT_ENCODING'} =~ m/\b $_->[0] \b/x) && # PP: if supported by the browser 427 (-x $_->[1]) ) # PP: and executable by the script 428 { 429 $RESULT{'encoding'} = $_->[0]; 430 $RESULT{'encoder' } = $_->[1] .' '. $_->[2]; 431 last; 432 }; 433 } 434 }; 435 436 $RESULT{'linenumbers'} = 'none'; 437 if ($input{'line-numbers'} eq "yes") { $RESULT{'linenumbers'} = 'normal'; }; 438 if ($input{'line-numbers'} eq "link") { $RESULT{'linenumbers'} = 'linked'; }; 439 if (defined($input{'replace_tabs'})) { $RESULT{'replacetabs'} = $input{'replace-tabs'} }; 440 if (defined($input{'fallback'})) { $RESULT{'alt_langmode'} = $input{'fallback'} }; 441 if (defined($input{'language_mode'})) { $RESULT{'langmode'} = $input{'language-mode'} }; 442 if (defined($input{'title'})) { $RESULT{'title'} = $input{'title'} }; 443 444 $RESULT{'content_type'} = 1; 445 $RESULT{'outputformat'} = $DEFAULT_OUTPUTFORMAT_IN_CGI; 446 $RESULT{'outfile'} = '-'; 447 } 448 else 449 { 450 my $verbose = 0; 451 my $linenumbers = 0; 452 my $linknumbers = 0; 453 my $replace_tabs = 0; 454 my $language_file = ''; 455 my $language_mode = ''; 456 my $modes = 0; 457 my $fallback = ''; 458 my $help = 0; 459 my $version = 0; 460 my $content_type = 0; 461 my $no_header = 0; 462 my $outputformat = $DEFAULT_OUTPUTFORMAT; 463 my $template = ''; 464 my $title = "__NOTHING__$$"; # some magix ;( 465 my $prefix = undef; 466 my $linewidth = undef; 467 my $linebreakprefix = undef; 468 my $linebreakprefixdefault = '» '; 469 470 my $patch_html; 471 472 473 # Get Options does not like - as a parameters (used for STDIN and STDOUT) 474 # So we're using a stupid magix again 475 @ARGV = map { $_ eq '-' ? "__STD__$$" : $_ } @ARGV; 476 477 Getopt::Long::config('bundling'); 478 unless ( GetOptions( 479 "--verbose" , \$verbose , 480 "-v" , \$verbose , 481 482 "--linenumbers" , \$linenumbers , 483 "-n" , \$linenumbers , 484 485 "--linknumbers" , \$linknumbers , 486 "-N" , \$linknumbers , 487 488 "--prefix=s" , \$prefix , 489 "-P=s" , \$prefix , 490 491 "--replace-tabs=i" , \$replace_tabs , 492 "--replace_tabs=i" , \$replace_tabs , 493 "-t=i" , \$replace_tabs , 494 495 "--language-file=s" , \$language_file , 496 "--language_file=s" , \$language_file , 497 "-L=s" , \$language_file , 498 499 "--language-mode=s" , \$language_mode , 500 "--language_mode=s" , \$language_mode , 501 "-l=s" , \$language_mode , 502 503 "--title=s" , \$title , 504 "-T=s" , \$title , 505 506 "--modes" , \$modes , 507 "-m" , \$modes , 508 509 "--fallback=s" , \$fallback , 510 511 "--output=s" , \$outputformat , 512 "-o=s" , \$outputformat , 513 514 "--template=s" , \$template , 515 516 "--help" , \$help , 517 "-h" , \$help , 518 519 "--version" , \$version , 520 "-V" , \$version , 521 522 "--content-type" , \$content_type , 523 "--content_type" , \$content_type , 524 "-c" , \$content_type , 525 526 "--no-header" , \$no_header , 527 "--no_header" , \$no_header , 528 "-H" , \$no_header , 529 530 531 "--patch-html" , \$patch_html , 532 "--patch_html" , \$patch_html , 533 "-p" , \$patch_html , 534 535 "--linewidth=i" , \$linewidth , 536 "-w=i" , \$linewidth , 537 "--linebreakprefix=s" , \$linebreakprefix , 538 "-b=s" , \$linebreakprefix , 539 ) 540 ) 541 { 542 print STDERR $short_short_help; 543 exit 1; 544 } 545 546 #reversing magix 547 @ARGV = map { $_ eq "__STD__$$" ? '-' : $_ } @ARGV; 548 549 if ($help) { print STDERR $short_help; exit 0; }; 550 if ($version) { print $version_message; exit 0; }; 551 552 if ($patch_html) 553 { 554 $RESULT{'what_to_do'} = 'patch_html'; 555 $RESULT{'verbose'} = $verbose; 556 557 if (!defined ($RESULT{'infile'} = shift(@ARGV))) { $RESULT{'infile'} = '-' }; 558 if (!defined ($RESULT{'outfile'} = shift(@ARGV))) { $RESULT{'outfile'} = $RESULT{'infile'}}; 559 if (defined (shift(@ARGV))) { print STDERR "too many parameters!\n"; 560 print STDERR $short_help; 561 exit 1; 562 }; 563 } 564 else 565 { 566 $RESULT{'what_to_do'} = 'normal'; 567 568 $RESULT{'verbose'} = $verbose; 569 if ($linknumbers) { $RESULT{'linenumbers'} = 'linked' } 570 elsif ($linenumbers) { $RESULT{'linenumbers'} = 'normal' } 571 else { $RESULT{'linenumbers'} = 'none' }; 572 $RESULT{'line_number_prefix'} = $prefix; 573 $RESULT{'replacetabs'} = $replace_tabs; 574 $RESULT{'langfile'} = $language_file; 575 $RESULT{'modes'} = $modes; 576 $RESULT{'alt_langmode'} = $fallback; 577 $RESULT{'content_type'} = $content_type; 578 $RESULT{'noheader'} = $no_header; 579 $RESULT{'langmode'} = $language_mode; 580 $RESULT{'template'} = $template; 581 $RESULT{'outputformat'} = $outputformat; 582 $RESULT{'linewidth'} = $linewidth; 583 $RESULT{'linebreakprefix'}= $linebreakprefix; 584 585 if (defined ($RESULT{'linebreakprefix'}) && 586 !defined ($RESULT{'linewidth'})) { 587 printf (STDERR "--linebreakprefix|-b does not make sense without --linewidth|-w!\n"); 588 print STDERR $short_help; 589 exit 1; 590 } 591 if (defined ($RESULT{'linewidth'})) { 592 if ($RESULT{'linewidth'} <= 0) { 593 printf (STDERR "linewidth must be greater then 0!\n"); 594 print STDERR $short_help; 595 exit 1; 596 } 597 if (!defined ($RESULT{'linebreakprefix'})) { 598 $RESULT{'linebreakprefix'} = $linebreakprefixdefault; 599 } 600 } 601 602 if (!defined ($RESULT{'infile'} = shift(@ARGV))) { $RESULT{'infile'} = '-'}; 603 if (!defined ($RESULT{'outfile'} = shift(@ARGV))) { $RESULT{'outfile'} = '-'}; 604 if (defined (shift(@ARGV))) { print STDERR "too many parameters!\n"; 605 print STDERR $short_help; 606 exit 1; 607 }; 608 }; 609 #the magix again 610 $RESULT{'title'} = $title eq "__NOTHING__$$" ? ($RESULT{'infile'} eq '-' ? 'STDIN' : $RESULT{'infile'}) : $title; 611 }; 612 613 614 return %RESULT; 615 }; 616 617 618 ################################################################################ 619 ####################### checkTabulator ######################################### 620 ################################################################################ 621 sub checkTabulator 622 { 623 my ($line, $TABSTOP) = @_; 624 625 while ((my $at = index($line, "\t")) != -1) 626 { 627 my $cnt = ($TABSTOP - ($at % $TABSTOP)); 628 my $replace_with = ' ' x $cnt if ($cnt); 629 $line =~ s/\t/$replace_with/; 630 }; 631 632 return $line; 633 } 634 635 ################################################################################ 636 ####################### splitLine ############################################## 637 ################################################################################ 638 sub splitLine 639 { 640 my ($line, $linewidth, $prefix) = @_; 641 642 my $length = length ($line); 643 my $pos = 0; 644 645 while ($length - $pos > $linewidth) 646 { 647 my $maxoff = ($pos + $linewidth > $length) ? ($length - 1) 648 : ($pos + $linewidth); 649 my $newpos = rindex ($line, " ", $maxoff); 650 if ($newpos > $pos) { 651 $pos = $newpos; 652 $line = substr ($line, 0, $pos)."\0$prefix".substr ($line, $pos + 1, $length); 653 } else { 654 $pos = $pos + $linewidth + 1; 655 $line = substr ($line, 0, $pos)."\0$prefix".substr ($line, $pos, $length); 656 } 657 }; 658 659 return $line; 660 } 661 662 ################################################################################ 663 ####################### get_input_file ######################################### 664 ################################################################################ 665 sub get_input_file 666 { 667 668 # in : \%params 669 # in : \%LANGUAGE; 670 # in/out : $langmode; 671 # in/out : $alt_langmode; 672 # returns: input file 673 674 my %PARAMS = %{$_[0]}; 675 my %LANGUAGE = %{$_[1]}; 676 my $langmode = $_[2]; 677 my $alt_langmode = $_[3]; 678 my $code; 679 680 681 if (defined $PARAMS{'input'}) 682 { 683 $code = $PARAMS{'input'}; 684 $code =~ s/\r//g; 685 } 686 else 687 { 688 open(FILEHANDLE, $PARAMS{'infile'}) || die("While opening '$PARAMS{'infile'}' for input: ".$!."\n"); 689 $code = <FILEHANDLE>; 690 close(FILEHANDLE); 691 }; 692 693 if ($PARAMS{'replacetabs'} != 0) 694 { 695 $code = join ( 696 "\n", 697 map{ 698 &checkTabulator($_, $PARAMS{'replacetabs'}) 699 } 700 my @dummy = split(/\n/, $code) 701 ); 702 }; 703 704 705 706 if (defined ($PARAMS{'linewidth'})) 707 { 708 $code = join ( 709 "\n", 710 map{ 711 &splitLine($_, $PARAMS{'linewidth'}, 712 $PARAMS{'linebreakprefix'}) 713 } 714 my @dummy = split(/\n/, $code) 715 ); 716 }; 717 718 719 720 if ((!defined($langmode)) || ($langmode eq '')) 721 { 722 my $test_code = substr($code, 0, $LANG_TEST_LENGTH); 723 warn("language mode not given. guessing...\n"); 724 725 $langmode = ''; 726 727 for (keys %LANGUAGE) 728 { 729 if ( (($LANGUAGE{$_}->{'filename'} ne '') && ($PARAMS{'infile'} =~ m/$LANGUAGE{$_}->{filename}/)) || 730 (($LANGUAGE{$_}->{'regex'} ne '') && ($test_code =~ m/$LANGUAGE{$_}->{regex}/ )) ) 731 { 732 $langmode = $_; 733 last; 734 }; 735 }; 736 737 if ($langmode eq '') 738 { 739 if ((defined($alt_langmode)) && ($alt_langmode ne '')) 740 { 741 warn("Guessing language mode failed. Using fallback mode: '$alt_langmode'\n"); 742 $langmode = $alt_langmode; 743 $alt_langmode = ''; 744 } 745 else 746 { 747 die("Guessing language mode failed.\n") 748 }; 749 } 750 else 751 { 752 warn("using '$langmode'\n"); 753 }; 754 }; 755 756 $_[2] = $langmode; 757 $_[3] = $alt_langmode; 758 return \$code; 759 }; 760 761 762 ################################################################################ 763 ####################### put_headers ############################################ 764 ################################################################################ 765 sub put_headers 766 { 767 my %PARAMS = %{shift()}; 768 my $STYLE_REF = shift(); 769 770 if (defined($PARAMS{'outfile'})) 771 { 772 unless ($PARAMS{'outfile'} eq '-'){ 773 open(SAVEOUT, ">&STDOUT"); print SAVEOUT ''; # so perl does not typo warn 774 open (STDOUT, '>'.$PARAMS{'outfile'}) || die("While redirecting STDOUT to '$PARAMS{'outfile'}' for output: ".$!."\n"); 775 }; 776 777 if (defined $PARAMS{'encoding'}) 778 { 779 $|=1; # PP: so the header is written before the data! 780 # PP: this took me hours of debugging :( 781 print "Content-Type: $$STYLE_REF{'content-type'}\n" if ($PARAMS{'content_type'}); 782 print "Content-Encoding: $PARAMS{'encoding'}\n\n"; 783 open (FILEHANDLE, "|$PARAMS{'encoder'}") || die("While opening '$PARAMS{'encoder'}': ".$!."\n"); 784 } 785 else 786 { 787 open( FILEHANDLE, ">&STDOUT" ) ; 788 print FILEHANDLE "Content-Type: $$STYLE_REF{'content-type'}\n\n" if ($PARAMS{'content_type'}); 789 }; 790 791 print FILEHANDLE $$STYLE_REF{'header'} unless $PARAMS{'noheader'}; 792 } 793 }; 794 795 ################################################################################ 796 ####################### apply_stylesheets_to_rules ############################# 797 ################################################################################ 798 sub apply_stylesheets_to_rules 799 { 800 my ( $regexps_ref, $style_ref ) = @_; 801 802 for ( @$regexps_ref ) { 803 # warn ("Style '".$_->{style}."' not defined in stylesheet.\n") unless defined $ { $$style_ref{'tags'} } { $_->{style} }; 804 if (defined ($ { $$style_ref{'tags'} } { $_->{style} })) { 805 $_->{'starttag'} = $ { $ { $$style_ref{'tags'} } { $_->{style} } } { 'start' }; 806 $_->{'endtag'} = $ { $ { $$style_ref{'tags'} } { $_->{style} } } { 'stop' }; 807 } else { 808 # no style no formating; if style == '' formating is done by childregex 809 warn ("Style '".$_->{style}."' not defined in stylesheet.\n") if ($_->{style} ne ''); 810 $_->{'starttag'} = ''; #$ { $ { $$style_ref{'tags'} } { $_->{style} } } { 'start' }; 811 $_->{'endtag'} = ''; #$ { $ { $$style_ref{'tags'} } { $_->{style} } } { 'stop' }; 812 } 813 apply_stylesheets_to_rules( $_->{childregex}, $style_ref ) if $_->{childregex}; 814 }; 815 }; 816 817 ################################################################################ 818 ####################### create_snippetlist ##################################### 819 ################################################################################ 820 sub create_snippetlist 821 { 822 my ( $regexps_ref, $code, $snippetlist_ref, $style_ref ) = @_ ; 823 my $length = length( $code ); 824 825 ## An array of regular expression sturctures, each of which is an 826 ## array. @res is kept sorted by starting position of the RExen and 827 ## then by the position of the regex in the language file. This allows 828 ## us to just evaluate $res[0], and to hand write fast code that typically 829 ## handles 90% of the cases without resorting to the _big_ guns. 830 ## 831 ## FWIW, I pronounce '@res' REEZE, as in the plural of '$re'. 832 ## 833 my @res ; 834 835 my $pos ; 836 837 for ( @$regexps_ref ) { 838 pos( $code ) = 0 ; 839 #++$m ; 840 next unless $code =~ m/($_->{regex})/gms ; 841 842 $pos = pos( $code ) ; 843 # $res[@res] = [ 844 # $_->{regex}, 845 # $ { $ { $$style_ref{'tags'} } { $_->{style} } } { 'start' }, 846 # $ { $ { $$style_ref{'tags'} } { $_->{style} } } { 'stop' }, 847 # $_->{childregex}, 848 # $pos - length( $1 ), 849 # $pos, 850 # scalar( @res ), 851 # ] ; 852 $res[@res] = [ 853 $_->{regex}, 854 $_->{starttag}, 855 $_->{endtag}, 856 $_->{childregex}, 857 $pos - length( $1 ), 858 $pos, 859 scalar( @res ), 860 ] ; 861 } 862 863 ## 90% of all child regexes end up with 0 or 1 regex that needs to be 864 ## worried about. Trimming out the 0's speeds things up a bit and 865 ## makes the below loop simpler, since there's always at least 866 ## 1 regexp. It donsn't speed things up much by itself: the percentage 867 ## of times this fires is really small. But it does simplify the loop 868 ## below and speed it up. 869 unless ( @res ) { 870 $code =~ s/($ENTITIES)/$ENTITIES{$1}/ge ; 871 push @$snippetlist_ref, $code ; 872 return ; 873 } 874 875 @res = sort { $a->[4] <=> $b->[4] || $a->[6] <=> $b->[6] } @res ; 876 877 ## Add a dummy at the end, which makes the logic below simpler / faster. 878 $res[@res] = [ 879 undef, 880 undef, 881 undef, 882 undef, 883 $length, 884 $length, 885 scalar( @res ), 886 ] ; 887 888 ## These are declared here for (minor) speed improvement. 889 my $re ; 890 my $match_spos ; 891 my $match_pos ; 892 my $re_spos ; 893 my $re_pos ; 894 my $re_num ; 895 my $prefix ; 896 my $snippet ; 897 my $rest ; 898 my $i ; 899 my $l ; 900 901 my @changed_res ; 902 my $j ; 903 904 $pos = 0 ; 905 MAIN: 906 while ( $pos < $length ) { 907 $re = $res[0] ; 908 909 $match_spos = $re->[4] ; 910 $match_pos = $re->[5] ; 911 912 if ( $match_spos > $pos ) { 913 $prefix = substr( $code, $pos, $match_spos - $pos ) ; 914 $prefix =~ s/($ENTITIES)/$ENTITIES{$1}/ge ; 915 push @$snippetlist_ref, $prefix ; 916 } 917 918 if ( $match_pos > $match_spos ) { 919 $snippet = substr( $code, $match_spos, $match_pos - $match_spos ) ; 920 if ( @{$re->[3]} ) { 921 push @$snippetlist_ref, $re->[1] ; 922 create_snippetlist( $re->[3], $snippet, $snippetlist_ref, $style_ref ) ; 923 push @$snippetlist_ref, $re->[2] ; 924 } 925 else { 926 $snippet =~ s/($ENTITIES)/$ENTITIES{$1}/ge ; 927 push @$snippetlist_ref, $re->[1], $snippet, $re->[2]; 928 } 929 } 930 931 $pos = $match_pos ; 932 933 ## 934 ## Hand coded optimizations. Luckily, the cases that arise most often 935 ## are the easiest to tune. 936 ## 937 938 # =pod 939 940 if ( $res[1]->[4] >= $pos ) { 941 ## Only first regex needs to be moved, 2nd and later are still valid. 942 ## This is often 90% of the cases for Perl or C (others not tested, 943 ## just uncomment the $n, $o, and $p lines and try it yourself). 944 #++$n{1} ; 945 #++$m ; 946 pos( $code ) = $pos ; 947 unless ( $code =~ m/($re->[0])/gms ) { 948 #++$o{'0'} ; 949 if ( @res == 2 ) { 950 ## If the only regexp left is the dummy, we're done. 951 $rest = substr( $code, $pos ) ; 952 $rest =~ s/($ENTITIES)/$ENTITIES{$1}/ge ; 953 push @$snippetlist_ref, $rest ; 954 last ; 955 } 956 shift @res ; 957 } 958 else { 959 $re->[5] = $re_pos = pos( $code ) ; 960 $re->[4] = $re_spos = $re_pos - length( $1 ) ; 961 962 ## Walk down the array looking for $re's new home. 963 ## The first few loop iterations are unrolled and done manually 964 ## for speed, which handles 85 to 90% of the cases where only 965 ## $re needs to be moved. 966 ## 967 ## Here's where that dummy regexp at the end of the array comes 968 ## in handy: we don't need to worry about array size here, since 969 ## it will always be after $re no matter what. The unrolled 970 ## loop stuff is outdented to make the conditionals fit on one 971 ## 80 char line. 972 ## Element 4 in @{$res[x]} is the start position of the match. 973 ## Element 6 is the order in which it was declared in the lang file. 974 $re_num = $re->[6] ; 975 if ( ( $re_spos <=> $res[1]->[4] || $re_num <=> $res[1]->[6] ) <= 0 ) { 976 #++$o{'1'} ; 977 next 978 } 979 $res[0] = $res[1] ; 980 981 #++$o{'2'} ; 982 if ( ( $re_spos <=> $res[2]->[4] || $re_num <=> $res[2]->[6] ) <= 0 ) { 983 $res[1] = $re ; 984 next ; 985 } 986 $res[1] = $res[2] ; 987 988 if ( ( $re_spos <=> $res[3]->[4] || $re_num <=> $res[3]->[6] ) <= 0 ) { 989 #++$o{'3'} ; 990 $res[2] = $re ; 991 next ; 992 } 993 $res[2] = $res[3] ; 994 995 if ( ( $re_spos <=> $res[4]->[4] || $re_num <=> $res[4]->[6] ) <= 0 ) { 996 #++$o{'3'} ; 997 $res[3] = $re ; 998 next ; 999 } 1000 $res[3] = $res[4] ; 1001 1002 if ( ( $re_spos <=> $res[5]->[4] || $re_num <=> $res[5]->[6] ) <= 0 ) { 1003 #++$o{'4'} ; 1004 $res[4] = $re ; 1005 next ; 1006 } 1007 $res[4] = $res[5] ; 1008 1009 #++$o{'ugh'} ; 1010 $i = 6 ; 1011 $l = $#res ; 1012 for ( ; $i < $l ; ++$i ) { 1013 last 1014 if ( 1015 ( $re_spos <=> $res[$i]->[4] || $re_num <=> $res[$i]->[6] ) 1016 <= 0 1017 ) ; 1018 $res[$i-1] = $res[$i] ; 1019 } 1020 #++$p{sprintf( "%2d", $i )} ; 1021 $res[$i-1] = $re ; 1022 } 1023 1024 next ; 1025 } 1026 1027 # =cut 1028 1029 ## 1030 ## End optimizations. You can comment them all out and this net 1031 ## does all the work, just more slowly. If you do that, then 1032 ## you also need to comment out the code below that deals with 1033 ## the second entry in @res. 1034 ## 1035 1036 #my $ni = 0 ; 1037 ## First re always needs to be tweaked 1038 #++$m ; 1039 #++$ni ; 1040 pos( $code ) = $pos ; 1041 unless ( $code =~ m/($re->[0])/gms ) { 1042 if ( @res == 2 ) { 1043 ## If the only regexp left is the dummy, we're done. 1044 $rest = substr( $code, $pos ) ; 1045 $rest =~ s/($ENTITIES)/$ENTITIES{$1}/ge ; 1046 push @$snippetlist_ref, $rest ; 1047 last ; 1048 } 1049 shift @res ; 1050 @changed_res = () ; 1051 $i = 0 ; 1052 } 1053 else { 1054 $re->[5] = $re_pos = pos( $code ) ; 1055 $re->[4] = $re_pos - length( $1 ) ; 1056 @changed_res = ( $re ) ; 1057 $i = 1 ; 1058 } 1059 1060 ## If the optimizations above are in, the second one always 1061 ## needs to be tweaked, too. 1062 $re = $res[$i] ; 1063 #++$m ; 1064 #++$ni ; 1065 pos( $code ) = $pos ; 1066 unless ( $code =~ m/($re->[0])/gms ) { 1067 if ( @res == 2 ) { 1068 ## If the only regexp left is the dummy, we're done. 1069 $rest = substr( $code, $pos ) ; 1070 $rest =~ s/($ENTITIES)/$ENTITIES{$1}/ge ; 1071 push @$snippetlist_ref, $rest ; 1072 last ; 1073 } 1074 shift @res ; 1075 } 1076 else { 1077 $re->[5] = $re_pos = pos( $code ) ; 1078 $re->[4] = $re_spos = $re_pos - length( $1 ) ; 1079 if ( @changed_res && 1080 ( $changed_res[0]->[4] <=> $re_spos || 1081 $changed_res[0]->[6] <=> $re->[6] 1082 ) > 0 1083 ) { 1084 unshift @changed_res, $re ; 1085 } 1086 else { 1087 $changed_res[$i] = $re ; 1088 } 1089 ++$i ; 1090 } 1091 1092 for ( ; ; ++$i ) { 1093 local $_ = $res[$i] ; 1094 #++$m ; 1095 last if $_->[4] >= $pos ; 1096 #++$ni ; 1097 #++$m ; 1098 pos( $code ) = $pos ; 1099 unless ( $code =~ m/($_->[0])/gms ) { 1100 if ( @res <= 2 ) { 1101 $rest = substr( $code, $pos ) ; 1102 $rest =~ s/($ENTITIES)/$ENTITIES{$1}/ge ; 1103 push @$snippetlist_ref, $rest ; 1104 last MAIN ; 1105 } 1106 ## If this regex is no longer needed, remove it by not pushing it 1107 ## on to @changed_res. This means we need one less slot in @res. 1108 shift @res ; 1109 redo ; 1110 } 1111 1112 $_->[5] = $re_pos = pos( $code ) ; 1113 $_->[4] = $re_spos = $re_pos - length( $1 ) ; 1114 1115 ## Insertion sort in to @changed_res 1116 $re_num = $_->[6] ; 1117 for ( $j = $#changed_res ; $j > -1 ; --$j ) { 1118 last 1119 if ( 1120 ( $changed_res[$j]->[4] <=> $re_spos || 1121 $changed_res[$j]->[6] <=> $re_num 1122 ) < 0 1123 ) ; 1124 $changed_res[$j+1] = $changed_res[$j] ; 1125 } 1126 $changed_res[$j+1] = $_ ; 1127 } 1128 1129 ## Merge sort @changed_res and @res in to @res 1130 $j = 0 ; 1131 $l = $#res ; 1132 for ( @changed_res ) { 1133 while ( 1134 $i < $l && 1135 ( $_->[4] <=> $res[$i]->[4] || $_->[6] <=> $res[$i]->[6] ) > 0 1136 ) { 1137 $res[$j++] = $res[$i++] ; 1138 } 1139 $res[$j++] = $_ ; 1140 } 1141 # =cut 1142 } 1143 }; 1144 1145 ################################################################################## 1146 ######################### create_snippetlist ##################################### 1147 ################################################################################## 1148 ##sub create_snippetlist 1149 ## { 1150 ## my ( $regexps_ref, $code, $snippetlist_ref ) = @_ ; 1151 1152 ## my $length = length( $code ); 1153 ## my @regexps; 1154 ## $regexps[scalar(@$regexps_ref)] = undef; 1155 1156 ## my $head_ptr = undef; 1157 ## my $current_ptr; 1158 ## my $help_ptr; 1159 1160 ## my $index = 0; 1161 1162 ## for (@$regexps_ref) 1163 ## { 1164 ## $current_ptr = $regexps[$index]; #0: start_ptr 1: length 2: next_ptr, 3: regex, 4:start, 5:end, 6: child 7: index 1165 ## $current_ptr->[7] = $index++; 1166 ## $current_ptr->[6] = $$_{'childregex'}; 1167 ## $current_ptr->[5] = $$_{'endtag'}; 1168 ## $current_ptr->[4] = $$_{'starttag'}; 1169 ## $current_ptr->[3] = $$_{'regex'}; 1170 1171 1172 ## pos( $code ) = 0; 1173 ## if ( $code =~ /($current_ptr->[3])/gms ) { $current_ptr->[0] = pos ($code) - length($1); $current_ptr->[1] = length($1); } else {next}; 1174 1175 ## if (!defined ($head_ptr) || $current_ptr->[0] < $head_ptr->[0] ) 1176 ## { 1177 ## $current_ptr->[2] = $head_ptr; 1178 ## $head_ptr = $current_ptr; 1179 ## } 1180 ## else 1181 ## { 1182 ## $help_ptr = $head_ptr; 1183 ## $help_ptr = $help_ptr->[2] 1184 ## while (defined ( $help_ptr->[2] ) && ($current_ptr->[0] >= $help_ptr->[2]->[0]) ); #iow: while (defined help->next && current->pos <= help->next->pos) 1185 1186 ## $current_ptr->[2] = $help_ptr->[2]; 1187 ## $help_ptr->[2] = $current_ptr; 1188 ## }; 1189 ## }; 1190 1191 1192 ## my $endpos = 0; 1193 ## my $oldhead; 1194 1195 ## my %entities ; 1196 ## $entities{'&'} = '&' ; 1197 ## $entities{'<'} = '<' ; 1198 ## $entities{'>'} = '>' ; 1199 ## $entities{'"'} = '"' ; 1200 1201 ## my $snippet; 1202 ## while (defined $head_ptr) 1203 ## { 1204 ## if ($head_ptr->[0] - $endpos > 0) { 1205 ## $snippet = substr($code, $endpos, $head_ptr->[0] - $endpos); 1206 ## $snippet =~ s/($ENTITIES)/$ENTITIES{$1}/ge; #"]); 1207 ## push @$snippetlist_ref, $snippet; 1208 ## }; 1209 ## push @$snippetlist_ref, $head_ptr->[4]; 1210 1211 ## &create_snippetlist( $head_ptr->[6], substr($code, $head_ptr->[0], $head_ptr->[1]) , $snippetlist_ref); 1212 ## push @$snippetlist_ref, $head_ptr->[5]; 1213 1214 ## $endpos = $head_ptr->[0] + $head_ptr->[1]; 1215 1216 ## # update & repair list : 1217 1218 ## $oldhead = $head_ptr; 1219 ## # 1) shift now invalid matches from list 1220 1221 ## $help_ptr = $head_ptr; 1222 ## $help_ptr = $help_ptr->[2] 1223 ## while (defined ( $help_ptr->[2] ) && ($endpos > $help_ptr->[2]->[0]) ); 1224 ## $head_ptr = $help_ptr->[2]; 1225 ## $help_ptr->[2] = undef; 1226 1227 ## # 2) rematch invalid matches and insert them into the list 1228 1229 ## while (defined $oldhead) 1230 ## { 1231 ## $current_ptr = $oldhead; 1232 ## $oldhead = $oldhead->[2]; 1233 1234 ## pos( $code ) = $endpos; 1235 ## if ( $code =~ /($current_ptr->[3])/gms ) { $current_ptr->[0] = pos ($code) - length($1); $current_ptr->[1] = length($1); } else {next}; 1236 ## if (!defined ($head_ptr) || 1237 ## ($current_ptr->[0] < $head_ptr->[0]) || 1238 ## ( 1239 ## ( $current_ptr->[0] == $head_ptr->[0]) && 1240 ## ( $current_ptr->[7] < $head_ptr->[7]) 1241 ## ) 1242 ## ) 1243 ## { 1244 ## $current_ptr->[2] = $head_ptr; 1245 ## $head_ptr = $current_ptr; 1246 ## } 1247 ## else 1248 ## { 1249 ## $help_ptr = $head_ptr; 1250 ## $help_ptr = $help_ptr->[2] 1251 ## while (defined ( $help_ptr->[2] ) && 1252 ## ( 1253 ## ($current_ptr->[0] > $help_ptr->[2]->[0]) || 1254 ## ( 1255 ## ( $current_ptr->[0] == $help_ptr->[2]->[0]) && 1256 ## ( $current_ptr->[7] > $help_ptr->[2]->[7]) 1257 ## ) 1258 ## ) 1259 ## ); #iow: while (defined help->next && current->pos <= help->next->pos) # if two patterns match at the same pos 1260 ## # the one that was declared earlier is taken 1261 1262 ## $current_ptr->[2] = $help_ptr->[2]; 1263 ## $help_ptr->[2] = $current_ptr; 1264 ## }; 1265 ## }; 1266 1267 ## # 3) done 1268 ## }; 1269 1270 ## $snippet = substr($code, $endpos); $snippet =~ s/($ENTITIES)/$ENTITIES{$1}/ge; #" ]); 1271 ## push @$snippetlist_ref, $snippet; 1272 ## }; 1273 1274 1275 1276 ################################################################################ 1277 ####################### put_output ############################################# 1278 ################################################################################ 1279 sub put_output { 1280 my ( $params, $snippetlist_ref, $STYLE_REF ) = @_ ; 1281 1282 my $result; 1283 1284 my $prefix = ''; 1285 $prefix = $params->{'line_number_prefix'}.'_' if defined $params->{'line_number_prefix'}; 1286 $result = & { $ { $$STYLE_REF{'linenumbers'} }{$params->{'linenumbers'}} } (join ('', @$snippetlist_ref), $prefix); 1287 1288 if (defined ($params{'linewidth'})) { 1289 $result =~ tr=\0=\n=; 1290 } 1291 1292 print FILEHANDLE $result unless (defined $params->{'dont_print_output'} && $params->{'dont_print_output'}); 1293 print FILEHANDLE $$STYLE_REF{'footer'} unless $params->{'noheader'}; 1294 1295 if (defined($params->{'outfile'})) { 1296 unless ($params->{'outfile'} eq '-'){ 1297 close (FILEHANDLE); 1298 close (STDOUT); 1299 open (STDOUT, ">&SAVEOUT"); 1300 }; 1301 }; 1302 return $result; 1303 }; 1304 1305 1306 1307 1308 ################################################################################ 1309 ####################### get_default_stylesheet ################################# 1310 ################################################################################ 1311 sub get_default_stylesheet 1312 { 1313 1314 my %STYLESHEET; 1315 1316 1317 ########## 1318 ########## different color modes for html. 1319 # those are named html-dark, html-nobc and html-light. 1320 # html-light is also named html 1321 # the only difference between html-light and html-nobc is 1322 # that html-light defines a body background and text color. 1323 # nobc stands for no body colors. 1324 1325 $STYLESHEET{'html-light'} = { 'template' => 1326 '<html> 1327 <head> 1328 <title>%%title%%</title> 1329 </head> 1330 <body bgcolor="#ffffff" text="#000000"> 1331 <pre> 1332 %%code%% 1333 </pre> 1334 <hr> 1335 syntax highlighted by <a href="http://www.palfrader.org/code2html">Code2HTML</a>, v. %%version%% 1336 </body> 1337 </html> 1338 ', 1339 'content-type' => 'text/html', 1340 'entities' => { 'listofchars' => '[<>&"]', # a regex actually 1341 'replace_by' => { 1342 '&' => '&', 1343 '<' => '<', 1344 '>' => '>', 1345 '"' => '"' 1346 } 1347 }, 1348 'linenumbers' => { 1349 'none' => sub { 1350 return $_[0]; 1351 }, 1352 'normal' => sub { 1353 # o as the first parameter is the joined snippetlist 1354 # o the second is an optional prefix, needed if more than one block 1355 # in a file is highlighted. needed in patch-mode. may be empty 1356 # the sub should the return a scalar made up of the joined lines including linenumbers 1357 my @lines = split ( /\n/, $_[0] ); 1358 1359 my $nr = 0; 1360 my $lengthofnr = length(@lines); 1361 my $format = qq{<a name="$_[1]line%u">%${lengthofnr}u</a> %s\n} ; 1362 join ('', map ( {$nr++; sprintf ( $format , $nr, $nr, $_ )} @lines)); 1363 }, 1364 'linked' => sub { 1365 # this should do the same as above only with linenumbers that link to themselves 1366 # If this style does not support this, use the same as above. 1367 my @lines = split ( /\n/, $_[0] ); 1368 1369 my $nr = 0; 1370 my $lengthofnr = length(@lines); 1371 my $format = qq{<a name="$_[1]line%u" href="#$_[1]line%u">%$ {lengthofnr}u</a> %s\n}; 1372 join ('', map ( {$nr++; sprintf ( $format , $nr, $nr, $nr, $_ )} @lines)); 1373 } 1374 }, 1375 'tags' => { 1376 'comment' => { 'start' => '<font color="#444444">', 1377 'stop' => '</font>' }, 1378 'doc comment' => { 'start' => '<font color="#444444"><i>', 1379 'stop' => '</i></font>' }, 1380 'string' => { 'start' => '<font color="#008000">', 1381 'stop' => '</font>' }, 1382 'esc string' => { 'start' => '<font color="#77dd77">', 1383 'stop' => '</font>' }, 1384 'character' => { 'start' => '<font color="#008000">', 1385 'stop' => '</font>' }, 1386 'esc character' => { 'start' => '<font color="#77dd77">', 1387 'stop' => '</font>' }, 1388 'numeric' => { 'start' => '<font color="#FF0000">', 1389 'stop' => '</font>' }, 1390 1391 'identifier' => { 'start' => '<font color="#2040a0">', 1392 'stop' => '</font>' }, 1393 'predefined identifier' => { 'start' => '<font color="#2040a0"><strong>', 1394 'stop' => '</strong></font>' }, 1395 1396 'type' => { 'start' => '<font color="#2040a0"><strong>', 1397 'stop' => '</strong></font>' }, 1398 'predefined type' => { 'start' => '<font color="#2040a0"><strong>', 1399 'stop' => '</strong></font>' }, 1400 1401 'reserved word' => { 'start' => '<strong>', 1402 'stop' => '</strong>' }, 1403 'library function' => { 'start' => '<font color="a52a2a"><strong>', 1404 'stop' => '</strong></font>' }, 1405 1406 'include' => { 'start' => '<font color="0000ff"><strong>', 1407 'stop' => '</strong></font>' }, 1408 'preprocessor' => { 'start' => '<font color="0000ff"><strong>', 1409 'stop' => '</strong></font>' }, 1410 1411 'braces' => { 'start' => '<font color="4444FF"><strong>', 1412 'stop' => '</strong></font>' }, 1413 'symbol' => { 'start' => '<font color="4444FF">', 1414 'stop' => '</font>' }, 1415 1416 'function header' => { 'start' => '<strong>', 1417 'stop' => '</strong>' }, 1418 'function header name' => { 'start' => '<font color="ff0000">', 1419 'stop' => '</font>' }, 1420 'function header args' => { 'start' => '<font color="2040a0">', 1421 'stop' => '</font>' }, 1422 1423 'regex' => { 'start' => '<font color="b000d0">', 1424 'stop' => '</font>' }, 1425 1426 'text' => { 'start' => '<i>', 1427 'stop' => '</i>'}, 1428 1429 # HTML 1430 'entity' => { 'start' => '<font color="ff0000">', 1431 'stop' => '</font>' }, 1432 1433 # MAKEFILE 1434 'assignment' => { 'start' => '<font color="2040a0">', 1435 'stop' => '</font>' }, 1436 'dependency line' => { 'start' => '<font color="8b2252">', 1437 'stop' => '</font>' }, 1438 'dependency target' => { 'start' => '<strong>', 1439 'stop' => '</strong>' }, 1440 'dependency continuation'=> { 'start' => '<font color="000000"><strong>', 1441 'stop' => '</strong></font>' }, 1442 'continuation' => { 'start' => '<strong>', 1443 'stop' => '</strong>' }, 1444 'macro' => { 'start' => '<font color="2040a0">', 1445 'stop' => '</font>' }, 1446 'int macro' => { 'start' => '<font color="4080ff">', 1447 'stop' => '</font>' }, 1448 'esc $$$' => { 'start' => '<font color="444444">', 1449 'stop' => '</font>' }, 1450 1451 # PATCH 1452 'separator' => { 'start' => '<font color="00A040"><strong>', 1453 'stop' => '</strong></font>' }, 1454 'line spec' => { 'start' => '<font color="A0A000"><strong>', 1455 'stop' => '</strong></font>' }, 1456 'deletion' => { 'start' => '<font color="FF0000"><strong>', 1457 'stop' => '</strong></font>' }, 1458 'insertion' => { 'start' => '<font color="0000FF"><strong>', 1459 'stop' => '</strong></font>' } 1460 1461 } 1462 }; 1463 # html-light is also called html 1464 1465 $STYLESHEET{'html'} = $STYLESHEET{'html-light'}; 1466 1467 1468 # html-nobc is a modification of html-light 1469 # in such a way, that the body tag does not define 1470 # a background and a text color 1471 # nobc stands for no body colors. 1472 1473 %{$STYLESHEET{'html-nobg'}} = %{$STYLESHEET{'html-light'}}; 1474 ${ $STYLESHEET{'html-nobg'}} {'template'} = '<html> 1475 <head> 1476 <title>%%title%%</title> 1477 </head> 1478 <body> 1479 <pre> 1480 %%code%% 1481 </pre> 1482 <hr> 1483 syntax highlighted by <a href="http://www.palfrader.org/code2html">Code2HTML</a>, v. %%version%% 1484 </body> 1485 </html> 1486 '; 1487 1488 1489 # html-dark is a modification of html-light 1490 # in such a way, that the body tag does define 1491 # different colors and that the <font> colors are different. 1492 1493 %{$STYLESHEET{'html-dark'}} = %{$STYLESHEET{'html-light'}}; 1494 ${ $STYLESHEET{'html-dark'}} {'template'} = '<html> 1495 <head> 1496 <title>%%title%%</title> 1497 </head> 1498 <body bgcolor="#000000" text="#C0C0C0" vlink="#FFFFFF" alink="#00FF00" link="#FFFFFF"> 1499 <pre> 1500 %%code%% 1501 </pre> 1502 <hr> 1503 syntax highlighted by <a href="http://www.palfrader.org/code2html">Code2HTML</a>, v. %%version%% 1504 </body> 1505 </html> 1506 '; 1507 ${ $STYLESHEET{'html-dark'}} {'tags'} = { 1508 'comment' => { 'start' => '<font color="#909000">', 1509 'stop' => '</font>' }, 1510 'doc comment' => { 'start' => '<font color="#909000"><i>', 1511 'stop' => '</i></font>' }, 1512 'string' => { 'start' => '<font color="yellow">', 1513 'stop' => '</font>' }, 1514 'esc string' => { 'start' => '<font color="#77dd77">', 1515 'stop' => '</font>' }, 1516 'character' => { 'start' => '<font color="yellow">', 1517 'stop' => '</font>' }, 1518 'esc character' => { 'start' => '<font color="#77dd77">', 1519 'stop' => '</font>' }, 1520 'numeric' => { 'start' => '<font color="#FF0000">', 1521 'stop' => '</font>' }, 1522 1523 'identifier' => { 'start' => '<font color="#B0B0B0">', 1524 'stop' => '</font>' }, 1525 'predefined identifier' => { 'start' => '<font color="#2040a0"><strong>', 1526 'stop' => '</strong></font>' }, 1527 1528 'type' => { 'start' => '<font color="#2040a0"><strong>', 1529 'stop' => '</strong></font>' }, 1530 'predefined type' => { 'start' => '<font color="#2040a0"><strong>', 1531 'stop' => '</strong></font>' }, 1532 1533 'reserved word' => { 'start' => '<strong>', 1534 'stop' => '</strong>' }, 1535 'library function' => { 'start' => '<font color="a52a2a"><strong>', 1536 'stop' => '</strong></font>' }, 1537 1538 'include' => { 'start' => '<font color="#00FF00">', 1539 'stop' => '</font>' }, 1540 'preprocessor' => { 'start' => '<font color="#00FF00">', 1541 'stop' => '</font>' }, 1542 1543 'braces' => { 'start' => '<font color="darkCyan"><strong>', 1544 'stop' => '</strong></font>' }, 1545 'symbol' => { 'start' => '<font color="darkCyan">', 1546 'stop' => '</font>' }, 1547 1548 'function header' => { 'start' => '<strong>', 1549 'stop' => '</strong>' }, 1550 'function header name' => { 'start' => '<font color="ff0000">', 1551 'stop' => '</font>' }, 1552 'function header args' => { 'start' => '<font color="2040a0">', 1553 'stop' => '</font>' }, 1554 1555 'regex' => { 'start' => '<font color="b000d0">', 1556 'stop' => '</font>' }, 1557 1558 'text' => { 'start' => '<i>', 1559 'stop' => '</i>'}, 1560 1561 # HTML 1562 'entity' => { 'start' => '<font color="ff0000">', 1563 'stop' => '</font>' }, 1564 1565 # MAKEFILE 1566 'assignment' => { 'start' => '<font color="2040a0">', 1567 'stop' => '</font>' }, 1568 'dependency line' => { 'start' => '<font color="8b2252">', 1569 'stop' => '</font>' }, 1570 'dependency target' => { 'start' => '<strong>', 1571 'stop' => '</strong>' }, 1572 'dependency continuation'=> { 'start' => '<font color="000000"><strong>', 1573 'stop' => '</strong></font>' }, 1574 'continuation' => { 'start' => '<strong>', 1575 'stop' => '</strong>' }, 1576 'macro' => { 'start' => '<font color="2040a0">', 1577 'stop' => '</font>' }, 1578 'int macro' => { 'start' => '<font color="4080ff">', 1579 'stop' => '</font>' }, 1580 'esc $$$' => { 'start' => '<font color="444444">', 1581 'stop' => '</font>' }, 1582 1583 # PATCH 1584 'separator' => { 'start' => '<font color="00FF00"><strong>', 1585 'stop' => '</strong></font>' }, 1586 'line spec' => { 'start' => '<font color="FFFF00"><strong>', 1587 'stop' => '</strong></font>' }, 1588 'deletion' => { 'start' => '<font color="FF0000"><strong>', 1589 'stop' => '</strong></font>' }, 1590 'insertion' => { 'start' => '<font color="0000FF"><strong>', 1591 'stop' => '</strong></font>' } 1592 }; 1593 1594 ##### 1595 # 1596 # nocolor 1597 # 1598 %{$STYLESHEET{'html-nocolor'}} = %{$STYLESHEET{'html-nobg'}}; 1599 ${ $STYLESHEET{'html-nocolor'}} {'tags'} = { 1600 'comment' => { 1601 'start' => '<I>', 1602 'stop' => '</I>' 1603 }, 1604 'doc comment' => { 1605 'start' => '', 1606 'stop' => '' 1607 }, 1608 'string' => { 1609 'start' => '<I>', 1610 'stop' => '</I>' 1611 }, 1612 'esc string' => { 1613 'start' => '', 1614 'stop' => '' 1615 }, 1616 'character' => { 1617 'start' => '', 1618 'stop' => '' 1619 }, 1620 'esc character' => { 1621 'start' => '', 1622 'stop' => '' 1623 }, 1624 'numeric' => { 1625 'start' => '', 1626 'stop' => '' 1627 }, 1628 'identifier' => { 1629 'start' => '<B>', 1630 'stop' => '</B>' 1631 }, 1632 'predefined identifier' => { 1633 'start' => '<U>', 1634 'stop' => '</U>' 1635 }, 1636 'type' => { 1637 'start' => '', 1638 'stop' => '' 1639 }, 1640 'predefined type' => { 1641 'start' => '<U>', 1642 'stop' => '</U>' 1643 }, 1644 'reserved word' => { 1645 'start' => '', 1646 'stop' => '' 1647 }, 1648 'library function' => { 1649 'start' => '', 1650 'stop' => '' 1651 }, 1652 'include' => { 1653 'start' => '', 1654 'stop' => '' 1655 }, 1656 'preprocessor' => { 1657 'start' => '<B>', 1658 'stop' => '</B>' 1659 }, 1660 'braces' => { 1661 'start' => '', 1662 'stop' => '' 1663 }, 1664 'symbol' => { 1665 'start' => '', 1666 'stop' => '' 1667 }, 1668 'function header' => { 1669 'start' => '', 1670 'stop' => '' 1671 }, 1672 'function header name' => { 1673 'start' => '', 1674 'stop' => '' 1675 }, 1676 'function header args' => { 1677 'start' => '', 1678 'stop' => '' 1679 }, 1680 'regex' => { 1681 'start' => '', 1682 'stop' => '' 1683 }, 1684 'text' => { 1685 'start' => '', 1686 'stop' => '' 1687 }, 1688 # HTML 1689 'entity' => { 1690 'start' => '', 1691 'stop' => '' 1692 }, 1693 # MAKEFILE 1694 'assignment' => { 1695 'start' => '<B>', 1696 'stop' => '</B>' 1697 }, 1698 'dependency line' => { 1699 'start' => '', 1700 'stop' => '' 1701 }, 1702 'dependency target' => { 1703 'start' => '<B>', 1704 'stop' => '</B>' 1705 }, 1706 'dependency continuation' => { 1707 'start' => '', 1708 'stop' => '' 1709 }, 1710 'continuation' => { 1711 'start' => '', 1712 'stop' => '' 1713 }, 1714 'macro' => { 1715 'start' => '<B>', 1716 'stop' => '</B>' 1717 }, 1718 'int macro' => { 1719 'start' => '<B>', 1720 'stop' => '</B>' 1721 }, 1722 'esc $$$' => { 1723 'start' => '', 1724 'stop' => '' 1725 }, 1726 # PATCH 1727 'separator' => { 1728 'start' => '<B>', 1729 'stop' => '</B>' }, 1730 'line spec' => { 1731 'start' => '', 1732 'stop' => '' 1733 }, 1734 'deletion' => { 1735 'start' => '', 1736 'stop' => '' 1737 }, 1738 'insertion' => { 1739 'start' => '', 1740 'stop' => '' 1741 } 1742 }; 1743 1744 1745 1746 ##### 1747 # 1748 # simple 1749 # 1750 %{$STYLESHEET{'html-simple'}} = %{$STYLESHEET{'html-nocolor'}}; 1751 ${ $STYLESHEET{'html-simple'}} {'template'} = '<html> 1752 <head> 1753 <title>%%title%%</title> 1754 </head> 1755 1756 <body> 1757 <h2>%%title%%</h2> 1758 <pre> 1759 %%code%% 1760 </pre> 1761 </body 1762 </html>'; 1763 1764 1765 1766 1767 # Vincent Sanders <vince@trinity.fluff.org> 1768 # html-fntlck is a modification of html-light 1769 # in such a way, that the body tag does define 1770 # different colors and that the <font> colors are different. 1771 #it is supposed to be the colours i get from emacs default font-lock mode 1772 1773 %{$STYLESHEET{'html-fntlck'}} = %{$STYLESHEET{'html-light'}}; 1774 ${ $STYLESHEET{'html-fntlck'}} {'template'} = '<html> 1775 <head> 1776 <title>%%title%%</title> 1777 </head> 1778 <body bgcolor="#ffffff" text="#000000" vlink="#0000ff" alink="#00FF00" link="#000000"> 1779 <pre> 1780 %%code%% 1781 </pre> 1782 <hr> 1783 syntax highlighted by <a href="http://www.palfrader.org/code2html">Code2HTML</a>, v. %%version%% 1784 </body> 1785 </html> 1786 '; 1787 ${ $STYLESHEET{'html-fntlck'}} {'tags'} = { 1788 'comment' => { 'start' => '<font color="bb0000">', 1789 'stop' => '</font>' }, 1790 'doc comment' => { 'start' => '<font color="bb0000"><i>', 1791 'stop' => '</i></font>' }, 1792 'string' => { 'start' => '<font color="#bb7766">', 1793 'stop' => '</font>' }, 1794 'esc string' => { 'start' => '<font color="#cc8877">', 1795 'stop' => '</font>' }, 1796 'character' => { 'start' => '<font color="#bb7766">', 1797 'stop' => '</font>' }, 1798 'esc character' => { 'start' => '<font color="#cc8877">', 1799 'stop' => '</font>' }, 1800 'numeric' => { 'start' => '<font color="#FF0000">', 1801 'stop' => '</font>' }, 1802 1803 'identifier' => { 'start' => '<font color="#0000ff">', 1804 'stop' => '</font>' }, 1805 'predefined identifier' => { 'start' => '<font color="#2040a0"><strong>', 1806 'stop' => '</strong></font>' }, 1807 1808 'type' => { 'start' => '<font color="#2040a0"><strong>', 1809 'stop' => '</strong></font>' }, 1810 'predefined type' => { 'start' => '<font color="#2040a0"><strong>', 1811 'stop' => '</strong></font>' }, 1812 1813 'reserved word' => { 'start' => '<font color="b000e0">', 1814 'stop' => '</font>' }, 1815 'library function' => { 'start' => '<font color="a52a2a"><strong>', 1816 'stop' => '</strong></font>' }, 1817 1818 'include' => { 'start' => '<font color="0000ff"><strong>', 1819 'stop' => '</strong></font>' }, 1820 'preprocessor' => { 'start' => '<font color="0000ff"><strong>', 1821 'stop' => '</strong></font>' }, 1822 1823 'braces' => { 'start' => '<font color="4444FF"><strong>', 1824 'stop' => '</strong></font>' }, 1825 'symbol' => { 'start' => '<font color="000000">', 1826 'stop' => '</font>' }, 1827 1828 'function header' => { 'start' => '<strong>', 1829 'stop' => '</strong>' }, 1830 'function header name' => { 'start' => '<font color="ff0000">', 1831 'stop' => '</font>' }, 1832 'function header args' => { 'start' => '<font color="2040a0">', 1833 'stop' => '</font>' }, 1834 1835 'regex' => { 'start' => '<font color="b000d0">', 1836 'stop' => '</font>' }, 1837 1838 'text' => { 'start' => '<i>', 1839 'stop' => '</i>'}, 1840 1841 # HTML 1842 'entity' => { 'start' => '<font color="ff0000">', 1843 'stop' => '</font>' }, 1844 1845 # MAKEFILE 1846 'assignment' => { 'start' => '<font color="2040a0">', 1847 'stop' => '</font>' }, 1848 'dependency line' => { 'start' => '<font color="8b2252">', 1849 'stop' => '</font>' }, 1850 'dependency target' => { 'start' => '<strong>', 1851 'stop' => '</strong>' }, 1852 'dependency continuation'=> { 'start' => '<font color="000000"><strong>', 1853 'stop' => '</strong></font>' }, 1854 'continuation' => { 'start' => '<strong>', 1855 'stop' => '</strong>' }, 1856 'macro' => { 'start' => '<font color="2040a0">', 1857 'stop' => '</font>' }, 1858 'int macro' => { 'start' => '<font color="4080ff">', 1859 'stop' => '</font>' }, 1860 'esc $$$' => { 'start' => '<font color="444444">', 1861 'stop' => '</font>' }, 1862 1863 # PATCH 1864 'separator' => { 'start' => '<font color="00A040"><strong>', 1865 'stop' => '</strong></font>' }, 1866 'line spec' => { 'start' => '<font color="A0A000"><strong>', 1867 'stop' => '</strong></font>' }, 1868 'deletion' => { 'start' => '<font color="FF0000"><strong>', 1869 'stop' => '</strong></font>' }, 1870 'insertion' => { 'start' => '<font color="0000FF"><strong>', 1871 'stop' => '</strong></font>' } 1872 1873 }; 1874 1875 1876 return \%STYLESHEET; 1877 1878 }; 1879 1880 1881 1882 ################################################################################ 1883 ####################### get_default_database ################################### 1884 ################################################################################ 1885 sub get_default_database 1886 { 1887 1888 my %LANGUAGE; 1889 1890 # written by PP 1891 $LANGUAGE{'plain'} = { 1892 'filename' => '', 1893 'regex' => '', 1894 'patterns' => [] 1895 }; 1896 1897 1898 1899 1900 1901 1902 # taken from nedit 1903 # modified by PP 1904 $LANGUAGE{'ada'} = { 1905 'filename' => '(?i)\\.a(d[asb]?)?$', 1906 'regex' => '', 1907 'patterns' => [ 1908 { 1909 'name' => 'Comments', 1910 'regex' => '--.*?$', 1911 'style' => 'comment', 1912 'childregex' => [], 1913 }, 1914 { 1915 'name' => 'String Literals', 1916 'regex' => '".*?("|$)', 1917 'style' => 'string', 1918 'childregex' => [] 1919 }, 1920 { 1921 'name' => 'Character Literals', 1922 'regex' => '\'.\'', 1923 'style' => 'character', 1924 'childregex' => [] 1925 }, 1926 { 1927 'name' => 'Ada Attributes', 1928 'regex' => '\'[a-zA-Z][a-zA-Z_]+\\b', 1929 'style' => 'reserved word', 1930 'childregex' => [] 1931 }, 1932 { 1933 'name' => 'Numeric Literals', 1934 'regex' => '(((2|8|10|16)#[_0-9a-fA-F]*#)|[0-9.]+)', 1935 'style' => 'numeric', 1936 'childregex' => [] 1937 }, 1938 { 1939 'name' => 'Withs Pragmas Use', 1940 'regex' => '\\b(?i)((with|pragma|use)[ \\t\\n\\f\\r]+[a-zA-Z0-9_.]+;)+\\b', 1941 'style' => 'include', 1942 'childregex' => [] 1943 }, 1944 { 1945 'name' => 'Predefined Types', 1946 'regex' => '\\b(?i)(boolean|character|count|duration|float|integer|long_float|long_integer|priority|short_float|short_integer|string)\\b', 1947 'style' => 'predefined type', 1948 'childregex' => [] 1949 }, 1950 { 1951 'name' => 'Predefined Subtypes', 1952 'regex' => '\\b(?i)field|natural|number_base|positive|priority\\b', 1953 'style' => 'predefined type', 1954 'childregex' => [] 1955 }, 1956 { 1957 'name' => 'Reserved Words', 1958 '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', 1959 'style' => 'reserved word', 1960 'childregex' => [] 1961 }, 1962 { 1963 'name' => 'Ada 95 Only', 1964 'regex' => '\\b(?i)(abstract|tagged|all|protected|aliased|requeue|until)\\b', 1965 'style' => 'reserved word', 1966 'childregex' => [] 1967 }, 1968 { 1969 'name' => 'Identifiers', 1970 'regex' => '\\b[a-zA-Z][a-zA-Z0-9_]*\\b', 1971 'style' => 'identifier', 1972 'childregex' => [] 1973 }, 1974 { 1975 'name' => 'Dot All', 1976 'regex' => '(?i)\\.all\\b', 1977 'style' => 'predefined identifier', 1978 'childregex' => [] 1979 } 1980 ] 1981 }; 1982 $LANGUAGE{'ada95'} = $LANGUAGE{'ada'}; 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 # written by JA 1999 $LANGUAGE{'awk'} = { 2000 'filename' => '(?i)\\.awk$', 2001 'regex' => '^\\s*#\\s*![^\\s]*awk', 2002 'patterns' => [ 2003 { 2004 'name' => 'comment', 2005 'regex' => '#.*?$', 2006 'style' => 'comment', 2007 'childregex' => [] 2008 }, 2009 { 2010 'name' => 'string', 2011 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 2012 # 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 2013 'style' => 'string', 2014 'childregex' => [ 2015 { 2016 'name' => 'esc character', 2017 'regex' => '\\\\.', 2018 'style' => 'esc character', 2019 'childregex' => [] 2020 } 2021 ] 2022 }, 2023 { 2024 'name' => 'string', 2025 'regex' => '\'\'|\'.*?([^\\\\](\\\\\\\\)*)\'|\'\\\\\\\\\'', 2026 # 'regex' => '\'\'|\'\\\\\\\\\'|\'[^\'\\\\]\'|\'[^\'].*?[^\\\\]\'', 2027 'style' => 'string', 2028 'childregex' => [ 2029 { 2030 'name' => 'esc character', 2031 'regex' => '\\\\.', 2032 'style' => 'esc character', 2033 'childregex' => [] 2034 } 2035 ] 2036 }, 2037 { 2038 'name' => 'function header', 2039 'regex' => 'function[\\t ]+([a-zA-Z0-9_]+)[\\t \\n]*(\\{|\\n)', 2040 'style' => 'function header', 2041 'childregex' => [ 2042 { 2043 'name' => 'function coloring', 2044 'regex' => '[\\t ]([a-zA-Z0-9_]+)', 2045 'style' => 'function header name', 2046 'childregex' => [] 2047 } 2048 ] 2049 }, 2050 { 2051 'name' => 'regex matching I 1', 2052 'regex' => '(\\b| )?(/)(\\\\/|[^/\\n])*(/[gimesox]*)', 2053 'style' => 'regex', 2054 'childregex' => [] 2055 }, 2056 { 2057 'name' => 'regex matching I 2', 2058 'regex' => '(?:\\b| )(?:(?:m|q|qq)([!"#$%&\'*+-/]))(\\\\\\2|[^\\2\\n])*(\\2[gimesox]*)', 2059 'style' => 'regex', 2060 'childregex' => [] 2061 }, 2062 { 2063 'name' => 'regex matching II', 2064 'regex' => '(?:\\b| )?(?:s([!"#$%&\'*+-/]))(?:\\\\\\2|[^\\2\\n])*?(\\2)[^(\\2)\\n]*?(\\2[gimesox]*)', 2065 'style' => 'regex', 2066 'childregex' => [] 2067 }, 2068 { 2069 'name' => 'translate', 2070 'regex' => '(?:\\b| )(?:(?:tr|y)([^\w\s]))(?:\\\\\\2|[^\\2\\n])*?(\\2)[^(\\2)\\n]*?(\\2[gimesox]*)', 2071 'style' => 'regex', 2072 'childregex' => [] 2073 }, 2074 { 2075 'name' => 'keywords', 2076 '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', 2077 'style' => 'reserved word', 2078 'childregex' => [] 2079 }, 2080 { 2081 'name' => 'keywords 2', 2082 'regex' => '\\b(if|while|do|for|in|break|continue|delete|exit|next|nextfile|function)\\b', 2083 'style' => 'reserved word', 2084 'childregex' => [] 2085 }, 2086 { 2087 'name' => 'library fns', 2088 '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', 2089 'style' => 'library function', 2090 'childregex' => [] 2091 }, 2092 { 2093 'name' => 'braces and parens', 2094 'regex' => '[\\[\\]\\{\\}\\(\\)]', 2095 'style' => 'braces', 2096 'childregex' => [] 2097 }, 2098 { 2099 'name' => '<< stuff', 2100 'regex' => '<<\'([^\\n]*)\';.*?^\\2$', 2101 'style' => 'text', 2102 'childregex' => [] 2103 }, 2104 { 2105 'name' => '<< stuff', 2106 'regex' => '<<([^\\n]*).*?^\\2$', 2107 'style' => 'text', 2108 'childregex' => [] 2109 } 2110 ] 2111 }; 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 # taken from nedit 2128 # modified by PP 2129 $LANGUAGE{'c'} = { 2130 'filename' => '\\.[ch]$', 2131 'regex' => '', 2132 'patterns' => [ 2133 { 2134 'name' => 'doc comment', 2135 'regex' => '/\\*\\*.*?\\*/', 2136 'style' => 'doc comment', 2137 'childregex' => [] 2138 }, 2139 { 2140 'name' => 'comment', 2141 'regex' => '/\\*.*?\\*/', 2142 'style' => 'comment', 2143 'childregex' => [] 2144 }, 2145 { 2146 'name' => 'string', 2147 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 2148 # 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 2149 'style' => 'string', 2150 'childregex' => [ 2151 { 2152 'name' => 'esc character', 2153 'regex' => '\\\\.', 2154 'style' => 'esc character', 2155 'childregex' => [] 2156 } 2157 ] 2158 }, 2159 { 2160 'name' => 'preprocessor line', 2161 'regex' => '^[ \\t]*#.*?$', 2162 'style' => 'preprocessor', 2163 'childregex' => [ 2164 { 2165 'name' => 'string', 2166 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 2167 # 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 2168 'style' => 'string', 2169 'childregex' => [ 2170 { 2171 'name' => 'esc character', 2172 'regex' => '\\\\.', 2173 'style' => 'esc character', 2174 'childregex' => [] 2175 } 2176 ] 2177 }, 2178 { 2179 'name' => '<files>', 2180 'regex' => '<.*?>', 2181 'style' => 'string', 2182 'childregex' => [] 2183 }, 2184 { 2185 'name' => 'comment', 2186 'regex' => '[^/]/\\*.*?\\*/', 2187 'style' => 'comment', 2188 'childregex' => [] 2189 } 2190 ] 2191 }, 2192 { 2193 'name' => 'character constant', 2194 'regex' => '\'(\\\\)?.\'', 2195 'style' => 'character', 2196 'childregex' => [ 2197 { 2198 'name' => 'esc character', 2199 'regex' => '\\\\.', 2200 'style' => 'esc character', 2201 'childregex' => [] 2202 } 2203 ] 2204 }, 2205 { 2206 'name' => 'numeric constant', 2207 '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', 2208 'style' => 'numeric', 2209 'childregex' => [] 2210 }, 2211 { 2212 'name' => 'storage keyword', 2213 'regex' => '\\b(const|extern|auto|register|static|unsigned|signed|volatile|char|double|float|int|long|short|void|typedef|struct|union|enum)\\b', 2214 'style' => 'reserved word', 2215 'childregex' => [] 2216 }, 2217 { 2218 'name' => 'keyword', 2219 'regex' => '\\b(return|goto|if|else|case|default|switch|break|continue|while|do|for|sizeof)\\b', 2220 'style' => 'reserved word', 2221 'childregex' => [] 2222 }, 2223 { 2224 'name' => 'braces', 2225 'regex' => '[\\{\\}]', 2226 'style' => 'braces', 2227 'childregex' => [] 2228 }, 2229 { 2230 'name' => 'symbols', 2231 'regex' => '([\\*\\-\\+=:;%&\\|<>\\(\\)\\[\\]!])', 2232 'style' => 'symbol', 2233 'childregex' => [] 2234 }, 2235 { 2236 'name' => 'identifiers', 2237 'regex' => '([a-zA-Z_][a-zA-Z_0-9]*)', 2238 'style' => 'identifier', 2239 'childregex' => [] 2240 } 2241 ] 2242 }; 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 # taken from nedit 2259 # modified by PP 2260 $LANGUAGE{'c++'} = { 2261 'filename' => '\\.(c(c|pp|xx)|h(h|pp|xx)|C(C|PP|XX)?|H(H|PP|XX)?|i)$', 2262 'regex' => '', 2263 'patterns' => [ 2264 { 2265 'name' => 'doc comment', 2266 'regex' => '/\\*\\*.*?\\*/', 2267 'style' => 'doc comment', 2268 'childregex' => [] 2269 }, 2270 { 2271 'name' => 'comment', 2272 'regex' => '/\\*.*?\\*/', 2273 'style' => 'comment', 2274 'childregex' => [] 2275 }, 2276 { 2277 'name' => 'cplus comment', 2278 'regex' => '//.*?$', 2279 'style' => 'comment', 2280 'childregex' => [] 2281 }, 2282 { 2283 'name' => 'string', 2284 'regex' => '""|"\\\\\\\\"|".*?([^\\\\](\\\\\\\\)*)"', 2285 # 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 2286 'style' => 'string', 2287 'childregex' => [ 2288 { 2289 'name' => 'esc character', 2290 'regex' => '\\\\.', 2291 'style' => 'esc character', 2292 'childregex' => [] 2293 } 2294 ] 2295 }, 2296 { 2297 'name' => 'preprocessor line', 2298 'regex' => '^[ \\t]*#.*?$', 2299 'style' => 'preprocessor', 2300 'childregex' => [ 2301 { 2302 'name' => 'string', 2303 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 2304 # 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 2305 'style' => 'string', 2306 'childregex' => [ 2307 { 2308 'name' => 'esc character', 2309 'regex' => '\\\\.', 2310 'style' => 'esc character', 2311 'childregex' => [] 2312 } 2313 ] 2314 }, 2315 { 2316 'name' => '<files>', 2317 'regex' => '<.*?>', 2318 'style' => 'string', 2319 'childregex' => [] 2320 }, 2321 { 2322 'name' => 'comment', 2323 'regex' => '[^/]/\\*.*?\\*/', 2324 'style' => 'comment', 2325 'childregex' => [] 2326 }, 2327 { 2328 'name' => 'cplus comment', 2329 'regex' => '//.*?$', 2330 'style' => 'comment', 2331 'childregex' => [] 2332 } 2333 ] 2334 }, 2335 { 2336 'name' => 'character constant', 2337 'regex' => '\'(\\\\)?.\'', 2338 'style' => 'character', 2339 'childregex' => [ 2340 { 2341 'name' => 'esc character', 2342 'regex' => '\\\\.', 2343 'style' => 'esc character', 2344 'childregex' => [] 2345 } 2346 ] 2347 }, 2348 { 2349 'name' => 'numeric constant', 2350 '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', 2351 'style' => 'numeric', 2352 'childregex' => [] 2353 }, 2354 { 2355 'name' => 'storage keyword', 2356 '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', 2357 'style' => 'reserved word', 2358 'childregex' => [], 2359 }, 2360 { 2361 'name' => 'keyword', 2362 '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', 2363 'style' => 'reserved word', 2364 'childregex' => [] 2365 }, 2366 { 2367 'name' => 'braces', 2368 'regex' => '[\\{\\}]', 2369 'style' => 'braces', 2370 'childregex' => [] 2371 }, 2372 { 2373 'name' => 'symbols', 2374 'regex' => '([\\*\\-\\+=:;%&\\|<>\\(\\)\\[\\]!])', 2375 'style' => 'symbol', 2376 'childregex' => [] 2377 }, 2378 { 2379 'name' => 'identifiers', 2380 'regex' => '([a-zA-Z_][a-zA-Z_0-9]*)', 2381 'style' => 'identifier', 2382 'childregex' => [] 2383 } 2384 ] 2385 }; 2386 $LANGUAGE{'cc'} = $LANGUAGE{'c++'}; 2387 $LANGUAGE{'cpp'} = $LANGUAGE{'c++'}; 2388 $LANGUAGE{'cxx'} = $LANGUAGE{'c++'}; 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 # written by VRS 2400 $LANGUAGE{'gpasm'} = { 2401 'filename' => '(?i)\\.(asm|inc)$', 2402 'regex' => '', 2403 'patterns' => [ 2404 { 2405 'name' => 'args', 2406 'regex' => '^.*$', 2407 'style' => 'symbol', 2408 'childregex' => [ 2409 { 2410 'name' => 'comment', 2411 'regex' => ';.*?$', 2412 'style' => 'comment', 2413 'childregex' => [] 2414 }, 2415 { 2416 'name' => 'labels', 2417 'regex' => '^[A-Za-z_][A-Za-z_0-9]*:?', 2418 'style' => 'identifier', 2419 'childregex' => [] 2420 }, 2421 2422 { 2423 'name' => 'menonics', 2424 'regex' => '^[ \t]+[A-Za-z_][A-Za-z_0-9]*', 2425 'style' => 'reserved word', 2426 'childregex' => [] 2427 }, 2428 { 2429 'name' => 'string', 2430 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 2431 'style' => 'string', 2432 'childregex' => [ 2433 { 2434 'name' => 'esc character', 2435 'regex' => '\\\\.', 2436 'style' => 'esc character', 2437 'childregex' => [] 2438 } 2439 ] 2440 } 2441 2442 2443 ] 2444 } 2445 ] 2446 }; 2447 2448 2449 2450 2451 2452 2453 2454 2455 # written by JA 2456 $LANGUAGE{'groff'} = { 2457 'filename' => '\\.groff$', 2458 'regex' => '', 2459 'patterns' => [ 2460 { 2461 'name' => 'comment', 2462 'regex' => '\\\\".*?$', 2463 'style' => 'comment', 2464 'childregex' => [] 2465 } 2466 ] 2467 }; 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 # taken from nedit 2484 # modified by PP 2485 $LANGUAGE{'html'} = { 2486 'filename' => '(?i)\\.html?$', 2487 'regex' => '', 2488 'patterns' => [ 2489 { 2490 'name' => 'comment', 2491 'regex' => '<!--.*?-->', 2492 'style' => 'comment', 2493 'childregex' => [] 2494 }, 2495 { 2496 'name' => 'entity', 2497 'regex' => '\\&[-.a-zA-Z0-9#]*;?', 2498 'style' => 'entity', 2499 'childregex' => [] 2500 }, 2501 { 2502 'name' => 'tag', 2503 'regex' => '<(/|!)?[-.a-zA-Z0-9]*.*?>', 2504 'style' => 'predefined identifier', 2505 'childregex' => [ 2506 { 2507 'name' => 'double quote string', 2508 'regex' => '".*?"', 2509 'style' => 'string', 2510 'childregex' => [] 2511 }, 2512 { 2513 'name' => 'single quote string', 2514 'regex' => '\'.*?\'', 2515 'style' => 'string', 2516 'childregex' => [] 2517 }, 2518 { 2519 'name' => 'brackets', 2520 'regex' => '[<>]', 2521 'style' => 'braces', 2522 'childregex' => [] 2523 }, 2524 { 2525 'name' => 'attribute', 2526 'regex' => '[^\'" ]+(?=.)', 2527 'style' => 'identifier', 2528 'childregex' => [] 2529 } 2530 ] 2531 } 2532 ] 2533 }; 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 # taken from nedit 2550 # modified by PP 2551 $LANGUAGE{'java'} = { 2552 'filename' => '\\.java$', 2553 'regex' => '', 2554 'patterns' => [ 2555 { 2556 'name' => 'doc comment', 2557 'regex' => '/\\*\\*.*?\\*/', 2558 'style' => 'doc comment', 2559 'childregex' => [] 2560 }, 2561 { 2562 'name' => 'comment', 2563 'regex' => '/\\*.*?\\*/', 2564 'style' => 'comment', 2565 'childregex' => [] 2566 }, 2567 { 2568 'name' => 'cplus comment', 2569 'regex' => '//.*?$', 2570 'style' => 'comment', 2571 'childregex' => [] 2572 }, 2573 { 2574 'name' => 'string', 2575 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 2576 # 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 2577 'style' => 'string', 2578 'childregex' => [ 2579 { 2580 'name' => 'esc character', 2581 'regex' => '\\\\.', 2582 'style' => 'esc character', 2583 'childregex' => [] 2584 } 2585 ] 2586 }, 2587 { 2588 'name' => 'single quoted', 2589 'regex' => '\'\'|\'.*?([^\\\\](\\\\\\\\)*)\'|\'\\\\\\\\\'', 2590 # 'regex' => '\'\'|\'\\\\\\\\\'|\'[^\'\\\\]\'|\'[^\'].*?[^\\\\]\'', 2591 'style' => 'string', 2592 'childregex' => [] 2593 }, 2594 { 2595 'name' => 'numeric constant', 2596 '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', 2597 'style' => 'numeric', 2598 'childregex' => [] 2599 }, 2600 { 2601 'name' => 'include', 2602 'regex' => '\\b(import|package)\\b.*?$', 2603 'style' => 'include', 2604 'childregex' => [ 2605 { 2606 'name' => 'esc character', 2607 'regex' => '\\\\(.|\\n)', 2608 'style' => 'esc character', 2609 'childregex' => [] 2610 }, 2611 { 2612 'name' => 'comment', 2613 'regex' => '[^/]/\\*.*?\\*/', 2614 'style' => 'comment', 2615 'childregex' => [] 2616 } 2617 ] 2618 }, 2619 { 2620 'name' => 'storage keyword', 2621 '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', 2622 'style' => 'reserved word', 2623 'childregex' => [] 2624 }, 2625 { 2626 'name' => 'keyword', 2627 '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', 2628 'style' => 'reserved word', 2629 'childregex' => [] 2630 }, 2631 { 2632 'name' => 'braces and parens', 2633 'regex' => '[\\{\\}\\(\\)\\[\\]]', 2634 'style' => 'braces', 2635 'childregex' => [] 2636 }, 2637 { 2638 'name' => 'Identifiers', 2639 'regex' => '\\b[a-zA-Z_][a-zA-Z0-9_]*\\b', 2640 'style' => 'identifier', 2641 'childregex' => [] 2642 }, 2643 { 2644 'name' => 'symbols', 2645 'regex' => '([\\*\\-\\+=:;%&\\|<>!])', 2646 'style' => 'symbol', 2647 'childregex' => [] 2648 } 2649 ] 2650 }; 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 # taken from nedit 2666 # modified by PP 2667 $LANGUAGE{'javascript'} = { 2668 'filename' => '(?i)\\.js$', 2669 'regex' => '', 2670 'patterns' => [ 2671 { 2672 'name' => 'comment', 2673 'regex' => '/\\*.*?\\*/', 2674 'style' => 'comment', 2675 'childregex' => [] 2676 }, 2677 { 2678 'name' => 'cplus comment', 2679 'regex' => '//.*?$', 2680 'style' => 'comment', 2681 'childregex' => [] 2682 }, 2683 { 2684 'name' => 'numeric constant', 2685 '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', 2686 'style' => 'numeric', 2687 'childregex' => [] 2688 }, 2689 { 2690 'name' => 'events', 2691 'regex' => '\\b(onAbort|onBlur|onClick|onChange|onDblClick|onDragDrop|onError|onFocus|onKeyDown|onKeyPress|onLoad|onMouseDown|onMouseMove|onMouseOut|onMouseOver|onMouseUp|onMove|onResize|onSelect|onSubmit|onUnload)\\b', 2692 'style' => 'reserved word', 2693 'childregex' => [] 2694 }, 2695 { 2696 'name' => 'braces', 2697 'regex' => '[\\{\\}]', 2698 'style' => 'braces', 2699 'childregex' => [] 2700 }, 2701 { 2702 'name' => 'statements', 2703 'regex' => '\\b(break|continue|else|for|if|in|new|return|this|typeof|var|while|with)\\b', 2704 'style' => 'reserved word', 2705 'childregex' => [] 2706 }, 2707 { 2708 'name' => 'function', 2709 'regex' => 'function[\\t ]+([a-zA-Z0-9_]+)[\\t \\(]+.*?[\\n{]', 2710 'style' => 'function header', 2711 'childregex' => [ 2712 { 2713 'name' => 'function args', 2714 'regex' => '\\(.*?\\)', 2715 'style' => 'function header args', 2716 'childregex' => [] 2717 }, 2718 { 2719 'name' => 'function name', 2720 'regex' => '[\\t ][a-zA-Z0-9_]+', 2721 'style' => 'function header name', 2722 'childregex' => [] 2723 } 2724 ] 2725 }, 2726 { 2727 'name' => 'built in object type', 2728 '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', 2729 'style' => 'predefined type', 2730 'childregex' => [] 2731 }, 2732 { 2733 'name' => 'string', 2734 'regex' => '".*?("|$)', 2735 'style' => 'string', 2736 'childregex' => [ 2737 { 2738 'name' => 'colors', 2739 '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])', 2740 'style' => 'identifier', 2741 'childregex' => [] 2742 } 2743 ] 2744 }, 2745 { 2746 'name' => 'string', 2747 'regex' => '\'.*?(\'|$)', 2748 'style' => 'string', 2749 'childregex' => [ 2750 { 2751 'name' => 'colors', 2752 '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])', 2753 'style' => 'identifier', 2754 'childregex' => [], 2755 } 2756 ] 2757 }, 2758 { 2759 'name' => 'event capturing', 2760 'regex' => '\\b(captureEvents|releaseEvents|routeEvent|handleEvent)\\b.*?(\\)|$)', 2761 'style' => 'reserved word', 2762 'childregex' => [] 2763 }, 2764 { 2765 'name' => 'predefined methods', 2766 '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', 2767 'style' => 'library function', 2768 'childregex' => [] 2769 }, 2770 { 2771 'name' => 'properties', 2772 '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', 2773 'style' => 'predefined identifier', 2774 'childregex' => [] 2775 }, 2776 { 2777 'name' => 'operators', 2778 'regex' => '([=;->/&|])', 2779 'style' => 'symbol', 2780 'childregex' => [] 2781 } 2782 ] 2783 }; 2784 $LANGUAGE{'js'} = $LANGUAGE{'javascript'}; 2785 2786 2787 2788 2789 2790 2791 2792 2793 # written by Andreas Krennmair 2794 # extremely incomplete 2795 2796 $LANGUAGE{'lisp'} = { 2797 'filename' => '\\.(lsp|l)$', 2798 'regex' => '', 2799 'patterns' => [ 2800 { 2801 'name' => 'parens', 2802 'regex' => '[()]', 2803 'style' => 'braces', 2804 'childregex' => [] 2805 }, 2806 { 2807 'name' => 'comment', 2808 'regex' => ';.*?$', 2809 'style' => 'comment', 2810 'childregex' => [] 2811 }, 2812 { 2813 'name' => 'string', 2814 'regex' => '".*?("|$)', 2815 'style' => 'string', 2816 'childregex' => [] 2817 }, 2818 { 2819 'name' => 'keywords', 2820 'regex' => '\\b(defun |xyz)\\b', 2821 'style' => 'reserved word', 2822 'childregex' => [] 2823 }, 2824 { 2825 'name' => 'numeric constant', 2826 'regex' => '(#\([0-9]+ [0-9]+\)|[0-9]+)', 2827 'style' => 'numeric', 2828 'childregex' => [] 2829 }, 2830 { 2831 'name' => 'identifiers', 2832 'regex' => '([-a-zA-Z]+)', 2833 'style' => 'identifier', 2834 'childregex' => [] 2835 } 2836 ] 2837 }; 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 # written by JA 2849 $LANGUAGE{'m4'} = { 2850 'filename' => '\\.m4$', 2851 'regex' => '', 2852 'patterns' => [ 2853 { 2854 'regex' => 'dnl.*?$', 2855 'style' => 'doc comment', 2856 'childregex' => [] 2857 }, 2858 { 2859 'regex' => '#.*?$', 2860 'style' => 'comment', 2861 'childregex' => [] 2862 }, 2863 { 2864 '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', 2865 'style' => 'reserved word', 2866 'childregex' => [] 2867 }, 2868 { 2869 'regex' => '\\b(ifdef|ifelse|loops)\\b', 2870 'style' => 'reserved word', 2871 'childregex' => [ 2872 { 2873 'regex' => '[$]\\$?({[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?', 2874 'style' => 'identifier', 2875 'childregex' => [] 2876 } 2877 ] 2878 } 2879 ] 2880 }; 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 # taken from nedit 2897 # modified by PP 2898 $LANGUAGE{'make'} = { 2899 'filename' => '[Mm]akefile.*', 2900 'regex' => '', 2901 'patterns' => [ 2902 { 2903 'name' => 'Comment', 2904 'regex' => '#.*?$', 2905 'style' => 'comment', 2906 'childregex' => [] 2907 }, 2908 { 2909 'name' => 'Assignment', 2910 'regex' => '^( *| [ \\t]*)[A-Za-z0-9_+]*[ \\t]*(\\+|:)?=', 2911 'style' => 'assignment', 2912 'childregex' => [] 2913 }, 2914 { 2915 'name' => 'Dependency Line', 2916 'regex' => '^ *([A-Za-z0-9./$(){} _%+-]|\\n)*::?', 2917 'style' => 'dependency line', 2918 'childregex' => [ 2919 { 2920 'name' => 'Dependency Target', 2921 'regex' => '[A-Za-z0-9./$(){} _%+-]+', 2922 'style' => 'dependency target', 2923 'childregex' => [] 2924 }, 2925 { 2926 'name' => 'Dependency Continuation', 2927 'regex' => '\\\\\\n', 2928 'style' => 'dependency continuation', 2929 'childregex' => [] 2930 }, 2931 { 2932 'name' => 'comment', 2933 'regex' => '#.*?$', 2934 'style' => 'comment', 2935 'childregex' => [] 2936 }, 2937 { 2938 'name' => 'macro', 2939 'regex' => '\\$([A-Za-z0-9_]|\\([^)]*\\)|{[^}]*})', 2940 'style' => 'macro', 2941 'childregex' => [] 2942 }, 2943 { 2944 'name' => 'int macro', 2945 'regex' => '\\$([<@*?%]|\\$@)', 2946 'style' => 'int macro', 2947 'childregex' => [] 2948 } 2949 ] 2950 }, 2951 { 2952 'name' => 'Continuation', 2953 'regex' => '\\\\$', 2954 'style' => 'continuation', 2955 'childregex' => [] 2956 }, 2957 { 2958 'name' => 'Macro', 2959 'regex' => '\\$([A-Za-z0-9_]|\\([^)]*\\)|{[^}]*})', 2960 'style' => 'macro', 2961 'childregex' => [] 2962 }, 2963 { 2964 'name' => 'Internal Macro', 2965 'regex' => '\\$([<@*?%]|\\$@)', 2966 'style' => 'int macro', 2967 'childregex' => [] 2968 }, 2969 { 2970 'name' => 'Escaped $$$', 2971 'regex' => '\\$\\$', 2972 'style' => 'esc $$$', 2973 'childregex' => [] 2974 }, 2975 { 2976 'name' => 'Include', 2977 'regex' => '^include[ \\t]', 2978 'style' => 'include', 2979 'childregex' => [] 2980 } 2981 ] 2982 }; 2983 $LANGUAGE{'makefile'} = $LANGUAGE{'make'}; 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 # taken from nedit 3000 # modified by PP 3001 $LANGUAGE{'pas'} = { 3002 'filename' => '(?i)\\.p(as)?$', 3003 'regex' => '', 3004 'patterns' => [ 3005 { 3006 'name' => 'comment1 (* *)', 3007 'regex' => '\\(\\*.*?\\*\\)', 3008 'style' => 'comment', 3009 'childregex' => [] 3010 }, 3011 { 3012 'name' => 'comment2 { }', 3013 'regex' => '\\{.*?\\}', 3014 'style' => 'comment', 3015 'childregex' => [] 3016 }, 3017 { 3018 'name' => 'string', 3019 'regex' => '\'.*?(\'|$)', 3020 'style' => 'string', 3021 'childregex' => [] 3022 }, 3023 { 3024 'name' => 'preprocessor line', 3025 'regex' => '^[ \\t]*#.*?$', 3026 'style' => 'preprocessor', 3027 'childregex' => [ 3028 { 3029 'name' => 'comment1 (* *)', 3030 'regex' => '\\(\\*.*?\\*\\)', 3031 'style' => 'comment', 3032 'childregex' => [] 3033 }, 3034 { 3035 'name' => 'comment2 { }', 3036 'regex' => '\\{.*?\\}', 3037 'style' => 'comment', 3038 'childregex' => [] 3039 } 3040 ] 3041 }, 3042 { 3043 'name' => 'character constant', 3044 'regex' => '\'.\'', 3045 'style' => 'character', 3046 'childregex' => [] 3047 }, 3048 { 3049 'name' => 'numeric constant', 3050 'regex' => '\\b((0(x|X)[0-9a-fA-F]*)|[0-9.]+((e|E)(\\+|-)?)?[0-9]*)(L|l|UL|ul|u|U|F|f)?\\b', 3051 'style' => 'numeric', 3052 'childregex' => [] 3053 }, 3054 { 3055 'name' => 'storage and ops', 3056 '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', 3057 'style' => 'reserved word', 3058 'childregex' => [] 3059 }, 3060 { 3061 'name' => 'keywords', 3062 'regex' => '\\b(?i)(begin|case|do|downto|else|end|for|goto|if|of|otherwise|repeat|then|to|until|while|with)\\b', 3063 'style' => 'reserved word', 3064 'childregex' => [] 3065 }, 3066 { 3067 'name' => 'sumbols', 3068 'regex' => '([\\*\\-\\+=:;<>\\(\\)\\[\\]!]|[^/]/[^/])', 3069 'style' => 'symbol', 3070 'childregex' => [] 3071 }, 3072 { 3073 'name' => 'identifiers', 3074 'regex' => '([a-zA-Z_][a-zA-Z_0-9.^]*[a-zA-Z_0-9]|[a-zA-Z_][a-zA-Z_0-9]*)', 3075 'style' => 'identifier', 3076 'childregex' => [ 3077 { 3078 'regex' => '(\\.|\\^)+', 3079 'style' => 'symbol', 3080 'childregex' => [] 3081 } 3082 ] 3083 } 3084 ], 3085 }; 3086 $LANGUAGE{'pascal'} = $LANGUAGE{'pas'}; 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 # taken from nedit 3103 # modified by PP 3104 # modified by BS 3105 # modified by JD 3106 # modified by JP 3107 $LANGUAGE{'perl'} = { 3108 'filename' => '(?i)\\.p([lm5]|od)$', 3109 'regex' => '^\\s*#\\s*![^\\s]*perl', 3110 'patterns' => [ 3111 { 3112 'name' => 'comment', 3113 'regex' => '(?:#.*?(?:\r?\n\s*)+)+', 3114 'style' => 'comment', 3115 'childregex' => [] 3116 }, 3117 { 3118 'name' => 'variables', 3119 'regex' => '[\\$@%]\\$?(?:{[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?', 3120 'style' => 'identifier', 3121 'childregex' => [] 3122 }, 3123 { 3124 'name' => '"" string', 3125 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 3126 # 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 3127 'style' => 'string', 3128 'childregex' => [ 3129 { 3130 'name' => 'esc character', 3131 'regex' => '\\\\.', 3132 'style' => 'esc character', 3133 'childregex' => [] 3134 }, 3135 { 3136 'name' => 'variables', 3137 'regex' => '[\\$@%]\\$?(?:{[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?', 3138 'style' => 'identifier', 3139 'childregex' => [] 3140 } 3141 ] 3142 }, 3143 { 3144 'name' => '\'\' string', 3145 'regex' => '\'\'|\'.*?([^\\\\](\\\\\\\\)*)\'|\'\\\\\\\\\'', 3146 # 'regex' => '\'\'|\'\\\\\\\\\'|\'[^\'\\\\]\'|\'[^\'].*?[^\\\\]\'', 3147 'style' => 'string', 3148 'childregex' => [ 3149 { 3150 'name' => 'esc character', 3151 'regex' => '\\\\.', 3152 'style' => 'esc character', 3153 'childregex' => [] 3154 } 3155 ] 3156 }, 3157 { 3158 'name' => 'more strings - q// qw//', 3159 'regex' => '(?:\\b| )(?:q|qw)([^\w\s])(?:\\\\\\2|[^\\2\\n])*\\2', 3160 'style' => 'string', 3161 'childregex' => [ 3162 { 3163 'name' => 'esc character', 3164 'regex' => '\\\\.', 3165 'style' => 'esc character', 3166 'childregex' => [] 3167 } 3168 ] 3169 }, 3170 { 3171 'name' => 'more strings - qq// qx//', 3172 'regex' => '(?:\\b| )(?:qq|qx)([^\w\s])(?:\\\\\\2|[^\\2\\n])*\\2', 3173 'style' => 'string', 3174 'childregex' => [ 3175 { 3176 'name' => 'esc character', 3177 'regex' => '\\\\.', 3178 'style' => 'esc character', 3179 'childregex' => [] 3180 }, 3181 { 3182 'name' => 'variables', 3183 'regex' => '[\\$@%]\\$?(?:{[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?', 3184 'style' => 'identifier', 3185 'childregex' => [] 3186 } 3187 ] 3188 }, 3189 { 3190 'name' => 'subroutine header', 3191 'regex' => 'sub[\\t ]+(?:[a-zA-Z0-9_]+)[\\t \\n]*(?:\\{|\\(|\\n)', 3192 'style' => 'function header', 3193 'childregex' => [ 3194 { 3195 'name' => 'subroutine header coloring', 3196 'regex' => '[\\t ][a-zA-Z0-9_]+', 3197 'style' => 'function header name', 3198 'childregex' => [] 3199 } 3200 ] 3201 }, 3202 { 3203 'name' => 'regex matching I', 3204 'regex' => '(?:\\b| )?(?:/(?:\\\\/|[^/\\n])*(?:/[gimesox]*)|s([^\w\s])(?:\\\\\\2|[^\\2\\n])*?(\\2)[^(\\2)\\n]*?(\\2[gimesox]*))', 3205 'style' => 'regex', 3206 'childregex' => [] 3207 }, 3208 { 3209 'name' => 'regex matching II', 3210 'regex' => '(?:\\b| )(?:m|qq?|tr|y)([^\w\s])(?:\\\\\\2|[^\\2\\n])*(?:\\2[gimesox]*)', 3211 'style' => 'regex', 3212 'childregex' => [] 3213 }, 3214 { 3215 'name' => 'keywords', 3216 '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', 3217 'style' => 'reserved word', 3218 'childregex' => [] 3219 }, 3220 { 3221 'name' => 'library functions', 3222 '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', 3223 'style' => 'library function', 3224 'childregex' => [] 3225 }, 3226 { 3227 'name' => 'braces, parens and brakets', 3228 'regex' => '[\\[\\]\\{\\}\\(\\)]', 3229 'style' => 'braces', 3230 'childregex' => [] 3231 }, 3232 { 3233 'name' => '<< stuff', 3234 'regex' => '<<(?:("|\')([^\\n]*)\\2|\\w*).*?^\\3$', 3235 'style' => 'text', 3236 'childregex' => [] 3237 }, 3238 { 3239 'name' => 'POD', 3240 'regex' => '^=.*?^(?:=cut|\\Z)', 3241 'style' => 'doc comment', 3242 'childregex' => [] 3243 } 3244 ] 3245 }; 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 # Thanks to Matt Giwer <jull43@ij.net> 3262 $LANGUAGE{'pov'} = { 3263 'filename' => '(?i)\\.pov$', 3264 'regex' => '', 3265 'patterns' => [ 3266 { 3267 'name' => 'doc comment', 3268 'regex' => '/\\*\\*.*?\\*/', 3269 'style' => 'doc comment', 3270 'childregex' => [] 3271 }, 3272 { 3273 'name' => 'comment', 3274 'regex' => '/\\*.*?\\*/', 3275 'style' => 'comment', 3276 'childregex' => [] 3277 }, 3278 { 3279 'name' => 'cplus comment', 3280 'regex' => '//.*?$', 3281 'style' => 'comment', 3282 'childregex' => [] 3283 }, 3284 { 3285 'name' => 'string', 3286 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 3287 # 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 3288 'style' => 'string', 3289 'childregex' => [ 3290 { 3291 'name' => 'esc character', 3292 'regex' => '\\\\.', 3293 'style' => 'esc character', 3294 'childregex' => [] 3295 } 3296 ] 3297 }, 3298 { 3299 'name' => 'preprocessor line', 3300 'regex' => '^[ \\t]*#.*?$', 3301 'style' => 'preprocessor', 3302 'childregex' => [ 3303 { 3304 'name' => 'string', 3305 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 3306 # 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 3307 'style' => 'string', 3308 'childregex' => [ 3309 { 3310 'name' => 'esc character', 3311 'regex' => '\\\\.', 3312 'style' => 'esc character', 3313 'childregex' => [] 3314 } 3315 ] 3316 }, 3317 { 3318 'name' => '<files>', 3319 'regex' => '<.*?>', 3320 'style' => 'string', 3321 'childregex' => [] 3322 }, 3323 { 3324 'name' => 'comment', 3325 'regex' => '[^/]/\\*.*?\\*/', 3326 'style' => 'comment', 3327 'childregex' => [] 3328 }, 3329 { 3330 'name' => 'cplus comment', 3331 'regex' => '//.*?$', 3332 'style' => 'comment', 3333 'childregex' => [] 3334 } 3335 ] 3336 }, 3337 { 3338 'name' => 'character constant', 3339 'regex' => '\'(\\\\)?.\'', 3340 'style' => 'character', 3341 'childregex' => [ 3342 { 3343 'name' => 'esc character', 3344 'regex' => '\\\\.', 3345 'style' => 'esc character', 3346 'childregex' => [] 3347 } 3348 ] 3349 }, 3350 { 3351 'name' => 'numeric constant', 3352 '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', 3353 'style' => 'numeric', 3354 'childregex' => [] 3355 }, 3356 { 3357 'name' => 'keyword', 3358 'regex' => '\\b(abs|absorption|acos|acosh|adaptive|adc_bailout|agate|agate_turb|all|alpha|ambient|ambient_light|angle|aperture|append|arc_angle|area_light|array|asc|asin|asinh|assumed_gamma|atan|atan2|atanh|average|background|bezier_spline|bicubic_patch|black_hole|blob|blue|blur_samples|bounded_by|box|boxed|bozo|break|brick|brick_size|brightness|brilliance|bumps|bump_map|bump_size|camera|case|caustics|ceil|checker|chr|clipped_by|clock|clock_delta|color|color_map|colour|colour_map|component|composite|concat|cone|confidence|conic_sweep|control0|control1|cos|cosh|count|crackle|crand|cube|cubic|cubic_spline|cubic_wave|cylinder|cylindrical|debug|declare|default|defined|degrees|density|density_file|density_map|dents|difference|diffuse|dimensions|dimension_size|direction|disc|distance|distance_maximum|div|eccentricity|else|emission|end|error|error_bound|exp|extinction|fade_distance|fade_power|falloff|falloff_angle|false|fclose|file_exists|filter|finish|fisheye|flatness|flip|floor|focal_point|fog|fog_alt|fog_offset|fog_type|fopen|frequency|gif|global_settings|gradient|granite|gray_threshold|green|height_field|hexagon|hf_gray_16|hierarchy|hollow|hypercomplex|if|ifdef|iff|ifndef|image_map|include|int|interior|interpolate|intersection|intervals|inverse|ior|irid|irid_wavelength|jitter|julia_fractal|lambda|lathe|leopard|light_source|linear_spline|linear_sweep|local|location|log|looks_like|look_at|low_error_factor|macro|mandel|map_type|marble|material|material_map|matrix|max|max_intersections|max_iteration|max_trace_level|media|media_attenuation|media_interaction|merge|mesh|metallic|min|minimum_reuse|mod|mortar|nearest_count|no|normal|normal_map|no_shadow|number_of_waves|object|octaves|off|offset|omega|omnimax|on|once|onion|open|orthographic|panoramic|perspective|pgm|phase|phong|phong_size|pi|pigment|pigment_map|planar|plane|png|point_at|poly|polygon|poly_wave|pot|pow|ppm|precision|prism|pwr|quadratic_spline|quadric|quartic|quaternion|quick_color|quick_colour|quilted|radial|radians|radiosity|radius|rainbow|ramp_wave|rand|range|ratio|read|reciprocal|recursion_limit|red|reflection|reflection_exponent|refraction|render|repeat|rgb|rgbf|rgbft|rgbt|right|ripples|rotate|roughness|samples|scale|scallop_wave|scattering|seed|shadowless|sin|sine_wave|sinh|sky|sky_sphere|slice|slope_map|smooth|smooth_triangle|sor|specular|sphere|spherical|spiral1|spiral2|spotlight|spotted|sqr|sqrt|statistics|str|strcmp|strength|strlen|strlwr|strupr|sturm|substr|superellipsoid|switch|sys|t|tan|tanh|text|texture|texture_map|tga|thickness|threshold|tightness|tile2|tiles|torus|track|transform|translate|transmit|triangle|triangle_wave|true|ttf|turbulence|turb_depth|type|u|ultra_wide_angle|undef|union|up|use_color|use_colour|use_index|u_steps|v|val|variance|vaxis_rotate|vcross|vdot|version|vlength|vnormalize|vrotate|v_steps|warning|warp|water_level|waves|while|width|wood|wrinkles|write|x|y|yes|z)\\b', 3359 'style' => 'reserved word', 3360 'childregex' => [] 3361 }, 3362 { 3363 'name' => 'braces', 3364 'regex' => '[\\{\\}]', 3365 'style' => 'braces', 3366 'childregex' => [] 3367 }, 3368 { 3369 'name' => 'symbols', 3370 'regex' => '([\\*\\-\\+=:;%&\\|<>\\(\\)\\[\\]!])', 3371 'style' => 'symbol', 3372 'childregex' => [] 3373 }, 3374 { 3375 'name' => 'identifiers', 3376 'regex' => '([a-zA-Z_][a-zA-Z_0-9]*)', 3377 'style' => 'identifier', 3378 'childregex' => [] 3379 } 3380 ] 3381 }; 3382 $LANGUAGE{'povray'} = $LANGUAGE{'pov'}; 3383 3384 3385 3386 3387 # by Tom Good 3388 $LANGUAGE{'python'} = { 3389 'filename' => '(?i)\\.py$', 3390 'regex' => '^\\s*#\\s*![^\\s]*python', 3391 'patterns' => [ 3392 { 3393 'name' => 'python comment', 3394 'regex' => '#.*?$', 3395 'style' => 'comment', 3396 'childregex' => [] 3397 }, 3398 { 3399 'name' => 'single quote string', 3400 'regex' => '\'.*?\'', 3401 'style' => 'string', 3402 'childregex' => [] 3403 }, 3404 3405 { 3406 'name' => 'string', 3407 'regex' => '""|"\\\\\\\\"|".*?([^\\\\](\\\\\\\\)*)"', 3408 'regex' => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"', 3409 'regex' => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"', 3410 'style' => 'string', 3411 'childregex' => [ 3412 { 3413 'name' => 'esc character', 3414 'regex' => '\\\\.', 3415 'style' => 'esc character', 3416 'childregex' => [] 3417 } 3418 ] 3419 }, 3420 { 3421 'name' => 'character constant', 3422 'regex' => '\'(\\\\)?.\'', 3423 'style' => 'character', 3424 'childregex' => [ 3425 { 3426 'name' => 'esc character', 3427 'regex' => '\\\\.', 3428 'style' => 'esc character', 3429 'childregex' => [] 3430 } 3431 ] 3432 }, 3433 { 3434 'name' => 'numeric constant', 3435 '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', 3436 'style' => 'numeric', 3437 'childregex' => [] 3438 }, 3439 { 3440 'name' => 'keyword', 3441 'regex' => '\\b(and|assert|break|class|continue|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while)\\b', 3442 'style' => 'reserved word', 3443 'childregex' => [] 3444 }, 3445 { 3446 'name' => 'braces', 3447 'regex' => '[\\{\\}]', 3448 'style' => 'braces', 3449 'childregex' => [] 3450 }, 3451 { 3452 'name' => 'symbols', 3453 'regex' => '([\\*\\-\\+=:;%&\\|<>\\(\\)\\[\\]!])', 3454 'style' => 'symbol', 3455 'childregex' => [] 3456 }, 3457 { 3458 'name' => 'identifiers', 3459 'regex' => '([a-zA-Z_][a-zA-Z_0-9]*)', 3460 'style' => 'identifier', 3461 'childregex' => [] 3462 }, 3463 { 3464 'name' => 'function', 3465 'regex' => '[\\t ]*def[\\t ]+([a-zA-Z0-9_]+)[\\t \\(]+.*?[\\n{]', 3466 'style' => 'function header', 3467 'childregex' => [ 3468 { 3469 'name' => 'function args', 3470 'regex' => '\\(.*?\\)', 3471 'style' => 'function header args', 3472 'childregex' => [] 3473 }, 3474 { 3475 'name' => 'function name', 3476 'regex' => '[\\t ][a-zA-Z0-9_]+', 3477 'style' => 'function header name', 3478 'childregex' => [] 3479 } 3480 ] 3481 }, 3482 { 3483 'name' => 'library functions', 3484 'regex' => '\\b(__import__|abs|apply|buffer|callable|chr|cmp|coerce|compile|complex|delatter|dir|divmod|eval|execfile|filter|float|getattr|globals|hasattr|hash|hex|id|input|int|intern|isinstance|issubclass|len|list|locals|long|map|max|min|oct|open|ord|pow|range|raw_input|reduce|reload|repr|round|setattr|slice|str|tuple|type|unichr|unicode|vars|xrange|zip)\\b', 3485 'style' => 'library function', 3486 'childregex' => [] 3487 }, 3488 ] 3489 }; 3490 3491 3492 3493 # by Joshua Swink <jswink@pacbell.net> 3494 $LANGUAGE{'ruby'} = { 3495 'filename' => '\\.rb$', 3496 'regex' => '^\\s*#\\s*![^\\s]*\\bruby\\b', 3497 'patterns' => [ 3498 { 3499 'name' => 'comment', 3500 'regex' => '(?:#.*?(?:\r?\n\s*)+)+', 3501 'style' => 'comment', 3502 'childregex' => [] 3503 }, 3504 { 3505 'name' => 'predefined variables', 3506 'regex' => '(?:\\$(?:[!@&`\'+\\d~=/\\\\,;.<>_*\\$?:"]|DEBUG|FILENAME|LOAD_PATH|stdin|stdout|stderr|VERBOSE|-[0adFiIlpv])|\\b(?:TRUE|FALSE|NIL|STDIN|STDOUT|STDERR|ENV|ARGF|ARGV|DATA|RUBY_VERSION|RUBY_RELEASE_DATE|RUBY_PLATFORM)\\b)', 3507 'style' => 'predefined identifier', 3508 'childregex' => [] 3509 }, 3510 { 3511 'name' => 'variables', 3512 'regex' => '[\\$@](?:{[^}]*}|[^\\w/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][\\w.]*)?', 3513 'style' => 'identifier', 3514 'childregex' => [] 3515 }, 3516 { 3517 'name' => '"" string', 3518 'regex' => '""|"(?:\\\\\\\\)+"|".*?(?:[^\\\\](?:\\\\\\\\)*)"|%[Qwx]?([^\\w\\[\\](){}<>])\\2|%[Qwx]?([^\\w\\[\\](){}<>]).*?(?:[^\\\\](?:\\\\\\\\)*)\\3|%[Qwx]?([^\\w\\[\\](){}<>])\\\\\\\\\\4|%[Qwx]?\\[\\]|%[Qwx]?\\[.*?([^\\\\](\\\\\\\\)*)\\]|%[Qwx]?\\[\\\\\\\\\\]|%[Qwx]?\\{\\}|%[Qwx]?\\{.*?([^\\\\](\\\\\\\\)*)\\}|%[Qwx]?\\{\\\\\\\\\\}|%[Qwx]?\\(\\)|%[Qwx]?\\(.*?([^\\\\](\\\\\\\\)*)\\)|%[Qwx]?\\(\\\\\\\\\\)|%[Qwx]?<>|%[Qwx]?<.*?([^\\\\](\\\\\\\\)*)>|%[Qwx]?<\\\\\\\\>', 3519 3520 'style' => 'string', 3521 'childregex' => [ 3522 { 3523 'name' => 'esc character', 3524 'regex', => '\\\\(?:x[\\da-fA-F]{2}|\d\d\d|c.|M-\\\\C-.|M-.|C-.|.)', 3525 'style' => 'esc character', 3526 'childregex' => [] 3527 }, 3528 { 3529 'name' => 'string expression', 3530 'regex' => '#[\\$\\@][a-zA-Z_][\\w.]*|#\\{[\\$\\@]?[^\\}]*\\}', 3531 'style' => 'identifier', 3532 'childregex' => [] 3533 } 3534 ] 3535 }, 3536 { 3537 'name' => '\'\' string', 3538 'regex' => '\'\'|\'(?:\\\\\\\\)+\'|\'.*?(?:[^\\\\](?:\\\\\\\\)*)\'|%q([^\\w\\[\\](){}<>])\\2|%q([^\\w\\[\\](){}<>]).*?(?:[^\\\\](?:\\\\\\\\)*)\\3|%q([^\\w\\[\\](){}<>])\\\\\\\\\\4|%q\\[\\]|%q\\[.*?([^\\\\](\\\\\\\\)*)\\]|%q\\[\\\\\\\\\\]|%q\\{\\}|%q\\{.*?([^\\\\](\\\\\\\\)*)\\}|%q\\{\\\\\\\\\\}|%q\\(\\)|%q\\(.*?([^\\\\](\\\\\\\\)*)\\)|%q\\(\\\\\\\\\\)|%q<>|%q<.*?([^\\\\](\\\\\\\\)*)>|%q<\\\\\\\\>', 3539 'style' => 'string', 3540 'childregex' => [ 3541 { 3542 'name' => 'esc character', 3543 'regex' => '(?:\\\\\'|\\\\\\\\)', 3544 'style' => 'esc character', 3545 'childregex' => [] 3546 } 3547 ] 3548 }, 3549 { 3550 'name' => 'subroutine header', 3551 'regex' => 'def[\\t ]+\\w[\\w.]*(?:\\([^)]*\\))?', 3552 'style' => 'function header', 3553 'childregex' => [ 3554 { 3555 'name' => 'arg list', 3556 'regex' => '\\(.*\\)', 3557 'style' => 'function header args', 3558 'childregex' => [ 3559 { 3560 'name' => 'arg list parens', 3561 'regex' => '[\\(\\)]', 3562 'style' => 'symbol', 3563 'childregex' => [] 3564 } 3565 ] 3566 }, 3567 { 3568 'name' => 'subroutine header', 3569 'regex' => '[\\t ]\w+', 3570 'style' => 'function header name', 3571 'childregex' => [] 3572 } 3573 ] 3574 }, 3575 { 3576 'name' => 'class header', 3577 'regex' => 'class[\\t ]+\\w+(?:\\s*<\\s*\\w+)?', 3578 'style' => 'function header', 3579 'childregex' => [ 3580 { 3581 'name' => 'class ancestor', 3582 'regex' => '<\\s*\\w+', 3583 'style' => 'include', 3584 'childregex' => [ 3585 { 3586 'name' => 'inheritance doohickey', 3587 'regex' => '<', 3588 'style' => 'symbol', 3589 'childregex' => [] 3590 } 3591 ] 3592 }, 3593 { 3594 'name' => 'class main', 3595 'regex' => '[\\t ]\\w+', 3596 'style' => 'type', 3597 'childregex' => [] 3598 } 3599 ] 3600 }, 3601 { 3602 'name' => 'regex matching 0', 3603 'regex' => '(?:%r([^\\w\\[\\](){}<>])\\2|%r([^\\w\\[\\](){}<>]).*?(?:[^\\\\](?:\\\\\\\\)*)\\3|%r([^\\w\\[\\](){}<>])\\\\\\\\\\4|%r\\[\\]|%r\\[.*?([^\\\\](\\\\\\\\)*)\\]|%r\\[\\\\\\\\\\]|%r\\{\\}|%r\\{.*?([^\\\\](\\\\\\\\)*)\\}|%r\\{\\\\\\\\\\}|%r\\(\\)|%r\\(.*?([^\\\\](\\\\\\\\)*)\\)|%r\\(\\\\\\\\\\)|%r<>|%r<.*?([^\\\\](\\\\\\\\)*)>|%r<\\\\\\\\>)[ixpno]*', 3604 'style' => 'regex', 3605 'childregex' => [ 3606 { 3607 'name' => 'string expression', 3608 'regex' => '#[\\$\\@][a-zA-Z_][\\w.]*|#\\{[\\$\\@]?[a-zA-Z_][^\\}]*\\}', 3609 'style' => 'identifier', 3610 'childregex' => [] 3611 } 3612 ] 3613 }, 3614 { 3615 'name' => 'regex matching I', 3616 'regex' => '(?:\\b| )?(?:/(?:\\\\/|[^/\\n])*(?:/[ixpno]*))', 3617 'style' => 'regex', 3618 'childregex' => [ 3619 { 3620 'name' => 'string expression', 3621 'regex' => '#[\\$\\@][a-zA-Z_][\\w.]*|#\\{[\\$\\@]?[a-zA-Z_][^\\}]*\\}', 3622 'style' => 'identifier', 3623 'childregex' => [] 3624 } 3625 ] 3626 }, 3627 { 3628 'name' => 'reserved words', 3629 'regex' => '\\b(BEGIN|class|ensure|nil|self|when|END|def|false|not|super|while|alias|defined|for|or|then|yield|and|do|if|redo|true|begin|else|in|rescue|undef|break|elsif|module|retry|unless|case|end|next|return|until)\\b', 3630 'style' => 'reserved word', 3631 'childregex' => [] 3632 }, 3633 { 3634 'name' => 'kernel module methods', 3635 'regex', => '\\b(Array|Float|Integer|String|at_exit|autoload|binding|caller|catch|chop|chomp|chomp!|eval|exec|exit|fail|fork|format|gets|global_variables|gsub|iterator|lambda|load|local_variables|loop|open|p|print|printf|proc|putc|puts|raise|rand|readline|readlines|require|select|sleep|split|sprintf|srand|sub|syscall|system|test|trace_var|trap|untrace_var)\\b', 3636 'style' => 'library function', 3637 'childregex' => [] 3638 }, 3639 { 3640 'name' => 'braces, parens and brakets', 3641 'regex' => '[\\[\\]\\{\\}\\(\\)]', 3642 'style' => 'braces', 3643 'childregex' => [] 3644 }, 3645 { 3646 'name' => '<< stuff', 3647 'regex' => '<<(?:("|\')([^\\n]*)\\2|\\w*).*?^\\3$', 3648 'style' => 'text', 3649 'childregex' => [] 3650 }, 3651 { 3652 'name' => 'symbols', 3653 'regex' => '(?:[:*-+<>=^!,/]+|\.\.+)', 3654 'style' => 'symbol', 3655 'childregex' => [] 3656 }, 3657 { 3658 'name' => 'numbers', 3659 'regex' => '\d[\d.]*', 3660 'style' => 'numeric', 3661 'childregex' => [] 3662 }, 3663 { 3664 'name' => 'embedded documentation', 3665 'regex' => '^=.*?^(?:=end|\\Z)', 3666 'style' => 'doc comment', 3667 'childregex' => [] 3668 } 3669 ] 3670 }; 3671 3672 # taken from nedit 3673 # modified by PP 3674 # very inclomplete! 3675 $LANGUAGE{'sql'} = { 3676 'filename' => '(?i)\\.sql$', 3677 'regex' => '', 3678 'patterns' => [ 3679 { 3680 'name' => 'keywords I', 3681 'regex' => '(?i)(,|%|<|>|:=|=|\\(|\\)|\\bselect|on|from|order by|desc|where|and|or|not|null|true|false)\\b', 3682 'style' => 'reserved word', 3683 'childregex' => [] 3684 }, 3685 { 3686 'name' => 'comment I', 3687 'regex' => '--.*?$', 3688 'style' => 'comment', 3689 'childregex' => [] 3690 }, 3691 { 3692 'name' => 'comment II', 3693 'regex' => '/\\*.*?\\*/', 3694 'style' => 'comment', 3695 'childregex' => [] 3696 }, 3697 { 3698 'name' => 'string', 3699 'regex' => '\'\'|\'.*?([^\\\\](\\\\\\\\)*)\'|\'\\\\\\\\\'', 3700 # 'regex' => '(\'\'|\'[^\'\\\\]\'|\'[^\'].*?[^\\\\]\')', 3701 'style' => 'string', 3702 'childregex' => [] 3703 }, 3704 { 3705 'name' => 'keywords II', 3706 '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', 3707 'style' => 'reserved word', 3708 'childregex' => [] 3709 }, 3710 { 3711 'name' => 'keywords III', 3712 'regex' => '(?i)\\balter\\b', 3713 'style' => 'reserved word', 3714 'childregex' => [] 3715 }, 3716 { 3717 'name' => 'datatypes', 3718 'regex' => '(?i)\\b(integer|blol|date|numeric|character|varying|varchar|char)\\b', 3719 'style' => 'predefined type', 3720 'childregex' => [] 3721 }, 3722 { 3723 'name' => 'words', 3724 'regex' => '(?i)\\b(constraint|key|references|primary|table|foreign|add|insert|group by)\\b', 3725 'style' => 'reserved word', 3726 'childregex' => [] 3727 } 3728 ] 3729 }; 3730 3731 3732 3733 $LANGUAGE{'patch'} = { 3734 'filename' => '(?i)\\.patch$|\\.diff$', 3735 'regex' => '', 3736 'patterns' => [ 3737 { 3738 'name' => 'header', 3739 'regex' => '^Index: .*?$|^===== .*?$|^diff .*?$|^--- .*?$|^\+\+\+ .*?$', 3740 'style' => 'separator', 3741 'childregex' => [] 3742 }, 3743 { 3744 'name' => 'hunk', 3745 'regex' => '^@@ .*?$', 3746 'style' => 'line spec', 3747 'childregex' => [] 3748 }, 3749 { 3750 'name' => 'from', 3751 'regex' => '^-.*?$', 3752 'style' => 'deletion', 3753 'childregex' => [] 3754 }, 3755 { 3756 'name' => 'to', 3757 'regex' => '^\+.*?$', 3758 'style' => 'insertion', 3759 'childregex' => [] 3760 } 3761 ] 3762 }; 3763 3764 3765 3766 ##### 3767 # 3768 # LANGUAGE: shell script 3769 # 3770 3771 $LANGUAGE{'shellscript'} = { 3772 'filename' => '\\.(sh|shell)$', 3773 'regex' => '^\\s*#\\s*![^\\s]*(sh|bash|ash|zsh|ksh)', 3774 'patterns' => [ { 3775 'name' => 'comment', 3776 # 'regex' => '^[ \t]*[^$]?\#[^!]?.*?$', 3777 'regex' => '(^| )#([^\\!].)*?$', 3778 'style' => 'comment', 3779 'childregex' => [] 3780 }, { 3781 'name' => 'identifier', 3782 'regex' => '[a-zA-Z][a-zA-Z0-9_]*=', 3783 'style' => '', 3784 'childregex' => [ { 3785 'name' => 'identifier', 3786 'regex' => '[a-zA-Z][a-zA-Z0-9_]*', 3787 'style' => 'identifier', 3788 'childregex' => [] 3789 } ] 3790 }, { 3791 'name' => 'identifier', 3792 'regex' => '\\$([0-9#\\*]|[a-zA-Z][a-zA-Z0-9_]*)', 3793 'style' => 'identifier', 3794 'childregex' => [] 3795 }, { 3796 'name' => 'interpreter line', 3797 'regex' => '^[ \t]*#!.*?$', 3798 'style' => 'preprocessor', 3799 childregex => [] 3800 }, { 3801 'name' => 'string', 3802 'regex' => '""|"(\\\\"|[^\\"])*"', 3803 'style' => 'string', 3804 childregex => [ { 3805 'name' => 'identifier', 3806 'regex' => '\\$([0-9#\\*]|[a-zA-Z][a-zA-Z0-9_]*)', 3807 'style' => 'identifier', 3808 'childregex' => [] 3809 } ] 3810 } ] 3811 }; 3812 3813 $LANGUAGE{'sh'} = $LANGUAGE{'shellscript'}; 3814 return \%LANGUAGE; 3815 3816 };