Suppose if you will, that for the moment, you can wave a magic wand and solve the problem of program documentation– what might that solution look like (and function like) and how might it be implemented? Here are the beginnings (pre-alpha at best) of my solution, worked out in HTML, CSS, and DHTML . All this for a source file written in Perl? Yes, but remember we're talking magic wand here!
The first thing that comes to mind is that we need to be able to see the actual code. Given style sheets, that is comparitively easy:
#!/usr/bin/perl -w # ftstamp.pl -- file modification time as time stamp. use strict; use warnings; use Getopt::Std; use Wild; use diagnostics; my %OPTIONS; getopts('ud',\%OPTIONS); WildARGV(); foreach (@ARGV) { if ($OPTIONS{d}) { print "ftstamp -d $_\n"; } else { stamp($_) unless (-d); } } sub stamp { my $s = shift; my $modified = time - ((-M $_) * 86400); my $t = localtime($modified); my $touched; my @filetext; open(FILE,$s); @filetext =; close(FILE); foreach (@filetext) { if ($_ =~ /Page last touched (.+?)(?:<|\n)/) { if ($1 ne $t) { s/\Q$1/$t/; $touched = 1; } } } if ($touched) { open(FILE,'>'.$_); print FILE @filetext; close(FILE); utime $modified,$modified,$_ if $OPTIONS{u}; print "$_ touched: $t\n"; } }
Not particularly difficult, just come up with a new form of the venerable <PRE></PRE> tag and away we go. On the other hand, hardly a solution and barely a start. Given the medium, we should at least expect color typing and some bare bones typography of some sort. Here is try the second:
#!/usr/bin/perl -w # ftstamp.pl -- file modification time as time stamp. use strict; use warnings; use Getopt::Std; use Wild; use diagnostics; my %OPTIONS; getopts('ud',\%OPTIONS); WildARGV(); foreach (@ARGV) { if ($OPTIONS{d}) { print "ftstamp -d $_\n"; } else { stamp($_); } } sub stamp { my $s = shift; my $modified = time - ((-M $_) * 86400); my $t = localtime($modified); my $touched; my @filetext; open(FILE,$s); @filetext = <FILE>; close(FILE); foreach (@filetext) { if ($_ =~ /Page last touched (.+?)(?:<|\n)/) { if ($1 ne $t) { print "\$1=$1\n"; print "quotemeta(\$1)=",quotemeta($1),"\n"; print "\$t=$t\n"; s/quotemeta($1)/$t/; $touched = 1; print "\$_=$_\n"; } } } if ($touched) { open(FILE,'>'.$_); print FILE @filetext; close(FILE); utime $modified,$modified,$_ if $OPTIONS{u}; print "$_ touched: $t\n"; } }
Once again, not particularly difficult. The hard part here done with PerlTidy and the -html option. Still, this is not what I've got in mind when I do the Literate Programming vision thing. Perhaps if we approach the problem in a fashion similar to how we might have written the code in the first place, i.e. top-down (or more accurately, pseudo-code to perl-code!) In that case, the beginning might look more like:
Hmmm… let's see. First the usual boiler-plate, bang-line, 'uses' and obvious global
variables. I'll call that:
<<boiler-plate>>
Then we have the ever present parse the command line and set the switches code, initial code
we run once:
<<initial and start-up code>>
Now that we have our ducks in a row, the final ingredient could just as easily be labeled; do-it! So we will:
<<do-it>>
This is the proto-typical example of pseudo-code, without much imagination it's clear that this could be applied to virtually any piece of code, in fact it is so general that it doesn't do much good. Let's try that once more from the top:
ftstamp – A Perl
script to timestamp '.html' files based on file modification date. A fairly
simple minded file filter, ftstamp, given a list of files to
examine will search for a 'marker' string (in this case, "Page last touched ").
If found, the string is used as an anchor for the file modification time and
date, i.e. it will replace "Page last touched whatever" with "Page last touched
Fri Mar 30 13:20:14. It may then optionally set the file's actual time and date
to the same value as the replacement string. ftstamp
will do this for all files specified on the command line.
In general this
breaks down to the following broad steps:
#!/usr/bin/perl -w # ftstamp.pl -- file modification time as time stamp. use strict; use warnings; use Getopt::Std; use Wild; use diagnostics;
my %OPTIONS; getopts('ud',\%OPTIONS); WildARGV();
foreach (@ARGV) { if ($OPTIONS{d}) { print "ftstamp -d $_\n"; } else { stamp($_); } }
sub stamp { my $s = shift; my $modified = time - ((-M $_) * 86400); my $t = localtime($modified); my $touched; my @filetext; open(FILE,$s); @filetext = <FILE>; close(FILE); foreach (@filetext) { if ($_ =~ /Page last touched (.+?)(?:<|\n)/) { if ($1 ne $t) { print "\$1=$1\n"; print "quotemeta(\$1)=",quotemeta($1),"\n"; print "\$t=$t\n"; s/quotemeta($1)/$t/; $touched = 1; print "\$_=$_\n"; } } } if ($touched) { open(FILE,'>'.$_); print FILE @filetext; close(FILE); utime $modified,$modified,$_ if $OPTIONS{u}; print "$_ touched: $t\n"; } }