diff options
Diffstat (limited to 'Build')
-rwxr-xr-x | Build/source/texk/texlive/linked_scripts/sty2dtx/sty2dtx.pl | 599 |
1 files changed, 442 insertions, 157 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/sty2dtx/sty2dtx.pl b/Build/source/texk/texlive/linked_scripts/sty2dtx/sty2dtx.pl index 5c0730ca5bb..e68b667141c 100755 --- a/Build/source/texk/texlive/linked_scripts/sty2dtx/sty2dtx.pl +++ b/Build/source/texk/texlive/linked_scripts/sty2dtx/sty2dtx.pl @@ -1,45 +1,59 @@ #!/usr/bin/env perl use strict; use warnings; -################################################################################ -# $Id: sty2dtx.pl 2125 2011-02-02 15:25:40Z martin $ -################################################################################ -my $COPYRIGHT = << 'EOT'; - Copyright (c) 2010-2011 Martin Scharrer <martin@scharrer-online.de> +use File::Basename qw(dirname); - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. +=head1 NAME - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +sty2dtx -- Converts a LaTeX .sty file to a documented .dtx file - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. +=head1 VERSION + +Version: v2.3 + +=head1 COPYRIGHT + +Copyright (c) 2010-2012 Martin Scharrer <martin@scharrer-online.de> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + + +=head1 DESCRIPTION + +Converts a .sty file (LaTeX package) to .dtx format (documented LaTeX source), +by surrounding macro definitions with 'macro' and 'macrocode' environments. +The macro name is automatically inserted as an argument to the 'macro' +environemnt. +Code lines outside macro definitions are wrapped only in 'macrocode' +environments. Empty lines are removed. +The script is not thought to be fool proof and 100% accurate but rather +as a good start to convert undocumented style files to .dtx files. + + +=head2 Basic Usage -EOT -################################################################################ -my $DESCRIPTION = << 'EOT'; - Converts a .sty file (LaTeX package) to .dtx format (documented LaTeX source), - by surrounding macro definitions with 'macro' and 'macrocode' environments. - The macro name is automatically inserted as an argument to the 'macro' - environemnt. - Code lines outside macro definitions are wrapped only in 'macrocode' - environments. Empty lines are removed. - The script is not thought to be fool proof and 100% accurate but rather - as a good start to convert undocumented style files to .dtx files. - - Usage: perl sty2dtx.pl infile [infile ...] outfile - or + +or + perl sty2dtx.pl < file.sty > file.dtx +=head2 Supported Definitions + +The following macro definitions are detected when they are at the start of a +line (can be prefixed by \global, \long, \protected and/or \outer): - The following macro definitions are detected when they are at the start of a - line (can be prefixed by \global, \long, \protected and/or \outer): \def \edef \gdef \xdef \newcommand{\name} \newcommand*{\name} \newcommand\name \newcommand*\name @@ -49,83 +63,183 @@ my $DESCRIPTION = << 'EOT'; \providecommand\name \providecommand*\name \@namedef{\name} \@namedef\name - The following environment definitions are detected when they are at the start - of a line: +The following environment definitions are detected when they are at the start +of a line: + \newenvironment{name} \renewenvironemnt{name} \provideenvironment{name} - The macro and environment definition must either end at the same line or with - a '}' on its own on a line. +The macro and environment definition must either end at the same line or with +a 'C<}>' on its own on a line. -EOT -################################################################################ -my $VERSION = "v2.1 " . substr( '$Date: 2011-02-02 15:25:40 +0000 (Wed, 02 Feb 2011) $', 7, 10 ); -$VERSION =~ tr/-/\//; -my $TITLE = << "EOT"; - sty2dtx -- Converts a LaTeX .sty file to a documented .dtx file - Version: $VERSION -EOT -sub usage { - print << "EOT"; -sty2dtx.pl [<options>] [--<VAR>=<VALUE> ...] [--] [<infile> ...] [<outfile>] -Version: $VERSION -EOT - print << 'EOT'; -Files: - * can be '-' for STDIN or STDOUT, which is the default if no files are given - * multiple input files are merged to one output file - -Variables: - can be defined using --<VAR>=<VALUE> or --<VAR> <VALUE> and will be used for - substitutions in the template file. - Common variables: +=head1 USAGE + + sty2dtx [<options>] [--<VAR>=<VALUE> ...] [--] [<infile(s)>] [<outfile>] + +=head2 Files + +=over 2 + +=item * + can be 'C<->' for STDIN or STDOUT, which is the default if no files are given + +=item * + multiple input files are merged to one output file + +=back + +=head2 Variables + +Variables can be defined using + + --<VAR>=<VALUE> + +or + + --<VAR> <VALUE> + +and will be used for substitutions in the template file. + +=head3 Common variables: + author, email, maintainer, year (for copyright), version, date, description (of package/class), type (either 'package' default or 'class'), filebase (automatically set from output or input file name), -Options: - -h : Print this help text - -H : Print extended help - -V : Print version and copyright - -v : Be verbose - -o <output> : Use given file as output - -O : Overwrite already existing output file(s) - -B : Use basename of single input file for output file - -I : Also create .ins (install) file - -c : Only use code section (like v1.0) - -i <ins file> : Create .ins file with given name - -t <template> : Use this file as template instead of the default one - -T <template> : Use this file as template for the .ins file - -e <file> : Export default .dtx template to file and exit - -E <file> : Export default .ins template to file and exit - -D : Use current date as file date - -F <file> : Read more options and variables from file. - Should contain one option or variable per line only. - -Examples: - Produce 'file.dtx' from 'file.sty': + +=head2 Options + +=over 8 + +=item B<-h> S< > + Print this help text + +=item B<-H> S< > + Print extended help + +=item B<-V> S< > + Print version and copyright + +=item B<-v> S< > + Be verbose + +=item B<-o> F<output> S< > + Use given file as output + +=item B<-O> S< > + Overwrite already existing output file(s) + +=item B<-B> S< > + Use basename of single input file for output file + +=item B<-I> S< > + Also create .ins (install) file + +=item B<-c> S< > + Only use code section (like v1.0) + +=item B<-r> S< > + Remove existing 'macro', 'macrocode', etc. environments. + +=item B<-R> S< > + Do not remove existing 'macro', 'macrocode', etc. environments. + +=item B<-i> F<ins-file> S< > + Create .ins file with given name + +=item B<-t> F<template> S< > + Use this file as template instead of the default one + +=item B<-T> F<template> S< > + Use this file as template for the .ins file + +=item B<-e> F<file> S< > + Export default .dtx template to file and exit + +=item B<-E> F<file> S< > + Export default .ins template to file and exit + +=item B<-D> S< > + Use current date as file date + +=item B<-F> F<file> S< > + Read more options and variables from file. + +=item B<-N> S< > + Do not read default config file; must be the first option + +=back + + +=head2 Config files + +A default config file either named 'sty2dtx.cfg' or '.sty2dtx.cfg' is searched +in the current directory, the users home directory and the directory of this +script, in this order. The first one found is loaded. If none is found the +'texmf' tree is searched for a 'sty2dtx.cfg' config file. As with -F files the +config file should contain one option or variable per line. +Lines starting with 'C<%>' or 'C<#>' are ignored. + + +=head1 Examples + +Produce 'file.dtx' from 'file.sty': + sty2dtx.pl < file.sty > file.dtx - or + +or + sty2dtx.pl file.sty file.dtx - or + +or + sty2dtx.pl -B file.sty - Produce 'file.dtx' and 'file.ins' from 'file.sty': +Produce 'file.dtx' and 'file.ins' from 'file.sty': + sty2dtx.pl -I file.sty file.dtx - or + +or + sty2dtx.pl file.sty -i file.sty file.dtx - or + +or + sty2dtx.pl -IB file.sty - Set custom variable values: +Set custom variable values: + sty2dtx.pl --author Me --email me@there.com mypkg.sty mypkg.dtx - Produce DTX file for a class: +Produce DTX file for a class: + sty2dtx.pl --type class mycls.sty mycls.dtx +=head1 AUTHOR + +Martin Scharrer + +E-mail: L<martin@scharrer-online.de> + +WWW: L<http://www.scharrer-online.de> + +=cut + +################################################################################ +use Pod::Usage; + +my $VERSION = "v2.3"; +$VERSION =~ tr/-/\//; + +my $TITLE = << "EOT"; + sty2dtx -- Converts a LaTeX .sty file to a documented .dtx file + Version: $VERSION EOT - exit(0); + +sub usage { + print "Version: $VERSION\n\n"; + pod2usage(-message => $TITLE, -sections => 'USAGE', -verbose=>99 ); } my $ERROR = "sty2dtx: Error:"; @@ -137,6 +251,12 @@ my $macrostart = <<'EOT'; %s%% \begin{macrocode} EOT +my $keystart = <<'EOT'; +%% +%% \begin{key}{%s}{%s} +%s%% \begin{macrocode} +EOT + my $environmentstart = <<'EOT'; %% %% \begin{environment}{%s} @@ -149,6 +269,12 @@ my $macrodescription = <<'EOT'; %% EOT +my $keydescription = <<'EOT'; +%% +%% \DescribeKey{\%s}{\%s} +%% +EOT + my $envdescription = <<'EOT'; %% %% \DescribeEnv{%s} @@ -162,6 +288,12 @@ my $macrostop = <<'EOT'; % EOT +my $keystop = <<'EOT'; +% \end{macrocode} +% \end{key} +% +EOT + my $environmentstop = <<'EOT'; % \end{macrocode} % \end{environment} @@ -176,18 +308,20 @@ my $macrocodestop = <<'EOT'; % \end{macrocode} EOT -my $USAGE = ''; # Store macro names for usage section -my $IMPL = ''; # Store implementation section +my $USAGE = q(); # Store macro names for usage section +my $IMPL = q(); # Store implementation section my $mode = 0; # 0 = outside of macro or macrocode environments # 1 = inside 'macrocode' environment # 2 = inside 'macro' environment # 3 = inside 'environment' environment +# 4 = inside 'key' environment # RegExs for macro names and defintion: -my $rmacroname = qr/[a-zA-Z\@:]+/; # Add ':' for LaTeX3 style macros -my $rusermacro = qr/[a-zA-Z]+/; # Macros intended for users +my $rmacroname = qr/[a-zA-Z\@:]+/xms; # Add ':' for LaTeX3 style macros +my $renvname = qr/[a-zA-Z\@:*]+/xms; # +my $rusermacro = qr/[a-zA-Z]+/xms; # Macros intended for users my $rmacrodef = qr/ ^ # Begin of line (no whitespaces!) ( @@ -203,17 +337,28 @@ my $rmacrodef = qr/ (.*) # Rest of line /xms; +my $rkeydef = qr/ + ^ # Begin of line (no whitespaces!) + \\ + (define\@[a-z]*key) + \s* + {([^}]+)} # Key family + \s* + {([^}]+)} # Key name + (.*) # Rest of line + /xms; + my $renvdef = qr/ ^ # Begin of line (no whitespaces!) \\( (?:new|renew|provide)environment\s* { \s* # LaTeX definitions ) - ($rmacroname) # Environment names follow same rules as macro names + ($renvname) # Environment names follow same rules as macro names \s* } # closing brace (.*) # Rest of line /xms; -my $comments = ''; +my $comments = q(); # Print end of environment, if one is open sub close_environment { @@ -227,6 +372,9 @@ sub close_environment { elsif ( $mode == 3 ) { $IMPL .= $environmentstop; } + elsif ( $mode == 4 ) { + $IMPL .= $keystop; + } } my ( $mday, $mon, $year ) = ( localtime(time) )[ 3 .. 5 ]; @@ -234,16 +382,18 @@ $mon = sprintf( "%02d", $mon + 1 ); $year += 1900; my @files; -my $outfile = ''; -my $verbose = 0; -my $codeonly = 0; -my $install = 0; -my $usebase = 0; -my $overwrite = 0; +my $outfile = q(); +my $verbose = 0; +my $codeonly = 0; +my $install = 0; +my $usebase = 0; +my $overwrite = 0; +my $removeenvs = 0; my $installfile; my $templfile; my $installtempl; my $checksum = 0; +my $config_file; # Holds the variables for the templates, is initiated with default values: my %vars = ( @@ -252,6 +402,9 @@ my %vars = ( year => "$year", ); +my $template = *DATA; +my %OUTFILES; + # Handle options sub option { my $opt = shift; @@ -259,10 +412,13 @@ sub option { usage(); } elsif ( $opt eq 'H' ) { - print $TITLE; - print "\n"; - print $DESCRIPTION; - exit(0); + pod2usage(-message => $TITLE, -sections => 'DESCRIPTION', -verbose=>99 ); + } + elsif ( $opt eq 'r' ) { + $removeenvs = 1; + } + elsif ( $opt eq 'R' ) { + $removeenvs = 0; } elsif ( $opt eq 'c' ) { $codeonly = 1; @@ -271,16 +427,14 @@ sub option { $usebase = 1; } elsif ( $opt eq 't' ) { - close(DATA); $templfile = shift @ARGV; - open( DATA, '<', $templfile ) - or die "$ERROR Couldn't open template file '$templfile'\n"; } elsif ( $opt eq 'e' ) { my $templ = shift @ARGV; if ( $templ ne '-' ) { + die "$ERROR '$templ' already exists\n" if -e $templ; open( STDOUT, '>', $templ ) - or die "$ERROR Couldn't open new template file '$templ'\n"; + or die "$ERROR Couldn't open new template file '$templ' ($!)\n"; } while (<DATA>) { last if /^__INS__$/; @@ -294,8 +448,9 @@ sub option { elsif ( $opt eq 'E' ) { my $templ = shift @ARGV; if ( $templ ne '-' ) { + die "$ERROR '$templ' already exists\n" if -e $templ; open( STDOUT, '>', $templ ) - or die "$ERROR Couldn't open new template file '$templ'\n"; + or die "$ERROR Couldn't open new template file '$templ' ($!)\n"; } while (<DATA>) { last if /^__INS__$/; @@ -322,34 +477,49 @@ sub option { $installtempl = shift @ARGV; } elsif ( $opt eq 'V' ) { - print $TITLE; - print "\n"; - print $COPYRIGHT; - exit(0); + pod2usage(-message => $TITLE, -sections => 'COPYRIGHT', -verbose=>99 ); + } + elsif ( $opt eq 'N' ) { + print STDERR "sty2dtx warning: '-N' option used after default config file was already loaded.\n" + if $config_file && $verbose; } elsif ( $opt eq 'F' ) { my $optfile = shift @ARGV; # Read more options and variables from file open( my $OPT, '<', $optfile ) - or die("Couldn't open options file '$optfile'!\n"); + or die("Couldn't open options file '$optfile' ($!)!\n"); while ( my $line = <$OPT> ) { chomp $line; # Skip comment lines next if $line =~ /^\s*[#%]/; - # Split variable lines without equal sign into name and value - if ( substr( $line, 0, 2 ) eq '--' and index( $line, '=' ) == -1 ) { - my ( $var, $val ) = split( /\s+/, $line, 2 ); - $val =~ s/^["']|["']$//g; + # Handle variables + # Split at '=' or space and add as two arguments + if ( $line =~ /\A\s*(--[a-zA-Z0-9]+?)(?:\s+|=)(.*)/xms ) { + my $var = $1; + (my $val = $2) =~ s/^["']|["']$//g; unshift @ARGV, $var, $val; } + # Handle options with and without values + # as well sets of options + elsif ($line =~ /\A\s*(-[a-zA-Z0-9]+)(?:\s+(.*))?/xms) { + my $var = $1; + my $val = $2; + if (defined $val) { + $val =~ s/^["']|["']$//g; + unshift @ARGV, $var, $val; + } + else { + unshift @ARGV, $var; + } + } else { - unshift @ARGV, $line; + die "$ERROR Could not recognize '$line' in '$optfile'\n"; } } - close($OPT); + close $OPT; } elsif ( $opt eq 'D' ) { $vars{date} = "$year/$mon/$mday"; @@ -360,6 +530,13 @@ sub option { elsif ( $opt eq 'O' ) { $overwrite = 1; } + elsif ( $opt eq 'A' ) { + $template = shift @ARGV; + } + elsif ( $opt eq 'a' ) { + my $outname = shift @ARGV; + $OUTFILES{$outname} = $template; + } else { print STDERR "sty2dtx: unknown option '-$opt'!\n"; exit(2); @@ -373,6 +550,33 @@ sub addtochecksum { } ################################################################################ + +my $CONFIG_NAME = "sty2dtx.cfg"; + +if (!@ARGV || $ARGV[0] !~ /^-[^-]*N/) { + +PATH: +foreach my $path ('.', $ENV{HOME}, dirname($0)) { + foreach my $file ($path.'/'.$CONFIG_NAME, $path.'/.'.$CONFIG_NAME) { + if (-e $file) { + $config_file = $file; + last PATH; + } + } +} +if (!$config_file) { + # Find the config file in the TeX tree. + $config_file = `kpsewhich -must-exist $CONFIG_NAME`; +} +if ($config_file) { + chomp $config_file; + print STDERR "sty2dtx info: loading config file '$config_file'.\n" + if ($verbose); + unshift @ARGV, '-F', $config_file; +} + +} + # Parse arguments while (@ARGV) { my $arg = shift; @@ -401,7 +605,12 @@ while (@ARGV) { } # Form "--var value" else { - $vars{ lc($name) } = shift; + if ($name eq "help") { + usage(); + } + else { + $vars{ lc($name) } = shift; + } } } # Files @@ -431,7 +640,7 @@ if ( $outfile && $outfile ne '-' ) { . " Use the -O option to overwrite.\n" ); } open( OUTPUT, '>', $outfile ) - or die("$ERROR Could not open output file '$outfile'!"); + or die("$ERROR Could not open output file '$outfile' ($!)!"); select OUTPUT; } @@ -447,6 +656,8 @@ while (<>) { my $name = $3; # macro name my $rest = $4; # rest of line + MACRO: + # Add to usage section if it is a user level macro if ( $name =~ /^$rusermacro$/i ) { $USAGE .= sprintf( $macrodescription, $name ); @@ -472,6 +683,36 @@ while (<>) { $mode = 0; } } + elsif (/$rkeydef/) { + my $pre = ""; # before command + my $cmd = $1; # definition command + my $keyfamily = $2; # macro name + my $keyname = $3; # macro name + my $rest = $4; # rest of line + + # Add to usage section if it is a user level macro + $USAGE .= sprintf( $keydescription, $keyfamily, $keyname ); + + close_environment(); + + # Print 'key' environment with current line. + $IMPL .= sprintf( $keystart, $keyfamily, $keyname, $comments ); + addtochecksum($_); + $IMPL .= $_; + $comments = ''; + + # Inside key mode + $mode = 4; + + # Test for one line definitions. + # $pre is tested to handle '{\somecatcodechange\gdef\name{short}}' lines + my $prenrest = $pre . $rest; + if ( $prenrest =~ tr/{/{/ == $prenrest =~ tr/}/}/ ) { + $IMPL .= $keystop; + # Outside mode + $mode = 0; + } + } # Test for environment definition command elsif (/$renvdef/) { my $cmd = $1; # definition command @@ -507,8 +748,12 @@ while (<>) { # Real comments are either: 1) starting with a '%' at SOL or 2) are followed # by at least one whitespace. This exclude (most) commented out code. elsif (/^%|^\s*%\s/) { - $_ =~ s/^\s*//; - $comments .= $_; + if (!$removeenvs || !/^%\s+\\(?:begin|end){(?:macro|environment|macrocode|key)}/) { + $_ =~ s/^\s*//; + if ($comments || !/^%\s*$/){ + $comments .= $_; + } + } if ( $mode == 1 ) { $IMPL .= $macrocodestop; $mode = 0; @@ -533,7 +778,8 @@ while (<>) { $IMPL .= $_; # A single '}' on a line ends a 'macro' or 'environment' environment if ( $mode > 1 && /^\}\s*$/ ) { - $IMPL .= ( $mode == 2 ) ? $macrostop : $environmentstop; + $IMPL .= ( $mode == 2 ) ? $macrostop : + ( $mode == 3 ) ? $environmentstop : $keystop; $mode = 0; } } @@ -570,10 +816,17 @@ if ($codeonly) { } } else { - while (<DATA>) { - last if /^__INS__$/; + if ($templfile) { + open( DTX, '<', $templfile ) + or die "$ERROR Couldn't open template file '$templfile' ($!)\n"; + } + else { + *DTX = *DATA; + } + while (<DTX>) { + last if !$templfile and /^__INS__$/; # Substitute template variables - s/<\+([^+]+)\+>\n?/exists $vars{$1} ? $vars{$1} : "<+$1+>"/eg; + s/<\+([^+]+)\+>/exists $vars{$1} ? $vars{$1} : "<+$1+>"/eg; print; } @@ -584,49 +837,81 @@ else { print STDERR ".\n"; } } - +select STDOUT; ################################################################################ # Write INS file if requested -exit(0) unless $install; +if ($install) { -if ( ( !$outfile || $outfile eq '-' ) && !$installfile ) { - print STDERR - "Warning: Did not generate requested .ins file because main file\n"; - print STDERR " was written to STDOUT and no -i option was given.\n"; - exit(1); -} + if ( ( !$outfile || $outfile eq '-' ) && !$installfile ) { + print STDERR + "Warning: Did not generate requested .ins file because main file\n"; + print STDERR " was written to STDOUT and no -i option was given.\n"; + exit(1); + } + + if ($installtempl) { + open( DATA, '<', $installtempl ) + or die "$ERROR Could't open template '$installtempl' for .ins file! ($!)\n"; + } + elsif ($codeonly || $templfile) { + # If DATA template was not used for main file go forward to correct position + while (<DATA>) { + last if /^__INS__$/; + } + } + + $installfile = $vars{filebase} . '.ins' unless defined $installfile; + if ( !$overwrite && -e $installfile && $installfile ne '/dev/null' ) { + die( "$ERROR Output file '$installfile' does already exists!" + . " Use the -O option to overwrite.\n" ); + } + open( INS, '>', $installfile ) + or die "$ERROR Could't open new .ins file '$installfile' ($!)\n"; -if ($installtempl) { - open( DATA, '<', $installtempl ) - or die "$ERROR Could't open template '$installtempl' for .ins file."; -} -elsif ($codeonly) { - # If DATA template was not used for main file go forward to correct position while (<DATA>) { - last if /^__INS__$/; + # Substitute template variables + s/<\+([^+]+)\+>/exists $vars{$1} ? $vars{$1} : "<+$1+>"/eg; + print INS $_; } -} -$installfile = $vars{filebase} . '.ins' unless defined $installfile; -if ( !$overwrite && -e $installfile && $installfile ne '/dev/null' ) { - die( "$ERROR Output file '$installfile' does already exists!" - . " Use the -O option to overwrite.\n" ); -} -open( INS, '>', $installfile ) - or die "$ERROR Could't open new .ins file '$installfile'."; + if ($verbose) { + print STDERR "Generated INS file '$installfile'"; + print STDERR " using template '$installtempl'" if $installtempl; + print STDERR ".\n"; + } -while (<DATA>) { - # Substitute template variables - s/<\+([^+]+)\+>\n?/exists $vars{$1} ? $vars{$1} : "<+$1+>"/eg; - print INS $_; } -if ($verbose) { - print STDERR "Generated INS file '$installfile'"; - print STDERR " using template '$installtempl'" if $installtempl; - print STDERR ".\n"; +################################################################################ +# Write additional files if requested +while (my ($outfile, $template) = each %OUTFILES) { + my $TEMPLATEHANDLE; + if (ref $template eq 'GLOB') { + $TEMPLATEHANDLE = $template; + } + # TODO: add support for DTX and INS templates in DATA + else { + open( $TEMPLATEHANDLE, '<', $template ) + or die "$ERROR Could't open template '$template' for file '$outfile' ($!)!\n"; + } + open( my $OUTFILEHANDLE, '>', $outfile ) + or die "$ERROR Could't create output file '$outfile' ($!)!\n"; + + while (<$TEMPLATEHANDLE>) { + # Substitute template variables + s/<\+([^+]+)\+>/exists $vars{$1} ? $vars{$1} : "<+$1+>"/eg; + print {$OUTFILEHANDLE} $_; + } + close $TEMPLATEHANDLE; + close $OUTFILEHANDLE; + + if ($verbose) { + print STDERR "Generated file '$outfile' using template '$template'.\n"; + } } ################################################################################ +exit (0); +################################################################################ # The templates for the DTX file and INS file # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Adepted from the skeleton file provided by the 'dtxtut' (DTX tuturial). |