i got kindof carried away and made a Javascript rip-off of Cory Johns' excellent
module.
To try, cut&paste into a html file, run it in IE or Mozilla and click anywhere in the perl code you see.
<html>
<head>
<style>
.quotedString
{
color: #0000FF;
}
.comment
{
color: #999999;
}
.operator
{
color: #00CCCC;
}
.builtinVariable
{
color: #CCCC00;
}
.variableSpecifier
{
color: #FF0000;
}
.keyword
{
color: #9900FF;
}
.builtinFunction
{
color: #FF00FF;
}
.identifier
{
color: #009900;
}
.number
{
color: #9999FF;
}
</style>
<script>
var ie = document.all != null;
var moz = !ie && document.getElementById != null && document.layers ==
+ null;
function emulateHTMLModel()
{
// copied from http://www.webfx.nu/dhtml/ieemu/htmlmodel.html
// This function is used to generate a html string for the text pr
+operties/methods
// It replaces '\n' with "<BR"> as well as fixes consecutive white
+ spaces
// It also repalaces some special characters
function convertTextToHTML(s) {
s = s.replace(/\&/g, "&").replace(/</g, "<").replace(/>
+/g, ">").replace(/\n/g, "<BR>").replace(/\t/g, " "); //tachyon
while (/\s\s/.test(s))
s = s.replace(/\s\s/, " ");
return s.replace(/\s/g, " ");
}
HTMLElement.prototype.__defineSetter__("innerText", function (sTex
+t) {
this.innerHTML = convertTextToHTML(sText);
return sText;
});
var tmpGet;
HTMLElement.prototype.__defineGetter__("innerText", tmpGet = funct
+ion () {
var r = this.ownerDocument.createRange();
r.selectNodeContents(this);
return r.toString();
});
}
if (moz)
emulateHTMLModel();
// Regular Expressions largely copied from Cory Johns (darkness@yossma
+n.net) excellent Syntax::Highlight::Perl module (see http://search.cp
+an.org/~johnsca/)
var re;
var RE = new Array;
// quoted string
re = /('|"|`).*?\1/;
RE[0] = new RegExp(re);
// comment
re = /\#.*?[\r\n]+/; //tachyon
RE[1] = new RegExp(re);
// operator
re = /xor|\.\.\.|and|not|\|\|\=|cmp|\>\>\=|\<\<\=|\<\=\>|\&\&\=|or|\=\
+>|\!\~|\^\=|\&\=|\|\=|\.\=|x\=|\%\=|\/\=|\*\=|\-\=|\+\=|\=\~|\*\*|\-\
+-|\.\.|\|\||\&\&|\+\+|\-\>|ne|eq|\!\=|\=\=|ge|le|gt|lt|\>\=|\<\=|\>\>
+|\<\<|\,|\=|\:|\?|\^|\||x|\%|\/|\*|\<|\&|\\|\~|\!|\>|\.|\-|\+ /;
RE[2] = new RegExp(re);
// builtin variables
re = /\$\#?_|\$(?:\^[LAECDFHIMOPRSTWX]|[0-9&`'+*.\/|,\\";#%=\-~^:?!@\$
+<>()\[\]])|\$\#?ARGV(?:\s*\[)?|\$\#?INC\s*\[|\$(?:ENV|SIG|INC)\s*\{|\
+@(?:_|ARGV|INC)|\%(?:INC|ENV|SIG)/;
RE[3] = new RegExp(re);
// variable class specifiers
re = /(?:(?:[\@\%\*]|\$\#?)\$*)/;
RE[4] = new RegExp(re);
// keyword
re = /(continue|foreach|require|package|scalar|format|unless|local|un
+til|while|elsif|next|last|goto|else|redo|sub|for|use|no|if|my)\b/;
RE[5] = new RegExp(re);
// builtin function
re = /(getprotobynumber|getprotobyname|getservbyname|gethostbyaddr|ge
+thostbyname|getservbyport|getnetbyaddr|getnetbyname|getsockname|getpe
+ername|setpriority|getprotoent|setprotoent|getpriority|endprotoent|ge
+tservent|setservent|endservent|sethostent|socketpair|getsockopt|getho
+stent|endhostent|setsockopt|setnetent|quotemeta|localtime|prototype|g
+etnetent|endnetent|rewinddir|wantarray|getpwuid|closedir|getlogin|rea
+dlink|endgrent|getgrgid|getgrnam|shmwrite|shutdown|readline|endpwent|
+setgrent|readpipe|formline|truncate|dbmclose|syswrite|setpwent|getpwn
+am|getgrent|getpwent|ucfirst|sysread|setpgrp|shmread|sysseek|sysopen|
+telldir|defined|opendir|connect|lcfirst|getppid|binmode|syscall|sprin
+tf|getpgrp|readdir|seekdir|waitpid|reverse|unshift|symlink|dbmopen|se
+mget|msgrcv|rename|listen|chroot|msgsnd|shmctl|accept|unpack|exists|f
+ileno|shmget|system|unlink|printf|gmtime|msgctl|semctl|values|rindex|
+substr|splice|length|msgget|select|socket|return|caller|delete|alarm|
+ioctl|index|undef|lstat|times|srand|chown|fcntl|close|write|umask|rmd
+ir|study|sleep|chomp|untie|print|utime|mkdir|atan2|split|crypt|flock|
+chmod|BEGIN|bless|chdir|semop|shift|reset|link|stat|chop|grep|fork|du
+mp|join|open|tell|pipe|exit|glob|warn|each|bind|sort|pack|eval|push|k
+eys|getc|kill|seek|sqrt|send|wait|rand|tied|read|time|exec|recv|eof|c
+hr|int|ord|exp|pos|pop|sin|log|abs|oct|hex|tie|cos|vec|END|ref|map|di
+e|\-C|\-b|\-S|\-u|\-t|\-p|\-l|\-d|\-f|\-g|\-s|\-z|uc|\-k|\-e|\-O|\-T|
+\-B|\-M|do|\-A|\-X|\-W|\-c|\-R|\-o|\-x|lc|\-w|\-r)\b/;
RE[6] = new RegExp(re);
// identifier (variable, subroutine, packages)
re = /(?:(?:[A-Za-z_]|::)(?:\w|::)*)/;
RE[7] = new RegExp(re);
// number
re = /0x[\da-fA-F]+|[_.\d]+([eE][-+]?\d+)?/;
RE[8] = new RegExp(re);
var classes = new Array("quotedString", "comment", "operator", "built
+inVariable", "variableSpecifier", "keyword", "builtinFunction", "iden
+tifier", "number");
/* This is the actual highlighting function.
* Takes an html object as argument
* returns nothing
* replaces the text inside the html object with colored text using <s
+pan>'s
* css is defined separately. See the array classes to find out the cs
+s class names.
*/
function HighlightCode(object)
{
codeText = object.innerText; //HTML.replace(/<.*?>/g, "");
object.innerHTML = '';
var left;
var match;
var right;
while (codeText.length > 0)
{
var mode = -1 ;
var index = 999999999;
for (var i = 0; i < RE.length; i++)
{
if ((codeText.match(RE[i])) && (RegExp.leftContext.length
+< index))
{
left = RegExp.leftContext;
match = RegExp.lastMatch;
right = RegExp.rightContext;
index = RegExp.leftContext.length;
mode = i;
}
}
if (mode == -1)
{
object.appendChild(document.createTextNode(codeText)); //.
+replace(/\r\n/g, "\r")));
codeText = '';
}
else
{
// append the plain text to the <code> block
object.appendChild(document.createTextNode(left)); //.repl
+ace(/\r\n/g, "\r")));
// create a new <span> with the current code
var span = document.createElement("span");
span.setAttribute("className", classes[mode]); // ie
span.setAttribute("class", classes[mode]); //mozilla
span.appendChild(document.createTextNode(match));
object.appendChild(span);
codeText = right;
}
}
}
</script>
</head>
<body>
<pre onClick ="HighlightCode(this);">
%EXPORT_TAGS = (
crlf => [qw(CR LF CRLF $CR $LF $CRLF)],
all => [@EXPORT, @EXPORT_OK],
);
BEGIN {
sub CR () {"\015"}
sub LF () {"\012"}
sub CRLF () {"\015\012"}
}
*CR = \CR();
*LF = \LF();
*CRLF = \CRLF();
sub sockaddr_in {
if (@_ == 6 && !wantarray) { # perl5.001m compat; use this && die
my($af, $port, @quad) = @_;
warnings::warn "6-ARG sockaddr_in call is deprecated"
if warnings::enabled();
pack_sockaddr_in($port, inet_aton(join('.', @quad)));
} elsif (wantarray) {
croak "usage: (port,iaddr) = sockaddr_in(sin_sv)" unless @_ == 1
+;
unpack_sockaddr_in(@_);
} else {
croak "usage: sin_sv = sockaddr_in(port,iaddr))" unless @_ == 2;
pack_sockaddr_in(@_);
}
}
# comment blaat
my $i = 2345;
sub sockaddr_un {
if (wantarray) {
croak "usage: (filename) = sockaddr_un(sun_sv)" unless @_ == 1;
unpack_sockaddr_un(@_);
} else {
croak "usage: sun_sv = sockaddr_un(filename)" unless @_ == 1;
pack_sockaddr_un(@_);
}
}
</pre>
</body>
</html>
Perhaps it could be discussed here if we could use it on the monestary.
If you find bugs or have suggestions for improvements, you might want to pm/mail/call/write me.