no vice-pre$ident here :)
This program generates a framed version
of
merlyn webtechniques and incidentally demonstrates that non
trivial javascript is not portable. This works only on a recent
Mozilla or Galeon.
Framed Web-pages often suck. Well used,
they can bring added navigability or readability like in the Annotated XML
Specification by Tim Bray.
Here, I process merlyn webtechniques
columns to use frames, JS and DOM to make easier reading.
The original format: in the same page, there is the explanation
of a program and the program itself. In the explanation part, the
program is referenced by line numbers. it is tedious for the eyes to
jump from the explanation to the explaned program chunk.
The framed format:
program and explanation are separated in two frames. Clicking
on a link (a line reference) in the explanation scrolls the program frame
to make visible the line(s). Mo?using over a link hilights the said
line(s) in red.
The program deals correctly with embedded code span references, say 30
through 100" and "lines 30 through 33".
If there is black lines within a span of red lines, that means that the
black lines are indded covered by a more specific explanation
I hoped to use the documented fact that the anchor name share the id
space... does not work. I happily transgressed the rule that nested
links are illegal.
A later version of the program should allow to mouse over the program and hilight the
explanations.
For a limited amount of time you can access the framed webtechniques
at http://properler.freesurf.fr/merlyn/index.html
use strict;
# use warnings;
# use diagnostics;
use HTML::Parser;
use CGI_Lite;
my ($prog, $inpre, $inprog, $intitle, $inxplain, $xplain, $title);
my $p = HTML::Parser->new( api_version => 3,
start_h => [\&start, "tagname, attr"],
end_h => [\&end, "tagname"],
text_h => [ \&text, "dtext" ],
marked_sections => 1,
);
my $dir = '/web/www.stonehenge.com/merlyn/WebTechniques'; # I shoved t
+hem here
my $idx; # content of the index
for my $nr ( '01' .. '67' ) {
my %ln; # memorize spans
$xplain = $prog = $title = '';
my ($fsfnm, $progfnm, $xplainfnm ) = map { "$dir/col$nr$_.html" } qw
+( fs prog xplain );
my $fnm = "$dir/col$nr.html";
die "can't find file $fnm" unless $p->parse_file("$fnm");
my $js = <<EOF;
<script language="javascript">
var previd = 0;
function hilite(id ) {
if ( previd != 0 ) {
top.frames[1].document.getElementById(previd).style.color = 'black'
+ ;
}
previd = id;
top.frames[1].document.getElementById(id).style.color = 'red' ;
+
}
</script>
EOF
my $head = "<html><head><title>$title</title></head><body>";
my $fshead = "<html><head><title>$title</title></head>";
my $tail = "</body></html>\n";
my $fstail ="</html>\n";
my $fs =qq|
<frameset rows="50%,*">
<frame src="file://$dir/col${nr}xplain.html" name="merlynxplain" id=
+"merlynxplain">
<frame src="file://$dir/col${nr}prog.html" name="merlynprog" id="mer
+lynprog">
<noframes>
you are not framed!
</noframes>
</frameset>
|;
# gathering line references coping with their style inconstency
$xplain =~ s((lines?\s+(\d+)(\s*(through|thru|to|-|and)\s*(?:line\s+
+)?(\d+))?))
(
$ln{"$2_$5"}++; genhilite($1, "$2_$5", $nr) )eig;
$xplain =~ s(<h2>.*?Listings.*?</h2>)()s; # supress listing left-ove
+r
for (keys %ln ) {
# the massage is the message
my ($from, $to ) = $_;
# print STDERR "$from -> $to\n";
($from, $to) = m/(\d+)_(\d*)/;
if ($to) {
$prog =~ s((?-s)(=$from=.*(?s).*?=$to=(?-s).*)) (<span><a></a>
+$1</span>);
# the first (?-s) should not be necessary
} else {
$prog =~ s((=$from=.*)) (<span><a></a>$1</spa
+n>);
}
}
open O, ">$fsfnm" or die $@;
print O $fshead, $fs, $fstail;
open O, ">$xplainfnm" or die $@;
print O $head, $js, $xplain, $tail;
open O, ">$progfnm" or die $@;
print O $head, "<pre>\n", $prog, "</pre>", $tail;
$idx .= qq|<li><a>$title</a></li>|;
}
$idx = "<html><title>Framing Merlyn</title><body><ul>$idx</ul></body><
+/html>";
open O, ">$dir/index.html";
print O $idx;
sub genhilite($$$) { my ( $str, $span, $nr) = @_;
qq(<a>$str</a>) ;
}
sub attr2str { my ( $attr ) = @_;
my $str;
$str .=" $_='$attr->{$_}'" for sort keys %$attr ;
$str;
}
sub start { my ( $tagnm, $attr) = @_;
$inpre = 1 if $tagnm eq 'pre';
$intitle = 1 if $tagnm eq 'title';
$xplain .= "<$tagnm" . attr2str($attr) .">" if $inxplain;
$inxplain = 1 if $tagnm eq 'body'; }
sub end { my ( $tagnm) = @_;
$inprog = $inpre = 0 if $tagnm eq 'pre';
$intitle = 0 if $tagnm eq 'title';
$inxplain = 0 if $tagnm eq 'body';
$xplain .= "<!- tagnm>" if $inxplain; }
sub text { my ( $dtxt ) = @_;
$inprog = $inpre && $dtxt =~ m/=\d+=/;
$dtxt = browser_escape( $dtxt) if $inpre;
if ( $inprog) {
$prog .= $dtxt;
} elsif ( $intitle) {
$title .= $dtxt;
} else {
$xplain .= $dtxt if $inxplain;
}
}
-- stefp
Edit Petruchio Sat Dec 29 03:12:20 UTC 2001 - Added READMORE tag.