#!/bin/sh exec perl -w -x $0 ${1+"$@"} #!perl # # Document options: -dir=Document_doc -shell -generic # # Note: If you are reading this file, you can generate the documentation # in LaTeX, PostScript, and HTML by running the Document perl script using # this file as input: # # % Document -self Document # # and then printing out the PostScript file: # # % lpr Document_doc/Document.ps # # or loading the HTML into a browser with the URL: # # file://localhost//Document_doc/index.html # # You can get the Document perl script at # # http://www.lanl.gov/Document/ # # You can get the hallstone.jpg file at # # http://MikeHall.org/images/backgrounds/hallstone.jpg # # ------------------------------------------------------------------------ # # Begin_Doc Document.tex # \documentclass{article} # \usepackage{html} # \usepackage{htmllist} # \usepackage{makeidx} # \usepackage{alltt} # # % Set colors/background for all pages. If you don't have the # % hallstone.jpg file, you can get it from # % http://MikeHall.org/images/backgrounds/hallstone.jpg # # \bodytext{background="hallstone.jpg" # text="000000" link="000066" vlink="006600" alink="990000"} # # % # % Set up standard margins and paragraph settings. # % # \setlength{\textwidth}{6.56in} # \setlength{\textheight}{9in} # \setlength{\evensidemargin}{0in} # \setlength{\oddsidemargin}{0in} # \setlength{\topmargin}{0in} # \setlength{\headheight}{0in} # \setlength{\parindent}{0pt} # \setlength{\parskip}{\baselineskip} # \makeindex # # \begin{document} # \input{doctitle} # \pagebreak # \renewcommand{\contentsname}{Table of Contents} # \tableofcontents # \pagebreak # \input{docinfo} # \pagebreak # \input{docquick} # \pagebreak # \input{docusage} # \pagebreak # \input{doccomp} # \pagebreak # \input{doccode} # \addcontentsline{toc}{section}{\protect\numberline{}{Index}} # \printindex # \end{document} # End_Doc # # Begin_Doc doctitle.tex # %begin{latexonly} # \title{{\huge\bf The {\tt Document} Package} \\[.5\baselineskip] # {\large\em A Simplified Approach to Literate Programming}} # \author{\Large\bf Michael L. Hall} # \date{\bf\today} # %end{latexonly} # \begin{htmlonly} # \title{The {\tt Document} Package: \\ \\ # {\small\em A Simplified Approach to Literate Programming}} # \author{Michael L. Hall} # \date{\today} # \end{htmlonly} # # \maketitle # # \begin{abstract} # The {\tt Document} package is used to process documentation that is imbedded # in the comments of a source code file. Any source code language may be # used, if the proper values for comment characters have been set. Any # formatting language may be used as well. Currently, options for Fortran, # M4, C++ (or C), \LaTeX\/, Java, Prolog and shell scripts (perl, sh, # csh, awk, Tcl) as the source code language have been implemented. # # \html{\htmladdnormallink{Postcript}{Document.ps} and # \htmladdnormallink{DVI}{Document.dvi} versions of # the documentation are available, as well as the # \htmladdnormallink{perl source code}{Document}, and a # \htmladdnormallink{gzipped tar file}{Document.tar.gz} # of the entire HTML node (includes LaTeX, PS, DVI and perl source).} # # User's Note: the \texttt{-docstyle} keyword which enabled compatibility with # the doc routine has been de-selected. \texttt{Document} no longer includes # this capability. # \end{abstract} # # \htmlrule # \begin{latexonly} # \pagebreak \vspace*{2in} # \end{latexonly} # # \begin{htmllist} # \htmlitemmark{GreenBall} # \item[Laziness:] The quality that makes you go to great effort to reduce # overall energy expenditure. It makes you write # labor-saving programs that other people will find useful, # and document what you wrote so you don't have to answer # so many questions about it. Hence, the first great virtue # of a programmer. Also, hence this book [program -MLH]. # \item[Impatience:] The anger you feel when the computer is being lazy. This # makes you write programs that don't just react to your # needs, but actually anticipate them. Or at least that # pretend to. Hence, the second great virtue of a # programmer. # \item[Hubris:] Excessive pride, the sort of thing that Zeus zaps you for. # Also the quality that makes you write (and maintain) # programs that other people won't want to say bad things # about. Hence, the third great virtue of a programmer. # \end{htmllist} # # \hspace*{\fill} From the glossary of {\em Programming perl}, by Larry Wall # and Randall L. Schwartz. # End_Doc # # Begin_Doc docinfo.tex # \section{Author, Date and Version Information} # # \begin{tabular}{lp{6in}} # Filename: & Document \\ # Author: & Michael L. Hall \\ # & Los Alamos National Laboratory \\ # & P.O. Box 1663, MS-D409 \\ # & Los Alamos, NM 87545 \\ # & Email: \htmladdnormallink{\tt hall@lanl.gov} # {mailto:hall@lanl.gov}\\ # \\ # CVS Info: & \verb$Id: Document,v 12.9 2004/02/06 17:41:42 hall Exp $ \\ # \\ # Contributions: & While the entire code (including any bugs) is solely the # responsibility of the author, the following people # were involved in discussions that proved very helpful: # Mark Gray, Chuck Henkel and John Turner. \\ # \end{tabular} # End_Doc # # Begin_Doc docquick.tex # \section{Quick Reference} # \index{quick reference} # # \begin{center} # {\large {\tt\large Document} Keywords for {\large\tt -generic} Option} # \\[\baselineskip] \html{\\} # \begin{tabular}{lp{4in}} # Keyword & Meaning \\ \hline # {\tt Begin\_Doc [filename]} & Start Documentation Mode and output to # filename if specified. \\ # {\tt End\_Doc} & Stop Documentation Mode. \\ # {\tt Begin\_Verbatim} & Start Verbatim Mode (only during # Documentation Mode) to leave comment # characters as they appear in the input.\\ # {\tt End\_Verbatim} & Stop Verbatim Mode. \\ # {\tt Begin\_Self\_Documentation} & Start Self Documentation Mode, which lists # the commands necessary to produce the # documentation for this file. This may or # may not appear within the Documentation # Mode. \\ # {\tt End\_Self\_Documentation} & Stop Self Documentation Mode. \\ # {\tt Begin\_Self\_Test} & Start Self Test Mode, a synonym for the # Self Documentation Mode. \\ # {\tt End\_Self\_Test} & Stop Self Test Mode, a synonym for Self # Documentation Mode. \\ \hline # \end{tabular} # \end{center} # # {\tt Document} keywords must appear on a comment line by themselves to take # effect. Lines containing {\tt Document} keywords are never printed. # \vspace{\baselineskip} # # \hrule # # Common syntax for including source code (with \LaTeX\ and Fortran): # # % The \bv, \ev hack is to allow (\begin/\end){verbatim} in an alltt # % environment (this is necessary in *both* LaTeX and LaTeX2HTML). What a # % pain... # % # \newcommand{\bv}{\char 92 begin\char 123 verbatim\char 125 \html{\ }} # \newcommand{\ev}{\char 92 end\char 123 verbatim\char 125 \html{\ }} # % # \begin{alltt} # c Begin\_Doc # c \bv # c Begin\_Verbatim # c # c Source Code to be quoted verbatim. # c # do i = 1, 20 # i = i + 1 # end do # c End\_Verbatim # c \ev # c End\_Doc # \end{alltt} # # \hrule # # The perl source code for the {\tt Document} package contains examples of # most of the things that can be done with {\tt Document}, \LaTeX\ and # \LaTeX 2\texttt{HTML}, such as: # # \begin{itemize} # \item Self-Documentation scripts # \item Multiple output files and Document options # \item Included code # \item Indexing # \item Items included in only \LaTeX\ or HTML # \item Hyper references # \item HTML lists and Exterior HTML links # \item Verbatim environments from hell # \end{itemize} # # \hrule # # End_Doc # # Begin_Doc docusage.tex # \section{Usage} # # \subsection{Generating Documentation for {\tt Document}} # \index{self-documentation} # # To generate the documentation for this routine, you can use {\tt Document}'s # self-documentation option to run an internally-defined script: # # \begin{verbatim} # % Document -self Document # \end{verbatim} # # Or, to generate the documentation manually, run {\tt Document} on itself: # \footnote{To make the documentation look exactly like the official version, # you will need the official .latex2html-init file.} # # \begin{verbatim} # Begin_Self_Document # % Document Document # % cd Document_doc # % latex Document # % makeindex Document # % latex Document # % latex Document # End_Self_Document # \end{verbatim} # # To view the dvi file, continue with: # # \begin{verbatim} # % xdvi Document_doc/Document & # \end{verbatim} # # If PostScript output is desired, then continue with: # # \begin{verbatim} # Begin_Self_Document # % dvips Document # End_Self_Document # % lpr Document.ps # \end{verbatim} # # If HTML documentation is desired, then continue with: # # \begin{verbatim} # Begin_Self_Document # % cp Document.dvi .. # % latex2html -nomath -html_version 4.0,math -no_subdir -toc_stars Document # % mv ../Document.dvi . # % cp ../Document . # % cp ../hallstone.jpg . # % cp -r /usr/share/latex2html/icons . # % rm Document.tar.gz *.aux *.idx *.ilg *.ind *.log *.toc # % cd .. # % gtar cvzhf Document.tar.gz Document_doc # % mv Document.tar.gz Document_doc # End_Self_Document # \end{verbatim} # # and load the URL # ``{\tt file://localhost//Document\_doc/index.html}'' # into your favorite web browser. # # \subsection{Software Requirements} \index{requirements} # # To run {\tt Document}, you must have {\tt perl} installed. You may also # need a compiler if you want to process the source code, and a formatter if # you want to process the {\tt Document} output (documentation) file. # # To generate the documentation for {\tt Document} in PostScript, you will # need \LaTeXe, {\tt makeindex} and {\tt dvips}. To generate the documentation # in HTML you will need \LaTeXe, {\tt makeindex}, gnu tar, and # \LaTeX 2\texttt{HTML}, which requires {\tt ghostscript}, {\tt netpbm}, and # {\tt perl}, version 5. # # The HTML version will look better if \LaTeX 2\texttt{HTML} v.98.2beta8, # (or later) is used. # # \subsection{Running the Script} # # Once the source code with the documentation imbedded in the # comments has been produced, it can be processed by {\tt Document} # in any of the following ways: # # \begin{verbatim} # % Document [options and files] > outfile # % cat file1 [file2, etc.] | Document [options] > outfile # \end{verbatim} # # The options and files may be in any order on the command line. The # files are processed in the command line order. The available # options are: # # \begin{center} # Source Language and Formatting Language Options \\ \hspace*{1in} \\ # \begin{tabular}{llp{4.25in}} # \index{options}% # Option & Language & Meaning \\ \hline # {\tt -c++} & Source Code & Use comment characters and other commands # suitable for processing a C++ or C source # code file. # \index{c++@{\tt -c++} option} \\ # {\tt -generic} & Formatting & Use verbatim definitions and other commands # suitable for processing a file with # generically formatted comments. This is the # default (and recommended) setting. It is # required if comment characters are to be # stripped off of verbatim environments. # \index{generic@{\tt -generic} option} \\ # {\tt -fortran} & Source Code & Use comment characters and other commands # suitable for processing a Fortran source # code file. # \index{fortran@{\tt -fortran} option} \\ # {\tt -java} & Source Code & Use comment characters and other commands # suitable for processing a Java source # code file. # \index{java@{\tt -java} option} \\ # {\tt -latex} & Source Code & Use comment characters and other commands # suitable for processing a \LaTeX\ # \textit{source code} file. # \index{latex@{\tt -latex} option} \\ # {\tt -m4} & Source Code & Use comment characters and other commands # suitable for processing an m4 source # code file. # \index{m4@{\tt -m4} option} \\ # {\tt -prolog} & Source Code & Use comment characters and other commands # suitable for processing a Prolog source # code file. # \index{prolog@{\tt -prolog} option} \\ # {\tt -shell} & Source Code & Use comment characters and other commands # suitable for processing a shell script (csh, # sh, awk, perl). # \index{shell@{\tt -shell} option} \\ # \hline # \end{tabular} # \end{center} # # \begin{center} # General Options \\ \hspace*{1in} \\ # \begin{tabular}{lp{5.in}} # Option & Meaning \\ \hline # {\tt -blanks=number} & The number of blanks to match and remove after # comment keywords. The default is # one. \index{blanks@{\tt -blanks} option} \\ # {\tt -dir=dirname} & Output any named files to the specified # directory. \index{dir@{\tt -dir} option} \\ # {\tt -headeronly} & Ignore any {\tt Document} keywords in the file # and output the file header only, verbatim, to # standard out. The file header consists of all lines # that are comment lines at the beginning of a file -- # the first non-commented line marks the end. If there # are files named .doc\_header and .doc\_footer located # in the current directory, they will be prepended and # appended to the output. See the \hyperref{Unmodified # Files section} {Unmodified Files section (section~} # {)}{Unmodified Files} for more information. # \index{headeronly@{\tt -headeronly} option} \\ # {\tt -self} & Use the self-documentation mode which extracts a # shell script from the file and runs it. Note that # a source code language must still be specified (or # defaulted) so that the proper comment characters # are used. \index{self@{\tt -self} option} \\ # {\tt -selftest} & Use the self-test mode which extracts a shell # script from the file and runs it. This # is a synonym for the {\tt -self} flag. # \index{selftest@{\tt-selftest} option} \\ # {\tt -silent} & Do not output anything to STDERR. This includes # informational output. Also, do not query the # user for verification before executing scripts. # \index{silent@{\tt -silent} option} \\ # {\tt -verbatim} & Ignore any {\tt Document} keywords in the file # and output the entire file, verbatim, to standard # out. If there are files named .doc\_header and # .doc\_footer located in the current directory, they # will be prepended and appended to the output. See # the \hyperref{Unmodified Files section} {Unmodified # Files section (section~} {)}{Unmodified Files} for # more information. \index{verbatim@{\tt -verbatim} # option} \\ # \hline # \end{tabular} # \end{center} # # The {\tt Document} package can be used with any formatting language, and # can be easily extended to other source code languages. # # If an option is specified for the source code language on the command line, # then it applies to all of the files being processed. If no source code # language option is given on the command line, then the first twenty lines of # each file are checked for a line containing: # \index{options!default} # # \begin{verbatim} # Document options: [options] # \end{verbatim} # # which will specify options for that file only. If the source code language # is still undefined, then the directory that contains the input file is # searched for a file named # .doc\_options,\index{doc\_options@.doc\_options file} which contains a # single line with only the desired options. If the source code language is # still undefined, the suffix of the file type will be checked for matches # with defined suffix types for each source code language: # # \begin{center} # \begin{tabular}{cc} # Source Code Language & File Suffixes \\ \hline # C++ & .C, .cc, .c, .H, .hh, .Cpp, .cpp, .hxx, .cxx\\ # Fortran & .F, .f, .h, .F90, .FCM, .inc, .fm4 \\ # Java & .java \\ # \LaTeX\ & .tex \\ # M4 & .m4, .gm4 \\ # Prolog & .ari, .pro, .nl \\ # Shell & .awk, .pl, .perl, .sed, .tcl, no suffix \\ \hline # \end{tabular} # \end{center} # # If the source code language is still undefined, then it will default to # {\tt -fortran}. # # \subsection{File Format} # # The idea behind the {\tt Document} package is that all documentation # keywords \index{keywords} are placed in the comments of the source code # document being processed. The source code can then be processed by the # compiler or interpreter without additional changes. The {\tt Document} # keywords instruct the {\tt Document} package how to extract documentation # from the source code file without affecting the operation of the source code # file itself. # # {\tt Document} keywords are different for each command line option that is # specified. In this description, the {\tt Document} keywords for the default # options \index{options!default} ({\tt -generic} and {\tt -fortran}) will be # used, with the name of the perl list variable for the specific keyword in # parantheses. For the values of the keywords for other options, consult the # \hyperref{Coding Details section}{Coding Details section (see section~} # {)}{CodeDetails}. # # To start the documentation process, enter the # \index{variables!start\_documentation} {\tt Begin\_Doc # (start\_documentation)} keyword, on a line by itself, in the comments of the # file: # # \begin{verbatim} # c This line of text will not be in the documentation file. # c Begin_Doc # c This line of text will be entered into the documentation file. # \end{verbatim} # # To terminate the documentation process, enter the # \index{variables!end\_documentation} {\tt End\_Doc (end\_documentation)} # keyword, on a line by itself, in the comments of the file: # # \begin{verbatim} # c This line of text will be entered into the documentation file. # c End_Doc # c This line of text will not be in the documentation file. # \end{verbatim} # # \index{multiple output files} # The format given above will send the documentation output to standard output. # An optional filename may be appended to the {\tt Begin\_Doc} # keyword to redirect output. This filename will be valid only for the current # documentation block. If the same filename is specified more than once, the # first specification will open the file and subsequent specifications will # append to the file. This feature can be used to change the order of input for # the documentation, as is shown in this example: # # % The \ia, \ib hack is to allow \input in a verbatim environment (and # % work correctly in both LaTeX and LaTeX2HTML). What a pain... # % # \newcommand{\ia}{\char 92 input\char 123 a\char 125 \html{\ }} # \newcommand{\ib}{\char 92 input\char 123 b\char 125 \html{\ }} # % # % More shenanigans to get past the various filters. # % # \newcommand{\percent}{\char 37} # \begin{alltt} # c Begin_Doc main.tex # c \percent\ Note that the order of files a.tex and b.tex has been switched. # c \ib # c \ia # c End_Doc # c # c Begin_Doc a.tex # c This line is in file a.tex. # c End_Doc # c # c Begin_Doc b.tex # c This line is in file b.tex. # c End_Doc # c # c Begin_Doc a.tex # c This line is appended to file a.tex. # c End_Doc # \end{alltt} # # The default documentation mode removes the comment characters from the # documentation before printing. For Fortran, the comment character keywords # \index{variables!comment\_characters} ({\tt comment\_characters}) are either # a ``c'' or whitespace and an exclamation point (``!'') at the beginning of # the line. In-line comments with coding followed by an exclamation point and a # comment are not modified. For example, in the default documentation mode # these lines: # # \begin{verbatim} # c Begin_Doc # c # c Comment. # c # ! Bang-style comment. # do i = 1, 10 # a(i) = i**2 ! In-line comment # end do # c End_Doc # \end{verbatim} # # would appear like this in the output: # # \begin{verbatim} # # Comment. # # Bang-style comment. # do i = 1, 10 # a(i) = i**2 ! In-line comment # end do # \end{verbatim} # # To stop the removal of comment character keywords from the output (i.e. to # leave lines unmodified), surround the text with the # \index{variables!start\_verbatim} {\tt Begin\_Verbatim (start\_verbatim)} # keyword, on a line by itself, and the \index{variables!end\_verbatim} # {\tt End\_Verbatim (end\_verbatim)} keyword, on a line by itself, in the # comments of the file: # # % The \bv, \ev hack is to allow (\begin/\end){verbatim} in an alltt # % environment (this is necessary in *both* LaTeX and LaTeX2HTML). What a # % pain... # % # % (Already defined above) # %\newcommand{\bv}{\char 92 begin\char 123 verbatim\char 125 \html{\ }} # %\newcommand{\ev}{\char 92 end\char 123 verbatim\char 125 \html{\ }} # % # \begin{alltt} # c Begin\_Doc # c These lines will have # c their comment characters removed # c # c \bv # c Begin\_Verbatim # c # c But these lines won't. # c # c End\_Verbatim # c \ev # c End\_Doc # \end{alltt} # # which will appear as follows in the output: # # \begin{alltt} # These lines will have # their comment characters removed # # \bv # c # c But these lines won't. # c # \ev # \end{alltt} # # Notice the use of the \LaTeX\ verbatim environment on the outside of the # {\tt Document} verbatim keywords. This is a common construct for situations # where quoting code and preserving the comments is desired. # # Two last {\tt Document} keywords are \index{variables!always\_print} # {\tt always\_print} and \index{variables!never\_print} {\tt never\_print}. If # any line is found with either of these keywords (even if there are other # things on the line), the specified action will be taken. The # {\tt never\_print} keyword takes precedence, and is primarily used for the # self-documentation option (see the # \hyperref{Self-Documentation section}{Self-Documentation section, section~} # {}{SelfDoc}). # For {\tt always\_print}, comments will be stripped off unless currently # inside a verbatim environment. {\tt always\_print} is not used with either # the {\tt -generic} or {\tt -fortran} options. # # \subsection{Running {\tt Document} on Unmodified Files} # \label{Unmodified Files}% # \index{Unmodified files} \index{Easy Implementation}% # # To reap the full benefits of using the {\tt Document} package, one must make # modifications to the source code files. However, there are situations where # it is desireable to have some form of rudimentary documentation for a package # that for some reason has unmodified source. For instance, it could be source # that is not maintained by the person doing the documentation, or it could be # the first attempt at using {\tt Document} before making specialized # modifications to the source. # # {\tt Document} provides two options that are useful in this situation, # {\tt -verbatim} \index{verbatim@{\tt -verbatim} option} and {\tt -headeronly} # \index{headeronly@{\tt -headeronly} option}. The {\tt -verbatim} option # outputs the entire contents of the file with no changes to standard out. The # {\tt -headeronly} option outputs only the header of the file, which is # defined as every line until a non-comment line is reached. Additionally, both # options will prepend and append the files .doc\_header and .doc\_footer if # they exist.\index{doc\_header@.doc\_header file} # \index{doc\_footer@.doc\_footer file} The .doc\_header and .doc\_footer # files can contain the following strings which will have the correct values # substituted in: # # \begin{tabular}{lp{5in}} # String & Substitution \\ \hline # doc\_filename & The complete filename, without the directory. \\ # doc\_filename\_base & The filename without any suffix, without the # directory. \\ # doc\_dirname & The immediate directory name (not the full directory # name, but only the directory name one level up from # the input file). \\ \hline # \end{tabular} # # The header and footer files may be configured for use with any formatting # language. A common choice for the header and footer files for use with # \LaTeX\ and \LaTeX 2\texttt{HTML} is: # # % Sigh... # % # \newcommand{\sbq}{\char 92 subsection\char 123 doc\_filename\_base \char 92 label\char 123 doc\_filename\_base\char 125 \char 125 \html{\ }} # \newcommand{\idx}{\char 92 index\char 123 doc\_dirname!doc\_filename\char 125 \html{\ }} # % # % Here's what is really represented here: # % # %\subsection{doc_filename_base \label{doc_filename_base}} # %\index{doc_dirname!doc_filename} # % # .doc\_header: # # \begin{alltt} # \sbq # \idx # \bv # \end{alltt} # # .doc\_footer: # # \begin{alltt} # \ev # \end{alltt} # # The desired options for processing the files (for example, the # {\tt -verbatim} or the {\tt -headeronly} option) may be specified in a # .doc\_options\index{doc\_options@.doc\_options file} file that is placed in # the same directory. # # \subsection{Self-Documentation} \label{SelfDoc} # # The commands used to generate the documentation for a file can be imbedded # in the file in a similar manner to the documentation itself. To activate # this feature, use the \index{self@{\tt -self} option} {\tt -self} option. # For example, the documentation for document can be generated by typing: # # \begin{verbatim} # % Document -self -shell Document # \end{verbatim} # # The {\tt -self} option parses the input file and removes comment characters # according to the setting of the source code option. The # \index{variables!start\_documentation} {\tt start\_documentation} keyword is # set to {\tt Begin\_Self\_Document}, and the # \index{variables!end\_documentation} {\tt end\_documentation} keyword is # set to {\tt End\_Self\_Document}. The {\tt -self} option then removes any # initial ``{\tt \%}'' sign (often used to indicate shell input), and executes # each line in turn. # # Here is an example self-documentation entry, in a Fortran code segment: # # % More shenanigans to get past the various filters # % (see percent definition above). # % # \begin{alltt} # c Begin\_Self\_Document # c \percent\ Document -fortran routine.F > routine.tex # c \percent\ latex routine # c End\_Self\_Document # c # c Other code and comments. # c # c Begin\_Self\_Document # c \percent\ makeindex routine # c \percent\ latex routine # c \percent\ latex routine # c \percent\ dvi routine # c \percent\ latex2html -dir routinehtml -nomath -html_version 4.0,math routine # c End\_Self\_Document # \end{alltt} # # which would execute the following commands: # # \begin{verbatim} # Document -fortran routine.F > routine.tex # latex routine # makeindex routine # latex routine # latex routine # dvi routine # latex2html -dir routinehtml -nomath -html_version 4.0,math routine # \end{verbatim} # # The {\tt -self} option is equivalent to the {\tt -selftest} option, and the # beginning and ending keywords can be written as {\tt Begin\_Self\_Test} and # {\tt End\_Self\_Test}. This usage underscores that the self-documentation # (or self-test) feature is a very powerful feature with many uses -- its # primary function is simply to couple a script with some input data so that # they can be maintained in sync. The function could be # # \begin{itemize} # \item processing the documentation in a file according to a script # contained in the same file; # \item compiling, running, and examining the output of the source code in # a file according to a script contained in the same file; or # \item writing several input files, running an executable on them, # and examining the output of the run, with all of the input files # and the execution script contained in the same file. # \end{itemize} # # End_Doc # # Begin_Doc doccode.tex # \section{Coding Details \label{CodeDetails}} # \begin{verbatim} # Begin_Verbatim # Settings. $, = ''; # Set output field separator. $\ = "\n"; # Set output record separator. $true = "1"; # Name for true variable. # Save STDOUT for later use. open(SAVESTDOUT,">&STDOUT"); # Process command line options. &set_options(@ARGV); ($source) && ($default_source = $source); ($format) && ($default_format = $format); ($file_verbatim) && ($default_file_verbatim = $file_verbatim); ($header_only) && ($default_header_only = $header_only); # Subroutine to process options. sub set_options { foreach (@_) { /^(-generic)$/ && ($format = $_); /^(-c\\+\\+|-fortran|-java|-latex|-m4|-prolog|-shell)$/ && ($source = $_); /^-self$/ && ($self_doc = $true); /^-selftest$/ && ($self_doc = $true) && ($self_test = $true); /^-silent$/ && ($silent = $true); /^-dir=(\S*)$/ && ($directory = $1); /^-blanks=(\S*)$/ && ($number_of_blanks = $1); /^-verbatim$/ && ($file_verbatim = $true); /^-headeronly$/ && ($header_only = $true); } !$silent && !$self_doc && ($verbose = $true); } # Sort argument list to put flags in front, then remove them. @ARGV = sort @ARGV; while ($ARGV[0] =~ /^-/) {shift;} # Loop over input files. foreach $infile (@ARGV) { open(INFILE, "$infile") || die "Can't open $infile: $!"; # Set default languages and modes from command line options. $format = 0; $source = 0; $file_verbatim = 0; $header_only = 0; ($default_format) && ($format = $default_format); ($default_source) && ($source = $default_source); ($default_file_verbatim) && ($file_verbatim = $default_file_verbatim); ($default_header_only) && ($header_only = $default_header_only); # Read first lines of file for options if necessary. if (!$source) { $i = 0; while ($i < 20) { $i++; $_ = ; if (/[dD]ocument\s*[oO]ptions:\s*(.*)$/) { &set_options(split(/ /,$1)); } } seek(INFILE,0,0); # Rewind the file. } # Look for .doc_options file for options if necessary. ($doc_options = $ENV{"PWD"}."/".$infile) =~ s|/[^/]*$||; $doc_options .= "/.doc_options"; if (!$source) { if (-r $doc_options) { open(OPTIONS, "$doc_options") || die "Can't open $doc_options: $!"; $_ = ; &set_options(split); close(OPTIONS); } } # Set source code language by file suffix if necessary. if (!$source) { $_ = $infile; if (/\.([^\.]*)$/) { $_ = $1; } else { $_ = ""; } /^(C|cc|c|H|hh|Cpp|cpp|hxx|cxx)$/ && ($source = "-c++"); /^(F|f|h|F90|FCM|inc|fm4)$/ && ($source = "-fortran"); /^(java)$/ && ($source = "-java"); /^(tex)$/ && ($source = "-latex"); /^(m4|gm4)$/ && ($source = "-m4"); /^(ari|pro|nl)$/ && ($source = "-prolog"); /^(awk|pl|perl|sed|sh|tcl)$/ && ($source = "-shell"); # Uncomment next line to make .pl files default to Prolog. #/^(pl)$/ && ($source = "-prolog"); ($_ eq "") && ($source = "-shell"); } # Set last resort default languages if necessary. (!$source) && ($source = "-fortran"); (!$format) && ($format = "-generic"); # End_Verbatim # \end{verbatim} # \index{variables!start\_verbatim} \index{variables!end\_verbatim} # \index{variables!always\_print} \index{generic@{\tt -generic} option} # \begin{verbatim} # Begin_Verbatim # Lists of reserved words related to the formatter. # # -generic : use generic commands (default). if ($format eq '-generic') { @start_verbatim = ('Begin_Verbatim'); @end_verbatim = ('End_Verbatim'); } # End_Verbatim # \end{verbatim} # \index{variables!comment\_characters} \index{variables!always\_print} # \index{variables!start\_documentation} \index{variables!end\_documentation} # \index{c++@{\tt -c++} option} \index{fortran@{\tt -fortran} option} # \index{java@{\tt -java} option} \index{latex@{\tt -latex} option} # \index{m4@{\tt -m4} option} \index{prolog@{\tt -prolog} option} # \index{shell@{\tt -shell} option} # \begin{verbatim} # Begin_Verbatim # Lists of reserved words related to the source code language. # # -c++ : use C++ (or C) commands. # -fortran : use Fortran commands (default). # -java : use Java commands (same as C++). # -latex : use LaTeX commands (as a *source* code language). # -m4 : use m4 commands. # -prolog : use Prolog commands. # -shell : use shell (csh, sh, perl, awk, tcl) commands. if ($source eq '-c++') { @start_documentation = ('Begin_Doc'); @end_documentation = ('End_Doc'); @always_print = (@always_print); @comment_characters = ('^\s*//','^\s*/\*','^#'); @comment_endings = ('\*/'); } elsif ($source eq '-fortran') { @start_documentation = ('Begin_Doc'); @end_documentation = ('End_Doc'); @always_print = (@always_print); @comment_characters = ('^[Cc]','^\\s*!'); } elsif ($source eq '-java') { @start_documentation = ('Begin_Doc'); @end_documentation = ('End_Doc'); @always_print = (@always_print); @comment_characters = ('^\s*//','^\s*/\*\*','^\s*/\*'); @comment_endings = ('\*/'); } elsif ($source eq '-latex') { @start_documentation = ('Begin_Doc'); @end_documentation = ('End_Doc'); @always_print = (@always_print); @comment_characters = ('^\s*%'); } elsif ($source eq '-m4') { @start_documentation = ('Begin_Doc'); @end_documentation = ('End_Doc'); @always_print = (@always_print); @comment_characters = ('^\s*dnl'); } elsif ($source eq '-prolog') { @start_documentation = ('Begin_Doc'); @end_documentation = ('End_Doc'); @always_print = (@always_print); @comment_characters = ('^\s*%','^\s*\/\*'); @comment_endings = ('\*/'); } elsif ($source eq '-shell') { @start_documentation = ('Begin_Doc'); @end_documentation = ('End_Doc'); @always_print = (@always_print); @comment_characters = ('^\s*#'); } # End_Verbatim # \end{verbatim} # \index{variables!never\_print} \index{self@{\tt -self} option} # \begin{verbatim} # Begin_Verbatim # Self-Documentation (or Self-Test) Mode. if ($self_doc) { @start_documentation = ('Begin_Self_Document','Begin_Self_Test'); @end_documentation = ('End_Self_Document','End_Self_Test'); @always_print = (); } @never_print = (@never_print,'Begin_Self\_Document','End_Self\_Document'); @never_print = (@never_print,'Begin_Self\_Test','End_Self\_Test'); # End_Verbatim # \end{verbatim} # \index{verbatim@{\tt -verbatim} option} # \index{headeronly@{\tt -headeronly} option} # \begin{verbatim} # Begin_Verbatim # Verbatim and Header-Only Modes. $doc_header = ".doc_header"; $doc_footer = ".doc_footer"; if ($file_verbatim || $header_only) { $include = $true; $verbatim = $true; ($infile_dir = $ENV{"PWD"}."/".$infile) =~ s|/[^/]*$||; $infile_dir =~ s|.*/||; ($infile_name = $infile) =~ s|^.*/||; ($infile_base = $infile_name) =~ s/\.[^\.]*$//; if (-r $doc_header) { open(HEADER, "$doc_header") || die "Can't open $doc_header: $!"; while (
) { chop; s/doc_filename_base/$infile_base/; s/doc_filename/$infile_name/; s/doc_dirname/$infile_dir/; print; } close(HEADER); } } else { $include = 0; $verbatim = 0; } # Set regexp for matching blanks after the comment keywords. # Default number of blanks to match is one. ($number_of_blanks) || ($number_of_blanks = 1); $blanks = '('.(' 'x$number_of_blanks).')?'; # Make regular expressions from the lists of keywords. $comment_characters = join("$blanks|",@comment_characters).$blanks; if (@comment_endings) { $endl = '\s*('.join('|',@comment_endings).')*\s*$'; } else { $endl = '\s*$'; } $beginl = '^('.join('|',@comment_characters).')*'.$blanks.'\s*('; $fname = ')\s*([\S]*)'.$endl; $start_documentation = $beginl.join('|',@start_documentation).$fname; $end_documentation = $beginl.join('|',@end_documentation).')'.$endl; $start_verbatim = $beginl.join('|',@start_verbatim) .')'.$endl; $end_verbatim = $beginl.join('|',@end_verbatim) .')'.$endl; $always_print = join('|',@always_print); $never_print = join('|',@never_print); # Loop over lines from each input file. while () { chop; # Strip record separator. # Turn off documentation mode if one of the end_documentation # keywords is found. Only check if outside of verbatim scope. if (!$verbatim) { /$end_documentation/ && ($include = 0); } # Turn off verbatim mode if one of the end_verbatim # keywords is found (unless -verbatim or -headeronly # has been specified as a flag). Set the suppress # variable to suppress printing of the keyword line. if (/$end_verbatim/ && !$file_verbatim && !$header_only) { $verbatim = 0; $suppress = $true; } # Turn off include mode at the end of the header for # -headeronly option. !/$comment_characters/ && ($header_only) && ($include = 0); # Optional massaging of documentation. if (!$verbatim) { # Remove comment characters. s/$comment_characters//; } # Turn on verbatim mode if one of the start_verbatim # keywords is found. Set the suppress variable to # suppress printing of the keyword line. if (/$start_verbatim/) { $verbatim = $true; $suppress = $true; } # Suppress printing if a never_print keyword is found. /$never_print/ && ($suppress = $true); # Optional print. if ($include && !$suppress) { # Self-Documentation (or Self-Test) mode. if ($self_doc) { # Remove Self-Doc Comment Characters. s/^\s*%//; push (@self_doc_script,$_); } # Regular print. else { print; } } else { $suppress = 0; # Print lines that contain an always_print keyword. ($#always_print != -1) && /$always_print/ && (print); } # Turn on documentation mode if one of the start_documentation # keywords is found. Start with verbatim turned off. if (/$start_documentation/ && !$header_only) { $include = $true; $verbatim = 0; # Redirect output as directed. $file = $4; if ($directory) { $file = $directory.'/'.$file; (! -d $directory) && (system "mkdir $directory"); } close(STDOUT); if ($file eq "") { ($verbose) && (print STDERR "Output to STDOUT."); open(STDOUT,">&SAVESTDOUT"); } elsif ($opened{$file}) { ($verbose) && (print STDERR "Output appended to ", $file, "."); open(STDOUT,">>$file"); } else { ($verbose) && (print STDERR "Output to ", $file, "."); $opened{$file} = 1; open(STDOUT,">$file"); } } } # Verbatim and Header-Only Modes. if ($file_verbatim || $header_only) { if (-r $doc_footer) { open(FOOTER, "$doc_footer") || die "Can't open $doc_footer: $!"; while (