% \CheckSum{3947}
% \iffalse meta-comment
%
% Copyright 1993, 1994, 1995, 1996 Alan Jeffrey,
% hacked and maintained 1997, 1998 Sebastian Rahtz,
% copyright 1998, 1999, 2000 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.1 or, at your option, any later version.
%
%%% From file: fimain.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{fimain.dtx}
\end{document}
%
% \fi
%
% \StopEventually{}
%
%
% \section{General commands}
%
% \subsection{Setting variables}
%
% \meta{int}, \meta{str}, and \meta{dim} below can be any strings.
% \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 |\i-|\meta{int}, |\s-|\meta{str}, |\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} 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 \cs{setint} by \cs{x_setint}. (LH)}
% \changes{1.900}{1999/02/07}{Replaced \cs{resetint} by \cs{x_resetint}.
% (LH)}
% \changes{1.900}{1999/02/07}{Replaced \cs{setstr} by \cs{x_setstr}.
% (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|misc>
\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>
\def\setint#1#2{\Bheading{Default} #1 = $\expression0{#2}$}
\def\setstr#1#2{\Bheading{Default} #1 = #2}
\def\setdim#1#2{\a@dimen=#2\relax\Bheading{Default} #1 = \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|misc>
\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>
\def\resetint#1#2{\Bheading{Value} #1 = $\expression0{#2}$}
\def\resetstr#1#2{\Bheading{Value} #1 = #2}
\def\resetdim#1#2{\a@dimen=#2\relax\Bheading{Value} #1 = \the\a@dimen}
\def\resetcommand#1{\gdef#1}
%
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\int}
% \changes{1.909}{1999/10/19}{doc implementation changed to using
% \cs{typeset@integer}. (LH)}
% \begin{macro}{\str}
% \begin{macro}{\dim}
% \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)}
% \begin{macrocode}
%<*pkg|misc>
\def\int#1{\csname~i-#1\endcsname}
\def\str#1{\csname~s-#1\endcsname}
\def\dim#1{\csname~d-#1\endcsname}
\def\strint#1{\expandafter\identity_one\expandafter{\number\int{#1}}}
%
% \end{macrocode}
%
% \missing{doc}{\str}
% \missing{doc}{\dim}
% \missing{doc}{\strint}
% \begin{macrocode}
%<*doc>
\def\int#1{\typeset@integer{#1}}
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro}
%
% \begin{macro}{\typeset@integer}
% \begin{macro}{\typeset@string}
% \begin{macro}{\typeset@dimen}
% These macros take the name of an integer\slash string\slash dimen
% as argument and typesets that name with the correct formating. They
% should work equally well in horizontal, math, and vertical mode.
% \begin{macrocode}
\def\typeset@integer#1{\x@relax \ifmmode {\fam0 #1}\else $\fam0 #1$\fi}
\def\typeset@string#1{\x@relax
\ifmmode \hbox{\normalfont#1}\else \textnormal{#1}\fi
}
\let\typeset@dimen=\typeset@string
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% \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|misc>
\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 \typeset@integer{#1} set}}
\def\ifisstr#1\then{\generic@if{string \typeset@string{#1} set}}
\def\ifisdim#1\then{\generic@if{dimension \typeset@dimen{#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|misc>
\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}
% LH 1999/02: 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.
%
% \DescribeMacro{\saved-COMMAND}
% The normal definition of a command that have 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
% \DescribeMacro{\off-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|misc>
\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|misc>
\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}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \subsection{For loops}
%
%
% \begin{macro}{\for}
% \begin{macro}{\endfor}
% LH 1999/02: 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|misc>
\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}
%
% \DescribeMacro{\for-NAME}The macro |\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}
%
% \DescribeMacro{\body-NAME}The macro |\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)}
% \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|.
%
% \missing{doc}{\foreach}
% \begin{macrocode}
%<*pkg|misc>
\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
}
%
% \end{macrocode}
% \end{macro} \end{macro}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \subsection{Integer expressions}
%
% \begin{macro}{\eval_expr}
% \begin{macro}{\eval_expr_to}
% \begin{macro}{\g_eval_expr_to}
% 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{integer variable}\marg{integer expression}
% \end{quote}
% locally assigns the value of \meta{integer expression} to
% \meta{integer variable} (which is an integer variable as defined
% in~\cite{TeXbook}).
% |\g_eval_expr_to| does the same globally.
%
% \begin{macrocode}
%<*pkg|misc>
\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}
%
% \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}
\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}
%
%
% \begin{macro}{\neg}
% \begin{macro}{\add}
% \begin{macro}{\sub}
% \changes{1.909}{1999/10/20}{Changed priority of first term, so that
% unnecessary bracketing is reduced. (LH)}
% \begin{macro}{\mul}
% \begin{macro}{\div}
% \changes{1.909}{1999/10/20}{Changed priority of numerator, so that
% unnecessary bracketing is reduced. (LH)}
% \begin{macro}{\max}
% \begin{macro}{\min}
% These macros return an integer expression:
% \begin{quote}
% |\neg|\marg{integer expression}\\
% |\add|\marg{integer expression}\marg{integer expression}\\
% |\sub|\marg{integer expression}\marg{integer expression}\\
% |\mul|\marg{integer expression}\marg{integer expression}\\
% |\div|\marg{integer expression}\marg{integer expression}\\
% |\max|\marg{integer expression}\marg{integer expression}\\
% |\min|\marg{integer expression}\marg{integer expression}\\
% |\scale|\marg{integer expression}\marg{integer expression}
% \end{quote}
%
% \begin{macrocode}
\def\neg#1{#1\global\result=-\result}
\def\add#1#2{#1{\a_count=\result\eval_expr{#2}
\global\advance\result by \a_count}}
\def\sub#1#2{#1{\a_count=\result\eval_expr{#2}
\advance\a_count by -\result
\global\result=\a_count}}
\def\mul#1#2{#1{\a_count=\result\eval_expr{#2}
\global\multiply\result by \a_count}}
\def\div#1#2{#1{\a_count=\result\eval_expr{#2}
\divide\a_count by \result
\global\result=\a_count}}
\def\max#1#2{#1{\a_count=\result\eval_expr{#2}
\ifnum\a_count>\result \global\result=\a_count \fi}}
\def\min#1#2{#1{\a_count=\result\eval_expr{#2}
\ifnum\a_count<\result \global\result=\a_count \fi}}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\neg#1{\priority8{-\expression6{#1}}}
\def\add#1#2{\priority2{\expression2{#1}+\expression2{#2}}}
\def\sub#1#2{\priority2{\expression2{#1}-\expression3{#2}}}
\def\mul#1#2{\priority4{\expression4{#1}\times\expression4{#2}}}
\def\div#1#2{\priority4{\expression4{#1}/\expression5{#2}}}
\def\max#1#2{\priority6{\expression6{#1}\sqcup\expression6{#2}}}
\def\min#1#2{\priority7{\expression7{#1}\sqcap\expression7{#2}}}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\scale}
% \begin{macro}{\grabchars@}
% \begin{macro}{\grabchars@i}
% \begin{macro}{\grabchars@ii}
% \begin{macro}{\grabchars@iii}
% \begin{macro}{\scale-500X}
% The |\scale| macro performs the operation of multiplying the
% operands and dividing that result by one thousand.
% \begin{macrocode}
%<*pkg|misc>
\def\scale#1#2{#1{\a_count=\result\eval_expr{#2}
\global\multiply\result by \a_count
\rounded_thousandths}}
%
% \end{macrocode}
%
% |\scale| is often used with a fixed scaling factor, such as for
% example 500, as the second argument. In those cases it often makes
% more sense to typeset the expression as for example a fraction times
% the first argument than to typeset it as |\div{\mul{#1}{#2}}{1000}|
% would. Such special cases can be specified by defining a control
% sequence \DescribeMacro{\scale-FACTOR}|\scale-|\meta{factor}, where
% \meta{factor} is the first four characters of the |#2| integer
% expression (all control sequences are |\string|ed), with |X|s added
% at the end if the expression is shorter than four characters.
%
% For the moment, the only scaling factor with such a special
% definition is 500. This scaling factor gets typeset as
% $\frac{1}{2}$.
% \begin{macrocode}
%<*doc>
\def\scale#1#2{%
\x@cs\ifx{scale-\grabchars@#2XXXX\@nil}\x@relax
\div{\mul{#1}{#2}}{1000}%
\else
\csname scale-\grabchars@#2XXXX\@nil\endcsname{#1}{#2}%
\fi
}
\def\grabchars@{\expandafter\grabchars@i\string}
\def\grabchars@i#1{#1\expandafter\grabchars@ii\string}
\def\grabchars@ii#1{#1\expandafter\grabchars@iii\string}
\def\grabchars@iii#1{#1\expandafter\@car\string}
\x@cs\def{scale-500X}#1#2{\priority4{\frac{1}{2}\expression4{#1}}}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\expression}
% \begin{macro}{\priority}
% \changes{1.909}{1999/10/20}{Changed condition for \cs{ifnum}, so
% that expressions with equal priority will not get bracketed when
% nested. (LH)}
% \begin{macro}{\identity}
% \begin{macro}{\bracket}
% \package{fontdoc} uses |\expression| and |\priority| for typsetting
% nested arithmetic expressions. |\expression| is called as
% \begin{quote}
% |\expression|\marg{priority}\marg{expression}
% \end{quote}
% where \meta{priority} is the minimum priority the outermost
% operation in \meta{expression} must have if \meta{expression} is to
% be read correctly without bracketing. |\priority| is called as
% \begin{quote}
% |\priority|\marg{priority}\marg{expression}
% \end{quote}
% where \meta{priority} is the priority the outermost operation in
% \meta{expression}. Its object is to bracket \meta{expression} if
% that is necessary.
%
% \begin{macrocode}
%<*doc>
\def\expression#1#2{\a@count=#1\relax#2}
% \end{macrocode}
% \begin{macrocode}
\def\priority#1#2{%
\ifnum #1<\a@count
\let\next=\bracket
\else
\let\next=\identity
\fi
\next{#2}}
\def\identity#1{#1}
\def\bracket#1{(#1)}
%
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro}
%
% \begin{macro}{\ifnumber}
% LH 1999/02: 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}
%<*pkg|misc>
\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{%
\generic@if{$ \expression0{#1} #2 \expression0{#3} $}%
}
%
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Comments}
%
% \changes{1.911}{1999/11/30}{Comment commands included in
% \protect\protect\protect\Module{misc} module. (LH)}
%
% \begin{macro}{\comment}
% In \package{fontinst}, |\comment| simply gobbles its argument.
% \begin{macrocode}
%<*pkg|misc>
\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}
%
% \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}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \section{Encoding files}
%
% \changes{1.911}{1999/11/21}{Definitions of encoding file commands
% added to \protect\protect\protect\Module{misc}. (LH)}
%
% \DescribeMacro{\inputetx}
% The macro
% \begin{quote}
% |\inputetx|\marg{filename}
% \end{quote}
% inputs \meta{filename}|.etx|, ignoring anything between |\relax|
% and |\encoding|, and anything after |\endencoding|.
%
% The file name is transformed to lowercase before opening.
%
% \begin{macro}{\inputetx}
% \begin{macro}{\encoding}
% \changes{1.900}{1999/02/07}
% {Changed group in fontdoc to \cs{begingroup} type. (LH)}
% \begin{macro}{\endencoding}
% \changes{1.900}{1999/02/07}{Made it outer. (LH)}
% \begin{macrocode}
%<*pkg|misc>
\def\inputetx#1{
\edef\lowercase_file{\lowercase{
\edef\noexpand\lowercase_file{#1}}}
\lowercase_file
\slot_number=0
\def\relax{\let\relax=\x_relax\iffalse}
\let\encoding=\fi
\primitiveinput \lowercase_file.etx\x_relax
\let\relax=\x_relax
}
\let\encoding=\relax
\outer\def\endencoding{\endinput}
%
% \end{macrocode}
%
% Things are a bit more complicated in \package{fontdoc}, since the
% |\relax| \textellipsis\ |\encoding| \textellipsis\ |\endencoding|
% markup must be able to work in two different ways. In the main file
% only |\encoding| actually does anything---it sets |\slot@number| to
% zero. In a file that is being |\inputetx|ed, they must work as with
% \package{fontinst}: Everything between |\relax| and |\encoding|,
% and everything after |\endencoding| must be ignored.
% \multchanges{\cs{inputetx}\cs{inputmtx}}{1.914}{2000/05/27}
% {New \package{fontdoc} definition, using \cs{IfFileExists}. (LH)}
% \begin{macrocode}
%<*doc>
\def\inputetx#1{%
\begingroup
\edef\lowercase@file{\lowercase{%
\edef\noexpand\lowercase@file{#1}%
}}%
\lowercase@file
\global\slot@number=0%
\IfFileExists{\lowercase@file.etx}{%
\def\relax{\let\relax=\x@relax\iffalse}%
\let\encoding=\fi
\outer\x@cs\def{endencoding}{\endinput}%
\@@input \@filef@und
\let\relax=\x@relax
}{%
\PackageError{fontdoc}{File #1.etx not found}%
{\@eha\MessageBreak You can \protect\inputetx\space
some other file now, if you want.}%
}
\endgroup
}
\def\encoding{\begingroup\global\slot@number=0}
\outer\def\endencoding{\endgroup}
%
% \end{macrocode}
% \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\setslot}
% \begin{macro}{\endsetslot}
% \begin{macro}{\slot_name}
% \begin{macro}{\slot@name}
% |\setslot|\marg{name} \meta{slot commands} |\endsetslot|
%
% In \package{fontinst}, this sets |\slot_name| to \meta{name} and
% calls |\do_slot| at the beginning of the slot and it calls
% |\end_do_slot| and increments |\slot_number| by one at the end.
% By default, |\do_slot| and |\end_do_slot| do nothing, but this is
% over-ridden later.
%
% \begin{macrocode}
%<*pkg|misc>
\def\setslot#1{\edef\slot_name{#1}\do_slot}
\def\endsetslot{\end_do_slot\advance\slot_number by 1\x_relax}
%
% \end{macrocode}
%
% In \package{fontdoc}, the same code sets |\slot@name| to \meta{name},
% prints an |\Aheading| heading for the slot which show the name and
% number of the slot, and prints the current automatic slot comment
% (if one has been set) at the beginning of the slot. At the end of
% the slot, it simply increments |\slot@number| by one.
%
% \begin{macrocode}
%<*doc>
\def\setslot#1{\def\slot@name{#1}%
\Aheading{Slot \the\slot@number\space `#1'}%
\ifslot@comment@ \comment{\slot@comment}\fi}
\def\endsetslot{\global\advance\slot@number by 1\relax}
%
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro}
%
% \begin{macro}{\do_slot}
% \begin{macro}{\end_do_slot}
% \begin{macrocode}
%<*pkg|misc>
\let\do_slot\empty_command
\let\end_do_slot\empty_command
% \end{macrocode}
% \expandafter\edef \csname saved@macroname\endcsname
% {\string\do_new_slot}
% \changes{1.910}{1999/11/01}{Macro removed. (LH)}
% \end{macro} \end{macro}
%
% \begin{macro}{\nextslot}
% \begin{macro}{\skipslots}
% \begin{macro}{\slot_number}
% \begin{macro}{\slot@number}
% |\nextslot|\marg{integer expression}\\
% |\skipslots|\marg{integer expression}
%
% In \package{fontinst}, |\nextslot| sets the |\slot_number| and
% |\skipslots| addvances the |\slot_number|.
%
% \begin{macrocode}
\newcount\slot_number
\def\nextslot#1{\eval_expr_to\slot_number{#1}}
\def\skipslots#1{\eval_expr{#1} \advance\slot_number by \result}
%
% \end{macrocode}
%
% The commands do the same in \package{fontdoc} as in
% \package{fontinst}, although they do it to |\slot@number| instead of
% |\slot_number|.
%
% \begin{macrocode}
%<*doc>
\newcount\slot@number
\def\nextslot#1{\global\slot@number=#1\relax}
\def\skipslots#1{\global\advance\slot@number by #1\relax}
%
% \end{macrocode}
%
% \ambiguity{What should the arguments to \cs{nextslot} and
% \cs{skipslots} be?} At least since v\,1.335 the comments in the
% source has said it was an integer expression, but the implementation
% was for a \TeX\ number. Alan's v\,1.5 manual and Rowland's v\,1.8
% manual both say the arguments must be numbers. Allowing arbitrary
% integer expressions with \package{fontinst} is trivial, the above
% implementation copes with that, but \package{fontdoc} gets in
% trouble, so what should we do about it? /LH
%
% AFAIK, all instances of |\nextslot| or |\skipslots| appearing in
% present |*.etx| files are explicit numbers, no fancy constructs. /UV
%
% \changes{1.900}{1999/02/07}{Made changes of \cs{slot@number}
% global. (LH)}
% \end{macro} \end{macro} \end{macro} \end{macro}
%
% \begin{macro}{\setleftboundary}
% \changes{1.909}{1999/10/19}{doc definition added. (LH)}
% \begin{macro}{\endsetleftboundary}
% \changes{1.909}{1999/10/19}{doc definition added. (LH)}
% \begin{macro}{\do_boundary}
% |\setleftboundary|\marg{glyph} \meta{slot commands}
% |\endsetleftboundary|
%
% These macros are like |\setslot| and |\endsetslot|, but they merely
% set the left boundary ligkern program, they do not cause any
% |CHARACTER| property list to be written. Thus the only metric
% information connected to the \meta{glyph} argument that is ever used
% is the kerns with this glyph on the left.
%
% |\do_boundary| and |\endsetleftboundary| are initally |\relax|, but
% are later redefined.
%
% \begin{macrocode}
%<*pkg>
\def\setleftboundary#1{\edef\slot_name{#1}\do_boundary}
\let\endsetleftboundary\x_relax
\let\do_boundary\x_relax
%
%<*doc>
\def\setleftboundary#1{\def\slot@name{#1}%
\Aheading{Left boundary `#1'}%
}
\let\endsetleftboundary=\x@relax
%
%<*misc>
\let\setleftboundary=\gobble_one
\let\endsetleftboundary=\x_relax
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
%
% \begin{macro}{\setrightboundary}
% |\setrightboundary|\marg{glyph}
%
% The |\setrightboundary| macro should be used to set which slot in
% the font is used as right boundary marker if that slot is empty. It
% advances |\slot_number| just like a |\setslot| \textellipsis\
% |\endsetslot| pair, but since the slot will be left empty, there is
% no need for any \meta{slot commands}, and hence there is no need for
% a closing |\endset|\textellipsis\ command either.
%
% If the right boundary marker slot is not to be left empty (often
% unavoidable), then one should use the slot command
% |\makerightboundary| instead.
%
% \changes{1.909}{1999/10/19}{doc definition added. (LH)}
% \begin{macrocode}
%<*pkg|misc>
\def\setrightboundary#1{
\makerightboundary{#1}
\advance \slot_number 1\x_relax
}
%
%<*doc>
\def\setrightboundary#1{%
\Aheading{Right boundary slot \the\slot@number\space `#1'}%
\global\advance\slot@number by 1\relax
}
%
% \end{macrocode}
% \end{macro}
%
%
% \DescribeMacro{\ligature}
% \DescribeMacro{\nextlarger}
% \DescribeMacro{\varchar}
% \DescribeMacro{\endvarchar}
% \DescribeMacro{\usedas}
% \DescribeMacro{\makerightboundary}
% The \meta{slot commands} are:
% \begin{quote}
% |\ligature|\marg{lig}\marg{glyph}\marg{glyph}\\
% |\nextlarger|\marg{glyph}\\
% |\varchar| \meta{varchar commands} |\endvarchar|\\
% |\usedas|\marg{command}\marg{type}\\
% |\makerightboundary|\marg{glyph}
% \end{quote}
% By default, these do nothing in \package{fontinst}, but those
% defaults are overridden later.\footnote{With the exception of
% \cs{usedas}, which is never used at all AFAIK. It was intended to be
% used for math font encodings, but that is still on the \texttt{TODO}
% list. /LH} In \package{fontdoc}, they generate descriptive headings.
%
% \begin{macro}{\ligature}
% \begin{macrocode}
%\let\ligature=\gobble_three
%<*doc>
\def\ligature#1{\Bheading{Ligature} \csname doc-#1\endcsname}
% \end{macrocode}
% Symbolic typesetting of |\ligature| programs requires
% special processing.
%
% \begin{macrocode}
\x@cs\def{doc-LIG}#1#2{%
$\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
\typeset@glyph{#2}$}
\x@cs\def{doc-/LIG}#1#2{%
$\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
\typeset@glyph{\slot@name} * \typeset@glyph{#2}$}
\x@cs\def{doc-LIG/}#1#2{%
$\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
\typeset@glyph{#2} * \typeset@glyph{#1}$}
\x@cs\def{doc-/LIG/}#1#2{%
$\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
\typeset@glyph{\slot@name} * \typeset@glyph{#2} * \typeset@glyph{#1}$}
\x@cs\def{doc-/LIG>}#1#2{%
$\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
\typeset@glyph{\slot@name} + \typeset@glyph{#2}$}
\x@cs\def{doc-LIG/>}#1#2{%
$\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
\typeset@glyph{#2} + \typeset@glyph{#1}$}
\x@cs\def{doc-/LIG/>}#1#2{%
$\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
\typeset@glyph{\slot@name} + \typeset@glyph{#2} * \typeset@glyph{#1}$}
\x@cs\def{doc-/LIG/>>}#1#2{%
$\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow
\typeset@glyph{\slot@name} + \typeset@glyph{#2} + \typeset@glyph{#1}$}
%
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\nextlarger}
% \begin{macro}{\usedas}
% \begin{macro}{\makerightboundary}
% \begin{macrocode}
%<*pkg|misc>
\let\nextlarger=\gobble_one
\let\usedas=\gobble_two
\let\makerightboundary=\gobble_one
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\nextlarger#1{\Bheading{Next larger} \typeset@glyph{#1}}
\def\makerightboundary#1{%
\Bheading{Right boundary marker slot} designation \typeset@glyph{#1}%
}
%
% \end{macrocode}
% \missing{doc}{\usedas}
% \end{macro} \end{macro} \end{macro}
%
%
% \DescribeMacro{\vartop}
% \DescribeMacro{\varmid}
% \DescribeMacro{\varbot}
% \DescribeMacro{\varrep}
% The \meta{varchar commands} are:
% \begin{quote}
% |\vartop|\marg{glyph}\\
% |\varmid|\marg{glyph}\\
% |\varbot|\marg{glyph}\\
% |\varrep|\marg{glyph}
% \end{quote}
% These too do by default, which is overridden later, nothing in
% \package{fontinst} but typeset descriptive headings in \package{fontdoc}.
%
% \begin{macro}{\varchar}
% \begin{macro}{\vartop}
% \begin{macro}{\varmid}
% \begin{macro}{\varbot}
% \begin{macro}{\varrep}
% \begin{macro}{\endvarchar}
% \begin{macrocode}
%<*pkg|misc>
\let\varchar=\empty_command
\let\vartop=\gobble_one
\let\varmid=\gobble_one
\let\varbot=\gobble_one
\let\varrep=\gobble_one
\let\endvarchar=\empty_command
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\varchar{\Bheading{Extensible glyph:}}
\def\vartop#1{\Bheading{Top} \typeset@glyph{#1}}
\def\varmid#1{\Bheading{Middle} \typeset@glyph{#1}}
\def\varbot#1{\Bheading{Bottom} \typeset@glyph{#1}}
\def\varrep#1{\Bheading{Repeated} \typeset@glyph{#1}}
\let\endvarchar\relax
%
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\useexamplefont}
% \begin{macro}{\slotexample}
% \begin{macro}{\setslotcomment}
% \begin{macro}{\resetslotcomment}
% \begin{macro}{\unsetslotcomment}
% \begin{macro}{\slot@comment}
% \begin{macro}{\slot@font}
% As of v\,1.8 of \package{fontinst}, we have added an interface
% for automatic documentation of encoding files, which has been
% developed by Matthias Clasen as part of his work on math fonts.
% The implementation was slightly modified and integrated into
% this version by Ulrik Vieth.
%
% |\setslotcomment| defines a default slot comment, stored in the
% variable |\slot@comment|, which is subsequently used to annotate
% all |\setslot| commands. The slot comment can be changed by
% |\resetslotcomment| or turned off by |\unsetslotcomment|.
%
% |\useexamplefont| defines a default font, |\slot@font|, which
% may be referenced by calling |\slotexample| in slot comments to
% display the character or symbol allocated to the current slot.
%
% Taking advantage of this mechanism, it is possible to write:
% \begin{quote}
% |\useexamplefont{FONT}|\\[0.5\baselineskip]
% |\setslotcomment{The symbol `\slotexample'.}|\\
% |\setslot{FOO}\endsetslot|\\
% |\setslot{BAR}\endsetslot|\\
% |\resetslotcomment{The character `\slotexample'.}|\\
% |\setslot{BAZ}\endsetslot|
% \end{quote}
% instead of having to write:
% \begin{quote}
% |\usepackage{PACKAGE-to-use-symbols-from-FONT}|\\[0.5\baselineskip]
% |\setslot{FOO}\comment{The symbol `\foo'.}\endsetslot|\\
% |\setslot{BAR}\comment{The symbol `\bar'.}\endsetslot|\\
% |\setslot{BAZ}\comment{The character `\baz'.}\endsetslot|
% \end{quote}
%
% These macros never do anything in \package{fontinst}, they just
% gobble their arguments.
% \begin{macrocode}
%<*pkg|misc>
\let\useexamplefont=\gobble_one
\let\slotexample=\empty_command
\let\setslotcomment=\gobble_one
\let\resetslotcomment=\gobble_one
\let\unsetslotcomment=\empty_command
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newif\ifslot@comment@
\slot@comment@false
\def\slot@comment{}
\def\setslotcomment#1{%
\slot@comment@true
\gdef\slot@comment{#1}}
\def\resetslotcomment#1{%
\gdef\slot@comment{#1}}
\def\unsetslotcomment{%
\slot@comment@false
\gdef\slot@comment{}}
% \end{macrocode}
%
% \begin{macrocode}
\let\slot@font=\nullfont
\def\useexamplefont#1{\font\slot@font=#1 }
\def\slotexample{{\slot@font\char\the\slot@number}}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \section{Metric files}
% \label{Sec:Metric files}
%
% \changes{1.911}{1999/11/17}{Definitions of metric file commands
% added to \protect\protect\protect\Module{misc}. (LH)}
%
% \DescribeMacro{\inputmtx}
% The macro
% \begin{quote}
% |\inputmtx|\marg{filename}
% \end{quote}
% inputs \meta{filename}|.mtx|, ignoring anything between |\relax| and
% |\metrics|, and anything after |\endmetrics|.
%
% \begin{macro}{\inputmtx}
% \begin{macro}{\metrics}
% \changes{1.914}{2000/05/26}{Fixed typo: \cs{x@relax} instead of
% \cs{x_relax}. (LH)}
% \begin{macro}{\endmetrics}
% \changes{1.900}{1999/02/08}{Made it outer. (LH)}
% \begin{macro}{\endmetrics_text}
% \begin{macro}{\endmetrics@hook}
% The |\endmetrics_text| macro expands to |\endmetrics| (eleven
% `other' tokens, not one control sequence token). It is used instead
% of |\string\endmetrics|, which does not work since |\endmetrics| is
% outer.
% \begin{macrocode}
%<*pkg|misc>
\def\inputmtx#1{
\def\relax{\let\relax=\x_relax\iffalse}
\let\metrics=\fi
\primitiveinput #1.mtx\x_relax
\let\relax=\x_relax
}
\let\metrics=\x_relax
\edef\endmetrics_text{\string\endmetrics}
\outer\def\endmetrics{\endinput}
%
% \end{macrocode}
% |\inputmtx| used to set |\a_count|, but we haven't been able to
% find a reason for this, so it was removed.
%
% In \package{fontdoc}, the |\metrics| and |\endmetrics| macros
% initially just define a group, but |\inputmtx| redefines them to
% work as they do in \package{fontinst}. |\endmetrics@hook| is a
% macro that gets executed just before the |\endgroup| in
% |\endmetrics|; it is normally |\@empty|, and it is set to this value
% at each |\metrics|, but the metric package system redefines it.
% \multchanges{\cs{endmetrics_hook}}{1.914}{2000/05/27}{Macro added.
% (LH)}
% \multchanges{\cs{inputetx}\cs{inputmtx}}{1.914}{2000/05/27}
% {New \package{fontdoc} definition, using \cs{IfFileExists}. (LH)}
% \begin{macrocode}
%<*doc>
\def\inputmtx#1{%
\begingroup
\edef\lowercase@file{\lowercase{%
\edef\noexpand\lowercase@file{#1}%
}}%
\lowercase@file
\let\endmetrics@hook=\@empty
\IfFileExists{\lowercase@file.mtx}{%
\skip@mtx@preamble
\@@input \@filef@und
\let\relax=\x@relax
}{%
\PackageError{fontdoc}{File #1.mtx not found}%
{\@eha\MessageBreak You can \protect\inputmtx\space
some other file now, if you want.}%
}
\endmetrics@hook
\endgroup
}
\def\skip@mtx@preamble{%
\def\relax{\let\relax=\x@relax\iffalse}%
\let\metrics=\fi
\outer\x@cs\def{endmetrics}{\endinput}%
}
\def\metrics{\begingroup\let\endmetrics@hook=\@empty}
\outer\def\endmetrics{\endmetrics@hook\endgroup}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
%
%
% \begin{macro}{\ProvidesMtxPackage}
% \begin{switch}{@mtxpackage@headed@}
% \begin{macro}{\announce@package}
% \begin{macro}{\finish@package}
% \multchanges{\cs{ProvidesMtxPackage}\cs{usemtxpackage}}{1.914}
% {2000/05/27}{New \package{fontdoc} implementation---the packages
% are actually loaded (they have to, since they can define
% commands). Multiple loading is prevented as in
% \package{fontinst}. (LH)}
% The call
% \begin{quote}
% |\ProvidesMtxPackage|\marg{package~name}
% \end{quote}
% signals to the package managing system that there is no need to load
% this package again.
% \begin{macrocode}
%\def\ProvidesMtxPackage#1{\x_cs\let{pack-#1}P}
%<*doc>
\def\ProvidesMtxPackage#1{%
\endmetrics@hook
\@mtxpackage@headed@false
\everypar={\announce@package{#1}}%
\def\endmetrics@hook{\finish@package{#1}}
\global\x@cs\let{FD@pack-#1}\@empty
}
% \end{macrocode}
% \begin{macrocode}
\newif\if@mtxpackage@headed@
% \end{macrocode}
% \begin{macrocode}
\def\announce@package#1{%
\everypar={}%
\@mtxpackage@headed@true
\Aheading{Metric package \textsf{#1}:}%
}
% \end{macrocode}
% \begin{macrocode}
\def\finish@package#1{%
\if@mtxpackage@headed@
\Aheading{End of metric package \textsf{#1}.}%
\else
\everypar={}%
\Aheading{(Metric package \textsf{#1}.)}%
\fi
\par\addvspace\medskipamount
}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{switch}\end{macro}
%
%
% \begin{macro}{\usemtxpackage}
% The call
% \begin{quote}
% |\usemtxpackage|\marg{package~list}
% \end{quote}
% inputs those of the packages in the list that have not been loaded
% yet (i.e., those for which no |\ProvidesMtxPackage| has been made).
% Each package is assumed to reside in the metric file that
% |\inputmtx| loads when given the name of the package as argument.
%
% The call
% \begin{quote}
% |\usemtxpackage|\oarg{filename}\marg{package~list}
% \end{quote}
% inputs the packages in the list if at least one of them has not been
% loaded yet. In this case, all the packages are assumed to reside in
% the single metric file that |\inputmtx| loads when given
% \meta{filename} as argument.
%
% \begin{macrocode}
%<*pkg>
\def\usemtxpackage{\futurelet\next_token\test_UseMtxPkg_arguments}
\def\test_UseMtxPkg_arguments{\ifx\next_token[
\expandafter\mtx_package_given_file
\else
\expandafter\mtx_package_separate_files
\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\mtx_package_given_file[#1]#2{
\_a_false
\process_csep_list\load_true_unless_loaded #2,\process_csep_list,
\if_a_ \inputmtx{#1} \fi
}
\def\load_true_unless_loaded#1{
\x_cs\ifx{pack-#1}P\else\_a_true\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\mtx_package_separate_files#1{
\process_csep_list\load_file_unless_loaded #1,\process_csep_list,
}
\def\load_file_unless_loaded#1{
\x_cs\ifx{pack-#1}P\else \inputmtx{#1} \fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\newcommand\usemtxpackage[2][\x@relax]{%
\ifx \x@relax#1%
\@for\@tempa:=#2\do{%
\x@cs\ifx{FD@pack-\@tempa}\@empty \else
\inputmtx{\@tempa}%
\fi
}%
\else
\@tempswafalse
\@for\@tempa:=#1\do{%
\x@cs\ifx{FD@pack-\@tempa}\@empty \else \@tempswatrue \fi
}%
\if@tempswa
\inputmtx{#2}%
\fi
\fi
}
%
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Kerning information}
%
% \DescribeMacro{\l-NAME}
% \DescribeMacro{\r-NAME}
% \DescribeMacro{\k}
% \DescribeMacro{\AMOUNT}
% The kerning information is kept in the macros |\l-|\meta{name} and
% |\r-|\meta{name}, containing information about how \meta{name} kerns on
% the left and on the right, respectively. The |\l-|\meta{name} macro
% should expand out to a series of
% \begin{quote}
% |\k|\,|\r-|\meta{name}\,|\|\meta{amount}
% \end{quote}
% control sequences, and vice versa. Examples of |\|\meta{amount}
% control sequences are: |\0|, |\1|, |\1000|, |\-50|, |\33|; these
% corresponds to the kern amounts $0$, $1$, $1000$ (which would be
% grotesquely large), $-50$, and $33$ respectively.
%
%
% \begin{macro}{\setkern}
% |\setkern|\marg{glyph1}\marg{glyph2}\marg{integer expression}
%
% Sets a kern pair between \meta{glyph1} and \meta{glyph2} to the
% specified value, which is typically a value returned by
% |\kerning|\marg{glyph3}\marg{glyph4}. If there already is a kern
% set between \meta{glyph1} and \meta{glyph2} then this will not affect
% the output, but it will use up another 3 units of token memory.
%
% \begin{macrocode}
%<*pkg>
\def\setkern#1#2#3{
\x_cs\ifx{i-rawscale}\x_relax
\expandafter\set_kern
\csname~r-#1\expandafter\endcsname
\csname~l-#2\endcsname{#3}
\else
\expandafter\set_kern
\csname~r-#1\expandafter\endcsname
\csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}}
\fi
}
\def\set_kern#1#2#3{
\eval_expr{#3}
\expandafter\set_kern_cs\csname\the\result\endcsname#1#2
}
\def\set_kern_cs#1#2#3{
\add_to#2{\k#3#1}
\add_to#3{\k#2#1}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\setkern#1#2#3{%
\Bheading{Kern} ${\typeset@glyph{#1} + \typeset@glyph{#2}}
\rightarrow \expression0{#3}$}
%
%\let\setkern=\gobble_three
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\resetkern}
% |\resetkern|\marg{glyph1}\marg{glyph2}\marg{integer expression}
%
% Resets the kern pair between \meta{glyph1} and \meta{glyph2} to
% the specified value. Note however that this does not relieve \TeX\
% of the burden to remember the previous kerning pair between these
% two glyphs (if there was one).
%
% \begin{macrocode}
%<*pkg>
\def\resetkern#1#2#3{
\x_cs\ifx{i-rawscale}\x_relax
\expandafter\reset_kern
\csname~r-#1\expandafter\endcsname
\csname~l-#2\endcsname{#3}
\else
\expandafter\reset_kern
\csname~r-#1\expandafter\endcsname
\csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}}
\fi
}
\def\reset_kern#1#2#3{
\eval_expr{#3}
\expandafter\reset_kern_cs\csname\the\result\endcsname#1#2
}
\def\reset_kern_cs#1#2#3{
\prep_to#2{\k\expandafter#3\expandafter#1}
\prep_to#3{\k\expandafter#2\expandafter#1}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\resetkern#1#2#3{%
\Bheading{Override kern} ${\typeset@glyph{#1} + \typeset@glyph{#2}}
\rightarrow \expression0{#3}$}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\setleftkerning}
% \begin{macro}{\setrightkerning}
% \begin{macro}{\setleftrightkerning}
% |\setleftkerning|\marg{glyph1}\marg{glyph2}\marg{scaled}\\
% |\setrightkerning|\marg{glyph1}\marg{glyph2}\marg{scaled}\\
% |\setleftrightkerning|\marg{glyph1}\marg{glyph2}\marg{scaled}
%
% Sets left or right kerning of \meta{glyph1} to that of \meta{glyph2}
% scaled by \meta{scaled} (which is an integer expression).
% |\setleftrightkerning| does both.
%
% \begin{macrocode}
%<*pkg>
\def\setleftkerning#1#2#3{
\eval_expr_to\b_count{#3}
\expandafter\set_kerning
\csname~l-#1\expandafter\endcsname
\csname~l-#2\endcsname
}
\def\setrightkerning#1#2#3{
\eval_expr_to\b_count{#3}
\expandafter\set_kerning
\csname~r-#1\expandafter\endcsname
\csname~r-#2\endcsname
}
\def\setleftrightkerning#1#2#3{
\eval_expr_to\b_count{#3}
\expandafter\set_kerning
\csname~l-#1\expandafter\endcsname
\csname~l-#2\endcsname
\expandafter\set_kerning
\csname~r-#1\expandafter\endcsname
\csname~r-#2\endcsname
}
\def\set_kerning#1#2{
\if\b_count=\one_thousand
\def\k##1##2{
\set_kern_cs##2##1#1
}
\else
\def\k##1##2{
\set_kern##1#1{
\scale\b_count{\expandafter\gobble_one\string##2}
}
}
\fi
#2
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\setleftkerning#1#2#3{%
\Bheading{Kern} \typeset@glyph{#1} on the left like
\typeset@glyph{#2} scaled $\expression0{#3}$}
\def\setrightkerning#1#2#3{%
\Bheading{Kern} \typeset@glyph{#1} on the right like
\typeset@glyph{#2} scaled $\expression0{#3}$}
\def\setleftrightkerning#1#2#3{%
\Bheading{Kern} \typeset@glyph{#1} on the left and right like
\typeset@glyph{#2} scaled $\expression0{#3}$}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\kerning}
% |\kerning|\marg{glyph1}\marg{glyph2}
%
% Returns the value of kern pair between \meta{glyph1} and
% \meta{glyph2} as an integer. Returns a value of zero if such a kern
% pair doesn't exist.
%
% \begin{macrocode}
%<*pkg>
\def\kerning#1#2{0\x_relax
\def\k##1{\csname~set-\string##1\endcsname\gobble_one}
\bgroup
\x_cs\def{set-\string\l-#2}##1##2{
\global\result=\expandafter\gobble_one\string##2\egroup
}
\csname~r-#1\endcsname
\csname~set-\string\l-#2\endcsname\gobble_one{00}
}
%
% \end{macrocode}
% \changes{1.909}{1999/10/19}{A use of \#1 where it should have
% been \#2 was corrected. (LH)}
% \begin{macrocode}
%\def\kerning#1#2{k(\typeset@glyph{#1})(\typeset@glyph{#2})}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifiskern}
% |\ifiskern|\marg{glyph1}\marg{glyph2}|\then|
%
% This command tests if there is a kern pair between \meta{glyph1} and
% \meta{glyph2}. It's hard to say if there is a use for it, but it is
% included for symmetry.
%
% \begin{macrocode}
%<*pkg>
\def\ifiskern#1#2\then{
\def\k##1##2{\ifx T##1 \let\k\gobble_two \fi}
\bgroup
\x_cs\let{l-#2}T
\csname r-#1\endcsname
\expandafter\egroup \ifx\k\gobble_two
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\ifiskern#1#2\then{%
\generic@if{kern \typeset@glyph{#1}${}+{}$\typeset@glyph{#2} set}}
%
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\unsetkerns}
% |\unsetkerns|\marg{left~glyph~list}\marg{right~glyph~list}
%
% This command unsets all kerns with a glyph in the \meta{left~glyph~list}
% on the left and a glyph in the \meta{right~glyph~list} on the right.
% The lists themselves are ordinary comma-separated lists. Unlike
% |\setkern| and |\resetkern|, |\unsetkerns| actually removes the
% kerning pairs from \TeX's memory.
%
% The implementation itself simply goes through |\r-|\meta{left~glyph}
% for each element \meta{left~glyph} in \meta{left~glyph~list} and
% |\l-|\meta{right~glyph} for each element \meta{right~glyph} in
% \meta{right~glyph~list}, removing each |\k|\meta{token}\meta{token}
% tripple that refers to a glyph from the opposite list as it goes
% along. To make this test reasonably fast, the routine first ``marks''
% the glyphs in the other list by setting the control sequences
% |\slots-|\meta{glyph} to |U| (the letter token U). This mark is
% later removed when the |\r-|\meta{glyph} or |\l-|\meta{glyph}
% respectively control sequences have been gone through; the
% |\slots-|\meta{glyph} control sequences are then set to |\relax|.
%
% \begin{macrocode}
%<*pkg>
\def\unsetkerns#1#2{
\let\k\k_unless_to_U
\process_csep_list\make_slots_U#1,\process_csep_list,
\def\do##1{\x_cs\main_remove_Us{l-##1}}
\process_csep_list\do#2,\process_csep_list,
\process_csep_list\make_slots_relax#1,\process_csep_list,
\process_csep_list\make_slots_U#2,\process_csep_list,
\def\do##1{\x_cs\main_remove_Us{r-##1}}
\process_csep_list\do#1,\process_csep_list,
\process_csep_list\make_slots_relax#2,\process_csep_list,
}
\def\make_slots_U#1{\x_cs\let{slots-#1}U}
\def\make_slots_relax#1{\x_cs\let{slots-#1}\x_relax}
\def\k_unless_to_U#1#2{
\x_cs\ifx{slots-\expandafter\gobble_three\string#1}U \else
\noexpand\k\noexpand#1\noexpand#2
\fi
}
\def\main_remove_Us#1{
\ifx#1\x_relax \else
\edef#1{#1}
\ifx#1\empty_command \let#1\x_relax \fi
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\unsetkerns#1#2{%
\Bheading{Remove} all kerning pairs in
\print@csep@list{\fam0}{\{#1\}\times\{#2\}}.%
}
%
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\noleftkerning}
% \changes{1.906}{1999/07/30}{Macro added. (LH)}
% \begin{macro}{\norightkerning}
% \changes{1.906}{1999/07/30}{Macro added. (LH)}
% \begin{macro}{\noleftrightkerning}
% \changes{1.906}{1999/07/30}{Macro added. (LH)}
% The argument of these commands is the name of a glyph. The commands
% removes all kerns on the left, on the right, and on both sides
% respectively, of this glyph.
%
% \begin{macrocode}
%<*pkg>
\def\noleftkerning#1{\no_kerning{l}{#1}}
\def\norightkerning#1{\no_kerning{r}{#1}}
\def\noleftrightkerning#1{\no_kerning{l}{#1}\no_kerning{r}{#1}}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\noleftkerning#1{%
\Bheading{Remove kerns} on the left of glyphs in
\print@csep@list{\fam0}{\{#1\}}.}
\def\norightkerning#1{%
\Bheading{Remove kerns} on the right of glyphs in
\print@csep@list{\fam0}{\{#1\}}.}
\def\noleftrightkerning#1{%
\Bheading{Remove kerns} on any side of glyphs in
\print@csep@list{\fam0}{\{#1\}}.}
%
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\no_kerning}
% \changes{1.906}{1999/07/30}{Macro added. (LH)}^^A
% \changes{1.906}{1999/08/01}{Macro thoroughly rewritten. (LH)}^^A
% This macro is called as
% \begin{quote}
% |\no_kerning|\marg{side}\marg{glyph list}
% \end{quote}
% where \meta{side} is |l| or |r|, and \meta{glyph list} is a
% comma-separated list of glyph names. The macro unsets all kerns on
% the \meta{side} side of the glyphs in the \meta{glyph list}.
%
% \begin{macrocode}
%<*pkg>
\def\no_kerning#1#2{
\let\k\no_kerning_i
\def\do##1{\csname #1-##1\endcsname}
\bgroup
\aftergroup\def \aftergroup\a_macro \aftergroup{
\process_csep_list\do #2,\process_csep_list,
\aftergroup}
\egroup
\def\do##1{\expandafter\let \csname #1-##1\endcsname \x_relax}
\process_csep_list\do #2,\process_csep_list,
\let\k\no_kerning_ii
\def\do##1{\edef##1{##1}}
\a_macro
}
% \end{macrocode}
% \begin{macro}{\no_kerning_i}
% The |\no_kerning_i| macro is used by |\no_kerning| in constructing
% a list of all glyphs that a glyph in the \meta{glyph list} has a
% \meta{side} kern to, while avoiding repetitions.
% \begin{macrocode}
\def\no_kerning_i#1#2{
\ifx #1\x_relax \else
\aftergroup\do \aftergroup#1
\let #1\x_relax
\fi
}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\no_kerning_ii}
% The |\no_kerning_ii| macro is similar to the |\k_unless_to_U|
% macro.
% \begin{macrocode}
\def\no_kerning_ii#1#2{
\ifx #1\x_relax \else \noexpand\k \noexpand#1 \noexpand#2 \fi
}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
% \subsection{Glyph information}
% \label{Ssec:Glyph-info}
%
% The glyph information is kept in the macros
% \DescribeMacro{\g-NAME}|\g-|\meta{name}, which expands out to:
% \begin{quote}
% \marg{width}\marg{height}\marg{depth}\marg{italic}^^A
% \marg{mapcommands}\marg{mapfonts}
% \end{quote}
% where the \meta{mapcommands} will write out VPL |MAP| fragments to a
% |.vpl| file, and the \meta{mapfonts} will produce any |MAPFONT|
% instructions that are needed.
%
%
% \begin{macro}{\typeset@glyph}
% \changes{1.909}{1999/10/20}{Macro added, and most commands that
% print a glyph name changed to use this macro. (LH)}
% The |\typeset@glyph| macro is analogous to |\typeset@string| and
% friends.
% \begin{macrocode}
%\let\typeset@glyph=\typeset@string
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\width}
% \begin{macro}{\height}
% \begin{macro}{\depth}
% \begin{macro}{\italic}
% |\width|\marg{glyph}\\
% |\height|\marg{glyph}\\
% |\depth|\marg{glyph}\\
% |\italic|\marg{glyph}
%
% In \package{fontinst}, these macros return the width, height,
% depth, and italic correction of \meta{glyph} as an integer.
% \begin{macrocode}
%<*pkg>
\def\width{\glyph_parameter\first_of_six}
\def\height{\glyph_parameter\second_of_six}
\def\depth{\glyph_parameter\third_of_six}
\def\italic{\glyph_parameter\fourth_of_six}
%
% \end{macrocode}
%
% In \package{fontdoc}, they print symbolic representations for the
% corresponding integer expressions.
% \begin{macrocode}
%<*doc>
\def\width#1{w(\typeset@glyph{#1})}
\def\height#1{h(\typeset@glyph{#1})}
\def\depth#1{d(\typeset@glyph{#1})}
\def\italic#1{i(\typeset@glyph{#1})}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\mapcommands}
% \begin{macro}{\mapfonts}
% These are similar to |\width| and its companions, but they are not
% user level commands.
% \begin{macrocode}
%<*pkg>
\def\mapcommands{\glyph_parameter\fifth_of_six}
\def\mapfonts{\glyph_parameter\sixth_of_six}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\glyph_parameter}
% \begin{macro}{\first_of_six}
% \begin{macro}{\second_of_six}
% \begin{macro}{\third_of_six}
% \begin{macro}{\fourth_of_six}
% \begin{macro}{\fifth_of_six}
% \begin{macro}{\sixth_of_six}
% \begin{macro}{\glyph_metrics}
% These macros are used to define |\width| and its friends.
% |\glyph_parameter| takes one of the other seven for its first
% argument and a glyph name for its second argument. The
% |\glyph_metrics| macro can be used if one wants to get all the
% metric variables at once.
% \begin{macrocode}
%<*pkg>
\def\glyph_parameter#1#2{
\expandafter\expandafter\expandafter
#1\csname g-#2\endcsname
}
% \end{macrocode}
% \begin{macrocode}
\def\first_of_six#1#2#3#4#5#6{#1}
\def\second_of_six#1#2#3#4#5#6{#2}
\def\third_of_six#1#2#3#4#5#6{#3}
\def\fourth_of_six#1#2#3#4#5#6{#4}
\def\fifth_of_six#1#2#3#4#5#6{#5}
\def\sixth_of_six#1#2#3#4#5#6{#6}
% \end{macrocode}
% \begin{macrocode}
\def\glyph_metrics#1#2#3#4#5#6{
\a_count=#1
\b_count=#2
\c_count=#3
\d_count=#4~
}
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
% \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\saved_scale}
% \begin{macro}{\saved_mapfont}
% \begin{macro}{\saved_raw}
% \begin{macro}{\saved_rule}
% \begin{macro}{\saved_special}
% \begin{macro}{\saved_warning}
% \begin{macro}{\saved_movert}
% \begin{macro}{\saved_moveup}
% \begin{macro}{\saved_push}
% \begin{macro}{\saved_pop}
% These are the commands allowed inside a glyph. They are initally
% set to |\relax|, so we can |\edef| with them safely.
% \begin{macrocode}
\let\saved_scale\x_relax
\let\saved_mapfont\x_relax
\let\saved_raw\x_relax
\let\saved_rule\x_relax
\let\saved_special\x_relax
\let\saved_warning\x_relax
\let\saved_movert\x_relax
\let\saved_moveup\x_relax
\let\saved_push\x_relax
\let\saved_pop\x_relax
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
%
% When the glyph is being constructed by
% \begin{quote}
% |\setglyph|\marg{glyph} \meta{glyph commands} |\endsetglyph|
% \end{quote}
% the values of each of these parameters are kept in the following
% variables. Except for |\glyph_width|, these are kept globally,
% so they survive through |\push| \textellipsis\ |\pop| pairs. In
% addition, the current vertical offset is kept locally in
% |\glyph_voffset|. The |\glyph_maxhpos| variable globally keeps track
% of the largest horizontal offset position reached so far (with the
% possible exception of the current position, i.e.\ width, which may
% well be larger).
%
%
% \begin{macro}{\glyph_width}
% \begin{macro}{\glyph_height}
% \begin{macro}{\glyph_depth}
% \begin{macro}{\glyph_italic}
% \begin{macro}{\glyph_map_commands}
% \begin{macro}{\glyph_map_fonts}
% \begin{macro}{\glyph_voffset}
% \begin{macro}{\glyph_maxhpos}
% \changes{1.903}{1999/05/20}{Variable added. (LH)}
% \begin{macrocode}
\newcount\glyph_width
\newcount\glyph_height
\newcount\glyph_depth
\newcount\glyph_italic
\newtoks\glyph_map_commands
\newtoks\glyph_map_fonts
\newcount\glyph_voffset
\newcount\glyph_maxhpos
% \end{macrocode}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
% \end{macro} \end{macro} \end{macro}
%
% \begin{macro}{\setglyph}
% \begin{macro}{\gobble_glyph}
% The |\setglyph|\marg{name} command defines |\g-|\meta{name},
% unless |\g-|\meta{name} has already been defined.
%
% The reason |\g-|\meta{name} is defined before calling |\resetglyph|
% is to make it possible to refer to ``the glyph constructed so far''
% using |\width|\marg{name}, |\height|\marg{name}, etc.
% \begin{macrocode}
\def\setglyph#1{
\ifisglyph{#1}\then
\expandafter\gobble_glyph
\else
\x_cs\def{g-#1}{{\the\glyph_width}{\the
\glyph_height}{\the\glyph_depth}{\the\glyph_italic}{\the
\glyph_map_commands}{\the\glyph_map_fonts}}
\resetglyph{#1}
\fi
}
\long\def\gobble_glyph#1\endsetglyph{}
%
% \end{macrocode}
% \begin{macrocode}
%\def\setglyph#1{\Aheading{Glyph `#1'}}
%\long\def\setglyph#1\endsetglyph{}
% \end{macrocode}
% \end{macro} \end{macro}
%
% \begin{macro}{\resetglyph}
% The |\resetglyph|\marg{name} command redefines |\g-|\meta{name},
% regardless of whether |\g-|\meta{name} has already been defined.
%
% \begin{macrocode}
%<*pkg>
\def\resetglyph#1{
\def\glyphname{#1}
\glyph_width=0
\global\glyph_height=0
\global\glyph_depth=0
\global\glyph_italic=0
\glyph_voffset=0
\global\glyph_maxhpos=0
\global\glyph_map_commands={}
\global\glyph_map_fonts={}
}
%
% \end{macrocode}
% \begin{macrocode}
%\def\resetglyph#1{\Aheading{Reset glyph `#1'}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endsetglyph}
% \begin{macro}{\endresetglyph}
% \begin{macrocode}
%<*pkg>
\def\endsetglyph{
\x_cs\edef{g-\glyphname}
{{\the\glyph_width}{\the\glyph_height}
{\the\glyph_depth}{\the\glyph_italic}
{\the\glyph_map_commands}{\the\glyph_map_fonts}}
}
\let\endresetglyph=\endsetglyph
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\endsetglyph{}
\def\endresetglyph{}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\setscaledrawglyph}
% \begin{macro}{\setrawglyph}
% The |\setscaledrawglyph| has the syntax
% \begin{isyntax}
% |\setscaledrawglyph|\marg{glyph}\marg{font}\marg{design size}^^A
% \marg{scale}\penalty0\marg{slot}\penalty0\marg{width}\penalty0
% \marg{height}\penalty0\marg{depth}\penalty0\marg{italic}
% \end{isyntax}
% It is a generalized form of the old |\setrawglyph| command, which
% has the syntax
% \begin{isyntax}
% |\setrawglyph|\marg{glyph}\marg{font}\marg{design size}^^A
% \marg{slot}\penalty0\marg{width}\penalty0
% \marg{height}\penalty0\marg{depth}\penalty0\marg{italic}
% \end{isyntax}
% |\setrawglyph| is now syntactic sugar for the equivalent call of
% |\set|\-|scaled|\-|raw|\-|glyph|.
% \begin{macrocode}
%<*pkg>
\def\setrawglyph#1#2#3{
\setscaledrawglyph{#1}{#2}{#3}\one_thousand
}
% \end{macrocode}
%
% These commands are generated automatically, when an |.mtx| file is
% written out by |\afmtomtx|, |\pltomtx|, or |\mtxtomtx|.
%
% To illustrate the difference between |\setrawglyph| and the new
% |\set|\-|scaled|\-|raw|\-|glyph|, note that
% \begin{quote}
% |\setscaledrawglyph{fscaled}{xfont}{10pt}{800}{102}%|\\
% | {300}{600}{300}{40}|
% \end{quote}
% produces the same \texttt{fscaled} glyph as
% \begin{quote}
% |\setrawglyph{f}{xfont}{10pt}{102}{375}{750}{375}{50}|\\
% |\setglyph{fscaled} \glyph{f}{800} \endsetglyph|
% \end{quote}
%
% \begin{macrocode}
\def\setscaledrawglyph#1#2#3#4#5#6#7#8#9{
\if_undefined{g-#1}\then
\eval_expr{#4}
\ifnum \result=\one_thousand
\let\a_macro\identity_one
\else
\edef\a_macro##1{\saved_scale{\the\result}{##1}}
\fi
\eval_expr_to\a_count{#6}
\eval_expr_to\b_count{#7}
\eval_expr_to\c_count{#8}
\eval_expr_to\d_count{#9}
\ifisint{i-rawscale}\then
\e_count=\int{rawscale}
\multiply \a_count \e_count \l_rounded_thousandths\a_count
\multiply \b_count \e_count \l_rounded_thousandths\b_count
\multiply \c_count \e_count \l_rounded_thousandths\c_count
\multiply \d_count \e_count \l_rounded_thousandths\d_count
\edef\a_macro##1{\saved_scale{\the\e_count}{\a_macro{##1}}}
\fi
\x_cs\edef{g-#1}{
{\the\a_count}
{\the\b_count}
{\the\c_count}
{\the\d_count}
{\a_macro{\saved_raw{#2}{#5}{#1}}}
{\a_macro{\saved_mapfont{#2}{#3}}}
}
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\setrawglyph#1#2#3#4#5#6#7#8{\Aheading{Glyph `#1'}
\Bheading{Taken from} slot #4 in font #2}
\def\setscaledrawglyph#1#2#3#4#5#6#7#8{\Aheading{Glyph `#1'}
\Bheading{Taken from} slot #5 in font #2 scaled by #4}
%
%\def\setrawglyph#1#2#3#4#5#6#7#8{}
%\def\setscaledrawglyph#1#2#3#4#5#6#7#8#9{}
% \end{macrocode}
% \end{macro}\end{macro}
%
% \begin{macro}{\setscalednotglyph}
% \begin{macro}{\setnotglyph}
% The |\setscalednotglyph| command has the same syntax as the
% |\set|\-|scaled|\-|raw|\-|glyph| command, i.e.,
% \begin{isyntax}
% |\setscalednotglyph|\marg{glyph}\marg{font}\marg{design size}^^A
% \marg{scale}\penalty0\marg{slot}\penalty0\marg{width}\penalty0
% \marg{height}\penalty0\marg{depth}\penalty0\marg{italic}
% \end{isyntax}
% It is a generalized form of the old |\setnotglyph| command, which
% has the syntax
% \begin{isyntax}
% |\setnotglyph|\marg{glyph}\marg{font}\marg{design size}^^A
% \marg{slot}\penalty0\marg{width}\penalty0\marg{height}\penalty0
% \marg{depth}\penalty0\marg{italic}
% \end{isyntax}
% |\setnotglyph| is now syntactic sugar for the equivalent call of
% |\set|\-|scaled|\-|not|\-|glyph|.
% \begin{macrocode}
%<*pkg>
\def\setnotglyph#1#2#3{
\setscalednotglyph{#1}{#2}{#3}\one_thousand
}
% \end{macrocode}
%
% Note that only the \meta{glyph}, \meta{width}, \meta{height},
% \meta{depth}, and \meta{italic} parameters are used. The reason for
% having the other parameters is that |\set|\-|scaled|\-|not|\-^^A
% |glyph| commands can be converted to |\set|\-|scaled|\-|raw|\-^^A
% |glyph| commands when a font is reencoded. Therefore all the
% information must be present, even if it is not used by the main
% definition.
%
% To think about (LH 2000/03/02): Perhaps the \meta{mapcommands} field
% of a \texttt{-not}-glyph should contain a |\glyphwarning|, just in
% case anyone tries to use one?
% \begin{macrocode}
\def\setscalednotglyph#1#2#3#4#5#6#7#8#9{
\if_undefined{g-#1-not}\then
\eval_expr_to\a_count{#6}
\eval_expr_to\b_count{#7}
\eval_expr_to\c_count{#8}
\eval_expr_to\d_count{#9}
\ifisint{i-rawscale}\then
\e_count=\int{rawscale}
\multiply \a_count \e_count \l_rounded_thousandths\a_count
\multiply \b_count \e_count \l_rounded_thousandths\b_count
\multiply \c_count \e_count \l_rounded_thousandths\c_count
\multiply \d_count \e_count \l_rounded_thousandths\d_count
\fi
\x_cs\edef{g-#1}{
{\the\a_count}
{\the\b_count}
{\the\c_count}
{\the\d_count}
{}{}
}
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%\def\setnotglyph#1#2#3#4#5#6#7#8{\Aheading{Pseudoglyph `#1-not'}}
%\def\setscalednotglyph#1{\setnotglyph}
%\let\setnotglyph=\setrawglyph
%\let\setscalednotglyph=\setscaledrawglyph
% \end{macrocode}
% \end{macro}\end{macro}
%
% \begin{macro}{\unsetglyph}
% The |\unsetglyph|\marg{name} command makes |\g-|\meta{name}
% undefined.
%
% \begin{macrocode}
%\def\unsetglyph#1{\x_cs\let{g-#1}\x_relax}
% \end{macrocode}
% \missing{doc}{\unsetglyph}
% \end{macro}
%
%
% \subsection{Glyph commands}
%
% The \meta{glyph commands} are:
% \changes{1.908}{1999/08/22}{Glyph commands avoid \cs{edef}ing old
% contents of \cs{glyph_map_commands} and \cs{glyph_map_fonts}. (LH)}
% \begin{macro}{\glyph}
% |\glyph|\marg{glyph}\marg{scale}
% \changes{1.900}{1999/02/08}{Avoids scaling by 1000. (LH)}
%
% \begin{macrocode}
%<*pkg>
\def\glyph#1#2{
\glyph_parameter\glyph_metrics{#1}
\eval_expr_to\e_count{#2}
\ifnum \e_count=\one_thousand
\edef\a_macro{\mapcommands{#1}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
\edef\a_macro{\mapfonts{#1}}
\else
\multiply \a_count \e_count \l_rounded_thousandths\a_count
\multiply \b_count \e_count \l_rounded_thousandths\b_count
\multiply \c_count \e_count \l_rounded_thousandths\c_count
\multiply \d_count \e_count \l_rounded_thousandths\d_count
\edef\a_macro{\saved_scale{\the\e_count}{\mapcommands{#1}}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
\edef\a_macro{\saved_scale{\the\e_count}{\mapfonts{#1}}}
\fi
\advance \glyph_width \a_count
\advance \b_count \glyph_voffset
\ifnum \glyph_height<\b_count \global\glyph_height=\b_count \fi
\advance \c_count -\glyph_voffset
\ifnum \glyph_depth<\c_count \global\glyph_depth=\c_count \fi
\global\glyph_italic=\d_count
\global\glyph_map_fonts\expandafter{
\the\expandafter\glyph_map_fonts \a_macro
}
}
%
% \end{macrocode}
% \begin{macrocode}
%\def\glyph#1#2{\Bheading{Glyph} `#1' scaled $\expression0{#2}$}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\glyphrule}
% |\glyphrule|\marg{width}\marg{height}
%
% \begin{macrocode}
%<*pkg>
\def\glyphrule#1#2{
\eval_expr_to\b_count{#1} \eval_expr_to\c_count{#2}
\advance\glyph_width by \b_count
\g_eval_expr_to\glyph_depth{\max\glyph_depth{-\glyph_voffset}}
\g_eval_expr_to\glyph_height{
\max\glyph_height{\add\glyph_voffset\c_count}
}
\global\glyph_italic=0
\edef\a_macro{\saved_rule{\the\b_count}{\the\c_count}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\glyphrule#1#2{%
\Bheading{Rule} $\expression0{#1}$ by $\expression0{#2}$}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\glyphspecial}
% \begin{macro}{\glyphwarning}
% |\glyphspecial|\marg{string}\\
% |\glyphwarning|\marg{string}
%
% \begin{macrocode}
%<*pkg>
\def\glyphspecial#1{
\edef\a_macro{\saved_special{#1}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
}
\def\glyphwarning#1{
\edef\a_macro{\saved_warning{#1}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\glyphspecial#1{\Bheading{Special} `#1'}
\def\glyphwarning#1{\Bheading{Warning} `#1'}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\movert}
% \changes{1.903}{1999/05/20}{Added update of \cs{glyph_maxhpos}. (LH)}
% \begin{macro}{\moveup}
% |\movert|\marg{xoffset}\\
% |\moveup|\marg{yoffset}
%
% \begin{macrocode}
%<*pkg>
\def\movert#1{
\eval_expr{#1}
\ifnum \glyph_maxhpos<\glyph_width
\global\glyph_maxhpos\glyph_width
\fi
\ifnum 0=\result \else
\advance\glyph_width by \result
\edef\a_macro{\saved_movert{\the\result}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
\fi
}
% \end{macrocode}
% \begin{macrocode}
\def\moveup#1{
\eval_expr{#1}
\ifnum\result=0\else
\advance\glyph_voffset by \result
\edef\a_macro{\saved_moveup{\the\result}}
\global\glyph_map_commands\expandafter{
\the\expandafter\glyph_map_commands \a_macro
}
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\movert#1{\Bheading{Rt}~$\expression0{#1}$}
\def\moveup#1{\Bheading{Up}~$\expression0{#1}$}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\push}
% \changes{1.907}{1999/08/02}{Removed the \cs{edef}. (LH)}
% \begin{macro}{\pop}
% \changes{1.903}{1999/05/20}{Added update of \cs{glyph_maxhpos}. (LH)}
% \changes{1.907}{1999/08/02}{Removed the \cs{edef}. (LH)}
% \begin{macrocode}
%<*pkg>
\def\push{
\bgroup
\global\glyph_map_commands\expandafter{
\the\glyph_map_commands \saved_push
}
}
% \end{macrocode}
% \begin{macrocode}
\def\pop{
\ifnum \glyph_maxhpos<\glyph_width
\global\glyph_maxhpos\glyph_width
\fi
\egroup
\global\glyph_map_commands\expandafter{
\the\glyph_map_commands \saved_pop
}
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\push{\Bheading{Push}}
\def\pop{\Bheading{Pop}}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\resetwidth}
% \begin{macro}{\resetheight}
% \begin{macro}{\resetdepth}
% \begin{macro}{\resetitalic}
% |\resetwidth|\marg{width}\\
% |\resetheight|\marg{height}\\
% |\resetdepth|\marg{depth}\\
% |\resetitalic|\marg{italic}
%
% \begin{macrocode}
%<*pkg>
\def\resetwidth#1{\movert{\sub{#1}\glyph_width}}
\def\resetheight{\g_eval_expr_to\glyph_height}
\def\resetdepth{\g_eval_expr_to\glyph_depth}
\def\resetitalic{\g_eval_expr_to\glyph_italic}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\resetwidth#1{\Bheading{Reset width to $\expression0{#1}$}}
\def\resetheight#1{\Bheading{Reset height to $\expression0{#1}$}}
\def\resetdepth#1{\Bheading{Reset depth to $\expression0{#1}$}}
\def\resetitalic#1{\Bheading{Reset italic to $\expression0{#1}$}}
%
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\glyphpcc}
% Some syntactic sugar: |\glyphpcc| could do with optimization.
%
% |\glyphpcc|\marg{glyph}\marg{xoffset}\marg{yoffset}
%
% \begin{macrocode}
%<*pkg>
\def\glyphpcc#1#2#3{
\push
\movert{#2}
\moveup{#3}
\glyph{#1}{\one_thousand}
\pop
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\glyphpcc#1#2#3{
\push
\movert{#2}
\moveup{#3}
\glyph{#1}{1000}
\pop
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\glyphbboxright}
% \changes{1.903}{1999/05/20}{Macro added. (LH)}
% The |\glyphbboxright| command is a valid integer expression, but
% its value is only meaningful inside a |\setglyph| \textellipsis\
% |\endsetglyph| or |\resetglyph| \textellipsis\ |\endresetglyph|
% structure. There its value is almost the horizontal position of
% the right edge of the bounding box for the glyph constructed so
% far---in reality it is the greatest horizontal offset reached so
% far.
%
% \begin{macrocode}
%\def\glyphbboxright{\max\glyph_width\glyph_maxhpos}
%\def\glyphbboxright{\hbox{glyphbboxright}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\samesize}
% \changes{1.903}{1999/05/20}{Added behaviour for nonexistent glyph
% (based on a suggestion from Hilmar Schlegel) and fixed typo in
% \package{fontdoc}. (LH)}
% |\samesize|\marg{glyph}
%
% \begin{macrocode}
%<*pkg>
\def\samesize#1{
\x_cs\ifx{g-#1}\x_relax
\resetwidth{\glyphbboxright}
\else
\expandafter\expandafter\expandafter
\same_size\csname g-#1\endcsname
\fi
}
\def\same_size#1#2#3#4#5#6{
\movert{\sub{#1}\glyph_width}
\global\glyph_height=#2
\global\glyph_depth=#3
\global\glyph_italic=#4
}
%
% \end{macrocode}
% \begin{macrocode}
%\def\samesize#1{\Bheading{Reset dimensions to those of `#1'.}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifisglyph}
% The control flow command:
%
% \begin{macrocode}
%<*pkg>
\def\ifisglyph#1\then{
\x_cs\ifx{g-#1}\x_relax
\expandafter\if_false
\else
\expandafter\if_true
\fi
}
%
% \end{macrocode}
% \changes{1.911}{1999/11/30}{\protect\protect\protect\Module{misc}
% definition added. (LH)}
% |\ifisglyph| evaluates to false in \Module{misc}, since this avoids
% uses of various metric integer expressions (such as |\width|,
% |\height|, etc.) that are not defined there.
% \begin{macrocode}
%\def\ifisglyph#1\then{\generic@if{glyph \typeset@glyph{#1} set}}
%\def\ifisglyph#1\then{\iffalse}
% \end{macrocode}
% \end{macro}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \section{Converting an ETX file to a (V)PL file}
%
% \subsection{Lowest-level user interface}
%
% \DescribeMacro{\etxtovpl}
% The macro:
% \begin{quote}
% |\etxtovpl|\marg{encoding}\marg{vplfile}
% \end{quote}
% writes a virtual font (as a virtual property list) with the encoding
% \meta{encoding}. (This macro is called by |\installfont|.)
%
% \DescribeMacro{\etxtopl}
% The macro:
% \begin{quote}
% |\etxtopl|\marg{encoding}\marg{plfile}
% \end{quote}
% writes a font (as a property list) with the encoding \meta{encoding}.
% (This macro is called by |\installrawfont|.)
%
% \begin{macro}{\etxtovpl}
% \begin{macro}{\etxtopl}
% \begin{macrocode}
%<*pkg>
\def\etxtovpl#1#2{{
\def\vpl_extension{vpl}
\def\vpl_title{COMMENT}
\def\vpl_font{virtual~font}
\def\vpl_Font{Virtual~font}
\def\vpl_caller{\string\etxtovpl}
\def\vpl_to_vf##1{vpltovf~##1.vpl~##1.vf~##1.tfm}
\etx_to_font{#1}{#2}
}}
\def\etxtopl#1#2{{
\def\vpl_extension{pl}
\def\vpl_title{COMMENT}
\def\vpl_font{font}
\def\vpl_Font{Font}
\def\vpl_caller{\string\etxtopl}
\def\vpl_to_vf##1{pltotfm~##1.pl~##1.tfm}
\_including_map_false
\global\rawfont_scaling=-\p@
\etx_to_font{#1}{#2}
}}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\if_including_map_}
% \changes{1.900}{1998/10/02}{New switch that can inhibit writing of
% VPL-specific properties. (LH)}
% The v\,1.5 method of controlling whether \texttt{MAP} and
% \texttt{MAPFONT} properties should be written requires that some
% code is put in an awkward place (in |\make_mapfonts| rather than
% |\make_characters|). As the code was being reorganised anyway, it
% seemed best to let a switch control this instead. If
% |\if_including_map_| is true, \texttt{MAP} and \texttt{MAPFONT}
% properties are written to the file (which should be a VPL), if it is
% false then they are not written to the file (which is then a normal
% PL).
% \begin{macrocode}
\newif\if_including_map_
\_including_map_true
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\etx_to_font}
% |\etx_to_font|\marg{encoding}\marg{fontfile} makes a (V)PL file.
%
% \begin{macrocode}
\def\etx_to_font#1#2{
\make_assignments{#1}
\open_out{#2.\vpl_extension}
\top_of_pl_hook
\out_line{(\vpl_title\space\vpl_font\space
#2~created~by~fontinst~v\fontinstversion)}
\out_line{}
\out_line{(COMMENT~Filename:~#2.\vpl_extension)}
\out_line{(COMMENT~Created~by:~tex~\jobname)}
\out_line{(COMMENT~Created~using:~\vpl_caller{#1}{#2})}
\out_line{}
\out_line{(COMMENT~This~file~can~be~turned~into~a~\vpl_font\space
with)}
\out_line{(COMMENT~\vpl_to_vf{#2})}
\out_line{}
\out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
\out_line{}
\make_header{#1}
\if_including_map_ \make_mapfonts{#1} \fi
\make_fontdimens{#1}
\make_ligtable{#1}
\make_characters{#1}
\make_tidy{#1}
\out_line{}
\out_line{(COMMENT~END~OF~FILE~#2.\vpl_extension)}
\close_out{\vpl_Font}
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\pre_first_etx_pass_hook}
% \begin{macro}{\pre_second_etx_pass_hook}
% \begin{macro}{\pre_third_etx_pass_hook}
% \begin{macro}{\pre_fourth_etx_pass_hook}
% \begin{macro}{\post_first_etx_pass_hook}
% \begin{macro}{\post_second_etx_pass_hook}
% \begin{macro}{\post_third_etx_pass_hook}
% \begin{macro}{\post_fourth_etx_pass_hook}
% \begin{macro}{\tidying_up_hook}
% \multchanges{\cs{pre_first_etx_pass_hook}^^A
% \cs{pre_second_etx_pass_hook}\cs{pre_third_etx_pass_hook}^^A
% \cs{pre_fourth_etx_pass_hook}\cs{post_first_etx_pass_hook}^^A
% \cs{post_second_etx_pass_hook}\cs{post_third_etx_pass_hook}^^A
% \cs{post_fourth_etx_pass_hook}\cs{tidying_up_hook}}{1.900}^^A
% {1998/09/30}{ETX-to-VPL hooks added. (LH)}
% \begin{macro}{\top_of_pl_hook}
% \changes{1.912}{2000/01/29}{Property list hook added. (LH)}
% As the |\etxtovpl| and |\etxtopl| macros are the
% lowest-level interfaces to what they do that are available in
% \package{fontinst} and as the amount of code they execute is really
% quite large, I suspect that users may occationally have need of
% some robust mechanism for inserting extra code at well specified
% positions. Such a mechanism is provided by the following hooks:
% \begin{macrocode}
\let\pre_first_etx_pass_hook\x_relax
\let\pre_second_etx_pass_hook\x_relax
\let\pre_third_etx_pass_hook\x_relax
\let\pre_fourth_etx_pass_hook\x_relax
\let\post_first_etx_pass_hook\x_relax
\let\post_second_etx_pass_hook\x_relax
\let\post_third_etx_pass_hook\x_relax
\let\post_fourth_etx_pass_hook\x_relax
\let\tidying_up_hook\x_relax
\let\top_of_pl_hook\x_relax
% \end{macrocode}
% The first nine are executed at the positions of the ETX-to-VPL
% file generation that their name indicate. |\top_of_pl_hook| is
% slightly different---it is executed right after a PL or VPL file
% is opened for writing. Thus it is also used by the MTX-to-PL system.
%
% To include code in one of them, one should write things like
% \begin{quote}
% |\add_to\pre_first_etx_pass_hook|\marg{extra code}
% \end{quote}
% I (LH) have the following in my \texttt{fontinst.rc} file
% \begin{quote}
% |\add_to\top_of_pl_hook{\out_line{(COMMENT~-*-Text-*-)}}|
% \end{quote}
% Without it, my text editor annoys me by assuming that \texttt{.pl}
% stands for Perl.
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
% \end{macro} \end{macro} \end{macro} \end{macro} \end{macro}
%
%
% \subsection{Glyph to slot assignments}
%
% \changes{1.900}{1998/12/06}{New method of storing slot assignments.
% (LH)}
% The way \package{fontinst} has traditionally kept track
% of which glyph goes to which slot---information which is needed when
% writing the |LIGTABLE| in a (V)PL, for |\nextlarger|, and for the
% varchar commands---is by storing the slot number in the integer
% whose name is the name of the glyph. There are two main problems with
% this implementation: (i)~If a user sets an integer which happens to
% have the same name as a glyph that is not assigned to any slot, then
% kerns for that unused glyph might be written to the file, accidentally
% creating a kerning pair where there should be none. (ii)~It is only
% possible to store one slot number per glyph, so if one uses the same
% glyph for several slots then \package{fontinst} can only write kerns
% (and ligatures) for one of the occurences, despite the fact that all
% occurences have the same typographical need for them. These problems
% do only occur for glyphs on the right side of a ligature/kerning
% pair, but they are still serious enough. This part of
% \package{fontinst} has therefore been reimplemented.
%
% \changes{1.910}{1999/11/04}{Changed the way slot numbers are stored
% in \cs{slots-}\meta{glyph} control sequences. (LH)}
% The new implementation does not use integers, instead it uses a new
% family of macros with names on the form |\slots-|\meta{glyph}^^A
% \DescribeMacro{\slots-GLYPH}. These macros expand to sequences of
% |\do|\thinspace\meta{character}, where \meta{character} is a category
% 12 (other) token whose character code equals the slot number.
%
% In the entire space of such names, each slot sould be mensioned
% at most once, with one exception, namely the slot which serves as
% right boundary marker, which may occur twice (once for the glyph
% which actually is assigned to the slot and once for the right boundary
% marker glyph). To detect whether there is a collision between these two
% uses of the slot, the right boundary marker glyph uses |\rboundary_do|
% instead of |\do| and the glyph whose slot serves as boundarychar uses
% |\rbserver_do| instead of |\do|. By redefining these two control
% sequences to generate a warning message when appropriate, the occurence
% of such a collision can be brought to the user's attention.
%
% \changes{1.900}{1998/12/11}{Added compability code for the old
% interface for boundary ligatures and kerns. (LH)}
% As it turned out to not be such a big deal, some extra code (protected
% by a \package{docstrip} switch called \Module{boundaryCompability})
% that makes \package{fontinst} compatible with the previous syntax for
% boundary handling has been included. I don't recommend using
% it though, since it makes \package{fontinst} store almost all slot
% numbers in two places.
%
%
% \begin{macro}{\make_assignments}
% \begin{macrocode}
\def\make_assignments#1{
\let\do_slot=\assign_slot
\let\end_do_slot=\end_assign_slot
\def\do_boundary{\bgroup
\let\makerightboundary=\bad_makerightboundary
}
\let\endsetleftboundary=\egroup
\let\makerightboundary=\assign_rboundary
\pre_first_etx_pass_hook
\inputetx{#1}
\post_first_etx_pass_hook
\let\end_do_slot=\empty_command
\let\do_boundary=\x_relax
\let\endsetleftboundary=\x_relax
\let\makerightboundary=\gobble_one
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\assign_slot}
% \begin{macro}{\end_assign_slot}
% \changes{1.907}{1999/08/20}{Slots are not assigned to glyphs that
% do not exist. (LH)}
% |\assign_slot| begins the assignment of a slot to a glyph.
% |\end_assign_slot| completes it. In the time between these two,
% some information is stored in |\a_toks|, so that it can be
% modified by an intervening |\makerightboundary| (which is then
% |\assign_rboundary|).
%
% Note that the code below will not reset |\lccode0|. The value of
% this register should be considered uncertain while a ligful PL
% or VPL file is written, i.e., in ETX files.
% \SortIndex{lccode0}{\cs{lccode} 0 register\encapchar usage}
% \begin{macrocode}
\def\assign_slot{\a_toks={\do}}
\begingroup
\catcode0=12
\gdef\end_assign_slot{
\ifisglyph\slot_name\then
\lccode0=\slot_number
\lowercase{
\expandafter\add_to
\csname slots-\slot_name\expandafter\endcsname
\expandafter{\the\a_toks^^@}
}
% \x_resetint\slot_name\slot_number
\fi
}
% \end{macrocode}
% \end{macro}\end{macro}
%
%
% \begin{macro}{\assign_rboundary}
% \begin{macro}{\bad_makerightboundary}
% |\assign_rboundary| is what |\makerightboundary| is when it is
% assigning a slot to act as right boundary marker.
%
% |\bad_makerightboundary| is what |\makerightboundary| temporarily
% gets set to between |\setleftboundary| and |\endsetleftboundary|.
% \begin{macrocode}
\gdef\assign_rboundary#1{
\lccode0=\slot_number
\lowercase{\x_cs\add_to{slots-#1}{\rboundary_do^^@}}
\x_setint{\percent_char boundarychar}\slot_number
\a_toks={\rbserver_do}
}
\endgroup
\def\bad_makerightboundary#1{
\errhelp={The~left~boundary~is~not~a~slot,~so~it~cannot~serve~
as~right~boundary.}
\errmessage{Incorrect~use~of~\string\makerightboundary}
}
% \end{macrocode}
% \end{macro} \end{macro}
%
% \begin{macro}{\get_slot_num}
% \changes{1.910}{1999/11/04}{Removed redefinition of \cs{do} to
% \cs{gobble_one} from temporary definition of \cs{do}, since a
% \cs{slots-} list usually contains only one or two elements
% anyway. (LH)}
% It is sometimes necessary to get the number of an arbitrary slot
% given only the name of the glyph which has been assigned to the
% slot. In such situations, the call
% \begin{quote}
% |\get_slot_num{|\meta{glyph}|}|
% \end{quote}
% will set |\result| to the number of one such slot if the glyph has
% been assigned to some slot, or set |\result| to minus one if the glyph
% has not been assigned to a slot.
% \begin{macrocode}
\def\get_slot_num#1{
%<*!boundaryCompability>
\global\result=-1
\bgroup
\def\do{\global\result=`}
\let\rbserver_do=\do
\let\rboundary_do=\gobble_one
\csname slots-#1\endcsname
\egroup
%!boundaryCompability>
%<*boundaryCompability>
\ifisint{#1}\then
\global\result=\int{#1}
\else
\global\result=-1
\fi
\x_relax
%
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\ifisinslot}
% The call |\ifisinslot|\marg{glyph}\marg{slot}|\then| can be used to
% test whether glyph \meta{glyph} has been assigned to slot \meta{slot}.
% Both then-part and else-part of the conditional will however be
% ignored when the ETX file is read the first time, since the
% assignment of glyph to slots need not have been completed yet.
% \begin{macrocode}
\def\ifisinslot#1#2\then{
\ifx \makerightboundary\gobble_one
% \end{macrocode}
% This is used to test if the ETX file is being read in for the first
% time. It is a bit hacky, but it is efficient.
% \begin{macrocode}
\eval_expr{#2}
\begingroup
\def\do##1{\ifnum `##1=\result \let\do=\gobble_one \fi}
\def\rbserver_do{\do}
\let\rboundary_do=\gobble_one
\csname slots-#1\endcsname
\expandafter\endgroup
\ifx \do\gobble_one
\expandafter\expandafter \expandafter\if_true
\else
\expandafter\expandafter \expandafter\if_false
\fi
\else
\expandafter\gobble_if
\fi
}
%
% \end{macrocode}
% \begin{macrocode}
%<*doc>
\def\ifisinslot#1#2\then{%
\generic@if{glyph \typeset@glyph{#1} assigned to slot
$\expression0{#2}$}%
}
%
% \end{macrocode}
% \end{macro}
%
%
% \subsection{The header, mapfonts, and fontdimens}
%
% \changes{1.913}{2000/02/26}{Using \cs{make_factor} for making PL
% reals, rather than \cs{afm_convert}+\cs{vpl_real}.
% \cs{scaled_design_size} replaced by new dimen \cs{mapfont_scaling} for
% determining mapfont atsize. (LH)}
%
% \begin{macro}{\mapfont_scaling}
% The |\mapfont_scaling| dimen is used for calculating how much a mapfont
% has been scaled, for use in \texttt{FONTAT} properties, and for
% selecting the correct mapfont. It is initialized to $1$.
% \begin{macrocode}
%<*pkg>
\newdimen\mapfont_scaling
\mapfont_scaling=1pt
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\rawfont_scaling}
% The |\rawfont_scaling| dimen is used for communicating the scaling
% that has been applied to a raw font---a font being installed using
% |\install|\-|rawfont|\penalty0---out to that macro. |\rawfont_|\-^^A
% |scaling| should always be globally assigned.
% \changes{1.913}{2000/03/21}{Dimen added. (LH)}
% \begin{macrocode}
\newdimen\rawfont_scaling
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\scaled_design_size}
% \begin{macro}{\afmconvert}
% The call
% \begin{quote}
% |\afmconvert|\meta{dimen}|=|\meta{integer expression}|;|
% \end{quote}
% converts a count into a dimen, assuming the count is a number
% of AFM units. I'll assume that the largest dimension I'll have
% to deal with is 131\,pt, to try to minimize rounding errors.
%
% \begin{macrocode}
% \newdimen\scaled_design_size
% \end{macrocode}
% \begin{macrocode}
% \def\afm_convert#1=#2;{
% \eval_expr{#2}
% #1=\scaled_design_size
% \divide#1 by 8
% \multiply #1 by \result
% \divide #1 by \one_thousand
% \multiply#1 by 8
% }
% \end{macrocode}
% \end{macro} \end{macro}
%
% \begin{macro}{\vpl_real}
% \begin{macro}{\vpl_int}
% The commands |\vpl_real|\meta{dimen} and |\vpl_int|\meta{count} print
% a dimension and integer respectively in (V)PL syntax.
%
% \begin{macrocode}
\def\vpl_real#1{R~\expandafter\lose_measure\the#1}
\def\vpl_int#1{D~\the#1}
% \end{macrocode}
% \end{macro} \end{macro}
%
%
% The count register |\boundary_char| has been removed, since
% the reimplementation of the left and right boundaries have drastically
% decreased the need to check which slot serves as the right boundary.
% Instead the integer |%boundarychar| (whose name cannot normally be typed)
% is used to store the number of this slot, but the user need never (and
% should not) access this integer directly. If the integer is not set
% then no slot serves as boundarychar.
% \changes{1.900}{1998/12/04}{\cs{boundary_char} count register
% removed. Right boundary slot number is now stored in the
% \texttt{\%boundarychar} integer instead. (LH)}
%
% \begin{macro}{\side_bearings}
% \begin{macro}{\curr_bearings}
% These two dimens are used by the letterspacing mechanism.
% \begin{macrocode}
\newdimen\side_bearings
\newdimen\curr_bearings
% \end{macrocode}
% \end{macro} \end{macro}
%
% \begin{macro}{\make_header}
% \begin{macrocode}
\def\make_header#1{
\global\font_count=0
\setdim{designsize}{10pt}
\a_dimen=\dim{designsize}
\out_line{(DESIGNSIZE~\vpl_real\a_dimen)}
\x_setstr{codingscheme}{UNKNOWN}
\out_line{(CODINGSCHEME~\str{codingscheme})}
%<*boundaryCompability>
\ifisint{boundarychar}\then
\x_setint{\percent_char boundarychar}{\int{boundarychar}}
\immediate\write16{Please~use~\string\setleftboundary\space
and/or~\string\makerightboundary^^J
instead~of~setting~the~boundarychar~integer.}
\fi
%
\ifisint{\percent_char boundarychar}\then
\a_count=\int{\percent_char boundarychar}
\out_line{(BOUNDARYCHAR~\vpl_int\a_count)}
\fi
\x_setint{letterspacing}{0}
\side_bearings=\make_factor{\int{letterspacing}}\half_point
\x_setint{minimumkern}{0}
\minimum_kern=\int{minimumkern}
\out_line{}
}
% \end{macrocode}
% \changes{1.900}{1999/01/20}{Removed test for no letterspacing. (LH)}
% \changes{1.900}{1999/01/20}{Made integer expression \cs{div} a
% dimen \cs{divide}. (LH)}
% \end{macro}
%
%
% \begin{macro}{\make_mapfonts}
% \begin{macrocode}
\def\make_mapfonts#1{
\let\saved_scale\vpl_scale
\let\saved_mapfont\vpl_mapfont
\let\do_slot=\do_mapfont
\pre_second_etx_pass_hook
\inputetx{#1}
\post_second_etx_pass_hook
\out_line{}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_mapfont}
% |\do_mapfont| produces a |MAPFONT| entry for each font used by
% glyph |\slot_name|.
% \begin{macrocode}
\def\do_mapfont{
\ifisglyph\slot_name\then
\mapfonts\slot_name
\fi
}
% \end{macrocode}
% \end{macro}
%
% The following commands can be used in the \meta{mapfonts} glyph
% parameter.
%
% \begin{macro}{\vpl_scale}
% \begin{macrocode}
\def\vpl_scale#1#2{{
\mapfont_scaling=\make_factor{#1}\mapfont_scaling
#2
}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_mapfont}
% \changes{1.904}{1999/06/16}{Added \cs{record_usage}. (LH)}
% \changes{1.913}{2000/02/26}{Mapfont number control sequences are
% named \cs{\meta{scaling factor}pt-\meta{font}} instead of
% \cs{\meta{font}-\meta{scaling factor}pt}. They are also made
% \cs{mathchardef}s. (LH)}
% \begin{macrocode}
\def\vpl_mapfont#1#2{
\a_dimen=#2
\if_undefined{\the\mapfont_scaling-#1}\then
\global\x_cs\mathchardef{\the\mapfont_scaling-#1}=\font_count
\x_cs\xdef{f-\the\font_count}{\the\mapfont_scaling-#1}
\out_line{(MAPFONT~\vpl_int\font_count\space
(FONTNAME~#1)~
(FONTDSIZE~\vpl_real\a_dimen)~
(FONTAT~\vpl_real\mapfont_scaling))}
\record_usage{#1}
\global\advance\font_count by 1
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pl_mapfont}
% As PL files have no \texttt{MAPFONT} properties, the |\pl_mapfont|
% macro only needs to do one thing: copy the current value of
% |\mapfont_|\-|scaling| to |\rawfont_|\-|scaling|. This is necessary
% since if the raw font for which a ligful PL is being written has
% been scaled, then that scaling factor must be put in the appropriate
% place in the FD file entry, and the simplest way to determine this
% scaling factor is to execute the |\mapfonts| of some glyph in the
% font.
%
% Due to the fact that the second ETX file pass (that during which the
% \texttt{MAPFONT} properties are written) is skipped when a PL file
% is being written, the |\mapfonts| get executed during the fourth ETX
% file pass instead of the second. This works fine since the
% |\mapcommands| that are executed at that time when a VPL file is
% being written aren't needed for PL files.
% \changes{1.913}{2000/03/21}{Macro added. (LH)}
% \begin{macrocode}
\def\pl_mapfont#1#2{\global\rawfont_scaling=\mapfont_scaling}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\font_count}
% \begin{macro}{\next_mapfont}
% \begin{macro}{\prev_mapfont}
% \begin{macrocode}
\newcount\font_count
\newcount\next_mapfont
\newcount\prev_mapfont
% \end{macrocode}
% \end{macro} \end{macro} \end{macro}
%
%
% \begin{macro}{\make_fontdimens}
% This macro writes the \texttt{FONTDIMEN} property list. Note that
% there is a difference between fontdimen 1 and the others, in that
% fontdimen 1 is always in \texttt{pt}, not in the atsize-relative
% \texttt{FONTUNITS} unit that the others are. Nonetheless, they can
% both be treated the same here. This relies on (i) that 1000 denotes
% the factor 1, and (ii) that 1000 AFM units equals 1 fontunit.
% \begin{macrocode}
\def\make_fontdimens#1{
\out_line{(FONTDIMEN}
\a_count=1
\loop\ifnum 256>\a_count
\ifisint{fontdimen(\the\a_count)}\then
\out_lline{(PARAMETER~\vpl_int\a_count\space
R~\make_factor{\int{fontdimen(\the\a_count)}})}
\fi
\advance \a_count \@ne
\repeat
\out_lline{)}
\out_line{}
}
% \end{macrocode}
% \end{macro}
%
%
% \subsection{The ligtable}
%
% \begin{macro}{\make_ligtable}
% \begin{macrocode}
\def\make_ligtable#1{
\bgroup
\out_line{(LIGTABLE}
% \let\do_slot=\bgroup
%<*boundaryCompability>
\def\do_slot{\bgroup
\ifisint{boundarychar}\then
\ifnum \int{boundarychar}=\slot_number
\def\vpl_liglabel{\out_liglabel\boundary_liglabel}
\fi
\fi
}
%
\let\end_do_slot=\vpl_kerning
\def\do_boundary{\bgroup \let\vpl_liglabel=\boundary_liglabel}
\let\endsetleftboundary=\vpl_kerning
\let\ligature=\vpl_ligature
\let\k=\vpl_kern
\let\rbserver_do=\vpl_rbserver_do
\let\rboundary_do=\vpl_rboundary_do
\pre_third_etx_pass_hook
\inputetx{#1}
\post_third_etx_pass_hook
\out_lline{)}
\egroup
\out_line{}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_rbserver_do}
% \begin{macro}{\vpl_rboundary_do}
% \begin{macro}{\wrn_rboundary_do}
% |\vpl_rbserver_do| and |\vpl_rboundary_do| are what |\rbserver_do|
% and |\rboundary_do| respectively are when a ligkern program is being
% written and no entry has yet been written for the boundarychar
% slot. |\wrn_rboundary_do| is what one of them will get set to
% afterwards, so that warnings are written when collisions between
% using the slot as a right boundary marker and using the slot for
% the actual glyph occur.
% \begin{macrocode}
\def\vpl_rbserver_do#1{
\do{#1}
\let\rboundary_do=\wrn_rboundary_do
}
\def\vpl_rboundary_do#1{
\do{#1}
\let\rbserver_do=\wrn_rboundary_do
}
\def\wrn_rboundary_do#1{
\do{#1}
\immediate\write16{Boundarychar~slot~usage~collision~in~
`\slot_name'~ligkern~program.}
}
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
%
% \begin{macro}{\vpl_ligature}
% |\vpl_ligature{|\meta{type}|}{|\meta{glyph}|}{|\meta{glyph}|}|
% produces a ligtable entry for glyph |\slot_name|.
%
% The double spaces in the |\out_lline| statement below might look
% strange, but |\number| will always gobble the first one.
% \begin{macrocode}
\def\vpl_ligature#1#2#3{
\get_slot_num{#3}
\ifnum -1=\result
\immediate\write16{Warning:~\string\ligature\space
for~unknown~slot~`#3'.}
\else
\x_cs\ifx{slots-#2}\x_relax
\immediate\write16{Warning:~\string\ligature\space
for~unknown~slot~`#2'.}
\else
\def\do##1{
\vpl_liglabel
\out_lline{(#1~D~\number`##1~\space\vpl_int\result)~
(COMMENT~#2~#3)}
}
\csname slots-#2\endcsname
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\vpl_kerning}
% |\vpl_kerning| writes out kerning instructions.
% \begin{macrocode}
\def\vpl_kerning{
\let\do=\vpl_kern_do
\csname~r-\slot_name\endcsname
\vpl_ligstop
\egroup
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_kern}
% |\vpl_kern|\,|\l-|\meta{name}\,|\|\meta{amount} writes out a |KRN|
% instruction.
%
% \changes{1.900}{1998/10/02}{Macro modified to avoid duplicate kerns.
% (LH)}
% |\vpl_kern| has been modified so that at most one
% \texttt{KRN} instruction is written for each (ordered) pair of
% characters. The idea is basically to make \package{fontinst} forget,
% until the end of |\vpl_kerning|, that the glyph for which |\vpl_kern|
% is being called has been assigned a slot, as this stops any more
% \texttt{KRN} instructions for that particular glyph from being
% written. |\vpl_kern| has also been modified so that it will not write
% out any \texttt{KRN} instructions for kerns whose absolute value is
% less than or equal to |\minimum_kern|. |\minimum_kern| gets set to
% the value of the integer \texttt{minimumkern} in |\make_header|. If
% the user has not set \texttt{minimumkern}, a default value of 0 will
% be supplied by \package{fontinst}.
%
% \changes{1.900}{1998/12/07}{Much of the code from \cs{vpl_kern} has
% been moved to \cs{vpl_kern_do}. (LH)}
% \changes{1.913}{2000/02/26}{Using a nested \cs{ifnum} construct to
% test the condition $\left\protect\vert
% \protect\mbox{\cs{a_count}}\right\protect\vert \quotechar >
% \protect\mbox{\cs{minimum_kern}}$. (LH)}
% \begin{macrocode}
\def\vpl_kern#1#2{
\edef\a_macro{\expandafter\gobble_three\string#1}
\a_count=\expandafter\gobble_one\string#2\x_relax
\ifnum \ifnum -\a_count>\a_count - \fi\a_count>\minimum_kern
\edef\b_macro{~R~\make_factor\a_count}
\csname slots-\a_macro\endcsname
\fi
\x_cs\let{slots-\a_macro}=\x_relax
}
% \end{macrocode}
% Observation (LH 1999/03/16): The above construction has the
% side-effect that a direct contradiction between a right boundary
% glyph and a glyph in the |%boundarychar| slot won't be detected if
% one of the items in contradiction is a kern less than or equal to
% |\minimum_kern|. Perhaps this should be changed (letting |\do| equal
% to |\gobble_one| would let the dectection mechanism work, but |\do|
% would have to be restored afterwards and it is doubtful if it is
% worth it).
% \end{macro}
%
%
% \begin{macro}{\vpl_kern_do}
% |\vpl_kern_do| is what |\do| is defined to be when kerns are written.
% \begin{macrocode}
\def\vpl_kern_do#1{
\vpl_liglabel
\out_lline{
(KRN~D~\number`#1~\b_macro)~
(COMMENT~\a_macro)
}
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\out_liglabel}
% \begin{macro}{\boundary_liglabel}
% \begin{macro}{\vpl_liglabel}
% |\out_liglabel| writes out a |LIGLABEL| instruction for a slot.
% |\boundary_liglabel| writes out a |LIGLABEL| instruction for the
% |BOUNDARYCHAR| ligkern program. |\vpl_liglabel| writes out the
% correct |LIGLABEL| instruction for the current ligkern program, if it
% is approriate.
%
% \begin{macrocode}
\def\out_liglabel{
\out_lline{(LABEL~\vpl_int\slot_number)~(COMMENT~\slot_name)}
\let\vpl_liglabel=\x_relax
\let\vpl_ligstop=\out_ligstop
}
\def\boundary_liglabel{
\out_lline{(LABEL~BOUNDARYCHAR)~(COMMENT~\slot_name)}
\let\vpl_liglabel=\x_relax
\let\vpl_ligstop=\out_ligstop
}
\let\vpl_liglabel=\out_liglabel
% \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\out_ligstop}
% \begin{macro}{\vpl_ligstop}
% |\vpl_ligstop| writes out a |LIGSTOP| instruction if appropriate.
% \begin{macrocode}
\def\out_ligstop{\out_lline{(STOP)}
\let\vpl_liglabel=\out_liglabel
\let\vpl_ligstop=\x_relax}
\let\vpl_ligstop=\x_relax
% \end{macrocode}
% \end{macro} \end{macro}
%
%
% \subsection{The characters}
%
% \begin{macro}{\make_characters}
% \begin{macrocode}
\def\make_characters#1{
\bgroup
\let\do_slot=\do_character
\let\end_do_slot=\end_do_character
\let\nextlarger=\vpl_nextlarger
\let\varchar=\vpl_varchar
\let\endvarchar=\end_vpl_varchar
\let\vartop=\vpl_vartop
\let\varmid=\vpl_varmid
\let\varbot=\vpl_varbot
\let\varrep=\vpl_varrep
\if_including_map_
\let\saved_raw\vpl_raw
\let\saved_rule\vpl_rule
\let\saved_special\vpl_special
\let\saved_warning\vpl_warning
\let\saved_movert\vpl_movert
\let\saved_moveup\vpl_moveup
\let\saved_push\vpl_push
\let\saved_pop\vpl_pop
\else
\def\do_character_map{
\ifdim \rawfont_scaling=-\p@
\mapfonts\slot_name
\else
\let\do_character_map=\x_relax
\fi
}
\let\saved_mapfont\pl_mapfont
\let\saved_scale\vpl_scale
\fi
\pre_fourth_etx_pass_hook
\inputetx{#1}
\post_fourth_etx_pass_hook
\egroup
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_character}
% \changes{1.913}{2000/03/10}{Negative italic corrections \emph{are}
% written to the (V)PL being generated. (LH)}
% |\do_character| produces a character entry for glyph |\slot_name| in
% slot |\slot_number|.
%
% \begin{macrocode}
\def\do_character{
\if_undefined{g-\slot_name}\then
\expandafter\gobble_setslot
\else
\ifx\slot_name\notdef_name\else
\out_line{(CHARACTER~\vpl_int\slot_number\space
(COMMENT~\slot_name)}
\glyph_parameter\glyph_metrics\slot_name
\a_dimen=\make_factor\a_count \p@
\do_character_sidebearings
\out_lline{(CHARWD~\vpl_real\a_dimen)}
\ifnum \z@=\b_count \else
\out_lline{(CHARHT~R~\make_factor\b_count)}
\fi
\ifnum \z@=\c_count \else
\out_lline{(CHARDP~R~\make_factor\c_count)}
\fi
\ifnum \z@=\d_count \else
\out_lline{(CHARIC~R~\make_factor\d_count)}
\fi
\do_character_map
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_character_sidebearings}
% \begin{macrocode}
\def\do_character_sidebearings{
\ifisint{\slot_name-spacing}\then
\curr_bearings=\make_factor{\int{\slot_name-spacing}}\half_point
\else
\curr_bearings=\side_bearings
\fi
\advance\a_dimen by 2\curr_bearings
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_character_map}
% \begin{macrocode}
\def\do_character_map{
\global\prev_mapfont=0
\out_lline{(MAP}
\ifdim 0pt=\curr_bearings
\mapcommands\slot_name
\else
\out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}
\mapcommands\slot_name
\out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}
\fi
\out_llline{)}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\do_character_no_letterspacing}
% LH 1999/03/27: This is an alternative version of |\do_character|
% which I think is now antiquated. It used to have an advantage over
% |\do_character| in that it did not do any letterspacing (in v\,1.5,
% that was good since |\do_character| used to write code for
% letterspacing to the VPL regardless of whether is was needed or
% not), but that advantage is gone since |\do_character_map| is now
% a bit less stupid than it used to be.
%
% For the record, I don't think there ever was a user interface for
% using this macro instead of |\do_character|, but I suspect there
% are plenty of people around who have hacked it into being used.
%
% With v\,1.913 I commented it out completely, since I didn't feel
% like updating the calls to |\afm_convert|.
% \begin{macrocode}
%<*obsolete>
% \def\do_character_no_letterspacing{
% \x_cs\ifx{g-\slot_name}\x_relax
% \expandafter\gobble_setslot
% \else
% \ifx\slot_name\notdef_name\else
% \out_line{(CHARACTER~\vpl_int\slot_number\space
% (COMMENT~\slot_name)}
% \afm_convert\a_dimen=\width\slot_name;
% \out_lline{(CHARWD~\vpl_real\a_dimen)}
% \afm_convert\a_dimen=\height\slot_name;
% \out_lline{(CHARHT~\vpl_real\a_dimen)}
% \afm_convert\a_dimen=\depth\slot_name;
% \out_lline{(CHARDP~\vpl_real\a_dimen)}
% \afm_convert\a_dimen=\italic\slot_name;
% \ifnum\a_dimen>0 \out_lline{(CHARIC~\vpl_real\a_dimen)} \fi
% \global\prev_mapfont=0 \out_lline{(MAP}
% \mapcommands\slot_name
% \out_llline{)}
% \fi
% \fi
% }
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\gobble_setslot}
% \begin{macrocode}
\long\def\gobble_setslot#1\endsetslot{\endsetslot}
% \end{macrocode}
% \changes{1.901}{1999/03/27}{Made \cs{gobble_setslot} a \cs{long}
% macro. (LH)}
% \end{macro}
%
% \begin{macro}{\end_do_character}
% \begin{macrocode}
\def\end_do_character{
\ifisglyph\slot_name\then
\out_lline{)}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\notdef_name}
% \begin{macrocode}
\def\notdef_name{.notdef}
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Slot commands that put things in a character property list}
%
% Here follows the active definitions for those slot commands that
% causes things to be put in |CHARACTER| property lists.
%
% \begin{macro}{\vpl_nextlarger}
% |\vpl_nextlarger|\marg{name} produces a |NEXTLARGER| entry.
% \begin{macrocode}
\def\vpl_nextlarger#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_lline{(NEXTLARGER~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\nextlarger\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_varchar}
% \begin{macro}{\end_vpl_varchar}
% |\vpl_varchar| \meta{varchar commands} |\end_vpl_varchar| produces
% a |VARCHAR| entry.
%
% \begin{macrocode}
\def\vpl_varchar{\out_lline{(VARCHAR}}
% \end{macrocode}
% \begin{macrocode}
\def\end_vpl_varchar{\out_llline{)}}
% \end{macrocode}
% \end{macro} \end{macro}
%
%
% \begin{macro}{\vpl_vartop}
% \begin{macrocode}
\def\vpl_vartop#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_llline{(TOP~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\vartop\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_varmid}
% \begin{macrocode}
\def\vpl_varmid#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_llline{(MID~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\varmid\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_varbot}
% \begin{macrocode}
\def\vpl_varbot#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_llline{(BOT~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\varbot\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_varrep}
% \begin{macrocode}
\def\vpl_varrep#1{
\get_slot_num{#1}
\ifnum -1<\result
\out_llline{(REP~D~\the\result)~(COMMENT~#1)}
\else
\immediate\write16{Warning:~\string\varrep\space
for~unknown~slot~`#1'}
\fi
}
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Saved map commands}
%
% The following commands (and |\vpl_scale|, which is defined above) can
% be used in the \meta{mapcommands} glyph parameter.
%
% \begin{macro}{\vpl_raw}
% This macro writes the entries in a \texttt{MAP} that are needed for
% the given raw character. Note that the `at' comment below gives the
% scaling relative to the atsize of the virtual font, not the physical
% atsize.
% \SortIndex{SELECTFONT property}{\texttt{SELECTFONT} property}
% \begin{macrocode}
\def\vpl_raw#1#2#3{
\global\next_mapfont=\csname\the\mapfont_scaling-#1\endcsname
\ifnum \next_mapfont=\prev_mapfont \else
\out_llline{(SELECTFONT~\vpl_int\next_mapfont)~
(COMMENT~#1~at~
\expandafter\lose_measure \the\mapfont_scaling)}
\fi
\out_llline{(SETCHAR~D~#2)~(COMMENT~#3)}
\global\prev_mapfont=\next_mapfont
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_rule}
% \begin{macrocode}
\def\vpl_rule#1#2{
\a_dimen=\make_factor{#2}\mapfont_scaling
\b_dimen=\make_factor{#1}\mapfont_scaling
\out_llline{(SETRULE~\vpl_real\a_dimen\space\vpl_real\b_dimen)}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vpl_special}
% \begin{macro}{\vpl_warning}
% \begin{switch}{warningspecials}
% \changes{1.913}{2000/02/26}{Switch controlling whether
% \cs{glyphwarning}s should put \texttt{SPECIALS} in the VPL was
% added. (LH)}
% \begin{macrocode}
\def\vpl_special#1{
\out_llline{(SPECIAL~#1)}}
% \end{macrocode}
% \begin{macrocode}
\def\vpl_warning#1{
\ifwarningspecials
\out_llline{(SPECIAL~Warning:~#1)}
\fi
\immediate\write16{Warning:~#1.}
}
% \end{macrocode}
% \begin{macrocode}
\newif\ifwarningspecials
\warningspecialstrue
% \end{macrocode}
% \end{switch}\end{macro}\end{macro}
%
% \begin{macro}{\vpl_movert}
% \begin{macro}{\vpl_moveup}
% \begin{macrocode}
\def\vpl_movert#1{
\a_dimen=\make_factor{#1}\mapfont_scaling
\out_llline{(MOVERIGHT~\vpl_real\a_dimen)}
}
% \end{macrocode}
% \begin{macrocode}
\def\vpl_moveup#1{
\a_dimen=\make_factor{#1}\mapfont_scaling
\out_llline{(MOVEUP~\vpl_real\a_dimen)}
}
% \end{macrocode}
% \end{macro} \end{macro}
%
% \begin{macro}{\vpl_push}
% \begin{macro}{\vpl_pop}
% \begin{macrocode}
\def\vpl_push{\out_llline{(PUSH)}}
% \end{macrocode}
% \begin{macrocode}
\def\vpl_pop{\out_llline{(POP)}}
% \end{macrocode}
% \end{macro} \end{macro}
%
%
% \subsection{Tidying up}
%
% \begin{macro}{\make_tidy}
% If a VPL file was written, the tidying up consists of clearing the
% list of mapfont numbers, since that is stored globally. If a PL
% file was written, the tidying up consists of writing a
% \texttt{DESIGNUNITS} property for those fonts which need one.
% \begin{macrocode}
\def\make_tidy#1{
\tidying_up_hook
\if_including_map_
\a_count=0
\loop\ifnum \a_count<\font_count
\edef\a_macro{\csname~f-\the\a_count\endcsname}
\global\x_cs\let\a_macro\x_relax
\advance\a_count by 1
\repeat
\global\font_count=0
\else
\ifdim \rawfont_scaling<\z@
\fontinstwarning{ETX~to~(V)PL}{The~font~
\out_filename\space doesn't~contain~any~characters}
\global\rawfont_scaling=\p@
\fi
\ifdim \rawfont_scaling=\p@ \else
\out_line{(DESIGNUNITS~\vpl_real\rawfont_scaling)}
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \section{Font installation commands and \texttt{.fd} files}
%
% \DescribeMacro{\installfonts}
% \DescribeMacro{\endinstallfonts}
% The call
% \begin{quote}
% |\installfonts| \meta{install commands} |\endinstallfonts|
% \end{quote}
% is the top-level interface for installing a number of fonts
% and creating |.fd| files for them.
%
% \DescribeMacro{\installfamily}
% \DescribeMacro{\installfont}
% \DescribeMacro{\installrawfont}
% The \meta{install commands} are:
% \begin{isyntax}
% |\installfamily|\marg{encoding}\marg{family}\marg{FD-commmands}\\
% |\installfont|\marg{font-name}\marg{file-list}\marg{etx}\penalty0
% \marg{encoding}\marg{family}\marg{series}\marg{shape}\marg{size}\\
% |\installrawfont|\marg{font-name}\marg{file-list}\marg{etx}^^A
% \penalty0
% \marg{encoding}\marg{family}\marg{series}\marg{shape}\marg{size}\\
% |\installfontas|\marg{font-name}\penalty0\marg{encoding}^^A
% \marg{family}\marg{series}\marg{shape}\marg{size}
% \end{isyntax}
%
% Each |\installfamily| command causes the generation of an |.fd| file
% for \meta{encoding} and \meta{family}, which is writen out by the time
% |\endinstallfonts| is processed.
%
% Each |\installfont| generates a |.vpl| font by calling |\etxtovpl|
% and adds an |.fd| entry.
% Each |\installrawfont| generates a ligfull |.pl| font by calling
% |\etxtopl| and adds an |.fd| entry. (Raw |.pl| fonts, containing only
% the glyph metrics without any ligaturing or kerning information,
% are also generated by |\mtxtopl| called from |\transformfont|
% statements.)
%
% \changes{1.912}{2000/01/15}{\cs{install}\dots\ commands updated to
% set \cs{setsomething_global} to \cs{global} around themselves. This
% reduces problems with assignments ``not working'' due to the
% unintuitive grouping. (LH) Problem pointed out by Hilmar
% Schlegel, , and others.}
%
% \begin{macro}{\installfonts}
% Initializes the |\family_toks| token register, which is used to store
% the information which is written out to |.fd| files at the end of the
% job.
%
% \begin{macrocode}
\newtoks\family_toks
\def\installfonts{
\bgroup
\global\family_toks={}
\gdef\prev_file_list{}
\global\let\setsomething_global=\global
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\installfamily}
% |\installfamily|\marg{encoding}\marg{family}\marg{FD-commmands}
%
% Adds the command
% \begin{quote}
% |\fd_family|\marg{encoding}\marg{family}\marg{FD-commmands}
% \end{quote}
% to the token list |\family_toks| and defines a macro
% |\|\meta{encoding}|-|\meta{family}.^^A
% \DescribeMacro{\ENCODING-FAMILY}
%
% \begin{macrocode}
\def\installfamily#1#2#3{
\global\family_toks=
\expandafter{\the\family_toks\fd_family{#1}{#2}{#3}}
\global\x_cs\let{#1-#2}\empty_command
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\installfont}
% \begin{macro}{\installrawfont}
% \changes{1.904}{1999/06/16}{Added \cs{record_usage}. (LH)}
% \multchanges{\cs{installfont}\cs{installrawfont}}{1.913}{2000/03/21}
% {Moved some code from \cs{install_font} to these commands. (LH)}
% |\installfont|\marg{font-name}\marg{file-list}\marg{etx}\\
% \vadjust{}\qquad \marg{encoding}\marg{family}\marg{series}^^A
% \marg{shape}\marg{size}\\
% |\installrawfont|\marg{font-name}\marg{file-list}\marg{etx}\\
% \vadjust{}\qquad \marg{encoding}\marg{family}\marg{series}^^A
% \marg{shape}\marg{size}
%
% \begin{macrocode}
\def\installfont#1#2#3#4#5#6#7#8{
\global\let\setsomething_global=\x_relax
\input_metrics{}{#2}
\etxtovpl{#3}{#1}
\installfontas{#1}{#4}{#5}{#6}{#7}{#8}
\global\let\setsomething_global=\global
}
\def\installrawfont#1#2#3#4#5#6#7#8{
\global\let\setsomething_global=\x_relax
\xdef\out_filename{#1}
\input_metrics{\let\storemapdata=\installraw_storemap}{#2}
\let\storemapdata=\gobble_three
\etxtopl{#3}{#1}
\record_usage{#1}
\installfontas{
\ifdim \rawfont_scaling=\p@ \else
[\expandafter\lose_measure\the\rawfont_scaling]~
\fi #1
}{#4}{#5}{#6}{#7}{#8}
\global\let\setsomething_global=\global
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\installraw_storemap}
% The |\installraw_storemap| macro is a definition of |\storemapdata|
% that is used when the metrics for a ligful PL file is being inputed.
% Its job is to write a |\storemapdata| command for this PL to the
% transforms record file if the PL being written does not have the
% same name as the MTX that the metrics are taken from (the
% information is already stored if both files have the same name).
% |\out_filename| is prematurely set by |\installrawfont| (i.e., long
% before the PL file is actually opened) so that it can be used in
% comparing the file names.
% \changes{1.913}{1999/03/23}{Macro added. (LH)}
% \begin{macrocode}
\def\installraw_storemap#1#2#3{
\def\a_macro{#1}
\ifx \a_macro\out_filename \else
\record_transform{\out_filename}{\string\frommtx{#1}}{}\if_false
\fi
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\input_metrics}
% The |\input_metrics| macro takes a comma-separated list of metric
% files as its second argument and sees to that exactly these metrics
% are loaded. If the list is identical to that used in the last call
% to |\input_metrics|, then this is already the case and
% |\input_metrics| simply refrains from flushing those previous
% metrics from \TeX's memory. Otherwise it closes a group (flushing
% the metrics from a previous call), opens a group (so that these
% metrics can be flushed at the next |\installfont| or
% |\installrawfont| command, if necessary), and starts inputting the
% metrics files in question.
%
% The first argument consists of code that will be executed after the
% group has been closed and opened, but before any metrics is inputed.
% \changes{1.900}{1999/02/13}
% {Use \cs{process_csep_list} for file-list. (LH)}
% \changes{1.914}{2000/05/26}{Redefined to suite \cs{file_list_metrics}.
% In particular, there will now be a comma at the end of
% \cs{curr_file_list} and \cs{prev_file_list}. (LH)}
% \begin{macrocode}
\def\input_metrics#1#2{
\let\metrics=\file_list_metrics
\xdef\curr_file_list{#2,}
\let\metrics=\x_relax
\ifx\prev_file_list\curr_file_list\else
\egroup\bgroup
#1
\expandafter\process_csep_list \expandafter\input_mtx_file
\curr_file_list\process_csep_list,
\global\let\prev_file_list=\curr_file_list
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\file_list_metrics}
% The |\file_list_metrics| macro is a definition of |\metrics| that
% is used in the \meta{file-list} argument of |\install|\-|font| and
% |\install|\-|raw|\-|font| when that is |\xdef|ed by |\input_metrics|.
% This special definition prevents the succeeding \meta{metric
% commands} from getting expanded.
% \changes{1.914}{2000/05/26}{Macro added. (LH)}
% \begin{macrocode}
\def\file_list_metrics#1,{
\iffalse{\fi}
\a_toks=\expandafter{\curr_file_list\x_relax#1,}
\xdef\curr_file_list{\the\a_toks \iffalse}\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\installfontas}
% The |\installfontas| command has the syntax
% \begin{isyntax}
% |\installfontas|\marg{font-info}\marg{encoding}\marg{family}^^A
% \penalty0\marg{series}\penalty0\marg{shape}\penalty0\marg{size}
% \end{isyntax}
% The precise definition of a \meta{font-info} can be found in
% \cite[Sec.~4]{fntguide}, here it suffices to say that a font name
% (name of (V)PL file) is a valid \meta{font-info}. The |\installfontas|
% command adds an entry for the \meta{font-info} font to a font
% definition file, giving it the NFSS attributes \meta{encoding}^^A
% \texttt{/}\nolinebreak[1]\meta{family}\texttt{/}\nolinebreak[1]^^A
% \meta{series}\texttt{/}\nolinebreak[1]\meta{shape}\texttt{/}^^A
% \nolinebreak[1]\meta{size}. The substitution mechanism will act on
% \meta{series} and \meta{shape}, and it is therefore possible that
% \meta{font-info} will appear in more than one |\Declare|\-|Font|\-^^A
% |Shape| command. \meta{size} can be either some \meta{size-infos},
% as defined in \cite[Sec.~4]{fntguide}, or a \package{fontinst}
% shorthand for a such, declared using |\declaresize|.
% \changes{1.912}{2000/01/16}{Command added. (LH)}
% \changes{1.913}{2000/03/02}{Specification changed to allow
% arbitrary \meta{font-info}s as first argument. (LH)}
% \begin{macrocode}
\def\installfontas#1#2#3#4#5#6{
\x_cs\ifx{#2-#3-#4-#5}\x_relax
\let\do_shape=\x_relax
\x_cs\xdef{#2-#3}{
\x_cs\ifx{#2-#3}\x_relax\else
\csname#2-#3\endcsname
\fi
\do_shape{#2}{#3}{#4}{#5}
}
\fi
\let\do_size=\x_relax
\x_cs\xdef{#2-#3-#4-#5}{
\x_cs\ifx{#2-#3-#4-#5}\x_relax\else
\csname#2-#3-#4-#5\endcsname
\fi
\do_size{#6}{#1}
}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endinstallfonts}
% Finish the installation by processing the |\family_toks|
% token register, which contains the accumulated information
% to be written out to |.fd| files.
%
% \begin{macrocode}
\def\endinstallfonts{
\global\let\setsomething_global=\x_relax
\let\do_shape=\fd_shape
\let\do_size=\fd_size
\the\family_toks
\global\family_toks{}
\egroup
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\input_mtx_file}
% The |\input_mtx_macro| takes one undelimited argument. It
% interprets this argument as if it was one item in the \meta{file-list}
% argument of |\install|\-|font| or |\install|\-|rawfont|, and does
% the corresponding processing. The argument should be one of the
% following four things:
% \begin{quote}
% \meta{font}\\
% \meta{font}\verb*| scaled |\meta{rawscale factor}\\
% |\metrics| \meta{metric commands}\\
% \meta{nothing}
% \end{quote}
% If, in the first two cases, an MTX file for \meta{font} does not
% exist then it is generated on the fly from a corresponding |.pl|,
% |.afm|, or |.vpl| file in the call to |\fromany|. In the third
% case, the \meta{metric commands} simply get executed. In the fourth
% case, nothing happens.
%
% \changes{1.904}{1999/06/16}{Now using \cs{fromany} to make an MTX
% file when necessary. Furthermore testing for empty argument using
% \cs{ifx} rather than \cs{if}. (LH)}
% \changes{1.912}{2000/01/15}{Added error message. (LH) Suggested by
% Alexei Kostin.}
% \changes{1.914}{2000/05/26}{Can now accept arbitrary metric
% commands in argument. (LH)}
% \begin{macrocode}
\def\input_mtx_file#1{
\ifx\x_relax#1\x_relax
% \end{macrocode}
% This tests for an empty argument, but it also lets explicit metric
% commands be executed.
% \begin{macrocode}
\else
\get_file_name #1~scaled~1000~;
\fromany\file_name
\ifisstr{afm-name}\then
\inputmtx\file_name
\else
\fontinsterror{\string\install...}{
Font/MTX~file~\file_name\space not found
}{
You~can~insert~an~\string\inputmtx\space command~here
\messagebreak to~input~some~other~MTX~file~instead.
\ifisint{rawscale}\then \messagebreak
The~requested~raw~scaling~will~then~be~applied~on~that.
\fi
}
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\get_file_name}
% The macro |\get_file_name| is expanded in the following context
% \begin{quote}
% |\get_file_name| \meta{filename}\verb*+ scaled +\relax
% \meta{scale}\verb*+ +\meta{junk}\,|;|
% \end{quote}
%
% \begin{macrocode}
\def\get_file_name #1~scaled~#2~#3;{
\edef\file_name{#1}
\ifnum#2=\one_thousand
\unsetint{rawscale}
\else
\x_resetint{rawscale}{#2}
\fi
}
% \end{macrocode}
% \changes{1.900}{1999/02/05}{Changed \cs{setint} to \cs{resetint}.
% (LH)}
% \end{macro}
%
%
% \subsection{Writing font definition files}
%
% \begin{macro}{\fd_family}
% |\fd_family{ENCODING}{FAMILY}{FD-COMMANDS}|
%
% Writes out an |.fd| file for the specified |ENCODING| and |FAMILY|
% processing the accumulated information and default substitutions.
%
% \begin{macrocode}
\def\fd_family#1#2#3{
\a_toks{#3}
\edef\lowercase_file{\lowercase{
\edef\noexpand\lowercase_file{#1#2.fd}}}
\lowercase_file
\open_out{\lowercase_file}
\out_line{\percent_char~Filename:~\lowercase_file}
\out_line{\percent_char~Created~by:~tex~\jobname}
\out_line{\percent_char~Created~using~fontinst~v\fontinstversion}
\out_line{}
\out_line{\percent_char~THIS~FILE~SHOULD~BE~PUT~IN~A~TEX~INPUTS~
DIRECTORY}
\out_line{}
\out_line{\string\ProvidesFile{\lowercase_file}}
\out_lline{[
\the\year/
\ifnum10>\month0\fi\the\month/
\ifnum10>\day0\fi\the\day\space
Fontinst~v\fontinstversion\space
font~definitions~for~#1/#2.
]}
\out_line{}
\out_line{\string\DeclareFontFamily{#1}{#2}{\the\a_toks}}
{
\csname #1-#2\endcsname
\out_line{}
\let\do_shape=\substitute_shape
\csname #1-#2\endcsname
\let\do_shape=\remove_shape
\csname #1-#2\endcsname
}
\x_cs\g_let{#1-#2}\x_relax
\out_line{}
\out_line{\string\endinput}
\close_out{Font~definitions}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fd_shape}
% |\fd_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}|
%
% \begin{macrocode}
\def\fd_shape#1#2#3#4{
\out_line{}
\out_line{\string\DeclareFontShape{#1}{#2}{#3}{#4}\left_brace_char}
\csname #1-#2-#3-#4\endcsname
\x_cs\g_let{#1-#2-#3-#4}\empty_command
\out_line{\right_brace_char{}}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fd_size}
% |\fd_size{SIZE}{FONT-NAME}|
%
% \begin{macrocode}
\def\fd_size#1#2{
\x_cs\ifx{siz-#1}\x_relax
\out_lline{#1~#2}
\else
\out_lline{\csname siz-#1\endcsname\space #2}
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\remove_shape}
% |\remove_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}|
%
% \begin{macrocode}
\def\remove_shape#1#2#3#4{
\x_cs\g_let{#1-#2-#3-#4}\x_relax
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\substitute_shape}
% |\substitute_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}|
%
% \begin{macrocode}
\def\substitute_shape#1#2#3#4{
\edef\orig_shape{#4}
\substitute_series{#1}{#2}{#3}{\orig_shape}
\x_cs\ifx{sub-\orig_shape}\x_relax\else
\edef\subst_shape{\csname sub-\orig_shape\endcsname}
\x_cs\ifx{#1-#2-#3-\subst_shape}\x_relax
\out_line{
\string\DeclareFontShape{#1}{#2}{#3}{\subst_shape}{
<->\csname typ-\orig_shape\endcsname\space
*~#2/#3/\orig_shape
}{}
}
\x_cs\let{#1-#2-#3-\subst_shape}\empty_command
\substitute_shape{#1}{#2}{#3}{\subst_shape}
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\substitute_series}
% |\substitute_series{ENCODING}{FAMILY}{SERIES}{SHAPE}|
%
% \begin{macrocode}
\def\substitute_series#1#2#3#4{
\edef\orig_series{#3}
\x_cs\ifx{sub-\orig_series}\x_relax\else
\edef\subst_series{\csname sub-\orig_series\endcsname}
\x_cs\ifx{#1-#2-\subst_series-#4}\x_relax
\out_line{
\string\DeclareFontShape{#1}{#2}{\subst_series}{#4}{
<->\csname typ-\orig_series\endcsname\space
*~#2/\orig_series/#4
}{}
}
\x_cs\let{#1-#2-\subst_series-#4}\empty_command
\substitute_series{#1}{#2}{\subst_series}{#4}
\fi
\fi
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\substitutesilent}
% \begin{macro}{\substitutenoisy}
% |\substitutesilent{TO}{FROM}|\\
% |\substitutenoisy{TO}{FROM}|
%
% Specifies a default substitution for family or shape |TO|,
% which is substituted by family or shape |FROM|.
%
% \begin{macrocode}
\def\substitutesilent#1#2{
\x_cs\def{sub-#2}{#1}
\x_cs\def{typ-#2}{ssub}
}
\def\substitutenoisy#1#2{
\x_cs\def{sub-#2}{#1}
\x_cs\def{typ-#2}{sub}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macrocode}
\substitutesilent{bx}{b}
\substitutesilent{b}{bx}
\substitutesilent{b}{sb}
\substitutesilent{b}{db}
\substitutesilent{m}{mb}
\substitutesilent{m}{l}
% \end{macrocode}
% \begin{macrocode}
\substitutenoisy{ui}{it}
% \end{macrocode}
%
% I don't think we want these since in OT1 encoding it will
% cause the old || vs || problem. (ASAJ)
% --- Oh yes we do. (SPQR)
%
% \begin{macrocode}
\substitutesilent{sl}{it}
\substitutesilent{it}{sl}
% \end{macrocode}
%
%
% \subsection{Default encodings and font sizes}
%
% \begin{macro}{\declareencoding}
% |\declareencoding{CODINGSCHEME}{ENCODING}|
%
% Declare a macro |\enc-CODINGSCHEME| which expands to |ENCODING|.
% This is used to determine the encoding in |\pltomtx|.
%
% \begin{macrocode}
\def\declareencoding#1#2{\x_cs\edef{enc-#1}{#2}}
% \end{macrocode}
% \end{macro}
%
% Old \TeX{} text font encodings.
% \begin{macrocode}
\declareencoding{TEX~TEXT}{OT1}
\declareencoding{TEX~TEXT~WITHOUT~F-LIGATURES}{OT1}
\declareencoding{TEX~TYPEWRITER~TEXT}{OT1TT}
% \end{macrocode}
%
% Old \TeX{} math font encodings.
% \begin{macrocode}
\declareencoding{TEX~MATH~ITALIC}{OML}
\declareencoding{TEX~MATH~SYMBOLS}{OMS}
\declareencoding{TEX~MATH~EXTENSION}{OMX}
\declareencoding{LATEX~SYMBOLS}{lasy}
% \end{macrocode}
%
% Euler math font encodings.
% \begin{macrocode}
\declareencoding{TEX~TEXT~SUBSET}{eufrak}
\declareencoding{TEX~MATH~ITALIC~SUBSET}{eurm}
\declareencoding{TEX~MATH~SYMBOLS~SUBSET}{euscr}
\declareencoding{EULER~SUBSTITUTIONS~ONLY}{euex}
% \end{macrocode}
%
% New \TeX{} text font encodings.
% \begin{macrocode}
\declareencoding{EXTENDED~TEX~FONT~ENCODING~-~LATIN}{T1}
\declareencoding{TEX~TEXT~COMPANION~SYMBOLS~1---TS1}{TS1}
% \end{macrocode}
%
% Rencoded PostScript font encdings.
% \begin{macrocode}
\declareencoding{TEXBASE1ENCODING}{8r}
\declareencoding{TEX~TYPEWRITER~AND~WINDOWS~ANSI}{8y}
% \end{macrocode}
%
% \begin{macro}{\declaresize}
% |\declaresize{FONTSIZE}{LATEXSIZE}|
%
% \begin{macrocode}
\def\declaresize#1#2{\x_cs\edef{siz-#1}{#2}}
% \end{macrocode}
% \end{macro}
%
% Default sizes. An empty size argument is equivalent to |<->|,
% for use with scalable fonts.
%
% \begin{macrocode}
\declaresize{}{<->}
\declaresize{5}{<5>}
\declaresize{6}{<6>}
\declaresize{7}{<7>}
\declaresize{8}{<8>}
\declaresize{9}{<9>}
\declaresize{10}{<10>}
\declaresize{11}{<10.95>}
\declaresize{12}{<12>}
\declaresize{14}{<14.4>}
\declaresize{17}{<17.28>}
\declaresize{20}{<20.74>}
\declaresize{25}{<24.88>}
% \end{macrocode}
%
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \section{Debugging}
%
% \begin{macro}{\NOFILES}
% |\NOFILES| switches off file generation, and causes
% \package{fontinst} to only generate empty files. It only affects the
% user level commands, so it is primarily of use when debugging
% commands that build on these, such as for example the
% |\latin|\-|family| command.
% \changes{1.914}{2000/05/20}{Added \cs{reglyphfont}. (LH)}
% \begin{macrocode}
\def\NOFILES{
\def\transformfont##1##2{
\touch_file{##1.mtx}
\touch_file{##1.pl}
}
\def\reglyphfont##1##2{\touch_file{##1.mtx}}
\def\installfonts{}
\def\endinstallfonts{}
\def\installfont##1##2##3##4##5##6##7##8{
\touch_file{##1.vpl}
}
\def\installrawfont##1##2##3##4##5##6##7##8{
\touch_file{##1.pl}
}
\def\installfamily##1##2##3{\touch_file{##1##2.fd}}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\touch_file}
% \begin{macrocode}
\def\touch_file#1{
\edef\lowercase_file{\lowercase{
\edef\noexpand\lowercase_file{#1}}}
\lowercase_file
\open_out{\lowercase_file}
\out_line{\percent_char~TEST~FILE.}
\out_line{\percent_char~Created~whilst~debugging~fontinst.}
\close_out{Test~file}
}
%
% \end{macrocode}
% \end{macro}
%
% \Finale
\endinput