#!/usr/bin/perl -w use strict; our($text, %config, %complements); $config{colors}={ #sigils=red '$' => '993333', '@' => 'CC6633', '%' => '660000', '&' => '990033', '*' => '990000', #quotes=blue "'" => '6699FF', '"' => '3366CC', '`' => '333399', 'qw' => '0000FF', #regexes 'm' => '000088', 's' => '0000CC', 'y' => '0000FF', 'tr' => '0000FF', #various '()' => '880000', '[]' => 'CC0000', '{}' => 'FF0000', '<<' => '00CC00', '#' => '339999', }; %complements=( '{' => '}', '(' => ')', '[' => ']', '<' => '>' ); for(32..127) { $complements{chr($_)}=chr($_) unless exists $complements{chr($_)}; } $/=undef; $text=<>; $text=highlight_quotes($text); $text=highlight_regexes($text); $text=highlight_various($text); $text=highlight_sigils($text); $text=fix_it_up($text); print <<"END"; $text END sub fixit($) { local $_=shift; if(/qq/) { '"' } elsif(/qx/) { '`' } elsif(/qw/) { 'qw'} elsif(/q/) { "'" } else { die "$0: $_ is not a valid quoter\n" } } sub fix_it_up($) { local $_=shift; s/\n/\0\n/g; s/(?/>/g; s/ /  /g; #since I'm using null as an escape character, I have to get rid of the ones that are left s/\0//g; return $_; } sub highlight_quotes($) { local $_=shift; #heredocs: MUST BE DONE before '' and "" highlighting s|<<(['"]?)(.*)\1([^\n]*?)\n(.*?)\n\2\n|<<$1$2$1$3\n\0$4\0\n$2\n|gs; #normal quoted strings s|(?$2\0$1|gs; # qX s|(q[qxwr]?)([^\w\s\[\{\(\<])(.*?)(?$3\0$complements{$2})|ges; return $_; } sub highlight_various($) { local $_=shift; #highlight subscripting and function args s|(?<=\w)([\{\[\(])(.*?)(??{quotemeta($complements{$1})})|\0$1\0$2\0\0$complements{$1}|sg; #highlight comments--unless the sharp appears to be the delimiter of a q, qq, qw, qx, tr, y, m, or s s|^([^#]+)(?\0#$2\0|gm; s|^#(.*)$|\0\0#$1\0|gm; return $_; } sub highlight_sigils($) { local $_=shift; #wrapped in {} 1 while s|(?\0$1\0{$2\0}\0|sg; #unwrapped s[(?\0$1$2\0]sg; return $_; } sub highlight_regexes($) { local $_=shift; #m//, m{} s{m([^\w\s\0])(.*?)(?$2\0$complements{$1}}gs; #s///, tr/// s{(s|tr|y)([^\w\s\0])(.*?)(?![\\\0])\2(.*?)(?![\\\0])\2} {$1$2\0$3\0$2\0$4\0$2}gs; #s{}{}, tr{}{} s{(s|tr|y)([\{\[\(\<])(.*?)(?$3\0$complements{$2}$4$5\0$6\0$complements{$5}}gs; return $_; }