summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/fontinst/base/ficommon.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/fontinst/base/ficommon.dtx')
-rw-r--r--Master/texmf-dist/source/fontinst/base/ficommon.dtx2415
1 files changed, 2415 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/fontinst/base/ficommon.dtx b/Master/texmf-dist/source/fontinst/base/ficommon.dtx
new file mode 100644
index 00000000000..3127c25cbe5
--- /dev/null
+++ b/Master/texmf-dist/source/fontinst/base/ficommon.dtx
@@ -0,0 +1,2415 @@
+% \CheckSum{2283}
+% \iffalse meta-comment
+%
+% Copyright 1993, 1994, 1995, 1996 Alan Jeffrey,
+% hacked and maintained 1997, 1998 Sebastian Rahtz,
+% copyright 1998, 1999, 2000, 2001 the fontinst maintenance team and
+% any individual authors listed elsewhere in this file.
+% All rights reserved.
+%
+% This file is part of the fontinst system version 1.9.
+% -----------------------------------------------------
+%
+% It may be distributed under the terms of the LaTeX Project Public
+% License, as described in lppl.txt in the base LaTeX distribution.
+% Either version 1.2 or, at your option, any later version.
+%
+%%% From file: ficommon.dtx
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{fisource}
+\title{The \package{fontinst} utility}
+\author{Alan Jeffrey, Sebastian Rahtz, Ulrik Vieth, Lars Hellstr\"om}
+\begin{document}
+\maketitle
+\tableofcontents
+\DocInput{ficommon.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \StopEventually{}
+%
+%
+% \section{General commands}
+% \changes{1.916}{2000/12/27}{Moved Section \thesection\ to
+% \texttt{ficommon.dtx}. (LH)}
+%
+% \changes{1.916}{2001/01/02}{\emph{Major} overhaul of \package{fontdoc}
+% mechanisms for integer and string expressions completed. (LH)}
+% There are roughly five types of arguments that \package{fontinst}
+% commands can take. These are
+% \begin{itemize}
+% \item integer expressions,
+% \item string expressions,
+% \item dimensions,
+% \item commands (i.e., \TeX\ control sequences), and
+% \item other (pretty much ``none of the above'').
+% \end{itemize}
+% The most common form of an integer expression is simply a \TeX\
+% \meta{number} and the most common form of a string expression is
+% simply a sequence of character tokens, but there are more complicated
+% forms. Dimensions are simply \TeX\ \meta{dimen}s; their use is rather
+% limited. Common to integer expressions, string expressions, and
+% dimensions is that these argument types get expanded during
+% evaluation (in the case of string expressions, this expansion
+% \emph{is} the evaluation), which means one can use macros in
+% arguments of these types.
+%
+% Command arguments do not get expanded---they are mainly used with
+% commands that modify the definitions of other commands. As for the
+% ``other'' arguments one cannot give any rules: they might get
+% expanded, but it could also happen that they won't.
+%
+%
+% \subsection{String expressions}
+%
+% The first problem with string expressions is to typeset the values.
+% The character strings that appear in ETX and MTX files usually consist
+% only of immediately printable characters, but there are a few
+% characters (such as underscore) which may be used even though they
+% aren't directly printable. This subsection defines commands which deal
+% with this problem by replacing non-printable characters by commands.
+% The implementation is based on the implementation of the
+% |\MakeHarmless| command in the \package{xdoc} package.
+%
+% \subsubsection{Typesetting problematic characters}
+%
+% \begin{macro}{\PrintChar}
+% \begin{macro}{\InvisibleCharPrefix}
+% \begin{macro}{\InvisibleCharSuffix}
+% The |\PrintChar| command has the syntax
+% \begin{quote}
+% |\PrintChar|\marg{8-bit number}
+% \end{quote}
+% where \meta{8-bit number} is a \TeX\ number in the range 0--255.
+% For arguments in the range 0--31, |\PrintChar| prints
+% `\textit{\ttfamily\string^\string^@}'--`\textit{\ttfamily
+% \string^\string^_}'. For an argument in the range 32--126,
+% |\PrintChar| calls |\Print|\-|Visible|\-|Char| which typesets the
+% corresponding ASCII character (similar to |\char|, but it takes the
+% path via the \LaTeX\ internal representation so that it works with
+% non-typewriter \texttt{OT1} fonts); in particular, |\PrintChar{32}|
+% prints a ``visible space'' character. |\PrintChar{127}| prints
+% `\textit{\ttfamily\string^\string^?}'. For arguments in the range
+% 128--255, |\PrintChar| prints
+% `\textit{\ttfamily\string^\string^80}'--`\textit{\ttfamily
+% \string^\string^ff}'.
+% The |\PrintChar| command is robust.
+%
+% The macros |\InvisibleCharPrefix| and |\InvisibleCharSuffix| begin
+% and end a |^^|-sequence. |\InvisibleCharPrefix| should print the
+% actual |^^|, but it may also for example select a new font for
+% the |^^|-sequence (such font changes are restored at the end of
+% |\PrintChar|).
+% \begin{macrocode}
+%<*doc>
+\DeclareRobustCommand\PrintChar[1]{%
+ \leavevmode
+ \begingroup
+ \count@=#1\relax
+ \ifnum \@xxxii>\count@
+ \advance \count@ 64%
+ \InvisibleCharPrefix
+ \PrintVisibleChar\count@
+ \InvisibleCharSuffix
+ \else\ifnum 127>\count@
+ \PrintVisibleChar\count@
+ \else
+ \InvisibleCharPrefix
+ \ifnum 127=\count@ \PrintVisibleChar{63}\else
+ \@tempcnta=\count@
+ \divide \count@ \sixt@@n
+ \@tempcntb=\count@
+ \multiply \count@ \sixt@@n
+ \advance \@tempcnta -\count@
+ \advance \@tempcntb \ifnum 9<\@tempcntb 87\else 48\fi
+ \advance \@tempcnta \ifnum 9<\@tempcnta 87\else 48\fi
+ \char\@tempcntb \char\@tempcnta
+ \fi
+ \InvisibleCharSuffix
+ \fi\fi
+ \endgroup
+}
+% \end{macrocode}
+% \begin{macrocode}
+\newcommand\InvisibleCharPrefix{%
+ \/\em
+ \PrintVisibleChar{`\^}\PrintVisibleChar{`\^}%
+}
+\newcommand\InvisibleCharSuffix{\/}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\PrintVisibleChar}
+% The |\PrintVisibleChar| command should print the visible ASCII
+% character whose character code is given in the argument. The
+% definition given here translates every character code to the
+% corresponding \LaTeX\ internal representation, which is necessary
+% if the current font is e.g.\ an \texttt{OT1}-encoded non-typewriter
+% font. If the current font is known to be \texttt{T1}-encoded then
+% one can do just as well with |\char#1 | as the replacement text.
+% \begin{macrocode}
+\newcommand\PrintVisibleChar[1]{%
+ \ifcase #1%
+ \or\or\or\or\or\or\or\or \or\or\or\or\or\or\or\or
+ \or\or\or\or\or\or\or\or \or\or\or\or\or\or\or\or
+ % "20
+ \textvisiblespace \or!\or\textquotedbl \or\#\or\textdollar
+ \or\%\or\&\or\textquoteright\or(\or)\or*\or+\or,\or-\or.\or/%
+ \or % "30
+ 0\or1\or2\or3\or4\or5\or6\or7\or8\or9\or:\or;\or
+ \textless\or=\or\textgreater\or?%
+ \or % "40
+ @\or A\or B\or C\or D\or E\or F\or G\or
+ H\or I\or J\or K\or L\or M\or N\or O%
+ \or % "50
+ P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z\or [\or
+ \textbackslash \or]\or\textasciicircum \or\textunderscore
+ \or % "60
+ \textquoteleft \or a\or b\or c\or d\or e\or f\or g\or h\or
+ i\or j\or k\or l\or m\or n\or o%
+ \or % "70
+ p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z\or
+ \textbraceleft \or\textbar \or\textbraceright \or\textasciitilde
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\textvisiblespace}
+% The |\textvisiblespace| command, which is heavily used in names of
+% coding schemes, unfortunately has a default definition which lacks
+% leading on the right side. This redefinition attempts to improve
+% things.
+% \changes{1.921}{2002/03/27}{Redefinition added. (LH)}
+% \begin{macrocode}
+\DeclareTextCommandDefault{\textvisiblespace}{%
+ \makebox[\fontdimen\tw@\font]{%
+ \hfil
+ \vrule \@height.3ex%
+ \vbox{\hrule \@width .66\fontdimen\tw@\font}%
+ \vrule \@height.3ex%
+ \hfil
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\FD@quoted@PrintChar}
+% One sometimes wants to use a printable character string as part of a
+% control sequence name. If the normal definition of |\PrintChar| is
+% in force at such times then each |\PrintChar| in the string would
+% produce lots of errors, which is why |\FD@quoted@PrintChar| has
+% been defined. This macro is an alternative definition of
+% |\PrintChar| which expands to |"|\meta{number}|"|, which can be part
+% of a macro name.
+% \begin{macrocode}
+\def\FD@quoted@PrintChar#1{"\number#1"}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Converting character strings}
+%
+% Replacing all problematic characters with |\PrintChar| calls certainly
+% makes the strings easier to manage, but actually making those
+% replacements is a rather complicated task. This subsubsection
+% contains the macros necessary for doing these replacements.
+%
+% The first problem is how to efficiently recognise the problematic
+% characters. One might think that it is sufficient to look at their
+% |\catcode|, but that will fail for characters like |<| whose normal
+% catcode is 12 but do not appear in the \texttt{OT1} encoding. Because
+% of this, I have chosen a brute strength solution: build a table
+% (indexed by character code) that gives the printable form of
+% every character. This table is stored in the
+% \describecsfamily{FD@printable@\meta{code}}^^A
+% |\FD@printable@|\meta{code} family of control sequences, where the
+% \meta{code} is in the range |32|--|126|. The printable form of
+% characters outside this range is always the |\PrintChar| form.
+% \begin{macrocode}
+\count@=32
+\begingroup
+ \catcode\z@=12\relax
+ \@firstofone{%
+\endgroup
+ \loop
+ \if \ifnum 11=\catcode\count@ 1\else \ifnum 12=\catcode\count@
+ 1\else 0\fi\fi 1%
+ \uccode\z@=\count@
+ \uppercase{\def\@tempa{^^@}}%
+ \else
+ \edef\@tempa{\noexpand\PrintChar{\the\count@}}%
+ \fi
+ \x@cs\let{FD@printable@\the\count@}=\@tempa
+ \advance \count@ \@ne
+ \ifnum 127>\count@ \repeat
+}
+% \end{macrocode}
+% This loop hasn't caught all non-printable characters, so a few
+% entries have to be set explicitly.
+% \begin{macrocode}
+\@namedef{FD@printable@34}{\PrintChar{34}} % "
+\@namedef{FD@printable@60}{\PrintChar{60}} % <
+\@namedef{FD@printable@62}{\PrintChar{62}} % >
+% \end{macrocode}
+%
+%
+% \begin{macro}{\MakePrintable}
+% To render a character string harmless, you do
+% \begin{quote}
+% |\MakePrintable|\marg{macro}\marg{flag}\marg{string}
+% \end{quote}
+% This locally assigns to \meta{macro} the printable character string
+% which corresponds to \meta{string}. Furthermore the control sequence
+% |\if|\meta{flag} is locally let to |\iftrue| or |\iffalse|
+% depending on whether the printable string is simple (only consists
+% of character tokens and |\PrintChar| commands) or not.
+%
+% During the conversion the converted part of the string is stored in
+% |\toks@| and the |@tempswa| switch keeps track of whether the string
+% so far is simple (yes when |false|), but those are both local to
+% |\MakePrintable|.
+% \begin{macrocode}
+\def\MakePrintable#1#2#3{%
+ \begingroup
+ \toks@={}%
+ \escapechar=`\\%
+ \@tempswafalse
+ \FD@printable@#3\protect\FD@printable@
+ \toks@=\expandafter{%
+ \expandafter\let \csname if#2\expandafter\endcsname
+ \csname if\if@tempswa false\else true\fi \expandafter\endcsname
+ \expandafter\def \expandafter#1\expandafter{\the\toks@}%
+ }%
+ \expandafter\endgroup \the\toks@
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\FD@printable@iii}
+% \begin{macro}{\FD@printable@iv}
+% \begin{macro}{\FD@printable@v}
+% \begin{macro}{\FD@printable@vi}
+% What one has to be most careful about when making strings printable
+% are the space tokens, since many of \TeX's primitives gladly
+% snatches an extra space (or more) where you don't want them to in
+% this case. Macro parameters can be particularly dangerous, as \TeX\
+% will skip any number of spaces while looking for the replacement
+% text for an undelimited macro argument. Therefore the algorithm for
+% rendering a character token harmless consists begins
+% (|\FD@printable@iii|) with |\string|ing the next token in the
+% string---this preserves the character code and sets the category to
+% 12 for all characters except the ASCII space, which gets category 10
+% (space)---and then |\futurelet| is used to peek at the next token. If
+% it is a space token (|\FD@printable@iv|) then the character code
+% is 32 and the actual space can be gobbled (|\FD@printable@v|), and
+% if it isn't then the next token can be grabbed in a undelimited macro
+% argument (|\FD@printable@vi|). In either case, the harmless form
+% is given by the |\FD@printable@|\meta{code} table entry
+% (in |\FD@printable@v| or |\FD@printable@vi|).
+% \begin{macrocode}
+\def\FD@printable@iii{%
+ \expandafter\futurelet \expandafter\@let@token
+ \expandafter\FD@printable@iv \string
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\FD@printable@iv{%
+ \ifx \@let@token\@sptoken
+ \expandafter\FD@printable@v
+ \else
+ \expandafter\FD@printable@vi
+ \fi
+}
+% \end{macrocode}
+% ^^A Hack:
+% \begingroup
+% \expandafter\def \expandafter\MakePrivateLetters \expandafter{^^A
+% \MakePrivateLetters
+% \catcode`3=11
+% \catcode`2=11
+% }
+% \begin{macrocode}
+\begingroup
+ \catcode`3=\catcode`a
+ \catcode`2=\catcode`a
+ \@firstofone{\gdef\FD@printable@v} {%
+ \toks@=\expandafter{\the \expandafter\toks@ \FD@printable@32}%
+ \FD@printable@
+ }
+\endgroup
+% \end{macrocode}
+% \endgroup
+% \begin{macrocode}
+\def\FD@printable@vi#1{%
+ \if \ifnum `#1<\@xxxii 1\else \ifnum `#1>126 1\else 0\fi\fi 1%
+ \toks@=\expandafter{\the\expandafter\toks@
+ \expandafter\PrintChar \expandafter{\number`#1}%
+ }%
+ \else
+ \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@
+ \csname FD@printable@\number`#1\endcsname}%
+ \fi
+ \FD@printable@
+}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\FD@printable@}
+% \begin{macro}{\FD@printable@i}
+% \begin{macro}{\FD@printable@ii}
+% \begin{macro}{\FD@printable@vii}
+% But that is not all |\MakePrintable| can do. One must also deal
+% with things in the string that are not simply characters, but more
+% complex items (for example |\str| and |\strint| constructions). When
+% control sequences that start such complex items are fed to
+% |\MakePrintable| they must be preceeded by a |\protect| (they will
+% be if the original command is defined using \LaTeX's
+% |\Declare|\-|Robust|\-|Command| command and the string has been fed
+% through a |\protected@edef|, which happens to be the case); this
+% |\protect| is taken as a signal that the next token should get
+% special processing. Control sequences that are not preceeded by a
+% |\protect| are simply |\string|ed.
+%
+% To accommodate for this, |\FD@printable@| (which is the first step
+% in converting a token) always begins by checking (in |\FD@|\-^^A
+% |printable@i|) whether the next token is a control sequence. If it
+% is and that control sequence is |\protect| then it is checked (in
+% |\FD@printable@ii|) whether the control sequence
+% \describecsfamily{FD@printable\PrintChar{`\\}\meta{cs-name}}^^A
+% |\FD@printable\|\meta{cs-name}, where \meta{cs-name} is the name
+% without |\| (and with any spaces removed) of the control sequence
+% encountered, is defined. If it is defined then control is handed
+% over to |\FD@printable\|\meta{cs-name} which should process the
+% arguments (if any) of |\|\meta{cs-name} and add a suitable
+% representation to |\toks@|, but if |\FD@printable\|\meta{cs-name}
+% isn't defined then this is considered to be an error.
+%
+% If the next token isn't a control sequence then control is handed
+% over to |\FD@printable@ii|. If the next token is a control sequence
+% but not |\protect| then that token is |\string|ed (in
+% |\FD@printable@vii|) and control is handed over to
+% |\FD@printable@vi|.
+% \begin{macrocode}
+\def\FD@printable@{\futurelet\@let@token \FD@printable@i}
+% \end{macrocode}
+% \begin{macrocode}
+\def\FD@printable@i{%
+ \csname FD@printable@%
+ \ifcat \noexpand\@let@token \noexpand\FD@printable@
+ \ifx \@let@token\protect ii\else vii\fi
+ \else iii\fi
+ \endcsname
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\FD@printable@ii\protect#1{%
+ \@ifundefined{FD@printable\expandafter\zap@space\string#1 \@empty}{%
+ \PackageError{fontdoc}{Command \protect#1 not allowed in string}%
+ \@eha
+ }{\csname FD@printable\expandafter\zap@space\string#1 \@empty
+ \endcsname}%
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\FD@printable@vii{\expandafter\FD@printable@vi \string}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\FD@printable\FD@printable@}
+% A control sequence |\FD@printable\|\meta{cs-name} is responsible for
+% interpreting the string item that begins with the control sequence
+% |\|\meta{cs-name} and appending a printable representation of it to
+% |\toks@|. Normal |\FD@printable\|\meta{cs-name} control sequences
+% must also end by inserting |\FD@printable@| in front of what remains
+% of the string after the complex string item has been removed. This
+% sees to that the rest of the string is also made printable. The only
+% such control sequence which does not insert |\FD@printable@| is
+% |\FD@printable\FD@printable@|, but that is as it should be since
+% |\MakePrintable| itself appends a |\FD@printable@| to every character
+% string it should convert to mark the end of it.
+% \begin{macrocode}
+\expandafter\let
+ \csname FD@printable\string\FD@printable@\endcsname \@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\FD@printable\PrintChar}
+% It is occasionally convenient to use a |\PrintChar| command as part
+% of a string that is to be made harmless instead of using the raw
+% character. The definition is very similar to that of
+% |\FD@printable@vi|.
+% \begin{macrocode}
+\@namedef{FD@printable\string\PrintChar}#1{%
+ \if \ifnum #1<\@xxxii 1\else \ifnum #1>126 1\else 0\fi\fi 1%
+ \toks@=\expandafter{\the\expandafter\toks@
+ \expandafter\PrintChar \expandafter{\number#1}%
+ }%
+ \else
+ \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@
+ \csname FD@printable@\number#1\endcsname}%
+ \fi
+ \FD@printable@
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\ExpandAndMakePrintable}
+% The |\ExpandAndMakePrintable| command is an abbreviation for a
+% common use of |\MakePrintable|, namely to first feed the string
+% through a |\protected@edef| to get rid of all the simple macros.
+% \begin{macrocode}
+\newcommand*\ExpandAndMakePrintable[3]{%
+ \protected@edef\@tempa{{#2}{#3}}%
+ \expandafter\MakePrintable \expandafter#1\@tempa
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Evaluating string expressions}
+%
+% In string expressions, the only available operation is juxtaposition
+% (fancy name for putting things next to each other) and thus the
+% syntax for a string expression is
+% \begin{quote}
+% \meta{string expression} \(\longrightarrow\) $\emptyset \mid$
+% \meta{string atom}\meta{string expression}
+% \end{quote}
+% where $\emptyset$ denotes the empty string. A \meta{string atom} is
+% one of
+% \begin{quote}
+% \meta{character token}\\
+% |\str|\marg{string expression}\\
+% |\strint|\marg{string expression}
+% \end{quote}
+% The meaning of a \meta{character token} is explained
+% in~\cite{TeXbook}. The |\str| and |\strint| forms of
+% \marg{string atom} refer to the respective values of the string and
+% integer variables (see Subsection~\ref{Ssec:Variables}) whose names
+% are given in the argument of |\str| or |\strint| respectively. Since
+% the names of variables are themselves string expressions, |\str| and
+% |\strint| may themselves be used in names of variables.
+%
+% It should be noted that most of \package{fontinst}'s string
+% expressions sooner or later end up between a |\csname| and the
+% corresponding |\endcsname|. This places significant restrictions on
+% what may occur in string expressions.
+%
+% \begin{macro}{\str}
+% \begin{macro}{\strint}
+% \changes{1.909}{1999/10/19}{Change to stop it from gobbling a
+% following space if the integer is stored in a macro. (LH)}
+% In \package{fontinst} the only macros needed for dealing with string
+% expressions are |\str| and |\strint|.
+% \begin{macrocode}
+%<*pkg>
+\def\str#1{\csname~s-#1\endcsname}
+\def\strint#1{\expandafter\identity_one\expandafter{\number\int{#1}}}
+%</pkg>
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \package{fontdoc} mainly uses \TeX's text mode for typesetting string
+% expressions because not all characters are available in math mode;
+% it's easier to switch to text mode than to augment the math setup. One
+% kind of material is however typeset in math mode, namely
+% ``string-valued functions'': the name and functional parenthesis of
+% such material is typeset in math mode to get a mathematical look.
+%
+% \begin{macro}{\FD@string@func}
+% The |\FD@string@func| macro has the syntax
+% \begin{quote}
+% |\FD@string@func|\marg{name}\marg{argument}
+% \end{quote}
+% It is used for typesetting the \meta{name}$($\meta{argument}$)$ of a
+% string-valued function (e.g.\ the value-of-string-variable function
+% $\mathrm{s}$). It should only be used in horizontal mode.
+%
+% |\FD@string@func| includes a bit of extra spacing around the typeset
+% text, but not at the beginning or end of a string and neither
+% between two string-valued functions. As a flag for this is used
+% that the value of |\spacefactor| is 1; when it is one should proceed
+% as if this extra spacing is already present.
+% \begin{macrocode}
+%<*doc>
+\def\FD@string@func#1#2{%
+ \relax
+ \ifnum \spacefactor=\@ne $\mkern1mu\else$\fi
+ \mathrm{#1}($%
+ #2%
+ \ifnum \spacefactor=\@ne $\mkern-1mu\else $\fi)\mkern1mu$%
+ \spacefactor=\@ne
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\TypesetStringExpression}
+% \begin{macro}{\FD@typeset@string}
+% \begin{macro}{\ifFD@swa}
+% In \package{fontdoc} the string expressions must be typeset, and
+% that is not trivial due to that (i) not all character tokens have
+% catcode 11 or 12 and (ii) not all characters are available in all
+% fonts. Furthermore the non-character string atoms should be given
+% special treatment in character strings!
+%
+% Because of this, string expressions that are to be typeset are
+% handed to a special command |\TypesetStringExpression|, which takes
+% the string to typeset as its only argument. This string may contain
+% user-defined macros.
+% \begin{macrocode}
+\newcommand\TypesetStringExpression[1]{%
+ \protected@edef\@tempa{%
+ \noexpand\MakePrintable \noexpand\@tempa {FD@swa}{#1}%
+ }%
+ \@tempa
+ \FD@typeset@string{\@tempa}%
+}
+% \end{macrocode}
+% Actually typesetting the string is handled in |\FD@typeset@string|,
+% but strings handed to this macro must be preprocessed by a full
+% protected expansion and a |\MakeHarmless|.
+% \begin{macrocode}
+\def\FD@typeset@string#1{%
+ \mbox{%
+ \normalfont\ttfamily
+ \spacefactor=\@ne
+ #1%
+ \ifnum \spacefactor=\@ne $\mkern-1mu\m@th$\fi
+ }%
+}
+% \end{macrocode}
+% The |\ifFD@swa| control sequence is often |\let| to |\iftrue| or
+% |\iffalse| by |\Make|\-|Printable|, and then it is used as a
+% conditional. Since that assignment sometimes takes place in
+% conditional text however, one must make sure that |\ifFD@swa|
+% always is some conditional.
+% \begin{macrocode}
+\let\ifFD@swa\iffalse
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\str}
+% \begin{macro}{\FD@printable\str}
+% The processing of the |\str| macro in \package{fontdoc} is far from
+% straightforward. |\str| has to be robust, but apart from that its
+% defintion has no effect on how its argument is processed. That is
+% instead controlled by |\FD@printable\str|, which happens to use
+% |\str| as an auxiliary formatting macro.
+%
+% Most of the complexity below is however due to the processing
+% needed to determine whether the string variable accessed has been
+% assigned a value. See |\Set|\-|String|\-|Variable| for more
+% information.
+% \begin{macrocode}
+\DeclareRobustCommand\str[1]{\FD@string@func{s}{#1}}
+\@namedef{FD@printable\string\str}#1{%
+ \MakePrintable\@tempa{FD@swa}{#1}%
+ \begingroup
+ \let\PrintChar=\FD@quoted@PrintChar
+ \if \ifFD@swa \@ifundefined{FD@s-\@tempa}{0}{1}\else 0\fi 1%
+ \expandafter
+ \endgroup
+ \csname FD@s-\@tempa\endcsname
+ \else
+ \endgroup
+ \toks@=\expandafter{\the\expandafter\toks@
+ \expandafter\str \expandafter{\@tempa}}%
+ \@tempswatrue
+ \fi
+ \FD@printable@
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+%
+% \begin{macro}{\strint}
+% \begin{macro}{\FD@printable\strint}
+% |\strint| is handled similarly to |\str|.
+% \begin{macrocode}
+\DeclareRobustCommand\strint[1]{\FD@string@func{int}{#1}}
+\@namedef{FD@printable\string\strint}#1{%
+ \MakePrintable\@tempa{FD@swa}{#1}%
+ \protected@edef\@tempa{%
+ \ifFD@swa \protect\FD@simple@int \else \strint \fi{\@tempa}%
+ }
+ \toks@=\expandafter{\the\expandafter\toks@ \@tempa}%
+ \@tempswatrue
+ \FD@printable@
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\macroparameter}
+% \changes{1.916}{2001/01/06}{Command added. (LH)}
+% \begin{macro}{\FD@printable\macroparameter}
+% The |\macroparameter| command can be used in string and integer
+% expressions as a sort of ``macro parameter placeholder''. It is not
+% defined in \package{fontinst}, but in \package{fontdoc} one
+% occationally writes comments which say things like ``XXX is short
+% for ASDFSKADN'', and in those cases one can use |\macroparameter|
+% as a placeholder for an argument. The syntax is
+% \begin{quote}
+% |\macroparameter|\marg{digit}
+% \end{quote}
+% where \meta{digit} should be a decimal digit between |1| and |9|
+% inclusive.
+%
+% The definition in |\macroparameter| handles uses of the command in
+% integer expressions, whereas |\FD@printable\macroparameter| takes
+% care of uses in string expressions.
+% \begin{macrocode}
+\DeclareRobustCommand\macroparameter[1]{%
+ \gdef\FD@expression{\text{\normalfont\itshape\##1}}%
+ \global\chardef\FD@priority=5%
+ \global\FD@bracket@level=\z@
+ \FD@evaluate@false
+}
+\@namedef{FD@printable\string\macroparameter}#1{%
+ \toks@=\expandafter{\the\toks@\textrm{\emph{\##1}}}%
+ \@tempswatrue
+ \FD@printable@
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+%
+%
+% \subsection{Integer expressions}
+%
+% An \meta{integer expression} is one of the following:
+% \begin{quote}
+% \meta{number}\\
+% |\int|\marg{string expression}\\
+% |\neg|\marg{integer expression}\\
+% |\add|\marg{integer expression}\marg{integer expression}\\
+% |\sub|\marg{integer expression}\marg{integer expression}\\
+% |\max|\marg{integer expression}\marg{integer expression}\\
+% |\min|\marg{integer expression}\marg{integer expression}\\
+% |\mul|\marg{integer expression}\marg{integer expression}\\
+% |\div|\marg{integer expression}\marg{integer expression}\\
+% |\half|\marg{integer expression}\\
+% |\otherhalf|\marg{integer expression}\\
+% |\scale|\marg{integer expression}\marg{integer expression}\\
+% |\width|\marg{string expression}\\
+% |\height|\marg{string expression}\\
+% |\depth|\marg{string expression}\\
+% |\italic|\marg{string expression}\\
+% |\kerning|\marg{string expression}\marg{string expression}
+% \end{quote}
+% \meta{number} is any \TeX\ number, as defined in~\cite{TeXbook}. The
+% \meta{string expression} in the argument of |\int| must be the name of
+% an integer variable which is currently set, i.e., the condition
+% \begin{quote}
+% |\ifisint|\marg{string expression}|\then|
+% \end{quote}
+% must evaluate to true. Likewise the \meta{string expression} in the
+% argument of |\width|, |\height|, |\depth|, and |\italic| must be the
+% name of a glyph which is currently set, i.e., the condition
+% \begin{quote}
+% |\ifisglyph|\marg{string expression}|\then|
+% \end{quote}
+% must evaluate to true.
+%
+% \begin{macro}{\eval_expr}
+% \begin{macro}{\eval_expr_to}
+% \begin{macro}{\g_eval_expr_to}
+% \begin{macro}{\result}
+% The only thing \package{fontinst} does with integer expressions is
+% evaluating them. The macro
+% \begin{quote}
+% |\eval_expr|\marg{integer expression}
+% \end{quote}
+% globally assigns |\result| to the value of
+% \meta{integer expression}, and changes the value of no other
+% counters.
+%
+% The macro
+% \begin{quote}
+% |\eval_expr_to|\marg{\TeX\ integer variable}^^A
+% \marg{integer expression}
+% \end{quote}
+% locally assigns the value of \meta{integer expression} to
+% \meta{\TeX\ integer variable} (which is an integer variable as
+% defined in~\cite{TeXbook}).
+% |\g_eval_expr_to| does the same globally.
+%
+% \begin{macrocode}
+%<*pkg>
+\newcount\result
+\def\eval_expr#1{\global\result=#1\x_relax}
+\def\eval_expr_to#1#2{\eval_expr{#2}#1=\result}
+\def\g_eval_expr_to#1#2{\eval_expr{#2}\global#1=\result}
+%</pkg>
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+%
+%
+% \begin{macro}{\TypesetIntegerExpression}
+% In \package{fontdoc} the main task is instead to typeset the
+% expression as a mathematical formula, but in some cases one wants to
+% know its value as well (if possible). Therefore things get a bit
+% more complex in that context. The top-level command there is
+% \begin{quote}
+% |\TypesetIntegerExpression|\marg{integer expression}
+% \end{quote}
+% which typesets the \meta{integer expression} by first forming (in the
+% |\FD@expression| macro) code for typesetting the integer expression.
+% |\Typeset|\-|Integer|\-|Expression| should be only be used in math
+% mode.
+%
+% Most of the work in |\TypesetIntegerExpression| is carried out by
+% the |\FD@eval@expr| macro and hence |\TypesetIntegerExpression| sets
+% a couple of other variables as explained below. Apart from the fact
+% that |\FD@eval@expr| doesn't actually typeset anything, the main
+% difference between it and |\Typeset|\-|Integer|\-|Expression| is that
+% the latter also accepts code that after expansion will become integer
+% expressions, whereas the former requires that all such macros have
+% first been expanded.
+% \begin{macrocode}
+%<*doc>
+\newcommand\TypesetIntegerExpression[1]{%
+ \protected@edef\@tempa{#1}%
+ \expandafter\FD@eval@expr \expandafter{\@tempa}%
+ \FD@expression
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\FD@expression}
+% \begin{macro}{\FD@result}
+% \begin{macro}{\FD@priority}
+% \begin{macro}{\FD@bracket@level}
+% \begin{switch}{FD@evaluate@}
+% The |\FD@expression| macro, |\FD@result| and |\FD@bracket@level|
+% count registers, the |\FD@priority| chardef token, and the
+% |FD@evaluate@| switch are used by \package{fontdoc} when formatting
+% and evaluating an integer expression. They are all assigned globally.
+%
+% The |\FD@expression| macro contains code for typesetting an
+% expression. |\FD@priority| is a chardef token whose numerical value
+% specifies the priority of the outermost operation in
+% |\FD@expression| according to the following table:
+% \begin{enumerate}
+% \item[0]
+% Outermost operation is $+$ or $-$.
+% \item[1]
+% Outermost operation is explicit multiplication ($\cdot$) or
+% division $/$. If it is one of the factors in a product then
+% that multiplication must be explicit.
+% \item[2]
+% Outermost operation is explicit multiplication. If it is to be
+% the right factor in a product, then the multiplication must be
+% made explicit too.
+% \item[3]
+% Outermost operation is explicit multiplication. It
+% does not need to be explicitly multiplied.
+% \item[4]
+% Outermost operation is implicit multiplication (juxtaposition),
+% unary prefix (unary $-$) or something which is bracketed anyway.
+% If it is to be the right factor in a product, then that
+% multiplication should be made explicit too. A typical example
+% of this kind of thing is an explicit negative number.
+% \item[5]
+% Outermost operation is implicit multiplication (juxtaposition)
+% or something which is bracketed anyway. It does not need to be
+% explicitly multiplied.
+% \item[6]
+% The expression is an explicit non-negative number. If it is to
+% be the right factor in a product, then the multiplication
+% should be made explicit.
+% \end{enumerate}
+% |\FD@bracket@level| keeps track of what parenthesis size one must
+% use to cover the expression in |\FD@expression|: 0 is the normal
+% size, 1 is |\big| size, 2 is |\Big| size, etc. The |FD@evaluate@|
+% switch specifies whether |\FD@eval@expr| should try to (upon entry)
+% or managed to (after it is completed) evaluate the integer
+% expression (true is evaluate, false is don't bother). When the value
+% has been evaluated, it is returned in |\FD@result|.
+% \begin{macrocode}
+\newcount\FD@result
+\newcount\FD@bracket@level
+\def\FD@evaluate@true{\global\let\ifFD@evaluate@\iftrue}
+\def\FD@evaluate@false{\global\let\ifFD@evaluate@\iffalse}
+\FD@evaluate@false
+% \end{macrocode}
+% \end{switch}\end{macro}\end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\FD@eval@expr}
+% The |\FD@eval@expr| macro has the syntax
+% \begin{quote}
+% |\FD@eval@expr|\marg{integer expression}
+% \end{quote}
+% It puts code for typesetting the \meta{integer expression} in the
+% |\FD@expression| macro, sets |\FD@bracket@level| to the
+% corresponding value, and if |FD@evaluate@| is true it also tries to
+% evaluate the expression and put the result in |\FD@result|.
+%
+% More precisely, |\FD@eval@expr| only handles the \meta{\TeX~number}
+% cases of integer expression. In the other cases the first token in
+% the integer expression is a robust command which should take care of
+% building the expression as needed.
+% \begin{macrocode}
+\def\FD@eval@expr#1{%
+ \expandafter\expandafter \expandafter\ifx
+ \expandafter\@car#1\x@relax\@nil \protect
+ #1%
+ \else\ifcat \expandafter\noexpand \@car#1\x@relax\@nil 0%
+ \global\FD@result=#1\x@relax
+ \xdef\FD@expression{\the\FD@result}%
+ \global\chardef\FD@priority=\ifnum \FD@result<\z@ 4\else 6\fi
+ \global\FD@bracket@level=\z@
+ \else
+ \begingroup
+ \MakePrintable\@tempa{FD@swa}{#1}%
+ \global\FD@bracket@level=\ifFD@swa\z@\else\@ne\fi
+ \protected@xdef\FD@expression{\protect\mbox{\texttt{\@tempa}}}%
+ \endgroup
+ \global\chardef\FD@priority=5%
+ \FD@evaluate@false
+ \fi\fi
+}
+%</doc>
+% \end{macrocode}
+% Note: It is important that all groups that are started or ended
+% during the evaluation of an integer expression are of |\begingroup|
+% type, since |\bgroup| groups affect spacing in math mode.
+% \end{macro}
+%
+% \begin{macro}{\add}
+% The |\add| command has the syntax
+% \begin{quote}
+% |\add|\marg{integer expression}\marg{integer expression}
+% \end{quote}
+% It represents the sum of the two \meta{integer expression}s.
+% \begin{macrocode}
+%<*pkg>
+\def\add#1#2{
+ #1
+ \bgroup
+ \a_count=\result
+ \eval_expr{#2}
+ \global\advance \result \a_count
+ \egroup
+}
+%</pkg>
+%<*doc>
+\DeclareRobustCommand\add[2]{%
+ \begingroup
+ \FD@eval@expr{#1}%
+ \let\@tempa=\FD@expression
+ \ifFD@evaluate@ \a@count=\FD@result \fi
+ \b@count=\FD@bracket@level
+ \FD@eval@expr{#2}%
+ \protected@xdef\FD@expression{\@tempa+\FD@expression}%
+ \ifFD@evaluate@ \global\advance \FD@result \a@count \fi
+ \ifnum \FD@bracket@level<\b@count
+ \global\FD@bracket@level=\b@count
+ \fi
+ \global\chardef\FD@priority=\z@
+ \endgroup
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sub}
+% The |\sub| command has the syntax
+% \begin{quote}
+% |\sub|\marg{integer expression}\marg{integer expression}
+% \end{quote}
+% It represents the difference between the two \meta{integer
+% expression}s.
+% \begin{macrocode}
+%<*pkg>
+\def\sub#1#2{
+ #1
+ \bgroup
+ \a_count=\result
+ \eval_expr{#2}
+ \advance \a_count -\result
+ \global\result=\a_count
+ \egroup
+}
+%</pkg>
+%<*doc>
+\DeclareRobustCommand\sub[2]{%
+ \begingroup
+ \FD@eval@expr{#1}%
+ \let\@tempa=\FD@expression
+ \ifFD@evaluate@ \a@count=\FD@result \fi
+ \b@count=\FD@bracket@level
+ \FD@eval@expr{#2}%
+ \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
+ \protected@xdef\FD@expression{\@tempa-\FD@expression}%
+ \ifFD@evaluate@
+ \advance \a@count -\FD@result
+ \global\FD@result=\a@count
+ \fi
+ \ifnum \FD@bracket@level<\b@count
+ \global\FD@bracket@level=\b@count
+ \fi
+ \global\chardef\FD@priority=\z@
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\FD@subexpression}
+% \begin{macro}{\FD@commapenalty}
+% The |\FD@subexpression| macro has the syntax
+% \begin{quote}
+% |\FD@subexpression|\marg{math mode material}
+% \end{quote}
+% It should only be used in math mode and produces results very
+% similar to \meta{math mode material}, but it locally increases all
+% the math-related penalties by |\FD@commapenalty| for when the math
+% mode material is converted to a horizontal list. This allows
+% linebreaking to take notice of logical nesting in expressions.
+%
+% |\FD@commapenalty| is used as a companion of |\relpenalty| and
+% |\binoppenalty|, but which is used after commas (where \TeX\ doesn't
+% insert penalties automatically).
+% \begin{macrocode}
+\def\FD@subexpression#1{${%
+ \advance \binoppenalty \FD@commapenalty
+ \advance \relpenalty \FD@commapenalty
+ \advance \FD@commapenalty \FD@commapenalty
+ $#1$}$%
+}
+\newcount\FD@commapenalty
+\FD@commapenalty=\binoppenalty
+\advance \FD@commapenalty \relpenalty
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\FD@bracket@expression}
+% The |\FD@bracket@expression| brackets the expression currently in
+% |\FD@expression| by the suitable size of parentheses and updates
+% |\FD@bracket@level| and |\FD@priority| accordingly.
+% \begin{macrocode}
+\def\FD@bracket@expression{%
+ \protected@xdef\FD@expression{%
+ \ifcase\FD@bracket@level \or \protect\bigl \or \protect\Bigl \or
+ \protect\biggl \else \protect\Biggl \fi (%
+ \protect\FD@subexpression{\FD@expression}%
+ \ifcase\FD@bracket@level \or \protect\bigr \or \protect\Bigr \or
+ \protect\biggr \else \protect\Biggr \fi )%
+ }%
+ \global\chardef\FD@priority=5%
+ \global\advance \FD@bracket@level \@ne
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\int}
+% \changes{1.909}{1999/10/19}{\package{fontdoc} implementation
+% changed to using \cs{typeset@integer}. (LH)}
+% \begin{macro}{\FD@simple@int}
+% The |\int| command has the syntax
+% \begin{quote}
+% |\int|\marg{string expression}
+% \end{quote}
+% It is used to represent the value of the \package{fontinst} integer
+% whose name is the value of the \meta{string expression} in integer
+% expressions.
+%
+% The |\FD@simple@int| macro take the printable string form of the
+% name of an integer variable as its argument and typesets the
+% printed representation of this integer, but it should only be used
+% when the argument is a simple string expression. When the argument
+% is not a simple string expression, |\FD@integer@func| should be
+% used instead. |\FD@simple@int| should only be called in horizontal
+% mode.
+% \begin{macrocode}
+%<pkg>\def\int#1{\csname i-#1 \endcsname}
+%<*doc>
+\DeclareRobustCommand\int[1]{%
+ \begingroup
+ \MakePrintable\@tempa{FD@swa}{#1}%
+ \protected@xdef\FD@expression{%
+ \ifFD@swa
+ \text{\protect\FD@simple@int{\@tempa}}%
+ \else
+ \protect\FD@integer@func{int}{\@tempa}%
+ \fi
+ }%
+ \global\chardef\FD@priority=5%
+ \global\FD@bracket@level=\ifFD@swa\z@\else\@ne\fi
+ \FD@evaluate@false
+ \endgroup
+}
+\def\FD@simple@int#1{{\normalfont\itshape #1\/}}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\FD@integer@func}
+% The |\FD@integer@func| macro has the syntax
+% \begin{quote}
+% |\FD@integer@func|\marg{name}\marg{argument}
+% \end{quote}
+% It is used for typesetting the \meta{name}$($\meta{argument}$)$
+% of an integer-valued function which takes a string expression as
+% argument (e.g.\ the width-of-glyph function $\mathrm{w}$). It
+% should only be used in math mode.
+%
+% The empty group in the argument of |\mathop| is there to ensure
+% that the nucleus of the mathop atom isn't simply a symbol, since
+% \TeX\ in that case centers it vertically.
+% \begin{macrocode}
+\def\FD@integer@func#1#2{%
+ \mathop{\mathrm{#1}{}}(\text{\FD@typeset@string{#2}})%
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\neg}
+% The |\neg| command has the syntax
+% \begin{quote}
+% |\neg|\marg{integer expression}
+% \end{quote}
+% It represents the negative of the \meta{integer expression}.
+% \begin{macrocode}
+%<pkg>\def\neg#1{#1 \global\result=-\result}
+%<*doc>
+\DeclareRobustCommand\neg[1]{%
+ \FD@eval@expr{#1}%
+ \ifnum 5>\FD@priority \FD@bracket@expression \fi
+ \protected@xdef\FD@expression{-\FD@expression}%
+ \global\chardef\FD@priority=4%
+ \ifFD@evaluate@ \global\FD@result=-\FD@result \fi
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\mul}
+% The |\mul| command has the syntax
+% \begin{quote}
+% |\mul|\marg{integer expression}\marg{integer expression}
+% \end{quote}
+% It represents the product of the two \meta{integer expression}s.
+% \begin{macrocode}
+%<*pkg>
+\def\mul#1#2{
+ #1
+ \bgroup
+ \a_count=\result
+ \eval_expr{#2}
+ \global\multiply \result \a_count
+ \egroup
+}
+%</pkg>
+% \end{macrocode}
+%
+% The main problem in the \package{fontdoc} definition of |\mul| is
+% to determine whether the multiplication should be made explicit or
+% not, and what priority code the resulting expression should be
+% given. It turns out that if the right factor has priority 1 (it is
+% a quotient or a product that ends with a quotient) then the
+% combined expression will be too, whereas if it isn't but the left
+% factor has priority 1 then the combined expression will get
+% priority 2. The remaining cases will be explicit or implicit
+% depending on the parity of the priority of the right expression, and
+% priority will be odd or even depending on the parity of the priority
+% of the left expression.
+% \begin{macrocode}
+%<*doc>
+\DeclareRobustCommand\mul[2]{%
+ \begingroup
+ \FD@eval@expr{#1}%
+ \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
+ \let\@tempa=\FD@expression
+ \ifFD@evaluate@ \a@count=\FD@result \fi
+ \b@count=\FD@bracket@level
+ \let\FD@left@priority=\FD@priority
+ \FD@eval@expr{#2}%
+ \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
+ \protected@xdef\FD@expression{%
+ \@tempa
+ \if \ifnum \FD@left@priority=\@ne e%
+ \else\ifnum \FD@priority<\thr@@ e%
+ \else\ifodd \FD@priority i\else e\fi\fi\fi e%
+ \cdot
+ \fi
+ \FD@expression
+ }%
+ \ifFD@evaluate@ \global\multiply \FD@result \a@count \fi
+ \ifnum \FD@bracket@level<\b@count
+ \global\FD@bracket@level=\b@count
+ \fi
+ \a@count=%
+ \ifnum \FD@priority=\@ne 1%
+ \else\ifnum \FD@left@priority=\@ne 2%
+ \else\ifodd\FD@left@priority
+ \ifodd\FD@priority 5\else 3\fi
+ \else
+ \ifodd\FD@priority 4\else 2\fi
+ \fi\fi\fi
+ \global\chardef\FD@priority=\a@count
+ \endgroup
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\div}
+% The |\div| command has the syntax
+% \begin{quote}
+% |\div|\marg{integer expression}\marg{integer expression}
+% \end{quote}
+% It represents the quotient of the two \meta{integer expression}s, as
+% computed by \TeX's |\divide| command: non-integer quotients are
+% rounded towards zero.
+% \begin{macrocode}
+%<*pkg>
+\def\div#1#2{
+ #1
+ \bgroup
+ \a_count=\result
+ \eval_expr{#2}
+ \divide \a_count \result
+ \global\result=\a_count
+ \egroup
+}
+%</pkg>
+%<*doc>
+\DeclareRobustCommand\div[2]{%
+ \begingroup
+ \FD@eval@expr{#1}%
+ \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
+ \let\@tempa=\FD@expression
+ \ifFD@evaluate@ \a@count=\FD@result \fi
+ \b@count=\FD@bracket@level
+ \FD@eval@expr{#2}%
+ \ifnum 4>\FD@priority \FD@bracket@expression \fi
+ \ifnum \FD@bracket@level<\b@count
+ \global\FD@bracket@level=\b@count
+ \fi
+ \protected@xdef\FD@expression{%
+ \@tempa
+ \ifcase\FD@bracket@level \or \protect\big \or \protect\Big \or
+ \protect\bigg \else \protect\Bigg \fi /%
+ \FD@expression
+ }%
+ \ifFD@evaluate@
+ \divide \a@count \FD@result
+ \global\FD@result=\a@count
+ \fi
+ \global\chardef\FD@priority=\@ne
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\FD@eval@spec@expr}
+% The |\FD@eval@spec@expr| macro has the syntax
+% \begin{isyntax}
+% |\FD@eval@spec@expr|\marg{integer expression}^^A
+% \discretionary{}{}{}\marg{spec-command}^^A
+% \discretionary{}{}{}\marg{rep-command}
+% \end{isyntax}
+% It does pretty much the same thing as |\FD@eval@expr|, but if the
+% first token in the \meta{integer expression} is the
+% \meta{spec-command} then it will do
+% \begin{quote}
+% \meta{rep-command}\meta{integer expression}
+% \end{quote}
+% instead of the normal activities. This is useful for operations that
+% are normally denoted as $n$-ary operations rather that binary ones,
+% i.e., for |\max| and |\min|.
+% \begin{macrocode}
+\def\FD@eval@spec@expr#1#2#3{%
+ \expandafter\ifx \@car#1\x@relax\@nil #2%
+ #3#1%
+ \else
+ \FD@eval@expr{#1}%
+ \fi
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\max}
+% The |\max| command has the syntax
+% \begin{quote}
+% |\max|\marg{integer expression}\marg{integer expression}
+% \end{quote}
+% It represents the maximum of the two \meta{integer expression}s.
+% \begin{macrocode}
+%<*pkg>
+\def\max#1#2{
+ #1
+ \bgroup
+ \a_count=\result
+ \eval_expr{#2}
+ \ifnum \a_count>\result \global\result=\a_count \fi
+ \egroup
+}
+%</pkg>
+%<*doc>
+\DeclareRobustCommand\max[2]{%
+ \begingroup
+ \toks@={}%
+ \a@count=-\maxdimen
+ \b@count=\z@
+ \FD@eval@spec@expr{\max{#1}{#2}}{\max}{\FD@maxmin@comma}%
+ \ifnum \a@count>\FD@bracket@level
+ \global\FD@bracket@level=\a@count
+ \fi
+ \protected@xdef\FD@expression{%
+ \protect\plainmax
+ \ifcase\FD@bracket@level \protect\@firstofone \or \protect\bigl
+ \or \protect\Bigl \or \protect\biggl \else \protect\Biggl
+ \fi{\{}%
+ \the\toks@
+ \protect\FD@subexpression{\FD@expression}%
+ \ifcase\FD@bracket@level \protect\@firstofone \or \protect\bigl
+ \or \protect\Bigl \or \protect\biggl \else \protect\Biggl
+ \fi{\}}%
+ }%
+ \ifFD@evaluate@
+ \ifnum \a@count>\FD@result \global\FD@result=\a@count \fi
+ \fi
+ \global\chardef\FD@priority=5%
+ \global\advance \FD@bracket@level \@ne
+ \endgroup
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\min}
+% The |\min| command has the syntax
+% \begin{quote}
+% |\min|\marg{integer expression}\marg{integer expression}
+% \end{quote}
+% It represents the minimum of the two \meta{integer expression}s.
+% \begin{macrocode}
+%<*pkg>
+\def\min#1#2{
+ #1
+ \bgroup
+ \a_count=\result
+ \eval_expr{#2}
+ \ifnum \a_count<\result \global\result=\a_count \fi
+ \egroup
+}
+%</pkg>
+%<*doc>
+\DeclareRobustCommand\min[2]{%
+ \begingroup
+ \toks@={}%
+ \a@count=\maxdimen
+ \b@count=\z@
+ \FD@eval@spec@expr{\min{#1}{#2}}{\min}{\FD@maxmin@comma}%
+ \ifnum \a@count>\FD@bracket@level
+ \global\FD@bracket@level=\a@count
+ \fi
+ \protected@xdef\FD@expression{%
+ \protect\plainmin
+ \ifcase\FD@bracket@level \protect\@firstofone \or \protect\bigl
+ \or \protect\Bigl \or \protect\biggl \else \protect\Biggl
+ \fi{\{}%
+ \the\toks@
+ \protect\FD@subexpression{\FD@expression}%
+ \ifcase\FD@bracket@level \protect\@firstofone \or \protect\bigl
+ \or \protect\Bigl \or \protect\biggl \else \protect\Biggl
+ \fi{\}}%
+ }%
+ \ifFD@evaluate@
+ \ifnum \a@count<\FD@result \global\FD@result=\a@count \fi
+ \fi
+ \global\chardef\FD@priority=5%
+ \global\advance \FD@bracket@level \@ne
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\FD@maxmin@comma}
+% The |\FD@maxmin@comma| macro does most of the work for |\max| and
+% |\min| in \package{fontdoc}. In some sense it inserts the commas
+% between the operands, but it also takes care of evaluating the
+% maximum\slash minimum and determining the proper bracketing level.
+%
+% The sequence of arguments (separated by commas) is compiled in
+% |\toks@|. The greatest\slash least value of an argument found so
+% far is kept in |\a@count|, and the greatest bracketing level found
+% is kept in |\b@count|.
+% \begin{macrocode}
+\def\FD@maxmin@comma#1#2#3{%
+ \FD@eval@spec@expr{#2}{#1}{\FD@maxmin@comma}%
+ \toks@=\expandafter{\the\expandafter\toks@
+ \expandafter\protect \expandafter\FD@subexpression
+ \expandafter{\FD@expression}%
+ ,\penalty\FD@commapenalty\,%
+ }
+ \ifFD@evaluate@
+ \ifnum \a@count \ifx\max#1<\else>\fi \FD@result
+ \a@count=\FD@result
+ \fi
+ \fi
+ \ifnum \b@count<\FD@bracket@level \b@count=\FD@bracket@level \fi
+ \FD@eval@spec@expr{#3}{#1}{\FD@maxmin@comma}%
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\half}
+% \begin{macro}{\otherhalf}
+% \multchanges{\cs{half}\cs{otherhalf}}{1.916}{2000/12/31}{Macros
+% added. (LH)}
+% The |\half| and |\otherhalf| macros have the syntaxes
+% \begin{quote}
+% |\half|\marg{integer expression}\\
+% |\otherhalf|\marg{integer expression}
+% \end{quote}
+% They both represent one half of the \meta{integer expression}, but
+% they don't round it the same way. |\half| does rounding as
+% specified in~\cite[p.~237]{TAOCP2} (towards even integers) whereas
+% |\otherhalf| does it the other way (towards odd integers). This
+% means that
+% \begin{quote}
+% |\add{\half{|\meta{IE}|}}{\otherhalf{|\meta{IE}|}}|
+% \end{quote}
+% will always sum up to precisely the same as the \meta{IE} integer
+% expression.
+% \begin{macrocode}
+%<*pkg>
+\def\half#1{
+ #1\x_relax
+ \ifodd\result
+ \global\advance \result \@ne
+ \global\divide \result \tw@
+ \ifodd\result \global\advance \result \m@ne \fi
+ \else
+ \global\divide \result \tw@
+ \fi
+}
+\def\otherhalf#1{
+ #1\x_relax
+ \ifodd\result
+ \global\advance \result \@ne
+ \global\divide \result \tw@
+ \ifodd\result \else \global\advance \result \m@ne \fi
+ \else
+ \global\divide \result \tw@
+ \fi
+}
+%</pkg>
+%<*doc>
+\DeclareRobustCommand\half[1]{%
+ \begingroup
+ \FD@eval@expr{#1}%
+ \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
+ \a@count=%
+ \ifnum \FD@priority=\@ne 1%
+ \else\ifodd\FD@priority 5%
+ \else 3\fi\fi
+ \global\chardef\FD@priority=\a@count
+ \protected@xdef\FD@expression{%
+ \protect\frac{1}{2}%
+ \ifnum \FD@priority>\thr@@ \else \cdot \fi
+ \FD@expression
+ }%
+ \ifFD@evaluate@
+ \ifodd \FD@result
+ \global\advance \FD@result \@ne
+ \global\divide \FD@result \tw@
+ \ifodd\FD@result \global\advance \FD@result \m@ne \fi
+ \else
+ \global\divide \FD@result \tw@
+ \fi
+ \fi
+ \endgroup
+}
+\DeclareRobustCommand\otherhalf[1]{%
+ \begingroup
+ \FD@eval@expr{#1}%
+ \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
+ \a@count=%
+ \ifnum \FD@priority=\@ne 1%
+ \else\ifodd\FD@priority 5%
+ \else 3\fi\fi
+ \global\chardef\FD@priority=\a@count
+ \protected@xdef\FD@expression{%
+ \protect\frac{1}{2}%
+ \ifnum \FD@priority>\thr@@ \else \cdot \fi
+ \FD@expression
+ }%
+ \ifFD@evaluate@
+ \ifodd \FD@result
+ \global\advance \FD@result \@ne
+ \global\divide \FD@result \tw@
+ \ifodd\FD@result\else \global\advance \FD@result \m@ne \fi
+ \else
+ \global\divide \FD@result \tw@
+ \fi
+ \fi
+ \endgroup
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\scale}
+% The |\scale| command has the syntax
+% \begin{quote}
+% |\scale|\marg{integer expression}\marg{integer expression}
+% \end{quote}
+% It represents the result of multiplying the first \meta{integer
+% expression} by as many thousands as is specified by the second
+% \meta{integer expression}. In practice, |\scale|\marg{ie1}\marg{ie2}
+% is very similar to
+% \begin{quote}
+% |\div{\mul|\marg{ie1}\marg{ie2}|}{1000}|
+% \end{quote}
+% but |\scale| also tries to do proper rounding (note however that
+% |\scale|ing by 500 is not rounded properly; use |\half| instead).
+% \begin{macrocode}
+%<*pkg>
+\def\scale#1#2{
+ #1
+ \bgroup
+ \a_count=\result
+ \eval_expr{#2}
+ \global\multiply \result \a_count
+ \rounded_thousandths
+ \egroup
+}
+%</pkg>
+% \end{macrocode}
+%
+% The second (scaling factor) argument of |\scale| is usually very
+% simple, and in that case the |\scale| will be formatted as a
+% fraction (containing the second argument) multiplied by the first
+% argument.
+% \begin{macrocode}
+%<*doc>
+\DeclareRobustCommand\scale[2]{%
+ \begingroup
+ \FD@eval@expr{#1}%
+ \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
+ \let\@tempa=\FD@expression
+ \ifFD@evaluate@ \a@count=\FD@result \fi
+ \b@count=\FD@bracket@level
+ \let\FD@left@priority=\FD@priority
+ \FD@eval@expr{#2}%
+ \if \ifnum \FD@bracket@level<\@ne \ifnum \FD@priority>\thr@@
+ 1\else 0\fi\else 0\fi 1%
+ \protected@xdef\FD@expression{%
+ \protect\frac{\FD@expression}{1000}%
+ \if \ifnum \FD@left@priority<\thr@@ e\else
+ \ifodd \FD@left@priority i\else e\fi\fi e%
+ \cdot
+ \fi
+ \@tempa
+ }
+ \global\chardef\FD@priority=%
+ \ifnum \FD@left@priority=\@ne 1\else
+ \ifodd\FD@left@priority 5\else 3\fi\fi
+ \global\FD@bracket@level=\b@count
+ \else
+ \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
+ \protected@xdef\FD@expression{%
+ \@tempa
+ \if \ifnum \FD@left@priority=\@ne e%
+ \else\ifnum \FD@priority<\thr@@ e%
+ \else\ifodd \FD@priority i\else e\fi\fi\fi e%
+ \cdot
+ \fi
+ \FD@expression
+ \ifcase\FD@bracket@level \or \protect\big \or \protect\Big
+ \or \protect\bigg \else \protect\Bigg \fi /1000%
+ }%
+ \ifnum \FD@bracket@level<\b@count
+ \global\FD@bracket@level=\b@count
+ \fi
+ \global\chardef\FD@priority=\@ne
+ \fi
+ \ifFD@evaluate@
+ \global\multiply \FD@result \a@count
+ \global\divide \FD@result 500
+ \ifodd \FD@result
+ \global\advance \FD@result \ifnum 0>\FD@result - \fi \@ne
+ \fi
+ \global\divide \FD@result \tw@
+ \fi
+ \endgroup
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\rounded_thousandths}
+% \changes{1.901}{1999/03/06}{Macro added. \cs{scale} changed to
+% use it. (LH)}
+% \begin{macro}{\l_rounded_thousandths}
+% The |\rounded_thousandths| macro divides |\result|
+% by 1000 and rounds the result to the nearest integer. This is
+% different from
+% \begin{quote}
+% |\global\divide \result \one_thousand|
+% \end{quote}
+% since the latter always rounds positive numbers downwards and
+% negative numbers upwards.
+%
+% |\l_rounded_thousandths| does the same thing, but to the register
+% passed as parameter \#1 and is assigned locally.
+% \changes{1.913}{2000/03/04}{Macro added. (LH)}
+% \begin{macrocode}
+%<*pkg>
+\def\rounded_thousandths{
+ \global\divide \result \five_hundred
+ \ifodd \result
+ \global\advance \result by \ifnum 0>\result - \fi 1
+ \fi
+ \global\divide \result \tw@
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\l_rounded_thousandths#1{
+ \divide #1 \five_hundred
+ \ifodd #1
+ \advance #1 by \ifnum 0>#1 - \fi\@ne
+ \fi
+ \divide #1 \tw@
+}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\l_inv_scale}
+% \changes{1.913}{2000/03/11}{Macro added. (LH)}
+% The |\l_inv_scale| takes two arguments: as \#1 a count register,
+% and as \#2 a \TeX\ number. |\l_inv_scale| scales \#1 by the inverse
+% of \#2, if the value in \#1 is $n$ and the value in \#2 is $m$ then
+% |\l_inv_scale| computes
+% $$
+% \left[ \frac{1000n}{m} \right] \mbox{,}
+% $$
+% where the brackets denote rounding to the nearest integer, and
+% assigns this number to \#1 locally.
+% \begin{macrocode}
+\def\l_inv_scale#1#2{
+ \multiply #1 \two_thousand
+ \divide #1 #2\x_relax
+ \ifodd#1 \advance #1 \ifnum 0>#1 - \fi\@ne \fi
+ \divide #1 \tw@
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \multchanges{\cs{priority}}{1.909}{1999/10/20}{Changed condition for
+% \cs{ifnum}, so that expressions with equal priority will not get
+% bracketed when nested. (LH)}
+% \multchanges{\cs{expression}\cs{priority}\cs{identity}^^A
+% \cs{bracket}}{1.916}{2001/01/01}{Macros removed. (LH)}
+%
+% \begin{macro}{\ifnumber}
+% \changes{1.900}{1999/02/15}{Command added. (LH)}
+% The call
+% \begin{quote}
+% |\ifnumber|\marg{integer expression}\meta{rel}^^A
+% \marg{integer expression}|\then|
+% \end{quote}
+% can be used to compare the two integer expressions. \meta{rel} may
+% be |<|, |=|, or |>|.
+% \begin{macrocode}
+\def\ifnumber#1#2#3\then{
+ \eval_expr_to\a_count{#1}
+ \eval_expr{#3}
+ \ifnum \a_count#2\result
+ \expandafter\if_true
+ \else
+ \expandafter\if_false
+ \fi
+}
+%</pkg>
+% \end{macrocode}
+%
+% Like the other conditionals, |\ifnumber| is treated as being true by
+% \package{fontdoc}.
+% \begin{macrocode}
+%<*doc>
+\def\ifnumber#1#2#3\then{%
+ \FD@evaluate@false
+ \generic@if{%
+ $\TypesetIntegerExpression{#1}#2\TypesetIntegerExpression{#3}$%
+ }%
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+
+
+% \subsection{Setting variables}
+% \label{Ssec:Variables}
+%
+% \meta{int}, \meta{str}, and \meta{dim} below are string expressions.
+% \meta{command} can be any control sequence.
+%
+% \DescribeMacro{\setint}
+% \DescribeMacro{\setstr}
+% \DescribeMacro{\setdim}
+% \DescribeMacro{\setcommand}
+% The macros:
+% \begin{quote}
+% |\setint|\marg{int}\marg{integer expression}\\
+% |\setstr|\marg{str}\marg{string}\\
+% |\setdim|\marg{dim}\marg{dimension}\\
+% |\setcommand|\meta{command}\meta{definition}
+% \end{quote}
+% define new macros
+% \describecsfamily{i-\meta{int}}|\i-|\meta{int},
+% \describecsfamily{s-\meta{str}}|\s-|\meta{str},
+% \describecsfamily{d-\meta{dim}}|\d-|\meta{dim}, or
+% \meta{command}.
+%
+% \DescribeMacro{\resetint}
+% \DescribeMacro{\resetstr}
+% \DescribeMacro{\resetdim}
+% \DescribeMacro{\resetcommand}
+% The macros:
+% \begin{quote}
+% |\resetint|\marg{int}\marg{integer expression}\\
+% |\resetstr|\marg{str}\marg{string}\\
+% |\resetdim|\marg{dim}\marg{dimension}\\
+% |\resetcommand|\meta{command}\meta{definition}
+% \end{quote}
+% redefine the macros |\i-|\meta{int}, |\s-|\meta{str}, |\d-|\meta{dim} or
+% \meta{command}.
+%
+% \DescribeMacro{\int}
+% \DescribeMacro{\str}
+% \DescribeMacro{\dim}
+% The macros:
+% \begin{quote}
+% |\int|\marg{int}\\
+% |\str|\marg{str}\\
+% |\dim|\marg{dim}\\
+% \meta{command}
+% \end{quote}
+% return the values of |\i-|\meta{int}, |\s-|\meta{str}, |\d-|\meta{dim},
+% or \meta{command}.
+%
+% \DescribeMacro{\strint}
+% The macro
+% \begin{quote}
+% |\strint|\marg{int}
+% \end{quote}
+% returns the value of |\i-|\meta{int} as a string.
+%
+% \DescribeMacro{\ifisint}
+% \DescribeMacro{\ifisstr}
+% \DescribeMacro{\ifisdim}
+% \DescribeMacro{\ifiscommand}
+% The macros:
+% \begin{quote}
+% |\ifisint|\marg{int}|\then|\\
+% |\ifisstr|\marg{str}|\then|\\
+% |\ifisdim|\marg{dim}|\then|\\
+% |\ifiscommand|\meta{command}|\then|
+% \end{quote}
+% return |\if_true| if |\i-|\meta{int}, |\s-|\meta{str},
+% |\d-|\meta{dim}, or \meta{command} respectively have been defined,
+% and |\if_false| otherwise.
+%
+% \DescribeMacro{\unsetint}
+% \DescribeMacro{\unsetstr}
+% \DescribeMacro{\unsetdim}
+% \DescribeMacro{\unsetcommand}
+% The macros:
+% \begin{quote}
+% |\unsetint|\marg{int}\\
+% |\unsetstr|\marg{str}\\
+% |\unsetdim|\marg{dim}\\
+% |\unsetcommand|\meta{command}
+% \end{quote}
+% undefine |\i-|\meta{int}, |\s-|\meta{str}, |\d-|\meta{dim}, or
+% \meta{command}.
+%
+% \DescribeMacro{\x_setint}
+% \DescribeMacro{\x_resetint}
+% \DescribeMacro{\x_setstr}
+% The macros |\x_setint|, |\x_resetint|, and |\x_setstr| are ``private''
+% versions of |\setint|, |\resetint|, and |\setstr| respectively. They
+% have been included to reduce the problems in case a user turns off one
+% of these commands and forgets to turn it on again.
+%
+% \changes{1.900}{1999/02/07}{Replaced internal \cs{setint},
+% \cs{resetint}, and \cs{setstr} by \cs{x_setint}, \cs{x_resetint},
+% and \cs{x_setstr} respectively, to make the public versions
+% possible to turn off. (LH)}
+%
+% Integers are kept as |\mathchardef|s if possible; a comparision of
+% doing this versus not doing this appears in
+% Subsection~\ref{Ssec: ASAJ tests}.
+%
+% \begin{macro}{\setsomething_global}
+% The |\setsomething_global| control sequence should be either
+% |\relax| or |\global|. It appears before the central assignments in
+% all the |\set|\textellipsis, |\reset|\textellipsis, and
+% |\unset|\textellipsis\ commands. The normal value is |\relax|, so
+% that these assignments are local.
+%
+% When there is counter-intuitive grouping, and it could seem that
+% \TeX\ should not be inside a group at all---i.e., between
+% |\installfonts| and |\endinstallfonts|---one can make the basic
+% assignment commands act more logical by setting
+% |\setsomething_global| to |\global|.
+%
+% \changes{1.912}{2000/01/15}{Control sequence introduced and added
+% to all \cs{set}\dots, \cs{reset}\dots, and \cs{unset}\dots\
+% commands, as well as \cs{offcommand} and \cs{oncommand}. (LH)}
+% \begin{macrocode}
+%<*pkg>
+\let\setsomething_global=\x_relax
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\x_setint}
+% \begin{macro}{\setint}
+% \begin{macro}{\x_setstr}
+% \begin{macro}{\setstr}
+% \begin{macro}{\setdim}
+% \begin{macro}{\setcommand}
+% \changes{1.909}{1999/10/17}{Since \package{fontdoc} adds some
+% grouping, \cs{setcommand} must set its argument globally there.
+% (LH)}
+% \changes{1.912}{2000/01/15}{Settings of a command already defined
+% is diverted to \cs{a_macro}; it used to be \cs{a_command}. Saves
+% one hash table position. (LH)}
+%
+% \begin{macrocode}
+\def\x_setint#1#2{
+ \x_cs\ifx{i-#1}\x_relax
+ \x_resetint{#1}{#2}
+ \fi
+}
+\let\setint=\x_setint
+\def\x_setstr#1#2{
+ \x_cs\ifx{s-#1}\x_relax
+ \setsomething_global\x_cs\edef{s-#1}{#2}
+ \fi
+}
+\let\setstr=\x_setstr
+\def\setdim#1#2{
+ \x_cs\ifx{d-#1}\x_relax
+ \a_dimen=#2\x_relax
+ \setsomething_global\x_cs\edef{d-#1}{\the\a_dimen}
+ \fi
+}
+\def\setcommand#1{
+ \ifx#1\undefined_command
+ \setsomething_global \expandafter\def \expandafter#1
+ \else
+ \expandafter\def \expandafter\a_macro
+ \fi
+}
+%</pkg>
+% \end{macrocode}
+%
+% In \package{fontdoc}, |\setint|, |\setstr|, and |\setdim| print
+% headings. There is no need for the private forms |\x_setint| and
+% |\x_setstr|. |\setcommand|, finally, does the same thing as in
+% \package{fontinst}; the assignment is global because of grouping
+% not present in \package{fontinst}.
+% \begin{macrocode}
+%<*doc>
+\newcommand\setint[2]{%
+ \Bheading{Default} \(\TypesetIntegerExpression{\int{#1}}\) =
+ \(\TypesetIntegerExpression{#2}\)%
+}
+\newcommand\setstr[2]{%
+ \Bheading{Default} \TypesetStringExpression{\str{#1}} =
+ \TypesetStringExpression{#2}%
+}
+\newcommand\setdim[2]{%
+ \a@dimen=#2\relax
+ \Bheading{Default} \TypesetStringExpression{#1} dimen = \the\a@dimen
+}
+\def\setcommand#1{\ifx#1\undefined@command
+ \expandafter\gdef\expandafter#1\else
+ \expandafter\gdef\expandafter\a@command\fi}
+%</doc>
+% \end{macrocode}
+% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\x_resetint}
+% \begin{macro}{\resetint}
+% \begin{macro}{\resetstr}
+% \begin{macro}{\resetdim}
+% \begin{macro}{\resetcommand}
+% \changes{1.909}{1999/10/17}{Since \package{fontdoc} adds some
+% grouping, \cs{resetcommand} must set its argument globally there.
+% (LH)}
+% \begin{macrocode}
+%<*pkg>
+\def\x_resetint#1#2{
+ \eval_expr{#2}
+ \setsomething_global
+ \ifnum\result<\max_mathchardef
+ \ifnum 0>\result
+ \x_cs\edef{i-#1}{\the\result}
+ \else
+ \x_cs\mathchardef{i-#1}=\result
+ \fi
+ \else
+ \x_cs\edef{i-#1}{\the\result}
+ \fi
+}
+\let\resetint=\x_resetint
+\def\resetstr#1#2{\setsomething_global\x_cs\edef{s-#1}{#2}}
+\def\resetdim#1#2{
+ \a_dimen=#2
+ \setsomething_global\x_cs\edef{d-#1}{\the\a_dimen}
+}
+\def\resetcommand#1{\setsomething_global\def#1}
+%</pkg>
+% \end{macrocode}
+%
+% In \package{fontdoc}, |\resetint|, |\resetstr|, and |\resetdim|
+% print headings. There is no need for the private form |\x_resetint|.
+% |\resetcommand|, finally, does the same thing as in
+% \package{fontinst}.
+%
+% \begin{macrocode}
+%<*doc>
+\newcommand\resetint[2]{%
+ \Bheading{Value} \(\TypesetIntegerExpression{\int{#1}}\) =
+ \(\TypesetIntegerExpression{#2}\)%
+}
+\newcommand\resetstr[2]{%
+ \Bheading{Value} \TypesetStringExpression{\str{#1}} =
+ \TypesetStringExpression{#2}%
+}
+\newcommand\resetdim[2]{%
+ \a@dimen=#2\relax
+ \Bheading{Value} \TypesetStringExpression{#1} dimen = \the\a@dimen
+}
+\def\resetcommand#1{\gdef#1}
+%</doc>
+% \end{macrocode}
+% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
+%
+%
+% \begin{macro}{\dim}
+% \begin{macrocode}
+%<pkg>\def\dim#1{\csname~d-#1\endcsname}
+% \end{macrocode}
+% \missing{doc}{\dim}
+% \end{macro}
+%
+% \multchanges{\cs{typeset@integer}\cs{typeset@string}^^A
+% \cs{typeset@dimen}}{1.916}{2000/01/02}{Macros removed. (LH)}
+%
+% \begin{macro}{\ifisint}
+% \begin{macro}{\ifisstr}
+% \begin{macro}{\ifisdim}
+% \multchanges{\cs{ifisint}\cs{ifisstr}\cs{ifisdim}}{1.912}
+% {2000/02/10}{Reimplemented using \cs{if_defined}. (LH)}
+% \begin{macro}{\ifiscommand}
+% \begin{macrocode}
+%<*pkg>
+\def\ifisint#1\then{\if_defined i-#1\then}
+\def\ifisstr#1\then{\if_defined s-#1\then}
+\def\ifisdim#1\then{\if_defined d-#1\then}
+\def\ifiscommand#1\then{
+ \ifx#1\undefined_command
+ \expandafter\if_false
+ \else
+ \expandafter\if_true
+ \fi
+}
+%</pkg>
+% \end{macrocode}
+%
+% In \package{fontdoc}, all conditionals are handled through
+% |\generic@if|, which by default expands to |\iftrue|.
+% \changes{1.909}{1999/10/17}{Changed one fontdoc definition of
+% \cs{ifisglyph} to a definition of \cs{ifiscommand}, which was
+% missing from fontdoc.}
+% \begin{macrocode}
+%<*doc>
+\def\ifisint#1\then{%
+ \generic@if{integer $\TypesetIntegerExpression{\int{#1}}$ set}%
+}
+\def\ifisstr#1\then{%
+ \generic@if{string \TypesetStringExpression{#1} set}%
+}
+\def\ifisdim#1\then{%
+ \generic@if{dimension \TypesetStringExpression{#1} set}%
+}
+\def\ifiscommand#1\then{%
+ \generic@if{command \normalfont{\ttfamily\string#1} set}%
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\unsetint}
+% \begin{macro}{\unsetstr}
+% \begin{macro}{\unsetdim}
+% \begin{macro}{\unsetcommand}
+% \begin{macrocode}
+%<*pkg>
+\def\unsetint#1{\setsomething_global\x_cs\let{i-#1}\x_relax}
+\def\unsetstr#1{\setsomething_global\x_cs\let{s-#1}\x_relax}
+\def\unsetdim#1{\setsomething_global\x_cs\let{d-#1}\x_relax}
+\def\unsetcommand#1{\setsomething_global\let#1=\undefined_command}
+%</pkg>
+% \end{macrocode}
+% \missing{doc}{\unsetint}
+% \missing{doc}{\unsetstr}
+% \missing{doc}{\unsetdim}
+% \missing{doc}{\unsetcommand}
+% \begin{macrocode}
+%<*doc>
+%</doc>
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+%
+% \begin{macro}{\offcommand}
+% \begin{macro}{\oncommand}
+% \multchanges{\cs{offcommand}\cs{oncommand}}{1.900}{1999/02/07}
+% {Commands added. (LH)}
+% The calls
+% \begin{quote}
+% |\offcommand|\meta{command}\\
+% |\oncommand|\meta{command}
+% \end{quote}
+% can be used to turn a command off (make it simply absorb its
+% arguments but expand to nothing) or on (return it to normal)
+% respectively. Their primary use is for ignoring some of the
+% commands in \texttt{.mtx} files that \package{fontinst} generates
+% from \texttt{.afm}, \texttt{.pl}, or other \texttt{.mtx} files.
+%
+% \describecsfamily{saved-\meta{\textbackslash command}}
+% The normal definition of a command that has been turned off
+% is saved as the control sequence |\saved-|\meta{command}. If the
+% syntax of a command is tricky---not all arguments are read by the
+% base command or its parameter text contains tokens that are not
+% parameters---or if simply making it do nothing is not the expected
+% `off' behaviour, then the automatic off-turning may not work. In such
+% cases a handtooled off definition of the command \meta{command}
+% may be provided as the control sequence |\off-|\meta{command}.^^A
+% \describecsfamily{off-\meta{\textbackslash command}}
+%
+% Nothing happens if |\offcommand| is called for a command that is
+% not on. Nothing happens if |\oncommand| is called for a command
+% that is not off.
+% \begin{macrocode}
+%<*pkg>
+\def\offcommand#1{
+ \x_cs\ifx{saved-\string#1}\x_relax
+ \setsomething_global\x_cs\let{saved-\string#1}#1
+ \x_cs\ifx{off-\string#1}\x_relax
+ \generate_off_command{#1}
+ \else
+ \setsomething_global \expandafter\let \expandafter#1
+ \csname off-\string#1\endcsname
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\oncommand#1{
+ \x_cs\ifx{saved-\string#1}\x_relax \else
+ \setsomething_global \expandafter\let \expandafter#1
+ \csname saved-\string#1\endcsname
+ \setsomething_global\x_cs\let{saved-\string#1}\x_relax
+ \fi
+}
+%</pkg>
+% \end{macrocode}
+% \multchanges{\cs{offcommand}\cs{oncommand}}{1.914}{2000/05/28}
+% {\package{fontdoc} definitions added. (LH)}
+% \begin{macrocode}
+%<*doc>
+\def\offcommand#1{\Bheading{Turn off} \texttt{\string#1}}
+\def\oncommand#1{\Bheading{Turn on} \texttt{\string#1}}
+%</doc>
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\generate_off_command}
+% \begin{macro}{\count_hashes}
+% \begin{macro}{\gobble_to_xrelax}
+% |\generate_off_command|\meta{command} converts \meta{command} to
+% an ``off'' version of itself by counting the number of arguments
+% and defining it to gobble that many arguments. It cannot cope with
+% commands whose parameter texts are not simply of the type
+% \begin{quote}
+% |#1#2|\textellipsis|#|$n$
+% \end{quote}
+% \begin{macrocode}
+%<*pkg>
+\def\generate_off_command#1{
+ \a_count=0
+ \let\next=\count_hashes
+ \expandafter\next\meaning#1~->\x_relax
+ \b_count=0
+ \a_toks={}
+ \loop \ifnum \b_count<\a_count
+ \advance \b_count 1
+ \a_toks=\expandafter{\the\expandafter\a_toks \expandafter####
+ \the\b_count}
+ \repeat
+ \setsomething_global \expandafter\def \expandafter#1 \the\a_toks {}
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\count_hashes#1#2{
+ \if \hash_char#1
+ \advance \a_count 1
+ \else
+ \if -#1
+ \if >#2
+ \let\next=\gobble_to_xrelax
+ \fi\fi
+ \fi
+ \next#2
+}
+\def\gobble_to_xrelax#1\x_relax{}
+%</pkg>
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+%
+% Control sequences of the form
+% \begin{quote}
+% \describecsfamily{FD@s-\meta{name}}|\FD@s-|\meta{name}
+% \end{quote}
+% are used by \package{fontdoc} to store the values of string variables
+% which have been assigned values; \meta{name} is the name of the string
+% variable. Unlike the case in \package{fontinst}, the
+% \package{fontdoc} |\setstr| command does not assign values to string
+% variables, but |\SetStringVariable| does.
+%
+% The contents of the |\FD@s-|\meta{name} macros aren't really the
+% string values, but code that will append the printable form of the
+% corresponding string expression to |\toks@| and update other variables
+% used by |\MakePrintable| accordingly. Typically it might look
+% something like
+% \begin{quote}
+% |\toks@=\expandafter{\the\toks@ ab}|
+% \end{quote}
+% when the value of the string is |ab|.
+%
+% \begin{macro}{\SetStringVariable}
+% \changes{1.916}{2001/01/24}{Command added. (LH)}
+% The |\SetStringVariable| command has the syntax
+% \begin{quote}
+% |\SetStringVariable|\marg{variable name}\marg{new value}
+% \end{quote}
+% where \meta{variable name} and \meta{new value} are both string
+% expressions. The \meta{variable name} must furthermore be a simple
+% string expression. The command globally defines the corresponding
+% |\FD@s-|\meta{name} control sequence to add the printable form of
+% the \marg{new value} string to the |\toks@| token list register and,
+% in case the \meta{new value} string is non-simple, sets the |@tempswa|
+% switch to true.
+%
+% The control sequence |\@tempa| can be used as part of \meta{new
+% value}, but not in the \meta{variable name}.
+% \begin{macrocode}
+%<*doc>
+\newcommand\SetStringVariable[2]{%
+ \protected@edef\@tempa{\noexpand\MakePrintable \noexpand\@tempa
+ {FD@swa}{#2}}%
+ \@tempa
+ \protected@edef\@tempa{%
+ \toks@=\noexpand\expandafter{\noexpand\the \toks@ \@tempa}%
+ \ifFD@swa \noexpand\@tempswatrue \fi
+ }%
+ \protected@edef\@tempb{\noexpand\MakePrintable \noexpand\@tempb
+ {FD@swa}{#1}}%
+ \@tempb
+ \ifFD@swa
+ \begingroup
+ \let\PrintChar=\FD@quoted@PrintChar
+ \global\expandafter\let \csname FD@s-\@tempb\endcsname \@tempa
+ \endgroup
+ \else
+ \PackageError{fontdoc}{Names of string variables must be
+ simple\MessageBreak if they are to be assigned values}\@eha
+ \fi
+}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \subsection{For loops}
+%
+%
+% \begin{macro}{\for}
+% \begin{macro}{\endfor}
+% \multchanges{\cs{for}\cs{endfor}}{1.900}{1999/02/16}{Commands
+% added. (LH)}
+% The command sequence
+% \begin{quote}
+% |\for|\parg{name}\marg{start}\marg{stop}\marg{step}\\
+% \vadjust{}\quad\meta{body code}\\
+% |\endfor|\parg{name}
+% \end{quote}
+% will cause the \meta{body code} to be repeated some number of times.
+% How many depends on the values of \meta{start}, \meta{stop}, and
+% \meta{step}, which are integer expressions.
+%
+% As a precaution, the \meta{body code} is not allowed to contain any
+% empty lines (|\par| tokens). If you want to have the visual
+% separation (for sakes of legibility or otherwise), put a |%|
+% somewhere on the line---that makes it nonempty.
+%
+% \meta{name} is used as the name of an integer variable. This
+% variable gets reset to the value of \meta{start} before the first
+% repetition of \meta{body code}. After each repetition but the last,
+% it is incremented by \meta{step}. \meta{body code} gets repeated if
+% the value of \meta{name} has not gotten past that of \meta{stop}. To
+% get past means to be bigger if \meta{step} is positive and to be
+% smaller if \meta{step} is negative. In the case that \meta{step} is
+% zero, the entire construction above will be equivalent to
+% \begin{quote}
+% |\resetint|\marg{name}\marg{start}\\
+% \meta{body code}
+% \end{quote}
+%
+% |\for| \textellipsis\ |\endfor| constructions can be nested.
+% \meta{name} is used by |\for| to identify its matching |\endfor|, so
+% they need to be identical in |\for| and |\endfor|.
+%
+% \multchanges{\cs{for}\cs{for_i}\cs{foreach}}{1.914}{2000/05/21}
+% {\cs{setsomething_global} added to assignments of the
+% \cs{for-\meta{name}} and \cs{body-\meta{name}} control
+% sequences. (LH)}
+% \begin{macrocode}
+%<*pkg>
+\def\for(#1)#2#3#4{
+ \eval_expr_to\a_count{#2}
+ \x_resetint{#1}{\a_count}
+ \eval_expr{#4}
+ \ifnum 0=\result \else
+ \c_count=\result
+ \eval_expr_to\b_count{#3}
+ \setsomething_global\x_cs\edef{for-#1}{
+ \the\c_count \x_relax
+ \noexpand\ifnum \gobble_one\fi
+ \the\b_count \ifnum 0>\c_count > \else < \fi
+ }
+ \def\next##1##2##3\endfor(#1){##2\for_i{##1}{##3}}
+ \next{#1}
+ \fi
+}
+% \end{macrocode}
+%
+% The macro \describecsfamily{for-\meta{name}}|\for-|\meta{name}
+% will contain
+% \begin{quote}
+% \meta{step}|\x_relax\ifnum|\meta{stop}\meta{rel}
+% \end{quote}
+% \meta{step} is the value of the \meta{step} parameter of |\for|,
+% computed when the loop was entered and now expressed in digits.
+% \meta{stop} is likewise for the \meta{stop} parameter. \meta{rel}
+% is |>| or |<|, depending on whether \meta{step} is positive or
+% negative respectively. The reason for this curious definition will
+% be appearent in the light of the definition of |\for_ii|.
+%
+% |\for_i| is expanded in the context
+% \begin{quote}
+% |\for_i|\marg{name}\marg{body code}
+% \end{quote}
+% Also remember, when reading the definition below, that |\ifnum|
+% keeps on expanding tokens until it has found a
+% \begin{quote}
+% \meta{number}\meta{relation}\meta{number}
+% \end{quote}
+% structure. It is therefore possible to nest |\ifnum|s like this!
+%
+% \begin{macrocode}
+\def\for_i#1#2{
+ \setsomething_global\x_cs\def{body-#1}{#2}
+ \ifnum \b_count \ifnum0>\c_count >\else<\fi \a_count
+ \expandafter\gobble_two
+ \else
+ \csname body-#1 \expandafter\endcsname
+ \fi
+ \for_ii{#1}
+}
+% \end{macrocode}
+%
+% The macro \describecsfamily{body-\meta{name}}|\body-|\meta{name}
+% expands to the \meta{body code}.
+%
+% |\for_ii| executes the following code:
+% \begin{quote}
+% |\a_count=\int|\marg{name}\\
+% |\advance \a_count |\meta{step}|\x_relax|\\
+% |\ifnum |\meta{stop}\meta{rel}|\a_count|\\
+% | \expandafter\gobble_two|\\
+% |\else|\\
+% | \resetint|\marg{name}|\a_count|\\
+% | \csname body-|\meta{name}| \expandafter\endcsname|\\
+% |\fi|\\
+% |\for_ii|\marg{name}
+% \end{quote}
+% \meta{step}, \meta{stop}, and \meta{rel} are in |\for-|\meta{name},
+% and since there only are two other tokens between \meta{step} and
+% \meta{rel} in the above, one might as well include them in
+% |\for-|\meta{name} as well. Doing that requires that a matching
+% hole---that will be filled in by |\for-|\meta{name}---is made in the
+% definition of |\for_ii| and that is the reason for its somewhat
+% curious definition.
+%
+% \begin{macrocode}
+\def\for_ii#1{
+ \a_count=\int{#1}
+ \advance \a_count \csname for-#1\endcsname \a_count
+ \expandafter\gobble_two
+ \else
+ \x_resetint{#1}\a_count
+ \csname body-#1 \expandafter\endcsname
+ \fi
+ \for_ii{#1}
+}
+% \end{macrocode}
+%
+% |\endfor| just gobbles its argument, so that the \meta{step}${}=0$
+% case will work right.
+%
+% \begin{macrocode}
+\def\endfor(#1){}
+%</pkg>
+% \end{macrocode}
+% \missing{doc}{\for}
+% \missing{doc}{\endfor}
+% \begin{macrocode}
+%<*doc>
+%</doc>
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+%
+% \begin{macro}{\foreach}
+% \changes{1.901}{1999/03/07}{Command added. (LH)}
+% \changes{1.916}{2001/01/24}{\package{fontdoc} definition added. (LH)}
+% \begin{macro}{\foreach_i}
+% The command sequence
+% \begin{quote}
+% |\foreach|\parg{name}\marg{csep-list}\\
+% \vadjust{}\quad\meta{body code}\\
+% |\endfor|\parg{name}
+% \end{quote}
+% will cause the \meta{body code} to be repeated one time for each item
+% in the \meta{csep-list}. \meta{csep-list} is a comma-separated list
+% of strings.
+%
+% As a precaution, the \meta{body code} is not allowed to contain any
+% empty lines (|\par| tokens). If you want to have the visual
+% separation (for sakes of legibility or otherwise), put a |%|
+% somewhere on the line---that makes it nonempty.
+%
+% \meta{name} is used as the name of a string variable. Before each
+% repetition of the \meta{body code}, this variable will get reset to
+% the next item in the \meta{csep-list}.
+%
+% |\for|\textellipsis\ |\endfor| constructions can be nested.
+% \meta{name} is used by |\foreach| to identify its matching |\endfor|,
+% so they need to be identical in |\foreach| and |\endfor|.
+%
+% \begin{macrocode}
+%<*pkg>
+\def\foreach(#1)#2{
+ \def\next##1\endfor(#1){
+ \setsomething_global\x_cs\def{body-#1}{##1}
+ \process_csep_list{\foreach_i{#1}}#2,\process_csep_list,
+ }
+ \next
+}
+\def\foreach_i#1#2{
+ \resetstr{#1}{#2}
+ \csname body-#1\endcsname
+}
+%</pkg>
+%<*doc>
+\def\foreach(#1)#2{%
+ \def\next##1\endfor(#1){%
+ \@for\@tempa:=#2\do{%
+ \SetStringVariable{#1}{\@tempa}%
+ ##1%
+ }%
+ }%
+ \next
+}
+%</doc>
+% \end{macrocode}
+% \end{macro} \end{macro}
+%
+%
+%
+% \subsection{Comments}
+%
+% \changes{1.911}{1999/11/30}{Comment commands included in
+% \texttt{finstmsc.sty}. (LH)}
+%
+% \begin{macro}{\comment}
+% In \package{fontinst}, |\comment| simply gobbles its argument.
+% \begin{macrocode}
+%<pkg>\let\comment=\gobble_one
+% \end{macrocode}
+%
+% In \package{fontdoc}, |\comment| starts a new text paragraph and
+% leaves the argument to be typeset.
+% \begin{macrocode}
+%<*doc>
+\def\comment{\par\noindent}
+%</doc>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\begincomment}
+% \changes{1.900}{1999/02/07}{Command added. (LH)}
+% \begin{macro}{\endcomment}
+% \changes{1.900}{1999/02/07}{Command added. (LH)}
+% Since |\comment| cannot be used for a comment longer than one
+% paragraph, we also provide the means of introducing longer comments,
+% by writing
+% \begin{quote}
+% |\begincomment| \meta{any amount of text} |\endcomment|
+% \end{quote}
+% The names are admittedly not nice from a \LaTeX\ point of view, but
+% it is hardly worth the cost to implement some kind of environment
+% processing in \package{fontinst}, just for the sake of this command.
+% \begin{macrocode}
+%<pkg>\let\begincomment=\iffalse
+%<doc>\let\begincomment=\iftrue
+%<pkg|doc>\let\endcomment=\fi
+% \end{macrocode}
+% \end{macro} \end{macro}
+%
+% \Finale
+%
+\endinput