% \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} % % \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 } % % \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}}} % % \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@ } % % \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} % % \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 } % % \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 } % %<*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 } % % \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 } % %<*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 } % % \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} %\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}})% } % % \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} %\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 } % % \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 } % % \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 } % % \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 } % %<*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 } % % \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 } % %<*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 } % % \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 } % %<*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}% } % % \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 } % %<*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 } % % \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 } % % \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 } % % \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 } % % \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}$% }% } % % \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 } % % \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} % % \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} % % \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} % % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % % % \begin{macro}{\dim} % \begin{macrocode} %\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 } % % \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}% } % % \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} % % \end{macrocode} % \missing{doc}{\unsetint} % \missing{doc}{\unsetstr} % \missing{doc}{\unsetdim} % \missing{doc}{\unsetcommand} % \begin{macrocode} %<*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 } % % \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}} % % \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{} % % \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 } % % \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){} % % \end{macrocode} % \missing{doc}{\for} % \missing{doc}{\endfor} % \begin{macrocode} %<*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}. % % |\foreach|\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 } % %<*doc> \def\foreach(#1)#2{% \def\next##1\endfor(#1){% \@for\@tempa:=#2\do{% \SetStringVariable{#1}{\@tempa}% ##1% }% }% \next } % % \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} %\let\comment=\gobble_one % \end{macrocode} % % In \package{fontdoc}, |\comment| starts a new text paragraph and % leaves the argument to be typeset. Note that the argument group % thus survives; some commands make use of this fact. % \begin{macrocode} %<*doc> \def\comment{\par\noindent} % % \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} %\let\begincomment=\iffalse %\let\begincomment=\iftrue %\let\endcomment=\fi % \end{macrocode} % \end{macro} \end{macro} % % \Finale % \endinput