
Typesetting perl programs in TeX
|>
|> Does anyone know of a program that will ``convert'' perl scripts to
|> something printable by TeX?
I don't know if this is exactly what was wanted, but someone may find
it useful:
8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---
#!/usr/local/bin/perl
#
# $Id: sh2latex,v 1.3 1994/03/08 18:13:55 bill Exp $
#\documentstyle{article}
#
#\hyphenation{next-state next-states}
#\title{{\tt sh2latex}\\a Script to \LaTeX\ Converter}
#\date{3rd March 1994}
#
#\begin{document}
#
#\maketitle
#
#\section*{Introduction}
#
#This script generates \LaTeX\ documents from script files whose comment
#delimeters run from \verb|#| to \verb|\n|, such as {\tt perl}, {\tt make},
#{\tt rdist} or {\tt sh}.
#
# If you are reading this as a well-formatted hardcopy document then it was
#created by issuing the following command:
#\begin{center}
#\begin{verbatim}
#sh2latex sh2latex > sh2latex.tex
#\end{verbatim}
#\end{center}
#\noindent
#then running \LaTeX\ on the {\tt .tex} file and printing the
#resulting {\tt .dvi} file in the normal way.
#
#The main feature of {\tt sh2latex} is that introductory material
#(such as this) is
#allowed to ``float'' to the top of the resulting \LaTeX\ document, and
#therefore can appear to preceed the obligatory \verb|#!/|{\it interpreter}
#line which must be the first text in an executable
#script.
#
#The idea is to read the file, writing to two temp files ({\small TOP}
#and {\small BODY}), then cat the
#results together afterwards. We look for lines that match
#
#switch introduce \LaTeX\ text which is simply output in-place.
#In both cases the leading \verb|#| is stripped out; and the
#section is terminated by a blank line, a non-comment line
#
#needed this feature when using {\tt sh2latex} to document a fairly
#large system, where inevitably the rules for building the documentation
#ended up in the {\tt Makefile}, which I wanted to document, but I
#didn't want the instructions for building the documentation to end up
#in the documentation).
#
#We implement this as a state table with pairs of actions (in italics)
#and nextstates (in roman) as follows (read ``perform actions then change to
#nextstate''):
#
#%LaTeX tables are a bit messy, but the results look good
#
#\begin{center}
#\begin{tabular}{|r||c|c|c|c|c|c|c|}
#\hline
# &\multicolumn{7}{|c|}{STATES}\\ \hline\hline
#INPUTS & S & top & tex & verb & topverb & ig & igverb \\ \hline
#\hline
# & top & top & top & topverb& topverb& ig & igverb \\ \hline
# & ig & ig & ig & igverb & igverb& ig & igverb \\ \hline
# & S & top & verb & verb & verb & tex & verb \\ \hline
# & - & - & - \\
# & tex & tex & tex & tex & tex & ig & igverb \\ \hline
#\verb|#| & \it bv, pB
# & \it sh, pT
# & \it sh, pB
# & \it pB
# & \it sh, pT
# & - & - \\
# & verb & top & tex & verb & topverb &ig & igverb \\ \hline
#\verb|blank| & - & \it pT, bv
# & \it pB, bv
# & \it pB
# & \it pT & - & - \\
# & S & verb & verb & verb & verb & ig & igverb \\ \hline
#\verb|other| & \it bv, pB
# & \it bv, pB
# & \it bv, pB
# & \it pB
# & \it pB & - & - \\
# & verb & verb & verb & verb & verb & ig & igverb \\ \hline
#\verb|EOF| & - & - & - & \it ev
# & \it ev & - & \it ev \\
# & end & end & end & end & end & end & end \\ \hline
#\end{tabular}
#\end{center}
#\noindent
# Where the actions (order is significant) are:
#\begin{center}
#\begin{tabular}{|c|l|}
#\hline
#- & no action \\ \hline
#\it bv & output a \verb|\begin{verbatim}| to the {\small BODY} \\ \hline
#\it ev & output an \verb|\end{verbatim}| to the {\small BODY} \\ \hline
#\it sh & strip leading hashes from the line \\ \hline
#\it pB & print the line to the {\small BODY} \\ \hline
#\it pT & print the line to the {\small TOP} \\ \hline
#\end{tabular}
#\end{center}
#\noindent
#and the states are:
#\begin{center}
#\begin{tabular}{|c|l|}
#\hline
# S & start state \\ \hline
# top & writing to {\small TOP} without a verbatim in effect in
# {\small BODY} \\ \hline
# tex & writing \LaTeX\ to {\small BODY} \\ \hline
# verb & writing verbatim text to {\small BODY} \\ \hline
# topverb & writing to top while a verbatim is in effect in
# {\small BODY} \\ \hline
# ig & ignoring text without a verbatim in effect \\ \hline
# igverb & ignoring text while a verbatim is in effect in
# {\small BODY} \\ \hline
#\end{tabular}
#\end{center}
#
#\section{Listing}
$0 =~ s#.*/##;
$usage = "use: $0 <file>\n";
$file = shift || die $usage;
$topfile = "/tmp/top$$";
$bodyfile = "/tmp/bod$$";
# open the input and two temp files
open(IN, $file) || die "$file: $!";
open(TOP, ">$topfile") || die "$topfile: $!";
open(BODY, ">$bodyfile") || die "$bodyfile: $!";
# read from the input file:
$state = 'S'; # start state
if ($state eq 'S') {
&change('top');
} elsif ($state eq 'tex') {
&change('top');
} elsif ($state eq 'verb') {
&change('topverb');
if ($state eq 'S') {
&change('ig');
} elsif ($state eq 'top') {
&change('ig');
} elsif ($state eq 'tex') {
&change('ig');
} elsif ($state eq 'verb') {
&change('igverb');
} elsif ($state eq 'topverb') {
&change('igverb');
if ($state eq 'tex') {
&change('verb');
} elsif ($state eq 'topverb') {
&change('verb');
} elsif ($state eq 'ig') {
&change('tex');
} elsif ($state eq 'igverb') {
&change('verb');
if ($state eq 'S') {
&change('tex');
} elsif ($state eq 'top') {
&change('tex');
} elsif ($state eq 'verb') {
&endverb;
&change('tex');
} elsif ($state eq 'topverb') {
&change('tex');
# then comment lines:
} elsif (/^\s*#/) {
if ($state eq 'S') {
s/^(\t*)/' ' x 8 x length($1)/e;
&beginverb;
print BODY $_;
&change('verb');
} elsif ($state eq 'top') {
s/^\s*#//;
print TOP $_;
} elsif ($state eq 'tex') {
s/^\s*#//;
print BODY $_;
} elsif ($state eq 'verb') {
s/^(\t*)/' ' x 8 x length($1)/e;
print BODY $_;
} elsif ($state eq 'topverb') {
s/^\s*#//;
print TOP $_;
#blank lines:
} elsif (/^\s*$/) {
if ($state eq 'top') {
print TOP $_;
&beginverb;
&change('verb');
} elsif ($state eq 'tex') {
print BODY $_;
&beginverb;
&change('verb');
} elsif ($state eq 'verb') {
print BODY $_;
} elsif ($state eq 'topverb') {
print TOP $_;
&change('verb');
}
# significant non-comment lines:
} else {
if ($state eq 'S') {
&beginverb;
s/^(\t*)/' ' x 8 x length($1)/e;
print BODY $_;
&change('verb');
} elsif ($state eq 'top') {
&beginverb;
s/^(\t*)/' ' x 8 x length($1)/e;
print BODY $_;
&change('verb');
} elsif ($state eq 'tex') {
&beginverb;
s/^(\t*)/' ' x 8 x length($1)/e;
print BODY $_;
&change('verb');
} elsif ($state eq 'verb') {
s/^(\t*)/' ' x 8 x length($1)/e;
print BODY $_;
} elsif ($state eq 'topverb') {
s/^(\t*)/' ' x 8 x length($1)/e;
print BODY $_;
&change('verb');
}
}
Quote:
}
#Now at {\tt EOF}. If the last thing we output to the body was
#verbatim, then we need to end it.
if ($state eq 'verb' || $state eq 'topverb' || $state eq 'igverb') {
&endverb;
Quote:
}
# Now all we do is to close the two output files, open them for
# reading, and cat them together ({\small TOP} first) to {\tt STDOUT}.
#Then we delete them.
close(TOP);
close(BODY);
open(TOP, $topfile) || die "$topfile: $!";
while (<TOP>) {
print;
Quote:
}
close(TOP);
open(BODY, "$bodyfile") || die "$bodyfile: $!";
while(<BODY>) {
print;
Quote:
}
close(BODY);
unlink($topfile, $bodyfile);
# Some subroutines. {\tt beginverb} and {\tt endverb} output the
# \LaTeX\ commands to change to and from {\tt verbatim} mode, while
# {\tt change} is used, rather than just doing assignment,
# purely to allow debugging.
sub beginverb {
print BODY "\\bigskip\n";
print BODY "\\hrule\n";
print BODY "\\small\n";
print BODY "\\begin{verbatim}\n";
Quote:
}
sub endverb {
printf BODY "\\%s\n", "end{verbatim}";
print BODY "\\normalsize\n";
print BODY "\\hrule\n";
print BODY "\\bigskip\n";
Quote:
}
sub change {
warn "changing from $state to $newstate:\n$_\n" if $debug;
$state =
...
read more »