#!/usr/local/bin/perl # Check options and load configuration files &init; ######################################################################## #### Site configuration ### ######################################################################## # Set the following variables according to the requirements of your site # Alternatively, copy the lines up to "End of configuration options" # to your $HOME/.makesegments.cnf or $PWD/.makesegments.cnf for # overriding system-wide defaults # These settings are OVERRIDDEN by corresponding command line options! # # This part of the program is run after any configuration file, # config file settings therefore override anything set here # Location to look for L2H-supported LaTeX styles $LATEX2HTMLSTYLES="/usr/local/lib/texmf/latex2html/styles" unless $LATEX2HTMLSTYLES; # Location for TeX style files etc. # $TEXINPUTS is read from the environment if not explicitly supplied $TEXINPUTS=$ENV{'TEXINPUTS'} unless $TEXINPUTS; $TEXINPUTS=".:/usr/local/lib/texmf/tex//" unless $TEXINPUTS; # Location for BibTeX Bibliography databases # $BIBINPUTS is read from the environment if not explicitly supplied $BIBINPUTS=$ENV{'BIBINPUTS'} unless $BIBINPUTS; $BIBINPUTS=".:/usr/local/lib/texmf/bibtex/bib/" unless $BIBINPUTS; # Location for BibTeX Bibliography styles (in addition to $TEXINPUTS) # $BSTINPUTS is read from the environment if not explicitly supplied $BSTINPUTS=$ENV{'BSTINPUTS'} unless $BSTINPUTS; $BSTINPUTS="/usr/local/lib/texmf/bibtex/bst/" unless $BSTINPUTS; # The lowest sectioning command at which to create segments # corresponds to -l option $LEVEL="section" unless $LEVEL; # set this to 1 if you want no Makefile by default # corresponds to -n option $NOMAKE=0 unless $NOMAKE; # Set this to one if LaTeX style files should be searched for by default # corresponds to -s option $CHECK_LATEX_STYLES=0 unless $CHECK_LATEX_STYLES; # Zeroeth-segment name (type makesegments -h for explanation) # corresponds to -z option $SEGSTART="a0" unless $SEGSTART; # Set this to one to supress inlining input files # corresponds to -i option $IGNOREINPUTS=0 unless defined $IGNOREINPUTS; # Set this to one to suppress copying required input files # corresponds to -d option $DONTCOPY=0 unless defined $DONTCOPY; # Set this to one to softlink input files instead of copying them # corresponds to -u option $USELINKS=0 unless defined $USELINKS; # SPECIALS=1 means that special sections (table of contents, # bibliography, index...) are put into special segments # corresponds to -e option $SPECIALS=0 unless defined $SPECIALS; # Hash SPECIALNAMES defines standard filenames for # The special segments. (For tableofcontents, toc.tex resp. toc.html) # Undefined entries (those commented out below) # will not create a special segment. %SPECIALNAMES=( "tableofcontents" => "toc", "printindex" => "ind", # "listoffigures" => "lof", # "listoftables" => "lot", # "bibliography" => "bbl", # "thebibliography" => "tbl", ); # URL titles for special segments. Customize if you need titles in other # languages. %SPECIALTITLES=( "tableofcontents" => "Contents", "listoffigures" => "Figures", "listoftables" => "Tables", "bibliography" => "References", "thebibliography" => "References", "printindex" => "Index"); ##################################### ## Options for Makefile generation ## ##################################### # set $TEXENV to TEXINPUTS=.:(my_tex_path) PKFONTS=.:(my_PK_font_path) ... # if you need to set these environment vars before starting latex # You may also say $TEXENV="TEXINPUTS=$TEXINPUTS..." if you've set $TEXINPUTS $TEXENV="" unless $TEXENV; # accordingly, set $DVIPSENV for dvips $DVIPSENV="" unless $DVIPSENV; # Insert special paths (and options) for executables, if required $LATEX="$TEXENV latex" unless $LATEX; $BIBTEX="bibtex -verbose" unless $BIBTEX; $MAKEINDEX="makeindex" unless $MAKEINDEX; $DVIPS="$DVIPSENV dvips" unless $DVIPS; $L2H="latex2html" unless $L2H; $MAKE="make" unless $MAKE; $TOUCH="touch" unless $TOUCH; # LaTeX2HTML command line options for all files $MAKE_COMMON="-index_in_navigation -contents_in_navigation" unless $MAKE_COMMON; # LaTeX2HTML command line options for child segments $MAKE_CHILDREN="-info \"\"" unless $MAKE_CHILDREN; # LaTeX2HTML command line options for master file $MAKE_TOP="" unless $MAKE_TOP; ######################################## ### EXPERTS ONLY: ######################################## # Define additional LaTeX commands to be recognized %USER_CMDS=(); # syntax: # %USER_CMDS=("cmd1_name" => [cmd1_arguments], # "cmd2_name" => [cmd2_arguments], # ...) # # cmdX_arguments is a list of the arguments in correct order, # $m for mandatory, $o for optional arguments. # # Give an empty list if no arguments are required. # # Example: # %USER_CMDS=("parbox" => [$o,$m,$m], "newline" => []) # to make makesegments recognize parbox commands. # # Supply an additional entry for the starred command if it takes # different arguments (but beware the same do... routine will be called!) # # See the syntax of %misc_cmds below for further examples. # You may add Perl code to support your commands by defining # a subroutine "do_command". # Example: Write all parboxes to a file "parboxes": # # sub do_parbox { # parboxnum++; # open (PARBOX,">>parboxes"); # print PARBOX "parbox No. $parboxnum, $command".join('',@args)."\n"; # print PARBOX "position: $opt[0], width=$mand[0]\n"; # print PARBOX "text: $mand[1]\n"; # close PARBOX; # }; # # The optional arguments can be retrieved from array @opt, # mandatory ones from @mand (parens and whitespace stripped). # Complete argument list is @arg (with parens). # $star is "*" if the command was encountered in a starred version. # # You MUST add "parbox" to %USER_CMDS to activate your routine! # # See below for examples. 1; # This should be the last line of your configuration script ######################################################################## #### End of configuration options ### #### Do not modify below this line ! ### ######################################################################## # Make sure that command line options override config-file settings # (users might omit unless defined ... in their config files) $O_LEVEL && ($LEVEL=$O_LEVEL); $O_DIR && ($DIR=$O_DIR); $O_OUTFILE && ($OUTFILE=$O_OUTFILE); $O_SEGSTART && ($SEGSTART=$O_SEGSTART); $O_CHECK_LATEX_STYLES && ($CHECK_LATEX_STYLES=$O_CHECK_LATEX_STYLES); $O_NOMAKE && ($NOMAKE=$O_NOMAKE); $O_IGNOREINPUTS && ($IGNOREINPUTS=$O_IGNOREINPUTS); $O_DONTCOPY && ($DONTCOPY=$O_DONTCOPY); $O_USELINKS && ($USELINKS=$O_USELINKS); $O_SPECIALS && ($SPECIALS=$O_SPECIALS); # Specify the allowed segmentation levels %levels=("document" => 0, "part" => 1, "chapter" => 2, "section" => 3, "subsection" => 4, "subsubsection" => 5); %nosegment_cmds=( "tableofcontents" => [], "listoffigures" => [], "listoftables" => [], "bibliography" => [$m], "printindex" => []); %label_cmds=("label" => [$m]); %ref_cmds=("ref" => [$m], "pageref" => [$m]); %index_cmds=("index" => [$m]); %misc_cmds=( "usepackage" => [$o,$m], "internal" => [$o,$m], "endinput" => [], # \no mandatory arg specified for \input # (people may use tex-style \input myfile) "input" => [], "include" => [$m], "title" => [$m], # newcommand ... are included only because their arguments should be # read by parse_simple_block rather than parse_latex_block "newcommand" => [$m,$o,$m], "renewcommand" => [$m,$o,$m], "newenvironment" => [$m,$o,$m,$m], "renewenvironment" => [$m,$o,$m,$m], "documentclass" => [$o,$m], "documentstyle" => [$o,$m], "bibliographystyle" => [$m], "begin" => [$m], "end" => [$m], "segment" => [$m,$m,$m], "includegraphics" => [$o,$m], "includegraphics*" => [$o,$o,$m], "epsfig" => [$m], "html" => [$m], "hyperref" => [$m,$m,$m,$m], "htmlref" => [$m,$m], %USER_CMDS); %nosegment_envs=( "thebibliography" => []); @bibfiles=(); @files_to_copy=(); # die if no input file specified !$FILE && die "$usage_string\n\nmakesegments: No filename specified!\n"; # add .tex to filename if it isn't already there !($FILE =~ /[.]tex$/) && do { $FILE=$FILE.".tex" }; # strip unnecessary /./ and ./ from filename $FILE =~ s|/[.]/|/|g; $FILE =~ s|^[.]/||; !defined($levels{$LEVEL}) && die "\nmakesegments: level $LEVEL not allowed!\nValid levels are: ". join(', ',(sort {$levels{$a} <=> $levels{$b}} (keys %levels)))."\n\n"; !defined($DIR) && do { $DIR="segmented"; print STDERR "No directory specified: trying ./$DIR\n" ; }; # strip unnecessary /./ from dirname. assume current if no dir specified. $DIR =~ s|/[.]/|/|g; $DIR =~ s|^[.]/||; if (!defined ($OUTFILE)) { if ($DIR =~ /^[.]$/) { ($OUTFILE=$FILE) =~ s/[.]tex$/_seg.tex/; # do not copy include files into the current directory $DONTCOPY=1; } else { ($OUTFILE=$FILE) =~ s|.*/|| }; print STDERR "No output file specified: trying $DIR/$OUTFILE\n"; }; ($OUTFILE =~ m|/|) && die "\nmakesegments: must use a simple filename with the -o option\n"; !($OUTFILE =~ /[.]tex$/) && do { $OUTFILE=$OUTFILE.".tex" }; $PWD=$ENV{"PWD"}."/"; if ($DIR =~ m|^/|) { $fulldir=$DIR } else { $fulldir="$PWD$DIR" }; $fulldir =~ s|/[.]$|| unless ($DIR =~ m|^/|); if ($FILE =~ m|^/|) { $fullfile=$FILE } else { $fullfile="$PWD$FILE" }; ($fullfile =~ m|^$fulldir/$OUTFILE$|) && die "\nmakesegments: can't overwrite $FILE!\n"; !(-f $FILE) && die "\nmakesegments: $FILE doesn't exist!\n" ; if (-e $DIR) { stat $DIR; !(-d _) && die "\nmakesegments: $DIR is not a directory!\n"; !(-r _) && die "\nmakesegments: $DIR is not readable!\n"; !(-w _) && die "\nmakesegments: $DIR is not writable!\n"; !(-x _) && die "\nmakesegments: $DIR is not executable!\n"; if (-e $OUTFILE) { !(-w $OUTFILE) && die "\nmakesegments: $OUTFILE exists and is non-writable!\n" } } else { !(mkdir $DIR, 0777) && die "\nmakesegments: can\'t create $DIR!\nsystem error:$!\n" }; foreach $key (keys %levels) { $segments{$key} = [$o,$m] unless ($levels{$key} > $levels{$LEVEL}); }; &make_known_cmds; $begin_env_re='\\\\begin\\s*\\{\\s*([^\}\s]+)\\s*\\}'; $begin_simple_re='([\\{]|[\\[])'; $end_simple_re='([\\}]|[\\]])'; $simple_delim_re='([\\{]|[\\[]|[\\}]|[\\]])'; $begin_block_re='([\\$]|[\\{]|[\\[]|\\\\begin\\s*\\{\\s*[^\}]+\\s*\\})'; $end_block_re='([\\$]|[\\}]|[\\]]|\\\\end\\s*\\{\\s*[^\}]+\\s*\\})'; $ord_command_re='(\\\\\\w+[*]?)'; $special_re='('.$begin_block_re.'|'.$end_block_re.'|'.$ord_command_re.')'; $command_re='(\\\\[\@\\w]+[*]?|\\\\[ !\\"\\$%&\'\\(\\)+,\\-.\\/:;<=>\\[\\]\\^_\\`{}|~]'. '|\\\\a[=\'\\`]|\\\\\@\\.)'; $no_escape_re='(^|[^\\\\])((?:\\\\\\\\)*)'; $use_html_mark="\001<>"; $begin_htmlonly_mark="\001<>"; $end_htmlonly_mark="\001<>"; $input="IN000"; $output="OUT000"; $segname=$SEGSTART; $preamble=1; $head=""; $ERROR=""; @l2hinputs=split(/:/,($ENV{'LATEX2HTMLSTYLES'} ? $ENV{'LATEX2HTMLSTYLES'}:$LATEX2HTMLSTYLES)); @texinputs=split(/:/,$TEXINPUTS); @bibinputs=split(/:/,$BIBINPUTS); @bstinputs=split(/:/,$BSTINPUTS); @graphicsinputs=@texinputs; @graphicsextensions=(".ps",".eps",".gif",".prn"); %packages=(); @temporary_files=(); ($outname=$OUTFILE) =~ s/[.]tex//; ($tmp_out = $OUTFILE) =~ s/[.]tex$/.tmp/; print STDERR "\nPass 1: Analyzing $FILE ...\n\n"; &push_input($FILE); #print STDERR "first line: $_\n"; ($one,$two)=&parse_latex_block("",$_); &pop_output; &pop_input; print STDERR "\nPass 2: looking for dependencies & linking segments\n\n"; &dependencies; &write_segments; &make_makefile unless $NOMAKE; print STDERR "Done.\n"; exit 0; sub get_next_line { # print STDERR "%"; if (eof ($input)) { if ($#inhandle > 0) { &pop_input ; } else { die "\nmakesegment: Reached eof before end of block !\n" ; }; }; my ($line); $line=<$input>; # print STDERR "get: $line\n"; chomp $line; $line; } sub gently_get_next_line { # print STDERR "&"; if (eof ($input)) { if ($#inhandle > 0) { &pop_input ; } else { $ERROR="\nmakesegment: Reached eof before end of block !\n" ; }; }; my ($line); $line=<$input>; # print STDERR "gently: $line\n"; chomp $line unless $ERROR; ($ERROR ? "" : $line ); } sub parse_latex_block { local ($_); my ($start); ($start,$_)=@_; my ($comment,$block,$delim,$after,$verb); local ($env,$done,$end_re); local $foundend=0; $env=""; $verb=""; local $gentle=0; local $direct=""; $done=$start; $start =~ s/\s//g; # check which kind of block TYPE: { length($start) == 0 && do { # This is only allowed for the outermost block $gentle=1; $preamble=1; $end_re=""; $direct=&push_output ("$DIR/$tmp_out"); $cur_seg=$SEGSTART; $segment_names{$cur_seg}="document"; last TYPE }; $start =~ /^\{$/ && do { $end_re='\}'; last TYPE }; $start =~ /^\[$/ && do { $end_re='\]'; last TYPE }; $start =~ /^\\begin\{(\w+)([*]?)\}$/ && do { $env=$1.($2 ? "\[$2\]" : ""); $end_re='\\\\end\s*\{\s*'.$env.'\s*\}'; last TYPE }; $start =~ /^\$$/ && do { $end_re='\$'; last TYPE }; die "\nparse_latex_block: invalid opening delimiter: \"$start\"!\n"; }; # print STDERR "Entering block: $start...$end_re\n"; while (1) { # print STDERR "line $.: \"$_\"\n"; ($_,$comment)=&strip_comment($_); CASE: { s/^\s*$// && do { if ($direct) { if ($preamble) { $head.="$&$comment\n" } else { print "$&$comment\n" } } else { $done.="$&$comment\n" }; $comment=""; $_=&gently_get_next_line; if ($ERROR) { if ($gentle) { return ("",""); } else { die $ERROR; }; }; last CASE; }; # handle \verb s/$no_escape_re(\\verb[*]?)(.*)$//o && do { $_.="$1$2"; $verb=$3; $comment="$4$comment"; # No last statement here - continue with \verb-stripped $_ and $verb set }; s/$no_escape_re$special_re//o && do { if ($direct) { if ($preamble) { $head.="$`$1$2" } else { print "$`$1$2" } } else { $done.="$`$1$2" }; $after=$'; ($delim=$3)=~ s/\s*//g; # print STDERR "BlockRE: $&, $1, $2, \"$delim\", $after\n"; DELIM: { # we're done $end_re && ($delim =~ /^$end_re$/) && do { if ($direct) { while ($#outhandle > 0 ) { &pop_output } }; return ("$done$delim","$after$verb$comment"); }; # It's an environment begin $delim =~ /^$begin_env_re$/ && do { ($block,$after)=&process_env($delim,"$after$verb$comment"); # if ($gentle){ print STDERR "MAIN: closed $delim : $direct :".select."\n"}; if ($direct && !(select =~ /$direct$/)) { $direct="" }; if ($direct) { if ($preamble) { $head.=$block } else { print $block} } else { $done.=$block }; $comment=""; $verb=""; $_=$after; last CASE; }; $delim =~ /^$begin_block_re$/ && do { # It's a block begin ($block,$after)=&parse_latex_block($delim,"$after$verb$comment"); # if ($gentle){ print STDERR "MAIN: closed $delim : $direct :".select."\n"}; if ($direct && !(select =~ /$direct$/)) { $direct="" }; if ($direct) { if ($preamble) { $head.=$block } else { print $block} } else { $done.=$block }; $comment=""; $verb=""; $_=$after; last CASE; }; $delim =~ /^$end_block_re$/ && do { if ($delim =~ /^\]/) { if ($direct) { if ($preamble) { $head.=$delim } else { print $delim} } else { $done.=$delim }; # print STDERR "WARNING: strange block: $done, $after, $_\n"; $_="$after$comment"; $comment=""; $verb=""; last CASE; $_=$after; } else { if ($delim =~ /^\}$/) { return ("$done","$delim$after$verb$comment") } else { die "\nmakesegments: Block end doesn't match:\n". "END: \"$delim\", expected: \"". ($env ? "\\end\{$env\}" : $end_re). "\"\ntext:$done\n";} }; }; $delim =~ /^$ord_command_re$/ && do { ($block,$after)=&process_command($delim,"$after$verb$comment"); # print STDERR "\$delim=$delim, select=".select.", \$direct=$direct\n"; if ($direct) { if ($preamble) { $head.=$block } else { print $block} } else { $done.=$block }; if ($foundend) { return ($done,$after) }; $comment=""; $verb=""; $_=$after; last CASE; }; }; }; $verb && do { if ($direct) { print "$_$verb" } else { $done.="$_$verb" }; ($block,$after)=&process_verb($comment); # print STDERR "VERB FOUND:\n$block\n"; if ($direct) { print $block } else { $done.=$block }; $comment=""; $verb=""; $_=$after; last CASE; }; # print STDERR "Nothing found on $_\n"; if ($direct) { if ($preamble) { $head.="$_$comment\n" } else { print "$_$comment\n" } } else { $done.="$_$comment\n" }; $comment=""; $_=&gently_get_next_line; if ($ERROR) { if ($gentle) { return ("",""); } else { die $ERROR; }; }; }; }; }; sub parse_simple_block { # Special version, only needed for arguments of commands like # \newcommand or \newenvironment. # In these cases, constructs like # \newcommand{\beq}{\begin{equation}} are legitimate. # (would be an error in parse_latex_block, sice environment isn't closed) # No command parsing is carried out. # Now generally used for command arguments, since these rarely contain # environments or commands that need to be parsed local ($_); my ($start); ($start,$_)=@_; my ($comment,$block,$delim,$after,$end_re,$done,$verb); $verb=""; $done=$start; $start =~ s/\s//g; # check which kind of block # print stderr "Parse_simple_block: $start, $_\n"; TYPE: { $start =~ /^\{$/ && do { $end_re='\}'; last TYPE }; $start =~ /^\[$/ && do { $end_re='\]'; last TYPE }; die "\nparse_simple_block: invalid opening delimiter: \"$start\"!\n"; }; while (1) { # print STDERR "line $.: \"$_\"\n"; ($_,$comment)=&strip_comment($_); CASE: { s/^\s*$// && do { $done.="$&$comment\n"; $comment=""; $_=&get_next_line; last CASE; }; # handle \verb s/$no_escape_re(\\verb[*]?)(.*)$//o && do { $_.="$1$2"; $verb=$3; $comment="$4$comment"; # No last statement here - continue with \verb-stripped $_ and $verb set }; s/$no_escape_re$simple_delim_re//o && do { $done.="$`$1$2"; $after=$'; ($delim=$3)=~ s/\s*//g; # print STDERR "BlockRE: $&, $1, $2, \"$delim\", $after\n"; DELIM: { # we're done $end_re && ($delim =~ /^$end_re$/) && do { return ("$done$delim","$after$verb$comment"); }; $delim =~ /^$begin_simple_re$/ && do { # It's a block begin ($block,$after)=&parse_simple_block($delim,"$after$verb$comment"); $done.=$block ; $comment=""; $verb=""; $_=$after; last CASE; }; $delim =~ /^$end_simple_re$/ && do { if ($delim =~ /^\]/) { if ($direct) { if ($preamble) { $head.=$delim } else { print $delim} } else { $done.=$delim }; print STDERR "PSB WARNING: strange block: $done, $after, $_\n"; $_="$after$comment"; $comment=""; $verb=""; last CASE; } else { if ($delim =~ /^\}$/) { return ("$done","$delim$after$verb$comment") } else { die "\nmakesegments: Block end doesn't match:\n". "$done\nEND: \"$delim\", expected: \"$end_re\"\n";} }; }; }; }; $verb && do { # print STDERR "Parse_simple_block: $start, $verb, $_\n"; $done.="$_$verb"; ($block,$after)=&process_verb($comment); # print STDERR "VERB FOUND:\n$block\n"; $done.=$block; $comment=""; $verb=""; $_=$after; last CASE; }; $done.="$_$comment\n"; $comment=""; $_=&get_next_line; }; }; }; sub process_env { # $above is local from calling parse_latex_block local ($_); my ($delim,$env,$done,$after); ($delim,$_)=@_; $delim =~ $begin_env_re; $env=$1; # print STDERR "PE: environment \"$env\"\n"; CASE: { $env =~ /document/ && do { !$preamble && die "\\begin{document} encountered after end of preamble !\n"; $head=&process_preamble($head); $preamble=0; last CASE; }; $env =~ /htmlonly/ && do { # Ignore inputs in htmlonly blocks local $IGNOREINPUTS=1; # Ignore segments local %segments=(); ($done,$_)=&parse_latex_block($delim,$_); $preamble && do { $done =~ s/^\s*\\begin\s*\{\s*htmlonly\s*\}/$begin_htmlonly_mark/; $done =~ s/\\end\s*\{\s*htmlonly\s*\}\s*$/$end_htmlonly_mark/; }; return ($done,$_); }; $env =~ /verbatim[*]?|rawhtml/ && do { my $end_re='\\\\end\s*\{\s*'.$env.'\s*\}'; while (1) { if (s/$end_re//) { return ("$delim$done$`$&",$'); } else { $done.="$_\n"; $_=&get_next_line; }; }; }; defined ($nosegment_envs{$env}) && do { while ($#outhandle > 0) { $direct=""; &pop_output; }; $special_sections{$env}=""; ($done,$_)=&parse_latex_block($delim,$_); $cur_seg=$SEGSTART; if ($SPECIALS && (defined $SPECIALNAMES{$env})) { open (SPECIAL,">$DIR/$SPECIALNAMES{$env}.tmp"); print SPECIAL "\n$done"; close SPECIAL; $done=join("\n","\\begin{latexonly}", # "\\DumpCounters\{$SPECIALNAMES{$env}\}\{section\}\{\}", $done, "\\end{latexonly}"); push @specialsegments,("$SPECIALNAMES{$env}"); }; return ($done,$_); }; }; # print STDERR "processing $env ..."; ($done,$_)=&parse_latex_block($delim,$_); return ($done,$_); } sub getargs { local($_); $_=shift; my ($actual,$done,$comment,$delim,@blocks); $done=""; while ($actual=shift) { if ($actual eq $m) { $actual="$actual|$ord_command_re" }; ($_,$comment)=&strip_comment($_); # skip empty or pure comment lines while ( s/^\s*$// ) { $done.="$&$comment\n"; $_=&get_next_line; if (/^\s*$/) { print STDERR "WARNING: empty line found where arguments expected.\n". "Ignoring - but LaTeX won\'t like this! \n"; }; ($_,$comment)=&strip_comment($_); }; if (s/^(\s*)($o|$m|$ord_command_re)//o) { $done.=$1; $delim=$2; CASE: { $delim =~ /$actual/ && do { if ($delim =~ /$ord_command_re/) { ($block,$_)=($&,"$_$comment"); # print STDERR "GA: $block, $_\n"; push @blocks,("\{$block\}"); } else { ($block,$_)=&parse_simple_block ($delim,"$_$comment"); push @blocks, ($block); }; $done.=$block; $comment=""; last CASE; }; # found mandatory, but opt requested ($actual eq $o) && do { push @blocks, (""); $_="$delim$_$comment"; last CASE; }; # found opt, but mandatory requested: error die "Wrong arguments to $command: $done $delim $_\n"; }; } else { die "Wrong arguments to $command: $done $delim $_\n"; }; }; ($done,$_,@blocks); }; sub process_command { local($_,$command); local ($cmd,@arg,@opt,@mand,$star,$text); ($command,$_)=@_; $command =~ s/\s*//g; $command =~ s/[*]?$//; $star=$&; $command =~ s/^\\//; # print STDERR "command: $command\n"; if (defined($known_commands{$command})) { if ($star && (defined $known_commands{"$command*"})) { ($text,$_,@arg) = &getargs($_,@{$known_commands{"$command*"}}); } else { ($text,$_,@arg) = &getargs($_,@{$known_commands{$command}}); }; map { s/(^\s*|\s*$)//g } @arg; @opt = grep { /^\[/ } @arg; @mand = grep { /^\{/ } @arg; map { s/^\[\s*//; s/\s*\]$// } @opt; map { s/^\{\s*//; s/\s*\}$// } @mand; # print STDERR "$command -> @arg : ".join(',',@opt)." -> ".join(",",@mand)."\n"; # print STDERR "Known command found: $command!\n"; CMD: { defined (&{"do_$command"}) && do { &{"do_$command"}; last CMD; }; defined ($segments{$command}) && do { &do_segment_cmd; last CMD; }; defined ($nosegment_cmds{$command}) && do { # print STDERR "NOSEG FOUND: $command!\n"; &do_nosegment_cmd; last CMD; }; defined ($label_cmds{$command}) && do { &do_label_cmd; last CMD; }; defined ($index_cmds{$command}) && do { &do_index_cmd; last CMD; }; defined ($ref_cmds{$command}) && do { &do_ref_cmd; last CMD; }; }; }; return (($command ? "\\$command$star" : "").join(" ",@arg),$_); }; sub do_begin { my $block; ($block,$_)=&process_env("\\begin\{$mand[0]\}",$_); if ($direct && !(select =~ /$direct$/)) { $direct="" }; if ($direct) { if ($preamble) { $head.=$block } else { print $block} } else { $done.=$block }; $command=""; @arg=(); }; sub do_end { if ($env eq $mand[0]) { if ($direct) { while ($#outhandle > 0 ) { &pop_output }; }; } else { die "\nmakesegments: Block end doesn't match:\n". "END: \"\\end\{$mand[0]\}\", expected: \"\\end\{$env\}\"\n"; }; $foundend=1; }; sub do_segment_cmd { while ($#outhandle > 0) { &pop_output; }; # protect commands in section heading # needed for the \segment command of html.sty $segname++; $mand[0] =~ s/$no_escape_re$ord_command_re/"$1$2".&protect($3)/ge; $done.="\\segment$star".'{'.$segname."\}\{$command\}\{$mand[0]\}\n"; $direct=&push_output("$DIR/$segname.tmp"); $cur_seg=$segname; # print STDERR "Starting segment: $segname\n"; $segment_names{$cur_seg}=$command; # print STDERR join (", ",keys %segment_names)."\n"; ($segment_titles{$cur_seg}=$mand[0]) =~ s/[\n\t]//g; 1 while ($segment_titles{$cur_seg} =~ s/$no_escape_re$ord_command_re(\s*\[[^\]]*\])*(\s*\{[^}]*\})*/$1$2/g); $command=""; @arg=(); }; sub protect { local ($_)=@_; $_="\\protect$_" unless ($_ eq "\\protect"); $_; }; sub do_nosegment_cmd { while ($#outhandle > 0) { $direct=""; &pop_output; }; $special_sections{$command}=""; if ($command eq "bibliography") { my $file,$key; foreach $key (split(',',$mand[0])) { $file=&find_texinput($key,\@bibinputs,[".bib"]); push @bibfiles, ($file) unless $file =~ m:^(/|~):; }; }; $cur_seg=$SEGSTART; if ($SPECIALS && (defined $SPECIALNAMES{$command})) { open (SPECIAL,">$DIR/$SPECIALNAMES{$command}.tmp"); print SPECIAL "\n\\$command".join("",@arg)."\n"; close SPECIAL; push @specialsegments, ("$SPECIALNAMES{$command}"); $command=join("\n","begin{latexonly}", # "\\DumpCounters\{$SPECIALNAMES{$command}\}\{section\}\{\}", " \\$command".join('',@arg), "\\end{latexonly}"); @arg=(); }; }; sub do_label_cmd { push @{$cur_seg."_labels"},($mand[0]); }; sub do_index_cmd { $indexsegs{$cur_seg}=""; }; sub do_ref_cmd { push @{$cur_seg."_refs"},($mand[0]) unless ($cmd=grep {/^$mand[0]$/} @{$cur_seg."_refs"}); }; sub do_htmlref { # print STDERR "Htmlref: ".join(',',@mand)."\n"; push @{$cur_seg."_refs"},($mand[1]) unless ($cmd=grep {/^$mand[1]$/} @{$cur_seg."_refs"}); }; sub do_hyperref { # print STDERR "Hyperref: ".join(',',@mand)."\n"; push @{$cur_seg."_refs"},($mand[3]) unless ($cmd=grep {/^$mand[3]$/} @{$cur_seg."_refs"}); }; sub do_bibliographystyle { my $file=&find_texinput($mand[0],[(@bstinputs,@texinputs)],[".bst"]); push @files_to_copy, ($file) unless $file =~ m:^(/|~):; }; sub do_endinput { &pop_input if ($#inhandle > 0); $command=""; }; sub do_input { # Allow argument in braces or simple (TeX-like) argument s/\s*\{\s*([^\}\s]+)\s*\}// || s/\s*([^\s\[\]\{\}]+)//; # Args are read in directly to allow for tex-style \input myfile my $file=$1; $file = &find_texinput ($file,\@texinputs,["",".tex"]); if (!$IGNOREINPUTS) { &push_input ($file) if $file; $command=""; @arg=(); } else { push @files_to_copy, ($file) unless $file=~ m:^(/|~):; @arg=("\{$file\}"); }; }; sub do_include { # Args are read in directly to allow for tex-style \input myfile my $file = &find_texinput($mand[0],\@texinputs,["",".tex"]); if (!$IGNOREINPUTS) { &push_input ($file) if $file; $command=""; @arg=(); } else { push @files_to_copy, ($file) unless $file=~ m:^(/|~):; }; }; sub do_includegraphics { if ((defined $packages{"graphics"}) || (defined $packages{"graphicx"})) { my $file=&find_texinput($mand[0],\@graphicsinputs,\@graphicsextensions); push @files_to_copy, ($file) unless (!$file or $file=~ m:^(/|~):); }; }; sub do_epsfig { if (defined $packages{"epsfig"}) { $mand[0]=~/file=(.*?)($|,)/; my $file=$1; # print STDERR "epsfig:\$file=$file\n"; $file =~ s/^\s*|\s*$//g; $file=&find_texinput($file,\@graphicsinputs,\@graphicsextensions); push @files_to_copy, ($file) unless (!$file or $file=~ m:^(/|~):); }; }; sub do_segment { # Encoutered an already existing segment. # print STDERR "processing segment file \"$mand[0]\"...$mand[1], $mand[2]\n"; my $file,$base; $file = &find_texinput($mand[0],\@texinputs,["",".tex"]); if (!$INGNOREINPUTS) { ($base = $file) =~ s/[.]tex$//; unless (open (TMPIN,"<$file")) { die "Couldnt open $file for input!\n" }; unless (open (TMPOUT,">$base\_msg.tex")) { die "Couldnt open $base_msg.tex for output!\n" }; unshift @temporary_files,("$base\_msg.tex"); my $line; my $startfound=0; my $comment; # Search for the \startdocument command while ($line=) { ($line,$comment)=&strip_comment($line); if ($line =~ s/$no_escape_re\\startdocument(\W)//) { $startfound=1; $line="$3$'comment"; last; }; }; if ($startfound) { print TMPOUT $line; while ($line=) { print TMPOUT $line; }; # Pretend a \section ... \input sequence was found in the text $_=join(" ","\\$mand[1]$star\{$mand[2]\}", "\\input\{$base\_msg.tex}",$_); } else { print STDERR "WARNING: No \\startdocument found in segment $file!\n"; }; close TMPIN; close TMPOUT; $command=""; @arg=(); } else { push @files_to_copy, ($file) unless $file=~ m:^(/|~):; }; }; sub do_title { ($maintitle=$mand[0]) =~ s/\n|\t//g; 1 while ($maintitle =~ s/$no_escape_re$ord_command_re(\s*\[[^\]]*\])*\s*(\{[^}]*\})*/$1$2/g); }; sub do_usepackage { my $file; if ($opt[0]) { if ($CHECK_LATEX_STYLES) { if (!($file=&find_texstyle("$mand[0].sty"))) { print STDERR "WARNING: style file of package $mand[0] not found - ignored !\n"; $command=""; @arg=(); } else { push @files_to_copy, ($file) unless $file =~ m:^(/|~):; $packages{$mand[0]}=$opt[0]; }; } else { $packages{$mand[0]}=$opt[0]; }; } else { my $pack; my @packs=split(',',$mand[0]); foreach $pack (@packs) { if ($CHECK_LATEX_STYLES) { if (!($file=&find_texstyle("$pack.sty"))) { print STDERR "WARNING: style file of package $pack not found - ignored !\n"; @packs=grep {!(/$pack/)} @packs; } else { $packages{$pack}=""; push @files_to_copy,($file) unless $file=~ m:^(/|~):; }; } else { $packages{$pack}=""; }; if ($#packs > -1) { @arg=("\{".join(',',@packs)."\}"); } else { @arg=(); $command="" }; }; }; }; sub do_documentclass { my $file; if (!$CHECK_LATEX_STYLES || ($file=&find_texstyle("$mand[0].cls"))) { $class=$mand[0]; $global_options=$opt[0]; $_="$use_html_mark$_"; push @files_to_copy, ($file) unless $file =~ m:^(/|~):; } else { die "Fatal: document class file $mand[0].cls not found"; }; }; sub do_internal { $command=""; @arg=(); }; sub process_preamble { local ($_)=@_; my ($args,$html,$dir); # insert a \usepackage{html} line if it's not yet there print STDERR "Document class: $class, global options: $global_options\n"; print STDERR "packages found:\n"; foreach $args (keys %packages) { print STDERR "$args ".($packages{$args} ? "(options: ". $packages{$args}.").. " : ".. "); foreach $dir (@l2hinputs) { if (-f "$dir/$args.perl") { ${$args."_supported"}=1 ; print STDERR "(supported!) .. "; }; }; }; print STDERR "\n"; $html=(defined $packages{"html"}); s/$use_html_mark/($html ? "" : "\n\\usepackage{html}") /e; if (!$html) { $packages{"html"}=""; print STDERR "Adding package html ...\n"; }; $_; } sub strip_comment { local ($_)=@_; my ($comment); if (s/(^|[^\\])(\\\\)*(%.*)//) { $comment=$3; $_.="$1$2" ; } else { $comment="" }; ($_,$comment); } sub get_following { local ($_)=$@; my ($found)=0; my ($comment,$done,$arg,$command,$before,$block,$after); while (!$found) { ($_,$comment)=&strip_comment($_); CASE: { s/^\s$// && do { # Empty line $done.="$&$comment\n"; $comment=""; $_=&get_next_line; last CASE; }; s/^\s*$end_block_re//o && do { $found=1; return ($found,$done,$1,"$'$comment"); }; s/^\s*$end_re//o && do { $found=1; $arg=$1; ($before,$block,$after)=&get_simple_argument("$'$comment"); if ($block) { $done.=$before; $arg.=$block; return ($found,$done,$arg,$after); } else { die "\nCorrupted \\end statement: \"$arg$before$block$after\"\n" }; }; s/^\s*$begin_block_re//o && do { $found=2; return ($found,$done,$1,"$'$comment"); }; s/^\s*$end_re//o && do { $found=2; $arg=$1; ($before,$block,$after)=&get_simple_argument("$'$comment"); if ($block) { $done.=$before; $arg.=$block; return ($found,$done,$arg,$after); } else { die "\nCorrupted \\begin statement: \"$arg$before$block$after\"\n" }; }; # \begin{...} and \end{...} already excluded s/^\s*$ord_command_re//o && do { $command=$1; $after=$'; # swallow \verb?...? if ("$command$after$comment" =~ /^(\\verb[*]?)(.)/) { # it's a \verb command: read \verb block and continue $command=$&; ($block,$after)=&process_verb ($2,$'); $done.="$command$block"; $_=$after; last CASE; } else { $found=3; return ($found,$done,$command,"$after$comment"); }; }; s/^\s*$command_re//o && do { $found=4; return ($found,$done,$1,"$'$comment"); }; # Normal text return (5,$done,"","$_$comment"); }; }; }; sub find_end_of_opt { local ($_)=@_; chomp; if (!(s/^\s*\[// )) { return ('',"$&$_\n") }; my ($before)=$&; my ($text)=""; my ($found)=0; my ($comment)=""; while (!$found) { if (s/(^|[^\\])(\\\\)*(%.*)//) { $_.="$1$2"; $comment=$3 }; if (s/(^|.*?[^\\])(\\\\)*([\[\]])//) { $text=$&; if ($3 =~ /\]/) { $before.=$text; $found=1; } else { $before.=$text; $before =~ s/[\[\]]$//; my ($block,$afterblock)=&find_end_of_opt("\{$_$comment\n"); $comment=""; print STDERR "subblock:\n$block\n"; $before .= $block; $_=$afterblock; next } } else { $before.="$_$comment\n"; $comment=""; if (eof) { die "\nmakesegment: Reached eof before end of optional !\n" }; $_=<$input>; chomp; }; }; ($before,$_.$comment) } sub process_verb { local ($_)=@_; my ($mark)=substr($_,0,1); my ($verbtext,$rest)=($mark,""); if ($mark =~ /[\\\]\[\{\}\^\|\(\)]/) { $mark="\\$mark"; }; # print STDERR "mark: $mark\n"; $_ =~ s/^[$mark]//; if (!$mark) { die "\nmakesegments: No valid \\verb delimiter found!\n" }; my ($found)=0; unless (s/^[^$mark]*[$mark]//) { s/^[^$mark]*$//; print STDERR "\\verb ended by end of line: $verbtext$&\n"; }; $verbtext.=$&; $rest=$'; # while (!$found) { # if (/[$mark]/) { # $found=1; # $verbtext.=$`$&; # $rest=$'; # } # else { # $verbtext.="$_\n"; # $_=&get_next_line; # } # }; ($verbtext,$rest); } sub process_verbatim { local ($star,$_)=@_; my ($verbtext,$rest)=("",""); my ($found)=0; my ($num)=0; if ($star) { $star="[$star]" }; while (!$found) { if (/\\end\s*\{\s*verbatim$star\s*\}/) { $found=1; $verbtext.="$`$&"; $rest="$'"; } else { $verbtext.="$_\n"; $_=&get_next_line; } }; ($verbtext,$rest); } sub push_output { my ($name)=@_; push @outhandle,(select); # print STDERR "outhandle: ".join(',',@outhandle)."\n"; $output++; unless (open ($output,">$name")) { die "Can't open file $name for output:\n$!\n" }; # print STDERR "opening $name, Handle=$output\n"; select $output; $output; }; sub push_input { my ($name)=@_; $input++; unless (open ($input,"<$name")) { die "Can't open file $name for input:\n$!\n" }; print STDERR "processing file $name ...\n"; unshift @inhandle,($input); $input; }; sub pop_input { my ($current)= shift @inhandle; $input=$inhandle[0]; close $current; $input; }; sub pop_output { my ($new)=pop @outhandle; # print STDERR "outhandle: ".join(',',@outhandle)."\n"; my ($current)=select; # print STDERR "Closed $current, selected $new\n"; close $current; select $new; }; sub make_known_cmds { my $key; %known_commands= ( %segments, %nosegment_cmds, %label_cmds, %ref_cmds, %index_cmds, %misc_cmds); # print STDERR "Known commands:\n"; # foreach $key (keys %known_commands) { # print "$key => ",join(',',@{$known_commands{$key}})."\n"; # }; # print STDERR join(", ",(keys %known_commands))."\n"; }; sub dependencies { foreach $key (keys %segment_names) { if (defined @{$key."_labels"}) { map { $labelsegs{$_} = $key } @{$key."_labels"}; }; }; foreach $key (keys %segment_names) { $internal{$key}="\\internal\{\}\n" ; if (defined @{$key."_refs"}) { map { $internal{$key}.="\\internal\{$labelsegs{$_}\}\n" unless ($labelsegs{$_} =~/$key|$SEGSTART/) } @{$key."_refs"}; }; foreach $k (@specialsegments) { $internal{$key}.="\\internal\{$k\}\n" ; }; }; $internal{$outname}=""; delete $segment_names{$SEGSTART}; foreach $k (@specialsegments) { $internal{$k}="\\internal\{\}\n"; foreach $key ((keys %segment_names),@specialsegments) { $internal{$k}.="\\internal\{$key\}\n"; }; }; foreach $key ((keys %segment_names),@specialsegments) { $internal{$outname}.="\\internal\{$key\}\n"; }; if (defined $special_sections{"printindex"}) { if ($SPECIALS && (defined $SPECIALNAMES{"printindex"})) { foreach $key ("",keys %segment_names) { $internal{$SPECIALNAMES{"printindex"}}.= "\\internal\[index\]\{$key\}\n"; }; if (defined $special_sections{"bibliography"}&& (defined $SPECIALNAMES{"bibliography"})) { foreach $key ("",keys %segment_names) { $internal{$SPECIALNAMES{"bibliography"}}.= "\\internal\[index\]\{$key\}\n"; }; }; if (defined $special_sections{"thebibliography"} && (defined $SPECIALNAMES{"thebibliography"})) { foreach $key ("",keys %segment_names) { $internal{$SPECIALNAMES{"thebibliography"}}.= "\\internal\[index\]\{$key\}\n"; }; }; } else { foreach $key (keys %segment_names) { $internal{$outname}.="\\internal\[index\]\{$key\}\n"; }; }; }; if (defined $special_sections{"tableofcontents"}) { if ($SPECIALS&& (defined $SPECIALNAMES{"tableofcontents"})) { foreach $key ("",(keys %segment_names), @specialsegments) { $internal{$SPECIALNAMES{"tableofcontents"}}.= "\\internal\[contents\]\{$key\}\n". "\\internal\[sections\]\{$key\}\n" ; }; } else { foreach $key (keys %segment_names) { $internal{$outname}.="\\internal\[contents\]\{$key\}\n". "\\internal\[sections\]\{$key\}\n"; }; }; }; if (defined $special_sections{"listoffigures"}) { if ($SPECIALS && (defined $SPECIALNAMES{"listoffigures"})) { foreach $key ("",keys %segment_names) { $internal{$SPECIALNAMES{"listoffigures"}}.= "\\internal\[figure\]\{$key\}\n"; }; } else { foreach $key (keys %segment_names) { $internal{$outname}.="\\internal\[figure\]\{$key\}\n"; }; }; }; if (defined $special_sections{"listoftables"}) { if ($SPECIALS && (defined $SPECIALNAMES{"listoffigures"})) { foreach $key ("",keys %segment_names) { $internal{$SPECIALNAMES{"listoftables"}}.= "\\internal\[table\]\{$key\}\n"; }; } else { foreach $key (keys %segment_names) { $internal{$outname}.="\\internal\[table\]\{$key\}\n"; }; }; }; }; sub write_segments { my $seghead; ($seghead=$head) =~ s/$begin_htmlonly_mark//g; $seghead =~ s/$end_htmlonly_mark//g; $head =~ s/$begin_htmlonly_mark/\\begin{htmlonly}/g; $head =~ s/$end_htmlonly_mark/\\end{htmlonly}/g; foreach $key (keys %segment_names) { unless (open (TMPFILE,"$DIR/$key.tmp")) { die "can't open $DIR/$key.tmp for input!\n" }; unless (open (CREATE,">$DIR/$key".".tex")) { die "can't open $DIR/$key.tex for output!\n" }; print CREATE join("\n", "\\begin\{htmlonly\}", $seghead, "\\input\{".$key.".ptr\}", "\\end\{htmlonly\}", $internal{$key}, "\\startdocument"); while () { print CREATE $_; }; close TMPFILE; close CREATE; }; foreach $name (@specialsegments) { # print "Making $DIR/$name.tex , $internal{$name}\n"; unless (open (TMPFILE,"$DIR/$name.tmp")) { die "can't open $DIR/$name.tmp for input!\n" }; unless (open (CREATE,">$DIR/$name.tex")) { die "can't open $DIR/$name.tex for output!\n" }; print CREATE join("\n", "\\begin\{htmlonly\}", $seghead, # "\\input\{".$name.".ptr\}", "\\end\{htmlonly\}", $internal{$name}, "\\startdocument"); while () { print CREATE $_; }; close TMPFILE; close CREATE; } unless (open (TMPFILE,"$DIR/$outname.tmp")) { die "can't open $DIR/$outname.tmp for input!\n" }; unless (open (CREATE,">$DIR/$OUTFILE")) { die "can't open $DIR/$OUTFILE for output!\n" }; print CREATE join("\n", $head, $internal{$outname}); while () { print CREATE $_; }; close TMPFILE; close CREATE; if (!$DONTCOPY) { foreach $file (@bibfiles) { if ($USELINKS) { if ($file && (-f $file)) { `rm -f $DIR/$file; ln -s $PWD$file $DIR/$file`; print STDERR "Linking $file to $DIR/$file\n"} ; $file=""; } else { if ($file && (-f $file)) { `cp $file $DIR`; print STDERR "Copying $file to $DIR\n"} else { $file="" }; }; }; foreach $file (@files_to_copy) { if ($USELINKS) { if ($file && (-f $file)) { `rm -f $DIR/$file; ln -s $PWD$file $DIR/$file`; print STDERR "Linking $file to $DIR/$file\n"} ; } else { if ($file && (-f $file)) { `cp $file $DIR`; print STDERR "Copying $file to $DIR\n"; }; }; }; }; unless ((unlink map { "$DIR/$_.tmp" } ($outname,(keys %segment_names),(@specialsegments))) and (!@temporary_files or unlink @temporary_files)) { print "\nmakesegments: Warning: couldn't delete temporary files!\n" }; }; sub make_makefile { # Check segment hierarchy $indexspecial=($SPECIALS && (defined $special_sections{"printindex"}) && (defined $SPECIALNAMES{"printindex"})); $contentspecial=($SPECIALS && (defined $special_sections{"tableofcontents"}) && (defined $SPECIALNAMES{"tableofcontents"})); foreach $key (sort (keys %levels)) { @{$key."_segs"}=grep { $segment_names{$_} =~ /^$key$/ } (keys %segment_names); }; foreach $key (keys %segment_names) { $k=$key; @higher= grep { ($levels{$segment_names{$_}} < $levels{$segment_names{$key}} ) && ($_ lt $key) } (keys %segment_names); $up=($#higher > -1 ? $higher[$#higher]: $outname); @higher= grep { ($levels{$segment_names{$_}} <= $levels{$segment_names{$key}} ) && ($_ lt $key) } (keys %segment_names); $prev=($#higher > -1 ? $higher[$#higher]: $up); @next= grep { ($levels{$segment_names{$_}} <= $levels{$segment_names{$key}} ) && ($_ gt $key) } (keys %segment_names); if ($#next > -1) { $down= $next[0] } elsif (defined $segment_names{++$k}) { $down=$k } elsif (defined @specialsegments) { $down=$specialsegments[0]; $lastsegment=$key; } else { $down=$outname ; $lastsegment=$key}; ($kupc=$key) =~ tr/a-z/A-Z/; ($uupc=$up)=~ tr/a-z/A-Z/; ($dupc=$down)=~ tr/a-z/A-Z/; ($pupc=$prev)=~ tr /a-z/A-Z/; $make{$key}=join("\\\n\t\t", "\$(L2H)", "\$(MAKE_COMMON) \$(CONTENTS) \$(INDEX)", "\$(MAKE_CHILDREN)", "-prefix $key -t \$($kupc"."TITLE)", "-up_url $up.html -up_title \$($uupc"."TITLE)", "-prev_url $prev.html -prev_title \$($pupc"."TITLE)", "-down_url $down.html -down_title \$($dupc"."TITLE)", "$key.tex"); }; for ($i=0;$i <= $#specialsegments;$i++) { $key=$specialsegments[$i]; $up=$outname; if ($i==0) { $prev=$lastsegment } else { $prev=$specialsegments[i-1] }; if ($i==$#specialsegments) { $down=$specialsegments[0] } else { $down=$specialsegments[$i+1] }; ($kupc=$key) =~ tr/a-z/A-Z/; ($uupc=$up)=~ tr/a-z/A-Z/; ($dupc=$down)=~ tr/a-z/A-Z/; ($pupc=$prev)=~ tr/a-z/A-Z/; $make{$key}=join("\\\n\t\t", "\$(L2H)", "\$(MAKE_COMMON) \$(CONTENTS) \$(INDEX)", "\$(MAKE_CHILDREN)", "-prefix $key -split 0 -link 0", "-t \$($kupc"."TITLE)", "-up_url $up.html -up_title \$($uupc"."TITLE)", "-prev_url $prev.html -prev_title \$($pupc"."TITLE)", "-down_url $down.html -down_title \$($dupc"."TITLE)", "$key.tex"); }; ($down=$SEGSTART)++; ($dupc=$down)=~ tr/a-z/A-Z/; ($kout=$outname) =~ tr/a-z/A-Z/; ($pupc=$lastsegment) =~ tr/a-z/A-Z/; $make{$outname}=join("\\\n\t\t", "\$(L2H)", "\$(MAKE_COMMON) \$(CONTENTS) \$(INDEX)", "\$(MAKE_TOP) -t \$($kout"."TITLE)", "-prev_url $lastsegment.html -prev_title \$($pupc"."TITLE)", "-down_url $down.html -down_title \$($dupc"."TITLE)", "$outname.tex"); print STDERR "Generating Makefile (edit for your own needs afterwards ...)\n"; unless (open (MAKE,">$DIR/Makefile")) { die "Can't create Makefile in $DIR!\n$!\n" }; print MAKE join("\n", "#", "# Makefile for segmented L2H document $OUTFILE", "# Generated by makesegments", "#", "# COMMANDS:", "#", "LATEX\t\t= $LATEX", "DVIPS\t\t= $DVIPS", "BIBTEX\t\t= $BIBTEX", "MAKEINDEX\t\t= $MAKEINDEX", "L2H\t\t= $L2H", "MAKE\t\t= $MAKE", "TOUCH\t\t= $TOUCH", "#", "# HTML TITLES: ", "#", "# Edit the XYTITLE variables to change HTML titles", "#", ""); print MAKE "$kout"."TITLE\t\t= \"".($maintitle ? $maintitle : "Main document")."\"\n"; foreach $key (keys %segment_names) { ($kupc=$key) =~ tr/a-z/A-Z/; print MAKE "$kupc"."TITLE\t\t= \"$segment_titles{$key}\"\n"; }; foreach $key (keys %special_sections) { ($kupc=$SPECIALNAMES{$key}) =~ tr/a-z/A-Z/; print MAKE "$kupc"."TITLE\t\t= \"$SPECIALTITLES{$key}\"\n" if $kupc; }; print MAKE join("\n", "#", "# FURTHER DEFINITIONS:", "#", "TEXFILES\t\t= ".join(' ',(map {$_.".tex"} (keys %segment_names, @specialsegments))), "SEGMENTS\t\t= ".join(' ',(map {"$outname/$_".".html"} (keys %segment_names, @specialsegments))), "INT\t\t= internals.pl\n", ""); print MAKE join("\n", "#", "# Latex2HTML command lines for each segment:", "#", "# Set INDEX to \"-index XXXX.html\" and ", "# CONTENTS to \"-contents YYYY.html\" for", "# correct links to contents and index page - ", "# Or set \$SPECIALS=1 in your Makesegments config file", "#", "MAKE_COMMON\t\t= -dir $outname $MAKE_COMMON", "MAKE_TOP\t\t= $MAKE_TOP", "MAKE_CHILDREN\t\t= -external_file $outname $MAKE_CHILDREN", "CONTENTS\t\t=". ($contentspecial ? " -contents ". $SPECIALNAMES{"tableofcontents"}.".html":""), "INDEX\t\t=". ($indexspecial ? " -index ".$SPECIALNAMES{"printindex"}.".html":""), "", "L2H$kout\t\t=$make{$outname}", ""); foreach $key (keys %segment_names) { ($kupc=$key) =~ tr/a-z/A-Z/; print MAKE "L2H$kupc\t\t= $make{$key}\n"; }; foreach $key (@specialsegments) { ($kupc=$key) =~ tr/a-z/A-Z/; print MAKE "L2H$kupc\t\t= $make{$key}\n"; }; print MAKE join ("\n", "html:\t$outname/$outname.html \$(SEGMENTS)", "", "all:\t$outname.ps html", "", "$outname.ps:\t$outname.dvi", "\t\$(DVIPS) -o \$\@ $outname", "", "$outname.dvi:\t$outname.aux", "\t\$(LATEX) $outname", "", "$outname.aux:\t$outname.stamp ". (defined $special_sections{"bibliography"} ? "$outname.bbl " : ""). (defined $special_sections{"printindex"} ? "$outname.ind " : ""), "\t\$(LATEX) $outname", "", "$outname.stamp:\t$outname.tex \$(TEXFILES)", "\t\$(LATEX) $outname", "\t\$(TOUCH) \$\@", "", (defined $special_sections{"bibliography"} ? "$outname.bbl:\t$outname.stamp ". join(' ', (map { (m:.*/: ? $& : $_) } @bibfiles)). "\n\t\$(BIBTEX) $outname\n" : ""), "", (defined $special_sections{"printindex"} ? "$outname.ind:\t$outname.stamp $outname.idx". "\n\t\$(MAKEINDEX) $outname.idx\n\n". "$outname.idx:\t$outname.stamp" : ""), "", "$outname/$outname.html:\t". join(" ", (map { ($internal{$outname} =~ /\{$_\}/ ? "$outname/$_".".stamp" : "") } ((keys %segment_names),@specialsegments))), "\t\$(L2H$kout)", "", "$outname/$outname.stamp:\t$outname.aux", "\t\$(L2H$kout)", "\t\$(TOUCH) \$\@", "",""); foreach $key (@specialsegments) { ($kupc=$key) =~ tr/a-z/A-Z/; print MAKE join ("\n", "$outname/$key.html:\t". join(" ", (map { ($internal{$key} =~ /\{$_\}/ ? "$outname/$_".".stamp" : "") } ((keys %segment_names),@specialsegments))), "\t\$(L2H$kupc)", "", "$outname/$key.stamp:\t$outname.aux", "\t\$(L2H$kupc)", "\t\$(TOUCH) \$\@", "",""); }; foreach $key (keys %segment_names) { ($kupc=$key) =~ tr/a-z/A-Z/; print MAKE join ("\n", "$outname/$key.html:\t". join(" ", (map { ($internal{$key} =~ /\{$_\}/ ? "$outname/$_".".stamp" : "") } ((keys %segment_names),@specialsegments))), "\t\$(L2H$kupc)", "", "$outname/$key.stamp:\t$outname.aux", "\t\$(L2H$kupc)", "\t\$(TOUCH) \$\@", "",""); }; print MAKE join ("\n", "clean:\t", "\trm -rf $outname \\", "\t". join(' ', map { $outname.$_ } (".ps",".dvi",".aux",".toc",".lof",".lot",".bbl",".idx",".ind",".stamp") )." \\", "\t".join(' ', map { $_.".ptr" } (keys %segment_names))."\\", "\t".join(' ', map { $_.".stamp" } (keys %segment_names)), ""); close MAKE; }; sub find_texinput { # parameters: filename, array reference for input dirs, # array reference for possible extensions my ($file,$inputs,$extensions) = @_; # print STDERR "Looking for $file in ". # join (" and ",@$inputs).", extensions: ".join (" and ",@$extensions)."\n"; my $basedir,$dir,$found,$dirtext,$match,$ex; $ext=""; $found=""; ($file =~ s/([.]\w+)$//) && do { $ext=$1 }; # Absolute pathname ? my $abs= ($file =~ m:^/|^~:); # filename is absolute if ($abs) { if ($ext) { (-f "$file$ext") && ($found="$file$ext") ; } else { foreach $ex (@$extensions) { $found || ((-f "$file$ex") && ($found="$file$ex")); }; }; } else { foreach $basedir (@$inputs) { $found =&search_tree ($basedir,$file,($ext ? $ext : @$extensions)); last if $found; }; }; !$found && print STDERR "WARNING: Input file $file not found!\n"; $ext && ($ext =~ /^.sty$|^.clo$|^.cls/) && do { print STDERR "WARNING: Attempt to input style file $file$ext with \\input or \\include!\n"; $found=""; }; return $found; }; sub find_texstyle { my ($file) = @_; my $basedir,$dir,$found,$dirtext; $ext=""; $found=""; ($file =~ s/([.]\w+)$//) && do { $ext=$1 }; # Absolute pathname ? my $abs= ($file =~ m:^/|^~:); # filename is absolute if ($abs) { ((-f $file) && ($found=$file)) || ((-f "$file.tex") && ($found="$file.tex")); } else { # strip directories $file =~ s:.*/::; (print STDERR "WARNING: Invalid input/inlude filename: $&\n", return "") unless $file; foreach $basedir (@texinputs) { $found =&search_tree ($basedir,$file,($ext ? $ext : ("",".tex"))); last if $found; }; }; !$found && print STDERR "WARNING: Input file $file not found!\n"; return $found; }; sub search_tree { local($_,$file,@exts)=@_; my ($found,$dir); my @subdirs,$filelist; my @files; # print STDERR "Looking for $file in $_, extensions: ".join(", ",@exts)." ...\n"; if (m://:) { # dirname contains double slash my $base=$`; my $sub=$'; if ($sub && $sub =~ s:/.*::) { my $rest=$&; @subdirs=split("\n", `find $base -follow -name $sub -type d -print`); foreach $dir (@subdirs) { if ($found=&search_tree("$dir$rest",$file,@exts)) { return $found }; }; } else { $filelist=join(" -o ",map { "-name $file$_" } @exts); @files=split("\n", `find $base -follow -type f \\( $filelist \\) -print`); if ($#files > 0) { print STDERR "WARNING: multiple files matching $file found in $base!\n"; return $files[0]; } elsif ($#files == 0) { return $files[0] }; }; } else { my $base=$_; $base.="/" unless ($base=~m:/$:); @files=grep { -f "$base$file$_" } @exts; if ($#files > 0) { print STDERR "WARNING: multiple files matching $file found in $base!\n"; return "$file$files[0]"; } elsif ($#files == 0) { return "$file$files[0]" }; }; return ""; }; sub init { local @_=@ARGV; # openers for *o*ptional and *m*andatory arguments ($o,$m)=("\\[","\\{"); $usage_string=join("\n", "Makesegments - create segmented documents for LaTeX2HTML.","", "Usage:", " makesegments [options] LaTeX-file\[.tex\]","", "Options:", " -level level: specify level of sectioning commands down to which", " segmentation is carried out (default section)", " (short: -l level)", " -dir dir: specify target directory (default ./segmented)", " (short: -d dir)", " -output outputfile: specify the name of the master file for output", " (short: -o outputfile)", " -config config-file: specify name of makesegments\'s configuration file", " (default ./.makesegments.cnf, \$HOME/.makesegments.cnf)", " (short: -c config-file)", " -zero string: basename of zeroeth segment (default a0)", " if you specify \"-zero SEG000\", segment names will be", " \"SEG001.tex\", \"SEG002.tex\",...", " (short: -z string)", " -no_makefile: Don\'t generate the Makefile (short: -n)", " -check_latex_styles: Check if requested LaTeX packages are accessible", " (requires proper setting of TEXINPUTS)", " (short: -s)", " -ignore_inputs: Don\'t replace \\input and \\include statements by the", " contents of input files (short: -i)", " -use_links: Use soft links for input files in the target directory", " instead of copying them (short: -u)", " -dont_copy: Don\'t copy or link input files from current in the target", " directory (short: -y)", " -specialsegments: Create special \"segments\" for Table of contents,", " index, bibliography etc. (short: -e)", " -help: Print this message (short: -h or -?)","", "See the documentation in makesegments.tex for further details."); # Parse options while ($_=shift) { OPTIONS: { /^-l$|^-level$/ && do { $O_LEVEL=shift; last OPTIONS }; /^-d$|^-dir$/ && do { $O_DIR=shift; last OPTIONS }; /^-o$|^-output$/ && do { $O_OUTFILE=shift; last OPTIONS }; /^-c$|^-config$/ && do { $CNF_FILE=shift; last OPTIONS }; /^-z$|^-zero$/ && do { $O_SEGSTART=shift; last OPTIONS }; /^-h$|^-?$|^-help$/ && do { print STDERR $usage_string; exit 0 }; /^-s$|^-check_latex_styles$/ && do { $O_CHECK_LATEX_STYLES=1; last OPTIONS }; /^-n$|^-no_makefile$/ && do { $O_NOMAKE=1; last OPTIONS }; /^-i$|^-ignore_inputs$/ && do { $O_IGNOREINPUTS=1; last OPTIONS }; /^-e$|^-specialsegments$/ && do { $O_SPECIALS=1; last OPTIONS }; /^-u$|^-use_links$/ && do { $O_USELINKS=1; last OPTIONS }; /^-y$|^-dont_copy$/&& do { $O_DONTCOPY=1; last OPTIONS }; /^-/ && die "$usage_string\nmakesegments: unknown option $_!\n"; $FILE=$_; }; }; # $CNF_FILE overrides ./.makesegments.cnf which overrides $HOME/.makesegments.cnf if (-f ($cnf=$ENV{'HOME'}."/.makesegments.cnf")) { unless (require $cnf) { print "WARNING: couldn't execute $cnf!\n" }; }; if (-f ($cnf="./.makesegments.cnf")) { unless (require $cnf) { print "WARNING: couldn't execute $cnf!\n" }; }; if (defined $CNF_FILE) { unless (require $CNF_FILE) { die "makesegments:\nCan't open configuration file $CNF_FILE!\n" }; }; };