#!/usr/bin/perl -w use strict; ################################################################ =pod =head1 NAME addmacros2tex.pl -- create some new preprocessing macros in TeX =head1 USAGE addmacros2tex.pl [--quiet] [--permitsystem] *.tex *.sty (the default is to process all .tex files in the directory) =head1 SYNOPSIS replaces the arguments in the following new macros with a value obtained from external sources. Note that the argument inside the {} is overwritten by this program! =over 4 =item \curfilewepoch{102312312} provides the unix time at which the file was last written. =item \curfilewdate{Dec 12, 2003} provides the date at which the file was last written. For simplicity, we use an easy to understand output format. you can easily change the coding below. (The right way to do this would be to allow you to change the program to allow a parameter ala \curfilewdate[mmm dd, yyyy]{Dec 12, 2003}.) =item \curfilewdatetime{Dec 12, 2003 (15:02h)} ditto. =item \curfilename{file.tex} obvious. =item \curbasename{file} obvious. =item \curfullfilename{/home/user/file.tex} not yet implemented. =item \system[command]{%\n command output \n}%\n unlike write18, the output is immediately redirected into the parentheses. note that it is the called program's responsibility to get the output right, e.g., to quote tex special characters. To enable this command, you need to call this program with --permitsystem as its first argument. Note that the '{%' '}%' is needed, because perl's regex's cannot recognize matching parentheses, and the argument might contain other LaTeX commands. (I am using \system to automatically create and include text analysis tables.) =back Warning: This is not a real TeX macro. Thus, if you have the macro in a TeX comment, it will still be expanded. This functionality should really be part of the core TeX distribution. Alas, the TeX developers seem to disagree with me.. =head2 LICENSE (C) Ivo Welch, 2002. GNU copyleft usage permitted by the author. Hope others will enhance this. =cut ################################################################ use Time::localtime; my $quiet= ((@ARGV) && ($ARGV[0] eq "--quiet")); $quiet and shift(@ARGV); my $permitsystem=0; if ((@ARGV) && ($ARGV[0] eq "--permitsystem")) { shift(@ARGV); $quiet or warn "WARNING: --permitsystem, so \\system[]{} is now executed.\n"; $permitsystem=1; } else { $quiet or warn "[To enable \\system[]{} preprocessing, use --permitsystem]\n"; } @ARGV = glob("*.tex") unless @ARGV; # default files; foreach (@ARGV) { my ($fnm,$basename,$extension)= ($_,$_,$_); my ($READTIME, $WRITETIME) = (stat($fnm))[8,9]; $quiet or print STDERR "Processing $fnm, modified on ".nicedate($WRITETIME).": "; # file names; ($basename =~ s/([\w\.\/\-]+)\.(\w+)/$1/); # create basename ($extension =~ s/([\w\.\/\-]+)\.(\w+)/$2/); # create extension ($extension eq "sty") or ($extension eq "tex") or warn "\nWARNING: File $_ does not have sty or tex extension, but '$extension'.\n"; # first read the file; open(FIN, "$fnm") or die "cannot open input file $fnm: $!\n"; $/= undef; my $file= ; close(FIN) or die "cannot close input file $fnm: $!\n"; my $changecount=0; my ($curfilewdate,$curfilewdatetime)= (nicedate($WRITETIME)); $changecount+= ($file =~ s/(\\curfilewdate)(\{[^\}]*\})/$1\{$curfilewdate\}/g); $changecount+= ($file =~ s/(\\curfilewdatetime)(\{[^\}]*\})/$1\{$curfilewdatetime\}/g); $changecount+= ($file =~ s/(\\curfilewepoch)(\{[^\}]*\})/$1\{$WRITETIME\}/g); $changecount+= ($file =~ s/(\\curbasename)(\{[^\}]*\})/$1\{$basename\}/g); $changecount+= ($file =~ s/(\\curfilename)(\{[^\}]*\})/$1\{$fnm\}/g); if ($permitsystem) { if ($file =~ /\\system\[[^]]+\]\{[^\%]/) { warn "\nWARNING: you have a \\system call in $fnm, but the command does not start with \{\%\n"; } my $syscount= ($file =~ s/(\\system\[)([^]]+)(\])(\{%.*\}%)/mysystem($1,"$2",$3)/ges); ($syscount) and $quiet and print STDERR "*$syscount system calls*"; $changecount+= $syscount; } if ($changecount>0) { $quiet or print STDERR "$changecount change(s). file rewritten."; open(FOUT, ">TEST") or die "cannot write $!\n"; print FOUT $file; close(FOUT) or die "cannot close $!\n"; rename($fnm, "$fnm~") or die "cannot rename old file $fnm to backup; aborting! $!\n"; rename("TEST", $fnm) or die "cannot rename (move back) TEST into new file $fnm: $!\n"; utime($READTIME, $WRITETIME, $fnm); } else { $quiet or print STDERR " no changes necessary."; } $quiet or print STDERR "\n"; } ################################################################ sub nicedate { my $t = localtime($_[0]); my ($seconds, $minutes, $hours, $day_of_month, $month, $year, $wday, $yday, $isdst) = @$t; $year+=1900; $month= ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "none!!")[$month]; return ("$month $day_of_month, $year", sprintf("$month $day_of_month, $year (%02d:%02dh)", $hours,$minutes)); } sub mysystem { my $command= $_[1]; my $output= `$command`; return "$_[0]$_[1]$_[2]\{% $output \}% "; }