<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">%
%  This is the distribution file for Cameron Smith's "wrtfile" utility.
%  Running TeX on this file causes it to write out the files that
%  make up the "wrtfile" distribution.
%
%  Go ahead and try it; it will ask permission before writing anything.
%
%  This distribution file is dated 19 October 1992.
%
%%%%%%%%%%%%%%%%%%%%%
%
%  ARCHIVISTS PLEASE TAKE NOTE:
%
%  The entire contents of this file are Copyright 1992 by Cameron Smith.
%  This file may be distributed freely *in its original form*.
%
%  Executing this file with the TeX processor causes portions of this file
%  to be written out to other files; but these constituent files may *NOT*
%  be distributed individually, nor assembled together in any other form
%  than this, if the distribution is to be called "wrtfile".
%
%  The computer code embodied in this file may be used freely for any
%  purpose without fee, and may be incorporated into other works,
%  provided that such works are not represented as the "wrtfile" TeX utility.
%
%  In other words, use it, enjoy it, build on it any way you want, but
%  if you want to redistribute "wrtfile" as such, you must distribute
%  it *only* in the form of this TeX file.
%
%%%%%%%%%%%%%%%%%%%%%
%
\begingroup
\catcode`\@ 11
\gdef\FILE #1 {%
  \@@FILESETUP
  \let\@@WRITELINE\@@FILEWRITELINE
  \let\@@ENDFILE\@@FILEEOF
  \immediate\openout 0 #1\relax
  \message{\string\FILE\space #1}%
  \@@READLINE
}
\gdef\TYPE{%
  \@@FILESETUP
  \let\@@WRITELINE\@@TYPELINE
  \let\@@ENDFILE\@@TYPEEOF
  \@@STARTTYPE
}
\gdef\@@FILESETUP{%
  \begingroup
  \endlinechar`\^^M
  \def\do##1{\catcode`##1 12 }%
  \dospecials
  \catcode`\^^I 12  \catcode`\^^L 12  \catcode`\^^M 12\relax
  \newlinechar`\^^M
  \def\empty{}%
}
\endlinechar -1
\catcode `\^^M 12 \relax
\catcode `\| 0 \relax
\catcode `\\ 12 |relax
|gdef|@@STARTTYPE#1^^M{|@@READLINE}
|gdef|@@READLINE#1^^M{
  |@@TESTLINE#1^^M\EOF
}
|gdef|@@TESTLINE#1\EOF{
  |def|@@TEST{#1}
  |ifx|@@TEST|empty
    % \EOF occurred at start of line
    |let|next|@@ENDFILE
  |else
    |def|next{|@@WRITELINE#1\EOF}
  |fi
  |next
}
|gdef|@@FILEWRITELINE#1^^M\EOF{
  |immediate|write 0{#1}
  |@@READLINE
}
|gdef|@@TYPELINE#1^^M\EOF{
  |immediate|write 16{#1}
  |@@READLINE
}
|gdef|@@FILEEOF#1^^M\EOF{
  |immediate|closeout 0|relax
  |endgroup
  |message{\EOF}
}
|gdef|@@TYPEEOF#1^^M\EOF{
  |endgroup
}
|endgroup

\TYPE
This is the distribution file for Cameron Smith's "wrtfile" utility.
Running TeX on this file causes it to write out the files that
make up the "wrtfile" distribution.

This distribution file is dated 19 October 1992.

In a moment you'll be asked whether you wish to proceed.
If you say yes, this job will write the following files:

  read.me -- you should read this!
  wrtfile.doc -- file-writing code, with comments explaining how it works
  wrtfile.tex -- same code, with comments stripped out for speed

If you already have files by these names, you may wish to stop
and rename the files or move them elsewhere so they don't get
overwritten.

Say "y" or "yes" to proceed, anything else to stop the job.
\EOF

\message{Do you wish to proceed? }
\read -1 to \answer

\def\getans #1 #2\endanswer{\uppercase{\def\answer{#1}}}
\expandafter\getans\answer\endanswer

\newif\ifYES
\def\ansY{Y}
\def\ansYES{YES}
\ifx\answer\ansY \YEStrue
\else\ifx\answer\ansYES \YEStrue
\fi\fi

\ifYES
    \let\next\relax
\else
    \let\next\end
    \message{Job aborted.}%
\fi
\next

\TYPE

The files will now be written.  Please read the file "read.me"!
It explains what "wrtfile" is for, how it works, what you may
do with it, and limitations on its redistribution.  Thanks!

\EOF

\FILE read.me

WRTFILE
=======

by Cameron Smith

version of 19 October 1992


HISTORY OF WRTFILE
------------------

Volume 92, Issue 37 of the UKTeX Digest (Friday, 9 Oct 1992) included
a trio of utilities by Jonathan Fine &lt;J.Fine@uk.ac.cambridge.dpmms&gt;.
These were commcheck.tex, plainind.tex, and filechop.tex.

I found them all interesting and useful, especially filechop.tex,
which makes it easy to write a TeX file that writes out other files
when TeXed.  But I was dissatisfied with the way Mr. Fine's filechop was
implemented, because it used TeX's parameter-collection mechanism
to gather up the information to be written out.  This approach made
Fine's code very simple, but it placed severe constraints on the amount
of material that could be written to a file -- no more than what could
be accommodated in TeX's parameter memory.  If memory overflow did occur,
the TeX job would be aborted ungracefully.  I decided to implement a
more robust file writing utility.

My file-writing algorithm reads and writes one line at a time.  The code
is more complicated than Fine's and executes more slowly, but it can write
files of any length (provided that no single line is longer than TeX's
input buffer can accommodate).  In the course of developing wrtfile I
realized that the same code that allows us to write to a file also makes
it easy to write to the terminal, so I implemented that as well.
It's useful in "driver files" (like the one that created this file!)
to be able to conveniently present several lines of information to the user.

The name "wrtfile" was chosen in deference to the 8-character naming
limitations of MS-DOS.  May that system soon perish from the world!


HOW DOES IT WORK?
-----------------

Put the code for "wrtfile" into a TeX document.  It defines two control
sequences that are meant to be invoked by users (and several more "internal"
macros that are not meant to be called directly).  The \FILE macro takes
as an argument a file name, opens up a file of that name for writing, and
writes the lines that follow it in the source file to that output file
until it encounters a line beginning with "\EOF".  For example, the lines

   \FILE abc.def
   Mary had a little lamb,
   its fleece was white as snow.
   \EOF

would cause the file "abc.def" to be created, and to contain the two
lines "Mary had a little lamb," and "its fleece was white as snow.".
All of TeX's special characters (such as \, ~, &amp;, {, }, $, and %) are
disabled during this operation -- the writing stops only when the
literal string "\EOF" appears.  Furthermore, this string must appear
flush at the left margin; it will not be recognized anywhere else.
And it will be detected even if it is immediately followed by other
non-blank characters: the "abc" in "\EOFabc" would not prevent this
string from terminating the writing of a file if it occurred at the
left end of a line.

The \TYPE macro works like the \FILE macro, except that it takes no
argument, and writes to the terminal and the log file rather than
creating another file.  For example, the lines

   \TYPE
   Mary had a little lamb,
   its fleece was white as snow.
   \EOF

would cause the two lines "Mary had a little lamb," and "its fleece was
white as snow." to be written to the terminal and into the log file.

For technical reasons, \TYPE should appear on a line by itself.
It actually uses TeX's parameter-collection mechanism to remove the
end-of-line character that TeX places at the end of each input line;
this is necessary because TeX puts the character there as soon as the
line is read into TeX's input buffer, before the \TYPE macro gains
control.  Similarly the \FILE macro should be followed by nothing except
the name of the file to be written, which should not contain blanks.
Any characters following an \EOF marker on the same line are discarded
(because they have been read with funny \catcode values and so are
probably not useful).


WHAT CAN I DO WITH IT?
----------------------

Although there might be several reasons why one would want to be able
to write a verbatim segment of a TeX input file out to another file,
the most obvious one that springs to mind is that of distributing
TeX macro packages.  Ideally, the distribution of a TeX package should
include several files:

 * two versions of the executable code, one heavily commented for
   ease of understanding and one with comments stripped out for
   speed of execution,

 * a user manual (comments explaining the workings of the code are no
   replacement for this!), which explains the features of the package
   and how to use them,

 * one or more sample files that can be processed by TeX to show how
   the package should be used in real applications,

 * (in some cases) source code in C or Pascal or another language
   providing utilities to be used with the macro package,

and possibly other files according to the needs and nature of the package.
But it is inconvenient and unreliable to distribute all of these files
separately.  One runs the risk that archives may get out of synch,
updating some files but not others when new versions are released,
or that users may retrieve only some of the files they need -- often
they get the program but not the documentation, resulting in unnecessary
pleas for help.  (Those who *get* the documentation but won't *read* it
are a different problem, alas.)  On the whole it is much better to
distribute software in a single package, which the recipient can
break apart to generate the several files that are needed.

There are, of course, many utilities for assembling collections of
files into single files for transmission or archiving.  But they
suffer from various drawbacks.  Many are tied to specific systems
and so are unsuitable for distributing TeX code, since TeX is
implemented on so many disparate systems.  Also, such utilities
typically create binary files; such files cannot be transmitted
through email, and some archives do not accept them.  (When I
was preparing to distribute my "pageframe" LaTeX utility, the first
archivist I approached told me that his site had a policy against
placing any non-ASCII file into its archives, and so would accept
the ".tar.Z" file I submitted only if I agreed to have the constituent
files broken out and made available for individual retrieval.
Since I did NOT want it to be possible for a user to retrieve
the code without the documentation, I was unhappy about this.)

Suppose you want to distribute a file that "wrtfile" can't write?
(See the "Bugs and Limitations" section below.)  One possibility
is to encode the file, use "wrtfile" to write the encoded version,
and tell recipients how to decode it.  For example, the "uuencode"
utility reads a file containing any sequence of bytes and writes
a file that contains only standard printable characters.  The companion
"uudecode" utility can read the printable file created by "uuencode"
and reconstruct the original file.  "uuencode" and "uudecode" originated
in UNIX environments, but freeware implementations of them for VMS,
Macintosh, and MS-DOS systems have been available for some time.
Other formats ("xxencode", "btoa", "vvencode", etc.) with similar
purposes are also in use.

Incidentally, the file-writing functionality provided by "wrtfile"
is similar to, but more primitive than, the capability provided by
the "docstrip" utility of Mittelbach, Duchier, and Braams.  However,
"docstrip" works best when it is guided by a "driver" file, separate
from the "package" file from which other files are extracted.  That
puts us back in the position of having to distribute two files (the
driver and the package file), keep them in synch, and make sure that
anyone who gets either file gets both.  Also, many sites do not have
the "docstrip" code, and its creators have placed restrictions on its
distribution that make it impractical to include a copy with your
own package so that all your recipients will have it.  (It is not
permitted to send "docstrip.sty" without sending the entire "doc.doc"
and "docstrip.doc" distribution set, which is prohibitively large.)
By contrast, the code for "wrtfile" is only about sixty lines long --
a little over 1K -- and may be freely incorporated into document
packages.  (See the section below on "Redistribution".)


BUGS AND LIMITATIONS
--------------------

There are two respects in which the files written by \FILE are not
faithful copies of the original data.  Neither one has any negative
effect if the files being written are going to be read only by TeX.
Fixing either one would require changes to TeX itself.  The two
discrepancies pertain to the handling of trailing blanks and
"non-printable" characters.

Trailing blanks on an input line will be chopped off.  This is a
feature of TeX's input routine, and happens even before category
codes are assigned.  (TeX was made to behave this way to accommodate
operating systems that handle text files as files of fixed-length
records; such systems usually pad the lines of text files with
blanks to fill them out to a common length.  By stripping off all
trailing blanks on all input lines, TeX is guaranteed to behave
the same way whether lines are padded or not.)  Since the code for
\FILE never receives the trailing blanks in the first place, it can't
know to write them out, so they don't appear in the output file.
So this method of writing a file will not faithfully reproduce files
that have lines with trailing blanks.  On the other hand, the same
fact about TeX that creates this problem means that the deleted
trailing blanks could never have influenced TeX anyway, so if the
file being written is destined to be TeX input then this blank removal
doesn't matter.

TeX writes some "non-printable" characters as special sequences
involving the "^^" notation.  The choice of which character codes get
written this way is implementation-dependent -- it may vary from one
machine or one implementation to another, but for each implementation
it is fixed at compile time and isn't changeable later.  In Unix TeX
the tab character is always written as "^^I", for example.  This is
another respect in which the lines written out by TeX may not faithfully
reconstruct the original input, but again it doesn't matter as long
as the files being written are going to be read in as TeX input later,
because TeX's reading mechanism converts the "^^" notation back into
the original characters as the lines are read.


REDISTRIBUTION OF WRTFILE
-------------------------

ARCHIVISTS PLEASE TAKE NOTE!

The entire contents of the "wrtfile" distribution package are copyright
1992 by Cameron Smith, with all rights reserved.  Permission to use the
code, without fee, for any purpose, is hereby given, subject to one
restriction: the "wrtfile" package itself must not be distributed in
any other form than that of the "wrtfdist.tex" distribution file.

In other words, you are free to use the unadorned "wrtfile.tex" code
to create a distribution package file that (when processed by TeX)
produces a collection of your own files, and you are free to distribute
such a package file that contains the "wrtfile" code.  But you must
not claim to distribute "wrtfile" itself unless you distribute it in its
original form (as a "wrtfile" package).  You may not, for instance,
distribute "wrtfile" by collecting the three files "read.me",
"wrtfile.tex", and "wrtfile.doc" into a .zip or .tar.Z archive file
and making that file available for FTP or email retrieval.


MAINTENANCE: BUG REPORTS AND FIXES
----------------------------------

The author of wrtfile intends to maintain it, and would be very grateful
to receive error reports and suggestions for enhancement.  His name is
Cameron Smith.  You can contact him via electronic mail as

    cameron@symcom.math.uiuc.edu

(on the Internet) or by telephone at 513-429-2707 (in the USA).

\EOF read.me
\FILE wrtfile.doc
%  The "wrtfile" code and comments are copyright 1992 by Cameron Smith.
%  Please read the file "read.me" for limitations on use and redistribution.
%
%  We'll be doing some monkey business with catcodes and other parameters,
%  but we want to keep it local.
%
\begingroup
%
%  Allow @ signs in macro names
%
\catcode`\@ 11
%
%  The \FILE macro gets things going.
%  It scoops up the name of the file to write,
%  reassigns catcodes of special characters,
%  makes sure that the \endlinechar, the \newlinechar, and
%  the macro \empty have their expected meanings,
%  opens the output file, writes a message to the terminal,
%  and starts the reading loop.
%
\gdef\FILE #1 {%
  \@@FILESETUP
  \let\@@WRITELINE\@@FILEWRITELINE
  \let\@@ENDFILE\@@FILEEOF
  \immediate\openout 0 #1\relax
  \message{\string\FILE\space #1}%
  \@@READLINE
}
%
%  \TYPE does the same things that \FILE does, but it outputs to the
%  terminal (and the log file) rather than to another file.  It's
%  handy for putting explanatory passages into the master file.
%  It uses the same reading loop as \FILE, but takes slightly
%  different actions when writing a line and at end-of-file.
%
\gdef\TYPE{%
  \@@FILESETUP
  \let\@@WRITELINE\@@TYPELINE
  \let\@@ENDFILE\@@TYPEEOF
  \@@STARTTYPE
}
%
%  This does the actual re-catcoding of characters and other setup
%  that both \FILE and \TYPE need.
%
\gdef\@@FILESETUP{%
  \begingroup
  \endlinechar`\^^M
  \def\do##1{\catcode`##1 12 }%
  \dospecials
  \catcode`\^^I 12  \catcode`\^^L 12  \catcode`\^^M 12\relax
  \newlinechar`\^^M
  \def\empty{}%
}
%
%  Henceforth we don't want any character added to the ends of lines.
%  Note: this applies while we are *defining* this code, not executing it!
%  When \@@FILESETUP is executed it sets the \endlinechar to ^^M.
%
\endlinechar -1
%
%  Within these definitions, make ^^M an "other" character,
%  | a macro escape character, and \ an "other" character.
%
\catcode `\^^M 12 \relax
\catcode `\| 0 \relax
\catcode `\\ 12 |relax
%
|gdef|@@STARTTYPE#1^^M{|@@READLINE}
%
%  The \@@READLINE macro reads up to the next ^^M character
%  (which is guaranteed to be present because \FILE sets \endlinechar)
%  and hands off the line to \@@TESTLINE, after introducing the characters
%  "\EOF" (note: "\" is an ordinary character now!) so that \@@TESTLINE
%  will definitely find those characters.
%
%  NOTE: Trailing blanks on an input line will be chopped off, and
%  some "non-printable" characters will be written as special
%  sequences involving the "^^" notation.  See the "read.me" file
%  distributed with this code for a discussion of these matters.
%
|gdef|@@READLINE#1^^M{
  |@@TESTLINE#1^^M\EOF
}
%
%  \@@TESTLINE scans up to the first "\EOF" sequence (\@@READLINE has
%  ensured that we will find one).  If nothing (not even ^^M or spaces)
%  precedes "\EOF", then we have found the end-of-file mark, and we call
%  \@@ENDFILE.  Otherwise we haven't found the end-of-file mark, so we call
%  \@@WRITELINE to write the line to the output file and then resume the
%  reading loop.  If we call \@@WRITELINE, we must be very careful to
%  put back the tokens that were swallowed by \@@TESTLINE, including the
%  "\EOF" sequence (which might not have come from the tokens inserted
%  by \@@READLINE, if "\EOF" occurred in the input line somwhere other than
%  at the left end).  Note that spaces are not ignored at the beginnings of
%  lines while this code is executing, so the "\EOF" sequence must be flush
%  at the left end of the line to be recognized as the end-of-file mark.
%  On the other hand, it will be recognized at the left end of the line
%  even if it is followed by alphabetic characters: the "abc" in "\EOFabc"
%  would not keep \@@TESTLINE from recognizing the "\EOF".
%
|gdef|@@TESTLINE#1\EOF{
  |def|@@TEST{#1}
  |ifx|@@TEST|empty
    % \EOF occurred at start of line
    |let|next|@@ENDFILE
  |else
    |def|next{|@@WRITELINE#1\EOF}
  |fi
  |next
}
%
%  \@@WRITELINE writes the line we just read, minus the end-of-line ^^M
%  character and the "\EOF" sequence introduced by \@@READLINE, to the
%  output file.
%
|gdef|@@FILEWRITELINE#1^^M\EOF{
  |immediate|write 0{#1}
  |@@READLINE
}
%
%  \@@TYPELINE does what \@@WRITELINE does, but it writes to the terminal
%  and the log file rather than to another file.
%
|gdef|@@TYPELINE#1^^M\EOF{
  |immediate|write 16{#1}
  |@@READLINE
}
%
%  Note: tokens following an \EOF that begins a line are thrown away!
%  They have been read with funny catcodes, so they aren't likely
%  to be useful anyway.  This lets us put a "comment" there, which is
%  useful for flagging which file the \EOF is supposed to be ending.
%
|gdef|@@FILEEOF#1^^M\EOF{
  |immediate|closeout 0|relax
  |endgroup
  |message{\EOF}
}
%
%  We don't have to close a file if we were writing to the terminal.
%
|gdef|@@TYPEEOF#1^^M\EOF{
  |endgroup
}
%
%  Revert to previous values of \endlinechar, catcodes, etc.
%
|endgroup
%
%  End of the file-chopping code.
%
\EOF wrtfile.doc
\FILE wrtfile.tex
%  The "wrtfile" code is copyright 1992 by Cameron Smith.
%  Please read the file "read.me" for limitations on use and redistribution.
\begingroup
\catcode`\@ 11
\gdef\FILE #1 {%
  \@@FILESETUP
  \let\@@WRITELINE\@@FILEWRITELINE
  \let\@@ENDFILE\@@FILEEOF
  \immediate\openout 0 #1\relax
  \message{\string\FILE\space #1}%
  \@@READLINE
}
\gdef\TYPE{%
  \@@FILESETUP
  \let\@@WRITELINE\@@TYPELINE
  \let\@@ENDFILE\@@TYPEEOF
  \@@STARTTYPE
}
\gdef\@@FILESETUP{%
  \begingroup
  \endlinechar`\^^M
  \def\do##1{\catcode`##1 12 }%
  \dospecials
  \catcode`\^^I 12  \catcode`\^^L 12  \catcode`\^^M 12\relax
  \newlinechar`\^^M
  \def\empty{}%
}
\endlinechar -1
\catcode `\^^M 12 \relax
\catcode `\| 0 \relax
\catcode `\\ 12 |relax
|gdef|@@STARTTYPE#1^^M{|@@READLINE}
|gdef|@@READLINE#1^^M{
  |@@TESTLINE#1^^M\EOF
}
|gdef|@@TESTLINE#1\EOF{
  |def|@@TEST{#1}
  |ifx|@@TEST|empty
    % \EOF occurred at start of line
    |let|next|@@ENDFILE
  |else
    |def|next{|@@WRITELINE#1\EOF}
  |fi
  |next
}
|gdef|@@FILEWRITELINE#1^^M\EOF{
  |immediate|write 0{#1}
  |@@READLINE
}
|gdef|@@TYPELINE#1^^M\EOF{
  |immediate|write 16{#1}
  |@@READLINE
}
|gdef|@@FILEEOF#1^^M\EOF{
  |immediate|closeout 0|relax
  |endgroup
  |message{\EOF}
}
|gdef|@@TYPEEOF#1^^M\EOF{
  |endgroup
}
|endgroup
\EOF wrtfile.tex
\end
</pre></body></html>