% % $Header: d:/noweb/work/RCS/nocond.nw%v 1.4 1995/07/29 17:14:49 LEEW Exp LEEW $ % $Workfile$ % % to tangle the sed script % notangle -t4 -R"sed script" nocond.nw > nocond % to tangle the shell script: % notangle -t4 -R"shell script" nocond.nw > nocond % to tangle the awk program % notangle -t4 -Rnocond.awk nocond.nw > nocond.awk % (use -filter "nocond MKS AWKC" if necessary) % to weave: % noweave -t4 -delay -x nocond.nw > nocond.tex % \documentstyle[noweb,twoside]{article} \noweboptions{longchunks} \let\nwnotused=\nwoutput \oddsidemargin=63pt % standard LaTeX margins don't work well for 2-sided webs \evensidemargin=63pt \ifx\LaTeXe\undefined\def\LaTeXe{\LaTeX2e}\fi % for old installations \def\noweb/{{\tt noweb}} \def\nocond/{{\tt nocond}} \def\notangle/{{\tt notangle}} \def\noweave/{{\tt noweave}} \title {A Filter For Conditional Tangling in \noweb/% \thanks{Copyright \copyright~1994, 1995 by Lee Wittenberg. Although this software is freely distributable, it is not in the public domain. It is provided ``as is'' and without any express or implied warranties, including, without limitation, the implied warranties of merchantability and fitness for a particular purpose.}} \author {Lee Wittenberg\\\tt leew@pilot.njin.net} %\input{nocondmac.tex} \bgroup \catcode`\@=11 \global\let\nc@LA=\LA \gdef\nocondmark#1)){\/{\bf[\negthinspace[#1]\negthinspace]}}% \global\let\nc@notused=\nwnotused \global\let\nc@output=\nwoutput \gdef\nc@rootchunk#1{\nwcodecomment{\nocondrootnote}% \global\let\nwnotused=\nc@notused \global\let\nwoutput=\nc@output }% \gdef\nocondrootnote{Conditional definition.}% % for noweb 2.6 (bug, since fixed?) \global\@namedef{r@???}{{0}{\nocondxref}} % for noweb 2.5: \global\@namedef{r@nw@notdef}{{0}{\nocondxref}} \gdef\nocondxref{(conditional)} \global\let\nc@nwixlog=\nwixlogsorted \gdef\nwixlogsorted#1#2{ \ifx#1c% \immediate\write\@auxout{\string\bgroup\string\catcode`\string\(=\string\active} \fi \nc@nwixlog{#1}{#2} \ifx#1c% \immediate\write\@auxout{\string\egroup} \fi}% \catcode`\(=\active \gdef\LA{\nc@LA \catcode`\(=\active \def(##1{\ifx##1(\global\let\nwnotused=\nc@rootchunk \global\let\nwoutput=\nc@rootchunk \nocondmark \else\char`\(##1\fi}% }% \egroup \pagestyle{noweb} \begin{document} \maketitle @ \iffalse % % We don't want a troff man page woven by TeX, do we? % <>= .TH NOCOND 1 "local 8/1/94" .SH NAME nocond \- provide noweb with conditional tangling .SH SYNOPSIS .B nocond version .br \fBawk -f nocond.awk\fP version .SH DESCRIPTION .I nocond is a filter designed to work with .I notangle(1) to provide it with a simple conditional capability. Chunk definitions may be marked as conditional by including a version name wrapped in double parentheses as part of the chunk name. .PP .I nocond concatenates its command line arguments (with a single space between each argument) to form a version name, and removes matching conditional marks from chunk definition names so .I notangle(1) will include the chunks as part of the appropriate definition. .PP .I nocond also provides a file of TeX macros, \fInocondmac.tex\fP, which will nicely typeset conditional chunk names. .SH EXAMPLE Suppose that a Pascal web (\fIpgm.nw\fP) uses the chunk .IP \fB@<<\fPOpen the output file\fB@>>\fP .PP The author can provide multiple definitions of this chunk: .IP \fB@<<\fPOpen the output file ((UCSD Pascal))\fB@>>=\fP .nf REWRITE(outfile, 'XYZ.DAT'); \fB@<<\fPOpen the output file ((Turbo Pascal))\fB@>>=\fP ASSIGN(outfile, 'XYZ.DAT'); REWRITE(outfile); .fi .PP To tangle the UCSD Pascal version, the command line .IP notangle -filter "nocond UCSD Pascal" pgm.nw > pgm.pas .PP will suffice. The Turbo Pascal version can be tangled similarly. .SH SEE ALSO .I notangle(1) .SH AUTHOR Lee Wittenberg. Internet address: \fBleew@pilot.njin.net\fP @ \fi @ \section{Introduction} This program is a very simple filter that provides \notangle/ with a simple conditional capability. It should be written in {\tt sed}, but non-Unix versions of that venerable utility are not as readily available as they should be, so we are using Awk instead (however, see section~\ref{sed script}). \section{The Awk Program} The Awk program simply passes all its input lines to the standard output. However, when it encounters a chunk definition name, it first removes any conditional marks that match the version specified on the command line. <>= <> BEGIN{ <> <> } <> {print} <> @ Chunk definition names are prefixed with the markup code `\verb*"@defn "', and [[gsub]] is just made for this kind of work. <>= /^@defn / { gsub(pattern, "", $0) } @ We want to remove marks surrounded by `\verb"(("' and `\verb"))"'. We need the backslashes in the pattern so Awk doesn't treat the parentheses as grouping symbols. <>= <> pattern = " *\(\(" version "\)\)" @ Some command processors are not very friendly about dealing with command line arguments containing spaces, so rather than require the version name to be supplied as a single argument, we treat all the arguments as a single, multi\-word one (with single spaces between the words). We then set [[ARGC]] to~1 to prevent Awk from trying to re-use the arguments as filenames. <>= version = ARGV[1] for (i = 2; i < ARGC; i++) { version = version " " ARGV[i] } ARGC = 1 @ \subsection{System Dependencies} The MKS Awk compiler tends to get confused about command line arguments, even though the interpreter has no problems. The following kludge seems to take care of it (don't ask): <>= ARGV[1] @ It's likely that other system-dependencies will arise as \nocond/ is tried with other versions of Awk. A bit depressing, but that's what the tool was designed for, and it's kind of nice to use it to implement itself. Since every Awk won't require special initialization, we provide a null chunk to avoid ``undefined chunk'' complaints from \notangle/. <>= @ \section{The Shell Script} Unix users can use the following shell script as a \notangle/ filter: <>= nawk '<>' @ \section{A {\tt sed} Script} \label{sed script}. {\sc Gnu} Awk, running under Linux, doesn't seem amenable to any patches that will make the above Awk program work correctly (the [[gsub]] function seems to be a sore spot in many Awk implementations). A {\tt sed} script, therefore, seems to be a necessity. The following does the trick. <>= <> sed "/^@defn/s/ *(($*))//" @ \section{Weaving a Conditional Web} Some people think the double parentheses don't look very good in woven output, and that the version name should stand out a bit from the chunk name. We provide the macro file \verb"nocondmac.tex" for those with such beliefs. These macros should be usable both in plain \TeX\ and \LaTeX, but have only been tested with the latter. They seem to work okay in \LaTeXe{} (in both native and compatibility modes), as well. We simply redefine the meaning of \noweb/'s [[\LA]] macro to make `\verb"("' an active character that typesets stuff in {\tt ((~$\ldots$~))} nicely and leaves other parentheses alone. As long as [[\LA]] exists and contains a \verb"\bgroup" this ought to work. <>= \bgroup \catcode`\@=11 \global\let\nc@LA=\LA <> <> \gdef\LA{\nc@LA <> \def(##1{\ifx##1(<>\nocondmark \else\char`\(##1\fi}% }% \egroup <>= \catcode`\(=\active @ The real work will be done by [[\nocondmark]]. This is the only macro that should be changed if you want to adjust the way conditionals are typeset. <>= \gdef\nocondmark#1)){\/{\bf[\negthinspace[#1]\negthinspace]}}% @ In \LaTeX\ webs, the cross-reference footnotes for root chunks are generated by [[\nwnotused]] or [[\nwoutput]], depending on whether the woven output was generated with the \notangle/ or \noweb/ command. We note the original definitions, but change them to print `Conditional definition.' when a chunk name includes {\tt ((~$\ldots$~))}. <>= \ifx\nwnotused\undefined\else \global\let\nc@notused=\nwnotused \fi \ifx\nwoutput\undefined\else \global\let\nc@output=\nwoutput \fi <>= \ifx\nc@rootchunk\undefined\else \global\let\nwnotused=\nc@rootchunk \global\let\nwoutput=\nc@rootchunk \fi @ The macro [[\nc@rootchunk]] is defined so that it resets [[\nwnotused]] and [[\nwoutput]] when it's finished, so that real root chunks will have the proper footnote. We use [[\nocondrootnote]] so that the conditional footnote can easily be customized. <>= \ifx\nwnotused\undefined\else \ifx\nwoutput\undefined\else \gdef\nc@rootchunk#1{\nwcodecomment{\nocondrootnote}% \global\let\nwnotused=\nc@notused \global\let\nwoutput=\nc@output }% \gdef\nocondrootnote{Conditional definition.}% \fi\fi @ In a web with conditional definitions, chunks that appear to be undefined are actually conditionally defined, so we change the `never defined' message to a more meaningful `conditional'. <>= \ifx\documentstyle\undefined\else % LaTeX only % noweb 2.5: \global\@namedef{r@nw@notdef}{{0}{\nocondxref}} % noweb 2.6: (bug, since fixed?) \global\@namedef{r@???}{{0}{\nocondxref}} \gdef\nocondxref{(conditional)} \fi @ The chunk index is a bit of a problem because \TeX\ assigns catcodes when a token is first read, but the chunk index is read in as part of the \verb".aux" file, when `\verb"("' is not an active character. We fix [[\nwixlogsorted]] so it will change the catcode of `\verb"("' temporarily for chunk index info in the \verb".aux" file. <>= \ifx\nwixlogsorted\undefined\else \global\let\nc@nwixlog=\nwixlogsorted \gdef\nwixlogsorted#1#2{ \ifx#1c \immediate\write\@auxout{\string\bgroup \string\catcode`\string\(=\string\active}% \fi \nc@nwixlog{#1}{#2} \ifx#1c \immediate\write\@auxout{\string\egroup}% \fi }% \fi @ On the other hand, all we need do for [[\nowebchunks@external]] is to set the catcode. Note that the \verb"externalindex" option must be set {\em after\/} executing \verb"\input nocondmac.tex" for things to work properly. <>= \ifx\nowebchunks@external\undefined\else \global\let\nc@chunks@external=\nowebchunks@external \gdef\nowebchunks@external{% \bgroup <> \nc@chunks@external \egroup }% \fi @ \appendix \section {Language and Version Control Tools} This puts revision information in the program so we can make sure things don't get ``out of sync.'' <>= # $Header: d:/noweb/work/RCS/nocond.nw%v 1.4 1995/07/29 17:14:49 LEEW Exp LEEW $ @ \section {Chunk Index} \nowebchunks %\twocolumn[\section{Identifier Index}] % no point, really, for this web %\nowebindex @ \end{document} % $Log: nocond.nw%v $ % Revision 1.4 1995/07/29 17:14:49 LEEW % Added sed script; minor cosmetic changes % % Revision 1.3 1994/09/11 18:06:26 LEEW % Fixed macros for noweb 2.6c % % Revision 1.2 1994/08/05 20:46:48 LEEW % Added macros to typeset chunk index correctly. % % Revision 1.1 1994/08/01 14:05:33 LEEW % Changed manpage to troff format. % Spiffed up nocondmac macros. % Removed non-standard macro packages. % % Revision 1.0 1994/06/20 17:47:55 LEEW % First public version. % % Revision 0.3 1994/06/20 17:31:49 LEEW % Added TeX macros % % Revision 0.2 1994/06/20 16:36:59 LEEW % Awk script complete % % Revision 0.1 1994/06/20 14:54:49 LEEW % Manpage only. % % $Header: d:/noweb/work/RCS/nocond.nw%v 1.4 1995/07/29 17:14:49 LEEW Exp LEEW $