The definitions in this section are only likely to be useful when you are writing nontrivial macros, not when writing a document.
Plain TeX defines \active (as the number 13) for use in
changing category codes. Although the author of The TeXbook
has "intentionally kept the category codes numeric", two other
categories are commonly used: letters (category code 11) and others
(12). Therefore, Eplain defines \letter and
\other.
Sometimes it is cleaner to make a character active without actually
writing a \catcode command. The \makeactive command takes
a character as an argument to make active (and ignores following
spaces). For example, here are two commands which both make \
active:
\makeactive`\\ \makeactive92
Usually, when you give a definition to an active character, you have
to do so inside a group where you temporarily make the character active,
and then give it a global definition (cf. the definition of
\obeyspaces in The TeXbook).
This is inconvenient if you are writing a long macro, or if the
character already has a global definition you do not wish to transcend.
Eplain provides \letreturn, which defines the usual end-of-line
character to be the argument. For example:
\def\mymacro{... \letreturn\myreturn ... }
\mymacro hello
there
The end-of-line between `hello' and `there' causes
\myreturn to be expanded.
The TeXbook describes \uncatcodespecials,
which makes all characters which are normally "special" into "other"
characters, but the definition never made it into plain TeX.
Eplain therefore defines it.
Finally, \percentchar
expands into a literal `%' character. This is useful when you
\write TeX output to a file, and want to avoid spurious
spaces. For example, Eplain writes a \percentchar after the
definition of cross-references. The macros \lbracechar
and \rbracechar
expand similarly.
Plain TeX provides macros that allocate registers of each primitive
type in TeX, to prevent different sets of macros from using the same
register for two different things. The macros are all named starting
with `new',
e.g., \newcount allocates a new "count"
(integer) register. Such allocations are usually needed only at the top
level of some macro definition file; therefore, plain TeX makes the
allocation registers \outer,
to help find errors. (The error this helps to find is a missing right
brace in some macro definition.)
Sometimes, however, it is useful to allocate a register as part of
some macro. An outer control sequence cannot be used as part of a macro
definition (or in a few other contexts: the parameter text of a
definition, an argument to a definition, the preamble of an alignment,
or in conditional text that is being skipped). Therefore, Eplain
defines "inner" versions of all the allocation macros, named with the
prefix `inner':
\innernewbox,
\innernewcount,
\innernewdimen,
\innernewfam,
\innernewhelp,
\innernewif,
\innernewinsert,
\innernewlanguage,
\innernewread,
\innernewskip,
\innernewtoks,
\innernewwrite.
You can also define non-outer versions of other macros in the same way
that Eplain defines the above. The basic macro is called
\innerdef:
\innerdef \innername {outername}
The first argument (\innername) to \innerdef is the
control sequence that you want to define. Any previous definition of
\innername is replaced. The second argument
(outername) is the characters in the name of the outer
control sequence. (You can't use the actual control sequence name,
since it's outer!)
If the outer control sequence is named \cs, and you want to
define innercs as the inner one, you can use
\innerinnerdef,
which is just an abbreviation for a call to \innerdef. For
example, these two calls are equivalent:
\innerdef\innerproclaim{proclaim}
\innerinnerdef{proclaim}
You can iterate through a comma-separated list of items with
\for.
Here is an example:
\for\name:=karl,kathy\do{%
\message{\name}%
}%
This writes `karl' and `kathy' to the terminal. Spaces
before or after the commas in the list, or after the :=, are
not ignored.
\for expands the iterated values fully (with \edef), so
this is equivalent to the above:
\def\namelist{karl,kathy}%
\for\name:=\namelist\do ...
It is occasionally useful to redefine a macro that takes arguments to
do nothing. Eplain defines \gobble,
\gobbletwo,
and \gobblethree to swallow one, two, and three arguments,
respectively.
For example, if you want to produce a "short" table of
contents--one that includes only chapters, say--the easiest thing to
do is read the entire .toc file (see section Contents), and just
ignore the commands that produce section or subsection entries. To be
specific:
\let\tocchapterentry = \shorttocchapter \let\tocsectionentry = \gobbletwo \let\tocsubsectionentry = \gobbletwo \readtocfile
(Of course, this assumes you only have chapters, sections, and subsections in your document.)
In addition, Eplain defines \eattoken
to swallow the single following token, using \let. Thus,
\gobble followed by `{...}' ignores the entire
brace-enclosed text. \eattoken followed by the same ignores only
the opening left brace.
Eplain defines a macro \identity
which takes one argument and expands to that argument. This may be
useful if you want to provide a function for the user to redefine, but
don't need to do anything by default. (For example, the default
definition of \eqconstruct (see section Formatting equation references) is \identity.)
You may also want to read an optional argument. The established
convention is that optional arguments are put in square brackets, so
that is the syntax Eplain recognizes. Eplain ignores space tokens
before an optional argument, via \futurenonspacelet.
You test for an optional argument by using \@getoptionalarg.
It takes one argument, a control sequence to expand after reading the
argument, if present. If an optional argument is present, the control
sequence \@optionalarg expands to it; otherwise,
\@optionalarg is \empty. You must therefore have the
category code of @ set to 11 (letter). Here is an example:
\catcode`@=\letter
\def\cmd{\@getoptionalarg\finishcmd}
\def\finishcmd{%
\ifx\@optionalarg\empty
% No optional argument present.
\else
% One was present.
\fi
}
If an optional argument contains another optional argument, the inner one will need to be enclosed in braces, so TeX does not mistake the end of the first for the end of the second.
Eplain defines \xrlabel
to produce control sequence names for cross-reference labels, et al.
This macro expands to its argument with an `_' appended. (It does
this because the usual use of \xrlabel is to generate a control
sequence name, and we naturally want to avoid conflicts between control
sequence names.)
Because \xrlabel is fully expandable, to make a control
sequence name out of the result you need only do
\csname \xrlabel{label}\endcsname
The \csname primitive makes a control sequence name out
of any sequence of character tokens, regardless of category code.
Labels can therefore include any characters except for `\',
`{', `}', and `#', all of which are used in macro
definitions themselves.
\sanitize takes a control sequence as an argument and converts
the expansion of the control sequence into a list of character tokens.
This is the behavior you want when writing information like chapter
titles to an output file. For example, here is part of the definition
of \writenumberedtocentry; #2 is the title that the user
has given.
...
\def\temp{#2}%
...
\write\tocfile{%
...
\sanitize\temp
...
}%
This section describes some miscellanous macros for expansion, etc.
\csn and \ece
\csn{name} simply abbreviates \csname name
\encsname, thus saving some typing. The extra level of expansion
does take some time, though, so I don't recommend it for an inner loop.
\expandafter token \csname name \endcsname
For example,
\def\fontabbrevdef#1#2{\ece\def{@#1font}{#2}}
\fontabbrevdef{normal}{ptmr}
defines a control sequence \@normalfont to expand to
ptmr.
\edefappend
\edefappend is a way of adding on to an existing definition. It
takes two arguments: the first is the control sequence name, the second
the new tokens to append to the definition. The second argument is
fully expanded (in the \edef that redefines the control sequence).
For example:
\def\foo{abc}
\def\bar{xyz}
\edefappend\foo{\bar karl}
results in \foo being defined as `abcxyzkarl'.
A hook is simply a name for a group of actions which is executed
in certain places--presumably when it is most useful to allow
customization or modification. TeX already provides many builtin
hooks; for example, the \every ... token lists are all
examples of hooks.
Eplain provides several macros for adding actions to hooks. They all take two arguments: the name of the hook and the new actions.
hookaction name actions
hookappend name actions
hookprepend name actions
hookactiononce name \cs
\hookactiononce adds cs to name, like the macros
above, but first it adds
\global\let \cs \relaxto the definition of \cs. (This implies \cs must be a true expandable macro, not a control sequence
\let to a
primitive or some other such thing.) Thus, \cs is expanded the
next time the hook name is run, but it will disappear after that.
The \global is useful because \hookactiononce is most
useful when the grouping structure of the TeX code could be anything.
Neither this nor the other hook macros do global assignments to the hook
variable itself, so TeX's usual grouping rules apply.
The companion macro to defining hook actions is \hookrun, for
running them. This takes a single argument, the name of the hook. If
no actions for the hook are defined, no error ensues.
Here is a skeleton of general \begin and \end macros that
run hooks, and a couple of calls to define actions. The use of
\hookprepend for the begin action and \hookappend for the
end action ensures that the actions are executed in proper sequence with
other actions (as long as the other actions use \hookprepend and
\hookappend also).
\def\begin#1{ ... \hookrun{begin} ... }
\def\end#1{ ... \hookrun{end} ... }
\hookprepend{begin}\start_underline
\hookappend{end}\finish_underline
A property is a name/value pair associated with another symbol, traditionally called an atom. Both atom and property names are control sequence names.
Eplain provides two macros for dealing with property lists:
\setproperty and \getproperty.
\setproperty atom propname value
\setproperty defines the property property on the atom
atom to be value. atom and propname can be
anything acceptable to \csname. value can be anything.
\getproperty atom propname
\getproperty expands to the value stored for propname on
atom. If propname is undefined, it expands to nothing
(i.e., \empty).
The idea of properties originated in Lisp (I believe). There, the implementation truly does associate properties with atoms. In TeX, where we have no builtin support for properties, the association is only conceptual.
The following example typesets `xyz'.
\setproperty{a}{pr}{xyz}
\getproperty{a}{pr}
\expandonce
\expandonce is defined as \expandafter\noexpand. Thus,
\expandonce token expands token once, instead of to
TeX primitives. This is most useful in an \edef.
For example, the following defines \temp to be \foo, not
`abc'.
\def\foo{abc}
\def\bar{\foo}
\edef\temp{\expandonce\bar}
\ifundefined
\ifundefined{cs} t \else f \fi expands the
t text if the control sequence \cs is undefined or
has been \let to \relax, and the f text otherwise.
Since \ifundefined is not a primitive conditional, it cannot be
used in places where TeX might skip tokens "at high speed", e.g.,
within another conditional---TeX can't match up the \if's and
\fi's.
This macro was taken directly from The TeXbook, page 308.
\futurenonspacelet
The \futurelet primitive allows you to look at the next token
from the input. Sometimes, though, you want to look ahead ignoring any
spaces. This is what \futurenonspacelet does. It is otherwise
the same as \futurelet: you give it two control sequences as
arguments, and it assigns the next nonspace token to the first, and then
expands the second. For example:
\futurenonspacelet\temp\finishup
\def\finishup{\ifx\temp ...}
\obeywhitespace makes both end-of-lines and space characters in
the input be respected in the output. Unlike plain TeX's
\obeyspaces, even spaces at the beginnings of lines turn into
blank space.
By default, the size of the space that is produced by a space
character is the natural space of the current font, i.e.,
what \ produces.
Ordinarily, a blank line in the input produces as much blank vertical
space as a line of text would occupy. You can adjust this by assigning
to the parameter \blanklineskipamount:
if you set this negative, the space produced by a blank line will be
smaller; if positive, larger.
Tabs are not affected by this routine. In particular, if tabs occur at the beginning of a line, they will disappear. (If you are trying to make TeX do the "right thing" with tabs, don't. Use a utility program like expand instead.)
\numbername
produces the written-out form of its argument, i.e., `zero' through
`ten' for the numbers 0--10, and numerals for all others.
TeX's built-in \penalty command simply appends to the
current list, no matter what kind of list it is. You might intend a
particular penalty to always be a "vertical" penalty, however, i.e.,
appended to a vertical list. Therefore, Eplain provides
\vpenalty
and \hpenalty
which first leave the other mode and then do \penalty.
More precisely, \vpenalty inserts \par if the current
mode is horizontal, and \hpenalty inserts \leavevmode if
the current mode is vertical. (Thus, \vpenalty cannot be used in
math mode.)
It is common to write some information out to a file to be used on a
subsequent run. But when it is time to read the file again, you only
want to do so if the file actually exists. \testfileexistence
is given an argument which is appended to \jobname,
and sets the conditional \iffileexists
appropriately.
For example:
\testfileexistence{toc}%
\iffileexists
\input \jobname.toc
\fi