The fontinst utility

Alan Jeffrey, Sebastian Rahtz, Ulrik Vieth, Lars Hellström

February 5, 2005

Contents

The fontinst documentation 5

1 Files 5 1.1 Source files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2 Generated files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.3 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 About previous fontinst releases 7 2.1 Pre-doc fontinst releases . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2 About fontinst v 1.8 . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3 About this fontinst release 8 3.1 Metric packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.2 Word boundary ligatures and kerns . . . . . . . . . . . . . . . . . . 13 3.3 Changing the names of glyphs . . . . . . . . . . . . . . . . . . . . . 14 3.4 Making map file fragments . . . . . . . . . . . . . . . . . . . . . . . 16 3.5 On verbatim, typewriter, and monowidth fonts . . . . . . . . . . . 18 3.6 Tuning accent positions—an application of loops . . . . . . . . . . 19 3.7 Font installation commands . . . . . . . . . . . . . . . . . . . . . . 21 3.∞ Coming attractions . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

4 Notes on using fontinst 25 4.1 General notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 4.2 Notes on small caps and oldstyle fonts . . . . . . . . . . . . . . . . 25 4.3 fontinst variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

5 fontdoc package overview 35 5.1 Some fontdoc commands that fontinst doesn’t know . . . . . . . . . 35

a fibasics.dtx  36

6 The first and the last 36 6.1 Version numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 6.2 Special catcodes and configuration file . . . . . . . . . . . . . . . . 37 6.3 Plain TEX macros from fontinst.ini . . . . . . . . . . . . . . . . 38 7 Basic definitions 40

7.1 Declaring variables and constants . . . . . . . . . . . . . . . . . . . 40 7.2 Trigonometry macros . . . . . . . . . . . . . . . . . . . . . . . . . . 41 7.3 fontdoc-specific declarations . . . . . . . . . . . . . . . . . . . . . . 41

8 TEX hackery 45 8.1 Utiltiy macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 8.2 Testing for TEX extensions . . . . . . . . . . . . . . . . . . . . . . . 46 8.3 Writing to output files . . . . . . . . . . . . . . . . . . . . . . . . . 49 8.4 Conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 8.5 Real numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 8.6 Hexadecimal numbers . . . . . . . . . . . . . . . . . . . . . . . . . 60 8.7 Error, warning, and info messages . . . . . . . . . . . . . . . . . . 61

b ficommon.dtx  66

9 General commands 66 9.1 String expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 9.2 Integer expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 9.3 Setting variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 9.4 For loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 9.5 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

c fimain.dtx  100

10 Encoding files 100

11 Metric files 111 11.1 Kerning information . . . . . . . . . . . . . . . . . . . . . . . . . . 114 11.2 Glyph information . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 11.3 Glyph commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

12 Converting an ETX file to a (V)PL file 132 12.1 Lowest-level user interface . . . . . . . . . . . . . . . . . . . . . . . 132 12.2 Glyph to slot assignments . . . . . . . . . . . . . . . . . . . . . . . 134 12.3 The header, mapfonts, and fontdimens . . . . . . . . . . . . . . . . 137 12.4 The ligtable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 12.5 The characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 12.6 Slot commands that put things in a character property list …. 145 12.7 Saved map commands . . . . . . . . . . . . . . . . . . . . . . . . . 147 12.8 Tidying up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

13 Font installation commands and .fd files 148 13.1 Writing font definition files . . . . . . . . . . . . . . . . . . . . . . 155 13.2 The font substitution mechanism . . . . . . . . . . . . . . . . . . . 158 13.3 Default encodings and font sizes . . . . . . . . . . . . . . . . . . . 162

14 Debugging 163

d ficonv.dtx  164

15 Basic file format conversions 164 15.1 Converting an ENC file to an ETX file . . . . . . . . . . . . . . . . 164 15.2 Converting an ETX file to an ENC file . . . . . . . . . . . . . . . . 165 15.3 Converting an ETX file to CMAP file . . . . . . . . . . . . . . . . 168 15.4 Converting an AFM file to an MTX file . . . . . . . . . . . . . . . 170 15.5 Converting a PL file to an MTX file . . . . . . . . . . . . . . . . . 175 15.6 Converting an MTX file to a PL file . . . . . . . . . . . . . . . . . 183

16 Font transformations 184 16.1 Transformable metric files . . . . . . . . . . . . . . . . . . . . . . . 184 16.2 Making font transformations . . . . . . . . . . . . . . . . . . . . . 185 16.3 Changing glyph names . . . . . . . . . . . . . . . . . . . . . . . . . 193

e filtfam.dtx  202

17 Installing Latin families 202 17.1 Processing a list of weights, widths and shapes . . . . . . . . . . . 203 17.2 Faking font shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 17.3 Faking font widths . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 17.4 Installing reencoded fonts . . . . . . . . . . . . . . . . . . . . . . . 215 17.5 Default weights, widths and shapes . . . . . . . . . . . . . . . . . . 217

f fimapgen.dtx  220

18 Generating map file fragments 220 18.1 Interface to main fontinst . . . . . . . . . . . . . . . . . . . . . . . 220 18.2 User interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 18.3 Deducing values for the map file entries . . . . . . . . . . . . . . . 232 18.4 Driver makers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234

Index 241

Change History 265

Internal notes 275

A Typographic treatment 275

B Planning topics 275 B.1 Reorganisation of the source . . . . . . . . . . . . . . . . . . . . . . 275 B.2 Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275

C Contributors 276 D To do 277

D.1 Things to do in the “near” future . . . . . . . . . . . . . . . . . . . 277 D.2 Things that probably won’t be done in the near future . . . . . . . 277 D.3 Things that have been done . . . . . . . . . . . . . . . . . . . . . . 278 D.4 Other notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

E Efficiency 280 E.1 Alan Jeffrey’s tests . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 E.2 Current tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281

About the fontinst package

This document implements and describes version 1.9 of fontinst.

1 Files

1.1 Source files

The source for fontinst is currently split on the six source files fibasics.dtx,

ficommon.dtx, fimain.dtx, ficonv.dtx, filtfam.dtx, and fimapgen.dtx.

1.2 Generated files

By running the docstrip installation script fontinst.ins, the following files are generated:

fontinst.sty This is the executable file that contains all the commands that set up the fontinst utility for use.

xfntinst.sty This is a variant of fontinst.sty in which the \latinfamily

command behaves differently with respect to from which fonts the digits are picked (see below).

cfntinst.sty This is a variant of fontinst.sty which supports the old way of selecting boundarychar for fonts (i.e., by setting the integer boundarychar). It requires a bit more memory than fontinst.sty does.

fontinst.ini This file contains some very basic initialization code. It is used in case fontinst is used under iniTEX without a preloaded format.

finstmsc.sty This file contains the routines for automatic map file generation, which can now generate map files for the dvips and dvipdfm drivers. The system is extendable, so users interested in generating map files for other drivers can extend the mapfile writer’s capabilities by adding code to their finstmsc.rc files. Contributions of such code is welcome. This file also contains some seldom-used code (the ENC to ETX conversion) that has been broken off from the main fontinst utility, as it almost always just sat there and used up space for no good reason.

fontdoc.sty This file contains the fontdoc package, which can be used to typeset encoding and metric files.

csc2x.tex This file contains the reglyphing commands that set up the common caps-and-small-caps to expert names conversion. See Subsections 3.3 and 16.3 for details.

csckrn2x.tex This file is a variant of csc2x.tex, which doesn’t copy the commands that actually set glyphs.

osf2x.tex This file is a variant of csc2x.tex, which only changes the names of digits.

fontinst.ins also generates the file trig.sty, which contains David Carlisle’s trig package, and puts it in the same place as fontinst.sty.

1.3 Modules

The source is split up on the following docstrip modules: ⟨boundaryCompability⟩, fimain Guards code that is needed for fontinst to be com-

patible with the old interface for boundary ligatures and kerns. ⟨!boundaryCompability⟩, fimain Guards code that is used when fontinst is not to

be compatible with the old interface for boundary ligatures and kerns. ⟨debug⟩, filtfam Guards code in the \latinfamily section that writes INFO>

messages. ⟨doc⟩, fibasics, ficommon, and fimain Guards code that is to go into fontdoc.sty. ⟨driver⟩, all files Guards the driver code—the short piece of L^{A}TEX code in the

beginning of each file that makes it possible to typeset as a L^{A}TEX document. docstrip.ins doesn’t extract this code, but it is possible to write a script that makes docstrip extract this code if one wants to write a modified driver. It’s not usual, though.

⟨everyjob⟩, fibasics Guards the code setting \everyjob for fontinst formats (by

default not used). ⟨!glyphs⟩, ficonv Guards reglyphing setup code that is relevant when commands

that set glyphs are not to be copied. ⟨glyphs⟩, ficonv Guards reglyphing setup code that is relevant when commands

that set glyphs are to be copied. ⟨ini⟩, fibasics Guards the code for fontinst.ini. ⟨map⟩, fimapgen Guards the code for the automatic map file generation. ⟨misc⟩, fibasics, fimain, and ficonv Guards code that is only to go into

     finstmsc.sty.

⟨!misc⟩, fibasics Guards code that is not to go into finstmsc.sty. ⟨obsolete⟩, ficommon and fimain Guards miscellaneous pieces of code that are

considered obsolete. ⟨oldstyle⟩, filtfam Guards code in the \latinfamily section. The purpose of

that code is described in more detail in Section 4. ⟨oldTeX⟩, fibasics Guards code that copes with a bug in TEX versions before

3.141. ⟨!oldTeX⟩, fibasics Guards normal code that wouldn’t work satisfactory for TEX

versions before 3.141 due to a bug in those TEXs. ⟨pkg⟩, all files Guards code that is to go into fontinst.sty (and its variants). ⟨pkg2⟩, fibasics A special variant of ⟨pkg⟩ that is used for code that is to end

up at the very end of fontinst.sty.

⟨reglyphletters⟩, ficonv Guards code that sets up for changing lower case letter names to corresponding smallcaps names. Used for csc2x.tex and

csckrn2x.tex.

⟨reglyphfigures⟩, ficonv Guards code that sets up for changing ordinary figure names to corresponding oldstyle names. Used for osf2x.tex, csc2x.tex,

and csckrn2x.tex.

⟨reglyph⟩, ficonv Guards code that is to go to the reglyphing setup files

csc2x.tex and csckrn2x.tex.

⟨textcomp⟩, filtfam Guards code in the \latinfamily section that generates text symbol (TS1/“text companion”) fonts.

⟨underconstruction⟩, main Guards some code that is “under construction”.

2 About previous fontinst releases

2.1 Pre-doc fontinst releases

The following is a choice of some fontinst versions and some comments about them. The complete list of versions in the range v 0.01–1.7 can be found in the

file CHANGES.

v 0.01 was begun by Alan Jeffrey in February 1993. This was the very first version recorded in the CHANGES file.

v 0.19 was completed in April 1993 and presented at the TUG ’93 conference in July 1993. It is described in the proceedings in TUGboat 14#3 and represents one of the earliest release versions, in which the user interface was still subject to change.

v 1.0 was begun in August 1993 right after the conference and represents the beginning of a complete re-write from scratch.

v 1.333 was presented one year later at the TUG ’94 conference and is described in the proceedings in TUGboat 15#3. It uses a different user interface, which is largely the same as in the present version, although the internals of the implementation have subsequently changed quite a bit.

v 1.335 was released in September 1994 and was the last “official” release version by Alan Jeffrey. Until the summer of 1998 this was still the version to be found in the fonts/utilities/fontinst directory on CTAN. It is considered obsolete and should not be used any longer.

v 1.400 was prepared in November 1994 and was the first version which used 8r-encoded raw fonts as a basis for virtual fonts.

v 1.500 appeared on CTAN in fonts/psfonts/tools in September 1995 together with Sebastian Rahtz’s Unix shell scripts to automate the installation. This version included a completely revised implementation of \latinfamily and added the \installrawfont command to install ligful raw fonts. v 1.504 appeared on CTAN in fonts/psfonts/tools in January 1996. It added

code to install (real or faked) small caps fonts and to fake narrow fonts, if they don’t exist.

v 1.511 was one of the last beta versions by Alan Jeffrey which dates back to June 1996, but for some reason was never released. It uses the encodings 9o and 9d instead of 9t and 9e to install expertized oldstyle fonts, but this change never found its way into subsequent “unofficial” releases until v 1.8.

v 1.6 appeared on CTAN in fonts/psfonts/tools in February 1997 and was the first “unofficial” version of fontinst maintained by Sebastian Rahtz. It contains only minor changes compared to v 1.504, such as switching to lowercase file names, searching for .pl files before .afm files, and adding the textcomp installation to the distribution.

v 1.6 was re-issued on CTAN in September 1997, when the Unix shell scripts were replaced by Perl scripts. The fontinst package itself didn’t change apart from minor changes of the debugging messages.

v 1.7 is the latest “unofficial version”, which was released on CTAN in May 1998. It includes some changes to the mapping between fontname and L^{A}TEX weight codes proposed by Ulrik Vieth, as well as some code to support the use of 8r-encoded .afm files generated by ttf2afm.

2.2 About fontinst v 1.8

Version 1.8 of the fontinst utility was the first to have been converted to docstrip format (this was made by Ulrik Vieth) and it was first released in June 1998. It is based on Sebastian Rahtz’s “unofficial” fontinst releases v 1.6 and 1.7 as of February 1997 and May 1998, which, in turn, are based on Alan Jeffrey’s versions v 1.500 and 1.504 of September 1995 and January 1996. In addition, version v 1.8 also incorporated some code from Alan Jeffrey’s last beta version, v 1.511, which dates back to June 1996, but was never released to the general public for some reason.

Version 1.8 was agreed upon by the fontinst hacker community, as represented on the fontinst mailing list, as the new officially endorsed version, on which all further additions and enhancements can be based.

3 About this fontinst release

Several improvements, some of which fixes old bugs and some of which introduces new features, have been made to in particular the generation of fonts. The most important are:

• The old multiple \setkern bug, which resulted in pointless KRN instructions being written to (V)PL files have been fixed. In addition, it is now possible to reset kerns (using \resetkern) and unset kerns (using \unsetkerns,

     \noleftkerning, \norightkerning, or \noleftrightkerning).

• A bug which resulted in too few kerns being written to a font if the same glyph is used in more than one slot (this occurs if you make an all-caps font from an encoding definition file which sets \lc, \lctop, and \lclig to the same to their \uc… counterparts) has been fixed. A consequence of this fix is that you cannot access the number of the slot that glyph ⟨glyph⟩ has been assigned to as \int{⟨glyph⟩} (unless you are using cfntinst.sty), but there really is no need for you to do so either.

• There is now a proper interface for using left and right boundaries which, in contrast to the old setting of the integer boundarychar, can make use of the full generality of the PL format. (The old interface is still available if you

use cfntinst.sty.)

• fontinst can now interpret AFM files which contain non-integer dimensions. There is also a user-level interface for changing the formula according to which the italic corrections of glyphs are computed.

• The PL to MTX converter can now cope with the VPL-unique property lists VTITLE, MAP, and MAPFONT, which means that it can now convert VPL files as well. In addition to this, there are a couple of minor bugfixes and improvements in the PL to MTX conversion.

• There is now a way of overriding the PL to MTX converter’s automatic choice of encoding definition file made based on the CODINGSCHEME property of a PL file. The command \generalpltomtx lets you select which encoding definition file you want to use, as does the new \fromplgivenetx transformed font command.

• Several fontinst commands that were previously missing have been added to the fontdoc package. The most significant are probably \inputmtx and

\inputetx.

• There is now a simple way of changing the names of glyphs in metric files generated from AFM files.

• The implementation of font metrics transformations, as done by \transformfont, has been rewritten and fontinst now handles uniform scaling internally; the driver only needs to do x-scaling and slanting. This can result in different font metrics, but we think only in that it comes out more like one would expect. The user interface is the same.

• There is now a new transformed font command \fromany which searches for a font metric file in any of the four formats MTX, PL, AFM, and VPL; converting it to MTX format and possibly generating a PL as well if necessary. This command is also used by \installfont, \installrawfont, and \reglyphfont to search for font metric files, so these can now take VPL files as a source for font metric data.

• There is now a mechanism for generating the necessary map files automatically. So far it knows how to generate map files for the dvips and dvipdfm drivers, but the system can easily be extended by adding code in

the finstmsc.rc file.
• There are two new commands \setscaledrawglyph and \setscaled-
notglyph which generalize the \setrawglyph and \setnotglyph com-

mands. These commands are described in Subsection 11.2.

• The routines for converting metrics to (V)PL format has changed. As a result of this the metrics of fonts are likely to change (slightly), but the conversion is now more accurate than it used to be. A side-effect is that VPL files generated by fontinst can now be used directly as a base for other fonts (it used to be necessary to convert them to binary format and back to get the metrics right).

• finstmsc.sty now contains a new command which generates a Postscript encoding (.enc) file from an ETX file. The syntax of this command is

\etxtoenc{⟨etxfile⟩}{⟨encfile⟩}

Usually you don’t need to use this command, since the routines which generate map files will call it when the encoding used in a \reencodefont isn’t known.

• The new command

\installfontas{⟨font⟩}{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩} {⟨size⟩}

adds an entry for ⟨font⟩ with the given NFSS parameters to the corresponding FD file.

• The \set…, \reset…, and \unset… commands now behaves as one would expect even when they occur between \installfonts and \endinstallfonts—the assignments they make are no longer subject to the grouping around the metrics of individual fonts. Assignments made by these commands when they occur in MTX and ETX files are however still subject to this grouping, so that behaves as usual.

• There are two control flow commands \for and \foreach which repeatedly execute a given sequence of commands—just like a normal programming language for loop. With \for the loop variable is an integer that is incremented or decremented by an amount that is specified in the beginning of the loop. With \foreach the loop variable is a string which assumes all the values given in a comma-separated list.

• The command \offcommand turns a command ‘off’, i.e., makes it gobble its arguments and do nothing. The command \oncommand turns a command back on, i.e., restores the original definition of a command that had been turned off. Turning a command off or on when it is already off or on respectively has no effect.

• If you begin an item in the file-list argument (#2) of \installfont or \installrawfont with the command \metrics, then that item (everything up till the next comma that is not inside a group) will be interpreted as explicit metric commands that are executed after the previous font was loaded and before the next is. Thus you can do e.g.

    \installfont{. . . }{a,\metrics\unsetint{xheight},b,. . .

if you want font a to be loaded before font b, but want to use the xheight value of font b, and you don’t want to bother writing an MTX file that simply contains the command \unsetint{xheight}.

• There is now a command \fontinstcc which switches to the catcodes that are in force for most of the time that fontinst.sty is read (@ and _are letters, ~ is a space, and spaces and newlines are ignored). This makes it simpler to redefine internal control sequences. To switch back to the normal catcodes, there is the \normalcc command. Neither command has any arguments.

• The \Unicode command may be used to specify what ISO 10646/Unicode character a slot corresponds to. See page 106 for details.

• The third arguments of the \installfont and \installrawfont commands can now be a comma-separated list of ETX files.

• File names in the second and third arguments of \installfont and \installrawfont may now be suffixed by zero or more modifier clauses that can change the interpretation of a file by e.g. assigning special values to some variables while the file is read in. This is described in Subsection 3.7 below.

• The \setfontdimen command allows an ETX file to declare which integer variables correspond to font dimensions in a (V)PL file. This correspondence is used both when generating a ligful (V)PL file and when a (V)PL file is converted to an MTX file.

• finstmsc.sty now contains a new command which generates a ToUnicode CMap file from an ETX file. The syntax of this command is

\etxtocmap{⟨etxfile⟩}{⟨cmapfile⟩}

• Unicode equivalents of slots need no longer be single characters. To specify a multiple-character equivalent of a slot, use the \charseq command and place the individual characters as \Unicode commands in its arguments. For a fi slot, one would say

    \charseq{
       \Unicode{0066}{LATIN SMALL LETTER F}
       \Unicode{0069}{LATIN SMALL LETTER I}
    }

3.1 Metric packages

fontinst has traditionally come with a collection of MTX files that complement the MTX files generated from base font metrics, in that they build glyphs that may be missing from the base fonts or in some other way needs to be improved. The most well-known of these is the latin.mtx file; other examples include textcomp.mtx, mathit.mtx, and latinsc.mtx. A problem with these is however that they cannot produce optimal results for all fonts simply because there are irregular differences in how fonts are set up by the foundries. Most glyphs come out alright, but there are usually a few for which the parameters used are more or less wrong. Therefore most high quality font installations are made with modified versions of these files, where the parameters have been tuned to the specific font design.

Modifying in particular latin.mtx is however not an entirely easy task, because this is a rather large file (with plenty of archaic pieces of code in curious places). Doing it once is no big problem, but if one has to do it several times (maybe because some errors are discovered in the original latin.mtx) then it is probably no fun anymore. Furthermore, if one has two or three modified copies of this file because one has made high quality installations of that many different fonts then even a trivial bugfix might start to feel like entirely too much work.

If one has to make modifications then it is usually easier to deal with several small files (many of which can be used unchanged) than one big file. Thus it would be better if these big files were split up into several smaller ones. The main problem with splitting up something like latin.mtx is that there are some commands which are defined at the top and which are then used in almost all sections of the file. One must make certain that these commands are always loaded, which makes the metric files somewhat harder to use (especially if the one who tries to use them is not the one who wrote them).

One strategy is to include all definitions needed for a metric file in it. This has the slight disadvantage that the commands will have to be defined several times. What is worse however, is that the command definitions will appear in several files, so if one finds a bug in one of them, one cannot simply correct this bug in one place. As the number of files can soon become quite large, correcting such bugs can become a boring procedure indeed.

Another strategy is to put all the command definitions in one file and then explicitly include it in the ⟨file-list⟩ argument of \installfont. This eliminates the repeated bug fixing problem, but requires the user to do something that the computer can actually do just as well.

A third strategy is to put the command definitions in one or several files and then in each metric file the user explicitly mentions load the command definitions needed for that particular file. Metric packages uses an improved version of this strategy, since they also make it possible for fontinst to remember which packages (i.e., sets of command definitions) that have already been loaded, so that they are not unnecessarily loaded again. The newlatin.mtx file is an alternative to latin.mtx that implements this strategy. Most of the actual code is located in the following metric packages:

ltcmds.mtx Defines some common commands used by the other files.

llbuild.mtx Builds the latin lower case alphabet (unaccented letters are ‘unfakable’, the rest are constructed if not present in the base fonts).

lubuild.mtx Builds the latin upper case alphabet.

lsbuild.mtx Builds accented letters in the latin smallcaps alphabet, but only if there are unaccented letters to build them from in the base fonts.

lsfake.mtx Fakes a latin smallcaps alphabet by shrinking the upper case alphabet, but only if the glyph had not already been manufactured.

lsmisc.mtx Make some miscellaneous smallcaps glyphs (mostly

“smallcaps f-ligatures”).

ltpunct.mtx Makes digits, punctuation marks, and other symbols (mostly by marking as “unfakable”).

All of these are easy to use as components of equivalents of a modified latin.mtx files, and all dependencies of one package upon another are handled via explicit

\usemtxpackage commands.

For information on the syntax etcetera of commands related to metric packages, see Section 11.

3.2 Word boundary ligatures and kerns

One of the new features added in TEX 3 was that of ligatures and kerns with word boundaries. fontinst has had an interface for making such ligatures and kerns, but it has been completely redesigned in v 1.9 and the old interface (setting the integer boundarychar) is no longer recognized by fontinst. Files which use the old interface can still be processed with cfntinst.sty, though.

Before considering the new commands, it is suitable to make a distinction between proper glyphs and pseudoglyphs. A proper glyph has been set using one

of the commands \setrawglyph, \setglyph, and \resetglyph. A pseudoglyph

is any name used in the context of a glyph name which does not denote a proper glyph. If a pseudoglyph g-not was set using the \setnotglyph command, then \ifisglyph{g-not}\then will evaluate to true, but something can be a pseudoglyph even if an \ifisglyph test evaluates to false. The interesting point about pseudoglyphs when considering word boundaries however, is that a pseudoglyph can have ligatures and kerns.

Kerns and ligatures at the left word boundary (beginning of word) are specified

using the commands \setleftboundary and \endsetleftboundary, which are

syntactically identical to \setslot and \endsetslot respectively. One important difference is however that the argument to \setslot must be a proper glyph, while the argument to \setleftboundary may be any glyph, hence any pseudoglyph will do just fine.

   \ligature commands between \setleftboundary and \endsetleftboundary

will generate beginning of word ligatures. Kerns on the right of the glyph specified in \setleftboundary will become beginning of word kerns.

Kerns and ligatures at the right word boundary (end of word) are trickier, due to the asymmetrical nature of the ligkern table in a PL file. What a font can do is to specify that the right word boundary, for purposes of kerning and ligatures, should be interpreted as character n. By including a kern or ligature with character n on the right, that kern or ligature will be used at the end of a word, but it will also be used each time the next character is character n. Because of this, one usually wants the slot n, which the right word boundary is interpreted as being, to be empty whenever the encoding allows this.

The command

     \setrightboundary{⟨glyph⟩}

will mark the current slot as used to denote the right word boundary, and leave the slot empty, increasing the current slot number by one just like a \setslot … \endsetslot block does. Kerns on the left of ⟨glyph⟩ will be end of word kerns and \ligature commands with ⟨glyph⟩ as the second argument will be for the end of a word.

The command

     \makerightboundary{⟨glyph⟩}

is similar to \setrightboundary, but it is a slot command which may only be used

between a \setslot and the matching \endsetslot. Like \setrightboundary,

it marks the current slot as used to denote the right word boundary, but the glyph specified in the enclosing \setslot will be written to that slot. Ligatures for the glyph specified by the \setslot and ligatures for the glyph specified by the \makerightboundary will both be for this single slot. Kerns on the right of the \setslot glyph and the \makerightboundary glyph will similarly both be for this single slot. The idea is that the \setslot glyph should be used when making a kern or ligature for that glyph, while the \makerightboundary glyph should be used when making a kern or ligature for the end of a word. fontinst will warn you if these two uses of the slot directly contradict each other.

3.3 Changing the names of glyphs

Sometimes, primarily when making a virtual font from more than one raw font and two of the raw fonts contain different glyphs with the same name, it becomes necessary to change the names of some glyphs to make some sense out of it. The main source of this kind of trouble is the “caps and small caps” (SC) and “oldstyle figures” (OsF) fonts within many commercial font families. The typical problem is that what is typographically different glyphs—such as the lowercase ‘a’ (a, for fontinst) and the smallcaps ‘a’ (Asmall, for fontinst)—are given the same name by the foundry.

One way to get round this is to say for example

     \setglyph{Asmall} \glyph{a}{1000} \endsetglyph
     \setleftrightkerning{Asmall}{a}{1000}
     \unsetglyph{a}
     \noleftrightkerning{a}

and continuing like that for all the duplicate glyph names. This is however a rather prolix method and if the number of glyphs is large then it is usually simpler to use the \reglyphfont command.

To reglyph one or several fonts, one writes

     \reglyphfonts

⟨reglyphing commands⟩

     \endreglyphfonts

There are two types of reglyphing commands: the \reglyphfont command, and the commands that modify what \reglyphfont will do to the fonts it operates on. The syntax of \reglyphfont is

\reglyphfont{⟨destination font⟩}{⟨source font⟩}

The ⟨source font⟩ font here is the name (suffix not included, of course) of the font metric file one wants to change the glyph names in. This font metric file can be in any of the formats MTX, PL, AFM, and VPL, and it will be converted to MTX format if it isn’t already in that format (this happens just as for files listed in the second argument of \installfont). ⟨destination font⟩ (which must be different from ⟨source font⟩) will be taken as the name for a new .mtx file that will be generated. The destination font can differ from the source font only in two ways: the names of some glyphs in the source font might be changed, and some of the commands from the source font might not have been copied to the destination font. To what extent the fonts are different is determined by what modifying commands have been executed; when no modifying commands have been executed, the source and destination font are equal.

The modifying reglyphing commands are

     \renameglyph{⟨to⟩}{⟨from⟩}
     \renameglyphweighted{⟨to⟩}{⟨from⟩}{⟨weight⟩}
     \killglyph{⟨glyph⟩}
     \killglyphweighted{⟨glyph⟩}{⟨weight⟩}
     \offmtxcommand{⟨command⟩}
     \onmtxcommand{⟨command⟩}

\renameglyph simply declares that occurrences of the glyph name ⟨from⟩ should be replaced by the glyph name ⟨to⟩. To each glyph name is also assigned a weight, which is used by a mechanism which conditions copying of commands from the source font to the destination font by the set of glyphs that command mentions. The details of this mechanism are however somewhat tricky, so those interested in the full generality should go to Subsection 16.3. Here it needs only be noted that if one applies \killglyph to a glyph name, then (under most circumstances) commands that refer to that glyph name will not be copied to the destination font.

\offmtxcommand and \onmtxcommand also control whether commands are copied to the destination font, but they look at the actual command rather than the glyphs it refers to. For example, after the command

     \offmtxcommand{\setkern}

no \setkern commands will be copied. By using \offmtxcommand, it is possible to achieve effects similar to those of the files kernoff.mtx and glyphoff.mtx—the difference is that with \offmtxcommand, it happens at an earlier stage of the font generation. As expected, \onmtxcommand undoes the effect of \offmtxcommand.

   A special rule pertains to the \setrawglyph, \setnotglyph, \setscaledraw-
glyph, and \setscalednotglyph commands, since \transformfont doesn’t care

what something was in the source font when it generates the transformed font. To turn these commands off while reglyphing, you use \offmtxcommand on \set-

scaledrawglyph.

The effects of modifying reglyphing commands are delimited by \reglyphfonts and \endreglyphfonts, which starts and ends a group respectively.

As we expect the most common reglyphing operation will be to go from SC glyph names to expert glyph names, there is a file csc2x.tex in the fontinst distribution which contains the modifying reglyphing commands needed for setting up that conversion. Thus you can write for example

     \reglyphfonts
       \input csc2x
       \reglyphfont{padrcx8r}{padrc8r}
       \reglyphfont{padscx8r}{padsc8r}
     \endreglyphfonts

to alter the glyph names in the SC fonts in the Adobe Garamond (pad) family. Note that the names of the destination fonts here really are rather arbitrary, since they will only exist as .mtx files, and thus only need to work within your local file system. In particular, all the \setrawglyph commands in the destination font files still refer to the source font, so it is that font which the drivers need to know about.

3.4 Making map file fragments

A map file fragment is the lines^{1} of a map file that the corresponding driver would need for handling some set of fonts. When told to, fontinst can (in a fairly automatic way) create the map file fragment which is needed for the set of raw fonts fontinst has (i) installed directly (using \installrawfont) or (ii) used as a base font for some installed virtual font (generated by \installfont). fontinst does not support the map file syntaxes of every existing driver, but the system is designed to be extendable and contributions that extend its capabilities are welcome. Nor can fontinst examine your TEX system and determine every piece of information needed to make the correct map file fragments, but you can tell it roughly how your installation looks, it can make guesses which work most of the time, and you can specify most things explicitly if the guesses turn out to be wrong. Should the available options for configuring the process turn out to be inadequate for your needs, then please write to the fontinst mailing list about this—there is probably a way to improve the system so that your needs can be met.

Now what does one have to do to use this map file fragment writer, then? First you need to tell fontinst to record the information the map file fragment writer needs. You do this by giving the command

     \recordtransforms{whatever.tex}

at the beginning of the run. Here whatever.tex is the name of a file that will be created, so you can use some other name if you like. After that you do all the

calls to \transformfont, \installfont, \installrawfont, \latinfamily, etc.

you need to make the fonts you want. When you’re done, you give the command

     \endrecordtransforms

and end the run (say \bye). The file whatever.tex will now contain the information about which fonts were used and what needs to be done with them.

The second step is to actually run the map file fragment writer. Observe that it is located in the file finstmsc.sty, not fontinst.sty! The commands you need to give it can be so few that you can type them in at TEX’s * prompt, but if you are writing a command file then it should typically have the following structure (comments not necessary, of course):

\input finstmsc.sty                   % Input command definitions
⟨general settings⟩  % See below
\adddriver{⟨driver name⟩}{⟨output file⟩}  % Open output file

      \input whatever.tex                   % Write to output file

\donedrivers                          % Close output file(s), tidy up

      \bye                                  % Quit

The \adddriver command gives the order “write map file entries for the ⟨driver name⟩ DVI driver to the file ⟨output file⟩.” The plan is that it should be possible to use the name of just about any major driver (dvips, xdvi,^{2} pdftex,^{3} OzTeX, etc.) here and get suitable map file entries for that driver as output, but for the moment only the dvips and dvipdfm^{4} drivers are supported. You may also use debug for ⟨driver name⟩; the entries in the file for that “DVI driver” simply contain all the available information about each font (hence it should come handy for debugging code writing entries for real drivers) in a format that should be easy to interpret for a human. It could be the right choice if you’re going to write the map file manually.

1Not in general an entire map file, hence the word fragment.

2Or does that use the same map file as dvips? I heard somewhere that it did. /LH

3pdfTEX can read the map files generated for dvips, but a separate driver is desirable because the formats are not completely identical.

The file whatever.tex in the above example contains the commands (\makemapentry commands) that actually cause entries to be written to the output file. It also contains a number of \storemapdata commands—these describe how some given font was made. If some metric file you have used contains \setrawglyph commands that were not automatically generated by fontinst, then there might not be a \storemapdata for the font they refer to in whatever.tex, so you will have to include such a command yourself somewhere. This can for example be done in the ⟨general settings⟩ part of the above example file. The syntax of the \storemapdata command is described in Subsection 18.1.

Another class of things that will typically appear in the ⟨general settings⟩ part above is commands that will inform the routines actually writing output about your TEX system, about the set of fonts you are using on this run, or about something else that might be useful. Some such commands are of a general nature and affect what assumptions fontinst will make in certain conditions when no specific information is available. For the moment there commands are:

\AssumeMetafont Assume all fonts with PL metrics are bitmaps generated by Metafont, and therefore make no entries for them.

\AssumeAMSBSYY Assume all fonts with PL metrics have their TEX names in all upper case as postscript names—just like the Computer Modern fonts in the AMS/Blue Sky/Y&Y distribution.

\AssumeBaKoMa Assume all fonts with PL metrics have their TEX names in all lower case as postscript names—just like the Computer Modern fonts in the BaKoMa distribution.

Otherwise the default action of the routine for finding out the postscript name of a font simply is to observe that it hasn’t got a clue about what the right value is when the metrics were taken from a PL file, and therefore it writes ‘??????’ for the postscript name.

\AssumeLWFN Assume postscript fonts for which nothing else has been specified are stored in files which are named according to the MacOS scheme for LWFNs.

Otherwise the default action is to use the name of the AFM or PL from which the metrics was originally taken, and add the file suffix stored in the string PSfontsuffix. The default value of this string is .pfa, but it can be changed

using \resetstr.

If neither the default nor the LWFN scheme produce correct results then you

\specifypsfont may use the more specific \specifypsfont command, which describes exactly which file (or files, if any) a given font is stored in. For syntax and examples of usage, see Subsubsection 18.2.2. (I consider the semantics of this command to still be under development, but in order to know how to develop it further I need to know in which cases it is insufficient.)

4Whose support I made very much to illustrate that you don’t have to be a big and ancient driver like dvips to have supporting code put into fontinst. (The fact that I just happened to have printed out the documentation and that is was easy to read also helped, of course.) Note, however, that there won’t be any support for a driver unless someone sits down and writes the code for it! Don’t assume I will. /LH

Finally, there is the \declarepsencoding command which is used to link ETX files to postscript encodings. If no postscript encoding has been linked to a given ETX file then fontinst will automatically create a postscript encoding (.enc) file for that encoding, and use this file for all reencoding commands. Again, see Subsubsection 18.2.2 for syntax and examples of usage. The 8r encoding is predeclared, and it doesn’t matter if an encoding is undeclared if you never use it to reencode fonts, but there is potentially a problem with not having declared encodings you have installed and use for reencoding, as you may then find yourself having two files with identical names that define encodings that do not have the same name (as far as postscript is concerned).

3.5 On verbatim, typewriter, and monowidth fonts

The verbatim, typewriter, and monowidth concepts are common sources of confusion for those who use fontinst to install fonts with (L^{A})TEX;^{5} in particular there are many misconceptions about the relation between them. The official view (of which not much has actually been brought forward) is that these concepts are really about three quite different things.

A font is a monowidth (monospaced, fixed-pitch) font if all glyphs in it have exactly the same width. Some font formats make special provisions for such fonts; the most notable example is the AFM format, where a single CharWidth keyword specifies the width for all glyphs in the font. fontinst responds to this by including the command

     \setint{monowidth}{1}

in the MTX file generated from an AFM, but that is everything that is hard-wired into the program. That a font is monowidth is however something that one should take note of when installing it for TEX, as it means many of the glyphs in it have such a strange appearance that they are (pretty much) useless. The endash is for example usually only half as long as the hyphen and the letters in ligature glyphs are only half as wide as normal letters. Many of the ETX and MTX files that come with fontinst contain special commands to avoid making use of such degenerate glyphs.

That a font is a typewriter font really only means that it has a typewriterish look about it. The two most familiar typewriter fonts are probably Computer Modern Typewriter (cmtt) and Courier. Both of these fonts are monowidth, but there is no absolute rule about this. One of the standard TEX fonts is for example Computer Modern Variable-width Typewriter (cmvtt), which is not a monowidth font, as Figure 1 shows.

The verbatim concept has very little to do with fonts at all; in L^{A}TEX it is considered to be a property of the environment (verbatim, macrocode, etc.) rather than a property of the font. The connection there is with fonts is that the encoding of the font must contain visible ASCII (as defined in Appendix C of The TEXbook [6]) as a subset for the text to be rendered correctly. The cmtt family

5Myself not excepted. /LH

 cmtt: The quick brown fox jumps over the lazy dog.

cmvtt: The quick brown fox jumps over the lazy dog.

Figure 1: Two typewriter fonts

             TEX TEXT

                          TEX TEXT WITHOUT
                            F-LIGATURES      TEX TYPEWRITER TEXT

non-italic

            cmb10
            cmbx5–12
            cmbxsl10
            cmdunh10
            cmff10
            cmfib8
            cmr6–17
            cmsl8–12
            cmss8–17
            cmssbx10
            cmssdc10
            cmssi8–17
            cmssq8
            cmssqi8
            cmvtt10

                             cmcsc8–10 cmr5

                                                   cmsltt10 cmtcsc10 cmtt8–12

 italic  cmbxti10 cmfi10 cmti7–12 cmu10        cmitt10

Table 2: “OT1-encoded” Computer Modern fonts, collected according to the actual font encoding

is the only one amongst the original Computer Modern fonts which meets this criterium and that is the primary grounds for the idea that these three concepts should be connected. Today that reason is at best a very weak one, as all T1encoded fonts also meet the criterium of containing visible ASCII as a subset.

A circumstance which has probably added to the confusion is that OT1 is usually claimed to be an encoding. In reality the Computer Modern fonts that are declared in L^{A}TEX as being OT1 display as many as five different encodings, as shown in Table 2. Since most monowidth fonts are only used for setting verbatim text, there is some code in ot1.etx which automatically chooses a TEX TYPEWRITER TEXT encoding for the font when the monowidth integer is set. The only reason for this is the guess that this is what the user wanted.

3.6 Tuning accent positions—an application of loops

The accent placements made by latin.mtx certainly aren’t perfect for all fonts, and the only way to find out where they should be put is through trying in text the accented letters you get for a couple of values for the position parameter and deciding which one works best. Since to try one parameter value you need to (i) edit it into an MTX file, (ii) run fontinst, (iii) run VPtoVF, (iv) run TEX on some test text, and (v) print that text, trying one parameter value can take annoyingly much time. Repeating the same procedure ten times to test ten values is not something one does without being bored (unless one scripts it, of course), but it is possible to try ten parameter values in a single virtual font, and without doing very much typing.

Say you’re not too happy with how latin.mtx positions the accent in the

ohungarumlaut glyph:
     \setglyph{ohungarumlaut}
        \topaccent{o}{hungarumlaut}{500}
     \endsetglyph

The 500 is the horizontal position (in thousandths of the width of the o) that the center of hungarumlaut in the glyph constructed will have, so that is the position parameter value that you want to change. Create an MTX file containing the code

     \for(pos){250}{750}{50}
        \setglyph{ohungarumlaut\strint{pos}}
           \topaccent{o}{hungarumlaut}{\int{pos}}
        \endsetglyph
        \setleftrightkerning{ohungarumlaut\strint{pos}}
           {ohungarumlaut}{1000}
     \endfor(pos)
This will set eleven glyphs ohungarumlaut250, ohungarumlaut300, ohungarumlaut350,

…, ohungarumlaut750, each being an Hungarianly umlauted ‘o’ (i.e., an ‘ő’) but all having that umlaut in slightly different positions. In order to put them in a font, you also need to make an encoding that contains them. Therefore create an ETX file which contains the code

     \relax\encoding
     \nextslot{"C0}
     \for(pos){250}{750}{50}
        \setslot{ohungarumlaut\strint{pos}}
        \endsetslot
     \endfor(pos)
     \endencoding

The command for installing this experiment font would be something like

\installfont{⟨some name⟩}{⟨the normal list of metrics⟩,⟨the new MTX ⟩}{ot1,⟨the new ETX ⟩}{OT1}…

The reason for including ot1 in the third argument above is that you’ll need letters other than ‘ő’ against which you can compare the experimental glyphs. It would not have been possible to use t1 instead of ot1 (even though that has more Hungarian letters) since that would set all slots in the font and leave none for these experimental ohungarumlauts.

It is even possible to use a loop for making the test text. The L^{A}TEX macros

\newcount\slotcount
\newcommand\testtext[3]{%
  \slotcount=#1\relax

  \begin{description}%
  \loop\item[\the\slotcount]#3%
  \ifnum #2>\slotcount \advance \slotcount 1 \repeat
  \end{description}%
}
\DeclareTextCompositeCommand{\H}{OT1}{o}{\char\slotcount}

will let you write

\testtext{⟨first⟩}{⟨last⟩}{⟨text⟩}

to get the text ⟨text⟩ typeset once for each slot from ⟨first⟩ to ⟨last⟩ inclusive, with \H{o} ranging through the glyphs in this interval. Thus in this case \testtext

{"C0}{"CA}{Erd\H{o}s} would be a trivial test.

3.7 Font installation commands

The \installfont, \installrawfont, and \installfontas commands have the

respective syntaxes

\installfont{⟨font-name⟩}{⟨metrics⟩}{⟨etx-list⟩}

{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩} \installrawfont{⟨font-name⟩}{⟨metrics⟩}{⟨etx-list⟩} {⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩}

     \installfontas{⟨font-name⟩}

{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩}

The ⟨font-name⟩ argument and the last five arguments are common to all these commands. The first argument is the name of a TEX font to install. The last five arguments are the NFSS attributes under which that font will be declared to L^{A}TEX—encoding, family, series, shape, and size. It is worth observing that encoding names are usually in upper case, whereas the family, series, and shape are usually in lower case. The size argument is either a shorthand (declared using

\declaresize \declaresize) for a particular font size (or range of font sizes), or an explicit list of font sizes or ranges of sizes, which is copied directly to the font declaration. The most common case is to let the size argument be empty, as that is declared as a shorthand for “any size”.

The \installfontas command does not itself create the font, it just makes a note that the specified font declaration should be written to the proper FD file

at \endinstallfonts. The \installfont and \installrawfont commands do

however produce the font, in the sense that they write a VPL and PL respectively file for the font. It depends solely on the ⟨metrics⟩ and ⟨etx-list⟩ arguments what this font will contain. Many features of these arguments are new with fontinst v 1.9; therefore the complete syntaxes are described below.

Both arguments are comma-separated lists of basically file names (not including an extension). The files listed in the ⟨metrics⟩ are font metric files which together build up a glyph base (definitions of glyphs and metrics related to one or several glyphs), whereas the files listed in the ⟨etx-list⟩ are encoding definition files that select a subset of the glyph base for turning into a TEX font. The font metrics can be in either of the four formats MTX, PL, AFM, and VPL, which are considered in that order. If the metrics are not originally in MTX format then they will be converted to this format (a new file will be created) before they are used. The encoding definitions must be in ETX format. The files actually read will have a suffix .mtx, .pl, .afm, .vpl, or .etx appended to the name given, depending on which format is expected.

Within each element of the comma-separated list, the actual file name is followed by zero or more modifier clauses. A ⟨modifier clause⟩ consists of a keyword followed by some number (usually one) of arguments, separated by spaces. The whole thing looks a lot like the ⟨rule specifications⟩ of e.g. the \vrule command, but here the spaces are mandatory. The currently defined ⟨modifier clause⟩s are

option ⟨string⟩ Available for metric and encoding files. This adds ⟨string⟩ to the list of options for this file, which may affect what code the file executes. The file can then test, using the \ifoption command, whether a specific string is one of the options it was given.

scaled ⟨factor⟩ Available for metric files. Causes the rawscale integer variable to be set to the ⟨factor⟩ (an integer expression) while the file is being read. This scales glyphs and kerns that are added to the glyph base by the ⟨factor⟩.

suffix ⟨suffix⟩ Available for metric files. Causes ⟨suffix⟩ to be appended to every glyph name appearing in a glyph or kern that file adds to the glyph base. Thus “suffix /2” effectively changes a

    \setrawglyph{a}. . .

to a

    \setrawglyph{a/2}. . .

encoding ⟨etx-name⟩ Available for metric files, and forces fontinst to only consider the PL and VPL formats for this font. As these file formats do not contain glyph names, an ETX file is used to assign glyph names to the slots in the font. This ETX file is usually selected according to the CODINGSCHEME property of the PL or VPL (using the correspondances set up via the \declareencoding command), but that information is not always as one would want it (there are even fonts for which it is quite wrong). An encoding clause bypasses this automatic mechanism, so that the file ⟨etx-name⟩.etx is used instead.

mtxasetx This is available for files in the ⟨etx-list⟩. The actual function of a

⟨file-name⟩ mtxasetx

item in the ⟨etx-list⟩ is that the file ⟨file-name⟩.mtx is inputted (not ⟨file-name⟩.etx) and that the correspondance between glyph names and

slot numbers set up in \setrawglyph or \setscaledrawglyph commands

in this file is treated as if it had been set up by \setslot commands in an ETX file. Provided the MTX file is transformable, the glyph base will be unaffected.

The purpose of this feature is to simplify quick and dirty installations of odd fonts for which no suitable ETX file is available. This can be useful in early stages of the design of a new font, but is inferior to installation using proper ETX files since one for example cannot specify any ligatures in MTX files.

Furthermore there is a special exception for the ⟨metrics⟩: if the first token in one of the list items is the control sequence \metrics, then the rest of that item is interpreted as explicit metric commands to execute.

If the ⟨metrics⟩ of two subsequent \installfont or \installrawfont commands are identical then the glyph bases will be identical as well. This creates an opportunity for optimization, which fontinst makes use of by caching glyph bases from one installation command to the next so that the glyph base does not have to be rebuilt in these cases. A side-effect of this caching is that local assignments made between two font installation commands are cleared out with the glyph base, but \setint and similar fontinst commands make global assignments when used in such positions.

Some examples might be in order. The first is an adaptation of an installation command from mfnt-0.59 [2] by Matthias Clasen and Ulrik Vieth: the installation command for the 8-bit math font xma1000 (which can be thought of as being to cmmi10 sort of as ecrm1000 is to cmr10). The first three encoding clauses are more fine-tuning—without them, a few glyphs would get incorrect names—but the last two are quite essential, as the msam10 and msbm10 fonts incorrectly claim to have the coding scheme TEX MATH SYMBOLS.

  \installfont{xma1000}{%
     yma1000 encoding mcin,%
     cmr10 encoding ot1upright,%
     cmmi10,%
     cmsy10 encoding omscal,%
     msam10 encoding msam,%
     msbm10 encoding msbm,%
     mccmhax,mccmkern,mcmissing,%
     cmsy10-base,cmsy10-extra%
  }{mc}{MC}{cm}{m}{n}{<10->}

Also note the explicit L^{A}TEX size specification for the range “10 pt and up”.

The second example makes use of a suffix clause to combine the letters from one font with the digits from another.

  \installfont{msbrj8t}{msbr8r,msbrc8r suffix /2,latin}{digit2,t1}
    {T1}{msbj}{m}{n}{}

In this case, the glyph base contains the glyphs of Monotype Sabon (SabonMT)— under names such as A for ‘A’, a for ‘a’, and one for a lining digit one—as well as the glyphs of Monotype Sabon Small Caps and Oldstyle Figures (SabonMT-SCOSF)—under names such as A/2 for ‘A’, a/2 for ‘a’, and one/2 for a hanging digit one. The digit2.etx file simply makes the definition

  \setcommand\digit#1{#1/2}

which causes t1.etx to put zero/2 in slot 48 (digit zero), one/2 in slot 49 etc., instead of as it normally would zero in slot 48, one in slot 49 and so on. The net effect is that the digits in the generated msbrj8t is from msbrc8r (SabonMT-SCOSF) but everything else is from msbr8r (SabonMT).

The third example makes use of an mtxasetx clause to install (with its default encoding) a font for which creating an appropriate ETX file seems not worth the trouble.

  \installrawfont{psyr}{psyr,\metrics

     \setint{xheight}{\height{alpha}}
  }{txtfdmns,psyr mtxasetx}{U}{psy}{m}{n}{}

The effect of the second psyr is that psyr.mtx is read (in case there was no psyr.mtx then it is created from (hopefully) psyr.afm) and the information in it will form the glyph base. Because of the \metrics control sequence, the rest of that item will be interpreted as explicit metric commands modifying the glyph base, and thus the \setint command can provide a value for the xheight variable (there doesn’t seem to be such a value in the AFM). Once the glyph base is completed, the \installrawfont starts writing the file psyr.pl (that’s for the first psyr). The encoding of that font will, because of the psyr mtxasetx, be the same as that used in psyr.mtx. Finally, the txtfdmns is for txtfdmns.etx, an ETX file which sets fontdimens 1–16 as for a T1 encoded font but does not set any slots. Since psyr.mtx reinterpreted as an ETX file sets slots but no fontdimens, these complement each other nicely.

3.∞ Coming attractions

We^{6} have some new features which we have pretty much sorted out how they should work and how they should be implemented, but didn’t want to introduce in this version as the large modifications in core systems would require another pre-release version before the proper release. Instead these features will probably appear in the first pre-release of fontinst v 2.0.

3.∞.1 Bounding boxes

Han The Thanh has created an implementation of bounding box support for fontinst, and it is a modified form of that support that will make it into fontinst v 2.0. One important characteristic of this implementation is that the dimensions of the bounding box are not bundled into the same data structure (the \g-⟨glyph⟩ macros) as the glyph’s width, height, depth, and italic correction are, but stored in a separate data structure (the \gb-⟨glyph⟩ macros). A glyph doesn’t need to have its bounding box set, it is simply a piece of information that fontinst will store if you tell it to and which you can later retrieve.

The bounding box will be stored as coordinates of the sides in the normal AFM coordinate system. The commands for retrieving these coordinates will probably be

Command  Side
\bbtop{⟨glyph⟩}  top (y-coordinate)
\bbbottom{⟨glyph⟩} bottom (y-coordinate)
\bbleft{⟨glyph⟩}  left (x-coordinate)
\bbright{⟨glyph⟩} right (x-coordinate)

In Thanh’s implementation the command names are \ury, \lly, \llx, and \urx respectively instead, but I think the former are easier to remember. If no bounding box has been set for a glyph then the above commands will instead report the corresponding coordinate of the glyph’s TEX box (i.e. \height{⟨glyph⟩}, \neg{\depth{⟨glyph⟩}}, 0, and \width{⟨glyph⟩} respectively).

The command for setting the bounding box of a glyph will be

6Well, perhaps it’s just me. /LH

\setglyphbb{⟨glyph⟩}{⟨left⟩}{⟨bottom⟩}{⟨right⟩}{⟨top⟩}

4 Notes on using fontinst

The primary purpose of fontinst is to simplify the installation of PostScript or TrueType text fonts.

4.1 General notes

Leaving aside unusual variants which require special attention such as alternate or swash fonts, almost all standard font families can be installed automatically using the \latinfamily command, optionally making use of the corresponding expert fonts as well.

Depending on what kind of fonts you have and want to install, \latinfamily supports three different modes of operation:

\latinfamily{⟨fam⟩}{} installs a normal font family using 8a-encoded standard fonts (reencoded to 8r) and nothing else. It installs .fd files for the L^{A}TEX families 8r⟨fam⟩, OT1/⟨fam⟩, T1/⟨fam⟩ and TS1/⟨fam⟩, and generates virtual fonts for the 7t, 8t, and 8c encodings. This is the only option available for most typefaces which do not have an expert set.

\latinfamily{⟨fam⟩x}{} installs an expertized font family using 8a-encoded standard fonts (reencoded to 8r) and 8x-encoded expert fonts. It installs .fd files for the L^{A}TEX families, OT1/⟨fam⟩x, T1/⟨fam⟩x and TS1/⟨fam⟩x, and generates virtual fonts for the 9t, 9e and 9c encodings.

\latinfamily{⟨fam⟩j}{} installs an expertized font family with oldstyle digits using 8a-encoded standard fonts (reencoded to 8r) and 8x-encoded expert fonts. It installs .fd files for the L^{A}TEX families, OT1/⟨fam⟩j, T1/⟨fam⟩j and TS1/⟨fam⟩j, and generates virtual fonts for the 9o, 9d and 9c encodings. Since TS1 has oldstyle digits by default, the 9c-encoded fonts should be the same as in the previous case. Finally, \latinfamily{⟨fam⟩9}{} is also supported as an alternative to \latinfamily{⟨fam⟩j}{} for backwards compatibility.

The whole installation process relies on certain assumptions about the symbol complement of Adobe’s expert fonts. In particular, it is assumed that the expert fonts include the oldstyle digits and a complete set of small caps glyphs, which is an assumption that’s not always satisfied for expert fonts by other suppliers. If these glyphs are not included in the expert fonts, the only way to get them is from real small caps fonts, but this requires some reshuffling of glyph names.

To support such unusual cases, this source file contains some optional code embedded between ⟨∗oldstyle⟩ … ⟨/oldstyle⟩, which extends the behaviour of \latinfamily for expertized encodings with oldstyle digits. Instead of relying only on the glyphs of the 8r-reencoded raw font and the 8x-encoded expert font, this version also looks for corresponding OsF or SC&OsF fonts and uses the default digits from those fonts as oldstyle digits.

4.2 Notes on small caps and oldstyle fonts

The \latinfamily command is supposed to do a reasonably good job of installing a complete font family based on all the .afm files it can find. If it doesn’t find a suitable font shape, it is sometimes possible to fake it by default substitutions.

However, in the case of small caps fonts, there are several options which may require some clarification.

For the majority of typefaces, a font family typically consists only of of roman and italic fonts in several weights. Since real small caps fonts are not included, they have to be faked from the roman fonts, which is implemented by setting \encoding_shape to ‘c’, so that different encoding files OT1c.etx or T1c.etx are used. Since these files call for glyph names such as ‘Asmall’ which are not found in the roman font, the default substitutions in latin.mtx are eventually used to approximate fake small caps glyphs by scaling and letterspacing. The outcome is just an approximation for a small caps font, but it is better than nothing.

For a small number of typefaces, the standard fonts are complemented by an expert collection, which usually includes two sets of fonts. First, for each standard font there is a corresponding expert font containing additional glyphs such as extra ligatures and symbols, oldstyle digits and small capital letters. For Adobe expert fonts this set is sufficient to build a complete small caps font from the standard and expert glyphs. Furthermore, the expert collection usually also contains a number of real small caps font corresponding to the roman fonts and some OsF fonts corresponding to the italic fonts. If these fonts are available, there are several options how to install small caps fonts.

By default, \latinfamily first tries to find a real small caps font. If it is found, it is installed using the default encoding files and metric files, just like any roman or slanted font. However, once \latinfamily has taken this choice, it will fail to find a corresponding expert font, since it is actually looking for an expert font in small caps shape which doesn’t exist. (In fact, it would be an error to substitute an expert font in normal shape.) The outcome will be a virtual font based only on glyphs from the real small caps raw font, which implies ending up with oldstyle digits as the default set of digits, but allows to inherit the kerning information of the real small caps font.

Another option for an expertized installation would be to make the real small caps fonts unavailable, so that \latinfamily will attempt to fake a small caps font using glyphs from the standard and expert fonts in normal shape. This means that \encoding_shape is again set to ‘c’, so that OT1c.etx and T1c.etx are used, but this time a glyph named ‘Asmall’ does exist in the expert font and will be used instead of faked one generated by scaling. The outcome will be a font based on normal and small caps glyphs from the standard and expert fonts. The oldstyle digits will only be used if they are called for, otherwise the default digits from the roman font are used. The only drawback of this approach is that the kerning around small capital letters will be based on the scaled kern amounts of the capital letters rather than on the kern pairs from the real small caps font.

Finally, the most promising approach of all these options would be to combine the glyphs from standard and expert fonts with kern pairs from the real small caps fonts. The current version of \latinfamily does not implement this, but it would be a worthwhile approach, and advanced fontinst users are encouraged to attempt it. The file csckrn2x.tex (a variant of csc2x.tex, which is mentioned in Subsection 3.3) should come in handy for this.

4.3 fontinst variables

The following is a list of the fontinst variables that are accessible for the user through the \set…, \reset…, \unset…, etc. commands. You may of course set or use other variables in the MTX and ETX files you write yourself, as does for example the standard MTX file latin.mtx, but all variables that fontinst commands implicitly use or set are listed below.

acccapheight (integer denoting length)

Description The height of accented full capitals. Set by MTX files. Used by Some ETX and MTX files.

address (string)

Description Snailmail address put in BibTEX-style file header of automatically generated ENC files. No address field is written unless the address string is set. Quotes are not automatically inserted around the address string.

Set by ETX files. Used by The ETX-to-ENC converter.

afm-name (string)

Description Name of source font. Internal variable. Set by \from… commands.

Used by The \transformfont, \installfont, \installrawfont, and
    \reglyphfont commands.

ascender (integer denoting length)

Description The ascender height of the font. Set by MTX files. The AFM-to-MTX converter usually writes \setint

commands for this integer. Used by Some MTX and ETX files.

author (string)

Description Author name(s) put in BibTEX-style file header of automatically generated ENC files. See the macro \ref_to_sourcefile for more details.

Set by ETX files. Used by The ETX-to-ENC converter. When not set, the value "See file

⟨etx name⟩" is used instead.

\autoinstallfamily (command)

Description Command called by the font installation commands, as

        \autoinstallfamily{⟨encoding⟩}{⟨family⟩}

when they are asked to install a font with a combination of ⟨encoding⟩ and ⟨family⟩ that has not been seen before (there was no explicit

    \installfamily).

Set by Explicit commands. Defaults to calling \installfamily. Used by Font installation commands.

axisheight (integer denoting length)

Description Math formula parameter σ_{22}. Set by MTX files. Used by Some ETX and MTX files.

baselineskip (integer denoting length)

Description The font designer’s recommendation for natural length of the

    TEX parameter \baselineskip.

Set by MTX files. Used by Some ETX and MTX files.

bigopspacing1 (integer denoting length)

Description Math formula parameter ξ_{9}. Set by MTX files. Used by Some ETX and MTX files.

bigopspacing2 (integer denoting length)

Description Math formula parameter ξ_{10}. Set by MTX files. Used by Some ETX and MTX files.

bigopspacing3 (integer denoting length)

Description Math formula parameter ξ_{11}. Set by MTX files. Used by Some ETX and MTX files.

bigopspacing4 (integer denoting length)

Description Math formula parameter ξ_{12}. Set by MTX files. Used by Some ETX and MTX files.

bigopspacing5 (integer denoting length)

Description Math formula parameter ξ_{13}. Set by MTX files. Used by Some ETX and MTX files.

capheight (integer denoting length)

Description The height of the font’s full capitals. Set by MTX files. The AFM-to-MTX converter usually writes \setint

commands for this variable. Used by Some MTX and ETX files.

cmapname (string)

Description The name given to the CMap generated from an ETX file. Set by ETX files. Used by The ETX-to-CMap converter. When not set, the value fontinst-

⟨cmap file name⟩ is used instead.

codingscheme (string)

Description The codingscheme name. Set by ETX files. Used by The (V)PL writer. When not set, the value UNKNOWN is used

instead.

defaultrulethickness (integer denoting length) Description Math formula parameter ξ_{8}. Set by MTX files. Used by Some ETX and MTX files.

delim1 (integer denoting length)

Description Math formula parameter σ_{20}. Set by MTX files. Used by Some ETX and MTX files.

delim2 (integer denoting length)

Description Math formula parameter σ_{21}. Set by MTX files. Used by Some ETX and MTX files.

denom1 (integer denoting length)

Description Math formula parameter σ_{11}. Set by MTX files. Used by Some ETX and MTX files.

denom2 (integer denoting length)

Description Math formula parameter σ_{12}. Set by MTX files. Used by Some ETX and MTX files.

descender (integer denoting length)

Description The depth of lower case letters with descenders. Set by MTX files. Used by Some ETX and MTX files.

descender_neg (integer denoting length)

Description The vertical position of the descender line of the font, i.e., the

negative of the font’s descender depth. Set by MTX files. The AFM-to-MTX converter usually writes \setint

commands for this variable. Used by Some MTX and ETX files.

designsize (dimension)

Description The design size of the font. Set by MTX files. The (V)PL-to-MTX converter usually writes \setdim

commands for this variable. Used by The (V)PL writer. The design size defaults to 10 pt if this variable

is not set. Note The value of this variable has no effect on how the font is declared to

L^{A}TEX.

designunits (dimension denoting a real number)

Description The design size of a font expressed in the design unit used in

a (V)PL file. Set by MTX files. The (V)PL-to-MTX converter usually writes \setdim

commands for this variable. Used by Nothing. If this variable is set, but to any value other than 1 pt,

then some metrics are most likely wrong.

digitwidth (integer denoting length)

Description The median width of the digits in the font. Set by MTX files. Used by Some ETX and MTX files.

email (string)

Description Email address put in BibTEX-style file header of automatically generated ENC files. See the macro \ref_to_sourcefile for more details.

Set by ETX files. Used by The ETX-to-ENC converter. When not set, the value "See file

⟨etx name⟩" is used instead.

encodingname (string)

Description The name by which the encoding in question is made known

to a Postscript interpreter. Set by ETX files. Used by The ETX-to-ENC converter. When not set, the value fontinst-

autoenc-⟨etx name⟩ is used instead.

etx-name (string)

Description Name of ETX file. Internal variable in \transformfont. Set by The \reencodefont command. Used by The \mtxtomtx command.

extraspace (integer denoting length)

Description The natural width of extra interword glue at the end of a

sentence. Set by MTX files. Used by Some ETX and MTX files.

fontdimen(n) (integer)

Description Family of semi-internal variables that store the values to use for font dimension n. It is preferred that the newer \setfontdimen interface is used for setting these values.

Set by ETX files. Used by The (V)PL writer.

\iftokeep (macro)

Description \iftokeep #1 \then, where #1 will be a ⟨number⟩, behaves like a switch and decides whether a glyph is kept or not while reglyphing.

Set by Explicit commands. Defaults to

                  \iftokeep #1 \then ↦ \ifnum-1<#1

Used by The \reglyphfont command.

interword (integer denoting length) Description The natural width of interword glue (spaces). Set by MTX files. Used by Some ETX and MTX files.

italicslant (integer denoting factor) Description The italic slant of a font. Set by MTX files generated from AFM or (V)PL files. MTX files gener-

ated by \transformfont. Locally in the AFM-to-MTX converter for

    possible use in \uprightitalcorr or \slanteditalcorr.

Used by MTX files (latin.mtx and the like). ETX files (for determining

    fontdimen(1)).
killweight (integer)

Description Weight for glyphs that are killed. Set by Explicit commands. Defaults to −10 if not set. Used by The \killglyph command; indirectly the \reglyphfont com-

mand.

letterspacing (integer denoting length)

Description Extra width added to all glyphs of a font. Set by ETX or MTX files. Used by The (V)PL writer. Defaults to 0 if not set.

maxdepth (integer denoting length) Description The maximal depth over all slots in the font. Set by MTX files. Used by Some ETX and MTX files.

maxdepth_neg (integer denoting length) Description The negative of the maximal depth of a glyph in the font. Set by MTX files. The AFM-to-MTX converter usually writes \setint

commands for this variable. Used by Some ETX and MTX files.

maxheight (integer denoting length) Description The maximal height of a glyph in the font. Set by MTX files. The AFM-to-MTX converter usually writes \setint

commands for this variable. Used by Some ETX and MTX files.

minimumkern (integer denoting length)

Description Kerns whose size in absolute value is less than or equal to this

variable are ignored. Set by fontinst command files or MTX files. Used by The AFM-to-MTX converter and the (V)PL file generator. When

not set, the value 0 is used instead.

monowidth (flag integer)

Description Set if this font is monowidth, unset otherwise. Set by MTX files. The AFM-to-MTX converter writes a \setint com-

mand for this variable if the AFM specifies IsFixedPitch true. Used by Some MTX files (latin.mtx and the like), ETX files.

num1 (integer denoting length)

Description Math formula parameter σ_{8}. Set by MTX files. Used by Some ETX and MTX files.

num2 (integer denoting length)

Description Math formula parameter σ_{9}. Set by MTX files. Used by Some ETX and MTX files.

num3 (integer denoting length)

Description Math formula parameter σ_{10}. Set by MTX files. Used by Some ETX and MTX files.

quad (integer denoting length)

Description The quad width of the font, normally approximately equal to

the font size and/or the width of an ‘M’. Set by MTX files. Used by Some ETX and MTX files.

PSfontsuffix (string)

Description Suffix added to font names to form name of file to download

to include font. Set by Explicit commands in finstmsc command files. Defaults to ‘.pfa’. Used by The map file fragments writer.

rawscale (integer denoting factor)

Description Scaling factor applied to raw glyphs. Set by The \installfont command (scaled clauses in argument #2).

Unset for metric files listed without a scaled clause.

Used by The \setrawglyph, \setnotglyph, \setscaledrawglyph, \set-
    scalednotglyph, \setkern, and \resetkern commands.
renameweight (integer)

Description Weight for glyphs that are renamed. Set by Explicit commands. Defaults to 1 if not set. Used by The \renameglyph command; indirectly the \reglyphfont com-

mand.

requireglyphs (flag integer)

Description Set if warnings are to be generated for glyphs listed in ETX

files but not present in the glyph base. Set by Explicit commands. By defaults not set. Used by The (V)PL file generator.

rightboundary (string)

Description The name of a glyph with the property that kerns on the left

may be intended as right word boundary kerns. Set by MTX files. The (V)PL-to-MTX converter can write \setstr com-

mands for this variable. Used by Some MTX files.

shrinkword (integer denoting length)

Description The (finite) shrink component of interword glue. Set by MTX files. Used by Some ETX and MTX files.

slant-scale (integer denoting factor)

Description Factor to slant by. Internal variable in \transformfont.

Set by The \slantfont, \xscalefont, and \scalefont commands.

Used by The \mtxtomtx command.

\SlantAmount (macro expanding to an integer expression) Description Slant factor used for faking oblique shape. Set by Explicit commands. Defaults to 167. Used by The \latinfamily command.

\slanteditalcorr (macro expanding to an integer expression)

Description The integer expression used to calculate a guess for the italic

correction of glyphs in a font with positive slant. It has the syntax

\slanteditalcorr{⟨width⟩}{⟨left⟩}{⟨right⟩}{⟨bottom⟩}{⟨top⟩} where ⟨width⟩ is the glyph’s advance width, and the remaining arguments are coordinates of sides of the glyph’s bounding box. The italicslant integer provides the italic slant of the font.

Set by Explicit commands in fontinst command files. Defaults to max{0, right− width}.

Used by The AFM-to-MTX converter.

stretchword (integer denoting length)

Description The (finite) stretch component of interword glue. Set by MTX files. Used by Some ETX and MTX files.

sub1 (integer denoting length)

Description Math formula parameter σ_{16}. Set by MTX files. Used by Some ETX and MTX files.

sub2 (integer denoting length)

Description Math formula parameter σ_{17}. Set by MTX files. Used by Some ETX and MTX files.

subdrop (integer denoting length)

Description Math formula parameter σ_{19}. Set by MTX files. Used by Some ETX and MTX files.

sup1 (integer denoting length)

Description Math formula parameter σ_{13}. Set by MTX files. Used by Some ETX and MTX files.

sup2 (integer denoting length)

Description Math formula parameter σ_{14}. Set by MTX files. Used by Some ETX and MTX files.

sup3 (integer denoting length)

Description Math formula parameter σ_{15}. Set by MTX files. Used by Some ETX and MTX files.

supdrop (integer denoting length)

Description Math formula parameter σ_{18}. Set by MTX files. Used by Some ETX and MTX files.

TFMfileprefix (string)

Description Prefix (typically a path) added to names of TFM files. Set by Explicit commands in finstmsc command files. By default not set,

which is equivalent to being empty. Used by The PLtoTF “map file fragments writer”.

underlinethickness (integer denoting length)

Description The recommended thickness of an underlining rule. Set by MTX files. The AFM-to-MTX converter usually writes \setint

commands for this variable. Used by Some MTX files (latin.mtx and the like).

\uprightitalcorr (macro expanding to an integer expression)

Description The integer expression used to calculate a guess for the italic correction of glyphs in a font with non-positive slant. It has the syntax

\uprightitalcorr{⟨width⟩}{⟨left⟩}{⟨right⟩}{⟨bottom⟩}{⟨top⟩} where ⟨width⟩ is the glyph’s advance width, and the remaining arguments are coordinates of sides of the glyph’s bounding box. The italicslant integer provides the italic slant of the font.

Set by Explicit commands in fontinst command files. Defaults to 0. Used by The AFM-to-MTX converter.

version (string)

Description Version number put in BibTEX-style file header of automatically generated ENC files. See the macro \ref_to_sourcefile for more details.

Set by ETX files. Used by The ETX-to-ENC converter. When not set, the value "See file

⟨etx name⟩" is used instead.

verticalstem (integer denoting length)

Description The dominant width of vertical stems (usually the width of

stems of lower case letters). Set by MTX files. The AFM-to-MTX converter writes \setint commands

for this variable if the AFM file specifies StdVW. Used by Currently nothing.

warningspecials (switch)

Description Controls whether \glyphwarning commands will generate

VPL SPECIALs. Defaults to ‘true’.

Set by Explicit commands (\warningspecialstrue and \warningspecialsfalse).

Used by The (V)PL file generator.

x-scale (integer denoting factor)

Description Horizontal scaling factor. Internal variable in \transform-

    font.
Set by The \xscalefont and \scalefont commands.

Used by The \mtxtomtx command.

xheight (integer denoting length)

Description The x-height of the font. Set by MTX files. The AFM-to-MTX and (V)PL-to-MTX converters usu-

ally write \setint commands for this variable. Used by MTX files, and ETX files (for determining fontdimen(5)).

y-scale (integer denoting factor)

Description Vertical scaling factor. Internal variable in \transformfont.

Set by The \yscalefont and \scalefont commands.

Used by The \mtxtomtx command.

⟨glyph⟩-spacing (integer denoting length)

Description Glyph-specific override for letterspacing; extra width added

to the glyph ⟨glyph⟩ as part of the process of writing a VPL file. Set by ETX or MTX files. Used by The (V)PL writer. Defaults to 0 if not set.

Besides these, the \latinfamily command provides a whole range of parameters that are often used somewhat like variables. That subject does however deserve to be treated separately.

5 fontdoc package overview

The purpose of the fontdoc package is to support typesetting of .etx and .mtx files intended for use with fontinst. The typical format of these files looks something like this:

     \relax
     \documentclass[twocolumn]{article}
     \usepackage{fontdoc}
     \begin{document}

L^{A}TEX commands

     \encoding or \metrics

fontinst commands

     \endencoding or \endmetrics

L^{A}TEX commands

     \end{document}

To make it work, fontdoc has to define all the user-level fontinst commands in terms of typesetting instructions. This goal is currently only partially achieved, but the percentage of fontinst commands covered by fontdoc is still fairly large, so it is our impression that problems with commands not covered occur only very rarely.

5.1 Some fontdoc commands that fontinst doesn’t know

Some of the commands defined by fontdoc are not defined by fontinst because they have no meaning in that context. Most of these commands are lower-level commands that are used in the implementations of commands common to fontinst and fontdoc, but a few are simply only meant to be used in the parts of ETX and MTX files that fontinst never executes.

With v 1.916 the mechanism for formatting integer expressions changed dra-

\TypesetIntegerExpression matically. The new base command to use is \TypesetIntegerExpression, which

takes as its only argument the integer expression to format and typesets it. \TypesetIntegerExpression expects to be used in math mode only. A simi-

\TypesetStringExpression lar command is \TypesetStringExpression, which takes a string expression as

argument, formats, and typesets it. \TypesetStringExpression can be used in any mode.

\macroparameter The \macroparameter command is (in integer and string expressions) understood as a “placeholder for a macro parameter”. This is primarily useful in comments that describe a user-defined macro; see ltcmds.mtx for examples.

File a

fibasics.dtx

“Can’t say I’ve ever been too fond of beginnings, myself. Messy little things. Give me a good ending any time. You know where you are with an ending.”

— from The kindly ones by Neil Gaiman et al.

6 The first and the last

6.1 Version numbers

We start by making some default catcode assignments, in case we are using iniTEX.

1 ⟨∗pkg⟩

 2 \catcode`\{=1
 3 \catcode`\}=2
 4 \catcode`\#=6
 5 \catcode`\^=7

6 ⟨/pkg⟩

\fontinstversion If we are running under iniTEX we cannot put the identification stuff any earlier than this. Note that \fontinstversion is not just used for indentification but

also in \needsfontinstversion.
 7 ⟨pkg | doc⟩\def\fontinstversion{1.929}

If we are running under iniTEX or plain, we have to get around the L^{A}TEX-

specific \ProvidesPackage stuff.

8 ⟨∗pkg⟩

 9 \ifx\ProvidesPackage\undefined
10 \def\NeedsTeXFormat#1{}
11 \def\ProvidesPackage#1[#2]{}
12 \fi

13 ⟨/pkg⟩

Now we can identify ourselves as usual.

14 ⟨doc⟩\NeedsTeXFormat{LaTeX2e}[1995/06/01]
15 ⟨doc⟩\ProvidesPackage{fontdoc}
16 ⟨pkg⟩\ProvidesPackage{fontinst}
17 ⟨pkg | doc⟩[2005/02/05 v\fontinstversion\space
18 ⟨doc⟩ fontinst documentation package]
19 ⟨pkg⟩ fontinst installation package]

While we’re at version numbers anyway, we might as well define the command for testing them. Note however that the module name is not ⟨pkg⟩ as above, but ⟨pkg2⟩. Code in the latter module ends up at the very end of fontinst.sty!

\needsfontinstversion The macro:
     \needsfontinstversion{⟨number⟩}

checks the version number.

20 ⟨∗pkg2⟩

21 \def\needsfontinstversion#1{{
22 \a_dimen=#1pt
23 \b_dimen=\fontinstversion~pt\x_relax
24 \ifnum\a_dimen>\b_dimen
25  \immediate\write16{}
26  \immediate\write16{Warning:~This~file~needs~fontinst~version~#1.}
27  \immediate\write16{Warning:~You~are~using~version~
28  \fontinstversion.}
29  \immediate\write16{Warning:~This~may~cause~errors.}
30  \immediate\write16{}
31 \fi
32 }}

33 ⟨/pkg2⟩

In fontdoc, \needsfontinstversion is printed out as a comment.

34 ⟨∗doc⟩

35 \newcommand*\needsfontinstversion[1]{%
36 \ifFD@spec@
37  \comment{Automatic processing of this document as a data file
38  requires \textsf{fontinst} v\,#1 or higher.}%
39 \else
40  \Bheading{Needs fontinst v\thinspace#1}%
41 \fi

42 } 43 ⟨/doc⟩

6.2 Special catcodes and configuration file

fontinst uses some unusual, but convenient, settings of \catcode. @ and _are made letters, ~ is made a space, and space and newline are ignored. Before setting those however, we save the current values of the catcodes, so that they can be restored at the end of fontinst.sty.

\normalcc \fontinstcc The \fontinstcc command changes the catcodes of certain characters to what is used in the fontinst source and the \normalcc command changes them back; their use is analogous to that of the \makeatletter and \makeatother commands in L^{A}TEX.

If, for some reason, you use other “normal” catcodes than fontinst does by default, you may have to redefine \fontinstcc and \normalcc. The easiest way to do this is probably to use the \add_to macro.

44 ⟨∗pkg⟩

45 \def\a_macro#1{\catcode\number`#1=\the\catcode`#1 }
46 \edef\normalcc{%
47 \a_macro{\ }\a_macro{\^^M}\a_macro{\@}\a_macro{\_}\a_macro{\~}

48 }

The above definition makes the \normalcc macro end with a space. This is deliberate; the space is used to terminate the last number in the macro.

49 \def\fontinstcc{%
50 \catcode`\ =9%
51 \catcode`\^^M=9%

52 \catcode`\@=11%
53 \catcode`\_=11%
54 \catcode`\~=10

55 }

56 \fontinstcc

57 ⟨/pkg⟩

We input the fontinst.rc file, if it exists.

UV, 06/1998: What is this fontinst.rc file good for? It turns out that you can use it to do \def\raw_encoding{8y} if you prefer to install your fonts the other way.

58 ⟨∗pkg2⟩ 59 ⟨∗!misc⟩

60 \if_file_exists{fontinst.rc}\then
61 \primitiveinput fontinst.rc
62 \else
63 \immediate\write16{No~file~fontinst.rc.}
64 \fi

65 ⟨/!misc⟩

Use a different configuration file for finstmsc.sty.

66 ⟨∗misc⟩

67 \if_file_exists{finstmsc.rc}\then
68 \primitiveinput finstmsc.rc
69 \else
70 \immediate\write16{No~file~finstmsc.rc.}
71 \fi

72 ⟨/misc⟩

At the end of fontinst.sty, we restore the catcodes we changed.

73 \normalcc

74 ⟨/pkg2⟩

6.3 Plain TEX macros from fontinst.ini

If we’re running in iniTEX we input some definitions taken from plain.

75 ⟨∗pkg⟩

76 \ifx\@ne\undefined_command
77 \input fontinst.ini\relax
78 \fi

79 ⟨/pkg⟩

80 ⟨∗ini⟩

81 \chardef\active=13

82

83 \chardef\@ne=1
84 \chardef\tw@=2
85 \chardef\thr@@=3
86 \chardef\sixt@@n=16
87 \chardef\@cclv=255
88 \mathchardef\@cclvi=256
89 \mathchardef\@m=1000
90 \mathchardef\@M=10000
91 \mathchardef\@MM=20000

 93 \count10=22 % allocates \count registers 23, 24, ...
 94 \count11=9 % allocates \dimen registers 10, 11, ...
 95 \count15=9 % allocates \toks registers 10, 11, ...
 96 \count16=-1 % allocates input streams 0, 1, ...
 97 \count17=-1 % allocates output streams 0, 1, ...
 98 \count20=255 % allocates insertions 254, 253, ...
 99 \countdef\insc@unt=20 % the insertion counter
100 \countdef\allocationnumber=21 % the most recent allocation
101 \countdef\m@ne=22 \m@ne=-1 % a handy constant
102 \def\wlog{\immediate\write\m@ne} % write on log file (only)

103

104 \countdef\count@=255
105 \dimendef\dimen@=0

106

107 \outer\def\newcount{\alloc@0\count\countdef\insc@unt}
108 \outer\def\newdimen{\alloc@1\dimen\dimendef\insc@unt}
109 \outer\def\newtoks{\alloc@5\toks\toksdef\@cclvi}
110 \outer\def\newread{\alloc@6\read\chardef\sixt@@n}
111 \outer\def\newwrite{\alloc@7\write\chardef\sixt@@n}

112

113 \def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne
114 \ch@ck#1#4#2% make sure there's still room
115 \allocationnumber=\count1#1%
116 \global#3#5=\allocationnumber
117 \wlog{\string#5=\string#2\the\allocationnumber}}
118 \outer\def\newinsert#1{\global\advance\insc@unt by\m@ne
119 \ch@ck0\insc@unt\count
120 \ch@ck1\insc@unt\dimen
121 \ch@ck2\insc@unt\skip
122 \ch@ck4\insc@unt\box
123 \allocationnumber=\insc@unt
124 \global\chardef#1=\allocationnumber
125 \wlog{\string#1=\string\insert\the\allocationnumber}}
126 \def\ch@ck#1#2#3{\ifnum\count1#1<#2%
127 \else\errmessage{No~room~for~a~new~#3}\fi}

128

129 \outer\def\newif#1{\count@\escapechar \escapechar\m@ne
130 \expandafter\expandafter\expandafter
131 \edef\@if#1{true}{\let\noexpand#1=\noexpand\iftrue}%
132 \expandafter\expandafter\expandafter
133 \edef\@if#1{false}{\let\noexpand#1=\noexpand\iffalse}%
134 \@if#1{false}\escapechar\count@} % the condition starts out false
135 \def\@if#1#2{\csname\expandafter\if@\string#1#2\endcsname}
136 {\uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}} % `if' is required

137

138 \newdimen\p@ \p@=1pt % this saves macro space and time
139 \newdimen\z@ \z@=0pt % can be used both for 0pt and 0

140

141 \def\space{~}
142 \let\bgroup={
143 \let\egroup=}

144

145 \def\loop#1\repeat{\def\body{#1}\iterate}

146 \def\iterate{\body \let\next\iterate \else\let\next\relax\fi \next}
147 \let\repeat=\fi % this makes \loop...\if...\repeat skippable

148

149 \def\supereject{\par\penalty-\@MM}
150 \outer\def\bye{\par\vfill\supereject\end}

151 ⟨/ini⟩

The two last commands above also need to be defined if we’re running under L^{A}TEX. In that case we need to be careful with \bye however, as no \if… can skip over code that explicitly contains that control sequence, if it has been defined as above.

152 ⟨∗pkg⟩

153 \ifx\bye\undefined_command
154 \def\supereject{\par\penalty-\@MM}
155 \outer\expandafter\def \csname bye\endcsname
156  {\par\vfill\supereject\@@end}
157 \fi

158 ⟨/pkg⟩

159 ⟨∗ini & everyjob⟩

160 \everyjob{%
161 \if_file_exists{fontinst.rc}\then
162  \primitiveinput~fontinst.rc
163 \else
164  \immediate\write16{No~file~fontinst.rc.}
165 \fi

166 } 167 ⟨/ini & everyjob⟩

7 Basic definitions

7.1 Declaring variables and constants

Some temporary variables:

\a_count
\b_count
\c_count
\d_count
\e_count
\f_count
\g_count

168 ⟨∗pkg⟩

169 \newcount\a_count
170 \newcount\b_count
171 \newcount\c_count
172 \newcount\d_count
173 \newcount\e_count
174 \newcount\f_count
175 \newcount\g_count
\a_dimen \b_dimen \c_dimen \d_dimen
176 \newdimen\a_dimen
177 \newdimen\b_dimen
178 \newdimen\c_dimen
179 \newdimen\d_dimen
\a_toks \b_toks \c_toks
180 \newtoks\a_toks

181 \newtoks\b_toks
182 \newtoks\c_toks

_a_switch

183 \newif\if_a_

\⟨letter⟩_macro Besides these temporary variables that have to be declared, the family of control sequences with names of the form \⟨letter⟩_macro, such as \a_macro, \b_macro, etc., should be used as “macro valued” temporary variables.

\out_file Some global variables:

184 \newwrite\out_file
\one_thousand \five_hundred \one_hundred \max_mathchardef \two_thousand \half_point Some constants:
185 \mathchardef\one_thousand=1000
186 \mathchardef\five_hundred=500
187 \mathchardef\one_hundred=100
188 \mathchardef\max_mathchardef="7FFF
189 \mathchardef\two_thousand=2000
190 \newdimen\half_point    \half_point=0.5pt

7.2 Trigonometry macros

Include David Carlisle’s trigonometry macros. First, do some hacks to get round all that \NeedsTeXFormat{LaTeX2e} stuff that David put in :-) In v 1.8 these hacks been moved to an earlier place since we put in \ProvidesPackage ourselves.

191 \let\@tempdima\a_dimen
192 \let\@tempdimb\b_dimen
193 \input trig.sty

194 ⟨/pkg⟩

7.3 fontdoc-specific declarations

As of v 1.917, fontdoc has options, so we better start with declaration and processing of these.

specification option FD@spec@ switch The specification option tells fontdoc that the document is an encoding specification rather than a production file—this changes some minor details in the typesetting. The state of this option is recorded in the FD@spec@ switch.

195 ⟨∗doc⟩

196 \newif\ifFD@spec@
197 \FD@spec@false
198 \DeclareOption{specification}{\FD@spec@true}

hypertex option pdftex option \FD@codepoint The hypertex and pdftex options tell fontdoc to include HyperTEX \specials and pdfTEX annotations, in every code point number set using \Unicode or \textunicode, for links to glyph images on the Unicode consortium web site. The URLs to use are as follows:

To access the reference glyph for any Unicode character, you can use the new URL syntax like this:

          http://www.unicode.org/cgi-bin/refglyph?⟨XX ⟩-⟨nnnn⟩

where ⟨XX ⟩ is the point size and ⟨nnnn⟩ is the hexadecimal codepoint. Please note however that only 24 is supported as a size parameter at this time. (We are reserving the possibility of providing other sizes in the future.) Here is an example of usage for U+4E78:

           http://www.unicode.org/cgi-bin/refglyph?24-4E78

(This supports up to 6 hex digits, so it can also be used with the supplementary characters.)

Coding this for HyperTEX is pretty straightforward.

199 \DeclareOption{hypertex}{
200 \providecommand*\FD@codepoint[1]{%
201  \uppercase{\edef\@tempa{#1}}%
202  \special{html:<a href="%
203  http://www.unicode.org/cgi-bin/refglyph?24-\@tempa
204  ">%

205 }%

206  \texttt{U+\@tempa}%
207  \special{html:</a>}%

208 }% 209 }

The pdfTEX implementation is easy too, but there is one complication: The key primitive is called \pdfannotlink in v 0.13, but \pdfstartlink in v 0.14. My thanks goes to Hàn Th´ ê Thành, who helped me sort that out.

210 \DeclareOption{pdftex}{
211 \providecommand*\FD@codepoint[1]{%
212  \mbox{%
213  \uppercase{\edef\@tempa{#1}}%
214  \ifx \pdfstartlink\@undefined
215  \pdfannotlink
216  \else
217  \pdfstartlink
218  \fi attr {/Border [0 0 0]} user {%
219  /Subtype /Link /A <<%
220  /S /URI /URI (%
221  http://www.unicode.org/cgi-bin/refglyph?24-\@tempa

222 )%

223  >>}%
224  \textcolor{blue}{\texttt{U+\@tempa}}%
225  \pdfendlink

226 }% 227 }%

228 \AtEndOfPackage{\RequirePackage[pdftex]{color}}%

229 }

It would be quite possible to make these links according to some other standard (e.g. L^{A}TEXtoHTML) instead by including a suitable definition of \FD@codepoint in your fontdoc.cfg file. I could include code for those standards as well if someone sends it to me.

I decided against using commands in the hyperref or hyper packages for this as these packages do so much more that I don’t want. If some day a package providing a basic interface for making hyperlinks is included in required L^{A}TEX then this decision should certainly be reconsidered.

Input a local configuration file, if it exists.

230 \InputIfFileExists{fontdoc.cfg}{%
231 \typeout{*************************************^^J%
232  * Local config file fontdoc.cfg used^^J%
233  *************************************}%
234 }{}

Finally process the options.

235 \ProcessOptions\relax

The amstext package is required, since the \text command is used in formatting some integer expressions.

236 \RequirePackage{amstext}
\a@count \b@count \a@dimen Three private variables:
237 \newcount\a@count
238 \newcount\b@count
239 \newdimen\a@dimen

Some useful macros and constrol structures:

240 \def\x@cs#1#2{\expandafter#1\csname#2\endcsname}
241 \def\FD@swap@two#1#2{#2#1}
\Aheading \Bheading  \Aheading and \Bheading are used to typeset various headings.
242 \newcommand\Aheading[1]{%
243 \par\pagebreak[1]\addvspace\medskipamount
244 \noindent\textbf{#1}\vadjust{\penalty200}\par

245 }

246 \newcommand\Bheading[1]{\par\noindent\textbf{#1}}

Some formating commands and a macro that comes in handy. It used to say \raggedright at this point as well, but that functionality has been moved into

\encoding and \metrics.
247 \raggedbottom
248 \ifdim 1sp>\lineskiplimit \lineskiplimit=0.5pt \fi
249 \newcommand\plain{\texttt{plain}}
\plainint \plaindiv \plainneg \plainmax \plainmin fontdoc saves away L^{A}TEX’s \int, \div, \neg, \max, and \min as \plainint,
\plaindiv, \plainneg, \plainmax, and \plainmin respectively, since these con-

trol sequences are going to be used for other purposes.

250 \let\plainint=\int
251 \let\plaindiv=\div
252 \let\plainneg=\neg
253 \let\plainmax=\max
254 \let\plainmin=\min
\TypesetList \list@item@counter The \TypesetList command typesets the ⟨arg⟩s in a sequence of \do{⟨arg⟩}

macros with separators depending on position in and length of the sequence. It is loosely based on a description of a similar command in the amsref package, but it has fewer features, and I don’t know if there is any similarity between the implementations.

The syntax is \TypesetList{⟨left⟩}{⟨onlysep⟩}{⟨nonlastsep⟩}{⟨lastsep⟩}{⟨right⟩}

{⟨empty⟩}{⟨wrap⟩}{⟨list⟩}

⟨list⟩ is the actual list of \do{⟨arg⟩}s. If that is empty then ⟨empty⟩ is typeset. Otherwise the typeset text begins with ⟨left⟩, ends with ⟨right⟩, and contains the formatted forms of every ⟨arg⟩ in the list of \do{⟨arg⟩}s. The formatting here consists of passing the ⟨arg⟩ as the argument to ⟨wrap⟩, which is typically a oneargument macro. Between two “formatted ⟨arg⟩s” will ⟨onlysep⟩, ⟨nonlastsep⟩, or ⟨lastsep⟩ be put, depending on the number of ⟨arg⟩s in the list and the position in the list. If the list has length two then ⟨onlysep⟩ will be used for the only separator needed. If the list has length greater than two then ⟨nonlastsep⟩ will be used for all separators but the last, and ⟨lastsep⟩ will be used for the last.

All of the arguments of \TypesetList must survive being passed through a

\def.
255 \newcount\list@item@counter
256 \newcommand\TypesetList[8]{%
257 \begingroup
258  \list@item@counter=\z@
259  \def\do##1{\advance\list@item@counter\@ne}%
260  #8%
261  \ifcase \list@item@counter \or
262  \def\do##1{#1#7{##1}}%
263  \or
264  \def\do##1{%
265  \advance\list@item@counter\@ne
266  \ifnum \list@item@counter=\@ne #1\else #2\fi
267  #7{##1}%

268 }%

269  \else
270  \advance\list@item@counter\m@ne
271  \expandafter\def \expandafter\do \expandafter##\expandafter1%
272  \expandafter{\expandafter\ifnum \the\list@item@counter
273  =\list@item@counter
274  #4%
275  \else\ifnum \z@=\list@item@counter
276  #1%
277  \else
278  #3%
279  \fi\fi
280  \advance\list@item@counter\@ne
281  #7{##1}%

282 }%

283  \fi
284  \ifnum \z@=\list@item@counter
285  #6%
286  \else
287  \list@item@counter=\z@
288  #8%
289  #5%
290  \fi
291 \endgroup

292 } 293 ⟨/doc⟩

8 TEX hackery

8.1 Utiltiy macros

\x_cs \x_relax \g_let

294 ⟨∗pkg⟩

295 \def\x_cs#1#2{\expandafter#1\csname#2\endcsname}
296 \let\x_relax=\relax
297 \def\g_let{\global\let}

298 ⟨/pkg⟩

\x@relax
299 ⟨doc⟩\let\x@relax=\relax
\empty_command
\gobble_one
\gobble_two
\gobble_three
\identity_one
\first_of_two
\second_of_two
\swap_two
\first_of_three

300 ⟨∗pkg⟩

301 \def\empty_command{}
302 \def\gobble_one#1{}
303 \def\gobble_two#1#2{}
304 \def\gobble_three#1#2#3{}
305 \def\identity_one#1{#1}
306 \def\first_of_two#1#2{#1}
307 \def\second_of_two#1#2{#2}
308 \def\swap_two#1#2{#2#1}
309 \def\first_of_three#1#2#3{#1}
\hash_char
\percent_char
\left_brace_char
\right_brace_char

310 \bgroup
311 \catcode`\[=1
312 \catcode`\]=2
313 \catcode`\#=12
314 \catcode`\%=12
315 \catcode`\{=12
316 \catcode`\}=12
317 \gdef\hash_char[#]
318 \gdef\percent_char[%]
319 \gdef\left_brace_char[{]
320 \gdef\right_brace_char[}]
321 \egroup

\first_char Return the first character of a string.

322 \def\first_char#1#2={#1}

\add_to Append one or more tokens to the replacement text of a parameterless macro.

323 \def\add_to#1#2{
324 \ifx#1\x_relax
325  \def#1{#2}
326 \else
327  \expandafter\def\expandafter#1\expandafter{#1#2}
328 \fi

329 }

\prep_to Prepend one or more tokens to the replacement text of a parameterless macro. Note that if more than one token is added then the second parameter must contain an \expandafter between every pair of tokens you actually mean to contribute. Thus if you want to prepend abc to \next, you must write

     \prep_to\next{a\expandafter b\expandafter c}

Also note that the second argument must not be empty.

330 \def\prep_to#1#2{
331 \ifx#1\x_relax
332  \expandafter\def\expandafter#1\expandafter{\expandafter#2}
333 \else
334  \expandafter\def\expandafter#1\expandafter{\expandafter#2#1}
335 \fi

336 }

\never_do The command \do, protected from expansion.

337 \def\never_do{\noexpand\do}

338 ⟨/pkg⟩

8.2 Testing for TEX extensions

Some tasks can be done better (and usually with simpler code) if one can assume that certain features in some TEX extensions, such as ε-TEX, is available. Unfortunately one cannot generally make this assumption, but it is sometimes possible to provide two implementations of a macro and at runtime choose the one which best utilizes the available features. This subsection defines macros for making these tests.

There is also a command \needsTeXextension which is used like \needsfontinstversion, but which tests the TEX rather than the version of fontinst. This ought to be of use for ETX files that describe 16 bit encodings,^{7} as the current implementation of the (V)PL writer in this case requires the underlying TEX to support 16 bit character codes.

The normal operation of the extension-testing macros is to set the _a_switch to true if the requested extension is present, and to leave the switch as it was if it isn’t present. This is so that one can easily test for a feature that has been added to several different extensions of TEX simply by doing the tests in sequence. That, however, is what the testing macros do if the switch _extensions_warning_is set to false. When it is set to true they instead expand to a short piece of text suitable for inclusion in a warning message about the absence of a needed feature.

_extensions_warning_switch This switch controls whether extension-testing macros should actually do the test (false) or produce a warning (true).

339 ⟨∗pkg⟩

340 \newif\if_extensions_warning_
341 \_extensions_warning_false

\eTeX The \eTeX command has the syntax

\eTeX{⟨version number⟩} where the ⟨version number⟩ is the complete version number (version number plus revision) of the ε-TEX one wishes to test for.

7At the time of writing, no such ETX files exist that I know of, but fontinst should not have any problem using them. /LH

The code below is geared towards not letting unnecessary control sequences get tokenized, as they will then always occupy a position in TEX’s hash table, but it seems one cannot get around testing whether \eTeXversion is defined, so we start with that and then do a \catcode trick to prevent TEX from seeing

 \eTeXrevision.
342 \ifx \eTeXversion\undefined_command
343 \catcode`\~=14 % 14=comment
344 \fi
345 \def\eTeX#1{
346 \if_extensions_warning_
347  \space/\space e-TeX\space version\space #1
348 ~  \else
349 ~     \ifdim \number\eTeXversion\eTeXrevision\p@ < #1\p@ \else
350 ~        \_a_true
351 ~     \fi
352 \fi

353 }

354 \catcode`\~=10

355 ⟨/pkg⟩

\eTeXlogo The \eTeXlogo command prints the ε-TEX logo.

356 ⟨∗doc⟩

357 \def\eTeX#1{\do{\eTeXlogo\nolinebreak[3] v\,#1}}
358 \def\eTeXlogo{\ensuremath{\varepsilon}-\kern-.125em\TeX}

359 ⟨/doc⟩

\pdfTeX The \pdfTeX command has the syntax

\pdfTeX{⟨version number⟩}{⟨revision⟩}

where the ⟨version number⟩ is the version number as returned by \pdftexversion, i.e., 100 times what it would normally be printed as, and the ⟨revision⟩ is the revision code as returned by \pdftexrevision. To test for pdfTEX 0.13c or newer,

 one would say \pdfTeX{13}{c}.

The code below uses the same \catcode trick as that in \eTeX.

360 ⟨∗pkg⟩

361 \ifx \pdftexversion\undefined_command
362 \catcode`\~=14 % 14=comment
363 \fi

364 ⟨/pkg⟩ 365 ⟨∗pkg | doc⟩

366 \def\pdfTeX#1#2{%
367 ⟨pkg⟩ \if_extensions_warning_
368 ⟨pkg⟩  \space/\space pdfTeX\space version\space
369 ⟨doc⟩ \do{pdf\TeX\nolinebreak[3] v\,%
370  \ifnum #1<100\space
371  0.\ifnum #1<10\space 0\fi
372  \else
373 ⟨pkg⟩  \expandafter\swap_two \expandafter.
374 ⟨doc⟩  \expandafter\FD@swap@two \expandafter.%
375  \fi

376  #1#2%

377 ⟨doc⟩ } 378 ⟨doc⟩} 379 ⟨/pkg | doc⟩ 380 ⟨∗pkg⟩

The above is not ideal, but it will do for now.

381 ~  \else
382 ~     \ifdim #1>\pdftexversion \else
383 ~        \ifnum \expandafter\expandafter \expandafter`
384 ~                   \expandafter\first_char \pdftexrevision= <
385 ~               \expandafter` \first_char#2=
386 ~        \else \_a_true \fi
387 ~     \fi
388 \fi

389 }

390 \catcode`\~=10
\needsTeXextension The \needsTeXextension command has the syntax
     \needsTeXextension{⟨extension tests⟩}{⟨who⟩}

If none of the extension tests set the _a_switch to true, then it prints a warning detailing the extensions tests which failed. ⟨who⟩ is what should be listed as the originator of this message; it is typically the name of the file which contains the

\needsTeXextension command.

An example (assuming that there will be an \Omega test as well some time in the future; I haven’t really looked into what that should look like, so maybe the arguments should be different): The command

     \needsTeXextension{\eTeX{1.2}\Omega{1.0}}{foobar.etx}

tests if the current TEX is ε-TEX verision 1.2 (or newer) or Omega version 1.0 (or newer). The implied conjunction between the tests is always ‘or’.

391 \def\needsTeXextension#1#2{
392 \_a_false

393 #1

394 \if_a_\else
395  \_extensions_warning_true
396  \edef\a_macro{#1}
397  \_extensions_warning_false
398  \fontinstwarningnoline{#2}{
399  This~file~needs:\messagebreak
400  \expandafter\second_of_two\a_macro
401  \iffalse
402  <no~sufficient~extensions~were~listed!!>\if_false
403  \fi
404  \messagebreak
405  You~are~not~using~any~of~them.~This~is~likely~to~cause~errors

406 }

407 \fi

408 } 409 ⟨/pkg⟩

410 ⟨∗doc⟩

411 \def\needsTeXextension#1#2{%
412 \Bheading{Needs
413  \TypesetList{}{ or }{, }{, or }{}{(unspecified)}{\@firstofone}{#1}}%

414 } 415 ⟨/doc⟩

8.3 Writing to output files

As of v 1.901, there are two different output file models in fontinst. One has been along “forever” and is for writing output to files which are only open for a short period of time—every fontinst file command that opens a file in this model must also close it—and it can only be used for one file at at time. The other model offers pooled allocation of output files—as long as there is an unused TEX output stream to open, you may open a new file, and it does not matter if files are not closed in the revese order of that in which they were opened.

\open_out \close_out \out_line \out_lline \out_llline These macros implement the classical output file commands.

416 ⟨∗pkg⟩

417 \def\open_out#1{
418 \immediate\openout\out_file=#1 \xdef\out_filename{#1}}
419 \def\close_out#1{
420 \immediate\write16{#1~written~on~\out_filename.}
421 \immediate\closeout\out_file}
422 \def\out_line#1{\immediate\write\out_file{#1}}
423 \edef\out_lline#1{\noexpand\out_line{\space\space\space#1}}
424 \edef\out_llline#1{
425 \noexpand\out_line{\space\space\space\space\space\space#1}

426 }

\pout_line In the new model, the basic writing command \pout_line takes two arguments: a file identifier control sequence and the token sequence to write. Thus its call looks like

\pout_line⟨identifier⟩{⟨text⟩}

The ⟨identifier⟩ is usually a chardef token whose number tells which input stream is used, but if TEX runs out of output streams then it might be defined as a parameterless macro which expands to \m@ne. This has the effect of making all output to that “file” go to the log file, from which the data might be salvaged.

\out_filename-⟨stream⟩ The new model operates using the control sequence family \out_filename-⟨stream⟩ both for storing the name of the output file and for handling allocation of output streams.

\TeX_terminal \closed_stream \out_filename-99 \out_filename--1 Output streams 16 and above always write to TEX’s terminal, and any output file that gets closed gets its identifier set to 99 so that any attempts to write to a closed file can be easily spotted. (99 is the character code for c.) Output stream –1 is the log file, and if another output stream cannot be allocated then attempts to write to the output file will be redirected to the log file.

427 \def\TeX_terminal{\string\TeX\space terminal}
428 \chardef\closed_stream=99
429 \x_cs\let{out_filename-99}=\TeX_terminal
430 \x_cs\def{out_filename--1}{\jobname.log}

\allocate_stream
\ch@ck
431 \def\allocate_stream{
432 \a_count=\m@ne
433 \b_count=\m@ne
434 \loop \ifnum \count17>\a_count

While \a_count < the number of the last allocated output stream …

435  \advance \a_count \@ne
436  \x_cs\ifx{out_filename-\the\a_count}\TeX_terminal

If \out_filename-⟨stream⟩, where ⟨stream⟩ is the value of \a_count, is equal to \TeX_terminal, then output stream \a_count is allocated to the pool but is not used for any currently open file. Thus we’ve found a stream that can be used.

437  \b_count=\a_count
438  \a_count=\count17
439  \fi
440 \repeat
441 \ifnum \b_count=\m@ne

In this case all streams allocated to the pool are currently in use, so try to allocate a new one.

442  \global\advance\count17by\@ne
443  \ifnum \count17<\sixt@@n

Then case: There was another output stream.

444  \b_count=\count17
445  \global\x_cs\let{out_filename-\the\b_count}\TeX_terminal
446  \wlog{\string\write\the\b_count\space allocated~to~the~pool.}
447  \else

Else case: See to that the output stream allocation register holds at 16.

448  \global\count17=\sixt@@n
449  \fi
450 \fi

451 }

By now, if a new stream could be allocated then the number of that stream is in \b_count, and if it couldn’t then \b_count is –1.

All output streams up to and including that whose number is in \count17 is checked to see if it is available. Many unsuccessful \newwrites could therefore mean we have to do quite a lot of checking. What’s more, output stream 99 would incorrectly be interpreted as being in the pool but not used. To guard against these (improbable) errors, \ch@ck is redefined to stop allocation \count registers at their limit value.

452 \def\ch@ck#1#2#3{
453 \ifnum \count1#1<#2 \else
454  \errmessage{No~room~for~a~new~#3}
455  \global\count1#1=#2
456 \fi

457 }

\open_pout \close_pout The syntax for \open_pout is

\open_pout⟨identifier⟩{⟨name⟩} ⟨name⟩ is the name of the output file one wishes to open. ⟨identifier⟩ is a control sequence which will be redefined (globally) to act as an identifier of the file.

458 \def\open_pout#1#2{
459 \allocate_stream
460 \ifnum \b_count=\m@ne
461  \immediate\write\sixt@@n{fontinst~is~out~of~output~streams.^^J
462  Output~file~#2~cannot~be~opened.^^J
463  Writes~will~be~redirected~to~the~log~file.

464 }

465  \gdef#1{\m@ne}
466 \else
467  \immediate\openout\b_count=#2\x_relax
468  \x_cs\xdef{out_filename-\the\b_count}{#2}
469  \global\chardef#1=\b_count
470 \fi

471 }

The syntax for \close_pout is

\close_pout⟨identifier⟩{⟨what⟩}

⟨identifier⟩ is the output stream identifier which should have been defined in an earlier call of \open_pout. ⟨what⟩ is a string which describes what has been written to the output file, e.g. Metrics or Raw~font. It will be used to write a message on the terminal.

472 \def\close_pout#1#2{
473 \ifnum #1=\closed_stream
474  \errmessage{Output~file~\string#1~(#2)~not~closed,^^J
475  since~it~was~not~open}
476 \else
477  \immediate\write\sixt@@n{#2~written~on~
478  \csname out_filename-\the#1\endcsname.}
479  \ifnum #1=\m@ne \else
480  \immediate\closeout#1
481  \global\x_cs\let{out_filename-\the#1}=\TeX_terminal
482  \fi
483  \global\chardef#1=\closed_stream
484 \fi

485 }

\pout_line The syntax for \pout_line is

\pout_line⟨identifier⟩{⟨text⟩}

⟨identifier⟩ is the output stream identifier which should have been defined in an earlier call to \open_pout. ⟨text⟩ is what will be written to the file.

486 \def\pout_line#1#2{\immediate\write#1{#2}}
\pout_lline \pout_llline There relate to \pout_line as \out_lline and \out_llline to \out_line.
487 \edef\pout_lline#1#2{\noexpand\pout_line#1{\space\space\space#2}}
488 \edef\pout_llline#1#2{
489 \noexpand\pout_line#1{\space\space\space\space\space\space#2}

490 }

\tempfileprefix \temp_prefix Selecting the directory for temporary files.

491 \def\tempfileprefix#1{\def\temp_prefix{#1}}
492 \tempfileprefix{}

493 ⟨/pkg⟩

8.4 Conditionals

8.4.1 Conditionals in fontinst

\then \if_true \if_false In order to write macros that expand out to nested \if-statements, I say:

     \ifblah . . . \then . . . \else . . . \fi

In order to match the \fi, \then has to be an \if.

494 ⟨pkg | doc⟩\let\then=\iffalse

495 ⟨∗pkg⟩

496 \def\if_false{\iffalse}
497 \def\if_true{\iftrue}
\if_defined \if_undefined These two macros are used as

\if_defined{⟨control sequence name⟩}\then \if_undefined{⟨control sequence name⟩}\then

The latter is functionally equivalent to

\x_cs\ifx{⟨control sequence name⟩}\x_relax

but it is shorter (1–3 tokens, depending on whether the unnecessary braces around ⟨control sequence name⟩ are included or not). The former tests the same thing, but has true and false cases reversed.

Apart from that it is shorter, another important reason for introducing these macros is that the ε-TEX primitives \ifcsname and \unless provide a much better implementation than what is possible in normal TEX. Therefore it is desirable to use these commands as much as possible, and by introducing these macros one can achieve this without having double definitions for more than these two macros.

To avoid trouble with mismatched ifs and tokenizing control sequences special for ε-TEX, ~ is temporarily made a comment character. I’m not sure \ifcsname and \unless weren’t available in ε-TEX versions before 2.0, but that’s the oldest version I have a manual for.

498 \_a_false\eTeX{2.0}
499 \if_a_\else \catcode`\~=14\x_relax \fi

The following use of \if is a trick I learnt from the implementation of docstrip. \if will expand any amount of material until it has two unexpandable tokens to compare, hence one can use it to evaluate arbitrary boolean expressions in a single TEX conditional, by expressing the expression as something which expands in TEX’s mouth to the value of the expression (either 0 or 1). In this case the expression is “the control sequence is defined and that definition is not \relax”.

500 ~  \def\if_defined#1\then{
501 ~     \if
502 ~        \ifcsname#1\endcsname
503 ~           \expandafter\ifx \csname#1\endcsname \x_relax

504 ~ 0

505 ~           \else

506 ~ 1

507 ~           \fi
508 ~        \else

509 ~ 0

510 ~        \fi

511 ~ 1 512 ~ }

513 ~  \def\if_undefined{\expandafter\unless\if_defined}
514 \catcode`\~=\if_a_14 \else 10 \fi \x_relax
515 ~  \def\if_defined#1\then{
516 ~     \expandafter\ifx \csname#1\endcsname\x_relax
517 ~        \expandafter\if_false
518 ~     \else
519 ~        \expandafter\if_true
520 ~     \fi

521 ~ }

522 ~  \def\if_undefined#1\then{
523 ~     \expandafter\ifx \csname#1\endcsname\x_relax

524 ~ }

525 \catcode`\~=10\x_relax

\gobble_if It is sometimes best to skip both the then-part and the else-part of a conditional. \gobble_if does this by using the fact that expanding \else skips everything until the next matching \fi without looking for other \elses.

526 \def\gobble_if{\iftrue\else}

\if_or \or_else \if_or … \or_else … \then gives the disjunction of two booleans.

527 \def\if_or#1\or_else#2\then{
528 #1\then
529  \expandafter\if_true
530 \else
531  #2\then
532  \expandafter\expandafter\expandafter\if_true
533  \else
534  \expandafter\expandafter\expandafter\if_false
535  \fi
536 \fi

537 }

\if_equal The \if_equal macro is a … \then-style wrapper around the \ifx primitive. Its calling syntax is

\if_equal⟨token1 ⟩⟨token2 ⟩\then

538 \def\if_equal#1\then{\ifx#1}
\if_file_exists  \if_file_exists checks to see if a file exits, using \openin.
539 \def\if_file_exists#1\then{
540 \immediate\openin1=#1\x_relax
541 \ifeof1\x_relax

542  \immediate\closein1
543  \expandafter\if_false
544 \else
545  \immediate\closein1
546  \expandafter\if_true
547 \fi

548 } 549 ⟨/pkg⟩

8.4.2 Conditionals in fontdoc

In order to get a reasonable documentation of branches in an ETX or MTX file, the code in both branches must be typeset and the positions of the if, the else, and the fi must be clearly marked. There seems to be no reasonable way to achieve this if the standard names for the else and fi are used. Therefore the alternative names \Else and \Fi for \else and \fi have been introduced, to be used as in for example

     \ifisint{monowidth}\then

⟨then-part⟩

     \Else

⟨else-part⟩

     \Fi

{\Else \atop \Fi} By default, these are identical to their lowercase counterparts.

550 ⟨∗pkg | doc⟩

551 \let\Else=\else
552 \let\Fi=\fi

553 ⟨/pkg | doc⟩

The interesting part begins if the ETX or MTX file gives the command \showbranches, since this means (i) that it wants the branches to be shown and (ii) that it complies to a simple rule about where to use \Else and \Fi. The rule is as follows: If an if statement is of fontinst form (it uses \then), then it must be terminated by \Fi, and a possible else in the statement must be an \Else. If an if statement is not of fontinst form (it has no \then), then it must be terminated by \fi, and a possible else in the statement must be an \else. Only the fontinst form if statements are affected by \showbranches.

\showbranches \generic@if The \showbranches command changes the definitions of \generic@if, \then,

\Else, and \Fi so that the branches of if statements will be made visible. \generic@if is used to implement all the fontinst form if statements in fontdoc. It is called as

     \generic@if{⟨description⟩}

and this will by default expand to \iftrue, but after executing \showbranches it will instead typeset

If ⟨description⟩ then

and do a bit of additional housekeeping.

554 ⟨∗doc⟩

555 \def\generic@if#1{\iftrue}

556 \newcommand\showbranches{%
557 \let\generic@if=\branches@if
558 \let\then=\x@relax
559 \let\Else=\branches@else
560 \let\Fi=\branches@fi

561 }

\saved@slot@number The \saved@slot@number is used for storing the value of \slot@number at the if

until the \Else. Unlike \slot@number, it is always set locally.

562 \newcount\saved@slot@number
\branches@if \branches@else \branches@fi \branches@type \branches@par The macros \branches@if, \branches@else, and \branches@fi contain the def-

initions of \generic@if, \Else, and \Fi respectively that are used when branches are to be shown. Their basic task is to typeset the texts If #1 then, Else, and Fi in an appropriate style and with appropriate spacing around. A complicating matter is however that \slot@number must have the same value at the beginning of the else part as at the beginning of the then part. To achieve this, the value of \slot@number is saved in \saved@slot@number at the if and copied back at the else. To make this work even with nested if s, both the then branch and the else branch are enclosed in groups and \saved@slot@number is assigned locally.

There are still some formatting issues to solve, however. In some cases it works best to put the text of adjacent if, else, or fi in the same paragraph, and it must be possible to recognize those cases. This is done by looking at the macro \branches@type, which should expand to

0 if the preceeding item was an if,

1 if the preceeding item was an else preceeded by an if,

2 if the preceeding item was an else not preceeded by an if,

3 if the preceeding item was a fi,

4 if it was anything else.

\branches@par is used for resetting \branches@type to 4. It is an auto-resetting definition of \par.

563 \def\branches@if#1{%
564 \ifnum \branches@type=\tw@
565  \begin{IfBranchDummy}%
566  \textit{ if #1 then}%
567 \else
568  \par
569  \ifFD@tight@\else \addvspace\medskipamount \fi
570  \noindent\textit{If #1 then}%
571 \fi
572 \saved@slot@number=\slot@number
573 \gdef\branches@type{0}%
574 \let\par=\branches@par

575 }

576 \def\branches@else{%
577 \ifnum \branches@type=\z@
578  \textit{ relax else}%

579  \gdef\branches@type{1}%
580 \else
581  \par
582  \end{IfBranch}%
583  \noindent\textit{Else}%
584  \gdef\branches@type{2}%
585 \fi
586 \global\slot@number=\saved@slot@number
587 \let\par=\branches@par

588 }

589 \def\branches@fi{%
590 \ifnum \branches@type=\thr@@
591  \expandafter\end \expandafter{\@currenvir}%
592  \expandafter\gdef \expandafter\FD@saved@fis
593  \expandafter{\FD@saved@fis \space fi}%
594 \else
595  \end{IfBranch}%
596  \gdef\FD@saved@fis{Fi}%
597 \fi
598 \gdef\branches@type{3}%
599 \let\par=\branches@par

600 }

601 \gdef\branches@type{4}
602 \def\branches@par{%
603 \@restorepar
604 \ifnum \branches@type=\thr@@
605  \noindent\textit{\FD@saved@fis}\par
606 \else
607  \begin{IfBranch}%
608 \fi
609 \gdef\branches@type{4}%

610 }

IfBranch FD@tight@ switch The branches of a conditional that is being shown are put in an IfBranch environment, to emphasize the branches as logical units in the file. Depending on the value of the FD@tight@ switch, there are two different ways that the branches can be distinguished. In the non-tight setting (FD@tight@ false), there is one \medskipamount of vertical space before and after the branch, but no indentation. In the tight setting (which is used for ⟨glyph commands⟩ and ⟨slot commands⟩), there is no extra vertical space around the branch, instead it is indented by 1 em.

611 \newif\ifFD@tight@
612 \newenvironment{IfBranch}{%
613 \list{}{%
614  \ifFD@tight@
615  \setlength\topsep{\z@skip}%
616  \@beginparpenalty=\z@
617  \@endparpenalty=\z@
618  \setlength\leftmargin{1em}%
619  \else
620  \setlength\topsep{\medskipamount}%
621  \@beginparpenalty=-10%
622  \@endparpenalty=\@beginparpenalty

623  \setlength\leftmargin{\z@}%
624  \fi
625  \setlength\partopsep{\z@skip}%
626  \setlength\itemsep{\z@skip}%
627  \setlength\parsep{\z@ plus\p@}%
628  \setlength\rightmargin{\z@}%
629  \setlength\itemindent{\z@}%

630 }%

631 \item[]%
632 }{\endlist}

IfBranchDummy In order to get the nesting right, each \branches@else command has to \begin a new environment, but if it is immediately followed by a \branches@if then that environment should not cause an indentation. In these cases the IfBranchDummy environment is used instead of IfBranch.

633 \newenvironment{IfBranchDummy}{}{}

634 ⟨/doc⟩

8.4.3 Miscellanea

\primitiveinput If \@@input is defined, I’ll assume it’s the L^{A}TEX version of the TEX \input primitive. I need this so that I can say \expandafter\foo\primitiveinput, which doesn’t work with the L^{A}TEX version of \input.

635 ⟨∗pkg⟩

636 \x_cs\ifx{@@input}\x_relax
637 \let\primitiveinput=\input
638 \else
639 \let\primitiveinput=\@@input
640 \fi
\process_csep_list  The macro
     \process_csep_list{⟨pretext⟩}⟨comma-sep list⟩,\process_csep_list,

executes ⟨pretext⟩{⟨item⟩} for every item in the ⟨comma-sep list⟩.

\process_csep_list
641 \def\process_csep_list#1#2,{
642 \ifx\process_csep_list#2
643  \expandafter\gobble_one
644 \else
645  \expandafter\identity_one
646 \fi{
647  #1{#2}
648  \process_csep_list{#1}

649 } 650 } 651 ⟨/pkg⟩

\print@csep@list Use of this macro is now deprecated; use \TypesetList instead wherever possible. The macro call

     \print@csep@list{⟨format⟩}{⟨list⟩}

prints the comma-separated list ⟨list⟩ in math mode. ⟨format⟩ can be used to set the style in which the list is printed, since it is executed in the beginning of the same group as in which the list is printed.

The formating is based on changing the \mathcode of comma to "8000 so that the comma can be used as if it was an active character without actually having to be one.

652 ⟨∗doc⟩

653 \begingroup
654 \catcode`\,=13
655 \gdef\print@csep@list#1#2{%

656 $%

657  \ifnum "8000=\mathcode`\,\else
658  \mathchardef\private@comma=\mathcode`\,%
659  \mathcode`\,="8000\x@relax
660  \fi
661  #1%
662  \let,=\active@comma
663  #2%

664 $% 665 }

666 \endgroup
667 \def\active@comma{\private@comma \penalty\binoppenalty}

668 ⟨/doc⟩

8.5 Real numbers

TEX’s ⟨number⟩s are merely integers, but fontinst needs to store and calculate with numerical entities (most of which are lengths) that are intrinsically real numbers. Most of the time, fontinst does this by using a representation of real numbers by integers in which a real number x is represented by the integer that 1000x gets rounded to. This representation has proved sufficiently precise for most purposes.

There are however a few cases in which real numbers must be delt with in a more general fashion. Generic routines for this appear in this subsection.

\make_factor The \make_factor macro is meant to be used in the context

     \make_factor{⟨number⟩}

where ⟨number⟩ can be any legal TEX number. It expands to the same number divided by 1000, with decimals, so that what it expands to matches the regular expression

     -?[0-9]+\.[0-9][0-9][0-9]

More specifically, \make_factor has two tasks to perform: it takes care of the sign, so that its subsidary macros need only work with unsigned numbers, and it converts the ⟨number⟩ (which could well be a countdef or mathchardef token) to a sequence of digits.

669 ⟨∗pkg⟩

670 \def\make_factor#1{
671 \ifnum #1<\z@
672  -\expandafter\make_factor_i\expandafter{\number-#1}
673 \else

674  \expandafter\make_factor_i\expandafter{\number#1}
675 \fi

676 }

\make_factor_i \make_factor_i distinguishes between the two main cases of numbers that in absolute value are less than 1000 and numbers that in absolute value are greater than or equal to 1000. In the former case, zeros need to be inserted. In the latter case, some number of digits need to be stepped over before the decimal point can be inserted.

677 \def\make_factor_i#1{
678 \ifnum #1<\one_thousand
679  \make_factor_ii{#1}
680 \else
681  \make_factor_iii #1
682 \fi

683 #1 684 }

\make_factor_ii \make_factor_ii inserts extra zeros, in the extent it is needed.

685 \def\make_factor_ii#1{

686 0.

687 \ifnum #1<\one_hundred

688 0

689  \ifnum #1<10~ 0\fi
690 \fi

691 }

\make_factor_iii \make_factor_iii steps over one digit and checks if this is the correct position for the decimal point. Note that #2#3 is exactly the digits in the number that has not been stepped over. Also note that comparision with #2#3 would not work, since #2 can be 0.

692 \def\make_factor_iii#1#2#3\fi#4{
693 \fi

694 #4

695 \ifnum 1#3<\one_thousand

696 .

697 \else
698  \make_factor_iii#2#3
699 \fi

700 }

It also happens that real numbers are represented by dimens, in the common way that the number 1 is represented by the dimen 1 pt. For those cases the following macro is indispensable.

\lose_measure Get rid of a trailing pt when converting dimension.

701 {

702 \catcode`\p=12
703 \catcode`\t=12
704 \gdef\lose_measure#1pt{#1}

705 } 706 ⟨/pkg⟩

8.6 Hexadecimal numbers

Some of the file formats fontinst can generate requires that some numbers are written in hexadecimal form rather than in TEX’s default decimal form. This is somewhat awkward, as it would be very hard to implement without using explicit arithmetic.

\format_hex The \format_hex command formats a number as hexadecimal digits. The syntax is

\format_hex{⟨command⟩}{⟨value⟩}{⟨digits⟩}

where ⟨command⟩ will be \defined to be the formatted number. ⟨value⟩ is the number to format; it must not be negative. ⟨digits⟩ is the number of digits to generate. If the ⟨value⟩ is greater than or equal to 16^{digits} then \a_count will be set to ⟨value⟩ divided by this number and the formatted value will be for the corresponding reminder.

   The macro overwrites \a_count, \b_count, and \c_count.

\format_hex_i The \format_hex_i macro is the iterator for \format_hex. It is used in the context

\format_hex_i{⟨command⟩}{⟨control token⟩}

If the ⟨control token⟩ is i then nothing is done. Otherwise the quotient and reminder of \a_count with respect to 16 is computed, where the former is assigned to \a_count and the latter is converted to hexadecimal and prepended to the ⟨command⟩, after which the macro expands to \format_hex_i⟨command⟩.

707 ⟨∗pkg⟩

708 \def\format_hex_i#1#2{
709 \if #2i \else
710  \b_count=\a_count
711  \divide \a_count \sixt@@n
712  \c_count=\a_count
713  \multiply \c_count \sixt@@n
714  \advance \b_count -\c_count
715  \edef#1{
716  \ifcase\b_count 0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or 8\or
717  9\or a\or b\or c\or d\or e\or f\fi

718 #1 719 }

720  \expandafter\format_hex_i \expandafter#1
721 \fi

722 }

To get the loop to run the wanted number of times, one uses the trick that \romannumeral can generate an arbitrary number of ms. The \identity_one stuff is to prevent \number from processesing the subsequent 001~, which will be the last that \roman reads.

723 \def\format_hex#1#2#3{
724 \a_count=#2
725 \let#1\empty_command
726 \expandafter\format_hex_i \expandafter#1 \romannumeral
727  \expandafter\identity_one\expandafter{\number#3}001~

728 } 729 ⟨/pkg⟩

8.7 Error, warning, and info messages

The code in this subsection is an adaptation of code from the L^{A}TEX kernel—more precisely from the source file lterror.dtx—and the same is true for some of the comments. As authors of that code are listed Johannes Braams, David Carlisle, Alan Jeffrey, Leslie Lamport, Frank Mittelbach, Chris Rowley, and Rainer Schöpf. The original source can be found in the file lterror.dtx in the macros/latex/ base directory in any of the Comprehensive TEX Archive Network FTP sites.^{8}

That should have fulfilled the conditions in the LPPL.

8.7.1 General commands

\messagebreak This command prints a new-line inside a message, followed by a continuation whose exact appearence may depend on the context. Normally this command is defined to be \relax, but inside messages it gets redefined to a linebreak (^^J) followed by the appropriate continuation.

730 ⟨pkg⟩\let\messagebreak\x_relax
731 ⟨doc⟩\let\messagebreak\space

\generic_info This takes two arguments: a continuation and a message, and sends the result to the log file.

732 ⟨∗pkg⟩

733 \def\generic_info#1#2{
734 \begingroup
735  \def\messagebreak{^^J#1}
736  \immediate\write\m@ne{#2\on_line.}
737 \endgroup

738 }

\generic_warning This takes two arguments: a continuation and a message, and sends the result to the screen.

739 \def\generic_warning#1#2{
740 \begingroup
741  \def\messagebreak{^^J#1}
742  \immediate\write\closed_stream{^^J#2\on_line.^^J}
743 \endgroup

744 }

\generic_error “This macro takes four arguments: a continuation, an error message, where to go for further information, and the help information. It displays the error message, and sets the error help (the result of typing h to the prompt), and does a horrible hack to turn the last context line (which by default is the only context line) into just three dots. This could be made more efficient.”

Thus far the L^{A}TEX comments, but the horrible hack it mensions has been removed since it just makes things look strange when \errorcontextlines is larger than one. The “where to go for further information” message is currently not used (it is commented out in \fontinsterror below), since there is no good place to refer to anyway. If the documentation is ever improved in this respect, it would of course be best to reinsert this message. Note however that unlike the case in L^{A}TEX, this message should end with a ^^J.

8As if anyone who has managed to get this far didn’t already know that!

A complication is that TEX versions older than 3.141 have a bug which causes ^^J to not force a linebreak in \message and \errmessage commands. So for these old TEX’s we use a \write to produce the message, and then have an empty \errmessage command. This causes an extra line of the form

! .

to appear on the terminal, but if you do not like it, you can always upgrade your TEX!

Since I don’t think many fontinst users use such old TEXs, I removed L^{A}TEX’s test for TEX version at this point. The code for old TEXs is still there, but it lies in a docstrip module of its own.

First the ‘standard case’.

745 ⟨∗!oldTeX⟩

746 \def\generic_error#1#2#3#4{
747 \begingroup
748  \immediate\write\closed_stream{}
749  \def\messagebreak{^^J}
750  \edef\a_macro{{#4}}
751  \errhelp\a_macro
752  \def\messagebreak{^^J#1}
753  \errmessage{#2.^^J^^J#3
754  Type~\space H~<return>~\space for~immediate~help

755 }

756 \endgroup

757 } 758 ⟨/!oldTeX⟩

Secondly the version for old TEX’s.

759 ⟨∗oldTeX⟩

760 \def\generic_error#1#2#3#4{%
761 \begingroup
762  \immediate\write\closed_stream{}
763  \def\messagebreak{^^J}
764  \edef\a_macro{{#4}}
765  \errhelp\a_macro
766  \def\messagebreak{^^J#1}
767  \immediate\write\closed_stream{!~#2.^^J^^J#3^^J
768  Type~\space H~<return>~\space for~immediate~help.

769 }

770  \errmessage{}
771 \endgroup

772 } 773 ⟨/oldTeX⟩

\fontinsterror \fontinstwarning \fontinstwarningnoline \fontinstinfo These commands are intended for giving a uniformed, and for the programmers

hopefully simplified, form of error, warning, and info messages. The syntax is:

\fontinsterror{⟨subsystem⟩}{⟨error⟩}{⟨help⟩}

     \fontinstwarning{⟨subsystem⟩}{⟨warning⟩}
     \fontinstwarningnoline{⟨subsystem⟩}{⟨warning⟩}
     \fontinstinfo{⟨subsystem⟩}{⟨info⟩}

A ⟨subsystem⟩ in this context is intended to be some piece of text which identifies some functionally clearly defined part of fontinst. Examples of ⟨subsystem⟩s could

be PL to MTX converter, Ligful (V)PL writer, and Latin family.

The \fontinsterror command prints the ⟨error⟩ message, and presents the interactive prompt; if the user types h, then the ⟨help⟩ information is displayed. The \fontinstwarning command produces a warning but does not present the interactive prompt. The \fontinstwarningnoline command does the same, but doesn’t print the input line number. The \fontinstinfo command writes the message to the log file. Within the messages, the command \messagebreak can be used to break a line and \space is a space, for example:

     \def\foo{FOO}
     \fontinstwarning{Hungarian}{
        Your~hovercraft~is~full~of~eels,\messagebreak
        and~\string\foo\space is~\foo}

produces:

     Hungarian warning:
             Your hovercraft is full of eels,
             and \foo is FOO on input line 54.

774 \def\fontinsterror#1#2#3{
775 \generic_error{
776  \four_spaces\four_spaces

777 }{

778  #1~error:\messagebreak #2

779 }{

780 %       See~the~#1~package~documentation~for~explanation.^^J
781 }{#3}

782 }

783 \def\fontinstwarning#1#2{
784 \generic_warning{
785  \four_spaces\four_spaces

786 }{

787  #1~warning:\messagebreak #2

788 } 789 }

790 \def\fontinstwarningnoline#1#2{
791 \fontinstwarning{#1}{#2\gobble_one}

792 }

793 \def\fontinstinfo#1#2{
794 \generic_info{
795  \four_spaces\four_spaces

796 }{

797  #1~info:\messagebreak #2

798 } 799 } 800 ⟨/pkg⟩

801 ⟨∗doc⟩

802 \def\fontinsterror#1#2#3{%
803 \Bheading{Error} observed by #1:%
804 \begin{quote}#2.\end{quote}%

805 }

806 \def\fontinstwarning#1#2{
807 \Bheading{Warning} from #1:%
808 \begin{quote}#2.\end{quote}%

809 }

810 \let\fontinstwarningnoline=\fontinstwarning
811 \def\fontinstinfo#1#2{
812 \Bheading{Info} from #1:%
813 \begin{quote}#2.\end{quote}%

814 } 815 ⟨/doc⟩

\on_line The message ‘ on input line n’. L^{A}TEX has special code for TEX 2, but since fontinst has assumed the existence of the \errorcontextlines parameter since v 1.500, the removal of that code shouldn’t cause problems for anyone who wasn’t already having related problems.

816 ⟨∗pkg⟩

817 \def\on_line{~on~input~line~\the\inputlineno}

\four_spaces Four spaces. Using \edef (rather than \def as in L^{A}TEX) to save some macro expansions.

818 \edef\four_spaces{\space\space\space\space}

8.7.2 Specific errors

\error_help_a \error_help_c \error_help_d \error_help_e The more common error help messages. The first three are called \@eha, \@ehc,

and \@ehd in L^{A}TEX. \@ehb is of no use for fontinst, so it has been omitted. \error_help_e is a new one for fontinst.

819 \gdef\error_help_a{
820 Your~command~was~ignored.\messagebreak
821 Type~\space I~<command>~<return>~\space to~replace~it~
822 with~another~command,\messagebreak
823 or~\space <return>~\space to~continue~without~it.}
824 \gdef\error_help_c{
825 Try~typing~\space <return>~
826 \space to~proceed.\messagebreak
827 If~that~doesn't~work,~type~\space X~<return>~\space to~quit.}
828 \gdef\error_help_d{
829 You're~in~trouble~here.~\space\error_help_c}
830 \def\error_help_e#1{You~can~continue,~but~the~#1~wrong.}

8.7.3 TEX parameters

\newlinechar Set \newlinechar for \errhelp messages.
831 \newlinechar=`\^^J

\errorcontextlines By default, show as much error info as you can. (We assume fontinst users are TEXperts.)

832 \errorcontextlines=999

\tracinglostchars Make \tracinglostchars positive—this will simplify catching bugs, as many fontinst bugs show up in that output is being generated, but that used to disappear silently when fontinst was run under IniTEX.

833 \tracinglostchars=1

834 ⟨/pkg⟩

File b

ficommon.dtx

9 General commands

There are roughly five types of arguments that fontinst commands can take. These are

• integer expressions,

• string expressions,

• dimensions,

• commands (i.e., TEX control sequences), and

• other (pretty much “none of the above”).

The most common form of an integer expression is simply a TEX ⟨number⟩ and the most common form of a string expression is simply a sequence of character tokens, but there are more complicated forms. Dimensions are simply TEX ⟨dimen⟩s; their use is rather limited. Common to integer expressions, string expressions, and dimensions is that these argument types get expanded during evaluation (in the case of string expressions, this expansion is the evaluation), which means one can use macros in arguments of these types.

Command arguments do not get expanded—they are mainly used with commands that modify the definitions of other commands. As for the “other” arguments one cannot give any rules: they might get expanded, but it could also happen that they won’t.

9.1 String expressions

The first problem with string expressions is to typeset the values. The character strings that appear in ETX and MTX files usually consist only of immediately printable characters, but there are a few characters (such as underscore) which may be used even though they aren’t directly printable. This subsection defines commands which deal with this problem by replacing non-printable characters by commands. The implementation is based on the implementation of the \MakeHarmless command in the xdoc package.

9.1.1 Typesetting problematic characters

\PrintChar \InvisibleCharPrefix \InvisibleCharSuffix The \PrintChar command has the syntax

\PrintChar{⟨8-bit number⟩}

where ⟨8-bit number⟩ is a TEX number in the range 0–255. For arguments in the range 0–31, \PrintChar prints ‘^^@ ’–‘^^_’. For an argument in the range 32–126, \PrintChar calls \PrintVisibleChar which typesets the corresponding ASCII character (similar to \char, but it takes the path via the L^{A}TEX internal representation so that it works with non-typewriter OT1 fonts); in particular, \PrintChar{32} prints a “visible space” character. \PrintChar{127} prints ‘^^? ’. For arguments in the range 128–255, \PrintChar prints ‘^^80 ’–‘^^ff ’. The \PrintChar command is robust.

   The macros \InvisibleCharPrefix and \InvisibleCharSuffix begin and

end a ^^-sequence. \InvisibleCharPrefix should print the actual ^^, but it may also for example select a new font for the ^^-sequence (such font changes are restored at the end of \PrintChar).

1 ⟨∗doc⟩

 2 \DeclareRobustCommand\PrintChar[1]{%
 3 \leavevmode
 4 \begingroup
 5  \count@=#1\relax
 6  \ifnum \@xxxii>\count@
 7  \advance \count@ 64%
 8  \InvisibleCharPrefix
 9  \PrintVisibleChar\count@
10  \InvisibleCharSuffix
11  \else\ifnum 127>\count@
12  \PrintVisibleChar\count@
13  \else
14  \InvisibleCharPrefix
15  \ifnum 127=\count@ \PrintVisibleChar{63}\else
16  \@tempcnta=\count@
17  \divide \count@ \sixt@@n
18  \@tempcntb=\count@
19  \multiply \count@ \sixt@@n
20  \advance \@tempcnta -\count@
21  \advance \@tempcntb \ifnum 9<\@tempcntb 87\else 48\fi
22  \advance \@tempcnta \ifnum 9<\@tempcnta 87\else 48\fi
23  \char\@tempcntb \char\@tempcnta
24  \fi
25  \InvisibleCharSuffix
26  \fi\fi
27 \endgroup

28 }

29 \newcommand\InvisibleCharPrefix{%
30 \/\em
31 \PrintVisibleChar{`\^}\PrintVisibleChar{`\^}%

32 }

33 \newcommand\InvisibleCharSuffix{\/}

\PrintVisibleChar The \PrintVisibleChar command should print the visible ASCII character whose character code is given in the argument. The definition given here translates every character code to the corresponding L^{A}TEX internal representation, which is necessary if the current font is e.g. an OT1-encoded non-typewriter font. If the current font is known to be T1-encoded then one can do just as well with \char#1 as the replacement text.

34 \newcommand\PrintVisibleChar[1]{%
35 \ifcase #1%
36 \or\or\or\or\or\or\or\or \or\or\or\or\or\or\or\or
37 \or\or\or\or\or\or\or\or \or\or\or\or\or\or\or\or
38 % "20
39  \textvisiblespace \or!\or\textquotedbl \or\#\or\textdollar

40  \or\%\or\&\or\textquoteright\or(\or)\or*\or+\or,\or-\or.\or/%
41 \or % "30
42  0\or1\or2\or3\or4\or5\or6\or7\or8\or9\or:\or;\or
43  \textless\or=\or\textgreater\or?%
44 \or % "40
45  @\or A\or B\or C\or D\or E\or F\or G\or
46  H\or I\or J\or K\or L\or M\or N\or O%
47 \or % "50
48  P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z\or [\or
49  \textbackslash \or]\or\textasciicircum \or\textunderscore
50 \or % "60
51  \textquoteleft \or a\or b\or c\or d\or e\or f\or g\or h\or
52  i\or j\or k\or l\or m\or n\or o%
53 \or % "70
54  p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z\or
55  \textbraceleft \or\textbar \or\textbraceright \or\textasciitilde
56 \fi

57 }

\textvisiblespace The \textvisiblespace command, which is heavily used in names of coding schemes, unfortunately has a default definition which lacks leading on the right side. This redefinition attempts to improve things.

58 \DeclareTextCommandDefault{\textvisiblespace}{%
59 \makebox[\fontdimen\tw@\font]{%
60  \hfil
61  \vrule \@height.3ex%
62  \vbox{\hrule \@width .66\fontdimen\tw@\font}%
63  \vrule \@height.3ex%
64  \hfil
65 }%

66 }

\FD@quoted@PrintChar One sometimes wants to use a printable character string as part of a control sequence name. If the normal definition of \PrintChar is in force at such times then each \PrintChar in the string would produce lots of errors, which is why \FD@quoted@PrintChar has been defined. This macro is an alternative definition of \PrintChar which expands to "⟨number⟩", which can be part of a macro name.

67 \def\FD@quoted@PrintChar#1{"\number#1"}

9.1.2 Converting character strings

Replacing all problematic characters with \PrintChar calls certainly makes the strings easier to manage, but actually making those replacements is a rather complicated task. This subsubsection contains the macros necessary for doing these replacements.

The first problem is how to efficiently recognise the problematic characters. One might think that it is sufficient to look at their \catcode, but that will fail for characters like < whose normal catcode is 12 but do not appear in the OT1 encoding. Because of this, I have chosen a brute strength solution: build a table (indexed by character code) that gives the printable form of every character. This

\FD@printable@⟨code⟩ table is stored in the \FD@printable@⟨code⟩ family of control sequences, where the ⟨code⟩ is in the range 32–126. The printable form of characters outside this range is always the \PrintChar form.

68 \count@=32
69 \begingroup
70 \catcode\z@=12\relax
71 \@firstofone{%
72 \endgroup
73 \loop
74  \if \ifnum 11=\catcode\count@ 1\else \ifnum 12=\catcode\count@
75  1\else 0\fi\fi 1%
76  \uccode\z@=\count@
77  \uppercase{\def\@tempa{^^@}}%
78  \else
79  \edef\@tempa{\noexpand\PrintChar{\the\count@}}%
80  \fi
81  \x@cs\let{FD@printable@\the\count@}=\@tempa
82  \advance \count@ \@ne
83 \ifnum 127>\count@ \repeat

84 }

This loop hasn’t caught all non-printable characters, so a few entries have to be set explicitly.

85 \@namedef{FD@printable@34}{\PrintChar{34}} % "
86 \@namedef{FD@printable@60}{\PrintChar{60}} % <
87 \@namedef{FD@printable@62}{\PrintChar{62}} % >

\MakePrintable To render a character string harmless, you do

     \MakePrintable{⟨macro⟩}{⟨flag⟩}{⟨string⟩}

This locally assigns to ⟨macro⟩ the printable character string which corresponds to ⟨string⟩. Furthermore the control sequence \if⟨flag⟩ is locally let to \iftrue or \iffalse depending on whether the printable string is simple (only consists of character tokens and \PrintChar commands) or not.

During the conversion the converted part of the string is stored in \toks@ and the @tempswa switch keeps track of whether the string so far is simple (yes when false), but those are both local to \MakePrintable.

88 \def\MakePrintable#1#2#3{%
89 \begingroup
90  \toks@={}%
91  \escapechar=`\\%
92  \@tempswafalse
93  \FD@printable@#3\protect\FD@printable@
94  \toks@=\expandafter{%
95  \expandafter\let \csname if#2\expandafter\endcsname
96  \csname if\if@tempswa false\else true\fi \expandafter\endcsname
97  \expandafter\def \expandafter#1\expandafter{\the\toks@}%
98  }%
99 \expandafter\endgroup \the\toks@

100 }

\FD@printable@iii \FD@printable@iv \FD@printable@v \FD@printable@vi What one has to be most careful about when making strings printable are the

space tokens, since many of TEX’s primitives gladly snatches an extra space (or more) where you don’t want them to in this case. Macro parameters can be particularly dangerous, as TEX will skip any number of spaces while looking for the replacement text for an undelimited macro argument. Therefore the algorithm for rendering a character token harmless consists begins (\FD@printable@iii) with \stringing the next token in the string—this preserves the character code and sets the category to 12 for all characters except the ASCII space, which gets category 10 (space)—and then \futurelet is used to peek at the next token. If it is a space token (\FD@printable@iv) then the character code is 32 and the actual space can be gobbled (\FD@printable@v), and if it isn’t then the next token can be grabbed in a undelimited macro argument (\FD@printable@vi). In either case, the harmless form is given by the \FD@printable@⟨code⟩ table entry

(in \FD@printable@v or \FD@printable@vi).
101 \def\FD@printable@iii{%
102 \expandafter\futurelet \expandafter\@let@token
103 \expandafter\FD@printable@iv \string

104 }

105 \def\FD@printable@iv{%
106 \ifx \@let@token\@sptoken
107  \expandafter\FD@printable@v
108 \else
109  \expandafter\FD@printable@vi
110 \fi

111 }

112 \begingroup
113 \catcode`3=\catcode`a
114 \catcode`2=\catcode`a
115 \@firstofone{\gdef\FD@printable@v} {%
116  \toks@=\expandafter{\the \expandafter\toks@ \FD@printable@32}%
117  \FD@printable@

118 }

119 \endgroup
120 \def\FD@printable@vi#1{%
121 \if \ifnum `#1<\@xxxii 1\else \ifnum `#1>126 1\else 0\fi\fi 1%
122  \toks@=\expandafter{\the\expandafter\toks@
123  \expandafter\PrintChar \expandafter{\number`#1}%

124 }%

125 \else
126  \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@
127  \csname FD@printable@\number`#1\endcsname}%
128 \fi
129 \FD@printable@

130 }

\FD@printable@ \FD@printable@i \FD@printable@ii \FD@printable@vii But that is not all \MakePrintable can do. One must also deal with things in the

string that are not simply characters, but more complex items (for example \str and \strint constructions). When control sequences that start such complex items are fed to \MakePrintable they must be preceeded by a \protect (they will be if the original command is defined using L^{A}TEX’s \DeclareRobustCommand command and the string has been fed through a \protected@edef, which happens to be the case); this \protect is taken as a signal that the next token should get special processing. Control sequences that are not preceeded by a \protect are simply \stringed.

To accommodate for this, \FD@printable@ (which is the first step in converting a token) always begins by checking (in \FD@printable@i) whether the next token is a control sequence. If it is and that control sequence is \protect then it is checked (in \FD@printable@ii) whether the control sequence

\FD@printable\⟨cs-name⟩ \FD@printable\⟨cs-name⟩, where ⟨cs-name⟩ is the name without \ (and with any spaces removed) of the control sequence encountered, is defined. If it is defined then control is handed over to \FD@printable\⟨cs-name⟩ which should process the arguments (if any) of \⟨cs-name⟩ and add a suitable representation to \toks@, but if \FD@printable\⟨cs-name⟩ isn’t defined then this is considered to be an error.

If the next token isn’t a control sequence then control is handed over to \FD@printable@ii. If the next token is a control sequence but not \protect then that token is \stringed (in \FD@printable@vii) and control is handed over

to \FD@printable@vi.
131 \def\FD@printable@{\futurelet\@let@token \FD@printable@i}
132 \def\FD@printable@i{%
133 \csname FD@printable@%
134  \ifcat \noexpand\@let@token \noexpand\FD@printable@
135  \ifx \@let@token\protect ii\else vii\fi
136  \else iii\fi
137 \endcsname

138 }

139 \def\FD@printable@ii\protect#1{%
140 \@ifundefined{FD@printable\expandafter\zap@space\string#1 \@empty}{%
141  \PackageError{fontdoc}{Command \protect#1 not allowed in string}%
142  \@eha
143 }{\csname FD@printable\expandafter\zap@space\string#1 \@empty
144  \endcsname}%

145 }

146 \def\FD@printable@vii{\expandafter\FD@printable@vi \string}

\FD@printable\FD@printable@ A control sequence \FD@printable\⟨cs-name⟩ is responsible for interpreting the string item that begins with the control sequence \⟨cs-name⟩ and appending a printable representation of it to \toks@. Normal \FD@printable\⟨cs-name⟩ control sequences must also end by inserting \FD@printable@ in front of what remains of the string after the complex string item has been removed. This sees to that the rest of the string is also made printable. The only such control sequence which

does not insert \FD@printable@ is \FD@printable\FD@printable@, but that is

as it should be since \MakePrintable itself appends a \FD@printable@ to every character string it should convert to mark the end of it.

147 \expandafter\let
148 \csname FD@printable\string\FD@printable@\endcsname \@empty

\FD@printable\PrintChar It is occasionally convenient to use a \PrintChar command as part of a string that is to be made harmless instead of using the raw character. The definition is very similar to that of \FD@printable@vi.

149 \@namedef{FD@printable\string\PrintChar}#1{%
150 \if \ifnum #1<\@xxxii 1\else \ifnum #1>126 1\else 0\fi\fi 1%
151  \toks@=\expandafter{\the\expandafter\toks@
152  \expandafter\PrintChar \expandafter{\number#1}%

153 }%

154 \else
155  \toks@=\expandafter{\the\expandafter\expandafter\expandafter\toks@
156  \csname FD@printable@\number#1\endcsname}%
157 \fi
158 \FD@printable@

159 }

\ExpandAndMakePrintable The \ExpandAndMakePrintable command is an abbreviation for a common use

of \MakePrintable, namely to first feed the string through a \protected@edef to get rid of all the simple macros.

160 \newcommand*\ExpandAndMakePrintable[3]{%
161 \protected@edef\@tempa{{#2}{#3}}%
162 \expandafter\MakePrintable \expandafter#1\@tempa

163 } 164 ⟨/doc⟩

9.1.3 Evaluating string expressions

In string expressions, the only available operation is juxtaposition (fancy name for putting things next to each other) and thus the syntax for a string expression is

⟨string expression⟩ ⟶ ∅ | ⟨string atom⟩⟨string expression⟩

where ∅ denotes the empty string. A ⟨string atom⟩ is one of

⟨character token⟩

\str{⟨string expression⟩} \strint{⟨string expression⟩}

The meaning of a ⟨character token⟩ is explained in [6]. The \str and \strint forms of {⟨string atom⟩} refer to the respective values of the string and integer variables (see Subsection 9.3) whose names are given in the argument of \str or \strint respectively. Since the names of variables are themselves string expressions, \str and \strint may themselves be used in names of variables.

It should be noted that most of fontinst’s string expressions sooner or later end up between a \csname and the corresponding \endcsname. This places significant restrictions on what may occur in string expressions.

\str \strint In fontinst the only macros needed for dealing with string expressions are \str

and \strint.

165 ⟨∗pkg⟩

166 \def\str#1{\csname~s-#1\endcsname}
167 \def\strint#1{\expandafter\identity_one\expandafter{\number\int{#1}}}

168 ⟨/pkg⟩

fontdoc mainly uses TEX’s text mode for typesetting string expressions because not all characters are available in math mode; it’s easier to switch to text mode than to augment the math setup. One kind of material is however typeset in math mode, namely “string-valued functions”: the name and functional parenthesis of such material is typeset in math mode to get a mathematical look.

\FD@string@func The \FD@string@func macro has the syntax

     \FD@string@func{⟨name⟩}{⟨argument⟩}

It is used for typesetting the ⟨name⟩(⟨argument⟩) of a string-valued function (e.g. the value-of-string-variable function s). It should only be used in horizontal mode.

\FD@string@func includes a bit of extra spacing around the typeset text, but not at the beginning or end of a string and neither between two string-valued functions. As a flag for this is used that the value of \spacefactor is 1; when it is one should proceed as if this extra spacing is already present.

169 ⟨∗doc⟩

170 \def\FD@string@func#1#2{%
171 \relax
172 \ifnum \spacefactor=\@ne $\mkern1mu\else$\fi
173 \mathrm{#1}($%
174 #2%
175 \ifnum \spacefactor=\@ne $\mkern-1mu\else $\fi)\mkern1mu$%
176 \spacefactor=\@ne

177 }

\TypesetStringExpression \FD@typeset@string \ifFD@swa In fontdoc the string expressions must be typeset, and that is not trivial due to that (i) not all character tokens have catcode 11 or 12 and (ii) not all characters are available in all fonts. Furthermore the non-character string atoms should be given special treatment in character strings!

Because of this, string expressions that are to be typeset are handed to a special command \TypesetStringExpression, which takes the string to typeset as its only argument. This string may contain user-defined macros.

178 \newcommand\TypesetStringExpression[1]{%
179 \protected@edef\@tempa{%
180  \noexpand\MakePrintable \noexpand\@tempa {FD@swa}{#1}%

181 }%

182 \@tempa
183 \FD@typeset@string{\@tempa}%

184 }

Actually typesetting the string is handled in \FD@typeset@string, but strings handed to this macro must be preprocessed by a full protected expansion and a

\MakeHarmless.
185 \def\FD@typeset@string#1{%
186 \mbox{%
187  \normalfont\ttfamily
188  \spacefactor=\@ne
189  #1%
190  \ifnum \spacefactor=\@ne $\mkern-1mu\m@th$\fi

191 }% 192 }

The \ifFD@swa control sequence is often \let to \iftrue or \iffalse by \Make-

Printable, and then it is used as a conditional. Since that assignment sometimes takes place in conditional text however, one must make sure that \ifFD@swa always is some conditional.

193 \let\ifFD@swa\iffalse

\str \FD@printable\str The processing of the \str macro in fontdoc is far from straightforward. \str has to be robust, but apart from that its defintion has no effect on how its argument is processed. That is instead controlled by \FD@printable\str, which happens to use \str as an auxiliary formatting macro.

Most of the complexity below is however due to the processing needed to determine whether the string variable accessed has been assigned a value. See \SetStringVariable for more information.

194 \DeclareRobustCommand\str[1]{\FD@string@func{s}{#1}}
195 \@namedef{FD@printable\string\str}#1{%
196 \MakePrintable\@tempa{FD@swa}{#1}%
197 \begingroup
198  \let\PrintChar=\FD@quoted@PrintChar
199 \if \ifFD@swa \@ifundefined{FD@s-\@tempa}{0}{1}\else 0\fi 1%
200  \expandafter
201 \endgroup
202  \csname FD@s-\@tempa\endcsname
203 \else
204 \endgroup
205  \toks@=\expandafter{\the\expandafter\toks@
206  \expandafter\str \expandafter{\@tempa}}%
207  \@tempswatrue
208 \fi
209 \FD@printable@

210 }

\strint \FD@printable\strint  \strint is handled similarly to \str.
211 \DeclareRobustCommand\strint[1]{\FD@string@func{int}{#1}}
212 \@namedef{FD@printable\string\strint}#1{%
213 \MakePrintable\@tempa{FD@swa}{#1}%
214 \protected@edef\@tempa{%
215  \ifFD@swa \protect\FD@simple@int \else \strint \fi{\@tempa}%

216 }

217 \toks@=\expandafter{\the\expandafter\toks@ \@tempa}%
218 \@tempswatrue
219 \FD@printable@

220 }

\macroparameter \FD@printable\macroparameter The \macroparameter command can be used in string and integer expressions

as a sort of “macro parameter placeholder”. It is not defined in fontinst, but in fontdoc one occationally writes comments which say things like “XXX is short for ASDFSKADN”, and in those cases one can use \macroparameter as a placeholder for an argument. The syntax is

      \macroparameter{⟨digit⟩}

where ⟨digit⟩ should be a decimal digit between 1 and 9 inclusive.

The definition in \macroparameter handles uses of the command in integer expressions, whereas \FD@printable\macroparameter takes care of uses in string expressions.

221 \DeclareRobustCommand\macroparameter[1]{%
222 \gdef\FD@expression{\text{\normalfont\itshape\##1}}%
223 \global\chardef\FD@priority=5%
224 \global\FD@bracket@level=\z@
225 \FD@evaluate@false

226 }

227 \@namedef{FD@printable\string\macroparameter}#1{%
228 \toks@=\expandafter{\the\toks@\textrm{\emph{\##1}}}%
229 \@tempswatrue
230 \FD@printable@

231 } 232 ⟨/doc⟩

9.2 Integer expressions

An ⟨integer expression⟩ is one of the following:

⟨number⟩ \int{⟨string expression⟩} \neg{⟨integer expression⟩} \add{⟨integer expression⟩}{⟨integer expression⟩} \sub{⟨integer expression⟩}{⟨integer expression⟩} \max{⟨integer expression⟩}{⟨integer expression⟩} \min{⟨integer expression⟩}{⟨integer expression⟩} \mul{⟨integer expression⟩}{⟨integer expression⟩} \div{⟨integer expression⟩}{⟨integer expression⟩} \half{⟨integer expression⟩} \otherhalf{⟨integer expression⟩} \scale{⟨integer expression⟩}{⟨integer expression⟩} \width{⟨string expression⟩} \height{⟨string expression⟩} \depth{⟨string expression⟩} \italic{⟨string expression⟩} \kerning{⟨string expression⟩}{⟨string expression⟩}

⟨number⟩ is any TEX number, as defined in [6]. The ⟨string expression⟩ in the argument of \int must be the name of an integer variable which is currently set, i.e., the condition

\ifisint{⟨string expression⟩}\then

must evaluate to true. Likewise the ⟨string expression⟩ in the argument of \width, \height, \depth, and \italic must be the name of a glyph which is currently set, i.e., the condition

\ifisglyph{⟨string expression⟩}\then

must evaluate to true.

\eval_expr \eval_expr_to \g_eval_expr_to \result The only thing fontinst does with integer expressions is evaluating them. The macro

\eval_expr{⟨integer expression⟩}

globally assigns \result to the value of ⟨integer expression⟩, and changes the value of no other counters.

The macro

\eval_expr_to{⟨TEX integer variable⟩}{⟨integer expression⟩} locally assigns the value of ⟨integer expression⟩ to ⟨TEX integer variable⟩ (which is an integer variable as defined in [6]). \g_eval_expr_to does the same globally.

233 ⟨∗pkg⟩

234 \newcount\result
235 \def\eval_expr#1{\global\result=#1\x_relax}
236 \def\eval_expr_to#1#2{\eval_expr{#2}#1=\result}
237 \def\g_eval_expr_to#1#2{\eval_expr{#2}\global#1=\result}

238 ⟨/pkg⟩

\TypesetIntegerExpression In fontdoc the main task is instead to typeset the expression as a mathematical formula, but in some cases one wants to know its value as well (if possible). Therefore things get a bit more complex in that context. The top-level command there is

     \TypesetIntegerExpression{⟨integer expression⟩}

which typesets the ⟨integer expression⟩ by first forming (in the \FD@expression macro) code for typesetting the integer expression. \TypesetIntegerExpression should be only be used in math mode.

Most of the work in \TypesetIntegerExpression is carried out by the

\FD@eval@expr macro and hence \TypesetIntegerExpression sets a couple of

other variables as explained below. Apart from the fact that \FD@eval@expr doesn’t actually typeset anything, the main difference between it and \Typeset-IntegerExpression is that the latter also accepts code that after expansion will become integer expressions, whereas the former requires that all such macros have first been expanded.

239 ⟨∗doc⟩

240 \newcommand\TypesetIntegerExpression[1]{%
241 \protected@edef\@tempa{#1}%
242 \expandafter\FD@eval@expr \expandafter{\@tempa}%
243 \FD@expression

244 }

\FD@expression \FD@result \FD@priority \FD@bracket@level FD@evaluate@ switch The \FD@expression macro, \FD@result and \FD@bracket@level count regis-

ters, the \FD@priority chardef token, and the FD@evaluate@ switch are used by fontdoc when formatting and evaluating an integer expression. They are all assigned globally.

The \FD@expression macro contains code for typesetting an expression. \FD@priority is a chardef token whose numerical value specifies the priority of the outermost operation in \FD@expression according to the following table:

0 Outermost operation is + or −.

1 Outermost operation is explicit multiplication (·) or division /. If it is one of the factors in a product then that multiplication must be explicit.

2 Outermost operation is explicit multiplication. If it is to be the right factor in a product, then the multiplication must be made explicit too.

3 Outermost operation is explicit multiplication. It does not need to be explicitly multiplied.

4 Outermost operation is implicit multiplication (juxtaposition), unary prefix (unary −) or something which is bracketed anyway. If it is to be the right factor in a product, then that multiplication should be made explicit too. A typical example of this kind of thing is an explicit negative number.

5 Outermost operation is implicit multiplication (juxtaposition) or something which is bracketed anyway. It does not need to be explicitly multiplied.

6 The expression is an explicit non-negative number. If it is to be the right factor in a product, then the multiplication should be made explicit.

\FD@bracket@level keeps track of what parenthesis size one must use to cover the expression in \FD@expression: 0 is the normal size, 1 is \big size, 2 is \Big size, etc. The FD@evaluate@ switch specifies whether \FD@eval@expr should try to (upon entry) or managed to (after it is completed) evaluate the integer expression (true is evaluate, false is don’t bother). When the value has been evaluated, it is returned in \FD@result.

245 \newcount\FD@result
246 \newcount\FD@bracket@level
247 \def\FD@evaluate@true{\global\let\ifFD@evaluate@\iftrue}
248 \def\FD@evaluate@false{\global\let\ifFD@evaluate@\iffalse}
249 \FD@evaluate@false
\FD@eval@expr The \FD@eval@expr macro has the syntax

\FD@eval@expr{⟨integer expression⟩}

It puts code for typesetting the ⟨integer expression⟩ in the \FD@expression macro, sets \FD@bracket@level to the corresponding value, and if FD@evaluate@ is true it also tries to evaluate the expression and put the result in \FD@result.

More precisely, \FD@eval@expr only handles the ⟨TEX number⟩ cases of integer expression. In the other cases the first token in the integer expression is a robust command which should take care of building the expression as needed.

250 \def\FD@eval@expr#1{%
251 \expandafter\expandafter \expandafter\ifx
252  \expandafter\@car#1\x@relax\@nil \protect
253  #1%
254 \else\ifcat \expandafter\noexpand \@car#1\x@relax\@nil 0%
255  \global\FD@result=#1\x@relax
256  \xdef\FD@expression{\the\FD@result}%
257  \global\chardef\FD@priority=\ifnum \FD@result<\z@ 4\else 6\fi
258  \global\FD@bracket@level=\z@
259 \else
260  \begingroup
261  \MakePrintable\@tempa{FD@swa}{#1}%
262  \global\FD@bracket@level=\ifFD@swa\z@\else\@ne\fi
263  \protected@xdef\FD@expression{\protect\mbox{\texttt{\@tempa}}}%
264  \endgroup
265  \global\chardef\FD@priority=5%
266  \FD@evaluate@false
267 \fi\fi

268 } 269 ⟨/doc⟩

Note: It is important that all groups that are started or ended during the evaluation of an integer expression are of \begingroup type, since \bgroup groups affect spacing in math mode.

\add The \add command has the syntax

\add{⟨integer expression⟩}{⟨integer expression⟩}

It represents the sum of the two ⟨integer expression⟩s.

270 ⟨∗pkg⟩

271 \def\add#1#2{

272 #1

273 \bgroup
274  \a_count=\result
275  \eval_expr{#2}
276  \global\advance \result \a_count
277 \egroup

278 } 279 ⟨/pkg⟩ 280 ⟨∗doc⟩

281 \DeclareRobustCommand\add[2]{%
282 \begingroup
283 \FD@eval@expr{#1}%
284 \let\@tempa=\FD@expression
285 \ifFD@evaluate@ \a@count=\FD@result \fi
286 \b@count=\FD@bracket@level
287 \FD@eval@expr{#2}%
288 \protected@xdef\FD@expression{\@tempa+\FD@expression}%
289 \ifFD@evaluate@ \global\advance \FD@result \a@count \fi
290 \ifnum \FD@bracket@level<\b@count
291  \global\FD@bracket@level=\b@count
292 \fi
293 \global\chardef\FD@priority=\z@
294 \endgroup

295 } 296 ⟨/doc⟩

\sub The \sub command has the syntax

\sub{⟨integer expression⟩}{⟨integer expression⟩}

It represents the difference between the two ⟨integer expression⟩s.

297 ⟨∗pkg⟩

298 \def\sub#1#2{

299 #1

300 \bgroup
301  \a_count=\result
302  \eval_expr{#2}
303  \advance \a_count -\result
304  \global\result=\a_count
305 \egroup

306 } 307 ⟨/pkg⟩ 308 ⟨∗doc⟩

309 \DeclareRobustCommand\sub[2]{%

310 \begingroup
311 \FD@eval@expr{#1}%
312 \let\@tempa=\FD@expression
313 \ifFD@evaluate@ \a@count=\FD@result \fi
314 \b@count=\FD@bracket@level
315 \FD@eval@expr{#2}%
316 \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
317 \protected@xdef\FD@expression{\@tempa-\FD@expression}%
318 \ifFD@evaluate@
319  \advance \a@count -\FD@result
320  \global\FD@result=\a@count
321 \fi
322 \ifnum \FD@bracket@level<\b@count
323  \global\FD@bracket@level=\b@count
324 \fi
325 \global\chardef\FD@priority=\z@
326 \endgroup

327 }

\FD@subexpression \FD@commapenalty The \FD@subexpression macro has the syntax
      \FD@subexpression{⟨math mode material⟩}

It should only be used in math mode and produces results very similar to ⟨math mode material⟩, but it locally increases all the math-related penalties by \FD@commapenalty for when the math mode material is converted to a horizontal list. This allows linebreaking to take notice of logical nesting in expressions.

    \FD@commapenalty is used as a companion of \relpenalty and \binoppenalty,

but which is used after commas (where TEX doesn’t insert penalties automatically).

328 \def\FD@subexpression#1{${%
329 \advance \binoppenalty \FD@commapenalty
330 \advance \relpenalty \FD@commapenalty
331 \advance \FD@commapenalty \FD@commapenalty
332 $#1$}$%

333 }

334 \newcount\FD@commapenalty
335 \FD@commapenalty=\binoppenalty
336 \advance \FD@commapenalty \relpenalty
\FD@bracket@expression The \FD@bracket@expression brackets the expression currently in \FD@expression

by the suitable size of parentheses and updates \FD@bracket@level and \FD@priority accordingly.

337 \def\FD@bracket@expression{%
338 \protected@xdef\FD@expression{%
339  \ifcase\FD@bracket@level \or \protect\bigl \or \protect\Bigl \or
340  \protect\biggl \else \protect\Biggl \fi (%
341  \protect\FD@subexpression{\FD@expression}%
342  \ifcase\FD@bracket@level \or \protect\bigr \or \protect\Bigr \or
343  \protect\biggr \else \protect\Biggr \fi )%

344 }%

345 \global\chardef\FD@priority=5%
346 \global\advance \FD@bracket@level \@ne

347 }

348 ⟨/doc⟩

\int \FD@simple@int The \int command has the syntax

\int{⟨string expression⟩}

It is used to represent the value of the fontinst integer whose name is the value of the ⟨string expression⟩ in integer expressions.

The \FD@simple@int macro take the printable string form of the name of an integer variable as its argument and typesets the printed representation of this integer, but it should only be used when the argument is a simple string expression. When the argument is not a simple string expression, \FD@integer@func should be used instead. \FD@simple@int should only be called in horizontal mode.

349 ⟨pkg⟩\def\int#1{\csname i-#1 \endcsname}

350 ⟨∗doc⟩

351 \DeclareRobustCommand\int[1]{%
352 \begingroup
353 \MakePrintable\@tempa{FD@swa}{#1}%
354 \protected@xdef\FD@expression{%
355  \ifFD@swa
356  \text{\protect\FD@simple@int{\@tempa}}%
357  \else
358  \protect\FD@integer@func{int}{\@tempa}%
359  \fi

360 }%

361 \global\chardef\FD@priority=5%
362 \global\FD@bracket@level=\ifFD@swa\z@\else\@ne\fi
363 \FD@evaluate@false
364 \endgroup

365 }

366 \def\FD@simple@int#1{{\normalfont\itshape #1\/}}
\FD@integer@func The \FD@integer@func macro has the syntax
     \FD@integer@func{⟨name⟩}{⟨argument⟩}

It is used for typesetting the ⟨name⟩(⟨argument⟩) of an integer-valued function which takes a string expression as argument (e.g. the width-of-glyph function w). It should only be used in math mode.

The empty group in the argument of \mathop is there to ensure that the nucleus of the mathop atom isn’t simply a symbol, since TEX in that case centers it vertically.

367 \def\FD@integer@func#1#2{%
368 \mathop{\mathrm{#1}{}}(\text{\FD@typeset@string{#2}})%

369 } 370 ⟨/doc⟩

\neg The \neg command has the syntax

\neg{⟨integer expression⟩}

It represents the negative of the ⟨integer expression⟩.

371 ⟨pkg⟩\def\neg#1{#1 \global\result=-\result}

372 ⟨∗doc⟩

373 \DeclareRobustCommand\neg[1]{%
374 \FD@eval@expr{#1}%
375 \ifnum 5>\FD@priority \FD@bracket@expression \fi
376 \protected@xdef\FD@expression{-\FD@expression}%
377 \global\chardef\FD@priority=4%
378 \ifFD@evaluate@ \global\FD@result=-\FD@result \fi

379 } 380 ⟨/doc⟩

\mul The \mul command has the syntax

\mul{⟨integer expression⟩}{⟨integer expression⟩}

It represents the product of the two ⟨integer expression⟩s.

381 ⟨∗pkg⟩

382 \def\mul#1#2{

383 #1

384 \bgroup
385  \a_count=\result
386  \eval_expr{#2}
387  \global\multiply \result \a_count
388 \egroup

389 } 390 ⟨/pkg⟩

The main problem in the fontdoc definition of \mul is to determine whether the multiplication should be made explicit or not, and what priority code the resulting expression should be given. It turns out that if the right factor has priority 1 (it is a quotient or a product that ends with a quotient) then the combined expression will be too, whereas if it isn’t but the left factor has priority 1 then the combined expression will get priority 2. The remaining cases will be explicit or implicit depending on the parity of the priority of the right expression, and priority will be odd or even depending on the parity of the priority of the left expression.

391 ⟨∗doc⟩

392 \DeclareRobustCommand\mul[2]{%
393 \begingroup
394 \FD@eval@expr{#1}%
395 \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
396 \let\@tempa=\FD@expression
397 \ifFD@evaluate@ \a@count=\FD@result \fi
398 \b@count=\FD@bracket@level
399 \let\FD@left@priority=\FD@priority
400 \FD@eval@expr{#2}%
401 \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
402 \protected@xdef\FD@expression{%
403  \@tempa
404  \if \ifnum \FD@left@priority=\@ne e%
405  \else\ifnum \FD@priority<\thr@@ e%
406  \else\ifodd \FD@priority i\else e\fi\fi\fi e%
407  \cdot
408  \fi
409  \FD@expression

410 }%

411 \ifFD@evaluate@ \global\multiply \FD@result \a@count \fi

412 \ifnum \FD@bracket@level<\b@count
413  \global\FD@bracket@level=\b@count
414 \fi
415 \a@count=%
416  \ifnum \FD@priority=\@ne 1%
417  \else\ifnum \FD@left@priority=\@ne 2%
418  \else\ifodd\FD@left@priority
419  \ifodd\FD@priority 5\else 3\fi
420  \else
421  \ifodd\FD@priority 4\else 2\fi
422  \fi\fi\fi
423 \global\chardef\FD@priority=\a@count
424 \endgroup

425 } 426 ⟨/doc⟩

\div The \div command has the syntax

\div{⟨integer expression⟩}{⟨integer expression⟩}

It represents the quotient of the two ⟨integer expression⟩s, as computed by TEX’s \divide command: non-integer quotients are rounded towards zero.

427 ⟨∗pkg⟩

428 \def\div#1#2{

429 #1

430 \bgroup
431  \a_count=\result
432  \eval_expr{#2}
433  \divide \a_count \result
434  \global\result=\a_count
435 \egroup

436 } 437 ⟨/pkg⟩ 438 ⟨∗doc⟩

439 \DeclareRobustCommand\div[2]{%
440 \begingroup
441 \FD@eval@expr{#1}%
442 \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
443 \let\@tempa=\FD@expression
444 \ifFD@evaluate@ \a@count=\FD@result \fi
445 \b@count=\FD@bracket@level
446 \FD@eval@expr{#2}%
447 \ifnum 4>\FD@priority \FD@bracket@expression \fi
448 \ifnum \FD@bracket@level<\b@count
449  \global\FD@bracket@level=\b@count
450 \fi
451 \protected@xdef\FD@expression{%
452  \@tempa
453  \ifcase\FD@bracket@level \or \protect\big \or \protect\Big \or
454  \protect\bigg \else \protect\Bigg \fi /%
455  \FD@expression

456 }%

457 \ifFD@evaluate@
458  \divide \a@count \FD@result
459  \global\FD@result=\a@count

460 \fi
461 \global\chardef\FD@priority=\@ne
462 \endgroup

463 }

\FD@eval@spec@expr The \FD@eval@spec@expr macro has the syntax

\FD@eval@spec@expr{⟨integer expression⟩}{⟨spec-command⟩} {⟨rep-command⟩}

It does pretty much the same thing as \FD@eval@expr, but if the first token in the ⟨integer expression⟩ is the ⟨spec-command⟩ then it will do

⟨rep-command⟩⟨integer expression⟩

instead of the normal activities. This is useful for operations that are normally denoted as n-ary operations rather that binary ones, i.e., for \max and \min.

464 \def\FD@eval@spec@expr#1#2#3{%
465 \expandafter\ifx \@car#1\x@relax\@nil #2%
466  #3#1%
467 \else
468  \FD@eval@expr{#1}%
469 \fi

470 } 471 ⟨/doc⟩

\max The \max command has the syntax

\max{⟨integer expression⟩}{⟨integer expression⟩}

It represents the maximum of the two ⟨integer expression⟩s.

472 ⟨∗pkg⟩

473 \def\max#1#2{

474 #1

475 \bgroup
476  \a_count=\result
477  \eval_expr{#2}
478  \ifnum \a_count>\result \global\result=\a_count \fi
479 \egroup

480 } 481 ⟨/pkg⟩ 482 ⟨∗doc⟩

483 \DeclareRobustCommand\max[2]{%
484 \begingroup
485 \toks@={}%
486 \a@count=-\maxdimen
487 \b@count=\z@
488 \FD@eval@spec@expr{\max{#1}{#2}}{\max}{\FD@maxmin@comma}%
489 \ifnum \a@count>\FD@bracket@level
490  \global\FD@bracket@level=\a@count
491 \fi
492 \protected@xdef\FD@expression{%
493  \protect\plainmax
494  \ifcase\FD@bracket@level \protect\@firstofone \or \protect\bigl
495  \or \protect\Bigl \or \protect\biggl \else \protect\Biggl

496  \fi{\{}%
497  \the\toks@
498  \protect\FD@subexpression{\FD@expression}%
499  \ifcase\FD@bracket@level \protect\@firstofone \or \protect\bigl
500  \or \protect\Bigl \or \protect\biggl \else \protect\Biggl
501  \fi{\}}%

502 }%

503 \ifFD@evaluate@
504  \ifnum \a@count>\FD@result \global\FD@result=\a@count \fi
505 \fi
506 \global\chardef\FD@priority=5%
507 \global\advance \FD@bracket@level \@ne
508 \endgroup

509 } 510 ⟨/doc⟩

\min The \min command has the syntax

\min{⟨integer expression⟩}{⟨integer expression⟩}

It represents the minimum of the two ⟨integer expression⟩s.

511 ⟨∗pkg⟩

512 \def\min#1#2{

513 #1

514 \bgroup
515  \a_count=\result
516  \eval_expr{#2}
517  \ifnum \a_count<\result \global\result=\a_count \fi
518 \egroup

519 } 520 ⟨/pkg⟩ 521 ⟨∗doc⟩

522 \DeclareRobustCommand\min[2]{%
523 \begingroup
524 \toks@={}%
525 \a@count=\maxdimen
526 \b@count=\z@
527 \FD@eval@spec@expr{\min{#1}{#2}}{\min}{\FD@maxmin@comma}%
528 \ifnum \a@count>\FD@bracket@level
529  \global\FD@bracket@level=\a@count
530 \fi
531 \protected@xdef\FD@expression{%
532  \protect\plainmin
533  \ifcase\FD@bracket@level \protect\@firstofone \or \protect\bigl
534  \or \protect\Bigl \or \protect\biggl \else \protect\Biggl
535  \fi{\{}%
536  \the\toks@
537  \protect\FD@subexpression{\FD@expression}%
538  \ifcase\FD@bracket@level \protect\@firstofone \or \protect\bigl
539  \or \protect\Bigl \or \protect\biggl \else \protect\Biggl
540  \fi{\}}%

541 }%

542 \ifFD@evaluate@
543  \ifnum \a@count<\FD@result \global\FD@result=\a@count \fi
544 \fi

545 \global\chardef\FD@priority=5%
546 \global\advance \FD@bracket@level \@ne
547 \endgroup

548 }

\FD@maxmin@comma The \FD@maxmin@comma macro does most of the work for \max and \min in fontdoc. In some sense it inserts the commas between the operands, but it also takes care of evaluating the maximum/minimum and determining the proper bracketing level.

The sequence of arguments (separated by commas) is compiled in \toks@. The greatest/least value of an argument found so far is kept in \a@count, and the greatest bracketing level found is kept in \b@count.

549 \def\FD@maxmin@comma#1#2#3{%
550 \FD@eval@spec@expr{#2}{#1}{\FD@maxmin@comma}%
551 \toks@=\expandafter{\the\expandafter\toks@
552  \expandafter\protect \expandafter\FD@subexpression
553  \expandafter{\FD@expression}%
554  ,\penalty\FD@commapenalty\,%

555 }

556 \ifFD@evaluate@
557  \ifnum \a@count \ifx\max#1<\else>\fi \FD@result
558  \a@count=\FD@result
559  \fi
560 \fi
561 \ifnum \b@count<\FD@bracket@level \b@count=\FD@bracket@level \fi
562 \FD@eval@spec@expr{#3}{#1}{\FD@maxmin@comma}%

563 } 564 ⟨/doc⟩

\half \otherhalf The \half and \otherhalf macros have the syntaxes

\half{⟨integer expression⟩}

\otherhalf{⟨integer expression⟩}

They both represent one half of the ⟨integer expression⟩, but they don’t round it the same way. \half does rounding as specified in [5, p. 237] (towards even integers) whereas \otherhalf does it the other way (towards odd integers). This means that

     \add{\half{⟨IE⟩}}{\otherhalf{⟨IE⟩}}

will always sum up to precisely the same as the ⟨IE⟩ integer expression.

565 ⟨∗pkg⟩

566 \def\half#1{
567 #1\x_relax
568 \ifodd\result
569  \global\advance \result \@ne
570  \global\divide \result \tw@
571  \ifodd\result \global\advance \result \m@ne \fi
572 \else
573  \global\divide \result \tw@
574 \fi

575 }

576 \def\otherhalf#1{
577 #1\x_relax

578 \ifodd\result
579  \global\advance \result \@ne
580  \global\divide \result \tw@
581  \ifodd\result \else \global\advance \result \m@ne \fi
582 \else
583  \global\divide \result \tw@
584 \fi

585 } 586 ⟨/pkg⟩ 587 ⟨∗doc⟩

588 \DeclareRobustCommand\half[1]{%
589 \begingroup
590 \FD@eval@expr{#1}%
591 \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
592 \a@count=%
593  \ifnum \FD@priority=\@ne 1%
594  \else\ifodd\FD@priority 5%
595  \else 3\fi\fi
596 \global\chardef\FD@priority=\a@count
597 \protected@xdef\FD@expression{%
598  \protect\frac{1}{2}%
599  \ifnum \FD@priority>\thr@@ \else \cdot \fi
600  \FD@expression

601 }%

602 \ifFD@evaluate@
603  \ifodd \FD@result
604  \global\advance \FD@result \@ne
605  \global\divide \FD@result \tw@
606  \ifodd\FD@result \global\advance \FD@result \m@ne \fi
607  \else
608  \global\divide \FD@result \tw@
609  \fi
610 \fi
611 \endgroup

612 }

613 \DeclareRobustCommand\otherhalf[1]{%
614 \begingroup
615 \FD@eval@expr{#1}%
616 \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
617 \a@count=%
618  \ifnum \FD@priority=\@ne 1%
619  \else\ifodd\FD@priority 5%
620  \else 3\fi\fi
621 \global\chardef\FD@priority=\a@count
622 \protected@xdef\FD@expression{%
623  \protect\frac{1}{2}%
624  \ifnum \FD@priority>\thr@@ \else \cdot \fi
625  \FD@expression

626 }%

627 \ifFD@evaluate@
628  \ifodd \FD@result
629  \global\advance \FD@result \@ne
630  \global\divide \FD@result \tw@
631  \ifodd\FD@result\else \global\advance \FD@result \m@ne \fi

632  \else
633  \global\divide \FD@result \tw@
634  \fi
635 \fi
636 \endgroup

637 } 638 ⟨/doc⟩

\scale The \scale command has the syntax

\scale{⟨integer expression⟩}{⟨integer expression⟩}

It represents the result of multiplying the first ⟨integer expression⟩ by as many thousands as is specified by the second ⟨integer expression⟩. In practice, \scale{⟨ie1 ⟩}{⟨ie2 ⟩} is very similar to

      \div{\mul{⟨ie1 ⟩}{⟨ie2 ⟩}}{1000}

but \scale also tries to do proper rounding (note however that \scaleing by 500 is not rounded properly; use \half instead).

639 ⟨∗pkg⟩

640 \def\scale#1#2{

641 #1

642 \bgroup
643  \a_count=\result
644  \eval_expr{#2}
645  \global\multiply \result \a_count
646  \rounded_thousandths
647 \egroup

648 } 649 ⟨/pkg⟩

The second (scaling factor) argument of \scale is usually very simple, and in that case the \scale will be formatted as a fraction (containing the second argument) multiplied by the first argument.

650 ⟨∗doc⟩

651 \DeclareRobustCommand\scale[2]{%
652 \begingroup
653 \FD@eval@expr{#1}%
654 \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
655 \let\@tempa=\FD@expression
656 \ifFD@evaluate@ \a@count=\FD@result \fi
657 \b@count=\FD@bracket@level
658 \let\FD@left@priority=\FD@priority
659 \FD@eval@expr{#2}%
660 \if \ifnum \FD@bracket@level<\@ne \ifnum \FD@priority>\thr@@
661  1\else 0\fi\else 0\fi 1%
662  \protected@xdef\FD@expression{%
663  \protect\frac{\FD@expression}{1000}%
664  \if \ifnum \FD@left@priority<\thr@@ e\else
665  \ifodd \FD@left@priority i\else e\fi\fi e%
666  \cdot
667  \fi
668  \@tempa

669 }

670  \global\chardef\FD@priority=%
671  \ifnum \FD@left@priority=\@ne 1\else
672  \ifodd\FD@left@priority 5\else 3\fi\fi
673  \global\FD@bracket@level=\b@count
674 \else
675  \ifnum \FD@priority<\@ne \FD@bracket@expression \fi
676  \protected@xdef\FD@expression{%
677  \@tempa
678  \if \ifnum \FD@left@priority=\@ne e%
679  \else\ifnum \FD@priority<\thr@@ e%
680  \else\ifodd \FD@priority i\else e\fi\fi\fi e%
681  \cdot
682  \fi
683  \FD@expression
684  \ifcase\FD@bracket@level \or \protect\big \or \protect\Big
685  \or \protect\bigg \else \protect\Bigg \fi /1000%

686 }%

687  \ifnum \FD@bracket@level<\b@count
688  \global\FD@bracket@level=\b@count
689  \fi
690  \global\chardef\FD@priority=\@ne
691 \fi
692 \ifFD@evaluate@
693  \global\multiply \FD@result \a@count
694  \global\divide \FD@result 500
695  \ifodd \FD@result
696  \global\advance \FD@result \ifnum 0>\FD@result - \fi \@ne
697  \fi
698  \global\divide \FD@result \tw@
699 \fi
700 \endgroup

701 } 702 ⟨/doc⟩

\rounded_thousandths \l_rounded_thousandths The \rounded_thousandths macro divides \result by 1000 and rounds the result

to the nearest integer. This is different from

      \global\divide \result \one_thousand

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.

703 ⟨∗pkg⟩

704 \def\rounded_thousandths{
705 \global\divide \result \five_hundred
706 \ifodd \result
707  \global\advance \result by \ifnum 0>\result - \fi 1
708 \fi
709 \global\divide \result \tw@

710 }

711 \def\l_rounded_thousandths#1{
712 \divide #1 \five_hundred
713 \ifodd #1

714  \advance #1 by \ifnum 0>#1 - \fi\@ne
715 \fi
716 \divide #1 \tw@

717 }

\l_inv_scale 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

[\frac{1000n}{m}],

where the brackets denote rounding to the nearest integer, and assigns this number to #1 locally.

718 \def\l_inv_scale#1#2{
719 \multiply #1 \two_thousand
720 \divide #1 #2\x_relax
721 \ifodd#1 \advance #1 \ifnum 0>#1 - \fi\@ne \fi
722 \divide #1 \tw@

723 }

\ifnumber The call

\ifnumber{⟨integer expression⟩}⟨rel⟩{⟨integer expression⟩}\then

can be used to compare the two integer expressions. ⟨rel⟩ may be <, =, or >.

724 \def\ifnumber#1#2#3\then{
725 \eval_expr_to\a_count{#1}
726 \eval_expr{#3}
727 \ifnum \a_count#2\result
728  \expandafter\if_true
729 \else
730  \expandafter\if_false
731 \fi

732 } 733 ⟨/pkg⟩

Like the other conditionals, \ifnumber is treated as being true by fontdoc.

734 ⟨∗doc⟩

735 \def\ifnumber#1#2#3\then{%
736 \FD@evaluate@false
737 \generic@if{%
738  $\TypesetIntegerExpression{#1}#2\TypesetIntegerExpression{#3}$%

739 }% 740 } 741 ⟨/doc⟩

9.3 Setting variables

⟨int⟩, ⟨str⟩, and ⟨dim⟩ below are string expressions. ⟨command⟩ can be any control sequence.

\setint The macros:

\setstr
\setdim
\setcommand
File: ficommon.dtx  89

\setint{⟨int⟩}{⟨integer expression⟩} \setstr{⟨str⟩}{⟨string⟩} \setdim{⟨dim⟩}{⟨dimension⟩} \setcommand⟨command⟩⟨definition⟩

\i-⟨int⟩ define new macros \i-⟨int⟩, \s-⟨str⟩, \d-⟨dim⟩, or ⟨command⟩.

\s-⟨str⟩ \d-⟨dim⟩

The macros:

\resetint
\resetstr
\resetdim
\resetcommand

\resetint{⟨int⟩}{⟨integer expression⟩}

\resetstr{⟨str⟩}{⟨string⟩}

\resetdim{⟨dim⟩}{⟨dimension⟩} \resetcommand⟨command⟩⟨definition⟩

redefine the macros \i-⟨int⟩, \s-⟨str⟩, \d-⟨dim⟩ or ⟨command⟩. \int The macros:

\str
\dim

\int{⟨int⟩}
\str{⟨str⟩}
\dim{⟨dim⟩}

⟨command⟩

return the values of \i-⟨int⟩, \s-⟨str⟩, \d-⟨dim⟩, or ⟨command⟩.

\strint The macro

\strint{⟨int⟩}

returns the value of \i-⟨int⟩ as a string.

\ifisint The macros:

\ifisstr
\ifisdim
\ifiscommand

\ifisint{⟨int⟩}\then
\ifisstr{⟨str⟩}\then
\ifisdim{⟨dim⟩}\then
\ifiscommand⟨command⟩\then

return \if_true if \i-⟨int⟩, \s-⟨str⟩, \d-⟨dim⟩, or ⟨command⟩ respectively have been defined, and \if_false otherwise.

\unsetint The macros:

\unsetstr
\unsetdim
\unsetcommand

\unsetint{⟨int⟩}
\unsetstr{⟨str⟩}
\unsetdim{⟨dim⟩}
\unsetcommand⟨command⟩

undefine \i-⟨int⟩, \s-⟨str⟩, \d-⟨dim⟩, or ⟨command⟩.

\x_setint  The macros \x_setint, \x_resetint, and \x_setstr are “private” versions
\x_resetint
\x_setstr

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.

Integers are kept as \mathchardefs if possible; a comparision of doing this versus not doing this appears in Subsection E.1.

\setsomething_global The \setsomething_global control sequence should be either \relax or \global.

It appears before the central assignments in all the \set…, \reset…, and \unset… 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.

742 ⟨∗pkg⟩

743 \let\setsomething_global=\x_relax
\x_setint
\setint
\x_setstr
\setstr
\setdim
\setcommand

744 \def\x_setint#1#2{
745 \x_cs\ifx{i-#1}\x_relax
746  \x_resetint{#1}{#2}
747 \fi

748 }

749 \let\setint=\x_setint
750 \def\x_setstr#1#2{
751 \x_cs\ifx{s-#1}\x_relax
752  \setsomething_global\x_cs\edef{s-#1}{#2}
753 \fi

754 }

755 \let\setstr=\x_setstr
756 \def\setdim#1#2{
757 \x_cs\ifx{d-#1}\x_relax
758  \a_dimen=#2\x_relax
759  \setsomething_global\x_cs\edef{d-#1}{\the\a_dimen}
760 \fi

761 }

762 \def\setcommand#1{
763 \ifx#1\undefined_command
764  \setsomething_global \expandafter\def \expandafter#1
765 \else
766  \expandafter\def \expandafter\a_macro
767 \fi

768 } 769 ⟨/pkg⟩

In 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 fontinst; the assignment is global because of grouping not present in fontinst.

770 ⟨∗doc⟩

771 \newcommand\setint[2]{%
772 \Bheading{Default} \(\TypesetIntegerExpression{\int{#1}}\) =
773 \(\TypesetIntegerExpression{#2}\)%

774 }

775 \newcommand\setstr[2]{%
776 \Bheading{Default} \TypesetStringExpression{\str{#1}} =
777 \TypesetStringExpression{#2}%

778 }

779 \newcommand\setdim[2]{%
780 \a@dimen=#2\relax
781 \Bheading{Default} \TypesetStringExpression{#1} dimen = \the\a@dimen

783 \def\setcommand#1{\ifx#1\undefined@command
784 \expandafter\gdef\expandafter#1\else
785 \expandafter\gdef\expandafter\a@command\fi}

786 ⟨/doc⟩

\x_resetint
\resetint
\resetstr
\resetdim
\resetcommand

787 ⟨∗pkg⟩

788 \def\x_resetint#1#2{
789 \eval_expr{#2}
790 \setsomething_global
791 \ifnum\result<\max_mathchardef
792  \ifnum 0>\result
793  \x_cs\edef{i-#1}{\the\result}
794  \else
795  \x_cs\mathchardef{i-#1}=\result
796  \fi
797 \else
798  \x_cs\edef{i-#1}{\the\result}
799 \fi

800 }

801 \let\resetint=\x_resetint
802 \def\resetstr#1#2{\setsomething_global\x_cs\edef{s-#1}{#2}}
803 \def\resetdim#1#2{
804 \a_dimen=#2
805 \setsomething_global\x_cs\edef{d-#1}{\the\a_dimen}

806 }

807 \def\resetcommand#1{\setsomething_global\def#1}

808 ⟨/pkg⟩

In 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 fontinst.

809 ⟨∗doc⟩

810 \newcommand\resetint[2]{%
811 \Bheading{Value} \(\TypesetIntegerExpression{\int{#1}}\) =
812 \(\TypesetIntegerExpression{#2}\)%

813 }

814 \newcommand\resetstr[2]{%
815 \Bheading{Value} \TypesetStringExpression{\str{#1}} =
816 \TypesetStringExpression{#2}%

817 }

818 \newcommand\resetdim[2]{%
819 \a@dimen=#2\relax
820 \Bheading{Value} \TypesetStringExpression{#1} dimen = \the\a@dimen

821 }

822 \def\resetcommand#1{\gdef#1}

823 ⟨/doc⟩

\dim
824 ⟨pkg⟩\def\dim#1{\csname~d-#1\endcsname}
Not in doc: \dim

\ifisint
\ifisstr
\ifisdim
\ifiscommand

825 ⟨∗pkg⟩

826 \def\ifisint#1\then{\if_defined i-#1\then}
827 \def\ifisstr#1\then{\if_defined s-#1\then}
828 \def\ifisdim#1\then{\if_defined d-#1\then}
829 \def\ifiscommand#1\then{
830 \ifx#1\undefined_command
831  \expandafter\if_false
832 \else
833  \expandafter\if_true
834 \fi

835 } 836 ⟨/pkg⟩

In fontdoc, all conditionals are handled through \generic@if, which by default expands to \iftrue.

837 ⟨∗doc⟩

838 \def\ifisint#1\then{%
839 \generic@if{integer $\TypesetIntegerExpression{\int{#1}}$ set}%

840 }

841 \def\ifisstr#1\then{%
842 \generic@if{string \TypesetStringExpression{#1} set}%

843 }

844 \def\ifisdim#1\then{%
845 \generic@if{dimension \TypesetStringExpression{#1} set}%

846 }

847 \def\ifiscommand#1\then{%
848 \generic@if{command \normalfont{\ttfamily\string#1} set}%

849 } 850 ⟨/doc⟩

\unsetint
\unsetstr
\unsetdim
\unsetcommand

851 ⟨∗pkg⟩

852 \def\unsetint#1{\setsomething_global\x_cs\let{i-#1}\x_relax}
853 \def\unsetstr#1{\setsomething_global\x_cs\let{s-#1}\x_relax}
854 \def\unsetdim#1{\setsomething_global\x_cs\let{d-#1}\x_relax}
855 \def\unsetcommand#1{\setsomething_global\let#1=\undefined_command}

856 ⟨/pkg⟩

Not in doc: \unsetint
Not in doc: \unsetstr
Not in doc: \unsetdim
Not in doc: \unsetcommand

857 ⟨∗doc⟩ 858 ⟨/doc⟩

\offcommand \oncommand The calls
      \offcommand⟨command⟩
      \oncommand⟨command⟩

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 .mtx files that fontinst generates from .afm, .pl, or other .mtx files.

\saved-⟨\command⟩ The normal definition of a command that has been turned off is saved as the control sequence \saved-⟨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 ⟨command⟩ may be provided as the

\off-⟨\command⟩ control sequence \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.

859 ⟨∗pkg⟩

860 \def\offcommand#1{
861 \x_cs\ifx{saved-\string#1}\x_relax
862  \setsomething_global\x_cs\let{saved-\string#1}#1
863  \x_cs\ifx{off-\string#1}\x_relax
864  \generate_off_command{#1}
865  \else
866  \setsomething_global \expandafter\let \expandafter#1
867  \csname off-\string#1\endcsname
868  \fi
869 \fi

870 }

871 \def\oncommand#1{
872 \x_cs\ifx{saved-\string#1}\x_relax \else
873  \setsomething_global \expandafter\let \expandafter#1
874  \csname saved-\string#1\endcsname
875  \setsomething_global\x_cs\let{saved-\string#1}\x_relax
876 \fi

877 } 878 ⟨/pkg⟩

879 ⟨∗doc⟩

880 \def\offcommand#1{\Bheading{Turn off} \texttt{\string#1}}
881 \def\oncommand#1{\Bheading{Turn on} \texttt{\string#1}}

882 ⟨/doc⟩

\generate_off_command \count_hashes \gobble_to_xrelax  \generate_off_command⟨command⟩ converts ⟨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

      #1#2. . . #n

883 ⟨∗pkg⟩

884 \def\generate_off_command#1{
885 \a_count=0
886 \let\next=\count_hashes
887 \expandafter\next\meaning#1~->\x_relax
888 \b_count=0
889 \a_toks={}
890 \loop \ifnum \b_count<\a_count
891  \advance \b_count 1
892  \a_toks=\expandafter{\the\expandafter\a_toks \expandafter####
893  \the\b_count}
894 \repeat
895 \setsomething_global \expandafter\def \expandafter#1 \the\a_toks {}

896 }

897 \def\count_hashes#1#2{
898 \if \hash_char#1
899  \advance \a_count 1
900 \else
901  \if -#1
902  \if >#2
903  \let\next=\gobble_to_xrelax
904  \fi\fi
905 \fi
906 \next#2

907 }

908 \def\gobble_to_xrelax#1\x_relax{}

909 ⟨/pkg⟩

Control sequences of the form

\FD@s-⟨name⟩  \FD@s-⟨name⟩

are used by fontdoc to store the values of string variables which have been assigned values; ⟨name⟩ is the name of the string variable. Unlike the case in fontinst, the fontdoc \setstr command does not assign values to string variables, but

\SetStringVariable does.

The contents of the \FD@s-⟨name⟩ macros aren’t really the string values, but code that will append the printable form of the corresponding string expression to \toks@ and update other variables used by \MakePrintable accordingly. Typically it might look something like

     \toks@=\expandafter{\the\toks@ ab}

when the value of the string is ab.

\SetStringVariable The \SetStringVariable command has the syntax

\SetStringVariable{⟨variable name⟩}{⟨new value⟩}

where ⟨variable name⟩ and ⟨new value⟩ are both string expressions. The ⟨variable name⟩ must furthermore be a simple string expression. The command globally defines the corresponding \FD@s-⟨name⟩ control sequence to add the printable form of the {⟨new value⟩} string to the \toks@ token list register and, in case the ⟨new value⟩ string is non-simple, sets the @tempswa switch to true.

The control sequence \@tempa can be used as part of ⟨new value⟩, but not in the ⟨variable name⟩.

910 ⟨∗doc⟩

911 \newcommand\SetStringVariable[2]{%
912 \protected@edef\@tempa{\noexpand\MakePrintable \noexpand\@tempa
913  {FD@swa}{#2}}%
914 \@tempa
915 \protected@edef\@tempa{%
916  \toks@=\noexpand\expandafter{\noexpand\the \toks@ \@tempa}%
917  \ifFD@swa \noexpand\@tempswatrue \fi

918 }%

919 \protected@edef\@tempb{\noexpand\MakePrintable \noexpand\@tempb
920  {FD@swa}{#1}}%
921 \@tempb

922 \ifFD@swa
923  \begingroup
924  \let\PrintChar=\FD@quoted@PrintChar
925  \global\expandafter\let \csname FD@s-\@tempb\endcsname \@tempa
926  \endgroup
927 \else
928  \PackageError{fontdoc}{Names of string variables must be
929  simple\MessageBreak if they are to be assigned values}\@eha
930 \fi

931 } 932 ⟨/doc⟩

9.4 For loops

\for \endfor The command sequence

\for(⟨name⟩){⟨start⟩}{⟨stop⟩}{⟨step⟩}

⟨body code⟩

     \endfor(⟨name⟩)

will cause the ⟨body code⟩ to be repeated some number of times. How many depends on the values of ⟨start⟩, ⟨stop⟩, and ⟨step⟩, which are integer expressions.

As a precaution, the ⟨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.

⟨name⟩ is used as the name of an integer variable. This variable gets reset to the value of ⟨start⟩ before the first repetition of ⟨body code⟩. After each repetition but the last, it is incremented by ⟨step⟩. ⟨body code⟩ gets repeated if the value of ⟨name⟩ has not gotten past that of ⟨stop⟩. To get past means to be bigger if ⟨step⟩ is positive and to be smaller if ⟨step⟩ is negative. In the case that ⟨step⟩ is zero, the entire construction above will be equivalent to

     \resetint{⟨name⟩}{⟨start⟩}

⟨body code⟩

\for … \endfor constructions can be nested. ⟨name⟩ is used by \for to identify its matching \endfor, so they need to be identical in \for and \endfor.

933 ⟨∗pkg⟩

934 \def\for(#1)#2#3#4{
935 \eval_expr_to\a_count{#2}
936 \x_resetint{#1}{\a_count}
937 \eval_expr{#4}
938 \ifnum 0=\result \else
939  \c_count=\result
940  \eval_expr_to\b_count{#3}
941  \setsomething_global\x_cs\edef{for-#1}{
942  \the\c_count \x_relax
943  \noexpand\ifnum \gobble_one\fi
944  \the\b_count \ifnum 0>\c_count > \else < \fi

945 }

946  \def\next##1##2##3\endfor(#1){##2\for_i{##1}{##3}}
947  \next{#1}
948 \fi

949 }

\for-⟨name⟩ The macro \for-⟨name⟩ will contain

⟨step⟩\x_relax\ifnum⟨stop⟩⟨rel⟩

⟨step⟩ is the value of the ⟨step⟩ parameter of \for, computed when the loop was entered and now expressed in digits. ⟨stop⟩ is likewise for the ⟨stop⟩ parameter. ⟨rel⟩ is > or <, depending on whether ⟨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

\for_i{⟨name⟩}{⟨body code⟩}

Also remember, when reading the definition below, that \ifnum keeps on expanding tokens until it has found a

⟨number⟩⟨relation⟩⟨number⟩

structure. It is therefore possible to nest \ifnums like this!

950 \def\for_i#1#2{
951 \setsomething_global\x_cs\def{body-#1}{#2}
952 \ifnum \b_count \ifnum0>\c_count >\else<\fi \a_count
953  \expandafter\gobble_two
954 \else
955  \csname body-#1 \expandafter\endcsname
956 \fi
957 \for_ii{#1}

958 }

\body-⟨name⟩ The macro \body-⟨name⟩ expands to the ⟨body code⟩. \for_ii executes the following code:

     \a_count=\int{⟨name⟩}
     \advance \a_count ⟨step⟩\x_relax
     \ifnum ⟨stop⟩⟨rel⟩\a_count
        \expandafter\gobble_two
     \else
        \resetint{⟨name⟩}\a_count
        \csname body-⟨name⟩ \expandafter\endcsname
     \fi
     \for_ii{⟨name⟩}

⟨step⟩, ⟨stop⟩, and ⟨rel⟩ are in \for-⟨name⟩, and since there only are two other tokens between ⟨step⟩ and ⟨rel⟩ in the above, one might as well include them in \for-⟨name⟩ as well. Doing that requires that a matching hole—that will be filled in by \for-⟨name⟩—is made in the definition of \for_ii and that is the reason for its somewhat curious definition.

959 \def\for_ii#1{
960 \a_count=\int{#1}
961 \advance \a_count \csname for-#1\endcsname \a_count
962  \expandafter\gobble_two
963 \else
964  \x_resetint{#1}\a_count
965  \csname body-#1 \expandafter\endcsname

966 \fi
967 \for_ii{#1}

968 }

\endfor just gobbles its argument, so that the ⟨step⟩ = 0 case will work right.

969 \def\endfor(#1){}

970 ⟨/pkg⟩

Not in doc: \for
Not in doc: \endfor

971 ⟨∗doc⟩ 972 ⟨/doc⟩

\foreach \foreach_i The command sequence

\foreach(⟨name⟩){⟨csep-list⟩}

⟨body code⟩

     \endfor(⟨name⟩)

will cause the ⟨body code⟩ to be repeated one time for each item in the ⟨csep-list⟩. ⟨csep-list⟩ is a comma-separated list of strings.

As a precaution, the ⟨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.

⟨name⟩ is used as the name of a string variable. Before each repetition of the ⟨body code⟩, this variable will get reset to the next item in the ⟨csep-list⟩.

\foreach… \endfor constructions can be nested. ⟨name⟩ is used by \foreach to identify its matching \endfor, so they need to be identical in

\foreach and \endfor.

973 ⟨∗pkg⟩

974 \def\foreach(#1)#2{
975 \def\next##1\endfor(#1){
976  \setsomething_global\x_cs\def{body-#1}{##1}
977  \process_csep_list{\foreach_i{#1}}#2,\process_csep_list,

978 }

979 \next

980 }

981 \def\foreach_i#1#2{
982 \resetstr{#1}{#2}
983 \csname body-#1\endcsname

984 } 985 ⟨/pkg⟩ 986 ⟨∗doc⟩

987 \def\foreach(#1)#2{%
988 \def\next##1\endfor(#1){%
989  \@for\@tempa:=#2\do{%
990  \SetStringVariable{#1}{\@tempa}%
991  ##1%

992 }% 993 }%

994 \next

995 } 996 ⟨/doc⟩

9.5 Comments

\comment In fontinst, \comment simply gobbles its argument.

997 ⟨pkg⟩\let\comment=\gobble_one

In fontdoc, \comment starts a new text paragraph and leaves the argument to be typeset. Note that the argument group thus survives; some commands make use of this fact.

998 ⟨∗doc⟩

999 \def\comment{\par\noindent}

1000 ⟨/doc⟩

\begincomment \endcomment Since \comment cannot be used for a comment longer than one paragraph, we also provide the means of introducing longer comments, by writing

     \begincomment ⟨any amount of text⟩ \endcomment

The names are admittedly not nice from a L^{A}TEX point of view, but it is hardly worth the cost to implement some kind of environment processing in fontinst, just for the sake of this command.

1001 ⟨pkg⟩\let\begincomment=\iffalse
1002 ⟨doc⟩\let\begincomment=\iftrue
1003 ⟨pkg | doc⟩\let\endcomment=\fi

File c

fimain.dtx

10 Encoding files

\inputetx The macro
     \inputetx{⟨filename⟩}

inputs ⟨filename⟩.etx, ignoring anything between \relax and \encoding, and anything after \endencoding.

The file name is transformed to lowercase before opening.

\inputetx
\encoding
\endencoding

1 ⟨∗pkg | misc⟩

 2 \def\inputetx#1{
 3 \edef\lowercase_file{\lowercase{
 4  \edef\noexpand\lowercase_file{#1}}}
 5 \lowercase_file
 6 \slot_number=0
 7 \def\relax{\let\relax=\x_relax\iffalse}
 8 \let\encoding=\fi
 9 \primitiveinput \lowercase_file.etx\x_relax
10 \let\relax=\x_relax

11 }

12 \let\encoding=\relax
13 \outer\def\endencoding{\endinput}

14 ⟨/pkg | misc⟩

Things are a bit more complicated in fontdoc, since the \relax … \encoding … \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 \inputetxed, they must work as with fontinst: Everything between \relax and \encoding, and everything after \endencoding must be ignored.

15 ⟨∗doc⟩

16 \def\inputetx#1{%
17 \begingroup
18  \edef\lowercase@file{\lowercase{%
19  \edef\noexpand\lowercase@file{#1}%
20  }}%
21  \lowercase@file
22  \global\slot@number=0%
23  \FD@slot@known@true
24  \IfFileExists{\lowercase@file.etx}{%
25  \FD@relax@encoding@tricks
26  \@@input \@filef@und
27  \let\relax=\x@relax
28  }{%
29  \PackageError{fontdoc}{File #1.etx not found}%
30  {\@eha\MessageBreak You can \protect\inputetx\space
31  some other file now, if you want.}%

32 }

33 \endgroup

34 }

\FD@relax@encoding@tricks There is a problem with \if … \fi nesting in the redefinition of \relax and \encoding, which interacts badly with \IfFileExists. To work around that, these redefinitions are hidden in the \FD@relax@encoding@tricks macro.

35 \def\FD@relax@encoding@tricks{%
36 \def\relax{\let\relax=\x@relax\iffalse}%
37 \let\encoding=\fi
38 \outer\x@cs\def{endencoding}{\endinput}%

39 }

40 \def\encoding{%
41 \par
42 \ifFD@spec@ \addvspace{\bigskipamount}\fi
43 \begin{flushleft}
44 \global\slot@number=\z@

45 }

46 \outer\def\endencoding{%
47 \end{flushleft}
48 \ifFD@spec@ \addvspace{\bigskipamount}\fi

49 } 50 ⟨/doc⟩

\setslot \endsetslot \slot_name  \setslot{⟨name⟩} ⟨slot commands⟩ \endsetslot

In fontinst, this sets \slot_name to ⟨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.

51 ⟨∗pkg | misc⟩

52 \def\setslot#1{\edef\slot_name{#1}\do_slot}
53 \def\endsetslot{\end_do_slot\advance\slot_number by 1\x_relax}

54 ⟨/pkg | misc⟩

\slot@name In fontdoc, the same code converts ⟨name⟩ to a printable string and stores the result in \slot@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.

55 ⟨∗doc⟩

56 \newcommand\setslot[1]{%
57 \protected@edef\slot@name{%
58  \noexpand\MakePrintable \noexpand\slot@name {FD@swa}{#1}%
59 }%
60 \slot@name
61 \FD@tight@true
62 \Aheading{Slot
63  \ifFD@slot@known@
64  \the\slot@number\space
65  \else
66  \(\FD@slot@expression + \the\slot@number\)
67  \fi
68  `\FD@typeset@string{\slot@name}'%

69 }%
70 \protected@edef\@currentlabel{%
71  \ifFD@slot@known@
72  \the\slot@number
73  \else
74  \protect\(%
75  \FD@slot@expression+\the\slot@number
76  \protect\)%
77  \fi
78  \space(\protect\FD@typeset@string{\slot@name})%
79 }%
80 \ifFD@slot@known@ \ifslot@comment@ \comment{\slot@comment}\fi\fi

81 }

82 \def\endsetslot{%
83 \global\advance \slot@number \@ne
84 \FD@tight@false

85 } 86 ⟨/doc⟩

\do_slot
\end_do_slot

87 ⟨∗pkg | misc⟩

88 \let\do_slot\empty_command
89 \let\end_do_slot\empty_command

\nextslot \skipslots \slot_number \slot@number FD@slot@known@ switch \FD@slot@expression  \nextslot{⟨integer expression⟩}

\skipslots{⟨integer expression⟩}

In fontinst, \nextslot sets the \slot_number and \skipslots addvances the

\slot_number.
90 \newcount\slot_number
91 \def\nextslot#1{\eval_expr_to\slot_number{#1}}
92 \def\skipslots#1{\eval_expr{#1} \advance\slot_number by \result}

93 ⟨/pkg | misc⟩

The commands do the same in fontdoc as in fontinst, although they do it to

\slot@number instead of \slot_number.

94 ⟨∗doc⟩

95 \newcount\slot@number
96 \def\FD@slot@known@true{\global\let\ifFD@slot@known@\iftrue}
97 \def\FD@slot@known@false{\global\let\ifFD@slot@known@\iffalse}
98 \FD@slot@known@true
99 \newcommand\nextslot[1]{%
100 \FD@evaluate@true
101 \FD@eval@expr{#1}%
102 \ifFD@evaluate@
103  \global\slot@number=\FD@result
104  \FD@slot@known@true
105 \else
106  \global\let\FD@slot@expression=\FD@expression
107  \global\slot@number=\z@
108  \FD@slot@known@false
109 \fi

110 }

111 \newcommand\skipslots[1]{%

112 \FD@evaluate@true
113 \FD@eval@expr{#1}%
114 \ifFD@evaluate@
115  \global\advance \slot@number \FD@result
116 \else
117  \ifFD@slot@known@
118  \global\let\FD@slot@expression=\FD@expression
119  \else
120  \protected@xdef\FD@slot@expression{%
121  \FD@slot@expression+\FD@expression

122 }%

123  \fi
124  \FD@slot@known@false
125 \fi

126 } 127 ⟨/doc⟩

There has been some ambiguity concerning what is allowed as arguments of \nextslot and \skipslots. 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 fontinst is trivial, the above implementation copes with that, but 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

No, but if a \setslot command appears in a \for loop then the slot number in that command will depend on the values of various integer expressions anyway, so we might as well deal with it. /LH

The matter was finally resolved when fontdoc was augmented to handle (and typeset) arbtrary integer expressions.

\setleftboundary \endsetleftboundary \do_boundary  \setleftboundary{⟨glyph⟩} ⟨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 ⟨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.

128 ⟨∗pkg⟩

129 \def\setleftboundary#1{\edef\slot_name{#1}\do_boundary}
130 \let\endsetleftboundary\x_relax
131 \let\do_boundary\x_relax

132 ⟨/pkg⟩ 133 ⟨∗doc⟩

134 \newcommand\setleftboundary[1]{%
135 \protected@edef\slot@name{%
136  \noexpand\MakePrintable \noexpand\slot@name {FD@swa}{#1}%

137 }%

138 \slot@name
139 \FD@tight@true
140 \Aheading{Left boundary `\FD@typeset@string{\slot@name}'}%
141 \protected@edef\@currentlabel{%

142  left boundary (\protect\FD@typeset@string{\slot@name})%

143 }% 144 }

145 \let\endsetleftboundary=\FD@tight@false

146 ⟨/doc⟩ 147 ⟨∗misc⟩

148 \let\setleftboundary=\gobble_one
149 \let\endsetleftboundary=\x_relax

150 ⟨/misc⟩

\setrightboundary  \setrightboundary{⟨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 … \endsetslot pair, but since the slot will be left empty, there is no need for any ⟨slot commands⟩, and hence there is no need for a closing \endset… 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.

151 ⟨∗pkg | misc⟩

152 \def\setrightboundary#1{
153 \makerightboundary{#1}
154 \advance \slot_number 1\x_relax

155 } 156 ⟨/pkg | misc⟩ 157 ⟨∗doc⟩

158 \newcommand\setrightboundary[1]{%
159 \Aheading{Right boundary slot
160  \ifFD@slot@known@
161  \the\slot@number\space
162  \else
163  \(\FD@slot@expression + \the\slot@number\)
164  \fi
165  `\TypesetStringExpression{#1}'%

166 }%

167 \global\advance \slot@number \@ne

168 } 169 ⟨/doc⟩

\ligature The ⟨slot commands⟩ are:

\Ligature
\oddligature
\nextlarger
\varchar
\endvarchar
\usedas
\makerightboundary
\Unicode

\ligature{⟨lig⟩}{⟨glyph⟩}{⟨glyph⟩} \Ligature{⟨lig⟩}{⟨glyph⟩}{⟨glyph⟩} \oddligature{⟨note⟩}{⟨lig⟩}{⟨glyph⟩}{⟨glyph⟩}

     \nextlarger{⟨glyph⟩}
     \varchar ⟨varchar commands⟩ \endvarchar

\usedas{⟨command⟩}{⟨type⟩}

     \makerightboundary{⟨glyph⟩}

\Unicode{⟨code point⟩}{⟨name⟩}

By default, these do nothing in fontinst, but most of those defaults are overridden locally in those situations where one wants them to do something. Exceptions are \usedas, which is never used at all AFAIK,^{9} and \oddligature and \Unicode, which are purely documentation commands. In fontdoc, they generate descriptive headings.

9It was intended to be used for math font encodings, but that never got off the TODO list. /LH

\ligature \Ligature \oddligature The \ligature and \Ligature commands have the same syntax and meaning to

fontinst, but fontdoc can give them slightly different treatment. In a specification ETX file, the \Ligature command gets the heading “Mandatory ligature”, whereas the \ligature command gets the heading “Ordinary ligature”.

The \oddligature command takes a fourth argument which contains a short note on when the ligature might be appropriate. The entire command is always ignored by fontinst.

170 ⟨pkg | misc⟩\let\ligature=\gobble_three
171 ⟨pkg | misc⟩\def\Ligature{\ligature}
172 ⟨pkg | misc⟩\def\oddligature#1#2#3#4{}

173 ⟨∗doc⟩

174 \newcommand\ligature[3]{%
175 \Bheading{\ifFD@spec@ Ordinary ligature\else Ligature\fi}
176 \@nameuse{FD@lig-#1}{#2}{#3}%

177 }

178 \newcommand\Ligature[3]{%
179 \Bheading{\ifFD@spec@ Mandatory ligature\else Ligature\fi}
180 \@nameuse{FD@lig-#1}{#2}{#3}%

181 }

182 \newcommand\oddligature[4]{%
183 \Bheading{Odd\footnote{#1} ligature}
184 \@nameuse{FD@lig-#2}{#3}{#4}%

185 }

\FD@lig-⟨lig⟩ Symbolic typesetting of \ligature programs requires special processing.

186 \x@cs\def{FD@lig-LIG}#1#2{%
187 \FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
188 ${}\rightarrow{}$\typeset@glyph{#2}%

189 }

190 \x@cs\def{FD@lig-/LIG}#1#2{%
191 \FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
192 ${}\rightarrow{}$%
193 \FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#2}%

194 }

195 \x@cs\def{FD@lig-LIG/}#1#2{%
196 \FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
197 ${}\rightarrow{}$%
198 \typeset@glyph{#2}${}*{}$\typeset@glyph{#1}%

199 }

200 \x@cs\def{FD@lig-/LIG/}#1#2{%
201 \FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
202 ${}\rightarrow{}$%
203 \FD@typeset@string{\slot@name}${}*{}$%
204 \typeset@glyph{#2}${}*{}$\typeset@glyph{#1}%

205 }

206 \x@cs\def{FD@lig-/LIG>}#1#2{%
207 \FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
208 ${}\rightarrow{}$%
209 \FD@typeset@string{\slot@name}${}*\lfloor$\typeset@glyph{#2}%

210 }

211 \x@cs\def{FD@lig-LIG/>}#1#2{%

212 \FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
213 ${}\rightarrow{}$%
214 \typeset@glyph{#2}${}*\lfloor$\typeset@glyph{#1}%

215 }

216 \x@cs\def{FD@lig-/LIG/>}#1#2{%
217 \FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
218 ${}\rightarrow{}$%
219 \FD@typeset@string{\slot@name}${}*\lfloor$%
220 \typeset@glyph{#2}${}*{}$\typeset@glyph{#1}%

221 }

222 \x@cs\def{FD@lig-/LIG/>>}#1#2{%
223 \FD@typeset@string{\slot@name}${}*{}$\typeset@glyph{#1}%
224 ${}\rightarrow{}$%
225 \FD@typeset@string{\slot@name}${}*{}$%
226 \typeset@glyph{#2}${}*\lfloor$\typeset@glyph{#1}%

227 } 228 ⟨/doc⟩

\nextlarger
\usedas
\makerightboundary

229 ⟨∗pkg | misc⟩

230 \let\nextlarger=\gobble_one
231 \let\usedas=\gobble_two
232 \let\makerightboundary=\gobble_one

233 ⟨/pkg | misc⟩

234 ⟨∗doc⟩

235 \def\nextlarger#1{\Bheading{Next larger} \typeset@glyph{#1}}
236 \def\makerightboundary#1{%
237 \Bheading{Right boundary marker slot} designation \typeset@glyph{#1}%

238 } 239 ⟨/doc⟩

Not in doc: \usedas

\Unicode \textunicode \FD@codepoint \FD@charname Since ISO 10646/Unicode has become the primary reference for identifying characters, we provide a special comment command for specifying which Unicode character corresponds to a particular slot in an encoding. The syntax is

\Unicode{⟨code point⟩}{⟨name⟩}

where the ⟨code point⟩ is the four hexadecimal digits that identify the code point of the character and ⟨name⟩ is the name of the character. An example is

      \Unicode{0041}{LATIN CAPITAL LETTER A}

which is typeset as

Unicode character U+0041, latin capital letter a.

The ⟨name⟩ field may be left empty.

The \Unicode command makes a whole \comment, but it is also useful to have a similar command for writing such data as part of a longer paragraph. The \textunicode command, which has the same argument structure as \Unicode, is provided for this. If you write

      see also \textunicode{0041}{LATIN CAPITAL LETTER A} for

then this is typeset as

see also U+0041 (latin capital letter a) for

As case is not significant in the character names and they furthermore usually seem to be written in capitals, I have chosen to typeset them using small capitals only. This is done by \FD@charname. The \FD@codepoint macro similarly handles typesetting of code points. See also the hypertex option to the fontdoc package.

The fontinst and finstmsc definitions of \Unicode are to gobble the arguments.

240 ⟨pkg | misc⟩\let\Unicode=\gobble_two

241 ⟨∗doc⟩

242 \newcommand*\Unicode[2]{%
243 \comment{%
244  \spaceskip=\fontdimen2\font minus 1.1\fontdimen4\font
245  Unicode character \FD@codepoint{#1}%
246  \ifx \par#2\par \else , \FD@charname{#2}\fi.%
247  \linepenalty=300\par

248 }% 249 }

250 \newcommand*\textunicode[2]{%
251 \FD@codepoint{#1} \ifx\par#2\par\else(\FD@charname{#2})\fi

252 }

253 \providecommand*\FD@codepoint[1]{\texttt{U+\uppercase{#1}}}
254 \providecommand*\FD@charname[1]{\textsc{\lowercase{#1}}}

255 ⟨/doc⟩

\charseq Most commonly occurring glyphs correspond to one \Unicode character, but this is not at all true in general—in fact there may even be letters which cannot be encoded as single characters, as they do not exist in precomposed form but have to be expressed with a base letter and combining diacritical mark. Reasonable compliance with the standard requires supporting character sequences as well as individual characters.

In fontinst, the \charseq command is used to specify such a character sequence. The syntax is

     \charseq{⟨\Unicode commands⟩}

where the ⟨\Unicode commands⟩ is one or several \Unicode commands. This means the sequence of those characters. For example

     \charseq{
        \Unicode{0066}{LATIN SMALL LETTER F}
        \Unicode{0069}{LATIN SMALL LETTER I}
     }

is typeset as

Unicode character sequence:

U+0066 (latin small letter f) U+0069 (latin small letter i)

This indentation is made using the IfBranch environment, which could be considered a bit hackish.

\charseq is gobbled in ⟨pkg⟩ and ⟨misc⟩, but in the latter case it might get redefined.

256 ⟨pkg | misc⟩\let\charseq=\gobble_one

Note how the environment group restores the definition of \Unicode.

257 ⟨∗doc⟩

258 \newcommand\charseq[1]{%
259 \comment{Unicode character sequence:}%
260 \begin{IfBranch}%
261  \def\Unicode##1##2{%
262  \noindent\FD@codepoint{##1}
263  \ifx\par##2\par\else(\FD@charname{##2})\fi
264  \par

265 }%

266  #1%
267 \end{IfBranch}%

268 } 269 ⟨/doc⟩

\vartop The ⟨varchar commands⟩ are:

\varmid
\varbot
\varrep

     \vartop{⟨glyph⟩}
     \varmid{⟨glyph⟩}
     \varbot{⟨glyph⟩}
     \varrep{⟨glyph⟩}

These too do by default, which is overridden later, nothing in fontinst but typeset descriptive headings in fontdoc.

\varchar
\vartop
\varmid
\varbot
\varrep
\endvarchar

270 ⟨∗pkg | misc⟩

271 \let\varchar=\empty_command
272 \let\vartop=\gobble_one
273 \let\varmid=\gobble_one
274 \let\varbot=\gobble_one
275 \let\varrep=\gobble_one
276 \let\endvarchar=\empty_command

277 ⟨/pkg | misc⟩

278 ⟨∗doc⟩

279 \def\varchar{\Bheading{Extensible glyph:}}
280 \def\vartop#1{\Bheading{Top} \typeset@glyph{#1}}
281 \def\varmid#1{\Bheading{Middle} \typeset@glyph{#1}}
282 \def\varbot#1{\Bheading{Bottom} \typeset@glyph{#1}}
283 \def\varrep#1{\Bheading{Repeated} \typeset@glyph{#1}}
284 \let\endvarchar\relax

285 ⟨/doc⟩

\useexamplefont \slotexample \setslotcomment \resetslotcomment \unsetslotcomment \slot@comment \slot@font As of v 1.8 of 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:

\useexamplefont{FONT}
\setslotcomment{The symbol `\slotexample'.}
\setslot{FOO}\endsetslot
\setslot{BAR}\endsetslot
\resetslotcomment{The character `\slotexample'.}
\setslot{BAZ}\endsetslot

instead of having to write:

\usepackage{PACKAGE-to-use-symbols-from-FONT}
\setslot{FOO}\comment{The symbol `\foo'.}\endsetslot
\setslot{BAR}\comment{The symbol `\bar'.}\endsetslot
\setslot{BAZ}\comment{The character `\baz'.}\endsetslot

These macros never do anything in fontinst, they just gobble their arguments.

286 ⟨∗pkg | misc⟩

287 \let\useexamplefont=\gobble_one
288 \let\slotexample=\empty_command
289 \let\setslotcomment=\gobble_one
290 \let\resetslotcomment=\gobble_one
291 \let\unsetslotcomment=\empty_command

292 ⟨/pkg | misc⟩

293 ⟨∗doc⟩

294 \newif\ifslot@comment@
295 \slot@comment@false
296 \def\slot@comment{}
297 \newcommand\setslotcomment[1]{%
298 \slot@comment@true
299 \gdef\slot@comment{#1}%

300 }

301 \newcommand\resetslotcomment[1]{\gdef\slot@comment{#1}}
302 \newcommand\unsetslotcomment{%
303 \slot@comment@false
304 \global\let\slot@comment\@empty

305 }

306 \let\slot@font=\nullfont
307 \newcommand\useexamplefont[1]{\font\slot@font=#1 }
308 \newcommand\slotexample{%
309 \ifFD@slot@known@{\slot@font\char\slot@number}\fi

310 } 311 ⟨/doc⟩

\setfontdimen The \setfontdimen command is used in an ETX file to set a font dimen. The syntax is

\setfontdimen{⟨fontdimen no.⟩}{⟨integer⟩}

where ⟨fontdimen no.⟩ and ⟨integer⟩ are string expressions. ⟨fontdimen no.⟩ specifies the fontdimen to set. ⟨integer⟩ is the name of the integer variable to whose value the fontdimen will be set.

When used in font installation, the above \setfontdimen command is equivalent to

     \ifisint{⟨integer⟩}\then
        \setint{fontdimen(⟨fontdimen no.⟩)}{\int{⟨integer⟩}}
     \fi

but \setfontdimen is also understood by the (V)PL-to-MTX converter as declaring an integer that the generated MTX file should set to the value of the fontdimen in the (V)PL.

312 ⟨∗pkg⟩

313 \def\setfontdimen#1#2{
314 \ifisint{#2}\then \setint{fontdimen(#1)}{\int{#2}} \fi

315 } 316 ⟨/pkg⟩

317 ⟨misc⟩\let\setfontdimen\gobble_two

318 ⟨∗doc⟩

319 \newcommand\setfontdimen[2]{%
320 \Bheading{Fontdimen} \TypesetStringExpression{#1} is
321 \(\TypesetIntegerExpression{\int{#2}}\)%

322 } 323 ⟨/doc⟩

\label fontinst and finstmsc defines the L^{A}TEX \label command to gobble its argument, so that one can use it to reference slots.

324 ⟨pkg | misc⟩\let\label=\gobble_one

direct switch The encoding aspect of a font can to a large extent be understood as a mapping from the set of slots to the set of glyphs—such mappings are for example realised by PostScript encoding vectors (mapping slots to glyph names) and virtual fonts (mapping slots to DVI commands for drawing a glyph). In some cases however, encodings are rather used to specify an inverse mapping going the opposite way. Since encodings are in general many-to-one, this means there need not be a proper inverse to a given encoding; instead the inverse image of a glyph is in practice chosen randomly^{10} among the slots that are mapped to it. This is not always desirable.

The direct switch can be used to check whether an encoding is interpreted in the direct (slots to glyphs) or inverse (glyphs to slots) manner. If those \setslot commands which are undesirable under the inverse interpretation are put inside an \ifdirect … \Fi construction, then these will be ignored in that circumstance, thus allowing the programmer to exactly specify both the direct and the inverse mappings.

In fontinst, this command is a switch, which is usually true.

325 ⟨pkg | misc⟩\newif\ifdirect \directtrue

In fontdoc, this is a conditional that will be typeset if \showbranches is being used.

326 ⟨doc⟩\newcommand\ifdirect{\generic@if{direct}}
\input_mtx_as_etx The \input_mtx_as_etx command is syntactically similar to the \inputetx

command, but it inputs an MTX file instead of an ETX file and redefines

\setscaledrawglyph so that it expands to a \nextslot followed by a \setslot

10In the sense: according to a very deterministic (but not particularly useful) rule which depends completely on details in the implementation, and therefore should not be relied upon anyway.

… \endsetslot. This is useful when making proofs of fonts with nonstandard encodings, as the MTX of a font can be used to specify “the default encoding” of that font.

Warning: Since this macro redefines a lot of the metric commands, you’ll probably only want to call it inside a group.

327 ⟨∗pkg | misc⟩

328 \def\input_mtx_as_etx#1{
329 \def\setscaledrawglyph##1##2##3##4##5##6##7##8##9{
330  \nextslot{##5}
331  \setslot{##1}\endsetslot

332 }

333 \offcommand\setscalednotglyph
334 \let\setglyph=\gobble_glyph
335 \offcommand\setkern
336 \inputmtx{#1}

337 } 338 ⟨/pkg | misc⟩

11 Metric files

\inputmtx The macro
     \inputmtx{⟨filename⟩}

inputs ⟨filename⟩.mtx, ignoring anything between \relax and \metrics, and any-

thing after \endmetrics.
\inputmtx \metrics \endmetrics \endmetrics_text \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.

339 ⟨∗pkg | misc⟩

340 \def\inputmtx#1{
341 \def\relax{\let\relax=\x_relax\iffalse}
342 \let\metrics=\fi
343 \primitiveinput #1.mtx\x_relax
344 \let\relax=\x_relax

345 }

346 \let\metrics=\x_relax
347 \edef\endmetrics_text{\string\endmetrics}
348 \outer\def\endmetrics{\endinput}

349 ⟨/pkg | misc⟩

\inputmtx used to set \a_count, but we haven’t been able to find a reason for this, so it was removed.

In fontdoc, the \metrics and \endmetrics macros initially just define a group, but \inputmtx redefines them to work as they do in 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.

350 ⟨∗doc⟩

351 \def\inputmtx#1{%
352 \begingroup

353  \edef\lowercase@file{\lowercase{%
354  \edef\noexpand\lowercase@file{#1}%
355  }}%
356  \lowercase@file
357  \let\endmetrics@hook=\@empty
358  \IfFileExists{\lowercase@file.mtx}{%
359  \skip@mtx@preamble
360  \@@input \@filef@und
361  \let\relax=\x@relax
362  }{%
363  \PackageError{fontdoc}{File #1.mtx not found}%
364  {\@eha\MessageBreak You can \protect\inputmtx\space
365  some other file now, if you want.}%

366 }

367  \endmetrics@hook
368 \endgroup

369 }

370 \def\skip@mtx@preamble{%
371 \def\relax{\let\relax=\x@relax\iffalse}%
372 \let\metrics=\fi
373 \outer\x@cs\def{endmetrics}{\endinput}%

374 }

375 \def\metrics{%
376 \begin{flushleft}%
377 \let\endmetrics@hook=\@empty

378 }

379 \outer\def\endmetrics{%
380 \endmetrics@hook
381 \end{flushleft}%

382 } 383 ⟨/doc⟩

\ProvidesMtxPackage @mtxpackage@headed@ switch \announce@package \finish@package The call
      \ProvidesMtxPackage{⟨package name⟩}

signals to the package managing system that there is no need to load this package again.

384 ⟨pkg⟩\def\ProvidesMtxPackage#1{\x_cs\let{pack-#1}P}

385 ⟨∗doc⟩

386 \def\ProvidesMtxPackage#1{%
387 \endmetrics@hook
388 %    \@mtxpackage@headed@false
389 %    \everypar={
390 \announce@package{#1}%
391 %    }%
392 \def\endmetrics@hook{\finish@package{#1}}
393 \global\x@cs\let{FD@pack-#1}\@empty

394 }

395 % \newif\if@mtxpackage@headed@
396 \def\announce@package#1{%
397 %    \everypar={}%
398 %    \@mtxpackage@headed@true
399 \Aheading{[Start of metric package \textsf{#1}.}%

401 \def\finish@package#1{%
402 %    \if@mtxpackage@headed@
403  \Aheading{End of metric package \textsf{#1}.]}%
404 %    \else
405 %       \everypar={}%
406 %       \Aheading{(Metric package \textsf{#1}.)}%
407 %    \fi
408 \par\addvspace\medskipamount

409 } 410 ⟨/doc⟩

\usemtxpackage The call
      \usemtxpackage{⟨package list⟩}

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

\usemtxpackage[⟨filename⟩]{⟨package list⟩}

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 ⟨filename⟩ as argument.

411 ⟨∗pkg⟩

412 \def\usemtxpackage{\futurelet\next_token\test_UseMtxPkg_arguments}
413 \def\test_UseMtxPkg_arguments{\ifx\next_token[
414  \expandafter\mtx_package_given_file
415 \else
416  \expandafter\mtx_package_separate_files
417 \fi

418 }

419 \def\mtx_package_given_file[#1]#2{
420 \_a_false
421 \process_csep_list\load_true_unless_loaded #2,\process_csep_list,
422 \if_a_\inputmtx{#1} \fi

423 }

424 \def\load_true_unless_loaded#1{
425 \x_cs\ifx{pack-#1}P\else\_a_true\fi

426 }

427 \def\mtx_package_separate_files#1{
428 \process_csep_list\load_file_unless_loaded #1,\process_csep_list,

429 }

430 \def\load_file_unless_loaded#1{
431 \x_cs\ifx{pack-#1}P\else \inputmtx{#1} \fi

432 } 433 ⟨/pkg⟩

434 ⟨∗doc⟩

435 \newcommand\usemtxpackage[2][\x@relax]{%
436 \ifx \x@relax#1%

437  \@for\@tempa:=#2\do{%
438  \x@cs\ifx{FD@pack-\@tempa}\@empty \else
439  \inputmtx{\@tempa}%
440  \fi

441 }%

442 \else
443  \@tempswafalse
444  \@for\@tempa:=#1\do{%
445  \x@cs\ifx{FD@pack-\@tempa}\@empty \else \@tempswatrue \fi

446 }%

447  \if@tempswa
448  \inputmtx{#2}%
449  \fi
450 \fi

451 } 452 ⟨/doc⟩

\glyph_name_modifier The \glyph_name_modifier macro is applied to all glyph names supplied to commands that are allowed in transformable MTX files (see Subsection 16.1). The syntax is

     \glyph_name_modifier{⟨glyph name⟩}

and the above must expand fully to a valid glyph name in TEX’s mouth.

The normal definition is to simply expand to the ⟨glyph name⟩, i.e.,

453 ⟨pkg⟩\let\glyph_name_modifier=\identity_one

but the command may expand to any sequence of character tokens. It was introduced to support (simple) automatic renaming of glyphs in cases where the \reglyphfont command would not be appropriate, such as when the wanted renaming is simply to add a short suffix to the glyph names.

The reason it only affects the commands allowed in transformable MTX files is that the macro isn’t meant as a generic override for metric commands.

11.1 Kerning information

\l-⟨name⟩ The kerning information is kept in the macros \l-⟨name⟩ and \r-⟨name⟩, contain- \r-⟨name⟩ ing information about how ⟨name⟩ kerns on the left and on the right, respectively.

The \l-⟨name⟩ macro should expand out to a series of

\k \k\r-⟨name⟩ \⟨amount⟩

\⟨amount⟩ control sequences, and vice versa. Examples of \⟨amount⟩ control sequences are: \0, \1, \1000, \-50, \33; these corresponds to the kern amounts 0, 1, 1000 (which would be a very large kern), −50, and 33 respectively.

\setkern \setkern{⟨glyph1 ⟩}{⟨glyph2 ⟩}{⟨integer expression⟩}

Sets a kern pair between ⟨glyph1 ⟩ and ⟨glyph2 ⟩ to the specified value, which is typically a value returned by \kerning{⟨glyph3 ⟩}{⟨glyph4 ⟩}. If there already is a kern set between ⟨glyph1 ⟩ and ⟨glyph2 ⟩ then this will not affect the output, but it will use up another 3 units of token memory.

454 ⟨∗pkg⟩

455 \def\setkern#1#2#3{
456 \x_cs\ifx{i-rawscale}\x_relax

457  \expandafter\set_kern
458  \csname~r-\glyph_name_modifier{#1}\expandafter\endcsname
459  \csname~l-\glyph_name_modifier{#2}\endcsname
460  {#3}
461 \else
462  \expandafter\set_kern
463  \csname~r-\glyph_name_modifier{#1}\expandafter\endcsname
464  \csname~l-\glyph_name_modifier{#2}\endcsname
465  {\scale{#3}{\int{rawscale}}}
466 \fi

467 }

468 \def\set_kern#1#2#3{
469 \eval_expr{#3}
470 \expandafter\set_kern_cs\csname\the\result\endcsname#1#2

471 }

472 \def\set_kern_cs#1#2#3{
473 \add_to#2{\k#3#1}
474 \add_to#3{\k#2#1}

475 } 476 ⟨/pkg⟩

477 ⟨∗doc⟩

478 \newcommand\setkern[3]{%
479 \Bheading{Kern} \typeset@glyph{#1}${{}+{}}$\typeset@glyph{#2}%
480 ${}\rightarrow \TypesetIntegerExpression{#3}$%

481 } 482 ⟨/doc⟩

483 ⟨misc⟩\let\setkern=\gobble_three

\resetkern \resetkern{⟨glyph1 ⟩}{⟨glyph2 ⟩}{⟨integer expression⟩}

Resets the kern pair between ⟨glyph1 ⟩ and ⟨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).

484 ⟨∗pkg⟩

485 \def\resetkern#1#2#3{
486 \x_cs\ifx{i-rawscale}\x_relax
487  \expandafter\reset_kern
488  \csname~r-#1\expandafter\endcsname
489  \csname~l-#2\endcsname{#3}
490 \else
491  \expandafter\reset_kern
492  \csname~r-#1\expandafter\endcsname
493  \csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}}
494 \fi

495 }

496 \def\reset_kern#1#2#3{
497 \eval_expr{#3}
498 \expandafter\reset_kern_cs\csname\the\result\endcsname#1#2

499 }

500 \def\reset_kern_cs#1#2#3{
501 \prep_to#2{\k\expandafter#3\expandafter#1}
502 \prep_to#3{\k\expandafter#2\expandafter#1}

503 } 504 ⟨/pkg⟩ 505 ⟨∗doc⟩

506 \newcommand\resetkern[3]{%
507 \Bheading{Override kern} \typeset@glyph{#1}${{}+{}}$\typeset@glyph{#2}%
508 ${}\rightarrow \TypesetIntegerExpression{#3}$%

509 } 510 ⟨/doc⟩

\setleftkerning \setrightkerning \setleftrightkerning  \setleftkerning{⟨glyph1 ⟩}{⟨glyph2 ⟩}{⟨scaled⟩}

\setrightkerning{⟨glyph1 ⟩}{⟨glyph2 ⟩}{⟨scaled⟩}

 \setleftrightkerning{⟨glyph1 ⟩}{⟨glyph2 ⟩}{⟨scaled⟩}

Sets left or right kerning of ⟨glyph1 ⟩ to that of ⟨glyph2 ⟩ scaled by ⟨scaled⟩ (which is an integer expression). \setleftrightkerning does both.

511 ⟨∗pkg⟩

512 \def\setleftkerning#1#2#3{
513 \eval_expr_to\b_count{#3}
514 \expandafter\set_kerning
515  \csname~l-#1\expandafter\endcsname
516  \csname~l-#2\endcsname

517 }

518 \def\setrightkerning#1#2#3{
519 \eval_expr_to\b_count{#3}
520 \expandafter\set_kerning
521  \csname~r-#1\expandafter\endcsname
522  \csname~r-#2\endcsname

523 }

524 \def\setleftrightkerning#1#2#3{
525 \eval_expr_to\b_count{#3}
526 \expandafter\set_kerning
527  \csname~l-#1\expandafter\endcsname
528  \csname~l-#2\endcsname
529 \expandafter\set_kerning
530  \csname~r-#1\expandafter\endcsname
531  \csname~r-#2\endcsname

532 }

533 \def\set_kerning#1#2{
534 \if\b_count=\one_thousand
535  \def\k##1##2{
536  \set_kern_cs##2##1#1

537 }

538 \else
539  \def\k##1##2{
540  \set_kern##1#1{
541  \scale\b_count{\expandafter\gobble_one\string##2}

542 } 543 }

544 \fi

545 #2 546 } 547 ⟨/pkg⟩

548 ⟨∗doc⟩

549 \newcommand\setleftkerning[3]{%
550 \Bheading{Kern} \typeset@glyph{#1} on the left like
551 \typeset@glyph{#2} \ConditionallyScaled{#3}}

552 \newcommand\setrightkerning[3]{%
553 \Bheading{Kern} \typeset@glyph{#1} on the right like
554 \typeset@glyph{#2} \ConditionallyScaled{#3}}
555 \newcommand\setleftrightkerning[3]{%
556 \Bheading{Kern} \typeset@glyph{#1} on the left and right like
557 \typeset@glyph{#2} \ConditionallyScaled{#3}}

\ConditionallyScaled Several metric commands have take a scaling factor argument which is rendered by fontdoc as “scaled ⟨argument⟩”. The by far most common value for this argument is however the constant number 1000 (no scaling), and in those cases the “scaled … ” feels a bit long-winded. The cure for this is the \ConditionallyScaled command, which takes an integer expression as its argument and typesets the “scaled ⟨integer expression⟩” unless that expression evaluates to 1000, in which case \ConditionallyScaled simply gobbles any spaces following it.

558 \newcommand\ConditionallyScaled[1]{%
559 \FD@evaluate@true
560 \FD@eval@expr{#1}%
561 \@tempswatrue
562 \ifFD@evaluate@ \ifnum \FD@result=\@m \@tempswafalse \fi\fi
563 \FD@evaluate@false
564 \if@tempswa scaled \(\FD@expression\)\else \ignorespaces \fi

565 } 566 ⟨/doc⟩

\kerning  \kerning{⟨glyph1 ⟩}{⟨glyph2 ⟩}

Returns the value of kern pair between ⟨glyph1 ⟩ and ⟨glyph2 ⟩ as an integer. Returns a value of zero if such a kern pair doesn’t exist.

567 ⟨∗pkg⟩

568 \def\kerning#1#2{0\x_relax
569 \def\k##1{\csname~set-\string##1\endcsname\gobble_one}
570 \bgroup
571 \x_cs\def{set-\string\l-#2}##1##2{
572  \global\result=\expandafter\gobble_one\string##2\egroup

573 }

574 \csname~r-#1\endcsname
575 \csname~set-\string\l-#2\endcsname\gobble_one{00}

576 } 577 ⟨/pkg⟩

578 ⟨∗doc⟩

579 \DeclareRobustCommand\kerning[2]{%
580 \begingroup
581 \MakePrintable\@tempa{FD@swa}{#1}%
582 \MakePrintable\@tempb{FD@swa}{#2}%
583 \protected@xdef\FD@expression{%
584  \mathop{\protect\mathrm{k{}}}(%
585  \text{\protect\FD@typeset@string{\@tempa}}%
586  ,\penalty\FD@commapenalty
587  \text{\protect\FD@typeset@string{\@tempb}}%

588 )% 589 }%

590 \global\chardef\FD@priority=5%
591 \global\FD@bracket@level=\@ne

592 \FD@evaluate@false
593 \endgroup

594 } 595 ⟨/doc⟩

\ifiskern  \ifiskern{⟨glyph1 ⟩}{⟨glyph2 ⟩}\then

This command tests if there is a kern pair between ⟨glyph1 ⟩ and ⟨glyph2 ⟩. It’s hard to say if there is a use for it, but it is included for symmetry.

596 ⟨∗pkg⟩

597 \def\ifiskern#1#2\then{
598 \def\k##1##2{\ifx T##1 \let\k\gobble_two \fi}
599 \bgroup
600  \x_cs\let{l-#2}T
601  \csname r-#1\endcsname
602 \expandafter\egroup \ifx\k\gobble_two

603 } 604 ⟨/pkg⟩

605 ⟨∗doc⟩

606 \def\ifiskern#1#2\then{%
607 \generic@if{kern \typeset@glyph{#1}${}+{}$\typeset@glyph{#2} set}%

608 } 609 ⟨/doc⟩

\unsetkerns \unsetkerns{⟨left glyph list⟩}{⟨right glyph list⟩}

This command unsets all kerns with a glyph in the ⟨left glyph list⟩ on the left and a glyph in the ⟨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-⟨left glyph⟩ for each element ⟨left glyph⟩ in ⟨left glyph list⟩ and \l-⟨right glyph⟩ for each element ⟨right glyph⟩ in ⟨right glyph list⟩, removing each \k⟨token⟩⟨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-⟨glyph⟩ to U (the letter token U). This mark is later removed when the \r-⟨glyph⟩ or \l-⟨glyph⟩ respectively control sequences have been gone through; the \slots-⟨glyph⟩ control sequences are then set to \relax.

610 ⟨∗pkg⟩

611 \def\unsetkerns#1#2{
612 \let\k\k_unless_to_U
613 \process_csep_list\make_slots_U#1,\process_csep_list,
614 \def\do##1{\x_cs\main_remove_Us{l-##1}}
615 \process_csep_list\do#2,\process_csep_list,
616 \process_csep_list\make_slots_relax#1,\process_csep_list,
617 \process_csep_list\make_slots_U#2,\process_csep_list,
618 \def\do##1{\x_cs\main_remove_Us{r-##1}}
619 \process_csep_list\do#1,\process_csep_list,
620 \process_csep_list\make_slots_relax#2,\process_csep_list,

621 }

622 \def\make_slots_U#1{\x_cs\let{slots-#1}U}
623 \def\make_slots_relax#1{\x_cs\let{slots-#1}\x_relax}
624 \def\k_unless_to_U#1#2{
625 \x_cs\ifx{slots-\expandafter\gobble_three\string#1}U \else

626  \noexpand\k\noexpand#1\noexpand#2
627 \fi

628 }

629 \def\main_remove_Us#1{
630 \ifx#1\x_relax \else
631  \edef#1{#1}
632  \ifx#1\empty_command \let#1\x_relax \fi
633 \fi

634 } 635 ⟨/pkg⟩

636 ⟨∗doc⟩

637 \newcommand\unsetkerns[2]{%
638 \Bheading{Remove} all kerning pairs in
639 \FD@typeset@string@set{#1}${}\times{}$\FD@typeset@string@set{#2}%

640 }

\FD@typeset@string@set \FD@typeset@string@set@ The \FD@typeset@string@set macro takes a comma-separated list of string ex-

pressions as argument and typesets that list as elements of a set, e.g.

      \FD@typeset@string@set{a,b,\str{c}}

is typeset as

{a, b, s(c)}

641 \def\FD@typeset@string@set#1{%
642 \toks@={}%
643 \@for\@tempa:=#1\do{%
644  \protected@edef\@tempa{%
645  \noexpand\MakePrintable \noexpand\@tempa {FD@swa}{\@tempa}%

646 }%

647  \@tempa
648  \toks@=\expandafter{\the\expandafter\toks@
649  \expandafter\do \expandafter{\@tempa}}%

650 }%

651 \expandafter\FD@typeset@string@set@ \expandafter{\the\toks@}%

652 }

653 \def\FD@typeset@string@set@#1{%
654 \TypesetList{$\{$}{$,\penalty\FD@commapenalty{}$}%
655  {$,\penalty\FD@commapenalty{}$}{$,\penalty\FD@commapenalty{}$}%
656  {$\}$}{$\emptyset$}{\FD@typeset@string}{#1}%

657 } 658 ⟨/doc⟩

\noleftkerning \norightkerning \noleftrightkerning 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.

659 ⟨∗pkg⟩

660 \def\noleftkerning#1{\no_kerning{l}{#1}}
661 \def\norightkerning#1{\no_kerning{r}{#1}}
662 \def\noleftrightkerning#1{\no_kerning{l}{#1}\no_kerning{r}{#1}}

663 ⟨/pkg⟩

664 ⟨∗doc⟩

665 \newcommand\noleftkerning[1]{%
666 \Bheading{Remove kerns} on the left of glyphs in

667 \FD@typeset@string@set{#1}.}
668 \newcommand\norightkerning[1]{%
669 \Bheading{Remove kerns} on the right of glyphs in
670 \FD@typeset@string@set{#1}.}
671 \newcommand\noleftrightkerning[1]{%
672 \Bheading{Remove kerns} on any side of glyphs in
673 \FD@typeset@string@set{#1}.}

674 ⟨/doc⟩

\no_kerning This macro is called as

\no_kerning{⟨side⟩}{⟨glyph list⟩}

where ⟨side⟩ is l or r, and ⟨glyph list⟩ is a comma-separated list of glyph names. The macro unsets all kerns on the ⟨side⟩ side of the glyphs in the ⟨glyph list⟩.

675 ⟨∗pkg⟩

676 \def\no_kerning#1#2{
677 \let\k\no_kerning_i
678 \def\do##1{\csname #1-##1\endcsname}
679 \bgroup
680  \aftergroup\def \aftergroup\a_macro \aftergroup{
681  \process_csep_list\do #2,\process_csep_list,
682  \aftergroup}
683 \egroup
684 \def\do##1{\expandafter\let \csname #1-##1\endcsname \x_relax}
685 \process_csep_list\do #2,\process_csep_list,
686 \let\k\no_kerning_ii
687 \def\do##1{\edef##1{##1}}
688 \a_macro

689 }

\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 ⟨glyph list⟩ has a ⟨side⟩ kern to, while avoiding repetitions.

690 \def\no_kerning_i#1#2{
691 \ifx #1\x_relax \else
692  \aftergroup\do \aftergroup#1
693  \let #1\x_relax
694 \fi

695 }

\no_kerning_ii The \no_kerning_ii macro is similar to the \k_unless_to_U macro.
696 \def\no_kerning_ii#1#2{
697 \ifx #1\x_relax \else \noexpand\k \noexpand#1 \noexpand#2 \fi

698 } 699 ⟨/pkg⟩

11.2 Glyph information

\g-⟨name⟩ The glyph information is kept in the macros \g-⟨name⟩, which expands out to:

{⟨width⟩}{⟨height⟩}{⟨depth⟩}{⟨italic⟩}{⟨mapcommands⟩}{⟨mapfonts⟩}

where the ⟨mapcommands⟩ will write out VPL MAP fragments to a .vpl file, and the ⟨mapfonts⟩ will produce any MAPFONT instructions that are needed.

\typeset@glyph The \typeset@glyph macro takes a string expression and typesets that as the name of a glyph. Currently names of glyphs are formatted precisely the same as any other string expression.

700 ⟨doc⟩\let\typeset@glyph=\TypesetStringExpression
\width \height \depth \italic  \width{⟨glyph⟩}
 \height{⟨glyph⟩}
 \depth{⟨glyph⟩}
 \italic{⟨glyph⟩}

In fontinst, these macros return the width, height, depth, and italic correction of ⟨glyph⟩ as an integer.

701 ⟨∗pkg⟩

702 \def\width{\glyph_parameter\first_of_six}
703 \def\height{\glyph_parameter\second_of_six}
704 \def\depth{\glyph_parameter\third_of_six}
705 \def\italic{\glyph_parameter\fourth_of_six}

706 ⟨/pkg⟩

In fontdoc, they print symbolic representations for the corresponding integer expressions.

707 ⟨∗doc⟩

708 \DeclareRobustCommand\width[1]{\FD@glyph@metric{w}{#1}}
709 \DeclareRobustCommand\height[1]{\FD@glyph@metric{h}{#1}}
710 \DeclareRobustCommand\depth[1]{\FD@glyph@metric{d}{#1}}
711 \DeclareRobustCommand\italic[1]{\FD@glyph@metric{i}{#1}}

\FD@glyph@metric The \FD@glyph@metric macro is a convenient shorthand to use when defining integer-valued functions which represents some glyph metric (e.g. \height). Its syntax is

\FD@glyph@metric{⟨func-name⟩}{⟨string expression⟩}

The ⟨string expression⟩ must be expanded.

712 \def\FD@glyph@metric#1#2{%
713 \begingroup
714 \MakePrintable\@tempa{FD@swa}{#2}%
715 \protected@xdef\FD@expression{%
716  \protect\FD@integer@func{#1}{\@tempa}%

717 }%

718 \global\chardef\FD@priority=5%
719 \global\FD@bracket@level=\@ne
720 \FD@evaluate@false
721 \endgroup

722 } 723 ⟨/doc⟩

\mapcommands \mapfonts These are similar to \width and its companions, but they are not user level commands.

724 ⟨∗pkg⟩

725 \def\mapcommands{\glyph_parameter\fifth_of_six}
726 \def\mapfonts{\glyph_parameter\sixth_of_six}

727 ⟨/pkg⟩

\glyph_parameter \first_of_six \second_of_six \third_of_six \fourth_of_six \fifth_of_six \sixth_of_six \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.

728 ⟨∗pkg⟩

729 \def\glyph_parameter#1#2{
730 \expandafter\expandafter\expandafter
731  #1\csname g-#2\endcsname

732 }

733 \def\first_of_six#1#2#3#4#5#6{#1}
734 \def\second_of_six#1#2#3#4#5#6{#2}
735 \def\third_of_six#1#2#3#4#5#6{#3}
736 \def\fourth_of_six#1#2#3#4#5#6{#4}
737 \def\fifth_of_six#1#2#3#4#5#6{#5}
738 \def\sixth_of_six#1#2#3#4#5#6{#6}
739 \def\glyph_metrics#1#2#3#4#5#6{
740 \a_count=#1
741 \b_count=#2
742 \c_count=#3
743 \d_count=#4~

744 }

\saved_scale \saved_mapfont \saved_raw \saved_rule \saved_special \saved_warning \saved_movert \saved_moveup \saved_push \saved_pop These are the commands allowed inside a glyph. They are initally set to \relax,

so we can \edef with them safely.

745 \let\saved_scale\x_relax
746 \let\saved_mapfont\x_relax
747 \let\saved_raw\x_relax
748 \let\saved_rule\x_relax
749 \let\saved_special\x_relax
750 \let\saved_warning\x_relax
751 \let\saved_movert\x_relax
752 \let\saved_moveup\x_relax
753 \let\saved_push\x_relax
754 \let\saved_pop\x_relax

When the glyph is being constructed by

     \setglyph{⟨glyph⟩} ⟨glyph commands⟩ \endsetglyph

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 … \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).

\glyph_width
\glyph_height
\glyph_depth
\glyph_italic
\glyph_map_commands
\glyph_map_fonts
\glyph_voffset
\glyph_maxhpos

755 \newcount\glyph_width
756 \newcount\glyph_height
757 \newcount\glyph_depth
758 \newcount\glyph_italic
759 \newtoks\glyph_map_commands
760 \newtoks\glyph_map_fonts

761 \newcount\glyph_voffset
762 \newcount\glyph_maxhpos

\setglyph \gobble_glyph The \setglyph{⟨name⟩} command defines \g-⟨name⟩, unless \g-⟨name⟩ has al-

ready been defined.

The reason \g-⟨name⟩ is defined before calling \resetglyph is to make it possible to refer to “the glyph constructed so far” using \width{⟨name⟩}, \height{⟨name⟩}, etc.

763 \def\setglyph#1{
764 \ifisglyph{\glyph_name_modifier{#1}}\then
765  \expandafter\gobble_glyph
766 \else
767  \x_cs\def{g-\glyph_name_modifier{#1}}{
768  {\the\glyph_width}{\the\glyph_height}
769  {\the\glyph_depth}{\the\glyph_italic}
770  {\the\glyph_map_commands}{\the\glyph_map_fonts}

771 }

772  \resetglyph{\glyph_name_modifier{#1}}
773 \fi

774 }

775 \long\def\gobble_glyph#1\endsetglyph{}

776 ⟨/pkg⟩

777 ⟨∗doc⟩

778 \newcommand\setglyph[1]{%
779 \FD@tight@true
780 \Aheading{Set glyph `\typeset@glyph{#1}'}%

781 } 782 ⟨/doc⟩

783 ⟨misc⟩\long\def\setglyph#1\endsetglyph{}

LH 2003/01/05: A very useful trick, which unfortunately used to be undocumented, is to put kerning or variable assignment commands between \setglyph and the corresponding \endsetglyph. These commands will then only be executed if the glyph is being set by that \setglyph. Typical application: If Aacutesmall is being made by skrinking Aacute, then it is reasonable to make Aacutesmall kern like Aacute (modulo some scaling factor). If on the other hand Aacutesmall has already been set then there is less reason to believe Aacutesmall should kern like Aacute (a more probable guess is that it should kern like Asmall).

\resetglyph The \resetglyph{⟨name⟩} command redefines \g-⟨name⟩, regardless of whether \g-⟨name⟩ has already been defined.

784 ⟨∗pkg⟩

785 \def\resetglyph#1{
786 \edef\glyphname{#1}
787 \glyph_width=0
788 \global\glyph_height=0
789 \global\glyph_depth=0
790 \global\glyph_italic=0
791 \glyph_voffset=0
792 \global\glyph_maxhpos=0
793 \global\glyph_map_commands={}
794 \global\glyph_map_fonts={}

795 } 796 ⟨/pkg⟩

797 ⟨∗doc⟩

798 \newcommand\resetglyph[1]{%
799 \FD@tight@true
800 \Aheading{Reset glyph `\typeset@glyph{#1}'}}

801 ⟨/doc⟩

\endsetglyph
\endresetglyph

802 ⟨∗pkg⟩

803 \def\endsetglyph{
804 \x_cs\edef{g-\glyphname}
805  {{\the\glyph_width}{\the\glyph_height}
806  {\the\glyph_depth}{\the\glyph_italic}
807  {\the\glyph_map_commands}{\the\glyph_map_fonts}}

808 }

809 \let\endresetglyph=\endsetglyph

810 ⟨/pkg⟩

811 ⟨∗doc⟩

812 \let\endsetglyph=\FD@tight@false
813 \let\endresetglyph=\FD@tight@false

814 ⟨/doc⟩

\setscaledrawglyph \setrawglyph The \setscaledrawglyph has the syntax

\setscaledrawglyph{⟨glyph⟩}{⟨font⟩}{⟨design size⟩}{⟨scale⟩}{⟨slot⟩} {⟨width⟩}{⟨height⟩}{⟨depth⟩}{⟨italic⟩}

It is a generalized form of the old \setrawglyph command, which has the syntax

\setrawglyph{⟨glyph⟩}{⟨font⟩}{⟨design size⟩}{⟨slot⟩}{⟨width⟩}{⟨height⟩} {⟨depth⟩}{⟨italic⟩}

\setrawglyph is now syntactic sugar for the equivalent call of \setscaledraw-

glyph.

815 ⟨∗pkg⟩

816 \def\setrawglyph#1#2#3{
817 \setscaledrawglyph{#1}{#2}{#3}\one_thousand

818 }

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 \setscaledrawglyph, note that

     \setscaledrawglyph{fscaled}{xfont}{10pt}{800}{102}%
        {300}{600}{300}{40}

produces the same fscaled glyph as

     \setrawglyph{f}{xfont}{10pt}{102}{375}{750}{375}{50}
     \setglyph{fscaled}  \glyph{f}{800}  \endsetglyph
819 \def\setscaledrawglyph#1#2#3#4#5#6#7#8#9{
820 \if_undefined{g-\glyph_name_modifier{#1}}\then
821  \eval_expr{#4}

822  \ifnum \result=\one_thousand
823  \let\a_macro\identity_one
824  \else
825  \edef\a_macro##1{\saved_scale{\the\result}{##1}}
826  \fi
827  \eval_expr_to\a_count{#6}
828  \eval_expr_to\b_count{#7}
829  \eval_expr_to\c_count{#8}
830  \eval_expr_to\d_count{#9}
831  \ifisint{rawscale}\then
832  \e_count=\int{rawscale}
833  \multiply \a_count \e_count  \l_rounded_thousandths\a_count
834  \multiply \b_count \e_count  \l_rounded_thousandths\b_count
835  \multiply \c_count \e_count  \l_rounded_thousandths\c_count
836  \multiply \d_count \e_count  \l_rounded_thousandths\d_count
837  \edef\a_macro##1{\saved_scale{\the\e_count}{\a_macro{##1}}}
838  \fi
839  \x_cs\edef{g-\glyph_name_modifier{#1}}{
840  {\the\a_count}
841  {\the\b_count}
842  {\the\c_count}
843  {\the\d_count}
844  {\a_macro{\saved_raw{#2}{#5}{#1}}}
845  {\a_macro{\saved_mapfont{#2}{#3}}}

846 }

847 \fi

848 } 849 ⟨/pkg⟩

850 ⟨∗doc⟩

851 \newcommand\setrawglyph[8]{%
852 \Aheading{Glyph `\typeset@glyph{#1}'}
853 \Bheading{Taken from} slot $\TypesetIntegerExpression{#4}$ in
854 font \TypesetStringExpression{#2}%

855 }

856 \newcommand\setscaledrawglyph[9]{%
857 \Aheading{Glyph `\typeset@glyph{#1}'}
858 \Bheading{Taken from} slot $\TypesetIntegerExpression{#5}$ in
859 font \TypesetStringExpression{#2} \ConditionallyScaled{#4}%

860 } 861 ⟨/doc⟩

862 ⟨misc⟩\def\setrawglyph#1#2#3#4#5#6#7#8{}
863 ⟨misc⟩\def\setscaledrawglyph#1#2#3#4#5#6#7#8#9{}
\setscalednotglyph \setnotglyph The \setscalednotglyph command has the same syntax as the \setscaledraw-

glyph command, i.e.,

\setscalednotglyph{⟨glyph⟩}{⟨font⟩}{⟨design size⟩}{⟨scale⟩}{⟨slot⟩} {⟨width⟩}{⟨height⟩}{⟨depth⟩}{⟨italic⟩}

It is a generalized form of the old \setnotglyph command, which has the syntax

\setnotglyph{⟨glyph⟩}{⟨font⟩}{⟨design size⟩}{⟨slot⟩}{⟨width⟩}{⟨height⟩} {⟨depth⟩}{⟨italic⟩} \setnotglyph is now syntactic sugar for the equivalent call of \setscalednot-

 glyph.

864 ⟨∗pkg⟩

865 \def\setnotglyph#1#2#3{
866 \setscalednotglyph{#1}{#2}{#3}\one_thousand

867 }

Note that only the ⟨glyph⟩, ⟨width⟩, ⟨height⟩, ⟨depth⟩, and ⟨italic⟩ parameters are used. The reason for having the other parameters is that \setscalednotglyph commands can be converted to \setscaledrawglyph 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 ⟨mapcommands⟩ field of a -not-glyph should contain a \glyphwarning, just in case anyone tries to use one?

868 \def\setscalednotglyph#1#2#3#4#5#6#7#8#9{
869 \if_undefined{g-\glyph_name_modifier{#1}-not}\then
870  \eval_expr_to\a_count{#6}
871  \eval_expr_to\b_count{#7}
872  \eval_expr_to\c_count{#8}
873  \eval_expr_to\d_count{#9}
874  \ifisint{rawscale}\then
875  \e_count=\int{rawscale}
876  \multiply \a_count \e_count  \l_rounded_thousandths\a_count
877  \multiply \b_count \e_count  \l_rounded_thousandths\b_count
878  \multiply \c_count \e_count  \l_rounded_thousandths\c_count
879  \multiply \d_count \e_count  \l_rounded_thousandths\d_count
880  \fi
881  \x_cs\edef{g-\glyph_name_modifier{#1}-not}{
882  {\the\a_count}
883  {\the\b_count}
884  {\the\c_count}
885  {\the\d_count}
886  {}{}

887 }

888 \fi

889 } 890 ⟨/pkg⟩

891 ⟨∗doc⟩

892 \newcommand\setnotglyph[8]{%
893 \Aheading{Pseudoglyph `\typeset@glyph{#1-not}'}%

894 }

895 \newcommand\setscalednotglyph[9]{%
896 \setnotglyph{#1}{#2}{#3}{#5}{#6}{#7}{#8}{#9}%

897 } 898 ⟨/doc⟩

899 ⟨misc⟩\let\setnotglyph=\setrawglyph
900 ⟨misc⟩\let\setscalednotglyph=\setscaledrawglyph

\unsetglyph The \unsetglyph{⟨name⟩} command makes \g-⟨name⟩ undefined.

901 ⟨pkg⟩\def\unsetglyph#1{\x_cs\let{g-#1}\x_relax}
902 ⟨doc⟩\newcommand\unsetglyph[1]{%
903 ⟨doc⟩ \Aheading{Unset glyph `\typeset@glyph{#1}'}}

11.3 Glyph commands

The ⟨glyph commands⟩ are:

\glyph  \glyph{⟨glyph⟩}{⟨scale⟩}

904 ⟨∗pkg⟩

905 \def\glyph#1#2{
906 \glyph_parameter\glyph_metrics{#1}
907 \eval_expr_to\e_count{#2}
908 \ifnum \e_count=\one_thousand
909  \edef\a_macro{\mapcommands{#1}}
910  \global\glyph_map_commands\expandafter{
911  \the\expandafter\glyph_map_commands \a_macro

912 }

913  \edef\a_macro{\mapfonts{#1}}
914 \else
915  \multiply \a_count \e_count  \l_rounded_thousandths\a_count
916  \multiply \b_count \e_count  \l_rounded_thousandths\b_count
917  \multiply \c_count \e_count  \l_rounded_thousandths\c_count
918  \multiply \d_count \e_count  \l_rounded_thousandths\d_count
919  \edef\a_macro{\saved_scale{\the\e_count}{\mapcommands{#1}}}
920  \global\glyph_map_commands\expandafter{
921  \the\expandafter\glyph_map_commands \a_macro

922 }

923  \edef\a_macro{\saved_scale{\the\e_count}{\mapfonts{#1}}}
924 \fi
925 \advance \glyph_width \a_count
926 \advance \b_count \glyph_voffset
927 \ifnum \glyph_height<\b_count \global\glyph_height=\b_count \fi
928 \advance \c_count -\glyph_voffset
929 \ifnum \glyph_depth<\c_count \global\glyph_depth=\c_count \fi
930 \global\glyph_italic=\d_count
931 \global\glyph_map_fonts\expandafter{
932  \the\expandafter\glyph_map_fonts \a_macro

933 } 934 } 935 ⟨/pkg⟩

936 ⟨∗doc⟩

937 \newcommand\glyph[2]{%
938 \Bheading{Glyph} `\typeset@glyph{#1}' \ConditionallyScaled{#2}%

939 } 940 ⟨/doc⟩

\glyphrule  \glyphrule{⟨width⟩}{⟨height⟩}

941 ⟨∗pkg⟩

942 \def\glyphrule#1#2{
943 \eval_expr_to\b_count{#1} \eval_expr_to\c_count{#2}
944 \advance\glyph_width by \b_count
945 \g_eval_expr_to\glyph_depth{\max\glyph_depth{-\glyph_voffset}}
946 \g_eval_expr_to\glyph_height{
947  \max\glyph_height{\add\glyph_voffset\c_count}

948 }

949 \global\glyph_italic=0
950 \edef\a_macro{\saved_rule{\the\b_count}{\the\c_count}}

951 \global\glyph_map_commands\expandafter{
952  \the\expandafter\glyph_map_commands \a_macro

953 } 954 } 955 ⟨/pkg⟩

956 ⟨∗doc⟩

957 \newcommand\glyphrule[2]{%
958 \Bheading{Rule} $\TypesetIntegerExpression{#1}$ by
959 $\TypesetIntegerExpression{#2}$%

960 } 961 ⟨/doc⟩

\glyphspecial \glyphwarning  \glyphspecial{⟨string⟩}
 \glyphwarning{⟨string⟩}

962 ⟨∗pkg⟩

963 \def\glyphspecial#1{
964 \edef\a_macro{\saved_special{#1}}
965 \global\glyph_map_commands\expandafter{
966  \the\expandafter\glyph_map_commands \a_macro

967 } 968 }

969 \def\glyphwarning#1{
970 \edef\a_macro{\saved_warning{#1}}
971 \global\glyph_map_commands\expandafter{
972  \the\expandafter\glyph_map_commands \a_macro

973 } 974 } 975 ⟨/pkg⟩

976 ⟨∗doc⟩

977 \newcommand\glyphspecial[1]{%
978 \Bheading{Special} `\TypesetStringExpression{#1}'}
979 \newcommand\glyphwarning[1]{%
980 \Bheading{Warning} `\TypesetStringExpression{#1}'}

981 ⟨/doc⟩

\movert \moveup  \movert{⟨xoffset⟩}
 \moveup{⟨yoffset⟩}

982 ⟨∗pkg⟩

983 \def\movert#1{
984 \eval_expr{#1}
985 \ifnum \glyph_maxhpos<\glyph_width
986  \global\glyph_maxhpos\glyph_width
987 \fi
988 \ifnum 0=\result \else
989  \advance\glyph_width by \result
990  \edef\a_macro{\saved_movert{\the\result}}
991  \global\glyph_map_commands\expandafter{
992  \the\expandafter\glyph_map_commands \a_macro

993 }

994 \fi

995 }

996 \def\moveup#1{

 997 \eval_expr{#1}
 998 \ifnum\result=0\else
 999  \advance\glyph_voffset by \result
1000  \edef\a_macro{\saved_moveup{\the\result}}
1001  \global\glyph_map_commands\expandafter{
1002  \the\expandafter\glyph_map_commands \a_macro

1003 } 1004 \fi 1005 } 1006 ⟨/pkg⟩

1007 ⟨∗doc⟩

1008 \newcommand\movert[1]{\Bheading{Rt}~$\TypesetIntegerExpression{#1}$}
1009 \newcommand\moveup[1]{\Bheading{Up}~$\TypesetIntegerExpression{#1}$}

1010 ⟨/doc⟩

{\push \atop \pop}

1011 ⟨∗pkg⟩

1012 \def\push{
1013 \bgroup
1014 \global\glyph_map_commands\expandafter{
1015  \the\glyph_map_commands \saved_push

1016 } 1017 }

1018 \def\pop{
1019 \ifnum \glyph_maxhpos<\glyph_width
1020  \global\glyph_maxhpos\glyph_width

1021 \fi

1022 \egroup
1023 \global\glyph_map_commands\expandafter{
1024  \the\glyph_map_commands \saved_pop

1025 } 1026 } 1027 ⟨/pkg⟩

1028 ⟨∗doc⟩

1029 \newcommand\push{\Bheading{Push}}
1030 \newcommand\pop{\Bheading{Pop}}

1031 ⟨/doc⟩

\resetwidth \resetheight \resetdepth \resetitalic  \resetwidth{⟨width⟩}
  \resetheight{⟨height⟩}
  \resetdepth{⟨depth⟩}
  \resetitalic{⟨italic⟩}

1032 ⟨∗pkg⟩

1033 \def\resetwidth#1{\movert{\sub{#1}\glyph_width}}
1034 \def\resetheight{\g_eval_expr_to\glyph_height}
1035 \def\resetdepth{\g_eval_expr_to\glyph_depth}
1036 \def\resetitalic{\g_eval_expr_to\glyph_italic}

1037 ⟨/pkg⟩

1038 ⟨∗doc⟩

1039 \newcommand\resetwidth[1]{%
1040 \Bheading{Reset width to $\TypesetIntegerExpression{#1}$}%

1041 }

1042 \newcommand\resetheight[1]{%
1043 \Bheading{Reset height to $\TypesetIntegerExpression{#1}$}%

1044 }

1045 \newcommand\resetdepth[1]{%
1046 \Bheading{Reset depth to $\TypesetIntegerExpression{#1}$}%

1047 }

1048 \newcommand\resetitalic[1]{%
1049 \Bheading{Reset italic to $\TypesetIntegerExpression{#1}$}%

1050 } 1051 ⟨/doc⟩

\glyphpcc Some syntactic sugar: \glyphpcc could do with optimization.

\glyphpcc{⟨glyph⟩}{⟨xoffset⟩}{⟨yoffset⟩}

1052 ⟨∗pkg⟩

1053 \def\glyphpcc#1#2#3{
1054 \ifisglyph{\glyph_name_modifier{#1}}\then
1055  \push
1056  \movert{#2}
1057  \moveup{#3}
1058  \glyph{\glyph_name_modifier{#1}}{\one_thousand}
1059  \pop
1060 \else
1061  \fontinsterror{\string\glyphpcc}{
1062  Base~glyph~not~set.\messagebreak
1063  This~could~be~a~sign~that~the~AFM~file~is~buggy
1064  }\error_help_a

1065 \fi 1066 } 1067 ⟨/pkg⟩

1068 ⟨∗doc⟩

1069 \def\glyphpcc#1#2#3{
1070 \push
1071  \movert{#2}
1072  \moveup{#3}
1073  \glyph{#1}{1000}
1074 \pop

1075 } 1076 ⟨/doc⟩

\glyphbboxright The \glyphbboxright command is a valid integer expression, but its value

  is only meaningful inside a \setglyph . . . \endsetglyph or \resetglyph . . .

\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.

1077 ⟨pkg⟩\def\glyphbboxright{\max\glyph_width\glyph_maxhpos}

1078 ⟨∗doc⟩

1079 \DeclareRobustCommand\glyphbboxright{%
1080 \gdef\FD@expression{\protect\mathrm{glyphbboxright}}
1081 \global\chardef\FD@priority=\tw@
1082 \global\FD@bracket@level=\z@
1083 \FD@evaluate@false

1085 ⟨/doc⟩

\samesize  \samesize{⟨glyph⟩}

1086 ⟨∗pkg⟩

1087 \def\samesize#1{
1088 \if_undefined{g-\glyph_name_modifier{#1}}\then
1089  \resetwidth{\glyphbboxright}
1090 \else
1091  \expandafter\expandafter\expandafter
1092  \same_size\csname g-\glyph_name_modifier{#1}\endcsname

1093 \fi 1094 }

1095 \def\same_size#1#2#3#4#5#6{
1096 \movert{\sub{#1}\glyph_width}
1097 \global\glyph_height=#2
1098 \global\glyph_depth=#3
1099 \global\glyph_italic=#4

1100 } 1101 ⟨/pkg⟩

1102 ⟨∗doc⟩

1103 \newcommand\samesize[1]{%
1104 \Bheading{Reset dimensions to those of `\typeset@glyph{#1}'.}%

1105 } 1106 ⟨/doc⟩

\ifisglyph The control flow command:

1107 ⟨pkg⟩\def\ifisglyph#1\then{\if_defined{g-#1}\then}

\ifisglyph evaluates to false in ⟨misc⟩, since this avoids uses of various metric integer expressions (such as \width, \height, etc.) that are not defined there.

1108 ⟨doc⟩\def\ifisglyph#1\then{\generic@if{glyph \typeset@glyph{#1} set}}
1109 ⟨misc⟩\def\ifisglyph#1\then{\iffalse}

\ifareglyphs The \ifareglyphs command test if all glyphs in a comma-separeted list of glyphs are set. The syntax is

      \ifareglyphs{⟨glyph list⟩}\then

The implementation relies on that \if_true and \if_false do not count when TEX is skipping text that is balanced with respect to \ifs and \fis.

1110 ⟨∗pkg⟩

1111 \def\ifareglyphs#1\then{
1112 \process_csep_list{\if_is_glyph}#1,\process_csep_list,
1113 \if_true

1114 }

1115 \def\if_is_glyph#1{
1116 \if_undefined{g-#1}\then \expandafter\if_false \fi

1117 } 1118 ⟨/pkg⟩

1119 ⟨misc⟩\let\ifareglyphs=\ifisglyph

1120 ⟨∗doc⟩

1121 \def\ifareglyphs#1\then{%
1122 \generic@if{all glyphs in \FD@typeset@string@set{#1} are set}%

1124 ⟨/doc⟩

12 Converting an ETX file to a (V)PL file

12.1 Lowest-level user interface

\etxtovpl The macro:

\etxtovpl{⟨encoding list⟩}{⟨vplfile⟩}

writes a virtual font (as a virtual property list) with the encoding specified by the items in the ⟨encoding list⟩, which typically are names of ETX files. (This macro

  is called by \installfont.)

\etxtopl The macro:

\etxtopl{⟨encoding list⟩}{⟨plfile⟩}

writes a font (as a property list) with the encoding specified by the items in the ⟨encoding list⟩, which typically are names of ETX files. (This macro is called by

  \installrawfont.)
\etxtovpl \etxtopl

1125 ⟨∗pkg⟩

1126 \def\etxtovpl#1#2{{
1127 \def\vpl_extension{vpl}
1128 \def\vpl_title{COMMENT}
1129 \def\vpl_font{virtual~font}
1130 \def\vpl_Font{Virtual~font}
1131 \def\vpl_call{\string\etxtovpl{#1}{#2}}
1132 \def\vpl_to_vf##1{vptovf~##1.vpl~##1.vf~##1.tfm}
1133 \a_toks={}
1134 \process_csep_list\make_inputetx #1,\process_csep_list,
1135 \expandafter\etx_to_font \expandafter{\the\a_toks}{#2}

1136 }}

1137 \def\etxtopl#1#2{{
1138 \def\vpl_extension{pl}
1139 \def\vpl_title{COMMENT}
1140 \def\vpl_font{font}
1141 \def\vpl_Font{Font}
1142 \def\vpl_call{\string\etxtopl{#1}{#2}}
1143 \def\vpl_to_vf##1{pltotf~##1.pl~##1.tfm}
1144 \_including_map_false
1145 \global\rawfont_scaling=-\p@
1146 \a_toks={}
1147 \process_csep_list\make_inputetx #1,\process_csep_list,
1148 \expandafter\etx_to_font \expandafter{\the\a_toks}{#2}

1149 }}

_including_map_switch The v 1.5 method of controlling whether MAP and 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, MAP and 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).

1150 \newif\if_including_map_
1151 \_including_map_true

\make_inputetx The \make_inputetx macro takes a single argument that should have the form

⟨file name root⟩⟨optional modifiers⟩

as explained in the comments to \input_mtx_file. The effect of this macro is to append some commands (usually \inputetx{⟨file name root⟩}) to \a_toks. This may however change if some clause in the ⟨optional modifiers⟩ redefines \a_macro.

1152 \def\make_inputetx#1{
1153 \def\a_macro{\noexpand\inputetx{\file_name}}
1154 \get_file_name #1~{}~\par
1155 \edef\a_macro{\a_macro}
1156 \a_toks=\expandafter{ \the\expandafter\a_toks \a_macro}

1157 }

\IFKW-mtxasetx The mtxasetx modifier clause causes the ⟨encoding list⟩ item in question to be input using \input_mtx_as_etx rather than \inputetx. This makes it possible

  to use the \setrawglyph and \setscaledrawglyph commands in an MTX file

as a poor substitute for a proper ETX file. This is sometimes useful for making proofs.

1158 \x_cs\def{IFKW-mtxasetx}{
1159 \def\a_macro{\noexpand\input_mtx_as_etx{\file_name}}
1160 \get_keyword

1161 }

\etx_to_font \etx_to_font{⟨encoding commands⟩}{⟨fontfile⟩} makes a (V)PL file whose encoding is specified by the ⟨encoding commands⟩. These are usually just one or a few \inputetx commands, as the specification of an encoding usually requires much more code than is convenient to provide as an argument.

1162 \def\etx_to_font#1#2{
1163 \make_assignments{#1}
1164 \open_out{#2.\vpl_extension}
1165 \top_of_pl_hook
1166 \out_line{(\vpl_title\space\vpl_font\space
1167  #2~created~by~fontinst~v\fontinstversion)}
1168 \out_line{}
1169 \out_line{(COMMENT~Filename:~#2.\vpl_extension)}
1170 \out_line{(COMMENT~Created~by:~tex~\jobname)}
1171 \out_line{(COMMENT~Created~using:~\vpl_call)}
1172 \out_line{}
1173 \out_line{(COMMENT~This~file~can~be~turned~into~a~\vpl_font\space
1174  with)}
1175 \out_line{(COMMENT~\vpl_to_vf{#2})}
1176 \out_line{}
1177 \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
1178 \out_line{}
1179 \make_header{#1}
1180 \if_including_map_\make_mapfonts{#1} \fi

1181 \make_fontdimens{#1}
1182 \make_ligtable{#1}
1183 \make_characters{#1}
1184 \make_tidy{#1}
1185 \out_line{}
1186 \out_line{(COMMENT~END~OF~FILE~#2.\vpl_extension)}
1187 \close_out{\vpl_Font}

1188 }

\pre_first_etx_pass_hook \pre_second_etx_pass_hook \pre_third_etx_pass_hook \pre_fourth_etx_pass_hook \post_first_etx_pass_hook \post_second_etx_pass_hook \post_third_etx_pass_hook \post_fourth_etx_pass_hook \tidying_up_hook \top_of_pl_hook As the \etxtovpl and \etxtopl macros are the lowest-level interfaces to what

they do that are available in 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:

1189 \let\pre_first_etx_pass_hook\x_relax
1190 \let\pre_second_etx_pass_hook\x_relax
1191 \let\pre_third_etx_pass_hook\x_relax
1192 \let\pre_fourth_etx_pass_hook\x_relax
1193 \let\post_first_etx_pass_hook\x_relax
1194 \let\post_second_etx_pass_hook\x_relax
1195 \let\post_third_etx_pass_hook\x_relax
1196 \let\post_fourth_etx_pass_hook\x_relax
1197 \let\tidying_up_hook\x_relax
1198 \let\top_of_pl_hook\x_relax

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

     \add_to\pre_first_etx_pass_hook{⟨extra code⟩}

I (LH) have the following in my fontinst.rc file

     \add_to\top_of_pl_hook{\out_line{(COMMENT~-*-Text-*-)}}

Without it, my text editor annoys me by assuming that .pl stands for Perl.

12.2 Glyph to slot assignments

The way 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 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 fontinst has therefore been reimplemented.

The new implementation does not use integers, instead it uses a new family

\slots-⟨glyph⟩ of macros with names on the form \slots-⟨glyph⟩. These macros expand to sequences of \do ⟨character⟩, where ⟨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.

As it turned out to not be such a big deal, some extra code (protected by a docstrip switch called ⟨boundaryCompability⟩) that makes fontinst compatible with the previous syntax for boundary handling has been included. I don’t recommend using it though, since it makes fontinst store almost all slot numbers in two places.

\make_assignments
1199 \def\make_assignments#1{
1200 \let\do_slot=\assign_slot
1201 \let\end_do_slot=\end_assign_slot
1202 \def\do_boundary{\bgroup
1203  \let\makerightboundary=\bad_makerightboundary

1204 }

1205 \let\endsetleftboundary=\egroup
1206 \let\makerightboundary=\assign_rboundary
1207 \pre_first_etx_pass_hook

1208 #1

1209 \post_first_etx_pass_hook
1210 \let\end_do_slot=\empty_command
1211 \let\do_boundary=\x_relax
1212 \let\endsetleftboundary=\x_relax
1213 \let\makerightboundary=\gobble_one

1214 }

\assign_slot \end_assign_slot  \assign_slot begins the assignment of a slot to a glyph. \end_assign_slot com-

pletes 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.

1215 \def\assign_slot{\a_toks={\do}}
1216 \begingroup
1217 \catcode0=12
1218 \gdef\end_assign_slot{
1219  \ifisglyph\slot_name\then
1220  \lccode0=\slot_number
1221  \lowercase{
1222  \expandafter\add_to
1223  \csname slots-\slot_name\expandafter\endcsname

1224  \expandafter{\the\a_toks^^@}

1225 }

1226 ⟨boundaryCompability⟩  \x_resetint\slot_name\slot_number

1227 \fi 1228 }

\assign_rboundary \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.
1229 \gdef\assign_rboundary#1{
1230  \lccode0=\slot_number
1231  \lowercase{\x_cs\add_to{slots-#1}{\rboundary_do^^@}}
1232  \x_setint{\percent_char boundarychar}\slot_number
1233  \a_toks={\rbserver_do}

1234 }

1235 \endgroup
1236 \def\bad_makerightboundary#1{
1237 \errhelp={The~left~boundary~is~not~a~slot,~so~it~cannot~serve~
1238  as~right~boundary.}
1239 \errmessage{Incorrect~use~of~\string\makerightboundary}

1240 }

\get_slot_num 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

      \get_slot_num{⟨glyph⟩}

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.

1241 \def\get_slot_num#1{

1242 ⟨∗!boundaryCompability⟩

1243 \global\result=-1
1244 \bgroup
1245  \def\do{\global\result=`}
1246  \let\rbserver_do=\do
1247  \let\rboundary_do=\gobble_one
1248  \csname slots-#1\endcsname
1249 \egroup

1250 ⟨/!boundaryCompability⟩ 1251 ⟨∗boundaryCompability⟩

1252 \ifisint{#1}\then
1253  \global\result=\int{#1}
1254 \else
1255  \global\result=-1

1256 \fi

1257 \x_relax

1258 ⟨/boundaryCompability⟩ 1259 }

\ifisinslot The call \ifisinslot{⟨glyph⟩}{⟨slot⟩}\then can be used to test whether glyph ⟨glyph⟩ has been assigned to slot ⟨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.

1260 \def\ifisinslot#1#2\then{
1261 \ifx \makerightboundary\gobble_one

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.

1262  \eval_expr{#2}
1263  \begingroup
1264  \def\do##1{\ifnum `##1=\result \let\do=\gobble_one \fi}
1265  \def\rbserver_do{\do}
1266  \let\rboundary_do=\gobble_one
1267  \csname slots-#1\endcsname
1268  \expandafter\endgroup
1269  \ifx \do\gobble_one
1270  \expandafter\expandafter \expandafter\if_true
1271  \else
1272  \expandafter\expandafter \expandafter\if_false

1273 \fi

1274 \else
1275  \expandafter\gobble_if

1276 \fi 1277 } 1278 ⟨/pkg⟩

1279 ⟨∗doc⟩

1280 \def\ifisinslot#1#2\then{%
1281 \generic@if{glyph \typeset@glyph{#1} assigned to slot
1282 $\TypesetIntegerExpression{#2}$}%

1283 } 1284 ⟨/doc⟩

12.3 The header, mapfonts, and fontdimens

\mapfont_scaling The \mapfont_scaling dimen is used for calculating how much a mapfont has been scaled, for use in FONTAT properties, and for selecting the correct mapfont. It is initialized to 1.

1285 ⟨∗pkg⟩

1286 \newdimen\mapfont_scaling
1287 \mapfont_scaling=1pt

\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 \installrawfont—out to that macro. \rawfont_scaling should always be globally assigned.

1288 \newdimen\rawfont_scaling
\scaled_design_size \afm_convert The call

\afm_convert⟨dimen⟩=⟨integer expression⟩;

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.

1289 % \newdimen\scaled_design_size

1290 % \def\afm_convert#1=#2;{
1291 %    \eval_expr{#2}
1292 %    #1=\scaled_design_size
1293 %    \divide#1 by 8
1294 %    \multiply #1 by \result
1295 %    \divide #1 by \one_thousand
1296 %    \multiply#1 by 8

1297 % }

\vpl_real \vpl_int The commands \vpl_real⟨dimen⟩ and \vpl_int⟨count⟩ print a dimension and integer respectively in (V)PL syntax.

1298 \def\vpl_real#1{R~\expandafter\lose_measure\the#1}
1299 \def\vpl_int#1{D~\the#1}

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.

\side_bearings \curr_bearings These two dimens are used by the letterspacing mechanism.

1300 \newdimen\side_bearings
1301 \newdimen\curr_bearings
\make_header
1302 \def\make_header#1{
1303 \global\font_count=0
1304 \setdim{designsize}{10pt}
1305 \a_dimen=\dim{designsize}
1306 \out_line{(DESIGNSIZE~\vpl_real\a_dimen)}
1307 \x_setstr{codingscheme}{UNKNOWN}
1308 \out_line{(CODINGSCHEME~\str{codingscheme})}

1309 ⟨∗boundaryCompability⟩

1310 \ifisint{boundarychar}\then
1311  \x_setint{\percent_char boundarychar}{\int{boundarychar}}
1312  \immediate\write16{Please~use~\string\setleftboundary\space
1313  and/or~\string\makerightboundary^^J
1314  instead~of~setting~the~boundarychar~integer.}

1315 \fi 1316 ⟨/boundaryCompability⟩

1317 \ifisint{\percent_char boundarychar}\then
1318  \a_count=\int{\percent_char boundarychar}
1319  \out_line{(BOUNDARYCHAR~\vpl_int\a_count)}

1320 \fi

1321 \x_setint{letterspacing}{0}
1322 \side_bearings=\make_factor{\int{letterspacing}}\half_point
1323 \x_setint{minimumkern}{0}
1324 \minimum_kern=\int{minimumkern}
1325 \out_line{}

1326 }

\make_mapfonts

1327 \def\make_mapfonts#1{
1328 \let\saved_scale\vpl_scale
1329 \let\saved_mapfont\vpl_mapfont
1330 \let\do_slot=\do_mapfont
1331 \pre_second_etx_pass_hook

1332 #1

1333 \post_second_etx_pass_hook
1334 \out_line{}

1335 }

\do_mapfont  \do_mapfont produces a MAPFONT entry for each font used by glyph \slot_name.
1336 \def\do_mapfont{
1337 \ifisglyph\slot_name\then
1338  \mapfonts\slot_name

1339 \fi 1340 }

The following commands can be used in the ⟨mapfonts⟩ glyph parameter.

\vpl_scale
1341 \def\vpl_scale#1#2{{
1342 \mapfont_scaling=\make_factor{#1}\mapfont_scaling

1343 #2 1344 }}

\vpl_mapfont
1345 \def\vpl_mapfont#1#2{
1346 \a_dimen=#2
1347 \if_undefined{\the\mapfont_scaling-#1}\then
1348  \global\x_cs\mathchardef{\the\mapfont_scaling-#1}=\font_count
1349  \x_cs\xdef{f-\the\font_count}{\the\mapfont_scaling-#1}
1350  \out_line{(MAPFONT~\vpl_int\font_count\space
1351  (FONTNAME~#1)~
1352  (FONTDSIZE~\vpl_real\a_dimen)~
1353  (FONTAT~\vpl_real\mapfont_scaling))}
1354  \record_usage{#1}
1355  \global\advance\font_count by 1

1356 \fi 1357 }

\pl_mapfont As PL files have no 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 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.

1358 \def\pl_mapfont#1#2{\global\rawfont_scaling=\mapfont_scaling}

\font_count
\next_mapfont
\prev_mapfont

1359 \newcount\font_count
1360 \newcount\next_mapfont
1361 \newcount\prev_mapfont

\make_fontdimens This macro writes the FONTDIMEN property list. Note that there is a difference between fontdimen 1 and the others, in that fontdimen 1 is always in pt, not in the atsize-relative 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.

1362 \def\make_fontdimens#1{
1363 \out_line{(FONTDIMEN}
1364  \a_count=1
1365  \loop\ifnum 256>\a_count
1366  \ifisint{fontdimen(\the\a_count)}\then
1367  \out_lline{(PARAMETER~\vpl_int\a_count\space
1368  R~\make_factor{\int{fontdimen(\the\a_count)}})}

1369 \fi

1370  \advance \a_count \@ne
1371  \repeat
1372 \out_lline{)}
1373 \out_line{}

1374 }

12.4 The ligtable

\make_ligtable
1375 \def\make_ligtable#1{
1376 \begingroup
1377  \out_line{(LIGTABLE}

1378 ⟨!boundaryCompability⟩ \let\do_slot=\bgroup 1379 ⟨∗boundaryCompability⟩

1380  \def\do_slot{\bgroup
1381  \ifisint{boundarychar}\then
1382  \ifnum \int{boundarychar}=\slot_number
1383  \def\vpl_liglabel{\out_liglabel\boundary_liglabel}

1384 \fi 1385 \fi 1386 } 1387 ⟨/boundaryCompability⟩

1388  \let\end_do_slot=\vpl_kerning
1389  \def\do_boundary{\bgroup \let\vpl_liglabel=\boundary_liglabel}
1390  \let\endsetleftboundary=\vpl_kerning
1391  \let\ligature=\vpl_ligature
1392  \let\k=\vpl_kern
1393  \let\rbserver_do=\vpl_rbserver_do
1394  \let\rboundary_do=\vpl_rboundary_do
1395  \pre_third_etx_pass_hook

1396 #1

1397  \post_third_etx_pass_hook
1398  \out_lline{)}
1399 \endgroup
1400 \out_line{}

\vpl_rbserver_do \vpl_rboundary_do \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.

1402 \def\vpl_rbserver_do#1{
1403 \do{#1}
1404 \let\rboundary_do=\wrn_rboundary_do

1405 }

1406 \def\vpl_rboundary_do#1{
1407 \do{#1}
1408 \let\rbserver_do=\wrn_rboundary_do

1409 }

1410 \def\wrn_rboundary_do#1{
1411 \do{#1}
1412 \immediate\write16{Boundarychar~slot~usage~collision~in~
1413  `\slot_name'~ligkern~program.}

1414 }

\vpl_ligature \vpl_ligature{⟨type⟩}{⟨glyph⟩}{⟨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.

1415 \def\vpl_ligature#1#2#3{
1416 \get_slot_num{#3}
1417 \ifnum -1=\result
1418  \immediate\write16{Warning:~\string\ligature\space
1419  for~unknown~slot~`#3'.}
1420 \else
1421  \x_cs\ifx{slots-#2}\x_relax
1422  \immediate\write16{Warning:~\string\ligature\space
1423  for~unknown~slot~`#2'.}
1424  \else
1425  \def\do##1{
1426  \vpl_liglabel
1427  \out_lline{(#1~D~\number`##1~\space\vpl_int\result)~
1428  (COMMENT~#2~#3)}

1429 }

1430  \csname slots-#2\endcsname

1431 \fi 1432 \fi 1433 }

\vpl_kerning \vpl_kerning writes out kerning instructions.

1434 \def\vpl_kerning{
1435 \let\do=\vpl_kern_do
1436 \csname~r-\slot_name\endcsname
1437 \vpl_ligstop
1438 \egroup

1439 }

\vpl_kern \vpl_kern\l-⟨name⟩ \⟨amount⟩ writes out a KRN instruction.

\vpl_kern has been modified so that at most one KRN instruction is written for each (ordered) pair of characters. The idea is basically to make 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 KRN instructions for that particular glyph from being written. \vpl_kern has also been modified so that it will not write out any 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

minimumkern in \make_header. If the user has not set minimumkern, a default

value of 0 will be supplied by fontinst.

1440 \def\vpl_kern#1#2{
1441 \edef\a_macro{\expandafter\gobble_three\string#1}
1442 \a_count=\expandafter\gobble_one\string#2\x_relax
1443 \ifnum \ifnum -\a_count>\a_count - \fi\a_count>\minimum_kern
1444  \edef\b_macro{~R~\make_factor\a_count}
1445  \csname slots-\a_macro\endcsname

1446 \fi

1447 \x_cs\let{slots-\a_macro}=\x_relax

1448 }

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).

\vpl_kern_do \vpl_kern_do is what \do is defined to be when kerns are written.

1449 \def\vpl_kern_do#1{
1450 \vpl_liglabel
1451 \out_lline{
1452  (KRN~D~\number`#1~\b_macro)~
1453  (COMMENT~\a_macro)

1454 } 1455 }

\out_liglabel \boundary_liglabel \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.

1456 \def\out_liglabel{
1457 \out_lline{(LABEL~\vpl_int\slot_number)~(COMMENT~\slot_name)}
1458 \let\vpl_liglabel=\x_relax
1459 \let\vpl_ligstop=\out_ligstop

1460 }

1461 \def\boundary_liglabel{
1462 \out_lline{(LABEL~BOUNDARYCHAR)~(COMMENT~\slot_name)}
1463 \let\vpl_liglabel=\x_relax
1464 \let\vpl_ligstop=\out_ligstop

1465 }

1466 \let\vpl_liglabel=\out_liglabel

\out_ligstop \vpl_ligstop  \vpl_ligstop writes out a LIGSTOP instruction if appropriate.
1467 \def\out_ligstop{\out_lline{(STOP)}
1468 \let\vpl_liglabel=\out_liglabel
1469 \let\vpl_ligstop=\x_relax}
1470 \let\vpl_ligstop=\x_relax

12.5 The characters

\make_characters
1471 \def\make_characters#1{
1472 \bgroup
1473  \let\do_slot=\do_character
1474  \let\end_do_slot=\end_do_character
1475  \let\nextlarger=\vpl_nextlarger
1476  \let\varchar=\vpl_varchar
1477  \let\endvarchar=\end_vpl_varchar
1478  \let\vartop=\vpl_vartop
1479  \let\varmid=\vpl_varmid
1480  \let\varbot=\vpl_varbot
1481  \let\varrep=\vpl_varrep
1482  \if_including_map_
1483  \let\saved_raw\vpl_raw
1484  \let\saved_rule\vpl_rule
1485  \let\saved_special\vpl_special
1486  \let\saved_warning\vpl_warning
1487  \let\saved_movert\vpl_movert
1488  \let\saved_moveup\vpl_moveup
1489  \let\saved_push\vpl_push
1490  \let\saved_pop\vpl_pop
1491  \else
1492  \def\do_character_map{
1493  \ifdim \rawfont_scaling=-\p@
1494  \mapfonts\slot_name
1495  \else
1496  \let\do_character_map=\x_relax

1497 \fi 1498 }

1499  \let\saved_mapfont\pl_mapfont
1500  \let\saved_scale\vpl_scale

1501 \fi

1502  \pre_fourth_etx_pass_hook

1503 #1

1504  \post_fourth_etx_pass_hook
1505 \egroup

1506 }

\do_character  \do_character produces a character entry for glyph \slot_name in slot \slot_number.
1507 \def\do_character{
1508 \if_undefined{g-\slot_name}\then
1509  \ifisint{requireglyphs}\then
1510  \fontinstwarning{ETX~to~(V)PL}{
1511  Undefined~glyph~`\slot_name'~requested\message_break
1512  for~slot~\the\slot_number\message_number}

1513 \fi

1514  \expandafter\gobble_setslot
1515 \else
1516  \ifx\slot_name\notdef_name\else
1517  \out_line{(CHARACTER~\vpl_int\slot_number\space
1518  (COMMENT~\slot_name)}
1519  \glyph_parameter\glyph_metrics\slot_name
1520  \a_dimen=\make_factor\a_count \p@
1521  \do_character_sidebearings
1522  \out_lline{(CHARWD~\vpl_real\a_dimen)}
1523  \ifnum \z@=\b_count \else
1524  \out_lline{(CHARHT~R~\make_factor\b_count)}

1525 \fi

1526  \ifnum \z@=\c_count \else
1527  \out_lline{(CHARDP~R~\make_factor\c_count)}

1528 \fi

1529  \ifnum \z@=\d_count \else
1530  \out_lline{(CHARIC~R~\make_factor\d_count)}

1531 \fi

1532  \do_character_map

1533 \fi 1534 \fi 1535 }

\do_character_sidebearings
1536 \def\do_character_sidebearings{
1537 \ifisint{\slot_name-spacing}\then
1538  \curr_bearings=\make_factor{\int{\slot_name-spacing}}\half_point
1539 \else
1540  \curr_bearings=\side_bearings

1541 \fi

1542 \advance\a_dimen by 2\curr_bearings

1543 }

\do_character_map
1544 \def\do_character_map{
1545 \global\prev_mapfont=0
1546 \out_lline{(MAP}
1547 \ifdim 0pt=\curr_bearings
1548  \mapcommands\slot_name
1549 \else
1550  \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}
1551  \mapcommands\slot_name
1552  \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)}

1553 \fi

1554 \out_llline{)}

1555 }

\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.

1556 ⟨∗obsolete⟩

1557 % \def\do_character_no_letterspacing{
1558 %    \x_cs\ifx{g-\slot_name}\x_relax
1559 %       \expandafter\gobble_setslot
1560 %    \else
1561 %       \ifx\slot_name\notdef_name\else
1562 %          \out_line{(CHARACTER~\vpl_int\slot_number\space
1563 %             (COMMENT~\slot_name)}
1564 %          \afm_convert\a_dimen=\width\slot_name;
1565 %          \out_lline{(CHARWD~\vpl_real\a_dimen)}
1566 %          \afm_convert\a_dimen=\height\slot_name;
1567 %          \out_lline{(CHARHT~\vpl_real\a_dimen)}
1568 %          \afm_convert\a_dimen=\depth\slot_name;
1569 %          \out_lline{(CHARDP~\vpl_real\a_dimen)}
1570 %          \afm_convert\a_dimen=\italic\slot_name;
1571 %          \ifnum\a_dimen>0 \out_lline{(CHARIC~\vpl_real\a_dimen)} \fi
1572 %          \global\prev_mapfont=0 \out_lline{(MAP}
1573 %             \mapcommands\slot_name
1574 %          \out_llline{)}
1575 %       \fi
1576 %    \fi

1577 % } 1578 ⟨/obsolete⟩

\gobble_setslot
1579 \long\def\gobble_setslot#1\endsetslot{\endsetslot}
\end_do_character
1580 \def\end_do_character{
1581 \ifisglyph\slot_name\then
1582  \out_lline{)}

1583 \fi 1584 }

\notdef_name
1585 \def\notdef_name{.notdef}

12.6 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.

\vpl_nextlarger  \vpl_nextlarger{⟨name⟩} produces a NEXTLARGER entry.
1586 \def\vpl_nextlarger#1{
1587 \get_slot_num{#1}
1588 \ifnum -1<\result

1589  \out_lline{(NEXTLARGER~D~\the\result)~(COMMENT~#1)}
1590 \else
1591  \immediate\write16{Warning:~\string\nextlarger\space
1592  for~unknown~slot~`#1'}

1593 \fi 1594 }

\vpl_varchar \end_vpl_varchar  \vpl_varchar ⟨varchar commands⟩ \end_vpl_varchar produces a VARCHAR entry.
1595 \def\vpl_varchar{\out_lline{(VARCHAR}}
1596 \def\end_vpl_varchar{\out_llline{)}}
\vpl_vartop
1597 \def\vpl_vartop#1{
1598 \get_slot_num{#1}
1599 \ifnum -1<\result
1600  \out_llline{(TOP~D~\the\result)~(COMMENT~#1)}
1601 \else
1602  \immediate\write16{Warning:~\string\vartop\space
1603  for~unknown~slot~`#1'}

1604 \fi 1605 }

\vpl_varmid
1606 \def\vpl_varmid#1{
1607 \get_slot_num{#1}
1608 \ifnum -1<\result
1609  \out_llline{(MID~D~\the\result)~(COMMENT~#1)}
1610 \else
1611  \immediate\write16{Warning:~\string\varmid\space
1612  for~unknown~slot~`#1'}

1613 \fi 1614 }

\vpl_varbot
1615 \def\vpl_varbot#1{
1616 \get_slot_num{#1}
1617 \ifnum -1<\result
1618  \out_llline{(BOT~D~\the\result)~(COMMENT~#1)}
1619 \else
1620  \immediate\write16{Warning:~\string\varbot\space
1621  for~unknown~slot~`#1'}

1622 \fi 1623 }

\vpl_varrep
1624 \def\vpl_varrep#1{
1625 \get_slot_num{#1}
1626 \ifnum -1<\result
1627  \out_llline{(REP~D~\the\result)~(COMMENT~#1)}
1628 \else
1629  \immediate\write16{Warning:~\string\varrep\space
1630  for~unknown~slot~`#1'}

1631 \fi 1632 }

12.7 Saved map commands

The following commands (and \vpl_scale, which is defined above) can be used in the ⟨mapcommands⟩ glyph parameter.

\vpl_raw This macro writes the entries in a 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.

1633 \def\vpl_raw#1#2#3{
1634 \global\next_mapfont=\csname\the\mapfont_scaling-#1\endcsname
1635 \ifnum \next_mapfont=\prev_mapfont \else
1636  \out_llline{(SELECTFONT~\vpl_int\next_mapfont)~
1637  (COMMENT~#1~at~
1638  \expandafter\lose_measure \the\mapfont_scaling)}

1639 \fi

1640 \out_llline{(SETCHAR~D~#2)~(COMMENT~#3)}
1641 \global\prev_mapfont=\next_mapfont

1642 }

\vpl_rule
1643 \def\vpl_rule#1#2{
1644 \a_dimen=\make_factor{#2}\mapfont_scaling
1645 \b_dimen=\make_factor{#1}\mapfont_scaling
1646 \out_llline{(SETRULE~\vpl_real\a_dimen\space\vpl_real\b_dimen)}

1647 }

\vpl_special
\vpl_warning
warningspecials switch

1648 \def\vpl_special#1{
1649 \out_llline{(SPECIAL~#1)}}
1650 \def\vpl_warning#1{
1651 \ifwarningspecials
1652  \out_llline{(SPECIAL~Warning:~#1)}

1653 \fi

1654 \immediate\write16{Warning:~#1.}

1655 }

1656 \newif\ifwarningspecials
1657 \warningspecialstrue
\vpl_movert \vpl_moveup
1658 \def\vpl_movert#1{
1659 \a_dimen=\make_factor{#1}\mapfont_scaling
1660 \out_llline{(MOVERIGHT~\vpl_real\a_dimen)}

1661 }

1662 \def\vpl_moveup#1{
1663 \a_dimen=\make_factor{#1}\mapfont_scaling
1664 \out_llline{(MOVEUP~\vpl_real\a_dimen)}

1665 }

\vpl_push \vpl_pop
1666 \def\vpl_push{\out_llline{(PUSH)}}
1667 \def\vpl_pop{\out_llline{(POP)}}

12.8 Tidying up

\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 DESIGNUNITS property for those fonts which need one.

1668 \def\make_tidy#1{
1669 \tidying_up_hook
1670 \if_including_map_
1671  \a_count=0
1672  \loop\ifnum \a_count<\font_count
1673  \edef\a_macro{\csname~f-\the\a_count\endcsname}
1674  \global\x_cs\let\a_macro\x_relax
1675  \advance\a_count by 1
1676  \repeat
1677  \global\font_count=0
1678 \else
1679  \ifdim \rawfont_scaling<\z@
1680  \fontinstwarning{ETX~to~(V)PL}{The~font~
1681  \out_filename\space doesn't~contain~any~characters}
1682  \global\rawfont_scaling=\p@

1683 \fi

1684  \ifdim \rawfont_scaling=\p@ \else
1685  \out_line{(DESIGNUNITS~\vpl_real\rawfont_scaling)}

1686 \fi 1687 \fi 1688 }

13 Font installation commands and .fd files

\installfonts The call
\endinstallfonts
     \installfonts ⟨install commands⟩ \endinstallfonts

is the top-level interface for installing a number of fonts and creating .fd files for them.

\installfamily The ⟨install commands⟩ are:

\installfont
\installrawfont

\installfamily{⟨encoding⟩}{⟨family⟩}{⟨FD-commmands⟩} \installfont{⟨font-name⟩}{⟨file-list⟩}{⟨etx⟩}

{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩} \installrawfont{⟨font-name⟩}{⟨file-list⟩}{⟨etx⟩}

{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩}

     \installfontas{⟨font-name⟩}

{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩}

Each \installfamily command causes the generation of an .fd file for ⟨encoding⟩ and ⟨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.)

\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.

1689 \newtoks\family_toks
1690 \def\installfonts{
1691 \bgroup
1692 \global\family_toks={}
1693 \gdef\prev_file_list{}
1694 \global\let\setsomething_global=\global

1695 }

\installfamily  \installfamily{⟨encoding⟩}{⟨family⟩}{⟨FD-commmands⟩}

Adds the command

\fd_family{⟨encoding⟩}{⟨family⟩}{⟨FD-commmands⟩}

\⟨encoding⟩-⟨family⟩ to the token list \family_toks and defines a macro \⟨encoding⟩-⟨family⟩.

1696 \def\installfamily#1#2#3{
1697 \global\family_toks=
1698  \expandafter{\the\family_toks\fd_family{#1}{#2}{#3}}
1699 \global\x_cs\let{#1-#2}\empty_command

1700 }

\installfont \installrawfont  \installfont{⟨font-name⟩}{⟨file-list⟩}{⟨etx⟩}

{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩} \installrawfont{⟨font-name⟩}{⟨file-list⟩}{⟨etx⟩}

{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩}{⟨size⟩}

1701 \def\installfont#1#2#3#4#5#6#7#8{
1702 \global\let\setsomething_global=\x_relax
1703 \input_metrics{}{#2}
1704 \etxtovpl{#3}{#1}
1705 \installfontas{#1}{#4}{#5}{#6}{#7}{#8}
1706 \global\let\setsomething_global=\global

1707 }

1708 \def\installrawfont#1#2#3#4#5#6#7#8{
1709 \global\let\setsomething_global=\x_relax
1710 \xdef\out_filename{#1}
1711 \input_metrics{\let\storemapdata=\installraw_storemap}{#2}
1712 \let\storemapdata=\gobble_three
1713 \etxtopl{#3}{#1}
1714 \record_usage{#1}
1715 \installfontas{
1716  \ifdim \rawfont_scaling=\p@ \else
1717  [\expandafter\lose_measure\the\rawfont_scaling]~
1718  \fi #1
1719 }{#4}{#5}{#6}{#7}{#8}
1720 \global\let\setsomething_global=\global

1721 }

\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.

1722 \def\installraw_storemap#1#2#3{
1723 \def\a_macro{#1}
1724 \ifx \a_macro\out_filename \else
1725  \record_transform{\out_filename}{\string\frommtx{#1}}{}\if_false

1726 \fi 1727 }

\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.

1728 \def\input_metrics#1#2{
1729 \let\metrics=\file_list_metrics
1730 \xdef\curr_file_list{#2,}
1731 \let\metrics=\x_relax
1732 \ifx\prev_file_list\curr_file_list\else
1733  \egroup\bgroup

1734 #1

1735  \expandafter\process_csep_list \expandafter\input_mtx_file
1736  \curr_file_list\process_csep_list,
1737  \global\let\prev_file_list=\curr_file_list

1738 \fi 1739 }

\file_list_metrics The \file_list_metrics macro is a definition of \metrics that is used in the

⟨file-list⟩ argument of \installfont and \installrawfont when that is \xdefed by \input_metrics. This special definition prevents the succeeding ⟨metric commands⟩ from getting expanded.

1740 \def\file_list_metrics#1,{
1741 \iffalse{\fi}
1742 \a_toks=\expandafter{\curr_file_list\x_relax#1,}
1743 \xdef\curr_file_list{\the\a_toks \iffalse}\fi

1744 }

\installfontas The \installfontas command has the syntax

\installfontas{⟨font-info⟩}{⟨encoding⟩}{⟨family⟩}{⟨series⟩}{⟨shape⟩} {⟨size⟩}

The precise definition of a ⟨font-info⟩ can be found in [7, Sec. 4], here it suffices to say that a font name (name of (V)PL file) is a valid ⟨font-info⟩. The \installfontas command adds an entry for the ⟨font-info⟩ font to a font definition file, giving it the NFSS attributes ⟨encoding⟩/⟨family⟩/⟨series⟩/⟨shape⟩/ ⟨size⟩. The substitution mechanism will act on ⟨series⟩ and ⟨shape⟩, and it is therefore possible that ⟨font-info⟩ will appear in more than one \DeclareFont-Shape command. ⟨size⟩ can be either some ⟨size-infos⟩, as defined in [7, Sec. 4], or a fontinst shorthand for a such, declared using \declaresize.

1745 \def\installfontas#1#2#3#4#5#6{
1746 \if_undefined{#2-#3-#4-#5}\then
1747  \let\do_shape=\x_relax
1748  \if_undefined{#2-#3}\then
1749  \x_cs\let{#2-#3}\empty_command
1750  \autoinstallfamily{#2}{#3}

1751 \fi

1752  \x_cs\xdef{#2-#3}{
1753  \csname#2-#3\endcsname
1754  \do_shape{#2}{#3}{#4}{#5}

1755 } 1756 \fi

1757 \let\do_size=\x_relax
1758 \x_cs\xdef{#2-#3-#4-#5}{
1759  \if_defined{#2-#3-#4-#5}\then
1760  \csname#2-#3-#4-#5\endcsname

1761 \fi

1762  \do_size{#6}{#1}

1763 } 1764 }

\autoinstallfamily This command is called by \installfontas when it is asked to install a font for which no \installfamily has been given. The syntax is

     \autoinstallfamily{⟨encoding⟩}{⟨family⟩}

It defaults to calling \installfamily in the obvious way, but it can be redefined if the user wants something different.

1765 \def\autoinstallfamily#1#2{\installfamily{#1}{#2}{}}

\endinstallfonts Finish the installation by processing the \family_toks token register, which contains the accumulated information to be written out to .fd files.

1766 \def\endinstallfonts{
1767 \global\let\setsomething_global=\x_relax
1768 \let\do_shape=\fd_shape
1769 \let\do_size=\fd_size
1770 \the\family_toks
1771 \global\family_toks{}
1772 \egroup

1773 }

The \installfont command has traditionally allowed that names of base fonts (MTX files) are suffixed by a ␣scaled␣⟨factor⟩ that would cause the rawscale integer to be set and thereby scale everything that was in that base font by the said ⟨factor⟩. There is now a more general approach to this. If the control sequence

\IFKW-⟨keyword⟩ IFKW-⟨keyword⟩ is defined then ⟨keyword⟩ may be used as scaled is above; this control sequence should grab all the “arguments” of the keyword, process them as necessary, and end with the \get_keyword macro so that another keyword may be processed. As a rule, the arguments and keywords are delimited from each other by single spaces. A macro grabbing an argument grabs also the space after it. The IFKW is for InstallFont KeyWord.

\input_mtx_file The \input_mtx_macro takes one undelimited argument. It interprets this argument as if it was one item in the ⟨file-list⟩ argument of \installfont or \installrawfont, and does the corresponding processing. The argument should be one of the following three things:

⟨font⟩⟨optional modifiers⟩ \metrics ⟨metric commands⟩ ⟨nothing⟩

If, in the first case, an MTX file for ⟨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 second case, the ⟨metric commands⟩ simply get executed. In the third case, nothing happens.

The ⟨optional modifiers⟩ is either empty or has the form ⟨modifier clause⟩⟨optional modifiers⟩. A ⟨modifier clause⟩ generally has the form

␣⟨keyword⟩␣⟨argument(s)⟩

e.g.,

␣scaled␣⟨rawscale factor⟩

1774 \def\input_mtx_file#1{
1775 \reset_modifiers_hook
1776 \ifx\x_relax#1\x_relax

This tests for an empty argument, but it also lets explicit metric commands be executed.

1777 \else
1778  \identity_one{\get_file_name #1~}~\par

The two spaces have the effect of putting an empty keyword modifier last in the ⟨optional modifiers⟩. If everything is all right then this will gobble the \par. However, if the user forgot some argument of the last keyword then there will be an error message when \get_keyword will try to grab the next keyword.

If an encoding has been specified then the source file must be a PL or VPL file (since these are the only ones for which it makes sense to specify an encoding), otherwise we rely on \fromany to find a font metrics file.

1779  \ifx \pl_encoding\empty_command
1780  \fromany\file_name
1781  \else
1782  \metrics_given_encoding{\file_name}{\pl_encoding}

1783 \fi

1784  \ifisstr{afm-name}\then
1785  \inputmtx{\str{afm-name}}
1786  \else
1787  \fontinsterror{\string\install...}{
1788  Font/MTX~file~\file_name\space not~found

1789 }{

1790  You~can~insert~an~\string\inputmtx\space command~here
1791  \messagebreak to~input~some~other~MTX~file~instead.
1792  \ifisint{rawscale}\then \messagebreak
1793  The~requested~raw~scaling~will~then~be~applied~on~that.

1794 \fi 1796 \fi 1797 \fi 1798 }

\metrics_given_encoding This macro is a cousin of \fromany, for the case that metrics are taken from a (V)PL file that furthermore is assigned nonstandard metrics. The syntax is

     \metrics_given_encoding{⟨font⟩}{⟨etx⟩}

and the generated MTX file is named ⟨font⟩-⟨etx⟩.mtx to avoid that it is picked up by \fromany by mistake.

1799 \def\metrics_given_encoding#1#2{
1800 \x_cs\edef{s-afm-name}{#1-#2}
1801 \if_file_exists{#1.pl}\then
1802  \generalpltomtx{#1}{#1-#2}{pl}{#2}
1803 \else
1804  \if_file_exists{#1.vpl}\then
1805  \generalpltomtx{#1}{#1-#2}{vpl}{#2}
1806  \else
1807  \unsetstr{afm-name}
1808 \fi\fi

1809 }

\reset_modifiers_hook The \reset_modifiers_hook macro contains code that initialises all parameters that are modified by some ⟨modifier clause⟩ to their default values. If you need to add some initialisations due to that you define additional keywords then you should append these initialisations to this macro.

1810 \def\reset_modifiers_hook{
1811 \unsetint{rawscale}
1812 \let\glyph_name_modifier\identity_one
1813 \let\pl_encoding\empty_command
1814 \let\list_of_options\empty_command

1815 }

\get_file_name The macro \get_file_name grabs the base font (or other MTX file) name and starts the processing of the ⟨optional modifiers⟩.

1816 \def\get_file_name #1~{
1817 \edef\file_name{#1}
1818 \get_keyword

1819 }

\get_keyword \gobble_keywords The \get_keyword macro expects to be expanded in the context
     \get_keyword ⟨keyword⟩␣

where the ⟨keyword⟩ is a possible keyword. If \IFKW-⟨keyword⟩ is defined then the above expands to it, otherwise the above expands to an error message followed by a \gobble_keywords, which will gobble the rest of the list of keywords and arguments.

1820 \def\get_keyword #1~{
1821 \if_defined{IFKW-#1}\then
1822  \csname IFKW-#1 \expandafter\endcsname
1823 \else

1824  \fontinsterror{\string\install...}{
1825  `#1'~is~not~a~defined~keyword

1826 }{

1827  \error_help_a\messagebreak
1828  Extra~tokens~will~be~flushed.

1829 }

1830  \expandafter\gobble_keywords

1831 \fi 1832 }

1833 \def\gobble_keywords#1\par{}

\IFKW- The empty keyword is used to flag the end of the ⟨optional modifiers⟩.

1834 \x_cs\let{IFKW-}=\gobble_keywords

\IFKW-scaled This macro handles grabbing the argument of the traditional scaled keyword.

1835 \x_cs\def{IFKW-scaled}#1~{
1836 \ifnum #1=\one_thousand
1837  \unsetint{rawscale}
1838 \else
1839  \x_resetint{rawscale}{#1}

1840 \fi

1841 \get_keyword

1842 }

\IFKW-suffix This macro handles grabbing the argument of the suffix keyword. The effect of ‘suffix ⟨suffix⟩’ is that ⟨suffix⟩ will be appended to the name of every glyph defined by the next MTX file to be read in.

1843 \x_cs\def{IFKW-suffix}#1~{
1844 \def\glyph_name_modifier##1{##1#1}
1845 \get_keyword

1846 }

\IFKW-encoding \pl_encoding This macro handles grabbing the argument of the encoding keyword. The effect of ‘encoding ⟨etx⟩’ is that ⟨etx⟩ will be used as encoding when converting a PL or VPL file to MTX. \pl_encoding is used for storing the argument value. Its expansion is normally empty, which means \fromafm handles locating the metrics file and the encoding used for a PL or VPL is determined by its codingscheme.

1847 \x_cs\def{IFKW-encoding}#1~{
1848 \def\pl_encoding{#1}
1849 \get_keyword

1850 }

1851 \let\pl_encoding=\empty_command

\IFKW-option This macro handles grabbing the argument of the option keyword. One can test using \ifoption whether a particular option was specified.

1852 \x_cs\def{IFKW-option}#1~{
1853 \add_to\list_of_options{\do{#1}}

1854 }

\ifoption \list_of_options The \ifoption command is used to test whether a particular option is present on the list of options. The syntax is

     \ifoption{⟨string⟩}\then

and it is tested whether the ⟨string⟩ was one of the options given. Like strings in general, the ⟨string⟩ is expanded before it is compared to the options listed in

  \list_of_options.

The \list_of_options is a sequence of items on the form

\do{⟨option⟩}

where each ⟨option⟩ is an already expanded string of characters.

1855 \def\ifoption#1\then{
1856 \_a_false
1857 \edef\a_macro{#1}
1858 \def\do##1{
1859  \if_a_\else
1860  \def\b_macro{##1}
1861  \ifx \a_macro\b_macro \_a_true \fi

1862 \fi 1863 }

1864 \list_of_options
1865 \if_a_

1866 } 1867 ⟨/pkg⟩ 1868 ⟨∗doc⟩

1869 \def\ifoption#1\then{%
1870 \generic@if{option \TypesetStringExpression{#1}}%

1871 } 1872 ⟨/doc⟩ 1873 ⟨∗pkg⟩

1874 \let\list_of_options\empty_command

13.1 Writing font definition files

\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.

1875 \def\fd_family#1#2#3{
1876 \a_toks{#3}
1877 \edef\lowercase_file{\lowercase{
1878  \edef\noexpand\lowercase_file{#1#2.fd}}}
1879 \lowercase_file
1880 \open_out{\lowercase_file}
1881 \out_line{\percent_char~Filename:~\lowercase_file}
1882 \out_line{\percent_char~Created~by:~tex~\jobname}
1883 \out_line{\percent_char~Created~using~fontinst~v\fontinstversion}
1884 \out_line{}
1885 \out_line{\percent_char~THIS~FILE~SHOULD~BE~PUT~IN~A~TEX~INPUTS~
1886  DIRECTORY}
1887 \out_line{}
1888 \out_line{\string\ProvidesFile{\lowercase_file}}
1889 \out_lline{[
1890  \the\year/
1891  \ifnum10>\month0\fi\the\month/
1892  \ifnum10>\day0\fi\the\day\space
1893  Fontinst~v\fontinstversion\space

1894  font~definitions~for~#1/#2.

1895 ]}

1896 \out_line{}
1897 \out_line{\string\DeclareFontFamily{#1}{#2}{\the\a_toks}}

1898 {

1899  \csname #1-#2\endcsname
1900  \out_line{}
1901  \let\do_shape=\substitute_shape
1902  \csname #1-#2\endcsname
1903  \let\do_shape=\remove_shape
1904  \csname #1-#2\endcsname

1905 }

1906 \x_cs\g_let{#1-#2}\x_relax
1907 \out_line{}
1908 \out_line{\string\endinput}
1909 \close_out{Font~definitions}

1910 }

\fd_shape  \fd_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}
1911 \def\fd_shape#1#2#3#4{
1912 \out_line{}
1913 \out_line{\string\DeclareFontShape{#1}{#2}{#3}{#4}\left_brace_char}
1914 \csname #1-#2-#3-#4\endcsname
1915 \x_cs\g_let{#1-#2-#3-#4}\empty_command
1916 \out_line{\right_brace_char{}}

1917 }

\fd_size  \fd_size{SIZE}{FONT-NAME}
1918 \def\fd_size#1#2{
1919 \x_cs\ifx{siz-#1}\x_relax
1920  \out_lline{#1~#2}
1921 \else
1922  \out_lline{\csname siz-#1\endcsname\space #2}

1923 \fi 1924 }

\remove_shape  \remove_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}
1925 \def\remove_shape#1#2#3#4{
1926 \x_cs\g_let{#1-#2-#3-#4}\x_relax

1927 }

\substitute_shape  \substitute_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}
1928 \def\substitute_shape#1#2#3#4{
1929 \edef\orig_shape{#4}
1930 \substitute_series{#1}{#2}{#3}{\orig_shape}
1931 \x_cs\ifx{sub-\orig_shape}\x_relax\else
1932  \edef\subst_shape{\csname sub-\orig_shape\endcsname}
1933  \x_cs\ifx{#1-#2-#3-\subst_shape}\x_relax
1934  \out_line{
1935  \string\DeclareFontShape{#1}{#2}{#3}{\subst_shape}{
1936  <->\csname typ-\orig_shape\endcsname\space
1937  *~#2/#3/\orig_shape

1938 }{}

1940  \x_cs\let{#1-#2-#3-\subst_shape}\empty_command
1941  \substitute_shape{#1}{#2}{#3}{\subst_shape}

1942 \fi 1943 \fi 1944 }

\substitute_series  \substitute_series{ENCODING}{FAMILY}{SERIES}{SHAPE}
1945 \def\substitute_series#1#2#3#4{
1946 \edef\orig_series{#3}
1947 \x_cs\ifx{sub-\orig_series}\x_relax\else
1948  \edef\subst_series{\csname sub-\orig_series\endcsname}
1949  \x_cs\ifx{#1-#2-\subst_series-#4}\x_relax
1950  \out_line{
1951  \string\DeclareFontShape{#1}{#2}{\subst_series}{#4}{
1952  <->\csname typ-\orig_series\endcsname\space
1953  *~#2/\orig_series/#4

1954 }{} 1955 }

1956  \x_cs\let{#1-#2-\subst_series-#4}\empty_command
1957  \substitute_series{#1}{#2}{\subst_series}{#4}

1958 \fi 1959 \fi 1960 }

\substitutesilent \substitutenoisy  \substitutesilent{TO}{FROM}
  \substitutenoisy{TO}{FROM}

Specifies a default substitution for family or shape TO, which is substituted by family or shape FROM.

1961 \def\substitutesilent#1#2{
1962 \x_cs\def{sub-#2}{#1}
1963 \x_cs\def{typ-#2}{ssub}

1964 }

1965 \def\substitutenoisy#1#2{
1966 \x_cs\def{sub-#2}{#1}
1967 \x_cs\def{typ-#2}{sub}

1968 }

1969 \substitutesilent{bx}{b}
1970 \substitutesilent{b}{bx}
1971 \substitutesilent{b}{sb}
1972 \substitutesilent{b}{db}
1973 \substitutesilent{m}{mb}
1974 \substitutesilent{m}{l}
1975 \substitutenoisy{ui}{it}

I don’t think we want these since in OT1 encoding it will cause the old <sterling> vs <dollar> problem. (ASAJ) — Oh yes we do. (SPQR)

1976 \substitutesilent{sl}{it}
1977 \substitutesilent{it}{sl}

13.2 The font substitution mechanism

Note: This subsection contains (part of) a new implementation of the font substitution mechanism, but it is uncertain whether it will ever be completed.

1978 ⟨∗underconstruction⟩

13.2.1 The substitution graph

Which substitutions are performed are determined by the substitution graph. The vertices of this graph are all combinations of a series and a shape. The arcs (directed edges) of this graph are the substitutions that can be made. Each arc has a wheight—a real number in the range [0, 1]—that describes how much of the quality of the font that is preserved with this substitution.

As an example, consider the case that there is an arc from m/it to m/sl and that the wheight of this arc is 0.5. This means that it is OK to substitute the medium italic (m/it) font as a medium slanted (m/sl) font if there is no medium slanted font, but that the medium italic font is only considered as being half (0.5) as good a medium slanted font as it is a medium italic font.

The main problem the substitution mechanism has to solve in this context is to find the best possible way of substituting a font, given the real fonts which has actually been installed (using \installfont or \installrawfont). The solution to this problem is computed by a brute force approach—all possible substitution paths are followed and during this process the best solution so far, for each vertex separately, is stored.

In practice, the substitution graph G is constructed as the cartesian product of one graph G_{1} of series substitutions and one graph G_{2} of shape substitutions, with the option of adding some additional arcs to this product. The reason for this is that one usually wants to make the same shape substitutions in all series and vice versa, so by only storing the G_{1} and G_{2} graphs, plus perhaps a handfull of extra edges, one gets away with using fewer tokens. The wheights of the arcs are stored as integers in the range 0–1000, where 0 means the real number 0 and 1000 means the real number 1.

\do_arc The \do_arc macro is probably the most common in the data structures that constitute the substitution graph. Its syntax is always

\do_arc{⟨series⟩}{⟨shape⟩}{⟨wheight⟩}

but it is meant to be redefined whenever one needs to do something “for all arcs” (usually all arcs at a given vertex or so). There are three families of macros which consist of \do_arc lists, namely

\sub1-⟨series⟩ \sub2-⟨shape⟩ \sub-⟨series⟩-⟨shape⟩

These macros store arcs going out from a vertex. The \sub1-⟨series⟩ macross store the arcs incident with the vertex ⟨series⟩ in the series substitution graph G_{1}. The \sub2-⟨shape⟩ macros store the arcs incident with the vertex ⟨shape⟩ in the shape substitution graph G_{2}. The \sub-⟨series⟩-⟨shape⟩ macros store the arcs of G that are incident with the vertex ⟨series⟩/⟨shape⟩ but do not appear in the cartesian product G_{1} × G_{2}.

The ⟨series⟩ and ⟨shape⟩ arguments of \do_arc tells which vertex the arc goes to, hence for example \do_arc{b}{it}{600} in the macro \sub-db-sl corresponds to an arc going from the db/sl vertex to the b/it vertex and having a wheight of 0.6.

\curr_series The above omits one important detail, namely that the ⟨shape⟩ argument for \curr_shape a \do_arc in a \sub1-… must be able to be all shapes since the shape is not

determined for arcs in G_{1} and the series is likewise for arcs in G_{2}. To make things work anyway, there are two macros \curr_series and \curr_shape which contain this missing information. Furthermore, a \do_arc item for an arc in G_{1} will always have the structure

     \do_arc{⟨series⟩}\curr_shape{⟨wheight⟩}

and a \do_arc item for an arc in G_{2} will have the structure

     \do_arc\curr_series{⟨shape⟩}{⟨wheight⟩}
\substituteshape \substituteseries \substituteseriesshape  \substituteshape{⟨to⟩}{⟨from⟩}{⟨wheight⟩}
\substituteseries{⟨to⟩}{⟨from⟩}{⟨wheight⟩}

\substituteseriesshape{⟨toseries⟩}{⟨toshape⟩}{⟨fromseries⟩}{⟨fromshape⟩}{⟨wheight⟩}

1979 \def\substituteshape#1#2#3{
1980 \round_wheight{#3}
1981 \edef\temp_command{#1}
1982 \edef\sub_suffix{#2}
1983 \ifx \temp_command\sub_suffix \else
1984  \def\sub_suffix##1##2{2-##2}
1985  \def\do_arc##1##2##3{
1986  \x_cs\ifx{sub2-##2}R \else
1987  \noexpand\do_arc\noexpand\curr_series{##2}{##3}

1988 \fi 1989 }

1990  \update_do_arc_list{}{#2}{}{#1}{\noexpand\curr_series{#1}}

1991 \fi 1992 }

1993 \def\substituteseries#1#2#3{
1994 \round_wheight{#3}
1995 \edef\temp_command{#1}
1996 \edef\sub_suffix{#2}
1997 \ifx \temp_command\sub_suffix \else
1998  \def\sub_suffix##1##2{1-##1}
1999  \def\do_arc##1##2##3{
2000  \x_cs\ifx{sub1-##1}R \else
2001  \noexpand\do_arc{##1}\noexpand\curr_shape{##3}

2002 \fi 2003 }

2004  \update_do_arc_list{#2}{}{#1}{}{{#1}\noexpand\curr_shape}

2005 \fi 2006 }

2007 \def\substituteseriesshape#1#2#3#4#5{
2008 \round_wheight{#5}
2009 \edef\temp_command{#1-#2}
2010 \edef\sub_suffix{#3-#4}
2011 \ifx \temp_command\sub_suffix \else

2012  \def\sub_suffix##1##2{-##1-##2}
2013  \def\do_arc##1##2##3{
2014  \x_cs\ifx{sub-##1-##2}R \else
2015  \noexpand\do_arc{##1}{##2}{##3}

2016 \fi 2017 }

2018  \update_do_arc_list{#3}{#4}{#1}{#2}{{#1}{#2}}

2019 \fi 2020 }

2021 \def\round_wheight#1{
2022 \eval_expr{#1}
2023 \ifnum \one_thousand<\result
2024  \result=\one_thousand
2025 \else \ifnum 0>\result
2026  \result=\z@
2027 \fi\fi

2028 }

\update_do_arc_list{⟨update-series⟩}{⟨update-shape⟩}{⟨tag-series⟩}{⟨tag-shape⟩} {⟨inserted series+shape⟩}

2029 \def\update_do_arc_list#1#2#3#4#5{
2030 \bgroup
2031  \edef\temp_command{sub\sub_suffix{#1}{#2}}
2032  \x_cs\let{sub\sub_suffix{#3}{#4}}=R
2033  \x_cs\xdef\temp_command{
2034  \x_cs\ifx\temp_command\relax \else
2035  \csname\temp_command\endcsname

2036 \fi

2037  \ifnum 0<\result
2038  \noexpand\do_arc #5{\the\result}

2039 \fi 2040 }

2041 \egroup

2042 }

\substitutesilent \substitutenoisy  \substitutesilent{TO}{FROM}
  \substitutenoisy{TO}{FROM}

Specifies a default substitution for family or shape TO, which is substituted by family or shape FROM.

2043 \def\substitutesilent#1#2{
2044 \substituteseries{#1}{#2}{900}
2045 \substituteshape{#1}{#2}{900}

2046 }

2047 \def\substitutenoisy#1#2{
2048 \substituteseries{#1}{#2}{500}
2049 \substituteshape{#1}{#2}{500}

2050 }

2051 \a_count=900 % Silent substitution wheight
2052 \b_count=500 % Noisy substitution wheight
2053 \substituteseries{bx}{b}{\a_count}
2054 \substituteseries{b}{bx}{\a_count}
2055 \substituteseries{b}{sb}{\a_count}

2056 \substituteseries{b}{db}{\a_count}
2057 \substituteseries{m}{mb}{\a_count}
2058 \substituteseries{m}{l}{\a_count}
2059 \substituteshape{ui}{it}{\b_count}

I don’t think we want these since in OT1 encoding it will cause the old <sterling> vs <dollar> problem. (ASAJ) — Oh yes we do. (SPQR)

2060 \substituteshape{sl}{it}{\a_count}
2061 \substituteshape{it}{sl}{\a_count}

13.2.2 Listing reachable vertices

While determining the optimal substitutions, there is a need to store some—more or less temporary—information for each vertex. Such information will be called a property of the vertex and it is stored in the \v-⟨series⟩-⟨shape⟩ family of macros.

The following are the basic properties:

\real_font{⟨quality⟩} This expresses that this vertex corresponds to a font that has actually been installed with a nominal quality of ⟨quality⟩.

\subs_font{⟨series⟩}{⟨shape⟩}{⟨quality⟩} This expresses that this vertex corresponds to a font for which the font ⟨series⟩/⟨shape⟩ has been substituted. ⟨quality⟩ is the quality this substitution is considered to have.

There will also be some lists of vertices. These will consist of simple \do{⟨series⟩}{⟨shape⟩} triples.

2062 \def\list_subs_vertices{
2063 \def\subs_vertex_list{}
2064 \let\do_arc=\subs_do_arc
2065 \let\do=\never_do
2066 \def\real_font##1{\c_count=\@MM}
2067 \def\subs_font##1##2##3{\c_count=##3\relax}
2068 \real_vertex_list

2069 }

2070 \def\subs_do_arc#1#2#3{
2071 \b_count=#3
2072 \multiply \b_count \a_count
2073 \divide \b_count \one_thousand
2074 \c_count=-\max_mathchardef
2075 \csname v-#1-#2\endcsname
2076 \ifnum \c_count<\b_count
2077  \ifnum \c_count=-\max_mathchardef
2078  \edef\subs_vertex_list{\subs_vertex_list\do{#1}{#2}}

2079 \fi

2080  \x_cs\edef{v-#1-#2}{\noexpand\subs_font{\subs_series}
2081  {\subs_shape}{\the\b_count}}
2082  \toks_a=\expandafter{\the\a_toks \do_subs{#1}{#2}}

2083 \fi 2084 }

2085 \def\do_subs#1#2{
2086 \edef\curr_series{#1}

2087 \edef\curr_shape{#2}
2088 \csname v-#1-#2\endcsname
2089 \a_count=\c_count
2090 \a_toks={}
2091 \csname sub-#1-#2\endcsname
2092 \csname sub1-#1\endcsname
2093 \csname sub2-#2\endcsname
2094 \the\a_toks

2095 }

2096 \def\start_subs_at#1#2{
2097 \edef\subs_series{#1} \let\curr_series=\subs_series
2098 \edef\subs_shape{#2}  \let\curr_shape=\subs_shape
2099 \a_count=\x_cs\second_of_two{v-#1-#2}
2100 \a_toks={}
2101 \csname sub-#1-#2\endcsname
2102 \csname sub1-#1\endcsname
2103 \csname sub2-#2\endcsname
2104 \the\a_toks

2105 }

2106 ⟨/underconstruction⟩

13.3 Default encodings and font sizes

\declareencoding  \declareencoding{CODINGSCHEME}{ENCODING}

Declare a macro \enc-CODINGSCHEME which expands to ENCODING. This is used to determine the encoding in \pltomtx.

2107 \def\declareencoding#1#2{\x_cs\edef{enc-#1}{#2}}

Old TEX text font encodings.

2108 \declareencoding{TEX~TEXT}{ot1}
2109 \declareencoding{TEX~TEXT~WITHOUT~F-LIGATURES}{ot1}
2110 \declareencoding{TEX~TYPEWRITER~TEXT}{ot1tt}

Old TEX math font encodings.

2111 \declareencoding{TEX~MATH~ITALIC}{oml}
2112 \declareencoding{TEX~MATH~SYMBOLS}{oms}
2113 \declareencoding{TEX~MATH~EXTENSION}{omx}
2114 \declareencoding{LATEX~SYMBOLS}{lasy}

Euler math font encodings.

2115 \declareencoding{TEX~TEXT~SUBSET}{eufrak}
2116 \declareencoding{TEX~MATH~ITALIC~SUBSET}{eurm}
2117 \declareencoding{TEX~MATH~SYMBOLS~SUBSET}{euscr}
2118 \declareencoding{EULER~SUBSTITUTIONS~ONLY}{euex}

New TEX text font encodings.

2119 \declareencoding{EXTENDED~TEX~FONT~ENCODING~-~LATIN}{t1}
2120 \declareencoding{TEX~TEXT~COMPANION~SYMBOLS~1---TS1}{ts1}

Rencoded PostScript font encdings.

2121 \declareencoding{TEXBASE1ENCODING}{8r}
2122 \declareencoding{TEX~TYPEWRITER~AND~WINDOWS~ANSI}{8y}
\declaresize  \declaresize{FONTSIZE}{LATEXSIZE}
2123 \def\declaresize#1#2{\x_cs\edef{siz-#1}{#2}}

Default sizes. An empty size argument is equivalent to <->, for use with scalable fonts.

2124 \declaresize{}{<->}
2125 \declaresize{5}{<5>}
2126 \declaresize{6}{<6>}
2127 \declaresize{7}{<7>}
2128 \declaresize{8}{<8>}
2129 \declaresize{9}{<9>}
2130 \declaresize{10}{<10>}
2131 \declaresize{11}{<10.95>}
2132 \declaresize{12}{<12>}
2133 \declaresize{14}{<14.4>}
2134 \declaresize{17}{<17.28>}
2135 \declaresize{20}{<20.74>}
2136 \declaresize{25}{<24.88>}

14 Debugging

\NOFILES \NOFILES switches off file generation, and causes 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 \latinfamily command.

2137 \def\NOFILES{
2138 \def\transformfont##1##2{
2139  \touch_file{##1.mtx}
2140  \touch_file{##1.pl}

2141 }

2142 \def\reglyphfont##1##2{\touch_file{##1.mtx}}
2143 \def\installfonts{}
2144 \def\endinstallfonts{}
2145 \def\installfont##1##2##3##4##5##6##7##8{
2146  \touch_file{##1.vpl}

2147 }

2148 \def\installrawfont##1##2##3##4##5##6##7##8{
2149  \touch_file{##1.pl}

2150 }

2151 \def\installfamily##1##2##3{\touch_file{##1##2.fd}}

2152 }

\touch_file
2153 \def\touch_file#1{
2154 \edef\lowercase_file{\lowercase{
2155  \edef\noexpand\lowercase_file{#1}}}
2156 \lowercase_file
2157 \open_out{\lowercase_file}
2158 \out_line{\percent_char~TEST~FILE.}
2159 \out_line{\percent_char~Created~whilst~debugging~fontinst.}
2160 \close_out{Test~file}

2161 } 2162 ⟨/pkg⟩

File d

ficonv.dtx

15 Basic file format conversions

15.1 Converting an ENC file to an ETX file

\enctoetx The macro

\enctoetx{⟨encfile⟩}{⟨etxfile⟩}

reads ⟨encfile⟩.enc and writes the same information to ⟨etxfile⟩.etx, in a format TEX can read more easily.

Each /⟨glyph⟩ command is recorded in a macro \o-⟨glyph⟩, which expands to a corresponding \setslot{⟨glyph⟩} … \endslot statement.

1 ⟨∗misc⟩

 2 \newif\ifmissingslots
 3 \x_cs\def{o-.notdef}#1{\global\missingslotstrue}
\enctoetx
 4 {
 5 \catcode`\/=\active
 6 \catcode`\]=\active
 7 \gdef\enctoetx#1#2{{
 8  \catcode`\/=\active
 9  \catcode`\]=\active
10  \def/##1[{
11  \a_count=0
12  \global\missingslotsfalse
13  \def/####1~{
14  \csname~o-####1\endcsname{
15  \ifmissingslots
16  \out_line{\string\nextslot{\the\a_count}}
17  \fi
18  \global\missingslotsfalse
19  \out_line{\string\setslot{####1}}
20  \out_line{\string\endsetslot}
21  \out_line{}

22 }

23  \advance\a_count by 1

24 } 25 }

26  \def]~def{}
27  \make_etx{#1}{#2}
28 }}

29 }

   \make_etx finishes the job of \enctoetx.
30 \def\make_etx#1#2{
31 \open_out{\temp_prefix#2.etx}
32 \out_line{\percent_char~Filename:~#2.etx}
33 \out_line{\percent_char~Created~by:~tex~\jobname}

34 \out_line{\percent_char~Created~using:~\string\enctoetx{#1}{#2}}
35 \out_line{}
36 \out_line{\percent_char~This~file~contains~the~
37  information~of~#1.enc~in~a~form}
38 \out_line{\percent_char~more~easily~read~by~TeX.~
39  It~is~used~by~the~fontinst~package.}
40 \out_line{}
41 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
42 \out_line{}
43 \out_line{\string\relax}
44 \out_line{}
45 \out_line{\string\documentclass[twocolumn]{article}}
46 \out_line{\string\usepackage{fontdoc}}
47 \out_line{}
48 \out_line{\string\begin{document}}
49 \out_line{}
50 \out_line{This~document~describes~the~#1~encoding.}
51 \out_line{It~was~automatically~generated~by~the}
52 \out_line{{\string\tt\space~fontinst}~package.}
53 \out_line{}
54 \out_line{\string\encoding}
55 \out_line{}
56 \out_line{\string\needsfontinstversion{\fontinstversion}}
57 \out_line{}
58 \primitiveinput #1.enc\x_relax
59 \out_line{}
60 \out_line{\string\end encoding}
61 \out_line{}
62 \out_line{\string\end{document}}
63 \close_out{Encoding~vector}

64 }

15.2 Converting an ETX file to an ENC file

\etxtoenc The command

\etxtoenc{⟨etxfile⟩}{⟨encfile⟩}

reads ⟨etxfile⟩.etx and generates a postscript encoding file ⟨encfile⟩.enc that specifies the same encoding vector.

\notdef_name This macro holds the name of the .notdef glyph, which must be put in all encoding positions where there is no other glyph.

65 \def\notdef_name{.notdef}

\etxtoenc The conversion has three steps. First the .notdef glyph is assigned to every slot in the encoding, then the ETX file is read and the assignments are changed for the slots which are not unassigned in the encoding, and finally the ENC file is written. The first two steps are carried out by \etxtoenc, but the final step is handled by \make_enc.

66 \def\etxtoenc#1#2{\begingroup
67 \a_count=\z@
68 \loop
69  \x_cs\let{name-\the\a_count}=\notdef_name

70 \ifnum \@cclv>\a_count
71  \advance \a_count \@ne
72 \repeat
73 \def\do_slot{
74  \x_cs\ifx{name-\the\slot_number}\notdef_name
75  \x_cs\edef{name-\the\slot_number}{\slot_name}
76  \fi

77 }

78 \process_csep_list\inputetx #1,\process_csep_list,
79 \make_enc{#1}{#2}
80 \endgroup}

\make_enc The command

\make_enc{⟨etxfiles⟩}{⟨encfile⟩}

creates the file ⟨encfile⟩.enc and writes to that file the definition of the postscript encoding vector which corresponds to the encoding currently stored in the \name-⟨slot⟩ family of macros. That encoding is assumed to be defined by the files listed in the ⟨etxfiles⟩.

81 \def\make_enc#1#2{
82 \setstr{encodingname}{fontinst-autoenc-#1}
83 \def\a_macro##1{
84  \add_to\b_macro{##1.etx}
85  \def\a_macro####1{
86  \add_to\b_macro{,~####1.etx}

87 } 88 }

89 \let\b_macro\empty_command
90 \process_csep_list\a_macro #1,\process_csep_list,
91 \open_out{#2.enc}
92 \out_line{\percent_char !PS-Adobe-3.0~Resource-Encoding}
93 \out_line{\percent_char\space @psencodingfile\left_brace_char}
94 \ref_to_sourcefile{author}\b_macro
95 \ref_to_sourcefile{version}\b_macro
96 \out_line{\percent_char\four_spaces date~=~"generated~
97  \the\year/
98  \ifnum10>\month0\fi\the\month/
99  \ifnum10>\day0\fi\the\day",}
100 \out_line{\percent_char\four_spaces filename~=~"\out_filename",}
101 \ref_to_sourcefile{email}\b_macro
102 \ifisstr{address}\then
103  \out_line{\percent_char\four_spaces address~=~\str{address}}
104 \fi
105 \out_line{\percent_char\four_spaces codetable~=~"ISO/ASCII",}
106 \out_line{\percent_char\four_spaces checksum~=~"",}
107 \out_line{\percent_char\four_spaces abstract~=~"
108  This~is~a~postscript~encoding~file,~automatically~
109  generated~by~fontinst~from~\b_macro."}
110 \out_line{\percent_char\space\right_brace_char}
111 \out_line{}
112 \out_line{\percent_char\space Created~by:~tex~\jobname}
113 \out_line{\percent_char\space Created~using:~
114  \string\etxtoenc{#1}{#2}}

115 \out_line{}
116 \out_line{\percent_char\space This~file~should~be~installed~
117  somewhere~that~your~DVI}
118 \out_line{\percent_char\space to~postscript~driver~looks~for~files.~
119  It~is~needed~for}
120 \out_line{\percent_char\space reencoding~some~font~you~have~
121  transformed.}
122 \out_line{}
123 \out_line{\percent_char\space After~installing~this~file,~you~
124  should~add~the~following}
125 \out_line{\percent_char\space line~(minus~\percent_char)~
126  to~your~finstmsc.rc~file:}
127 \out_line{\percent_char\space\string\declarepsencoding
128  {#1}{\str{encodingname}}{\string\download{\out_filename}}}
129 \edef\a_macro{
130  \noexpand\declarepsencoding{#1}{\str{encodingname}}
131  {\noexpand\download{\out_filename}}

132 }

133 \a_macro
134 \out_line{}
135 \out_line{\percent_char\percent_char BeginResource:~
136  encoding~\str{encodingname}}
137 \out_line{/\str{encodingname}\space[}
138 \b_count=8
139 \a_count=\z@
140 \loop
141  \ifnum 8=\b_count
142  \b_count=\z@
143  \out_line{\percent_char\space\the\a_count}
144  \fi
145  \out_line{/\csname name-\the\a_count \endcsname}
146 \ifnum \@cclv>\a_count
147  \advance \a_count \@ne
148  \advance \b_count \@ne
149 \repeat
150 \out_line{]~def}
151 \out_line{\percent_char\percent_char EndResource}
152 \out_line{}
153 \out_line{\percent_char\space End~of~file~\out_filename.}
154 \close_out{Encoding~vector}

155 }

\ref_to_sourcefile The command
      \ref_to_sourcefile{⟨field⟩}{⟨sourcefile⟩}

writes a ⟨field⟩ field of a BibTEX-style header to the current main output file. If the string named ⟨field⟩ is set then the value for this field will be that string, and if it isn’t set then the value will be the string "See file ⟨sourcefile⟩". Note that the string #1 is not quoted, so it must contain the quotes if it isn’t simply an integer.

156 \def\ref_to_sourcefile#1#2{
157 \ifisstr{#1}\then
158  \out_line{\percent_char\four_spaces #1~=~\str{#1},}

159 \else
160  \out_line{\percent_char\four_spaces #1~=~"See~file~#2",}
161 \fi

162 }

15.3 Converting an ETX file to CMAP file

\etxtocmap The command

\etxtocmap{⟨etxfile⟩}{⟨cmapfile⟩}

reads ⟨etxfile⟩.etx and generates a ToUnicode CMap file ⟨cmapfile⟩.cmap that maps slots to Unicode strings as specified by the ⟨etxfile⟩.

\write_cmap_body The \write_cmap_body command writes the actual CMap data^{11} to the current output file. The syntax is

      \write_cmap_body{⟨etxfile⟩}

More precisely, what this command writes is the codespace range specification and the mappings. The latter are all encoded using bfchar operators.

163 \def\write_cmap_body#1{
164 \out_line{1~begincodespacerange~<00>~<FF>~endcodespacerange}
165 \let\do_slot=\_a_true
166 \def\Unicode##1##2{\cmap_charseq{\cmap_codepoint{##1}{##2}}}
167 \let\charseq=\cmap_charseq
168 \inputetx{#1}

169 }

\cmap_codepoint This is what \Unicode is inside a \charseq. It appends a UTF-16BE character in hexadecimal notation (either four hex digits for a character in the BMP, or eight hex digits for a surrogate pair) to \a_macro, and also appends a space for grouping the digits for easier reading.

170 \def\cmap_codepoint#1#2{
171 \uppercase{\a_count="#1\x_relax}
172 \ifnum "10000>\a_count
173  \format_hex\b_macro{\a_count}{4}
174  \edef\a_macro{\a_macro \b_macro \space}
175 \else
176  \advance \a_count -"10000
177  \d_count=\a_count
178  \divide \a_count "400
179  \b_count=\a_count
180  \multiply \b_count "400
181  \advance \d_count -\b_count
182  \advance \a_count "D800
183  \advance \d_count "DC00~
184  \format_hex\b_macro{\a_count}{4}
185  \format_hex\c_macro{\d_count}{4}
186  \edef\a_macro{\a_macro \b_macro \c_macro \space}
187 \fi

188 }

11As opposed to silly stuff that is requested by the file format specification but probably isn’t of any use for anything, which is written by \ref_to_sourcefile.

\cmap_charseq This macro is what \charseq is when generating a CMap; all writing of CMap entries is routed through it. Only the first character equivalent of each slot should get written to file, so the _a_switch is used for keeping track of whether this would be the first.

189 \def\cmap_charseq#1{%
190 \if_a_
191  \bgroup
192  \let\Unicode=\cmap_codepoint
193  \let\a_macro=\empty_command

194 #1

195  \format_hex\b_macro{\slot_number}{2}
196  \out_line{1~beginbfchar~<\b_macro>~<~\a_macro>~endbfchar}
197  \egroup
198  \_a_false
199 \fi

200 }

\etxtocmap The
201 \def\etxtocmap#1#2{\begingroup
202 \inputetx{#1}
203 \open_out{#2.cmap}
204 \out_line{\percent_char !PS-Adobe-3.0~Resource-CMap}
205 \out_line{\percent_char\percent_char
206  DocumentNeededResources:~procset~CIDInit}
207 \out_line{\percent_char\percent_char
208  IncludeResource:~procset~CIDInit}

Here comes the first problem: the CMap must have a name. If the ETX file sets the string variable cmapname then that is used as name, but otherwise fontinst-⟨cmapfile⟩ is used as name. Note that this is different from the pattern in \etxtoenc, which instead uses the ⟨etxname⟩.

209 \setstr{cmapname}{fontinst-#2}
210 \out_line{\percent_char\percent_char
211  BeginResource:~CMap~\str{cmapname}}

The next problem is whether one should bother with the quite extensive version control junk that Adobe has specified. I prefer not to, because it is very much geared towards using CMaps with CIDFonts, which is not the case here.

Thus it is time for the actual PS code.

212 \out_line{/CIDInit~/ProcSet~findresource~begin}
213 \out_line{7~dict~begin}
214 \out_line{begincmap}
215 \out_line{/CMapName~/\str{cmapname}~def}
216 \out_line{/CMapType~2~def}
217 \write_cmap_body{#1}
218 \out_line{endcmap}
219 \out_line{CMapName~currentdict~/CMap~defineresource~pop}
220 \out_line{end}
221 \out_line{end}
222 \out_line{\percent_char\percent_char EndResource}
223 \out_line{\percent_char\percent_char EOF}
224 \close_out{ToUnicode~CMap}
225 \endgroup}

226 ⟨/misc⟩

15.4 Converting an AFM file to an MTX file

\afmtomtx The macro

\afmtomtx{⟨afmfile⟩}{⟨mtxfile⟩}

reads ⟨afmfile⟩.afm, and writes the same information out to ⟨mtxfile⟩.mtx.

\afmtomtx

227 ⟨∗pkg⟩

228 \def\afmtomtx#1#2{{
229 \let\setsomething_global=\x_relax
230 \open_out{\temp_prefix#2.mtx}
231 \edef\raw_font_name{#2}
232 \edef\source_font_name{#1}
233 \x_resetint{italicslant}{0}
234 \let\italcorr_expression=\uprightitalcorr
235 \x_setint{minimumkern}{0}
236 \minimum_kern=\int{minimumkern}
237 \out_line{\percent_char~Filename:~#2.mtx}
238 \out_line{\percent_char~Created~by:~tex~\jobname}
239 \out_line{\percent_char~Created~using:~\string\afmtomtx{#1}{#2}}
240 \out_line{}
241 \out_line{\percent_char~This~file~contains~the~
242  information~of~#1.afm~in~a~form}
243 \out_line{\percent_char~more~easily~read~by~TeX.~
244  It~is~used~by~the~fontinst~package.}
245 \out_line{}
246 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
247 \out_line{}
248 \out_line{\string\relax}
249 \out_line{\string\metrics}
250 \out_line{}
251 \out_line{\string\needsfontinstversion{\fontinstversion}}
252 \out_line{}
253 \catcode`\^^M=12
254 \catcode`\ =10
255 \expandafter\afm_line\primitiveinput #1.afm\x_relax
256 \out_line{}
257 \out_line{\endmetrics_text}
258 \close_out{Metrics}

259 }}

Kerns below this value are ignored.

260 \newcount\minimum_kern

\afm_length \afm_unit_dimen The call \afm_length⟨count⟩{⟨real⟩} interprets the ⟨real⟩ as a real number, rounds it to the nearest integer, and sets the ⟨count⟩ (a \count register) to that integer. In this process, \a_dimen is used as a temporary storage.

261 \def\afm_length#1#2{
262 \a_dimen=#2\afm_unit_dimen
263 #1=\a_dimen
264 \divide #1 by \afm_unit_dimen
265 \advance \a_dimen by -#1\afm_unit_dimen

266 \ifdim \a_dimen>0.5\afm_unit_dimen
267  \advance #1 by 1
268 \else \ifdim \a_dimen<-0.5\afm_unit_dimen
269  \advance #1 by -1
270 \fi\fi
271 \x_relax

272 }

The dimen \afm_unit_dimen is used to keep track of how long an AFM unit is interpreted as being in this routine. Lowering its value makes \afm_length capable of handling greater lengths but looses some very slight precision in the rounding, increasing the value has the opposite effects. The current value of 1000 sp means it reads lengths with three decimals accuracy (not very much use for them though as the number is rounded to zero decimals accuracy anyway, but it does make a difference when deciding how a ⟨real⟩ like 0.502 should be rounded) and can handle lengths of an absolute value of a good million AFM units. This should be adequate in most cases. It is, by the way, probably wisest to keep it a power of ten scaled points in all cases, as this should reduce the rounding errors caused by various base conversions.

273 \newdimen\afm_unit_dimen
274 \afm_unit_dimen=1000sp

The command \afm_line reads to the end of the line, calls \afm_command on that line, then calls \afm_line again.

275 {\catcode`\^^M=12 \gdef\afm_line#1
276 {\afm_command#1~\end_of_line\afm_line}}

The command \afm_command reads the first word FOO, and calls afm-FOO. If this does not exist, then \gobble_one_line will eat up the rest of the line.

277 \def\afm_command#1~{\csname~afm-#1\endcsname\gobble_one_line}
278 \def\gobble_one_line#1\end_of_line{}

This all stops when we reach the command EndFontMetrics.

279 \x_cs\def{afm-EndFontMetrics}#1\afm_line{\endinput}

\afm_def To define an AFM command, you say \afm_def{⟨command⟩}(⟨pattern⟩){⟨result⟩}

280 \def\afm_def#1(#2)#3{\x_cs\def{afm-#1}
281 \gobble_one_line#2\end_of_line{#3}}

\afm_let Saying \afm_let{⟨dest-command⟩}{⟨source-command⟩} copies the definition of one AFM command to another.

282 \def\afm_let#1#2{
283 \expandafter\let \csname afm-#1\expandafter\endcsname
284  \csname afm-#2\endcsname

285 }

For example, we can define the following AFM commands:

286 \afm_def{CharWidth}(#1){\afm_length\char_x_width{#1}}
287 \afm_def{ItalicAngle}(#1~){\calculate_it_slant{#1}}
288 \afm_def{XHeight}(#1){
289 \afm_length\a_count{#1}
290 \out_line{\string\setint{xheight}{\the\a_count}}}

291 \afm_def{CapHeight}(#1){
292 \afm_length\a_count{#1}
293 \out_line{\string\setint{capheight}{\the\a_count}}}
294 \afm_def{Ascender}(#1){
295 \afm_length\a_count{#1}
296 \out_line{\string\setint{ascender}{\the\a_count}}}
297 \afm_def{Descender}(#1){
298 \afm_length\a_count{#1}
299 \out_line{\string\setint{descender_neg}{\the\a_count}}}
300 \afm_def{UnderlineThickness}(#1){
301 \afm_length\a_count{#1}
302 \out_line{\string\setint{underlinethickness}{\the\a_count}}}
303 \afm_def{FontBBox}(#1~#2~#3~#4){
304 \afm_length\a_count{#4}
305 \out_line{\string\setint{maxheight}{\the\a_count}}
306 \afm_length\a_count{#2}
307 \out_line{\string\setint{maxdepth_neg}{\the\a_count}}}
308 \afm_def{StdVW}(#1){
309 \afm_length\a_count{#1}
310 \out_line{\string\setint{verticalstem}{\the\a_count}}}
311 \afm_def{IsFixedPitch}(#1){
312 \if\first_char#1=f
313 \else\out_line{\string\setint{monowidth}{1}}
314 \fi

315 }

\afm-FontName The FontName of a font is needed for the \storemapdata command, so it is when that is encountered that this is written. This information is of no use when making TFMs and VFs, but it is likely to be of use for generation of map files, so it will be included in a file of recorded transforms, if such a file is being generated.

316 \afm_def{FontName}(#1~){
317 \record_transform{\raw_font_name}
318  {\string\fromafm{\source_font_name}{#1}}{}\iftrue

319 }

Processing kern pairs. If one of the glyph name starts with a dot as in .notdef or .null the kern pair is ignored.

320 \afm_def{KP}(#1~#2~#3~#4){
321 \if\first_char#1=.\else
322 \if\first_char#2=.\else
323  \afm_length\a_count{#3}
324  \ifnum \a_count>\minimum_kern
325  \out_line{\string\setkern{#1}{#2}{\the\a_count}}
326  \else\ifnum \a_count<-\minimum_kern
327  \out_line{\string\setkern{#1}{#2}{\the\a_count}}
328  \fi\fi
329 \fi\fi

330 }

331 \afm_let{KPX}{KP}

Processing char metrics.

332 \afm_def{C}(#1~;#2){\init_afm{#1}\do_list[#2]\afm_char}
333 \afm_let{CH}{C}

Processing composite chars.

334 \afm_def{CC}(#1~#2~;#3){\init_cc{#1}\do_list[#3]\cc_char}

When parsing a character, we set the values of the following variables:

335 \newcount\char_slot
336 \newcount\char_x_width
337 \newcount\x_width
338 \newcount\bbox_llx
339 \newcount\bbox_lly
340 \newcount\bbox_urx
341 \newcount\bbox_ury
342 \let\char_name=\empty_command

\init_afm initializes the variables the AFM character list writes to.

343 \def\init_afm#1{
344 \char_slot=#1\x_relax
345 \x_width=\char_x_width
346 \bbox_llx=0
347 \bbox_lly=0
348 \bbox_urx=0
349 \bbox_ury=0
350 \let\char_name=\empty_command

351 }

352 \def\afm_char{
353 \a_count=-\bbox_lly
354 \eval_expr{
355  \italcorr_expression\x_width\bbox_llx\bbox_urx\bbox_lly\bbox_ury

356 }

357 \out_line{
358  \ifnum -1<\char_slot
359  \string\setrawglyph
360  \else
361  \string\setnotglyph
362  \fi
363  {\char_name}
364  {\raw_font_name}
365  {10pt}
366  {\the\char_slot}
367  {\the\x_width}
368  {\the\bbox_ury}
369  {\the\a_count}
370  {\the\result}

371 } 372 }

\init_cc and \cc_char write out a composite character glyph.

373 \def\init_cc#1{%
374 \out_line{\string\setglyph{#1}}
375 \def\char_name{#1}

376 }

377 \def\cc_char{%
378 \out_lline{\string\samesize{\char_name-not}}
379 \out_line{\string\endsetglyph}

380 }

\italcorr_expression The way the italic correction is computed has been changed quite a bit, although the computed values are still the same. The point is that it is much simpler to modify the formula according to which the value is computed using this method than using the previous method.

The call

\italcorr_expression{⟨width⟩}{⟨left⟩}{⟨right⟩}{⟨bottom⟩}{⟨top⟩},

where the arguments are TEX ⟨number⟩s, should expand to an integer expression. The value of that expression will be taken as the italic correction of the current character.

⟨width⟩ is the width of the character. ⟨left⟩, ⟨right⟩, ⟨bottom⟩, and ⟨top⟩ are the respective coordinates of the sides of the bounding box of the character. A quantity which is not given as an argument, but which nontheless might be of interest for a calculation of italic correction, is the italic slant of the font. This quantity can be found in the fontinst integer italicslant. (The MTX file written will also set the integer italicslant to this value.)

\uprightitalcorr \slanteditalcorr These two commands are what \italcorr_expression will get set to—the slanted

version is used if the italic slant is positive and the upright version is used otherwise. The default definitions compute the same values as in fontinst v 1.8, but the definitions can easily be modified using \resetcommand.

381 \def\uprightitalcorr#1#2#3#4#5{0}
382 \def\slanteditalcorr#1#2#3#4#5{\max{\sub{#3}{#1}}{0}}

\calculate_it_slant To set the italic angle, we need to calculate the tangent of the angle that the .afm file contains. This is done with David Carlisle’s trig macros. Note that the trig macros don’t like a space at the end of their argument.

383 \def\calculate_it_slant#1{
384 \edef\theangle{#1}
385 \CalculateTan{\theangle}
386 \a_dimen=-\one_thousand sp
387 \a_dimen=\UseTan{\theangle}\a_dimen
388 \a_count=\a_dimen
389 \out_line{\string\setint{italicslant}{\the\a_count}}
390 \x_resetint{italicslant}{\a_count}
391 \ifnum 0<\a_count
392  \let\italcorr_expression=\slanteditalcorr
393 \else
394  \let\italcorr_expression=\uprightitalcorr
395 \fi

396 }

397 % \def\strip_spaces#1~#2\end_strip_spaces{#1}

To process a list of commands separated by semi-colons, we call \do_list[LIST]. This works in a similar way to \afm_line.

398 \def\do_list[~#1~#2;~#3]{
399 \csname~list-#1\endcsname\gobble_one_semi#2;
400 \ifx\x_relax#3\x_relax\expandafter\gobble_one
401 \else\expandafter\identity_one\fi
402 {\do_list[~#3]}

403 }

404 \def\gobble_one_semi#1;{}

There is an analagous \list_def for defining commands to be used inside lists.

405 \def\list_def#1(#2)#3{\x_cs\def{list-#1}\gobble_one_semi#2~;{#3}}

For example, these are the commands that are used in giving character metrics:

406 \list_def{W}(#1~#2){\afm_length\x_width{#1}}
407 \list_def{WX}(#1){\afm_length\x_width{#1}}
408 \list_def{WY}(#1){}
409 \list_def{N}(#1){\def\char_name{#1}}
410 \list_def{B}(#1~#2~#3~#4){
411 \afm_length\bbox_llx{#1}
412 \afm_length\bbox_lly{#2}
413 \afm_length\bbox_urx{#3}
414 \afm_length\bbox_ury{#4}

415 }

416 \list_def{PCC}(#1~#2~#3){
417 \afm_length\a_count{#2}
418 \afm_length\b_count{#3}
419 \out_lline{\string\glyphpcc{#1}{\the\a_count}{\the\b_count}}

420 }

15.5 Converting a PL file to an MTX file

\generalpltomtx The macro

\generalpltomtx{⟨plfile⟩}{⟨mtxfile⟩}{⟨plsuffix⟩}{⟨opt-enc⟩}

reads ⟨plfile⟩.⟨plsuffix⟩, interprets it as having the encoding specified by the file ⟨opt-enc⟩.etx, and writes the same metric information out to ⟨mtxfile⟩.mtx. In case ⟨opt-enc⟩ is empty, the encoding will be determined using the CODINGSCHEME

\pltomtx property of the file being read. The macro

\pltomtx{⟨plfile⟩}{⟨mtxfile⟩}

reads ⟨plfile⟩.pl, uses the CODINGSCHEME property in that file to determine its encoding, and writes the same metric information out to ⟨mtxfile⟩.mtx.

None of these commands can cope with SKIP properties in the (V)PL file.

\generalpltomtx
421 \def\generalpltomtx#1#2#3#4{{
422 \let\setsomething_global=\x_relax
423 \let\setfontdimen=\pl_setfontdimen
424 \if _#4_\else
425  \def\do_slot{\x_cs\let{name-\the\slot_number}\slot_name}
426  \def\do_boundary{\x_cs\let{name-BOUNDARYCHAR}\slot_name}
427  \inputetx{#4}
428  \let\CODINGSCHEME=\ignore_parens
429 \fi
430 \pl_to_mtx{#1}{#2}{#3}{\string\generalpltomtx{#1}{#2}{#3}{#4}}

431 }}

\pltomtx
432 \def\pltomtx#1#2{\generalpltomtx{#1}{#2}{pl}{}}

\pl_to_mtx The \pl_to_mtx macro contains all code that was common to \pltomtx and \generalpltomtx before the former was redefined to a call of the latter. The structure of a call of \pl_to_mtx is

\pl_to_mtx{⟨plfile⟩}{⟨mtxfile⟩}{⟨plsuffix⟩}{⟨call⟩}

⟨call⟩ is what should be written in the “Created using:” comment at the top of the MTX file written.

433 \def\pl_to_mtx#1#2#3#4{
434 \edef\raw_font_name{#1}
435 \open_out{\temp_prefix#2.mtx}
436 \out_line{\percent_char~Filename:~#2.mtx}
437 \out_line{\percent_char~Created~by:~tex~\jobname}
438 \out_line{\percent_char~Created~using:~#4}
439 \out_line{}
440 \out_line{\percent_char~This~file~contains~the~
441  information~of~#1.#3~in~a~form}
442 \out_line{\percent_char~more~easily~read~by~TeX.~
443  It~is~used~by~the~fontinst~package.}
444 \out_line{}
445 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
446 \out_line{}
447 \out_line{\string\relax}
448 \out_line{\string\metrics}
449 \out_line{}
450 \out_line{\string\needsfontinstversion{\fontinstversion}}
451 \out_line{}
452 \lowercase{
453  \record_transform{#2}{
454  \string\from#3 \x_cs\ifx{from#3}\frompl {#1} \fi
455  }{}\iftrue

456 }

457 \out_line{}
458 \catcode`\(=0 \catcode`\)=9
459 \let\/=\ignore_parens
460 \let\do_pl_glyph=\x_relax
461 \primitiveinput #1.#3\x_relax
462 \do_pl_glyph
463 \out_line{}
464 \ifisint{\percent_char boundarychar}\then
465  \f_count=\int{\percent_char boundarychar}
466  \x_cs\ifx{name-\the\f_count}\x_relax \else
467  \out_line{\string\setstr{rightboundary}
468  {\csname name-\the\f_count\endcsname}

469 }

470  \out_line{}
471  \fi
472 \fi
473 \out_line{\endmetrics_text}
474 \close_out{Metrics}

475 }

To parse a .pl file, we first make ( the escape character, make ) ignored, then define the various PL commands as TEX control sequences. We can ignore a parenthesis matched string by making ( and ) the group delimiters, then gobbling them up.

476 \def\ignore_parens{\bgroup\catcode`(=1 \catcode`)=2 \x_relax
477 \expandafter\expandafter\expandafter\gobble_parens
478  \iftrue\expandafter{\else}\fi}
479 \def\gobble_parens#1{\egroup}

\pl_real \pl_realer Convert a PL real to an AFM unit, assuming it contains a decimal point.

480 \def\pl_real#1{\pl_realer(#1000)}
481 \def\pl_realer(#1.#2#3#4#5){#1#2#3#4}

\pl_real only works if the DESIGNUNITS setting is at the default value 1. Luckily, this is what TFtoPL and VFtoVP use in all (V)PL files they create, so you can always get a (V)PL file that will work by converting first to TFM (+ VF) and then back again. As of v 1.913, that is also the value fontinst uses for all VPL files it generates, so the problem isn’t particularly important.

\pl_rounded_real The \pl_rounded_real macro is like \pl_realer in that it converts a PL unit

containing a decimal point to an AFM unit. The difference is (i) that it rounds the number rather than truncating it and (ii) that it stores the result in \result rather than expanding to it. Note that the actual real (character string) to convert must be followed by at least four zeros for the conversion to work correctly in all cases.

482 \def\pl_rounded_real(#1.#2#3#4#5){
483 \global\result=#1#2#3#4\relax
484 \ifnum \first_char#5= >4
485  \global\advance \result
486  \if - \first_char#1= \m@ne \else \@ne \fi
487 \fi

488 }

\pl_int Convert a PL int to a TEX int, assuming it’s prefixed by C, D, O, or H.

489 \def\pl_int#1#2{
490 \ifx#1C `#2
491 \else\ifx#1D #2
492 \else\ifx#1O '#2
493 \else\ifx#1H "#2
494 \else -1\errmessage{Unknown~PL~number~prefix~`#1'}
495 \fi\fi\fi\fi

496 }

Many of the PL commands are ignored, and I’m assuming the Rs are in the places tftopl puts them, which is a bit naughty of me.

FAMILY property

FACE property

CHECKSUM property

HEADER property

SEVENBITSAFEFLAG property

497 \let\FAMILY=\ignore_parens
498 \let\FACE=\ignore_parens
499 \let\CHECKSUM=\ignore_parens
500 \def\HEADER~#1~#2~#3~#4~{}
501 \def\SEVENBITSAFEFLAG~#1~{}

COMMENT property

LIG property

NEXTLARGER property

VARCHAR property

502 \let\COMMENT=\ignore_parens

503 \let\LIG=\ignore_parens
504 \let\NEXTLARGER=\ignore_parens
505 \let\VARCHAR=\ignore_parens

VTITLE property MAPFONT property MAP property The properties which are unique for VPL files—VTITLE, MAPFONT, MAP,

FONTNAME, FONTAREA, FONTCHECKSUM, FONTAT, FONTDSIZE, SELECTFONT, SETCHAR,
SETRULE, MOVERIGHT, MOVELEFT, MOVEUP, MOVEDOWN, PUSH, POP, SPECIAL, and

SPECIALHEX—should also be ignored, but it is actually sufficient to ignore the first three since the others are only allowed inside MAP or MAPFONT property lists.

506 \let\VTITLE=\ignore_parens
507 \let\MAPFONT=\ignore_parens
508 \let\MAP=\ignore_parens

CODINGSCHEME property \CODINGSCHEME_cont When we reach a CODINGSCHEME instruction, we read the coding string, and read

in the corresponding ⟨encoding⟩.etx file.

The corresponding ⟨encoding⟩ is specified by \declareencoding statements (see below). Each \declare_encoding defines a macro \enc-⟨codingscheme⟩ which expands to ⟨encoding⟩.

If the PL file is converted using the \generalpltomtx command with a nonempty ⟨opt-enc⟩ argument then the CODINGSCHEME instruction is ignored since an encoding file has already been read in.

509 \def\CODINGSCHEME{\bgroup\catcode`\)=12\x_relax\CODINGSCHEME_cont}
510 \def\CODINGSCHEME_cont#1){
511 \egroup
512 \if_undefined{enc-#1}\then
513  \errhelp{The~encoding~for~`#1'~has~not~been~declared.^^J
514  You~should~declare~it~with~
515  \string\declareencoding{#1}{ETXFILE}.^^J
516  Press~<RETURN>~to~carry~on~with~fingers~crossed,^^J
517  or~X~<RETURN>~to~exit.}
518  \errmessage{Undeclared~encoding~`#1'}
519 \else
520  \def\do_slot{\x_cs\let{name-\the\slot_number}\slot_name}
521  \def\do_boundary{\x_cs\let{name-BOUNDARYCHAR}\slot_name}
522  \catcode`\(=12 \catcode`\)=12
523  \x_cs\inputetx{enc-#1}\x_relax
524  \catcode`\(=0 \catcode`\)=9
525 \fi

526 }

DESIGNSIZE property The DESIGNSIZE is needed because the FONTDSIZE specified in a MAPFONT property list has to be the same as the DESIGNSIZE of the corresponding base font.

527 \def\DESIGNSIZE~#1~#2~{
528 \a_dimen=#2pt
529 \out_line{\string\setdim{designsize}{\the\a_dimen}}

530 }

DESIGNUNITS property The PL to MTX converter assumes that the (V)PL files to convert look like the ones created by TFtoPL/VFtoVP, and the interpretation of the DESIGNUNITS property is one thing specifically affected by this. The TFM file format does not store the DESIGNUNITS value used, so the two above programs always generate (V)PL files with the default setting of design unit equal to the design size. Hence any occurence of the DESIGNUNITS property with a nondefault value is an indication of an error.

The incorrect metrics can be corrected by scaling by a suitable amount (1000 divided by the designunits dimen), but it is much simpler to convert the PL to a TFM and then convert it back, that will also fix the units.

531 \def\DESIGNUNITS~#1~#2~{
532 \b_dimen=#2pt\x_relax
533 \ifdim 1pt=\b_dimen \else
534  \fontinsterror{PL-to-MTX}{Nondefault~unit~used~in~PL~file}
535  {You~may~continue,~but~the~metrics~for~this~font~will~be~wrong.}
536 \fi
537 \out_line{\string\setdim{designunits}{\the\b_dimen}}

538 }

BOUNDARYCHAR property
539 \def\BOUNDARYCHAR~#1~#2~{
540 \x_setint{\percent_char boundarychar}{\pl_int{#1}{#2}}

541 }

Declared fontdimens are converted to \setint commands in the MTX file. A

\fdimen-⟨n⟩ fontdimen declaration for fontdimen n is stored in the control sequence \fdimen-n; if this control sequence is undefined then the fontdimen is not declared and if it is set then it is a macro which expands to the name of the corresponding integer variable.

\pl_setfontdimen Fontdimens are declared by the \pl_setfontdimen macro, which is a definition of \setfontdimen that is used during (V)PL-to-MTX conversion.

542 \def\pl_setfontdimen#1#2{\x_cs\def{fdimen-#1}{#2}}

PARAMETER property The PARAMETER property is the generic specifier of fontdimens in (V)PL files. It takes two arguments: the fontdimen number (integer) and value (real).

543 \def\PARAMETER~#1~#2~R~#3~{
544 \f_count=\pl_int{#1}{#2}\x_relax
545 \if_defined{fdimen-\the\f_count}\then
546  \pl_rounded_real(#3 0000)
547  \out_line{\string\setint{\csname fdimen-\the\f_count\endcsname}
548  {\the\result}}
549 \fi

550 }

FONTDIMEN property No special processing is required for the FONTDIMEN property.

551 \let\FONTDIMEN=\x_relax

SLANT property SPACE property STRETCH property SHRINK property XHEIGHT property QUAD property EXTRASPACE property The properties for the seven mandatory fontdimens are converted to the corresponding PARAMETER properties but their meanings are predeclared. The effect of these predeclarations is that even ETX files that don’t use \setfontdimen to set the fontdimens have these fontdimens converted to \setints.

A scan shows that the current (2001/03/17) MTX and ETX files aren’t using

the integers stretchword, shrinkword, quad, and extraspace. They probably

should.

552 \def\SLANT{\PARAMETER D~1~}
553 \pl_setfontdimen{1}{italicslant}

554 \def\SPACE{\PARAMETER D~2~}
555 \pl_setfontdimen{2}{interword}
556 \def\STRETCH{\PARAMETER D~3~}
557 \pl_setfontdimen{3}{stretchword}
558 \def\SHRINK{\PARAMETER D~4~}
559 \pl_setfontdimen{4}{shrinkword}
560 \def\XHEIGHT{\PARAMETER D~5~}
561 \pl_setfontdimen{5}{xheight}
562 \def\QUAD{\PARAMETER D~6~}
563 \pl_setfontdimen{6}{quad}
564 \def\EXTRASPACE{\PARAMETER D~7~}
565 \pl_setfontdimen{7}{extraspace}

NUM∗ properties DENOM∗ properties The NUM∗ and DENOM∗ properties are for fontdimens 8–10 and 11–12. They have to do with positioning numerator and denominator in fractions.

566 \def\NUM#1~#2~#3~{
567 \ifcase #1\or
568  \PARAMETER D~8~#2~#3~
569 \or
570  \PARAMETER D~9~#2~#3~
571 \or
572  \PARAMETER D~10~#2~#3~
573 \fi

574 }

575 \def\DENOM#1~#2~#3~{
576 \ifcase #1\or
577  \PARAMETER D~11~#2~#3~
578 \or
579  \PARAMETER D~12~#2~#3~
580 \fi

581 }

SUP∗ properties SUB∗ properties The SUP∗ and SUB∗ properties are for fontdimens 13–15 and 16–17. They have to do with positioning superscripts and subscripts.

582 \def\SUP#1~#2~#3~{
583 \ifcase #1\or
584  \PARAMETER D~13~#2~#3~
585 \or
586  \PARAMETER D~14~#2~#3~
587 \or
588  \PARAMETER D~15~#2~#3~
589 \fi

590 }

591 \def\SUB#1~#2~#3~{
592 \ifcase #1\or
593  \PARAMETER D~16~#2~#3~
594 \or
595  \PARAMETER D~17~#2~#3~
596 \fi

597 }

SUPDROP property SUBDROP property AXISHEIGHT property These are fontdimens 18, 19, and 22.

598 \def\SUPDROP{\PARAMETER D~18~}
599 \def\SUBDROP{\PARAMETER D~19~}

600 \def\AXISHEIGHT{\PARAMETER D~22~}

DELIM∗ properties The DELIM∗ fondimens have number 20 and 21. They have to do with the size of delimiters put around a generalised fraction.

601 \def\DELIM#1~#2~#3~{
602 \ifcase #1\or
603  \PARAMETER D~20~#2~#3~
604 \or
605  \PARAMETER D~21~#2~#3~
606 \fi

607 }

DEFAULTRULETHICKNESS property BIGOPSPACING∗ properties The fontdimen properties that are special for math extension fonts are DEFAULT-

RULETHICKNESS and the various BIGOPSPACING∗.
608 \def\DEFAULTRULETHICKNESS{\PARAMETER D~8~}
609 \def\BIGOPSPACING#1~#2~#3~{
610 \ifcase #1\or
611  \PARAMETER D~9~#2~#3~
612 \or
613  \PARAMETER D~10~#2~#3~
614 \or
615  \PARAMETER D~11~#2~#3~
616 \or
617  \PARAMETER D~12~#2~#3~
618 \or
619  \PARAMETER D~13~#2~#3~
620 \fi

621 }

This is the old definition of \DEFAULTRULETHICKNESS for historical references (since its behaviour has changed).

622 % \def\DEFAULTRULETHICKNESS~R~#1~{
623 %    \out_line{\string\setint{underlinethickness}{\pl_real{#1}}}

624 % }

LABEL property \LABEL_slot \LABEL_boundarychar \do_if_defined The most complicated part of the processing of the LIGTABLE property list is that it has to keep track of which glyphs the current ligature/kerning program applies to. This stored as a \do{⟨glyph⟩} list in \a_macro and building this list is the job of the LABEL property.

It is assumed that \do is \never_do whenever some element is added to

\a_macro.
625 \def\LABEL~#1{\ifx #1B
626  \expandafter\LABEL_boundarychar
627 \else
628  \expandafter\LABEL_slot \expandafter#1
629 \fi

630 }

631 \def\LABEL_slot #1~#2~{
632 \f_count=\pl_int{#1}{#2}
633 \edef\a_macro{\a_macro
634  \x_cs\do_if_defined{name-\the\f_count}

635 } 636 }

637 \def\LABEL_boundarychar OUNDARYCHAR{
638 \edef\a_macro{\a_macro
639  \x_cs\do_if_defined{name-BOUNDARYCHAR}

640 } 641 }

642 \def\do_if_defined#1{\ifx #1\x_relax \else \do{#1} \fi}

LIGTABLE property STOP property SKIP property The LIGTABLE, STOP, and SKIP properties are the remaining properties involved in managing the \a_macro list. SKIP properties are not processed.

643 \def\LIGTABLE{\let\do=\never_do\let\a_macro\empty_command}
644 \def\STOP{\let\a_macro\empty_command}
645 \def\SKIP~#1~#2~{\immediate\write16{Warning:~SKIP~instruction~ignored.}}

KRN property \write_pl_krn KRN properties are converted to \setkern instructions.

646 \def\KRN~#1~#2~R~#3~{
647 \pl_rounded_real(#3 0000)
648 \edef\do{\noexpand\write_pl_krn{\pl_int{#1}{#2}}{\the\result}}
649 \a_macro
650 \let\do=\never_do

651 }

652 \def\write_pl_krn#1#2#3{
653 \f_count=#1\x_relax
654 \x_cs\ifx{name-\the\f_count}\x_relax \else
655  \out_line{\string\setkern{#3}
656  {\csname name-\the\f_count\endcsname}{#2}

657 }

658 \fi

659 }

CHARACTER property CHARWD property CHARHT property CHARDP property CHARIC property The character metrics that are processed are CHARWD, CHARHT, CHARDP, and CHARIC. The CHARACTER property takes care of writing the information to the MTX file, but note that each new CHARACTER property writes the information from the preceeding

 CHARACTER property.
660 \def\CHARWD~R~#1~{\pl_rounded_real(#1 0000) \b_count=\result}
661 \def\CHARHT~R~#1~{\pl_rounded_real(#1 0000) \c_count=\result}
662 \def\CHARDP~R~#1~{\pl_rounded_real(#1 0000) \d_count=\result}
663 \def\CHARIC~R~#1~{\pl_rounded_real(#1 0000) \e_count=\result}
664 \def\CHARACTER~#1~#2~{
665 \do_pl_glyph
666 \a_count=\pl_int{#1}{#2}
667 \b_count=0
668 \c_count=0
669 \d_count=0
670 \e_count=0
671 \let\do_pl_glyph=\write_pl_glyph

672 }

\write_pl_glyph The \write_pl_glyph actually writes the information contained in a CHARACTER property list to the MTX file as a \setrawglyph command.

673 \def\write_pl_glyph{
674  \x_cs\ifx{name-\the\a_count}\x_relax\else
675  \out_line{\string\setrawglyph
676  {\csname~name-\the\a_count\endcsname}

677  {\raw_font_name}
678  {\the\a_dimen}
679  {\the\a_count}
680  {\the\b_count}
681  {\the\c_count}
682  {\the\d_count}
683  {\the\e_count}}
684  \fi

685 }

15.6 Converting an MTX file to a PL file

\mtxtopl The macro

\mtxtopl{⟨mtxfile⟩}{⟨plfile⟩}

writes a font from the \setrawglyph instructions in ⟨mtxfile⟩ to ⟨plfile⟩. It ignores any font dimensions and kerning, so the resulting font is only useful for generating virtual fonts from. (This macro is called by \transformfont.)

\mtxtopl
686 \def\mtxtopl#1#2{{
687 \let\setsomething_global=\x_relax
688 \open_out{#2.pl}
689 \top_of_pl_hook
690 \out_line{(COMMENT~raw~font~#2~created~by~fontinst~
691  v\fontinstversion)}
692 \out_line{}
693 \out_line{(COMMENT~Filename:~#2.pl)}
694 \out_line{(COMMENT~Created~by:~tex~\jobname)}
695 \out_line{(COMMENT~Created~using:~\string\mtxtopl{#1}{#2})}
696 \out_line{}
697 \out_line{(COMMENT~This~file~can~be~turned~into~
698  a~ligless~TeX~font~with)}
699 \out_line{(COMMENT~pltotf~#2.pl~#2.tfm)}
700 \out_line{}
701 \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)}
702 \out_line{}
703 \out_line{(DESIGNSIZE~R~10.0)}
704 \out_line{}
705 \let\setglyph=\iffalse
706 \let\endsetglyph=\fi
707 \let\setkern=\gobble_three
708 \let\setscaledrawglyph=\first_pl_raw_glyph
709 \def\setscalednotglyph##1##2##3##4##5##6##7##8##9{}
710 \inputmtx{#1}
711 \out_line{}
712 \out_line{(COMMENT~END~OF~FILE~#2.pl)}
713 \close_out{Raw~font}

714 }}

\first_pl_raw_glyph The \first_pl_raw_glyph writes the DESIGNUNITS property for the font when

the first \setscaledrawglyph is encountered. This is to undo the scaling that has already been applied to the metrics, so that the metrics will match the actual font.

715 \def\first_pl_raw_glyph#1#2#3#4{
716 \out_line{(DESIGNUNITS~R~\make_factor{#4})}
717 \let\setscaledrawglyph=\pl_raw_glyph
718 \pl_raw_glyph{#1}{#2}{#3}{#4}

719 }

\pl_raw_glyph
720 \def\pl_raw_glyph#1#2#3#4#5#6#7#8#9{
721 \out_line{(CHARACTER~D~\number#5~\space(COMMENT~#1)}
722 \out_lline{(CHARWD~R~\make_factor{#6})}
723 \out_lline{(CHARHT~R~\make_factor{#7})}
724 \out_lline{(CHARDP~R~\make_factor{#8})}
725 \out_lline{(CHARIC~R~\make_factor{#9})}
726 \out_lline{)}

727 }

16 Font transformations

16.1 Transformable metric files

A transformable metric file is a metric file which complies with certain restrictions in its syntax. The only metric commands allowed are

\setscaledrawglyph{⟨glyph⟩}{⟨font⟩}{⟨size⟩}{⟨scale⟩}{⟨slot⟩}{⟨width⟩}

{⟨height⟩}{⟨depth⟩}{⟨italic⟩} \setrawglyph{⟨glyph⟩}{⟨font⟩}{⟨size⟩}{⟨slot⟩}{⟨width⟩}{⟨height⟩}

{⟨depth⟩}{⟨italic⟩} \setscalednotglyph{⟨glyph⟩}{⟨font⟩}{⟨size⟩}{⟨scale⟩}{⟨slot⟩}{⟨width⟩}

{⟨height⟩}{⟨depth⟩}{⟨italic⟩} \setnotglyph{⟨glyph⟩}{⟨font⟩}{⟨size⟩}{⟨slot⟩}{⟨width⟩}{⟨height⟩}

{⟨depth⟩}{⟨italic⟩} \setkern{⟨glyph1 ⟩}{⟨glyph2 ⟩}{⟨amount⟩}

     \setglyph{⟨glyph⟩} ⟨glyph commands⟩ \endsetglyph

where ⟨glyph⟩, ⟨glyph1 ⟩, ⟨glyph2 ⟩, and ⟨font⟩ are strings without any variable references (no \str or \strint are allowed), ⟨scale⟩, ⟨slot⟩, ⟨width⟩, ⟨height⟩, ⟨depth⟩, ⟨italic⟩, and ⟨amount⟩ are TEX numbers, and ⟨size⟩ is a TEX dimen. (More accurately, all dimens in a transformable metric file should be on the form ⟨optional signs⟩⟨decimal constant⟩⟨physical unit⟩, but that’s at the “dangerous bend” level.) The ⟨glyph⟩s may be of the form

\aliased{⟨font’s name⟩}{⟨alias name⟩}

Such ⟨glyph⟩s are interpreted as ⟨alias name⟩ for all purposes except reencoding, when they are interpreted as ⟨font’s name⟩. ⟨glyph⟩s of this form are furthermore copied as they are to MTX files created by \transformfont (\mtxtomtx).

The only ⟨glyph commands⟩ allowed are

     \samesize{⟨glyph⟩}

\glyphpcc{⟨glyph⟩}{⟨xoffset⟩}{⟨yoffset⟩} where ⟨glyph⟩ is as above, and ⟨xoffset⟩ and ⟨yoffset⟩ are TEX numbers.

The only general commands allowed are

     \needsfontinstversion{⟨version⟩}

\setint{⟨name⟩}{⟨number⟩} \setdim{⟨name⟩}{⟨dimen⟩} \setstr{⟨name⟩}{⟨string⟩} \storemapdata{⟨font⟩}{⟨source⟩}{⟨transformations⟩}

where ⟨name⟩ and ⟨string⟩ are strings without variable references, ⟨number⟩ is a TEX number, and ⟨dimen⟩ is a TEX dimen. The arguments of \needsfontinstversion and \storemapdata are as usual, but these commands do not get copied in a font transformation.

The metric files produced by \afmtomtx and \generalpltomtx are meant to be transformable. If they are not then there is a bug somewhere.

The name of the integer in \setint commands is interpreted. This name is used to determine how the number should be transformed, see the implementation

of \mtxtomtx_setint below.

16.2 Making font transformations

\transformfont The macro:

\transformfont{⟨font-name⟩}{⟨transformed font⟩}

transforms the metrics of a raw font. As far as TEX is concerned, ⟨font-name⟩ will be a new font. Actually doing the transformation and providing the transformed font (as opposed to the metrics of the transformed font) is for most transforms up to some other piece of software, in most cases the DVI driver, but fontinst will handle isotropic scaling itself.

The easiest way to find out which transformations need to be carried out is to generate a map file for the debug “driver” (see Section 18). Of course, if fontinst can generate a mapfile for the target driver then you probably don’t need to find out which transformations were necessary … In any case, the arguments of \storemapdata in the MTX file generated will tell which transformations of this \transformfont command that must be performed by some other software.

\fromafm The ⟨transformed font⟩ commands are:

\frommtx
\frompl
\scalefont
\xscalefont
\yscalefont
\slantfont
\reencodefont

     \fromafm{⟨AFM file⟩}
     \frompl{⟨PL file⟩}
     \fromplgivenetx{⟨PL file⟩}{⟨etx⟩}
     \frommtx{⟨MTX file⟩}
     \fromany{⟨file⟩}

\scalefont{⟨integer expression⟩}{⟨transformed font⟩} \xscalefont{⟨integer expression⟩}{⟨transformed font⟩} \yscalefont{⟨integer expression⟩}{⟨transformed font⟩} \slantfont{⟨integer expression⟩}{⟨transformed font⟩} \reencodefont{⟨etx⟩}{⟨transformed font⟩}

Each \transformfont command generates an .mtx file for ⟨font-name⟩ and a corresponding raw .pl file, which is written out by \mtxtopl.

   Each \fromafm, \frompl, or \fromplgivenetx command also generates an

.mtx file for the source font, which is written out by \afmtomtx or \generalpltomtx.

In addition, \fromafm also uses \mtxtopl to generate a corresponding raw .pl file.

\fromany reads an MTX, PL, AFM, or VPL file depending on what it can find. It tries them in the order first MTX, then PL, then AFM, and last VPL.

\transformfont
728 \def\transformfont#1#2{{
729 \let\setsomething_global=\x_relax
730 \unsetstr{afm-name}
731 \unsetstr{etx-name}
732 \x_resetint{x-scale}{\one_thousand}
733 \x_resetint{y-scale}{\one_thousand}
734 \x_resetint{slant-scale}{0}

735 #2

736 \ifisstr{afm-name}\then
737  \mtxtomtx{\str{afm-name}}{#1}
738  \mtxtopl{#1}{#1}
739 \else
740  \fontinsterror{Transformfont}{
741  Failed~to~make~transformed~font~#1;\messagebreak
742  source~font~metrics~file~not~found
743  }\error_help_a
744 \fi

745 }}

\fromafm
746 \def\fromafm#1{
747 \if_file_exists{#1.afm}\then
748  \x_setstr{afm-name}{#1}
749  \afmtomtx{#1}{#1}
750  \mtxtopl{#1}{#1}
751 \fi

752 }

\frommtx
753 \def\frommtx#1{
754 \if_file_exists{#1.mtx}\then \x_setstr{afm-name}{#1} \fi

755 }

\frompl
\fromplgivenetx
756 \def\frompl#1{
757 \if_file_exists{#1.pl}\then
758  \x_setstr{afm-name}{#1}
759  \generalpltomtx{#1}{#1}{pl}{}
760 \fi

761 }

762 \def\fromplgivenetx#1#2{
763 \if_file_exists{#1.pl}\then
764  \x_setstr{afm-name}{#1}
765  \generalpltomtx{#1}{#1}{pl}{#2}
766 \fi

767 }

Regarding \fromvpl and \fromvplgivenetx: I realized that there isn’t any point in reading metrics for a font that is to be transformed from a VPL file, since no driver I know of can transform virtual fonts. If someone has a problem with this then I suppose he or she should send word about it. /LH

\fromany The \fromany transformed font command searches for font metrics for #1 by looking for, in turn, the files #1.mtx, #1.pl, #1.afm, and #1.vpl. If an MTX file doesn’t exist, it is generated, and if the MTX is generated from an AFM then a corresponding (non-ligful) PL file is generated as well. \fromany also sets the fontinst string afm-name according to what kind of font it found. If none of the fonts existed then afm-name is unset.

768 \def\fromany#1{
769 \x_cs\edef{s-afm-name}{#1}
770 \if_file_exists{#1.mtx}\then\else

1997/01/15 SPQR changed the below search order to .pl before .afm because of the cmr*.afm files found in the TEXMF/fonts/afm hierarchy.

771  \if_file_exists{#1.pl}\then
772  \generalpltomtx{#1}{#1}{pl}{}
773  \else
774  \if_file_exists{#1.afm}\then
775  \afmtomtx{#1}{#1}
776  \mtxtopl{#1}{#1}
777  \else
778  \if_file_exists{#1.vpl}\then
779  \generalpltomtx{#1}{#1}{vpl}{}
780  \else
781  \unsetstr{afm-name}
782 \fi\fi\fi\fi

783 }

The mathematical basis for the metric font transformations

Mathematically, all the metric font transformations (\scalefont, \xscalefont, \yscalefont, and \slantfont) are linear mappings of the real plane onto itself. All quantities in a transformable metric file are interpreted as being determined by some point in this plane and hence their transformation depends on how that point would be moved by the metric font transformations performed. This is usually simpler than it sounds, since all quantities except italicslant are interpreted as either the x- or the y-coordinate of some point. italicslant is interpreted as the quotient \frac{x}{y} for a point.

The best way to describe a linear mapping of the real plane to itself is by a 2 × 2 matrix whose components are real numbers. Since true real numbers are not available in TEX, integers are used instead, with the convention that they are in units of thousandths. In a concrete form this means that 0 represents 0, 500 represents \frac{1}{2}, 1000 represents 1, etc. This works just as for the scaling factors used in \scale. It also means that the matrix

( \begin{matrix}1000 & 0 \\ 0 & 1000 \end{matrix} )

represents the identity mapping (the mapping taking everything to itself).

Thinking of points as column vectors (2 × 1 matrices) with the x-coordinate in the first component and the y-coordinate in the second, the respective elementary metric font transformations correspond to the following matrices:

\scalefont\{⟨n⟩\} is ( \begin{matrix}⟨n⟩ & 0 \\ 0 & ⟨n⟩ \end{matrix} )
\xscalefont\{⟨n⟩\} is ( \begin{matrix}⟨n⟩ & 0 \\ 0 & 1000 \end{matrix} )
\yscalefont\{⟨n⟩\} is ( \begin{matrix}1000 & 0 \\ 0 & ⟨n⟩ \end{matrix} )
\slantfont\{⟨n⟩\} is ( \begin{matrix}1000 & ⟨n⟩ \\ 0 & 1000 \end{matrix} )

Since all these matrices are upper triangular, all products of such matrices (corresponding to compositions of the linear mappings) will be upper triangular as well. It is therefore unnecessary to store the subdiagonal component anywhere (it is always zero), and hence fontinst represents an arbitrary metric transform by the matrix

                      ( \begin{matrix}x-scale & slant-scale \\ 0 & y-scale \end{matrix} )

where x-scale, y-scale, and slant-scale are fontinst integers.

The reason there is a representation of arbitrary metric transforms is that all the elementary metric transforms listed in the second argument of \transformfont are concatenated before the actual font file conversion is made. This reduces the amount of calculations performed in case there are many transformations of the font.

Why do we only consider transformations that correspond to upper triangular matrices? Well, a transformation corresponds to an upper triangular matrix if and only if it leaves horizontal lines horizontal. Since in particular the baseline must always be horizontal in TEX, there is no point in considering other linear transformations.

\scalefont
\xscalefont
\yscalefont
\slantfont
\reencodefont

784 \def\scalefont#1#2{
785 \eval_expr_to\d_count{#1}
786 \x_resetint{x-scale}{\scale{\d_count}{\int{x-scale}}}
787 \x_resetint{y-scale}{\scale{\d_count}{\int{y-scale}}}
788 \x_resetint{slant-scale}{\scale{\d_count}{\int{slant-scale}}}

789 #2 790 }

791 \def\xscalefont#1#2{
792 \x_resetint{x-scale}{\scale{#1}{\int{x-scale}}}

793 #2 794 }

795 \def\yscalefont#1#2{
796 \eval_expr_to\d_count{#1}
797 \x_resetint{y-scale}{\scale{\d_count}{\int{y-scale}}}
798 \x_resetint{slant-scale}{\scale{\d_count}{\int{slant-scale}}}

799 #2 800 }

801 \def\slantfont#1#2{

802 \x_resetint{slant-scale}{
803  \add{\scale{#1}{\int{x-scale}}}{\int{slant-scale}}

804 } 805 #2 806 }

807 \def\reencodefont#1#2{

808 #2

809 \resetstr{etx-name}{#1}

810 }

That’s only half the story, however. It is true that the transformation matrix,

as computed by \scalefont, \slantfont, \xscalefont, and \yscalefont above,

is used for transforming the font metrics, but it is not directly used for transforming the font itself. Instead it is factorized as

( \begin{matrix}x & s \\ 0 & y \end{matrix} ) = y ( \begin{matrix}x/y & s/y \\ 0 & 1 \end{matrix} )

Here the scalar factor y will be used to scale the ⟨scale⟩ argument of \setscaledrawglyph and \setscalednotglyph commands, whereas the matrix factor will be put in the third argument of \storemapdata in the MTX file written. Thus fontinst will handle the scalar factor of the transformation itself, but leave the matrix factor for some other software to take care of.

\mtxtomtx  The macro:

\mtxtomtx{⟨source MTX ⟩}{⟨destination MTX ⟩}

converts the first .mtx file to the second, using the current values of \int{x-scale},

\int{y-scale}, \int{slant-scale}, and \str{etx-name}.

NOTE: this doesn’t convert arbitrary .mtx files, just the transformable ones.

\mtxtomtx
811 \def\mtxtomtx#1#2{{
812 \ifisstr{etx-name}\then
813  \def\do_slot{\x_cs\edef{slots-\slot_name}{\the\slot_number}}
814  \directfalse
815  \inputetx{\str{etx-name}}
816  \edef\a_macro{\string\reencodefont{\str{etx-name}}}
817 \else
818  \let\a_macro=\empty_command
819 \fi
820 \_a_true
821 \ifnum \int{x-scale}=\int{y-scale}
822  \ifnum \int{slant-scale}=\z@
823  \_a_false
824 \fi \fi
825 \if_a_
826  \a_count=\int{x-scale}
827  \l_inv_scale\a_count{\int{y-scale}}
828  \b_count=\int{slant-scale}
829  \l_inv_scale\b_count{\int{y-scale}}
830  \edef\a_macro{\a_macro
831  \string\transformfont{\the\a_count}{\the\b_count}

833 \fi
834 \open_out{\temp_prefix#2.mtx}
835 \edef\raw_font_name{#2}
836 \out_line{\percent_char~Filename:~#2.mtx}
837 \out_line{\percent_char~Created~by:~tex~\jobname}
838 \out_line{\percent_char~Created~using:~\string\mtxtomtx{#1}{#2}}
839 \out_line{}
840 \out_line{\percent_char~This~file~is~used~by~the~fontinst~package.}
841 \out_line{}
842 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
843 \out_line{}
844 \out_line{\string\relax}
845 \out_line{\string\metrics}
846 \out_line{}
847 \out_line{\string\needsfontinstversion{\fontinstversion}}
848 \out_line{}
849 \record_transform{#2}{\string\frommtx{#1}}{\a_macro}\iftrue
850 \out_line{}
851 \mtxtomtx_redefinitions
852 \inputmtx{#1}
853 \out_line{}
854 \out_line{\endmetrics_text}
855 \close_out{Transformed~metrics}

856 }}

\mtxtomtx_redefinitions This macro serves as a hook. One can make additional commands transformable by appending suitable redefenitions of them to this macro.

857 \def\mtxtomtx_redefinitions{
858 \let\setint=\mtxtomtx_setint
859 \let\setdim=\mtxtomtx_setdim
860 \let\setstr=\mtxtomtx_setstr
861 \let\setscaledrawglyph=\mtxtomtx_setscaledrawglyph
862 \let\setscalednotglyph=\mtxtomtx_setscaledrawglyph
863 \let\setkern=\mtxtomtx_setkern
864 \let\setglyph=\mtxtomtx_setglyph
865 \let\glyphpcc=\mtxtomtx_glyphpcc
866 \let\samesize=\mtxtomtx_samesize
867 \let\endsetglyph=\mtxtomtx_endsetglyph
868 \def\aliased{\string\aliased}

869 } 870 ⟨/pkg⟩

\aliased The \aliased macro has the syntax

\aliased{⟨font’s name⟩}{⟨alias name⟩}

This normally expands to ⟨alias name⟩, but in \mtxtomtx it normally expands to

\string\aliased{⟨font’s name⟩}{⟨alias name⟩}

and when \mtxtomtx_setscaledrawglyph is reencoding it uses ⟨font’s name⟩ to determine the new slot position.

871 ⟨pkg | misc⟩\let\aliased=\second_of_two
872 ⟨doc⟩\let\aliased=\@secondoftwo

\mtxtomtx_setint \italicslant_name \width_ints_list Most integers are transformed as if they are the y-coordinates of some points, but italicslant and the integers in the \width_ints_list are treated differently. italicslant is interpreted as the quotient \frac{x}{y} for a point (x, y), but represented as a real number (i.e., the TEX number is really a thousand times the actual quotient). The integers in the \width_ints_list are transformed as if they are the x-coordinates of some points on the baseline.

The \width_ints_list macro is an ordinary \do-type list where each \do has precisely one argument. These arguments are the names of the integers which should be transformed as widths. Elements can be added to the list using the

\add_to macro.

The test for whether a specific integer is in the \width_ints_list exploits that \if_true and \if_false only matter in \if–\fi matching after they have been expanded, whereas \gobble_one\iftrue only matters before it is expanded.

873 ⟨∗pkg⟩

874 \def\mtxtomtx_setint#1#2{
875 \def\a_macro{#1}
876 \ifx \a_macro\italicslant_name
877  \eval_expr{#2}
878  \global\multiply \result \int{x-scale}
879  \a_count=\int{slant-scale}
880  \multiply \a_count \one_thousand
881  \advance \a_count \result
882  \divide \a_count \int{y-scale}\x_relax
883 \else
884  \def\do##1{
885  \def\b_macro{##1}
886  \ifx \a_macro\b_macro \expandafter\if_false \fi

887 }

888  \gobble_one\iftrue \width_ints_list \if_true
889  \eval_expr_to\a_count{\scale{#2}{\int{y-scale}}}
890  \else
891  \eval_expr_to\a_count{\scale{#2}{\int{x-scale}}}
892  \fi
893 \fi
894 \out_line{\string\setint{#1}{\the\a_count}}

895 }

896 \def\italicslant_name{italicslant}
897 \def\width_ints_list{
898 \do{interword}\do{stretchword}\do{shrinkword}\do{quad}
899 \do{extraspace}\do{digitwidth}\do{verticalstem}

900 }

\mtxtomtx_setdim \mtxtomtx_setstr Strings and dimens are not affected by the \mtxtomtx transforms.

901 \def\mtxtomtx_setdim#1#2{
902 \out_line{\string\setdim{#1}{#2}}

903 }

904 \def\mtxtomtx_setstr#1#2{
905 \out_line{\string\setstr{#1}{#2}}

906 }

\mtxtomtx_setscaledrawglyph #6 (the width) is transformed as the x-coordinate of a point on the baseline. #7 and #8 (the height and depth respectively) are transformed as y-coordinates.

The depth should probably really have been transformed as the negative of a ycoordinate, but it comes out the same in the end anyway. #9 (the italic correction) is transformed as the x-coordinate of a point whose y-coordinate equals the height of the character. #4 (the scaling) is transformed as a y-coordinate.

If the italic slant of the font is negative then the italic correction should possibly be transformed as the x-coordinate of a point whose y-coordinate equals the negative of the depth instead (as that is the part of the box that is sticking out to the right), but it is hard to say for sure how that case should be treated.

907 \def\mtxtomtx_setscaledrawglyph#1#2#3#4#5#6#7#8#9{
908 \eval_expr_to\a_count{\scale{#6}{\int{x-scale}}}
909 \eval_expr_to\b_count{\scale{#7}{\int{y-scale}}}
910 \eval_expr_to\c_count{\scale{#8}{\int{y-scale}}}
911 \eval_expr_to\d_count{#9} \eval_expr{#7}
912 \multiply \d_count \int{x-scale}
913 \global\multiply \result \int{slant-scale}
914 \global\advance \result \d_count
915 \rounded_thousandths
916 \d_count=\result
917 \eval_expr{\scale{#4}{\int{y-scale}}}
918 \ifisstr{etx-name}\then
919  \bgroup
920  \let\aliased=\first_of_two
921  \if_undefined{slots-#1}\then
922  \egroup \e_count=\m@ne
923  \else
924  \expandafter\egroup \expandafter\e_count
925  \csname slots-#1\endcsname
926  \fi
927 \else
928  \e_count=#5
929 \fi
930 \out_line{
931  \ifnum \e_count>\m@ne
932  \string\setscaledrawglyph
933  \else
934  \string\setscalednotglyph
935  \fi
936  {#1}{\raw_font_name}{#3}{\the\result}{\the\e_count}
937  {\the\a_count}{\the\b_count}{\the\c_count}{\the\d_count}

938 } 939 }

\mtxtomtx_setkern Kerns are transformed as the x-coordinate of a point on the baseline.

940 \def\mtxtomtx_setkern#1#2#3{
941 \eval_expr{\scale{\int{x-scale}}{#3}}
942 \out_line{\string\setkern{#1}{#2}{\the\result}}

943 }

\mtxtomtx_setglyph
\mtxtomtx_samesize
\mtxtomtx_endsetglyph

944 \def\mtxtomtx_setglyph#1{\out_line{\string\setglyph{#1}}}
945 \def\mtxtomtx_samesize#1{\out_lline{\string\samesize{#1}}}
946 \def\mtxtomtx_endsetglyph{\out_line{\string\endsetglyph}}

\mtxtomtx_glyphpcc #2 is transformed as the x-coordinate and #3 is transformed as the y-coordinate of a point—the same point for both parameters.

947 \def\mtxtomtx_glyphpcc#1#2#3{
948 \eval_expr_to\b_count{\scale{\int{y-scale}}{#3}}
949 \eval_expr_to\a_count{#2} \eval_expr{#3}
950 \multiply \a_count \int{x-scale}
951 \global\multiply \result \int{slant-scale}
952 \global\advance \result \a_count
953 \rounded_thousandths
954 \out_lline{\string\glyphpcc{#1}{\the\result}{\the\b_count}}

955 }

16.3 Changing glyph names

fontinst uses names to identify glyphs, and if for example the font in question is a postscript font, then names will also be used to identify glyphs in the printer. Between those two points however, and in particular inside TEX itself, glyphs are represented with numbers (slots). Therefore there is no real need for the glyph names used within fontinst and the glyph names used in the printer (the names gotten from the AFM file) to be equal, but they usually are. There are some cases though where the glyph names of a font are unsuitable for use with fontinst— mainly because fontinst can mix glyphs from different printer fonts—and therefore fontinst also offers the ability to automatically change the names of glyphs in transformable metric files.

\reglyphfonts \endreglyphfonts        \reglyphfonts ⟨reglyphing commands⟩ \endreglyphfonts
956 \def\reglyphfonts{
957 \begingroup
958 \let\setsomething_global=\x_relax
959 \x_setint{renameweight}{1}
960 \x_setint{killweight}{-10}
961 \setcommand\iftokeep##1\then{\ifnum -1<##1}

962 }

963 \def\endreglyphfonts{\endgroup}

The ⟨reglyphing commands⟩ are

     \renameglyph{⟨to⟩}{⟨from⟩}
     \renameglyphweighted{⟨to⟩}{⟨from⟩}{⟨weight⟩}
     \killglyph{⟨glyph⟩}
     \killglyphweighted{⟨glyph⟩}{⟨weight⟩}
     \offmtxcommand{⟨command⟩}
     \onmtxcommand{⟨command⟩}

\reglyphfont{⟨destination font⟩}{⟨source font⟩}

The only reglyphing command that actually convert the names of any glyphs is

\reglyphfont \reglyphfont; it reads a font ⟨source font⟩ (which may be of type MTX, PL, AFM, or VPL) and writes another font ⟨destination font⟩ in which the names of glyphs have been converted. All the other commands control how this conversion should be made, and these settings get cleared at the closing \endreglyphfonts.

The conversion works in two ways. First of all, the names of the glyphs can be

\renameglyph changed. This works as a general mapping and is controlled by the \renameglyph \renameglyphweighted and \renameglyphweighted commands. Any mensioning of the glyph ⟨from⟩ in

a command will be converted to a mensioning of the glyph ⟨to⟩, if that command survives the conversion. The other way the conversion works is that it can selectively kill—refrain from including in ⟨destination font⟩—commands in the metric file. This part weighs in several factors.

For one thing, one can specify that all metric commands of a certain type should

\offmtxcommand be killed, and this is done with the \offmtxcommand command. For example, one can see to that all kerning commands are killed by

     \offmtxcommand{\setkern}

The effect is the same as that of saying

offkern,⟨destination font⟩,onkern

rather than just ⟨destination font⟩ in the second argument to \installfont, but it is somewhat faster since less text is written to and subsequently read from the ⟨destination font⟩.mtx file. The effect of a previous \offmtxcommand can be

\onmtxcommand canceled by a call to \onmtxcommand, just like with \offcommand and \oncommand.

The survivance of a command is also affected by the glyphs it refers to. Each glyph has a weight associated with it and the sum of the weights for all glyphs mensioned by a command is also used to decide whether that command should

\iftokeep survive. The test here is performed by the macro \iftokeep, whose parameter text must be #1\then, where #1 will be a \count register. This macro must eventually expand to an if of some sort and that if evaluating to true is interpreted as that the command should be kept. The default replacement text is \ifnum -1<#1, which causes a command to be killed (not kept) iff the sum of weights for it is negative.

\killglyph  The weight of a glyph is set by \renameglyph, \renameglyphweighted, \kill-
\killglyphweighted  glyph, and \killglyphweighted. The \rename. . . commands also set a new

name for the glyph if it survives, whereas the \kill… commands will keep the old name. Since the standard settings are that a \rename… weight is small and positive and a \kill… weight is large and negative, glyphs for which a \kill… has been done will usually not survive.

   Any one of \renameglyph, \renameglyphweighted, \killglyph, and \kill-

glyphweighted for a glyph will override all previous settings by any of these four commands for that glyph. The equivalent of the neutral state for a glyph (no settings by any of these commands have been made for that glyph) is achieved by the command

     \killglyphweighted{⟨glyph⟩}{0}
\offmtxcommand \onmtxcommand These two are just special forms of \offcommand and \oncommand.
964 \def\offmtxcommand#1{
965 \x_cs\offcommand{reglyph_\expandafter\gobble_one\string#1}

966 }

967 \def\onmtxcommand#1{
968 \x_cs\oncommand{reglyph_\expandafter\gobble_one\string#1}

969 }

\slots-⟨glyph⟩  Inside a \reglyphfonts . . . \endreglyphfonts block, the family \slots-⟨glyph⟩

of control sequences is used to store the information about how glyph ⟨glyph⟩ should be converted. These control sequences are either undefined or parameterless macros whose replacement texts are of one of the forms

     \rename_glyph{⟨to⟩}{⟨weight⟩}
     \rename_glyph{⟨to⟩}\i-renameweight
     \kill_glyph{⟨weight⟩}
     \kill_glyph\i-killweight

⟨to⟩ is what the glyph will be renamed to and ⟨weight⟩ is the associated weight. These four different forms are generated by the four different commands

\renameglyphweighted, \renameglyph, \killglyphweighted, and \killglyph

respectively.

\renameglyph \renameglyphweighted The difference between the commands \renameglyphweighted and \renameglyph

is that the former lets one specify the weight exactly while the latter will use the value of the integer renameweight at the time of conversion. By changing the value of renameweight between two conversions, one changes the weights used for all glyph renamings declared using \renameglyph.

970 \begingroup
971 \catcode`\-=11
972 \gdef\renameglyph#1#2{
973  \x_cs\edef{slots-#2}{
974  \noexpand\rename_glyph{#1}\noexpand\i-renameweight

975 } 976 }

977 \endgroup
978 \def\renameglyphweighted#1#2#3{
979 \eval_expr{#3}
980 \x_cs\edef{slots-#2}{\noexpand\rename_glyph{#1}{\the\result}}

981 }

\killglyph \killglyphweighted The difference between the commands \killglyphweighted and \killglyph is

that the former lets one specify the weight exactly while the latter will use the value of the integer killweight at the time of conversion. By changing the value of killweight between two conversions, one changes the weights used for all glyph killings declared using \killglyph.

982 \begingroup
983 \catcode`\-=11
984 \gdef\killglyph#1{
985  \x_cs\def{slots-#1}{\kill_glyph\i-killweight}

986 }

987 \endgroup
988 \def\killglyphweighted#1#2{
989 \eval_expr{#2}
990 \x_cs\edef{slots-#1}{\noexpand\kill_glyph{\the\result}}

991 }

\reglyphfont The command

\reglyphfont{⟨destination font⟩}{⟨source font⟩}

reads the font metric file ⟨source font⟩.mtx (which must be transformable), ⟨source font⟩.pl, or ⟨source font⟩.afm (the possibilities are tried in that order) and writes out a font metric file ⟨destination font⟩.mtx that is the converted (as described above) form of the source font.

⟨destination font⟩ and ⟨source font⟩ may not be equal.

 992 \def\reglyphfont#1#2{
 993 \fromany{#2}
 994 \ifisstr{afm-name}\then
 995  \reglyph_font{#1}{#2}
 996 \else
 997  \fontinsterror{Reglyph}{Could~not~find~font~metrics~for~#2.}
 998  \error_help_a
 999 \fi

1000 }

\reglyph_font This macro does the actual conversion.

1001 \def\reglyph_font#1#2{{
1002 \open_out{\temp_prefix#1.mtx}
1003 \out_line{\percent_char~Filename:~#1.mtx}
1004 \out_line{\percent_char~Created~by:~tex~\jobname}
1005 \out_line{\percent_char~Created~using:~\string\reglyphfont{#1}{#2}}
1006 \out_line{}
1007 \out_line{\percent_char~This~file~is~used~by~the~fontinst~package.}
1008 \out_line{}
1009 \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.}
1010 \out_line{}
1011 \out_line{\string\relax}
1012 \out_line{\string\metrics}
1013 \out_line{}
1014 \out_line{\string\needsfontinstversion{\fontinstversion}}
1015 \out_line{}
1016 \record_transform{#1}{\string\frommtx{#2}}{\string\reglyphfont}
1017  \iftrue
1018 \out_line{}
1019 \reglyph_redefinitions
1020 \inputmtx{#2}
1021 \out_line{}
1022 \out_line{\endmetrics_text}
1023 \close_out{Reglyphed~metrics}

1024 }}

\reglyph_redefinitions This macro serves as a hook. One can make additional commands transformable by appending suitable redefenitions of them to this macro.

1025 \def\reglyph_redefinitions{
1026 \let\setint=\reglyph_setint
1027 \let\setdim=\reglyph_setdim
1028 \let\setstr=\reglyph_setstr
1029 \let\setscaledrawglyph=\reglyph_setscaledrawglyph
1030 \let\setscalednotglyph=\reglyph_setscaledrawglyph
1031 \let\setkern=\reglyph_setkern
1032 \let\setglyph=\reglyph_setglyph
1033 \let\glyphpcc=\reglyph_glyphpcc
1034 \let\samesize=\reglyph_samesize
1035 \let\endsetglyph=\reglyph_endsetglyph

1036 }

\reglyph_setint \reglyph_setdim \reglyph_setstr These are just copied to the file generated.

1037 \def\reglyph_setint#1#2{\out_line{\string\setint{#1}{#2}}}
1038 \def\reglyph_setdim#1#2{\out_line{\string\setdim{#1}{#2}}}
1039 \def\reglyph_setstr#1#2{\out_line{\string\setstr{#1}{#2}}}

\command_survivance This \count register stores the sum of the weights associated with the glyphs considered so far. It is updated by \rename_glyph and \kill_glyph.

1040 \newcount\command_survivance

\glyphname The macro \glyphname holds the name of the glyph currently under consideration. It is altered by \rename_glyph.

\rename_glyph
\kill_glyph
1041 \def\rename_glyph#1{\def\glyphname{#1}\kill_glyph}
1042 \def\kill_glyph#1{\advance \command_survivance #1\x_relax}
\reglyph_setscaledrawglyph The \reglyph_setscaledrawglyph macro is straightforward. Whether it writes
  a \setscaledrawglyph or a \setscalednotglyph command depends on the fifth
  parameter, just like with \mtxtomtx_setscaledrawglyph.
1043 \def\reglyph_setscaledrawglyph#1#2#3#4#5#6#7#8#9{
1044 \command_survivance=0
1045 \def\glyphname{#1}
1046 \csname slots-#1\endcsname
1047 \iftokeep\command_survivance\then
1048  \out_line{
1049  \ifnum #5<\z@
1050  \string\setscalednotglyph
1051  \else
1052  \string\setscaledrawglyph

1053 \fi

1054  {\glyphname}{#2}{#3}{\number#4}{#5}{#6}{#7}{#8}{#9}

1055 } 1056 \fi 1057 }

\reglyph_setkern
1058 \def\reglyph_setkern#1#2#3{
1059 \command_survivance=0
1060 \def\glyphname{#1}
1061 \csname slots-#1\endcsname
1062 \let\a_macro=\glyphname
1063 \def\glyphname{#2}
1064 \csname slots-#2\endcsname
1065 \iftokeep\command_survivance\then
1066  \out_line{\string\setkern{\a_macro}{\glyphname}{#3}}

1067 \fi 1068 }

\reglyph_setglyph \off-\reglyph_setglyph \reglyph_glyphpcc \reglyph_samesize \reglyph_endsetglyph In \setglyph . . . \endsetglyph constructions (which are written for composite

characters in AFM files), the decision of whether to write a command or not due to glyph weights is done only once for the entire construction. This means that the commands must be saved until the \endsetglyph where the result is finally known. The token list register \a_toks is used for this purpose.

1069 \def\reglyph_setglyph#1{

1070 \command_survivance=0
1071 \def\glyphname{#1}
1072 \csname slots-#1\endcsname
1073 \edef\a_macro{\noexpand\out_line{\string\setglyph{\glyphname}}}
1074 \a_toks=\expandafter{\a_macro}

1075 }

1076 \x_cs\def{off-\string\reglyph_setglyph}#1{\gobble_glyph}
1077 \def\reglyph_glyphpcc#1#2#3{
1078 \def\glyphname{#1}
1079 \csname slots-#1\endcsname
1080 \edef\a_macro{\noexpand\out_lline{
1081  \string\glyphpcc{\glyphname}{#2}{#3}

1082 }}

1083 \a_toks=\expandafter{\the\expandafter\a_toks \a_macro}

1084 }

1085 \def\reglyph_samesize#1{
1086 \def\glyphname{#1}
1087 \csname slots-#1\endcsname
1088 \edef\a_macro{\noexpand\out_lline{
1089  \string\samesize{\glyphname}

1090 }}

1091 \a_toks=\expandafter{\the\expandafter\a_toks \a_macro}

1092 }

1093 \def\reglyph_endsetglyph{
1094 \iftokeep\command_survivance\then
1095  \the\a_toks
1096  \out_line{\string\endsetglyph}

1097 \fi

1098 \a_toks={}

1099 } 1100 ⟨/pkg⟩

Three common reglyphing schemes

As is mensioned elsewhere, the most common reglyphing operation is to take a caps and small caps font produced by some major foundry and change the glyph names so that they agree with the glyph names used in expert fonts. The following code contains the modifying reglyphing commands to set up this reglyphing, in two different variants.

The commands are currently based on a comparision of Adobe Garamond Small Caps & Oldstyle Figures (padrc8a in the Berry scheme) with Adobe Garamond Regular Expert (padr8x in the Berry scheme), so they should be correct for a fair amount of Adobe font families, but it is also highly probable that there are lots of fonts out there for which it doesn’t work quite right. In case you do find such a font, please write to tell the fontinst mailing list about it—it would be rather easy to add various alternative set-up schemes, controlled by switches, to these files. Just make sure first (by checking the newest version of fontinst) that the alternative setting you have found hasn’t already been included.

As mentioned, there are two different reglyphing schemes that are set up by the code below—one has docstrip guard ⟨glyphs⟩, the other has guard ⟨!glyphs⟩— but they both change SC names to Expert names. The difference lies instead in what information is copied from source font to destination font: the ⟨glyphs⟩ variant copies everything, whereas the ⟨!glyphs⟩ variant doesn’t copy

\setrawglyph commands, \setnotglyph commands, \setscaledrawglyph com-

mands, \setscalednotglyph commands or \setglyph constructions. The ⟨!glyphs⟩ variant also suppresses kerns between two glyphs that doesn’t change name.

The motive for having such a curious set-up naturally lies in how the files are meant to be used. If you have SC fonts, but no Expert fonts, then you should definitely use the ⟨glyphs⟩ variant. If on the other hand you have both SC and Expert fonts for a family, then it is worth considering using the ⟨!glyphs⟩ variant instead. The observation this is based on is that within a triad of the corresponding regular, expert, and SC fonts, almost all glyphs present in the SC font can also be found in either the regular or the expert font; furthermore the only missing glyphs were FIsmall, FLsmall, and SSsmall, which (i) were included in the SC font only to complete the 8a encoding vector and (ii) are identical to fontinst’s fakes for them.

Thus by constructing the sc shape fonts from the regular and expert variants, instead of the SC variant, one can get away with using one raw font less, thus reducing the time needed for downloading the fonts to the printer and the size of the corresponding postscript file. One thing not found in either of the regular or expert font in the triad is however the kerns between capitals and small capitals, but these can be extracted from the metrics of the SC font, and doing this is the primary objective for the ⟨!glyphs⟩ variant.

First there is the English alphabet:

1101 ⟨∗reglyphletters⟩

1102 \renameglyph{Asmall}{a}
1103 \renameglyph{Bsmall}{b}
1104 \renameglyph{Csmall}{c}
1105 \renameglyph{Dsmall}{d}
1106 \renameglyph{Esmall}{e}
1107 \renameglyph{Fsmall}{f}
1108 \renameglyph{Gsmall}{g}
1109 \renameglyph{Hsmall}{h}
1110 \renameglyph{Ismall}{i}
1111 \renameglyph{Jsmall}{j}
1112 \renameglyph{Ksmall}{k}
1113 \renameglyph{Lsmall}{l}
1114 \renameglyph{Msmall}{m}
1115 \renameglyph{Nsmall}{n}
1116 \renameglyph{Osmall}{o}
1117 \renameglyph{Psmall}{p}
1118 \renameglyph{Qsmall}{q}
1119 \renameglyph{Rsmall}{r}
1120 \renameglyph{Ssmall}{s}
1121 \renameglyph{Tsmall}{t}
1122 \renameglyph{Usmall}{u}
1123 \renameglyph{Vsmall}{v}
1124 \renameglyph{Wsmall}{w}
1125 \renameglyph{Xsmall}{x}
1126 \renameglyph{Ysmall}{y}
1127 \renameglyph{Zsmall}{z}

1128 ⟨/reglyphletters⟩

Then there are the figures:

1129 ⟨∗reglyphfigures⟩

1130 \renameglyph{zerooldstyle}{zero}
1131 \renameglyph{oneoldstyle}{one}
1132 \renameglyph{twooldstyle}{two}
1133 \renameglyph{threeoldstyle}{three}
1134 \renameglyph{fouroldstyle}{four}
1135 \renameglyph{fiveoldstyle}{five}
1136 \renameglyph{sixoldstyle}{six}
1137 \renameglyph{sevenoldstyle}{seven}
1138 \renameglyph{eightoldstyle}{eight}
1139 \renameglyph{nineoldstyle}{nine}

1140 ⟨/reglyphfigures⟩

Then there are the accents and a couple of miscellaneous symbols. You might want to check these carefully, as there might not always be a distinction.

1141 ⟨∗reglyphletters⟩

1142 \renameglyph{Acutesmall}{acute}
1143 \renameglyph{Brevesmall}{breve}
1144 \renameglyph{Caronsmall}{caron}
1145 \renameglyph{Cedillasmall}{cedilla}
1146 \renameglyph{Circumflexsmall}{circumflex}
1147 \renameglyph{Dieresissmall}{dieresis}
1148 \renameglyph{Dotaccentsmall}{dotaccent}
1149 \renameglyph{Gravesmall}{grave}
1150 \renameglyph{Hungarumlautsmall}{hungarumlaut}
1151 \renameglyph{Macronsmall}{macron}
1152 \renameglyph{Ogoneksmall}{ogonek}
1153 \renameglyph{Ringsmall}{ring}
1154 \renameglyph{Tildesmall}{tilde}
1155 \renameglyph{ampersandsmall}{ampersand}
1156 \renameglyph{centoldstyle}{cent}
1157 \renameglyph{dollaroldstyle}{dollar}

There are also all the non-English letters:

1158 \renameglyph{AEsmall}{ae}
1159 \renameglyph{Ethsmall}{eth}
1160 \renameglyph{Lslashsmall}{lslash}
1161 \renameglyph{Oslashsmall}{oslash}
1162 \renameglyph{OEsmall}{oe}
1163 \renameglyph{Thornsmall}{thorn}
1164 \renameglyph{Agravesmall}{agrave}
1165 \renameglyph{Egravesmall}{egrave}
1166 \renameglyph{Igravesmall}{igrave}
1167 \renameglyph{Ogravesmall}{ograve}
1168 \renameglyph{Ugravesmall}{ugrave}
1169 \renameglyph{Aacutesmall}{aacute}
1170 \renameglyph{Eacutesmall}{eacute}
1171 \renameglyph{Iacutesmall}{iacute}
1172 \renameglyph{Oacutesmall}{oacute}
1173 \renameglyph{Uacutesmall}{uacute}
1174 \renameglyph{Yacutesmall}{yacute}
1175 \renameglyph{Acircumflexsmall}{acircumflex}

1176 \renameglyph{Ecircumflexsmall}{ecircumflex}
1177 \renameglyph{Icircumflexsmall}{icircumflex}
1178 \renameglyph{Ocircumflexsmall}{ocircumflex}
1179 \renameglyph{Ucircumflexsmall}{ucircumflex}
1180 \renameglyph{Atildesmall}{atilde}
1181 \renameglyph{Ntildesmall}{ntilde}
1182 \renameglyph{Otildesmall}{otilde}
1183 \renameglyph{Adieresissmall}{adieresis}
1184 \renameglyph{Edieresissmall}{edieresis}
1185 \renameglyph{Idieresissmall}{idieresis}
1186 \renameglyph{Odieresissmall}{odieresis}
1187 \renameglyph{Ydieresissmall}{ydieresis}
1188 \renameglyph{Udieresissmall}{udieresis}
1189 \renameglyph{Aringsmall}{aring}
1190 \renameglyph{Ccedillasmall}{ccedilla}
1191 \renameglyph{Scaronsmall}{scaron}
1192 \renameglyph{Zcaronsmall}{zcaron}

The following four glyphs aren’t really necessary, since they are usually identical to another glyph or to their fakes.

1193 \killglyph{dotlessi}

1194 ⟨∗glyphs⟩

1195 \renameglyph{FIsmall}{fi}
1196 \renameglyph{FLsmall}{fl}
1197 \renameglyph{SSsmall}{germandbls}

1198 ⟨/glyphs⟩ 1199 ⟨∗!glyphs⟩

1200 \killglyph{fi}
1201 \killglyph{fl}
1202 \killglyph{germandbls}

1203 ⟨/!glyphs⟩ 1204 ⟨/reglyphletters⟩

The ⟨!glyphs⟩ settings have no need for \setrawglyph, \setscaledrawglyph, or \setglyph commands, and no need for the kerns between capitals either, since these are already known from the regular variant. Note that it is pointless to say

  \offmtxcommand\setrawglyph as of v 1.913 since \setrawglyph is now simply

syntactic sugar for the equivalent \setscaledrawglyph.

1205 ⟨∗(reglyphletters | reglyphfigures)&!glyphs⟩

1206 \offmtxcommand\setscaledrawglyph
1207 \offmtxcommand\setglyph
1208 \resetcommand\iftokeep#1\then{\ifnum 0<#1}

1209 ⟨/(reglyphletters | reglyphfigures)&!glyphs⟩

File e

filtfam.dtx

17 Installing Latin families

\latinfamily The macro:

\latinfamily{⟨family⟩}{⟨commands⟩}

installs a Latin font family.

1 ⟨∗pkg⟩

 2 \def\latinfamily#1#2{{
 3 \edef\a_macro{#1}
 4 \expandafter\parse_family\a_macro
 5  \empty_command\empty_command\end_parse_family
 6 \installfonts
 7  \if_file_exists{\raw_encoding.mtx}\then
 8  \installfamily{\raw_encoding}{\latex_family}{#2}
 9  \fi
10  \installfamily{OT1}{\latex_family}{#2}
11  \installfamily{T1}{\latex_family}{#2}

12 ⟨∗textcomp⟩

13  \installfamily{TS1}{\latex_family}{#2}

14 ⟨/textcomp⟩

15  \latin_weights
16 \endinstallfonts
17 }}
\parse_family \font_family \font_variant \raw_variant \latex_variant  \parse_family FAMILY\end_parse_family

Intializes \latex_family to FAMILY, \font_family to first three characters of FAMILY, \font_variant and \raw_variant to fourth and fifth character (if present).

SPQR 02/95: If the fourth parameter is x or 9, then its an expert indication, not a variant. So initialy set \raw_variant to #4, but unset it if the expert test succeeds. When #4 is used for a real variant, it passes through.

SPQR 05/95: If it is an expert font, then the variantness is expressed by the encoding, not a variant letter, so unset \font_variant.

UV 06/98: Added \if_oldstyle_code from Alan’s v 1.511 beta. If the fourth parameter is 9, treat it as if j was given.

Note that instead of using \setcommand\digit, we now use separate encoding files for T1j.etx, etc.

18 \def\parse_family #1#2#3#4#5\end_parse_family{
19 \gdef\font_family{#1#2#3}
20 \gdef\font_variant{#4#5}
21 \gdef\raw_variant{#4#5}
22 \gdef\latex_family{#1#2#3#4#5}
23 \_expert_false
24 \_oldstyle_false
25 \ifx#4x
26  \_expert_true
27  \gdef\raw_variant{#5}

28  \gdef\font_variant{#5}
29  %\setcommand\digit##1{##1}
30 \else\ifx#4j
31  \_expert_true
32  \_oldstyle_true
33  \gdef\raw_variant{#5}
34  \gdef\font_variant{#5}
35  %\setcommand\digit##1{##1oldstyle}
36 \else\ifx#49
37  \gdef\latex_family{#1#2#3j#5}
38  \_expert_true
39  \_oldstyle_true
40  \gdef\raw_variant{#5}
41  \gdef\font_variant{#5}
42  %\setcommand\digit##1{##1oldstyle}
43 \else
44  \_expert_false
45  \_oldstyle_false
46  %\setcommand\digit##1{##1}
47 \fi\fi\fi

48 ⟨∗debug⟩

49 \if_oldstyle_
50 \immediate\write16{INFO>~parse~family~<#1#2#3><#5>~(oldstyle)}
51 \else\if_expert_
52 \immediate\write16{INFO>~parse~family~<#1#2#3><#5>~(expert)}
53 \else
54 \immediate\write16{INFO>~parse~family~<#1#2#3><#4#5>}
55 \fi\fi

56 ⟨/debug⟩ 57 }

\if_expert_
\if_oldstyle_
58 \newif\if_expert_
59 \newif\if_oldstyle_

17.1 Processing a list of weights, widths and shapes

\latin_weight \font_weight \latex_weight  \latin_weight{FONTWEIGHT}{LATEXWEIGHT}
60 \def\latin_weight#1#2{
61 \gdef\font_weight{#1}%
62 \gdef\latex_weight{#2}%
63 \latin_widths

64 }

\latin_width \font_width \latex_width  \latin_width{FONTWIDTH}{LATEXWIDTH}
65 \def\latin_width#1#2{
66 \gdef\font_width{#1}
67 \gdef\latex_width{#2}
68 \latin_shapes

69 }

\latin_shape \font_shape \raw_shape \encoding_shape \latex_shape \encoding_switches  \latin_shape{FONTSHAPE}{RAWSHAPE}{ENCODINGSHAPE}{LATEXSHAPE}{SWITCHES}

   Calls \fake_width_WIDTH and \fake_shape_SHAPE to generate an 8r-reencoded

.mtx file. If successful, calls \latin_encodings.

UV 06/98: Added a fifth argument SWITCHES, which may be used to set

\if_textcomp_before it is evaluated in \latin_encodings.
70 \def\latin_shape#1#2#3#4#5{
71 \gdef\font_shape{#1}
72 \gdef\raw_shape{#2}
73 \gdef\encoding_shape{#3}
74 \if_oldstyle_
75  \gdef\encoding_shape{#3\oldstyle_shape}
76 \fi
77 \gdef\latex_shape{#4}
78 \gdef\encoding_switches{#5}

79 ⟨∗debug⟩

80 \immediate\write16{
81  INFO>~to~make~LaTeX~font~shape~<\latex_family,
82  \latex_weight,\latex_shape,\latex_width>~seek~
83  \font_family\font_weight\raw_shape
84  \raw_variant\raw_encoding\font_width.mtx}

85 ⟨/debug⟩

86 \csname fake_width_\font_width\endcsname
87 \csname fake_shape_\raw_shape\endcsname
88 \if_file_exists{
89  \font_family\font_weight\raw_shape
90  \raw_variant\raw_encoding\font_width.mtx
91 }\then
92  \latin_encodings
93 \fi

94 }

17.2 Faking font shapes

(CK) changed font faking code; based on SPQR’s code (still in this file). I am not sure that know what I am doing here; let’s hope I won’t be caught. Also changed: Order of \font_width and \font_encoding in MANY places. Also added tests which prevent multiple calls to the same font faking routine. (Seems to be necessary in some cases and can’t hurt.) — (ASAJ) I think CK knows more about what he’s doing than he’s letting on.

\fake_shape_Check if an 8a-encoded .afm file exists for current combination of font attributes, and, if so, call \fake_shape_raw_encoding. For expert fonts, also check if an 8xencoded .afm file exists, and call \fake_shape_expert_encoding, if approporiate.

UV, 06/98: Cut down lengthy \fake_shape_routine into several subroutines

\fake_shape_raw_encoding and optionally \fake_shape_expert_encoding and
\fake_shape_oldstyle_encoding.

UV, 06/98: Added experimental code to install OsF or SC&OsF fonts.

95 \def\fake_shape_{
96 \if_file_exists{
97  \font_family\font_weight\raw_shape\raw_variant
98  \adobe_encoding\font_width.afm
99 }\then
100  \fake_shape_raw_encoding

101 \fi
102 \if_expert_
103  \if_file_exists{
104  \font_family\font_weight\raw_shape\raw_variant
105  \expert_encoding\font_width.afm
106  }\then
107  \fake_shape_expert_encoding
108  \fi
109 \fi

110 ⟨∗oldstyle⟩

111 \if_oldstyle_
112  \gdef\oldstyle_variant{\oldstyle_shape}
113  \if_file_exists{
114  \font_family\font_weight\raw_shape\oldstyle_variant
115  \adobe_encoding\font_width.afm
116  }\then
117  \fake_shape_oldstyle_encoding
118  \else
119  \gdef\oldstyle_variant{\caps_shape}
120  \if_file_exists{
121  \font_family\font_weight\raw_shape\oldstyle_variant
122  \adobe_encoding\font_width.afm
123  }\then
124  \fake_shape_oldstyle_encoding
125  \fi
126  \fi
127 \fi

128 ⟨/oldstyle⟩ 129 }

\fake_shape_raw_encoding Called from \fake_shape_if an 8a-encoded .afm file was found. Invokes
      \transformfont{<FONT>8r}
        {\reencodefont{8r}{\fromafm{<FONT>8a}}}

to generate an 8r-reencoded .mtx file (and a raw .pl file), followed by

      \installrawfont{<FONT>8r}{<FONT>8r,8r}{8r}...

to install a ligfull .pl file.

130 \def\fake_shape_raw_encoding{
131 \if_file_exists{
132  \font_family\font_weight\raw_shape\raw_variant
133  \raw_encoding\font_width.mtx
134 }\then % no action required
135 \else

136 ⟨∗debug⟩

137  \immediate\write16{
138  INFO>~run~\string\transformfont\space\space
139  <\font_family\font_weight\raw_shape\raw_variant
140  \raw_encoding\font_width>~from~
141  <\font_family\font_weight\raw_shape\raw_variant
142  \adobe_encoding\font_width>

143 } 144 ⟨/debug⟩

145  \transformfont{
146  \font_family\font_weight\raw_shape\raw_variant
147  \raw_encoding\font_width

148 }{

149  \reencodefont{\raw_encoding}{
150  \fromafm{
151  \font_family\font_weight\raw_shape\raw_variant
152  \adobe_encoding\font_width

153 } 154 } 155 }

156  \if_file_exists{ \raw_encoding.mtx }\then

157 ⟨∗debug⟩

158  \immediate\write16{
159  INFO>~run~\string\installrawfont\space
160  <\font_family\font_weight\font_shape\raw_variant
161  \raw_encoding\font_width>
162  <\font_family\font_weight\raw_shape\raw_variant
163  \raw_encoding\font_width,
164  \raw_encoding>
165  <\raw_encoding>
166  <\raw_encoding>
167  <\latex_family>
168  <\latex_weight\latex_width>
169  <\latex_shape>}

170 ⟨/debug⟩

171  \installrawfont{
172  \font_family\font_weight\raw_shape\raw_variant
173  \raw_encoding\font_width
174  }{ \font_family\font_weight\raw_shape\raw_variant
175  \raw_encoding\font_width,
176  \raw_encoding
177  }{ \raw_encoding
178  }{ \raw_encoding
179  }{ \latex_family
180  }{ \latex_weight\latex_width
181  }{ \latex_shape
182  }{}
183  \fi
184 \fi

185 }

\fake_shape_expert_encoding Called from \fake_shape_if an 8x-encoded .afm file was found. Invokes
      \fromafm{<FONT>8x}

to generate an 8x-encoded .mtx file (and a raw .pl file).

186 \def\fake_shape_expert_encoding{
187 \if_file_exists{
188  \font_family\font_weight\raw_shape\raw_variant
189  \expert_encoding\font_width.mtx
190 }\then % no action required
191 \else
192  \fromafm{

193  \font_family\font_weight\raw_shape\raw_variant
194  \expert_encoding\font_width

195 }

196 \fi

197 }

\fake_shape_oldstyle_encoding Called from \fake_shape_if an OsF or SC&OsF variant of an 8a-encoded .afm

file was found. Invokes

      \transformfont{<FONT>j8r}
        {\reencodefont{8r}{\fromafm{<FONT>j8a}}}

to generate an 8r-reencoded .mtx file (and a raw .pl file).

198 ⟨∗oldstyle⟩

199 \def\fake_shape_oldstyle_encoding{
200 \if_file_exists{
201  \font_family\font_weight\raw_shape\oldstyle_variant
202  \adobe_encoding\font_width.mtx
203 }\then % no action required
204 \else

205 ⟨∗debug⟩

206  \immediate\write16{
207  INFO>~run~\string\transformfont\space\space
208  <\font_family\font_weight\raw_shape\oldstyle_variant
209  \raw_encoding\font_width>~from~
210  <\font_family\font_weight\raw_shape\oldstyle_variant
211  \adobe_encoding\font_width>

212 } 213 ⟨/debug⟩

214  \transformfont{
215  \font_family\font_weight\raw_shape\oldstyle_variant
216  \raw_encoding\font_width

217 }{

218  \reencodefont{\raw_encoding}{
219  \fromafm{
220  \font_family\font_weight\raw_shape\oldstyle_variant
221  \adobe_encoding\font_width

222 } 223 } 224 }

225 \fi

226 } 227 ⟨/oldstyle⟩

\fake_shape_c Check if an 8a-encoded .afm file exists for the small caps shape. If so, call \fake_shape_to generate an 8r-reencoded MTX file and to install a ligfull .pl file. If not, reset \raw_shape to the default shape and \encoding_shape to small caps before calling \fake_shape_to install a faked small caps font.

228 \def\fake_shape_c{
229 \if_file_exists{
230  \font_family\font_weight\raw_shape\raw_variant
231  \adobe_encoding\font_width.afm
232 }\then
233  \fake_shape_

234 \else
235  % If real smallcaps font doesn't exist, fake it from the roman.
236  \gdef\raw_shape{}
237  \if_oldstyle_
238  \gdef\encoding_shape{cj}
239  \else
240  \gdef\encoding_shape{c}
241  \fi
242  \fake_shape_
243 \fi

244 }

\fake_shape_o Check if an 8a-encoded .afm file exists for the oblique shape. If so, call \fake_shape_to generate an 8r-reencoded MTX file and to install a ligfull .pl file. If not, call macros to fake a oblique fonts.

245 \def\fake_shape_o{
246 \if_file_exists{
247  \font_family\font_weight\raw_shape\raw_variant
248  \adobe_encoding\font_width.afm
249 }\then
250  \fake_shape_
251 \else
252  \fake_shape_o_raw_encoding
253  \if_expert_
254  \fake_shape_o_expert_encoding
255  \fi

256 ⟨∗oldstyle⟩

257  \if_oldstyle_
258  \fake_shape_o_oldstyle_encoding
259  \fi

260 ⟨/oldstyle⟩

261 \fi

262 }

\fake_shape_o_raw_encoding Called from \fake_shape_o if the oblique shape needs to be faked. Invokes

      \transformfont{<FONT>o8r}
        {\slantfont{SLANT}{\frommtx{<FONT>8r}}}

to generate an 8r-reencoded .mtx file (and a raw .pl file), followed by

      \installrawfont{<FONT>o8r}{<FONT>o8r,8r}{8r}...

to install a ligfull .pl file.

263 \def\fake_shape_o_raw_encoding{
264 \if_file_exists{
265  \font_family\font_weight\raw_variant
266  \raw_encoding\font_width.mtx
267 }\then
268  \if_file_exists{
269  \font_family\font_weight\font_shape\raw_variant
270  \raw_encoding\font_width.mtx
271  }\then % no action required
272  \else

273 ⟨∗debug⟩

274  \immediate\write16{
275  INFO>~run~\string\transformfont\space\space
276  <\font_family\font_weight\font_shape\raw_variant
277  \raw_encoding\font_width>~from~
278  <\font_family\font_weight\raw_variant
279  \raw_encoding\font_width>~(faking~oblique)

280 } 281 ⟨/debug⟩

282  %%% WARNING: famtool.pl relies on this message format!!!
283  \immediate\write16{
284  Faking~oblique~font~
285  \font_family\font_weight\font_shape\raw_variant
286  \raw_encoding\font_width
287  \space from~
288  \font_family\font_weight\raw_variant
289  \raw_encoding\font_width

290 }

291  \transformfont{
292  \font_family\font_weight\font_shape\raw_variant
293  \raw_encoding\font_width

294 }{

295  \slantfont{\SlantAmount}{
296  \frommtx{
297  \font_family\font_weight\raw_variant
298  \raw_encoding\font_width

299 } 300 } 301 }

302  \if_file_exists{ \raw_encoding.mtx }\then

303 ⟨∗debug⟩

304  \immediate\write16{
305  INFO>~run~\string\installrawfont\space
306  <\font_family\font_weight\font_shape\raw_variant
307  \raw_encoding\font_width>
308  <\font_family\font_weight\font_shape\raw_variant
309  \raw_encoding\font_width,
310  \raw_encoding>
311  <\raw_encoding>
312  <\raw_encoding>
313  <\latex_family>
314  <\latex_weight\latex_width>
315  <\latex_shape>}

316 ⟨/debug⟩

317  \installrawfont{
318  \font_family\font_weight\font_shape\raw_variant
319  \raw_encoding\font_width
320  }{ \font_family\font_weight\font_shape\raw_variant
321  \raw_encoding\font_width,
322  \raw_encoding
323  }{ \raw_encoding
324  }{ \raw_encoding
325  }{ \latex_family
326  }{ \latex_weight\latex_width

327  }{ \latex_shape
328  }{}
329  \fi
330  \fi
331 \fi

332 }

\fake_shape_o_expert_encoding Called from \fake_shape_o if the oblique shape needs to be faked. Invokes

      \transformfont{<FONT>o8x}
        {\slantfont{SLANT}{\frommtx{<FONT>8x}}}

to generate an 8x-reencoded .mtx file (and a raw .pl file).

333 \def\fake_shape_o_expert_encoding{
334 \if_file_exists{
335  \font_family\font_weight\raw_variant
336  \expert_encoding\font_width.mtx
337 }\then
338  \if_file_exists{
339  \font_family\font_weight\font_shape\raw_variant
340  \expert_encoding\font_width.mtx
341  }\then % no action required
342  \else

343 ⟨∗debug⟩

344  \immediate\write16{
345  INFO>~run~\string\transformfont\space\space
346  <\font_family\font_weight\font_shape\raw_variant
347  \expert_encoding\font_width>~from~
348  <\font_family\font_weight\raw_variant
349  \expert_encoding\font_width>~(faking~oblique)

350 } 351 ⟨/debug⟩

352  %%% WARNING: famtool.pl relies on this message format!!!
353  \immediate\write16{
354  Faking~oblique~font~
355  \font_family\font_weight\font_shape\raw_variant
356  \expert_encoding\font_width
357  \space from~
358  \font_family\font_weight\raw_variant
359  \expert_encoding\font_width

360 }

361  \transformfont{
362  \font_family\font_weight\font_shape\raw_variant
363  \expert_encoding\font_width

364 }{

365  \slantfont{\SlantAmount}{
366  \frommtx{
367  \font_family\font_weight\raw_variant
368  \expert_encoding\font_width

369 } 370 } 371 }

372  \fi
373 \fi

374 }

\fake_shape_o_oldstyle_encoding Called from \fake_shape_o if the oblique shape needs to be faked. Invokes

      \transformfont{<FONT>oj8r}
        {\slantfont{SLANT}{\frommtx{<FONT>j8r}}}

to generate an 8r-reencoded .mtx file (and a raw .pl file).

375 ⟨∗oldstyle⟩

376 \def\fake_shape_o_oldstyle_encoding{
377 \if_file_exists{
378  \font_family\font_weight\oldstyle_variant
379  \raw_encoding\font_width.mtx
380 }\then
381  \if_file_exists{
382  \font_family\font_weight\font_shape\oldstyle_variant
383  \raw_encoding\font_width.mtx
384  }\then % no action required
385  \else

386 ⟨∗debug⟩

387  \immediate\write16{
388  INFO>~run~\string\transformfont\space\space
389  <\font_family\font_weight\font_shape\oldstyle_variant
390  \raw_encoding\font_width>~from~
391  <\font_family\font_weight\oldstyle_variant
392  \raw_encoding\font_width>~(faking~oblique)

393 } 394 ⟨/debug⟩

395  %%% WARNING: famtool.pl relies on this message format!!!
396  \immediate\write16{
397  Faking~oblique~font~
398  \font_family\font_weight\font_shape\oldstyle_variant
399  \raw_encoding\font_width
400  \space from~
401  \font_family\font_weight\oldstyle_variant
402  \raw_encoding\font_width

403 }

404  \transformfont{
405  \font_family\font_weight\font_shape\oldstyle_variant
406  \raw_encoding\font_width

407 }{

408  \slantfont{\SlantAmount}{
409  \frommtx{
410  \font_family\font_weight\oldstyle_variant
411  \raw_encoding\font_width

412 } 413 } 414 }

415  \fi
416 \fi

417 } 418 ⟨/oldstyle⟩

\fake_shape_i Call \fake_shape_to generate an 8r-reencoded .mtx file and a ligfull .pl file, if a corresponding 8a-encoded .afm file exists. Otherwise, do nothing, since an italic shape can’t be faked.

419 \let\fake_shape_i\fake_shape_% We must do this again!

17.3 Faking font widths

\if_fake_narrow_
420 \newif\if_fake_narrow_
421 \_fake_narrow_false
\fakenarrow  \fakenarrow{WIDTH}

Sets the expansion factor used to generate faked narrow fonts. If it isn’t set, do not attempt to install faked narrow fonts.

422 \def\fakenarrow#1{
423 \_fake_narrow_true
424 \gdef\fake_narrow_width{#1}

425 }

\fake_width_Do nothing for the default width or the condensed width.

426 \def\fake_width_{}
427 \def\fake_width_c{}

\fake_width_n If we are faking narrow fonts, check if an 8a-encoded .afm file exists for the current shape in narrow width, and if not call \fake_shape_n_raw_encoding and

\fake_shape_n_expert_encoding.
428 \def\fake_width_n{
429 \if_fake_narrow_
430  \if_file_exists{
431  \font_family\font_weight\raw_shape\raw_variant
432  \adobe_encoding\font_width.afm
433  }\then % no action required
434  \else
435  \fake_width_n_raw_encoding
436  \if_expert_
437  \fake_width_n_expert_encoding
438  \fi
439  \fi
440 \fi

441 }

\fake_width_n_raw_encoding Called from \fake_width_n if the narrow width needs to be faked. Invokes

     \transformfont{<FONT>8rn}
       {\xscalefont{WIDTH}{\frommtx{<FONT>8r}}}

to generate an 8r-encoded .mtx file for a faked narrow font, followed by

     \installrawfont{<FONT>8rn}{<FONT>8rn,8r}{8r}...

to install a ligfull .pl file.

442 \def\fake_width_n_raw_encoding{
443 \if_file_exists{
444  \font_family\font_weight\font_shape\raw_variant
445  \raw_encoding.mtx
446 }\then

447  \if_file_exists{
448  \font_family\font_weight\font_shape\raw_variant
449  \raw_encoding\font_width.mtx
450  }\then % no action required
451  \else

452 ⟨∗debug⟩

453  \immediate\write16{
454  INFO>~run~\string\transformfont\space\space
455  <\font_family\font_weight\font_shape\raw_variant
456  \raw_encoding\font_width>~from~
457  <\font_family\font_weight\font_shape\raw_variant
458  \raw_encoding>~(faking~narrow)

459 } 460 ⟨/debug⟩

461  %%% WARNING: famtool.pl relies on this message format!!!
462  \immediate\write16{
463  Faking~narrow~font~
464  \font_family\font_weight\font_shape\raw_variant
465  \raw_encoding\font_width
466  \space from~
467  \font_family\font_weight\font_shape\raw_variant
468  \raw_encoding

469 }

470  \transformfont{
471  \font_family\font_weight\font_shape\raw_variant
472  \raw_encoding\font_width

473 }{

474  \xscalefont{\fake_narrow_width}{
475  \frommtx{
476  \font_family\font_weight\font_shape\raw_variant
477  \raw_encoding

478 } 479 } 480 }

481  \if_file_exists{ \raw_encoding.mtx }\then

482 ⟨∗debug⟩

483  \immediate\write16{
484  INFO>~run~\string\installrawfont\space
485  <\font_family\font_weight\font_shape\raw_variant
486  \raw_encoding\font_width>
487  <\font_family\font_weight\font_shape\raw_variant
488  \raw_encoding\font_width,
489  \raw_encoding>
490  <\raw_encoding>
491  <\raw_encoding>
492  <\latex_family>
493  <\latex_weight\latex_width>
494  <\latex_shape>}

495 ⟨/debug⟩

496  \installrawfont{
497  \font_family\font_weight\font_shape\raw_variant
498  \raw_encoding\font_width
499  }{ \font_family\font_weight\font_shape\raw_variant
500  \raw_encoding\font_width,

501  \raw_encoding
502  }{ \raw_encoding
503  }{ \raw_encoding
504  }{ \latex_family
505  }{ \latex_weight\latex_width
506  }{ \latex_shape
507  }{}
508  \fi
509  \fi
510 \fi

511 }

\fake_width_n_expert_encoding Called from \fake_width_n if the narrow width needs to be faked. Invokes

      \transformfont{<FONT>8xn}
        {\xscalefont{WIDTH}{\frommtx{<FONT>8x}}}

to generate an 8x-encoded .mtx file for a faked narrow font.

512 \def\fake_width_n_expert_encoding{
513 \if_file_exists{
514  \font_family\font_weight\font_shape\raw_variant
515  \expert_encoding.mtx
516 }\then
517  \if_file_exists{
518  \font_family\font_weight\font_shape\raw_variant
519  \expert_encoding\font_width.mtx
520  }\then % no action required
521  \else

522 ⟨∗debug⟩

523  \immediate\write16{
524  INFO>~run~\string\transformfont\space\space
525  <\font_family\font_weight\font_shape\raw_variant
526  \expert_encoding\font_width>~from~
527  <\font_family\font_weight\font_shape\raw_variant
528  \expert_encoding>~(faking~narrow)

529 } 530 ⟨/debug⟩

531  %%% WARNING: famtool.pl relies on this message format!!!
532  \immediate\write16{
533  Faking~narrow~font~
534  \font_family\font_weight\font_shape\raw_variant
535  \expert_encoding\font_width
536  \space from~
537  \font_family\font_weight\font_shape\raw_variant
538  \expert_encoding

539 }

540  \transformfont{
541  \font_family\font_weight\font_shape\raw_variant
542  \expert_encoding\font_width

543 }{

544  \xscalefont{\fake_narrow_width}{
545  \frommtx{
546  \font_family\font_weight\font_shape\raw_variant
547  \expert_encoding

549 } 550 }

551  \fi
552 \fi

553 }

17.4 Installing reencoded fonts

\latin_encoding \font_encoding \latex_encoding \latex_mtx  \latin_encoding{FONTENC}{EXPERTISED-ENC}{OLDSTYLE-ENC}{LATEXENC}{LATEXMTX}

If this is an expertised family EXPERTISED-ENC is used instead of FONTENC. If this is an expertised family with oldstyle digits OLDSTYLE-ENC is used instead of

 EXPERTISED-ENC.

UV 06/98: Added code for oldstyle encodings from Alan’s v 1.511. The

 \font_encoding is changed when \if_oldstyle_is true.

UV 06/98: Added anonther parameter for the default metrics file (which is

 usually either latin.mtx or textcomp.mtx).

UV 06/98: Added experimental code for OsF or SC&OsF fonts.

554 \def\latin_encoding#1#2#3#4#5{
555 \gdef\latex_encoding{#4}
556 \gdef\latex_mtx{#5}
557 \if_oldstyle_
558  \gdef\font_encoding{#3}
559 \else\if_expert_
560  \gdef\font_encoding{#2}
561 \else
562  \gdef\font_encoding{#1}
563 \fi\fi
564 \gdef\expert_font{}
565 \gdef\oldstyle_font{}
566 \if_expert_
567  \if_file_exists{
568  \font_family\font_weight\raw_shape\raw_variant
569  \expert_encoding\font_width.mtx
570  }\then
571  \gdef\expert_font{
572  \font_family\font_weight\raw_shape\raw_variant
573  \expert_encoding\font_width,

574 }

575  \fi
576 \fi

577 ⟨∗oldstyle⟩

578 \if_oldstyle_
579  \if_file_exists{
580  \font_family\font_weight\raw_shape\oldstyle_variant
581  \raw_variant\raw_encoding\font_width.mtx
582  }\then
583  \gdef\oldstyle_font{
584  unsetnum,
585  \font_family\font_weight\raw_shape\oldstyle_variant
586  \raw_variant\raw_encoding\font_width,
587  resetosf,

588 }

589  \fi
590 \fi

591 ⟨/oldstyle⟩ 592 ⟨∗debug⟩

593 \immediate\write16{
594  INFO>~run~\string\installfont\space
595  <\font_family\font_weight\font_shape\font_variant
596  \font_encoding\font_width>
597  <\font_family\font_weight\raw_shape\raw_variant
598  \raw_encoding\font_width,
599  \if_oldstyle_
600  \ifx\raw_shape\caps_shape
601  resetosf,
602  \fi
603  \fi
604  \expert_font
605  \oldstyle_font
606  \latex_mtx>
607  <\latex_encoding\encoding_shape>
608  <\latex_encoding>
609  <\latex_family>
610  <\latex_weight\latex_width>
611  <\latex_shape>}

612 ⟨/debug⟩

613 \installfont{
614  \font_family\font_weight\font_shape\font_variant
615  \font_encoding\font_width

616 }{

617  \font_family\font_weight\raw_shape\raw_variant
618  \raw_encoding\font_width,
619  \if_oldstyle_
620  \ifx\raw_shape\caps_shape
621  resetosf,
622  \fi
623  \fi
624  \expert_font
625  \oldstyle_font
626  \latex_mtx

627 }{

628  \latex_encoding\encoding_shape

629 }{

630  \latex_encoding

631 }{

632  \latex_family

633 }{

634  \latex_weight\latex_width

635 }{

636  \latex_shape
637 }{}

638 }

17.5 Default weights, widths and shapes

Fontname: weight.map  NFSS: L^{A}TEX Companion, p. 190
a Thin Hairline  ul Ultra Light
j ExtraLight  el Extra Light
l Light  l Light
r Regular Roman  m Medium
k Book  m Medium
m Medium  mb (was: m)
d Demi  db (was: sb)
s Semibold  sb Semibold
b Bold  b Bold
h Heavy Heavyface  eb (was missing)
c Black  eb (was missing)
x ExtraBold ExtraBlack eb Extra Bold
u Ultra UltraBlack  ub Ultra Bold
p Poster  (still missing)

\latin_weights Each call to \latin_weight maps a Fontname weight code (\font_weight) to a

L^{A}TEX weight code (\latex_weight). Non-existing weights are ignored (or substituted when the .fd files are written out by \endinstallfont).

The standard values are given in the table. They may be changed, but you’d better know what you’re doing.

UV, 04/98: Changed the processing order: Do the most common shapes first. Added new mappings for c and h, changed mapping for m to newly invented L^{A}TEX weight mb.

639 \def\latin_weights{
640 \latin_weight{r}{m}
641 \latin_weight{k}{m}
642 \latin_weight{b}{b}
643 \latin_weight{s}{sb}
644 \latin_weight{d}{db} % was {d}{sb}, SPQR changed
645 \latin_weight{m}{mb} % was {m}{m},  UV changed
646 \latin_weight{c}{eb} % UV added
647 \latin_weight{h}{eb} % UV added
648 \latin_weight{x}{eb}
649 \latin_weight{u}{ub}
650 \latin_weight{l}{l}
651 %\latin_weight{j}{el}
652 %\latin_weight{a}{ul} % UV added

653 }

Fontname: width.map  NFSS: L^{A}TEX Companion, p. 190
t Thin  – –
o Ultra Condensed  uc Ultra Condensed
u Ultra Compressed  uc . .
q Extra Compressed  ec Extra Condensed
c Condensed  c Condensed
p Compressed  c . .
n Narrow  c . .
– –  sc Semi Condensed
r Normal, Medium, Regular m Medium
– –  sx Semi Expanded
e Expanded  x Expanded
x Extended  x . .
v Extra Expanded  ex Extra Expanded
– –  ux Ultra Expanded
w Wide  – –

\latin_widths Each call to \latin_width maps a Fontname width code (\font_width) to a L^{A}TEX width code (\latex_width). Non-existing narrow fonts are faked only if \fakenarrow is specifically called for.

654 \def\latin_widths{
655 \latin_width{}{}
656 \latin_width{n}{c}
657 %latin_width{c}{c}
658 %latin_width{x}{x}

659 }

\latin_shapes The fifth argument of \latin_shape is stored in the variable \encoding_switches.
660 \def\latin_shapes{
661 \latin_shape{} {} {} {n} {\_textcomp_true }
662 \latin_shape{c}{c}{} {sc}{\_textcomp_false}
663 \latin_shape{o}{o}{} {sl}{\_textcomp_true }
664 \latin_shape{i}{i}{i}{it}{\_textcomp_true }

665 }

\latin_encodings  \encoding_switches is evaluated immediatley before the \if_textcomp_test to

set it as appropriate for the curent shape.

666 \def\latin_encodings{
667 \latin_encoding{7t}{9t}{9o}{OT1}{newlatin}
668 \latin_encoding{8t}{9e}{9d}{T1} {newlatin}

669 ⟨∗textcomp⟩

670 \encoding_switches
671 \if_textcomp_
672  \latin_encoding{8c}{9c}{9c}{TS1}{textcomp}
673 \fi

674 ⟨/textcomp⟩ 675 }

\if_textcomp_Switch to control whether or not to install a text companion encoding. It is set or unset for each shape by \latin_shapes and evaluated in \latin_encodings.

676 \newif\if_textcomp_

\raw_encoding
\adobe_encoding
\expert_encoding

677 \def\raw_encoding{8r}
678 \def\adobe_encoding{8a}
679 \def\expert_encoding{8x}
\caps_shape
\oldstyle_shape
680 \def\caps_shape{c}
681 \def\oldstyle_shape{j}
\SlantAmount
682 \def\SlantAmount{167}

683 ⟨/pkg⟩

File f

fimapgen.dtx

18 Generating map file fragments

A map file is a file which is used by some DVI driver to link various kinds of font information to each other, as is needed for the driver’s operation. Examples of such files are the file psfonts.map used by dvips and the config files of OzTEX. There are however many other such files around in the TEX world.

Not all of a map file need to be related to linking specific kinds of font information to each other. OzTEX config files can for example be used to set the values of TEX implementation parameters^{12} and there need not be any font-related information at all in them. The important thing is however that there can be map information in them—that information could be automatically written by the routines described here.

Since there may be other kinds of information in these files (and often enough need to be for everthing to work right), the routines described here will only generate map file fragments. These fragments will then have to be inserted in the final map files somehow, usually through manual editing. The purpose of the routines described here is only to save the user a good deal of (often quite boring) typing, not to actually install everything where it needs to be.

\mapfrags_subsystem This macro holds the name of the automatic map file fragments writer subsystem of fontinst, as it appears in error messages.

 1 \def\mapfrags_subsystem{Map~fragments~writer}

18.1 Interface to main fontinst

The automatic generation of map file fragments is based on the two commands \storemapdata and \makemapentry. Their respective syntaxes are

\storemapdata{⟨TEX font name⟩}{⟨source⟩}{⟨transforms⟩}

     \makemapentry{⟨TEX font name⟩}

\storemapdata \storemapdata commands are written when a metric file ⟨TEX font name⟩.mtx is generated. The purpose of these commands is to record where the data for that file came from, and what was done to these data. The source of the data is specified in the ⟨source⟩ argument, which can contain one of

\fromafm{⟨AFM name⟩}{⟨PS name⟩}

     \frompl{⟨PL name⟩}
     \frommtx{⟨MTX name⟩}
     \fromvpl

The only real difference between \fromafm and \frompl at this stage is that the former specifies the PS name of the font, but the latter do not. If you write a \storemapdata command yourself and want to supply the PS name then you should use \fromafm even if you took the font metrics from a PL. There is a important difference between \fromvpl and the first three in that virtual fonts need no map file entry (and hence there should not be any either). Besides some error checking, \fromvpl causes a \makemapentry to do essentially nothing.

12The kind of things that were Pascal constants in the original Web sources for TEX.

What was done to the data is specified by the ⟨transforms⟩ argument, which is a possibly empty sequence of commands, in which each item is one of

\transformfont{⟨x-scale⟩}{⟨slant-scale⟩}

     \reencodefont{⟨etx⟩}
     \reglyphfont

The order is interpreted so that the thing done first appear first in the sequence. In normal cases there is at most one of each, and then the order is not important. ⟨x-scale⟩, ⟨slant-scale⟩, and ⟨y-scale⟩ are the values of these variables used for the transformation, as TEX numbers. ⟨etx⟩ is the name of the ETX file used for the font reencoding. \reglyphfont is an error marker. It will not be encountered (but it may well get stored in some table) unless a metric font transform is applied to a font that has been reglyphed, which is illegal.

In addition to being written to a transforms record file (if one is open), \storemapdata commands are also written to the actual metric file. This makes it possible to find out where the data for a file comes from even if the file was made on a previous fontinst run, but since it requires reading an additional file just to find one command, it will be slower than if the \storemapdata appeared in a transforms records file.

\makemapentry \makemapentry commands are written when a VPL that uses or a ligfull PL for a font is generated. These commands are the ones which actually cause the map file fragment generator to write an entry, but entries are only written if they haven’t been written before. \makemapentry uses information that was stored by a previous call to \storemapdata.

\Tf-⟨font⟩ \storemapdata stores its arguments in one of the control sequences \Tf-⟨font⟩, where ⟨font⟩ is the same thing as ⟨TEX font name⟩ above. Tf stands for “TEX font”. The control sequences in this family are paramterless macros whose replacement texts have the following form:

{⟨made⟩}{⟨source⟩}{⟨transforms⟩}

Here ⟨source⟩ and ⟨transforms⟩ are exactly as above. ⟨made⟩ is a number which describes the current status of this font. If ⟨made⟩ is even then the font has been defined but no entry for it has subsequently been written to the map file, whereas if it is odd then an entry for it has been written to the map file. If the value of ⟨made⟩ is less than \process_generation then the data in the other two arguments is from a previous run and should be ignored. The \Tf-⟨font⟩ control sequences should always be set globally.

\process_generation \process_generation_succ  \process_generation is a counter which stores the number of the current “en-

try generation”. It starts at 0 and is increased by two at each \donedrivers. \process_generation_succ is a macro which expands to a number one larger

than that in \process_generation.

2 ⟨∗map⟩

 3 \newcount\process_generation
 4 \process_generation=0
 5 \def\process_generation_succ{1}

6 ⟨/map⟩

\recordtransforms \endrecordtransforms \transform_record_file In main fontinst, the command
     \recordtransforms{⟨filename⟩}

starts a block of code within which font transforms will be recorded in the file ⟨filename⟩. \endrecordtransforms ends such a block.

7 ⟨∗pkg⟩

 8 \def\recordtransforms#1{\open_pout\transform_record_file{#1}}
 9 \def\endrecordtransforms{
10 \close_pout\transform_record_file{Font~transformation~records}

11 }

12 \chardef\transform_record_file=\closed_stream

13 ⟨/pkg⟩

\extract_font_generation The \extract_font_generation macro takes the name of a font and returns the

⟨made⟩ component from the \Tf-⟨font⟩ macro for that font, or minus one if that macro hasn’t been defined.

14 ⟨∗map⟩

15 \def\extract_font_generation#1{
16 \if_defined{Tf-#1}\then
17  \expandafter\expandafter \expandafter\first_of_three
18  \csname Tf-#1\endcsname
19 \else
20  \m@ne
21 \fi

22 }

\storemapdata There should not be two \storemapdata for the same font, hence the check below. (Note that a ‘font’ in this case is an MTX file. It is quite possible (and legal) to generate the PL file for that MTX file more than once.)

23 \def\storemapdata#1#2#3{
24 \expandafter\def \expandafter\a_macro
25  \expandafter{ \expandafter{ \the\process_generation}{#2}{#3}}
26 \ifnum \extract_font_generation{#1}<\process_generation \else
27  \x_cs\ifx{Tf-#1}\a_macro
28  \fontinstinfo\mapfrags_subsystem
29  {Repeated~definition~of~font~#1}
30  \else
31  \fontinstwarning\mapfrags_subsystem
32  {Inconsistent~redefinition~of~font~#1}
33  \fi
34 \fi
35 \x_cs\let{Tf-#1}=\a_macro

36 } 37 ⟨/map⟩

In main fontinst, \storemapdata should be a noop so that it can appear in metric files.

38 ⟨pkg⟩\let\storemapdata=\gobble_three

\record_transform In main fontinst, the call

\record_transform{⟨TFM name⟩}{⟨source⟩}{⟨transforms⟩}{⟨if ⟩}

writes

\storemapdata{⟨TFM name⟩}{⟨source⟩}{⟨transforms⟩}

to the transformation recordings file (if font transforms are being recorded) and to the main output file (if the ⟨if ⟩ evaluates to true). Note that the caller of \record_transform must see to that macros in ⟨source⟩ and ⟨transforms⟩ are written correctly to the file (this is usually accomplished by adding \string in suitable places of these arguments during their construction).

39 ⟨∗pkg⟩

40 \def\record_transform#1#2#3#4{
41 \ifnum \transform_record_file=\closed_stream \else
42  \pout_line\transform_record_file{\string\storemapdata{#1}{#2}{#3}}
43 \fi
44 #4 \out_line{\string\storemapdata{#1}{#2}{#3}} \fi

45 } 46 ⟨/pkg⟩

\transformfont \reencodefont \reglyphfont These are initially \relax, so they can be \edefed with safely.

47 ⟨∗map⟩

48 \let\transformfont\x_relax
49 \let\reencodefont\x_relax
50 \let\reglyphfont\x_relax

\makemapentry  \makemapentry sets \TeX_font_name, checks if any map data have been stored

for the font in question, and passes them on to \make_map_entry if they have; otherwise it raises an error. There is also a group which is begun and ended by \makemapentry, to stop values deduced for one entry to interfere with the deduction of values in the following.

51 \def\makemapentry#1{\begingroup
52 \def\TeX_font_name{#1}
53 \ifnum \extract_font_generation{#1}<\process_generation
54  \if_file_exists{#1.mtx}\then
55  \inputmtx{#1}
56 \fi\fi
57 \ifnum \extract_font_generation{#1}<\process_generation
58  \from_unknown{#1}
59  \x_cs\xdef{Tf-#1}{
60  {\process_generation_succ}{\noexpand\from_unknown{#1}}{}

61 }

62 \else
63  \expandafter\expandafter \expandafter\make_map_entry
64  \csname Tf-#1\endcsname
65 \fi
66 \endgroup

67 }

\make_map_entry \make_map_entry oversees the interpretation of the ⟨source⟩ part of the map data,

something which sets \source_font_TeX_name and possibly \PS_font_name. It

also collects the transforms applied in \font_transforms, concatenates them, and calls a list macro \entry_makers_list which causes the actual entries to be written, and records in \Tf-⟨TEX font name⟩ that the entries have been written.

68 \def\make_map_entry#1#2#3{
69 \ifnum #1=\process_generation

70  \def\font_transforms{#3}
71  #2
72  \_a_false
73  \let\transformfont\concat_transformfont
74  \let\reencodefont\concat_reencodefont
75  \let\reglyphfont\_a_true
76  \font_transforms
77  \if_a_
78  \fontinsterror\mapfrags_subsystem{
79  \string\makemapentry\space for~reglyphed~font
80  }{ No~entry~for~font~\TeX_font_name\space
81  can~be~written,\messagebreak
82  since~it~had~been~reglyphed!~\error_help_a

83 }

84  \else
85  \entry_makers_list
86  \fi
87  \expandafter\gdef \csname Tf-\TeX_font_name \expandafter\endcsname
88  \expandafter{\expandafter{\process_generation_succ}{#2}{#3}}
89 \fi

90 } 91 ⟨/map⟩

\record_usage In main fontinst, the call

     \record_usage{⟨TFM name⟩}

writes

     \makemapentry{⟨TFM name⟩}

to the transformation recordings file, if font transforms are being recorded. The \record_usage command is, roughly speaking, only used by \installfont and

\installrawfont.

92 ⟨∗pkg⟩

93 \def\record_usage#1{
94 \ifnum \transform_record_file=\closed_stream \else
95  \pout_line\transform_record_file{\string\makemapentry{#1}}
96 \fi

97 } 98 ⟨/pkg⟩

\fromafm \fromafm saves its two arguments in the suitable string macros.

99 ⟨∗map⟩

100 \def\fromafm#1#2{
101 \def\source_font_TeX_name{#1}
102 \def\PS_font_name{#2}

103 }

\frompl \frompl saves its argument in the suitable string macro.

104 \def\frompl#1{
105 \def\source_font_TeX_name{#1}

106 }

\frommtx This one is tricky, since it will have to work recursively, fetching data that were stored for some other font. If it cannot find those data in memory, then it tries to get them from the metric file itself.

107 \def\frommtx#1{%
108 \ifnum \extract_font_generation{#1}<\process_generation
109  \if_file_exists{#1.mtx}\then
110  \inputmtx{#1}
111 \fi\fi
112 \ifnum \extract_font_generation{#1}<\process_generation
113  \from_unknown{#1}
114  \x_cs\xdef{Tf-#1}{
115  {\the\process_generation}{\noexpand\from_unknown{#1}}{}

116 }

117 \else
118  \expandafter\expandafter \expandafter\from_mtx
119  \csname Tf-#1\endcsname
120 \fi

121 }

\from_mtx
122 \def\from_mtx#1#2#3{
123 \edef\font_transforms{#3\font_transforms}

124 #2 125 }

\fromvpl The \fromvpl command checks if \font_transforms is empty. If it is then everything is fine, but no entry should be written for this font. If it isn’t then someone has tried to make a transformation of a virtual font, which doesn’t work.

126 \def\fromvpl{
127 \ifx \empty_command\font_transforms \else
128  \fontinsterror\mapfrags_subsystem{
129  Font~is~virtual,~it~cannot~be~transformed}{
130  No~entry~for~font~\TeX_font_name\space can~be~written.
131  \messagebreak\error_help_a

132 }

133 \fi
134 \let\maker_do\gobble_one

135 }

\AssumeMetafont The \AssumeMetafont general settings command makes \frompl behave like

 \fromvpl.
136 \def\AssumeMetafont{
137 \def\frompl{
138  \ifx \empty_command\font_transforms \else
139  \fontinsterror\mapfrags_subsystem{
140  A~Metafont~cannot~be~transformed}{
141  No~entry~for~font~\TeX_font_name\space can~be~written.
142  \messagebreak\error_help_a

143 }

144  \fi
145  \let\maker_do\gobble_one

146 } 147 }

\from_unknown This special value for ⟨source⟩ is used for fonts that are referenced by some \frommtx but which have no \storemapdata themselves.

148 \def\from_unknown#1{
149 \fontinstwarningnoline\mapfrags_subsystem{
150  No~map~data~stored~for~font~#1.\messagebreak
151  No~entry~for~\TeX_font_name\space will~be~written,\messagebreak
152  due~to~insufficient~information}
153 \includewarning\warn_unknown_source
154 \let\maker_do\gobble_one

155 }

\font_transforms This macro is used to collect all transformations that have been applied to a font in, before they are concatenated.

156 \let\font_transforms\empty_command
\xscale_factor \slant_factor \reencode_etx  \xscale_factor and \slant_factor are dimens which the entry makers can in-

spect to check the amount of horizontal scaling and slanting should be applied to the current font. 1 pt equals the factor 1.

     \expandafter\lose_measure\the\xscale_factor

will produce the corresponding factor.

\reencode_etx is a macro which contains the name of the (last) ETX file used to reencode the font; it is empty if the font hasn’t been reencoded.

157 \newdimen\xscale_factor  \newdimen\slant_factor
158 \xscale_factor=\p@       \slant_factor=\z@
159 \let\reencode_etx\empty_command

\concat_transformfont The \concat_transformfont macro is a definition of \transformfont which

concatenates the transformation expressed by the arguments with the one in \xscale_factor and \slant_factor. Mathematically, it performs the multiplication

        ( \begin{matrix}f(#1) & f(#2) \\ 0 & 1 \end{matrix} ) ( \begin{matrix}\xscale_factor & \slant_factor \\ 0 & 1 \end{matrix} )

where f stands for \make_factor.

160 \def\concat_transformfont#1#2{
161 \edef\a_macro{\make_factor{#1}}
162 \xscale_factor=\a_macro\xscale_factor
163 \slant_factor=\a_macro\slant_factor
164 \advance \slant_factor \make_factor{#2}\p@

165 }

\concat_reencodefont The \concat_reencodefont macro is a definition of \reencodefont which con-

catenates the reencoding expressed by the argument with the one in \reencode_etx. Since reencoding ignores the previous encoding, concatenating is the same thing as remembering the last reencoding.

166 \def\concat_reencodefont#1{\def\reencode_etx{#1}}

18.2 User interface

The basic usage of the automatic map file fragment generator consists of specifying for which driver(s) entries should be generated, \inputing a file of recorded transformations generated by main fontinst, and signaling that there isn’t anything more to write. This can be done with the commands

\adddriver{⟨driver name⟩}{⟨fragment file name⟩}

⟨possible additional \adddriver commands⟩

\input ⟨recorded transforms file⟩

     \donedrivers
     \bye

It should however be noted that this is the basic usage. The map fragments that work for one TEX system need not work for another (even if the driver is the same), and therefore it is necessary to make the whole process of writing map file fragments configurable. A few examples of things you may have to inform the map fragment writer about are (and these are for dvips alone; that’s the driver I know best):

• Is the font resident on the printer or must it be downloaded?

• If the font must be downloaded, what is the name of the file it is in? Here one must take into account not only the possibility that the font file might have to be shared with some other software (such as a GUI) and thus cannot be named according to the Berry scheme—even if it is named according to the Berry scheme one still has the question of its extension: .pfa, .pfb, or something else? For instances of Multiple Master fonts, you (at least sometimes) have to download more than one file.

• Again if the font must be downloaded, can/should it be partially downloaded?

• In case the font has been reencoded, what is the name of the file which defines this encoding, and by what name does that file make the encoding known to the postscript interpreter?

The mechanisms available for such configuration are described in Subsection 18.2.2. Note that map files for DVI viewers are on average more likely to need various platform-specific information about the fonts than map files for DVI printer drivers are, and hence once can expect that generation of these will need more extensive configuration than that for the printer drivers.

18.2.1 Interface for basic usage

An entry maker is a group of macros which write the entry for the font currently under consideration to a map fragments file each time they are called. The macro

\make_⟨driver⟩ to call must have a name of the form \make_⟨driver⟩ for \adddriver to recognise

it. Each entry maker has a separate output file (opened using \open_pout) and

\output_⟨driver⟩ the identifier connected to that file is called \output_⟨driver⟩.

A list of all entry makers currently active is maintined in the macro \entry_makers_list. Each item in this list has the form

     \maker_do\make_⟨driver⟩

\maker_do is usually \relax, but it does occationally get set to other values.

\adddriver The \adddriver command adds the named driver to the list of drivers to write entries for and opens an output file where the entries for that particular driver will go. Repeated calls to \adddriver for the same driver have no effect.

167 \def\adddriver#1#2{
168 \x_cs\ifx{make_#1}\x_relax
169  \fontinsterror\mapfrags_subsystem
170  {There~is~no~entry~maker~for~#1}\error_help_a
171 \else
172  \x_cs\ifx{output_#1}\x_relax \_a_true \else
173  \x_cs\ifx{output_#1}\closed_stream \_a_true \else
174  \_a_false
175  \fi\fi
176  \if_a_
177  \x_cs\open_pout{output_#1}{#2}
178  \expandafter\add_to \expandafter\entry_makers_list
179  \expandafter{ \expandafter\maker_do
180  \csname make_#1\endcsname}
181  \fi
182 \fi

183 }

\entry_makers_list
\maker_do
184 \let\entry_makers_list\empty_command
185 \let\maker_do\x_relax

\donedrivers The main function performed by the \donedrivers command is to close all the open output files. It might also print some warning messages.

186 \def\donedrivers{
187 \def\maker_do##1{
188  \x_cs\close_pout{output\expandafter\gobble_five\string##1}
189  {Map~file~fragments}

190 }

191 \entry_makers_list
192 \let\maker_do\x_relax
193 \let\entry_makers_list\empty_command
194 \errorstopmode
195 \reportwarnings
196 \advance \process_generation \thr@@
197 \edef\process_generation_succ{\the\process_generation}
198 \advance \process_generation \m@ne

199 }

\gobble_five
200 \def\gobble_five#1#2#3#4#5{}

It is appropriate that the map file writer writes a summary of the kinds of risky things which happened when it is done writing data to files. To simplify

\includewarning implementing such things, there is a command \includewarning that takes care of the bookkeeping involved. After the call

      \includewarning⟨command⟩

the ⟨command⟩ will be executed exactly once the next time \reportwarnings is executed. The ⟨command⟩ usually expands to something like

     \fontinstwarningnoline\mapfrags_subsystem{
        Check~the~output~file(s)--some~data~was~considered~uncertain}

\warnings_list The \warnings_list macro contains a list of all warnings that should be made. It expands to a sequence of

     \warning_do⟨command⟩

\warnings_list is always assigned globally.

201 \g_let\warnings_list=\empty_command
\includewarning \warning_do The \includewarning command adds an entry for its argument to the \warnings_list

list, provided there wasn’t already such an entry. \includewarning is based on the macro \warning_do, which does most of the bookkeeping for making sure the list contains at most one entry of each kind. \warning_do normally expects to be expanded in the context

\warning_do⟨new command⟩⟨old command⟩⟨next⟩

The ⟨new command⟩ is the command that is being added to the list, and the ⟨old command⟩ is a command that is already in the list. ⟨next⟩ is the first token in the next item in the list—in most cases another \warning_do. If ⟨new command⟩ and ⟨old command⟩ are not equal, this should expand to

\noexpand\warning_do\noexpand⟨old command⟩ ⟨next⟩ ⟨new command⟩

If on the other hand they are equal, this should expand to

     \noexpand\warning_do\noexpand⟨old command⟩ ⟨next⟩ \x_relax

The reason for this is that the last ⟨next⟩ will not be a \warning_do, but an \ifx which tests whether a new item should be added to the list.

202 \def\warning_do#1#2#3{
203 \noexpand\warning_do \noexpand#2
204 \ifx #1#2
205  \expandafter#3 \expandafter\x_relax
206 \else
207  \expandafter#3 \expandafter#1
208 \fi

209 }

210 \def\includewarning#1{
211 \xdef\warnings_list{
212  \expandafter\swap_two \expandafter#1 \warnings_list
213  \if_equal\x_relax\then \else
214  \noexpand\warning_do \noexpand#1
215  \fi

216 } 217 }

\reportwarnings The \reportwarnings command reports all the warnings and empties the

\warnings_list.
218 \def\reportwarnings{

219 \begingroup
220  \let\warning_do=\x_relax
221  \warnings_list
222 \endgroup
223 \g_let\warnings_list=\empty_command

224 }

\warn_unknown_source \warn_undecided_data \warn_uncertain_data These macros are used to output warnings at the \reportwarnings at the end of
\donedrivers.
225 \def\warn_unknown_source{
226 \fontinstwarningnoline\mapfrags_subsystem{
227  Some~font~is~missing~from~the~output~file(s),\messagebreak
228  since~its~source~is~unknown}

229 }

230 \def\warn_undecided_data{
231 \fontinstwarningnoline\mapfrags_subsystem{
232  Check~the~output~file(s)--some~data~could~not~be~determined}

233 }

234 \def\warn_uncertain_data{
235 \fontinstwarningnoline\mapfrags_subsystem{
236  Check~the~output~file(s)--some~data~was~considered~uncertain}

237 }

18.2.2 Configuration interface

To correctly format reencodings, the map file writer must know what the ETX encodings correspond to. In the case of drivers which generate postscript output,

\pse-⟨etx⟩ this information is stored in the \pse-⟨etx⟩ family of macros. ⟨etx⟩ is the name (suffix excluded) of the ETX file that the information pertains to. The expansion of these macros are of the form

{⟨postscript name⟩}{⟨action⟩}

⟨postscript name⟩ is the name by which the encoding is known to the postscript interpreter, and ⟨action⟩ lists any additional action that must be taken before the

\download encoding can be used. So far the only action known is \download{⟨file⟩}, which will cause code for downloading the file by the name ⟨file⟩ (suffix included) to be inserted in the output.

\declarepsencoding Data is entered in a \pse-⟨etx⟩ macro using the \declarepsencoding command. Its syntax is

\declarepsencoding{⟨etx⟩}{⟨postscript name⟩}{⟨action⟩}

238 \def\declarepsencoding#1#2#3{\x_cs\gdef{pse-#1}{{#2}{#3}}}

\download By default \download gobbles its argument. It should be redefined when that is not the desired effect.

239 \let\download=\gobble_one

\fulldownload By default this defaults to being a synonym of \download, to simplify matters for drivers where the distinction is not relevant. They should be redefined when that is not the desired effect.

240 \def\fulldownload#1{\download{#1}}

Some encodings seem to always be present, so they can be declared here.

241 \declarepsencoding{8r}{TeXBase1Encoding}{\download{8r.enc}}
242 \declarepsencoding{8a}{StandardEncoding}{}

fontinst must be told about other postscript encodings (if you have them installed). The finstmsc.rc file is the right place for these declarations.

Next we have the cofiguration for fonts, which works in a similar fashion. The main problem here seems to be to determine which files (if any) should be downloaded to the printer, and this can be specified using \download commands

\psf-⟨PS font name⟩ as for the encodings. The family \psf-⟨PS font name⟩ of macros expand to a sequence of ⟨actions⟩ as for the encodings. If there is such a macro for a font then the instructions found there should be followed.

It is recommended that the contents of a \psf-⟨PS font name⟩ macro is executed before the map file entry is written, and that commands like \download are temporarily redefined to build the text for the entry, rather than having the \write in \pout_line expand the contents of \psf-⟨PS font name⟩.

\specifypsfont The \specifypsfont command is used as

\specifypsfont{⟨PS font name⟩}{⟨actions⟩}

It can be used to specify the actions that should be done to make a Postscript font known to the printer, when the automatic guessing would not be right.

243 \def\specifypsfont#1#2{\x_cs\def{psf-#1}{#2}}

Examples of cases where \specifypsfont would be needed are:

• Fonts which are resident on the printer. In this case the ⟨actions⟩ argument should be empty, e.g.

         \specifypsfont{Times-Roman}{}

• Instances of multiple master fonts. In this case one must download both the multiple master font and the stub file that defines the instance.

Subsection 10.6.1 in The L^{A}TEX graphics companion [4] contains an example with an instance of the MinionMM multiple master font. Both the TEX and (what is of interest here) the PS name for this instance is zmnl8ac6, the base multiple master font is stored in the file MinionMM.pfb, and the stub file is called zmnl8ac6.pro. The \specifypsfont command for this is

         \specifypsfont{zmnl8ac6}{%
            \download{MinionMM.pfb}\download{zmnl8ac6.pro}%
         }

• Fonts which do not fit any of the general naming schemes.

\AssumeLWFN This command makes MacOS LWFN style abbreviated Postscript font names the default for fonts that have no \psf- entry.

244 \def\AssumeLWFN{\let\get_PS_font_file\LWFN_get_PS_font_file}

18.3 Deducing values for the map file entries

18.3.1 Basic principles

The automatic generation of map file fragments mainly consists of determining various text strings and writing these to a file as the format of the map file being written requires. The complicated part is usually to determine what these text strings should be, since the only restriction imposed by the output format often is that the strings should be written in the right order and with separating whitespace.

It is furthermore the case that some of these text strings seem to be hard to deduce from the information primarily given in the command to write the entry, but somewhat easier to deduce from some other deduced text string.

Therefore the following model seems appropriate. For each text string that may need to be deduced, there is one macro which is used to store the string (if it has been deduced) and one macro which can be called to set the former macro to an appropriate value. Thus there is one macro \PS_font_name which stores the postscript name for the font currently in question and one

\get_⟨string name⟩ macro \get_PS_font_name which determines the proper value for \PS_font_name.

\unknown_str There is also a macro \unknown_str to which all the string storing macros should initially be \let, so that it can be easily tested whether a string storing macro has been given its proper value or not.

Typically, if \PS_font_name is used somewhere, one would first have a piece of code that says

     \ifx\PS_font_name\unknown_str
        \get_PS_font_name
     \fi

to ensure that it is known when it is used.

\unknown_str A suitable value for this macro seems to be ?????.

245 \def\unknown_str{?????}

\clueless_str To further support this model, there is also a macro \clueless_str which a string storing macro should be \let equal to if its proper value could not be determined. This distinction is useful for the \get_… macros, since if \get_A can determine the correct value of A from B, but also from C, then it helps if \get_A can easily check whether it has previously turned out to be impossible to determine the value of B, because then it can simply deduce A from C instead.

246 \edef\clueless_str{\unknown_str ?}

An example of how \clueless_str should be used is the following skeleton of a \get_A macro:

     \def\get_A{
        \ifx\unknown_str\B \get_B \fi
        \ifx\clueless_str\B
           \ifx\unknown_str\C \get_C \fi
           \ifx\clueless_str\C
              \let\A\clueless_str
           \else

⟨Deduce A from C⟩

           \fi
        \else

⟨Deduce A from B⟩

        \fi
     }

18.3.2 Implementation

\TeX_font_name This is the name (as appearing in a DVI or VF file) of the font for which an entry should be made. It is set by \makemapentry, so no \get_… macro is needed.

247 \let\TeX_font_name\unknown_str

\source_font_TeX_name This is the name (as AFM or PL) of the font whose metrics were used by fontinst. It is set by \fromafm or \frompl, so no \get_… macro is needed.

248 \let\source_font_TeX_name\unknown_str

\PS_font_name This is the name (as FontName entry in an AFM or correspondingly) of the font in question.

249 \let\PS_font_name\unknown_str

\get_PS_font_name I expect this to become one of the central macros in the map file generation (at least when entries are generated for postscript fonts), but for the moment it does the closest thing to nothing a \get_… macro is allowed to do; it admits it hasn’t got a clue about what the proper value is.

250 \def\get_PS_font_name{\let\PS_font_name\clueless_str}
\AssumeAMSBSYY \AssumeBaKoMa These commands redefine \get_PS_font_name so that it returns the PS name

this font would have if it was part of the AMS/Blue Sky/Y&Y and BaKoMa respectively distribution of the Computer Modern fonts—the TEX font name in all upper case and all lower case respectively.

251 \def\AssumeAMSBSYY{\def\get_PS_font_name{
252 \uppercase \expandafter{ \expandafter\def
253  \expandafter\PS_font_name \expandafter{ \source_font_TeX_name}

254 } 255 }}

256 \def\AssumeBaKoMa{\def\get_PS_font_name{
257 \lowercase \expandafter{ \expandafter\def
258  \expandafter\PS_font_name \expandafter{ \source_font_TeX_name}

259 } 260 }}

\PS_font_file This is the name of the file (suffix included) in which the PS font is expected to be found.

261 \let\PS_font_file\unknown_str
\get_PS_font_file \normal_get_PS_font_file PSfontsuffix string The macro \normal_get_PS_font_file is (hardly surprisingly) the normal
\get_PS_font_file. It simply uses \source_font_TeX_name plus the suffix spec-

ified by the PSfontsuffix string.

262 \resetstr{PSfontsuffix}{.pfa}
263 \def\normal_get_PS_font_file{
264 \edef\PS_font_file{\source_font_TeX_name\str{PSfontsuffix}}

265 }

266 \let\get_PS_font_file=\normal_get_PS_font_file

\LWFN_get_PS_font_file \abbreviate_PS_font_name In MacOS, Postscript fonts file names are usually abbreviated forms of the Postscript font names, formed using the so called 5 + 3 + 3 + ⋯ rule—keep the first five letters of the first subword, keep the first three letters of all following subwords. The \LWFN_get_PS_font_file macro uses this scheme if the Postscript name for the font is known, otherwise it calls the \normal_get_PS_font_file. The LWFN in the macro name is the type code for such files.

The algorithm is based on using \aftergroup to construct the wanted \def statement, only \aftergrouping the letters that are not to be removed in the abbreviation. \a_count is used as a counter of how many more letters in the current subword should be kept.

267 \def\LWFN_get_PS_font_file{
268 \ifx \PS_font_name\unknown_str \get_PS_font_name \fi
269 \ifx \PS_font_name\clueless_str
270  \normal_get_PS_font_file
271  \includewarning\warn_uncertain_data
272 \else
273  \begingroup
274  \aftergroup\def \aftergroup\PS_font_file
275  \aftergroup{
276  \a_count=4~
277  \expandafter\expandafter \expandafter\aftergroup
278  \expandafter\swap_two \expandafter\abbreviate_PS_font_name
279  \PS_font_name \x_relax
280  \aftergroup}
281  \endgroup
282 \fi

283 }

284 \def\abbreviate_PS_font_name#1{
285 \ifx \x_relax#1 \else
286  \ifnum \uccode`#1=`#1
287  \a_count=2
288  \aftergroup#1
289  \else\ifx -#1
290  \a_count=\z@
291  \else\ifnum \a_count>\z@
292  \advance \a_count \m@ne
293  \aftergroup#1
294  \fi\fi\fi
295  \expandafter\abbreviate_PS_font_name
296 \fi

297 }

18.4 Driver makers

This subsection contains the definitions of macros that makes up the driver makers.

18.4.1 The debug driver

The debug driver maker doesn’t really generate entries for any DVI driver map file, it just prints the data that was available. It is mainly intended for debugging purposes, but it might also serve as a basic model for other driver makers.

\make_debug
298 \def\make_debug{
299 \pout_line\output_debug{Driver~data~for~font~\TeX_font_name:}
300 \pout_lline\output_debug{Source~font~TeX~name:~\source_font_TeX_name}
301 \ifx \reencode_etx\empty_command \else
302  \pout_lline\output_debug{Font~reencoded~using~\reencode_etx.etx.}
303 \fi
304 \ifdim \xscale_factor=\p@ \else
305  \pout_lline\output_debug{Font~x-scaled~by~
306  \expandafter\lose_measure\the\xscale_factor.

307 }

308 \fi
309 \ifdim \slant_factor=\z@ \else
310  \pout_lline\output_debug{Font~slanted~by~
311  \expandafter\lose_measure\the\slant_factor.

312 }

313 \fi
314 \debug_values_hook

315 }

\debug_value The \debug_value macro can be used to print the name and contents of an arbitrary value macro in the debug driver. It is called with the value macro as argument, e.g.

      \debug_value\PS_font_name
316 \def\debug_value#1{
317 \ifx #1\unknown_str
318  \csname get_\expandafter\gobble_one \string#1 \endcsname
319 \fi
320 \pout_lline\output_debug{\string#1:~#1}
321 \ifx #1\clueless_str \includewarning\warn_undecided_data \fi

322 }

\debugvalue \debug_values_hook The \debugvalue command is a user level interface for adding value macros to the list of those that are displayed by the debug driver. The argument is the name of the value in question, e.g.

      \debugvalue{PS_font_name}

Note that the name given to \debugvalue is not the control sequence in which the name is stored.

323 \def\debugvalue#1{
324 \expandafter\add_to \expandafter\debug_values_hook
325 \expandafter{ \expandafter\debug_value \csname#1\endcsname}

326 }

327 \let\debug_values_hook\empty_command
328 \debugvalue{PS_font_name}

18.4.2 The dvips driver

Before constructing an entry for a dvips mapfile, it should be sorted out how such an entry should look. The dvips manual says

The parsing of the psfonts.map file should be explained to eliminate all confusion. If a line is empty or begins with a space, asterisk, semicolon, or hash mark, it is ignored. Each remaining line is separated into words, where words are separated by spaces or tabs. If a word begins with a double quote, it extends until the next double quote or the end of the line. If a word starts with a less than character, it is treated as a font header file (or a downloaded PostScript font). There can be more than one such header for a given font. If a word starts with a double quote, it is a special instruction for generating that font. Otherwise it is a name. The first such name is always the name TEX uses for the font and is also the name of the raw tfm file. If there is another name word, that name is used as the PostScript name; if there is only one name word, it is used for both the TEX name and the PostScript name.

A fontinst-generated map file entry for the dvips driver has the following structure:

⟨TEX font name⟩ ⟨PS font name⟩ ⟨downloads⟩ ⟨font transformations⟩

⟨TEX font name⟩ is simply the value of \TeX_font_name and ⟨PS font name⟩ is simply the value of \PS_font_name. ⟨downloads⟩ is a possibly empty sequence in which each item has the form

⟨prefix⟩⟨filename⟩

The ⟨prefix⟩ values I’ve came across are empty,^{13} <, <<, and <[. Currently < is always used. ⟨filename⟩ is a filename with suffix. ⟨font transformations⟩ is either empty or has the form

" ⟨Postscript code⟩ "

Should support for the << or <[ prefixes be needed, then this should be done by adding some new variant of the \download command—\fullldownload, maybe— rather than adding the extra character to the ⟨filename⟩. To simplify matters for other drivers, such new variants should by default expand to \download, rather

than \gobble_one.

\downloads_list \append_download The \downloads_list is a token list register which is especially used for accumulating \download commands. Each driver maker which uses it should begin by emptying it.

\append_download{⟨arg⟩}

appends

\download{⟨arg⟩}
to \downloads_list.
329 \newtoks\downloads_list
330 \def\append_download#1{
331 \downloads_list=\expandafter{ \the\downloads_list \download{#1} }

332 }

13I think this is only used for files that dvips should ignore, but which certain other programs that read the same psfonts.map need.

\make_dvips This macro gathers the information for a dvips driver entry and writes it to the corresponding output file. As a dvips mapfile entry is on one line, the entire entry is written at once. The ⟨font transformations⟩ is collected as explicit text in the macro \postscript_code. The ⟨downloads⟩ is collected as a sequence of \download commands in the \downloads_list token register.

333 \def\make_dvips{
334 \downloads_list={}
335 \let\postscript_code\empty_command
336 \let\download\append_download
337 \ifx \reencode_etx\empty_command \else
338  \if_undefined{pse-\reencode_etx}\then
339  \etxtoenc{\reencode_etx}{\reencode_etx}
340  \fi
341  \expandafter\expandafter \expandafter\second_of_two
342  \csname pse-\reencode_etx\endcsname
343  \edef\postscript_code{\postscript_code\space
344  \expandafter\expandafter \expandafter\first_of_two
345  \csname pse-\reencode_etx\endcsname
346  \space ReEncodeFont

347 }

348 \fi
349 \ifdim \xscale_factor=\p@ \else
350  \edef\postscript_code{\postscript_code
351  \space\expandafter\lose_measure\the\xscale_factor
352  \space ExtendFont

353 }

354 \fi
355 \ifdim \slant_factor=\z@ \else
356  \edef\postscript_code{\postscript_code
357  \space\expandafter\lose_measure\the\slant_factor
358  \space SlantFont

359 }

360 \fi

After constructing the ⟨Postscript code⟩ and having appended the necessary download (if any) for that code, the next problem is to determine the actual ⟨PS font name⟩ and append the downloads needed to actually define the font to the Postscript interpreter. If there is no special entry for this font in the \psf-⟨PS font name⟩ table, or if its ⟨PS font name⟩ is unknown, then it is assumed that exactly one file should be downloaded. As the name of that file is taken the value

 of \PS_font_file.
361 \ifx \PS_font_name\unknown_str \get_PS_font_name \fi
362 \ifx \PS_font_name\clueless_str
363  \includewarning\warn_undecided_data
364  \_a_true
365 \else
366  \if_undefined{psf-\PS_font_name}\then
367  \_a_true
368  \else
369  \csname psf-\PS_font_name \endcsname
370  \_a_false
371 \fi\fi
372 \if_a_

373  \ifx \PS_font_file\unknown_str \get_PS_font_file \fi
374  \append_download{\PS_font_file}
375  \ifx \PS_font_file\clueless_str
376  \includewarning\warn_undecided_data
377  \fi
378 \fi

Finally, the entire entry is written to the file. The point with expanding past an empty command is that TEX in a \write normally jumps past the expansion of a \the⟨token list register⟩ without expanding it further, but this effect can be prevented by expanding the \the with an \expandafter.

379 \def\download##1{~<##1}
380 \pout_line\output_dvips{
381  \TeX_font_name\space\PS_font_name
382  \expandafter\empty_command \the\downloads_list
383  \ifx \postscript_code\empty_command \else
384  \space"\postscript_code\space"
385  \fi

386 } 387 }

18.4.3 The dvipdfm driver

A mapfile entry for the dvipdfm driver has the following structure:

⟨TEX font name⟩ ⟨encoding⟩ ⟨PS font⟩ ⟨options⟩

⟨TEX font name⟩ is simply the value of \TeX_font_name. ⟨encoding⟩ is the name of the encoding file which should be used to reencode the font, or default if there is none. ⟨PS font⟩ is the value of \PS_font_name for the standard 35 fonts (i.e., fonts which will not be included in the PDF generated), but for other fonts it is the name of the file which contains the font.^{14} ⟨options⟩, finally, is a possibly empty sequence of space-separated options. Each option is one of the following

-e ⟨number⟩ -s ⟨number⟩

     -r

The -e and -s options extend and slant by the given amounts. The -r option is a workaround for some Acrobat bugs; it is currently not generated by fontinst.

\make_dvipdfm This macro gathers the information for a dvipdfm driver entry and writes it to the corresponding output file. As a dvipdfm mapfile entry is on one line, the entire entry is written at once. The ⟨options⟩ text is collected as explicit text in the macro \options_text. The ⟨downloads⟩ is collected as a sequence of \download commands in the \downloads_list token register.

388 \def\make_dvipdfm{
389 \def\font_encoding{default}
390 \ifx \reencode_etx\empty_command \else
391  \if_undefined{pse-\reencode_etx}\then
392  \etxtoenc{\reencode_etx}{\reencode_etx}

14The documentation seems to say that dvipdfm can only understand fonts in PFB format; I have chosen to ignore this potential problem.

393  \fi
394  \def\download##1{\def\font_encoding{##1}}
395  \expandafter\expandafter \expandafter\second_of_two
396  \csname pse-\reencode_etx\endcsname
397 \fi
398 \let\options_text\empty_command
399 \ifdim \xscale_factor=\p@ \else
400  \edef\options_text{\options_text\space
401  -e~\expandafter\lose_measure\the\xscale_factor

402 }

403 \fi
404 \ifdim \slant_factor=\z@ \else
405  \edef\options_text{\options_text\space
406  -s~\expandafter\lose_measure\the\slant_factor

407 }

408 \fi

After constructing the ⟨options⟩ and having determined ⟨encoding⟩, the next problem is to determine the actual ⟨PS font⟩, which will be put in \a_macro. If there is no special entry for this font in the \psf-⟨PS font name⟩ table, or if its ⟨PS font name⟩ is unknown, then it is assumed that exactly one file should be downloaded. As the name of that file is taken the value of \PS_font_file.

409 \ifx \PS_font_name\unknown_str \get_PS_font_name \fi
410 \if_or \if_equal\PS_font_name\clueless_str \or_else
411  \if_undefined{psf-\PS_font_name}
412 \then
413  \ifx \PS_font_file\unknown_str \get_PS_font_file \fi
414  \ifx \PS_font_file\clueless_str
415  \includewarning\warn_undecided_data
416  \fi
417  \let\a_macro=\PS_font_file
418 \else
419  \let\a_macro=\PS_font_name
420  \def\download##1{\def\a_macro{##1}}
421  \csname psf-\PS_font_name \endcsname
422 \fi

Finally, the entire entry is written to the file.

423 \pout_line\output_dvipdfm{
424  \TeX_font_name\space\font_encoding\space\a_macro
425  \options_text

426 } 427 }

18.4.4 The pltotf “driver”

It can sometimes be hard to determine which of all the PL files that fontinst creates need to be converted to TFM files. In most cases no 8a-encoded PLs need to be converted as they aren’t used as base fonts or installed in an FD file, but to automatically exclude them isn’t a trivial task (even though it probably could be done by a regular expression filter for fonts named according to the fontname scheme). There furthermore seems to be some systems on which it for various reasons isn’t easy to convert all PLs in a directory. The pltotf “driver” support is meant to help with both these problems, as the “map file” it creates really is a shell script (batch file) for converting precisely those PL files that need a map file entry to TFM format. I believe the shell script will work both for UNIX and DOS systems.

\make_pltotf TFMfileprefix string \make_pltotf writes a PLtoTF command for converting the current font’s PL file to a TFM file. If set, the string TFMfileprefix will be prepended to the TFM file name—this could be used for putting the TFMs in some directory other than the current.

428 \def\make_pltotf{
429 \pout_line\output_pltotf{pltotf~\TeX_font_name.pl~
430  \ifisstr{TFMfileprefix}\then \str{TFMfileprefix}\fi
431  \TeX_font_name.tfm

432 } 433 }

434 ⟨/map⟩

Index

Compound numbers (numbers with a hyphen) refer to a code line, and the letter that is the first part of such a number specifies the source file the code line is in, as explained by the file key below. Simple numbers refer to pages. Numbers written in italics refer to places where the corresponding entry is described, the ones underlined to where it is defined, and the rest to where it is used.

Symbols

\( . . . . . . . . . . . . . . . b-772, b-773, b-811, b-812, c-66, c-74, c-163, c-321, c-564, d-458, d-522, d-524

\⟨amount⟩ . . . . . . . . . . . . . . . . . . 114 \⟨encoding⟩-⟨family⟩ . . . . . . . . . . . 149 \⟨letter⟩_macro . . . . . . . . . . . . . . . . 41 \) . . . . . . . . . . b-772, b-773, b-811,

b-812, c-66, c-76, c-163, c-321, c-564, d-458, d-509, d-522, d-524

\, . . . . . . . . . . . . . . . . a-38, a-357,

a-369, a-654, a-657–a-659, b-554 \- . . . . . . . . . . . . . . . . . . d-971, d-983 \/ … b-30, b-33, b-366, d-5, d-8, d-459 \@ . . . . . . . . . . . . . . . . . . . . a-47, a-52 \@@end . . . . . . . . . . . . . . . . . . . . a-156 \@@input . . . . . . . . . a-639, c-26, c-360 \[ . . . . . . . . . . . . . . . . . . . . . . . a-311 \␣ . . . . . . . . . . . . . . . a-47, a-50, d-254 \# . . . . . . a-4, a-313, b-39, b-222, b-228 \% . . . . . . . . . . . . . . . . . . . a-314, b-40 \& . . . . . . . . . . . . . . . . . . . . . . . . b-40 \\ . . . . . . . . . . . . . . . . . . . . . . . . b-91 \^. . . . . . . . . . . . . . . . . . . . . . a-5,

a-47, a-51, a-831, b-31, d-253, d-275 \_. . . . . . . . . . . . . . . . . . . . a-47, a-53 \{ . . . . . a-2, a-315, b-496, b-535, c-654 \} . . . . . a-3, a-316, b-501, b-540, c-656 \~ . . . . . . . a-47, a-54, a-343, a-354,

a-362, a-390, a-499, a-514, a-525 \] . . . . . . . . . . . . . . . . a-312, d-6, d-9

A

\a@command . . . . . . . . . . . . . . . . b-785 \a@count . . . . . . . . . . . . . \underline{a-237}, b-

285, b-289, b-313, b-319, b-320, b-397, b-411, b-415, b-423, b-444, b-458, b-459, b-486, b-489, b-490, b-504, b-525, b-528, b-529, b-543, b-557, b-558, b-592, b-596, b-617, b-621, b-656, b-693

\a@dimen \underline{a-237}, b-780, b-781, b-819, b-820 _a_switch . . . . . . . . . . . . . . . . . \underline{a-183} \a_count \underline{a-168}, a-432, a-434–a-438, a-

710–a-712, a-724, b-274, b-276, b-301, b-303, b-304, b-385, b-387, b-431, b-433, b-434, b-476, b-478, b-515, b-517, b-643, b-645, b-725, b-727, b-885, b-890, b-899, b-935, b-936, b-952, b-960, b-961, b-964, c-740, c-827, c-833, c-840, c-870, c-876, c-882, c-915, c-925, c-1318, c-1319, c-1364–c-1368, c-1370, c-1442–c-1444, c-1520, c-1671–c-1673, c-1675, c-2051, c-2053–c-2058, c-2060, c-2061, c-2072, c-2089, c-2099, d-11, d-16, d-23, d-67, d-69–d-71, d-139, d-143, d-145–d-147, d-171–d-173, d-176–d-179, d-182, d-184, d-289, d-290, d-292, d-293, d-295, d-296, d-298, d-299, d-301, d-302, d-304–d-307, d-309, d-310, d-323– d-327, d-353, d-369, d-388–d-391, d-417, d-419, d-666, d-674, d-676, d-679, d-826, d-827, d-831, d-879–d-882, d-889, d-891, d-894, d-908, d-937, d-949, d-950, d-952, f-276, f-287, f-290–f-292

\a_dimen . . . . . . . a-22, a-24, \underline{a-176}, a-191, b-758, b-759, b-804, b-805, c-1305, c-1306, c-1346, c-1352, c-1520, c-1522, c-1542, c-1564–c-1571, c-1644, c-1646, c-1659, c-1660, c-1663, c-1664, d-262, d-263, d-265, d-266, d-268, d-386–d-388, d-528, d-529, d-678

\_a_false . . . . . . . . . . . . . . \underline{a-183}, a-392, a-498, c-420, c-1856, d-198, d-823, f-72, f-174, f-370

\a_macro a-45, a-47, a-396, a-400, a-750, a-751, a-764, a-765, b-766, c-680, c-688, c-823, c-825, c-837, c-844, c-845, c-909, c-911, c-913, c-919, c-921, c-923, c-932, c-950, c-952, c-964, c-966, c-970, c-972, c-990, c-992, c-1000, c-1002, c-1153, c-1155, c-1156, c-1159, c-1441, c-1445, c-1447, c-1453, c-1673, c-1674, c-1723, c-1724, c-1857, c-1861, d-83, d-85, d-90, d-129, d-133, d-174, d-186, d-193, d-196, d-633, d-638, d-643, d-644, d-649, d-816, d-818, d-830, d-849, d-875, d-876, d-886, d-1062, d-1066, d-1073, d-1074, d-1080, d-1083, d-1088, d-1091, e-3, e-4, f-24, f-27, f-35, f-161–f-163, f-417, f-419, f-420, f-424

\a_toks . . . . . . . . . . . \underline{a-180}, b-889, b-892, b-895, c-1133, c-1135, c-1146, c-1148, c-1156, c-1215, c-1224, c-1233, c-1742, c-1743, c-1876, c-1897, c-2082, c-2090, c-2094, c-2100, c-2104, d-1074, d-1083, d-1091, d-1095, d-1098

\_a_true . . . . . . . . . . . . . \underline{a-183}, a-350, a-386, c-425, c-1861, d-165, d-820, f-75, f-172, f-173, f-364, f-367

\abbreviate_PS_font_name . . . . . \underline{f-267}

\active . . . . . . . a-81, d-5, d-6, d-8, d-9 \active@comma . . . . . . . . . a-662, a-667 \add . . . . . . . . . . . . \underline{b-270}, c-947, d-803 \add_to . . . . . . . . . . . . . . . . \underline{a-323},

c-473, c-474, c-1222, c-1231, c-1853, d-84, d-86, f-178, f-324

\adddriver . . . . . . . . . . . . . . . . \underline{f-167} \addvspace a-243, a-569, c-42, c-48, c-408 \adobe_encoding … e-98, e-115, e-

122, e-142, e-152, e-202, e-211, e-221, e-231, e-248, e-432, \underline{e-677}

\advance . . . . . a-113, a-118, a-259, a-265, a-270, a-280, a-435, a-442, a-714, b-7, b-20–b-22, b-82, b-276, b-289, b-303, b-319, b-329–b-331, b-336, b-346, b-507, b-546, b-569, b-571, b-579, b-581, b-604, b-606, b-629, b-631, b-696, b-707, b-714, b-721, b-891, b-899, b-961, c-53, c-83, c-92, c-115, c-154, c-167, c-925, c-926, c-928, c-944, c-989, c-999, c-1355, c-1370, c-1542, c-1675, d-23, d-71, d-147, d-148, d-176, d-181–d-183, d-265, d-267, d-269, d-485, d-881, d-914, d-952, d-1042, f-164, f-196, f-198, f-292

\afm-FontName . . . . . . . . . . . . . . \underline{d-316} \afm_char . . . . . . . . . . . . d-332, d-352 \afm_command . . . . . . . . . . d-276, d-277 \afm_convert . . . . . . . . . . . \underline{c-1289},

c-1564, c-1566, c-1568, c-1570 \afm_def . . . . . . . . . . . . . . . . . . . .

\underline{d-280}, d-286–d-288, d-291, d-294, d-297, d-300, d-303, d-308, d-311, d-316, d-320, d-332, d-334

\afm_length … \underline{d-261}, d-286, d-289, d-292, d-295, d-298, d-301, d-304, d-306, d-309, d-323, d-406, d-407, d-411–d-414, d-417, d-418

\afm_let . . . . . . . . \underline{d-282}, d-331, d-333 \afm_line . . d-255, d-275, d-276, d-279 \afm_unit_dimen . . . . . . . . . . . . \underline{d-261} \afmtomtx … 170, \underline{d-227}, d-749, d-775 \aftergroup . . c-680, c-682, c-692, f-

274, f-275, f-277, f-280, f-288, f-293 \Aheading … \underline{a-242}, c-62, c-140, c-

159, c-399, c-403, c-406, c-780, c-800, c-852, c-857, c-893, c-903

\aliased . . . . . . . . d-868, \underline{d-871}, d-920 \alloc@ . . . . . . . . . . a-107–a-111, a-113 \allocate_stream . . . . . . \underline{a-431}, a-459

                                \allocationnumber . . . . . . . . . . . .

. a-100, a-115–a-117, a-123–a-125

                                \announce@package . . . . . . . . . . \underline{c-384}

\append_download . . \underline{f-329}, f-336, f-374

                                \assign_rboundary . . . . c-1206, \underline{c-1229}

\assign_slot . . . . . . . . . c-1200, \underline{c-1215} \AssumeAMSBSYY . . . . . . . . . . . . . \underline{f-251} \AssumeBaKoMa . . . . . . . . . . . . . . \underline{f-251} \AssumeLWFN . . . . . . . . . . . . . . . . \underline{f-244} \AssumeMetafont . . . . . . . . . . . . \underline{f-136} \AtEndOfPackage . . . . . . . . . . . . a-228

                                \autoinstallfamily . . . . c-1750, \underline{c-1765}

\AXISHEIGHT . . . . . . . . . . . . . . . . \underline{d-598}

B \b@count . . . . . . . . . . . . . \underline{a-237}, b-

286, b-290, b-291, b-314, b-322, b-323, b-398, b-412, b-413, b-445, b-448, b-449, b-487, b-526, b-561, b-657, b-673, b-687, b-688

\b_count \underline{a-168}, a-433, a-437, a-441, a-444–a-446, a-460, a-467–a-469, a-710, a-714, a-716, b-888, b-890, b-891, b-893, b-940, b-944, b-952, c-513, c-519, c-525, c-534, c-541, c-741, c-828, c-834, c-841, c-871, c-877, c-883, c-916, c-926, c-927, c-943, c-944, c-950, c-1523, c-1524, c-2052, c-2059, c-2071–c-2073, c-2076, c-2081, d-138, d-141, d-142, d-148, d-179–d-181, d-418, d-419, d-660, d-667, d-680, d-828, d-829, d-831, d-909, d-937, d-948, d-954 \b_dimen . . a-23, a-24, \underline{a-176}, a-192,

c-1645, c-1646, d-532, d-533, d-537 \b_macro . . . . . . . . . . . . . . . . . . c-

1444, c-1452, c-1860, c-1861, d-84, d-86, d-89, d-94, d-95, d-101, d-109, d-173, d-174, d-184, d-186, d-195, d-196, d-885, d-886

\b_toks . . . . . . . . . . . . . . . . . . . \underline{a-180}

\bad_makerightboundary c-1203, \underline{c-1229}

\bbox_llx . . d-338, d-346, d-355, d-411 \bbox_lly . . . . . . . . . . . . . . . . . . .

d-339, d-347, d-353, d-355, d-412

\bbox_urx . . d-340, d-348, d-355, d-413 \bbox_ury . . . . . . . . . . . . . . . . . . .

d-341, d-349, d-355, d-368, d-414

\begin . . . . . a-565, a-607, a-804, a-

808, a-813, c-43, c-260, c-376, d-48 \begincomment . . . . . . . . . . . . . \underline{b-1001} \begingroup . . . . . . . . . . . . . . . . a-

257, a-653, a-734, a-740, a-747, a-761, b-4, b-69, b-89, b-112, b-197, b-260, b-282, b-310, b-352, b-393, b-440, b-484, b-523, b-589, b-614, b-652, b-923, c-17, c-352, c-580, c-713, c-1216, c-1263, c-1376, d-66, d-201, d-957, d-970, d-982, f-51, f-219, f-273

\@beginparpenalty a-616, a-621, a-622

\bgroup . a-142, a-310, b-273, b-300, b-384, b-430, b-475, b-514, b-642, c-570, c-599, c-679, c-1013, c-1202, c-1244, c-1378, c-1380, c-1389, c-1472, c-1691, c-1733, c-2030, d-191, d-476, d-509, d-919

\Bheading a-40, \underline{a-242}, a-412, a-803, a-807, a-812, b-772, b-776, b-781, b-811, b-815, b-820, b-880, b-881, c-175, c-179, c-183, c-235, c-237, c-279–c-283, c-320, c-479, c-507, c-550, c-553, c-556, c-638, c-666, c-669, c-672, c-853, c-858, c-938, c-958, c-978, c-980, c-1008, c-1009, c-1029, c-1030, c-1040, c-1043, c-1046, c-1049, c-1104

\Big . . . . . . . . . . . . . . . . . b-453, b-684 \big . . . . . . . . . . . . . . . . . b-453, b-684 \Bigg . . . . . . . . . . . . . . . . b-454, b-685 \bigg . . . . . . . . . . . . . . . . b-454, b-685 \Biggl b-340, b-495, b-500, b-534, b-539 \biggl b-340, b-495, b-500, b-534, b-539 \Biggr . . . . . . . . . . . . . . . . . . . . b-343 \biggr . . . . . . . . . . . . . . . . . . . . b-343 \Bigl . b-339, b-495, b-500, b-534, b-539 \bigl . b-339, b-494, b-499, b-533, b-538 \BIGOPSPACING . . . . . . . . . . . . . . \underline{d-608} \Bigr . . . . . . . . . . . . . . . . . . . . . b-342 \bigr . . . . . . . . . . . . . . . . . . . . . b-342 \bigskipamount . . . . . . . . . . c-42, c-48 \binoppenalty …. a-667, b-329, b-335 \body . . . . . . . . . . . . . . . . a-145, a-146 \body-⟨name⟩ . . . . . . . . . . . . . . . . . 97

                                \boundary_liglabel . . . . . . . . . . . .

. . . . . . . . c-1383, c-1389, \underline{c-1456} \BOUNDARYCHAR . . . . . . . . . . . . . . \underline{d-539} \box . . . . . . . . . . . . . . . . . . . . . . a-122

                                \FD@bracket@expression . . . . . . . .

. . . . . . . . . . . . b-316, \underline{b-337}, b-375, b-395, b-401, b-442, b-447, b-591, b-616, b-654, b-675

                                \FD@bracket@level . . . . . . . . . . . .

b-224, \underline{b-245}, b-258, b-262, b-286, b-290, b-291, b-314, b-322, b-323, b-339, b-342, b-346, b-362, b-398, b-412, b-413, b-445, b-448, b-449, b-453, b-489, b-490, b-494, b-499, b-507, b-528, b-529, b-533, b-538, b-546, b-561, b-657, b-660, b-673, b-684, b-687, b-688, c-591, c-719, c-1082

\branches@else . . . . . . . . a-559, \underline{a-563} \branches@fi . . . . . . . . . . a-560, \underline{a-563} \branches@if . . . . . . . . . . a-557, \underline{a-563} \branches@par . . . . . . . . . . . . . . \underline{a-563} \branches@type . . . . . . . . . . . . . \underline{a-563} \bye . . . . . . . . . . . . . . . . . a-150, a-153

C \c_count . . . . . . . . . . . . . \underline{a-168}, a-

712–a-714, b-939, b-942, b-944, b-952, c-742, c-829, c-835, c-842, c-872, c-878, c-884, c-917, c-928, c-929, c-943, c-947, c-950, c-1526, c-1527, c-2066, c-2067, c-2074, c-2076, c-2077, c-2089, d-661, d-668, d-681, d-910, d-937

\c_dimen . . . . . . . . . . . . . . . . . . \underline{a-176} \c_macro . . . . . . . . . . . . . d-185, d-186 \c_toks . . . . . . . . . . . . . . . . . . . \underline{a-180}

                                \calculate_it_slant . . . . d-287, \underline{d-383}

\CalculateTan . . . . . . . . . . . . . . d-385 \caps_shape . . e-119, e-600, e-620, \underline{e-680} \@car . . . . . . . . . . . b-252, b-254, b-465 Carlisle, David . . . . . . . . . . . . . . . . . 5 \catcode . . . . . . . . . . . . . . . a-2–a-

5, a-45, a-50–a-54, a-311–a-316, a-343, a-354, a-362, a-390, a-499, a-514, a-525, a-654, a-702, a-703, b-70, b-74, b-113, b-114, c-1217, d-5, d-6, d-8, d-9, d-253, d-254, d-275, d-458, d-476, d-509, d-522, d-524, d-971, d-983

\cc_char . . . . . . . . . . . . . d-334, d-377 \@cclv . . . . . . . . . . . . a-87, d-70, d-146 \@cclvi . . . . . . . . . . . . . . . a-88, a-109 \cdot . b-407, b-599, b-624, b-666, b-681 \ch@ck . a-114, a-119–a-122, a-126, \underline{a-431} \char . . . . . . . . . . . . . . . . . b-23, c-309 \char_name . . . . . . . . . . . . . d-342,

d-350, d-363, d-375, d-378, d-409 \char_slot . d-335, d-344, d-358, d-366 \char_x_width …. d-286, d-336, d-345 \CHARACTER . . . . . . . . . . . . . . . . \underline{d-660} \chardef . . . . . . . . . . . . . . . . a-81,

a-83–a-87, a-110, a-111, a-124, a-428, a-469, a-483, b-223, b-257, b-265, b-293, b-325, b-345, b-361, b-377, b-423, b-461, b-506, b-545, b-596, b-621, b-670, b-690, c-590, c-718, c-1081, f-12

\CHARDP . . . . . . . . . . . . . . . . . . . \underline{d-660} \CHARHT . . . . . . . . . . . . . . . . . . . \underline{d-660} \CHARIC . . . . . . . . . . . . . . . . . . . \underline{d-660} \FD@charname . . . . . . . . . . \underline{c-240}, c-263 \charseq . . . . . . . . . . . . . \underline{c-256}, d-167 \CHARWD . . . . . . . . . . . . . . . . . . . \underline{d-660} \CHECKSUM . . . . . . . . . . . . . . . . . \underline{d-497} \close_out . . \underline{a-416}, c-1187, c-1909,

c-2160, d-63, d-154, d-224, d-258, d-474, d-713, d-855, d-1023

\close_pout . . . . . . . . \underline{a-458}, f-10, f-188 \closed_stream . . . . . . . . . . \underline{a-427},

a-473, a-483, a-742, a-748, a-762, a-767, f-12, f-41, f-94, f-173

\closein . . . . . . . . . . . . . a-542, a-545 \closeout . . . . . . . . . . . . a-421, a-480 \clueless_str . . . . . \underline{f-246}, f-250, f-

269, f-321, f-362, f-375, f-410, f-414 \cmap_charseq …. d-166, d-167, \underline{d-189} \cmap_codepoint . . d-166, \underline{d-170}, d-192 \FD@codepoint . . . . . \underline{a-199}, \underline{c-240}, c-262 \CODINGSCHEME . . . . . . . . . d-428, \underline{d-509}

\CODINGSCHEME_cont . . . . . . . . . . \underline{d-509}
\command_survivance . . . . . . . . . . .

\underline{d-1040}, d-1042, d-1044, d-1047, d-1059, d-1065, d-1070, d-1094

\FD@commapenalty . . . . . . . . . . . . .

. \underline{b-328}, b-554, c-586, c-654, c-655 \COMMENT . . . . . . . . . . . . . . . . . . \underline{d-502} \comment a-37, \underline{b-997}, c-80, c-243, c-259

\concat_reencodefont . . . . . f-74, \underline{f-166}
\concat_transformfont . . . . f-73, \underline{f-160}

                                       \ConditionallyScaled . . . . . c-551,

c-554, c-557, \underline{c-558}, c-859, c-938 \count . . a-93–a-98, a-107, a-113, a-

115, a-119, a-126, a-434, a-438, a-442–a-444, a-448, a-453, a-455

\count@ . . a-104, a-129, a-134, b-5– b-7, b-9, b-11, b-12, b-15–b-20, b-68, b-74, b-76, b-79, b-81–b-83

\count_hashes . . . . . . . . . . . . . . \underline{b-883} \countdef … a-99–a-101, a-104, a-107 \curr_bearings . . \underline{c-1300}, c-1538, c-

1540, c-1542, c-1547, c-1550, c-1552

                                       \curr_file_list . . . . . . c-1730, c-

1732, c-1736, c-1737, c-1742, c-1743 \curr_series . . . . . . . . . . . . . . . . .

159, c-1987, c-1990, c-2086, c-2097 \curr_shape . . . . . . . . . . . . . . . . . .

159, c-2001, c-2004, c-2087, c-2098 \@currentlabel . . . . . . . . . c-70, c-141 \@currenvir . . . . . . . . . . . . . . . . a-591

D \d-⟨dim⟩ . . . . . . . . . . . . . . . . . . . . 90

\d_count . . . . . . . . . . . . . . . \underline{a-168},

c-743, c-830, c-836, c-843, c-873, c-879, c-885, c-918, c-930, c-1529, c-1530, d-177, d-181, d-183, d-185, d-662, d-669, d-682, d-785–d-788, d-796–d-798, d-911, d-912, d-914, d-916, d-937

\d_dimen . . . . . . . . . . . . . . . . . . \underline{a-176} \day . . . . . . . . . . . . . . . . . c-1892, d-99 \debug_value . . . . . . . . . . . \underline{f-316}, f-325

                                       \debug_values_hook . . . . . . f-314, \underline{f-323}

\debugvalue . . . . . . . . . . . . . . . . \underline{f-323}

                                       \declareencoding . . . . . . . . . . . . .

… \underline{c-2107}, c-2108–c-2122, d-515

                                       \DeclareFontFamily . . . . . . . . . c-1897

\DeclareFontShape c-1913, c-1935, c-1951 \DeclareOption … a-198, a-199, a-210

                                       \declarepsencoding . . . . . . . . . . . .

. d-127, d-130, \underline{f-238}, f-241, f-242

                                       \DeclareRobustCommand . . . . . . . b-

2, b-194, b-211, b-221, b-281, b-309, b-351, b-373, b-392, b-439, b-483, b-522, b-588, b-613, b-651, c-579, c-708–c-711, c-1079

\declaresize . 21, \underline{c-2123}, c-2124–c-2136

                                       \DeclareTextCommandDefault . . . . b-58
                                       \DEFAULTRULETHICKNESS . . . . . . . \underline{d-608}

\DELIM . . . . . . . . . . . . . . . . . . . . \underline{d-601} \DENOM . . . . . . . . . . . . . . . . . . . . \underline{d-566} \depth . . . . . . . . . . . . . . . \underline{c-701}, c-1568 \DESIGNSIZE . . . . . . . . . . . . . . . . \underline{d-527} \DESIGNUNITS . . . . . . . . . . . . . . . \underline{d-531} \digit . . . . . . . . . e-29, e-35, e-42, e-46 \dim . . . . . . . . . . . . . . 90, \underline{b-824}, c-1305 \dimen . . . . . . . . . . . a-94, a-108, a-120 \dimen@ . . . . . . . . . . . . . . . . . . . a-105 \dimendef . . . . . . . . . . . . a-105, a-108 direct switch . . . . . . . . . . . . . . . \underline{c-325} \directfalse . . . . . . . . . . \underline{c-325}, d-814 \directtrue . . . . . . . . . . . c-325, \underline{c-325} \div . . . . . . . . . . . . . . . . . a-251, \underline{b-427} \divide . . . . . a-711, b-17, b-433, b-

458, b-570, b-573, b-580, b-583, b-605, b-608, b-630, b-633, b-694, b-698, b-705, b-709, b-712, b-716, b-720, b-722, c-1293, c-1295, c-2073, d-178, d-264, d-882

\do . . a-259, a-262, a-264, a-271, a-337, a-357, a-369, b-989, c-437, c-444, c-614, c-615, c-618, c-619, c-643, c-649, c-678, c-681, c-684, c-685, c-687, c-692, c-1215, c-1245, c-1246, c-1264, c-1265, c-1269, c-1403, c-1407, c-1411, c-1425, c-1435, c-1853, c-1858, c-2065, c-2078, d-642, d-643, d-648, d-650, d-884, d-898, d-899

\do_arc 158, c-1985, c-1987, c-1999, c-

2001, c-2013, c-2015, c-2038, c-2064 \do_boundary . . . . . . . . . . . . \underline{c-128},

c-1202, c-1211, c-1389, d-426, d-521 \do_character . . . . . . . . c-1473, \underline{c-1507}

\do_character_map . . . . . . . . . . . .

. . c-1492, c-1496, c-1532, \underline{c-1544}

\do_character_no_letterspacing \underline{c-1556}
\do_character_sidebearings . . . . .

. . . . . . . . . . . . . . c-1521, \underline{c-1536} \do_if_defined . . . . . . . . . . . . . \underline{d-625} \do_list … d-332, d-334, d-398, d-402 \do_mapfont . . . . . . . . . . c-1330, \underline{c-1336} \do_pl_glyph d-460, d-462, d-665, d-671 \do_shape . . . . . . . . . . . . . . . . . c-

1747, c-1754, c-1768, c-1901, c-1903 \do_size . . . . . . c-1757, c-1762, c-1769 \do_slot . . . . . . c-52, \underline{c-87}, c-1200,

c-1330, c-1378, c-1380, c-1473, d-73, d-165, d-425, d-520, d-813

\do_subs . . . . . . . . . . . . c-2082, c-2085 \documentclass . . . . . . . . . . . . . . d-45 \donedrivers . . . . . . . . . . . . . . . \underline{f-186} \download . . . . . . . . . . . . . . . 230,

d-128, d-131, \underline{f-239}, f-240, f-241, f-331, f-336, f-379, f-394, f-420

\downloads_list … \underline{f-329}, f-334, f-382

E

\e_count \underline{a-168}, c-832–c-837, c-875–c-879, c-907, c-908, c-915–c-919, c-923, d-663, d-670, d-683, d-922, d-924, d-928, d-931, d-936

\edef . . . . . . . . . . . . a-46, a-131, a-133, a-201, a-213, a-396, a-423, a-424, a-487, a-488, a-715, a-750, a-764, a-818, b-79, b-752, b-759, b-793, b-798, b-802, b-805, b-941, c-3, c-4, c-18, c-19, c-52, c-129, c-347, c-353, c-354, c-631, c-687, c-786, c-804, c-825, c-837, c-839, c-881, c-909, c-913, c-919, c-923, c-950, c-964, c-970, c-990, c-1000, c-1155, c-1441, c-1444, c-1673, c-1800, c-1817, c-1857, c-1877, c-1878, c-1929, c-1932, c-1946, c-1948, c-1981, c-1982, c-1995, c-1996, c-2009, c-2010, c-2031, c-2078, c-2080, c-2086, c-2087, c-2097, c-2098, c-2107, c-2123, c-2154, c-2155, d-75, d-129, d-174, d-186, d-231, d-232, d-384, d-434, d-633, d-638, d-648, d-769, d-813, d-816, d-830, d-835, d-973, d-980, d-990, d-1073, d-1080, d-1088, e-3, f-123, f-161, f-197, f-246, f-264, f-343, f-350, f-356, f-400, f-405

\egroup . . . . . . a-143, a-321, b-277, b-305, b-388, b-435, b-479, b-518, b-647, c-572, c-602, c-683, c-1022, c-1205, c-1249, c-1438, c-1505, c-1733, c-1772, c-2041, d-197, d-479, d-511, d-922, d-924

\@eha . . . . . . . b-142, b-929, c-30, c-364 \Else . . . . . . . . . . . . . . . . \underline{a-550}, a-559 \em . . . . . . . . . . . . . . . . . . . . . . . b-30 \emph . . . . . . . . . . . . . . . . . . . . . b-228 \@empty . b-140, b-143, b-148, c-304,

c-357, c-377, c-393, c-438, c-445 \empty_command . . . . . \underline{a-300}, a-725,

c-88, c-89, c-271, c-276, c-288, c-291, c-632, c-1210, c-1699, c-1749, c-1779, c-1813, c-1814, c-1851, c-1874, c-1915, c-1940, c-1956, d-89, d-193, d-342, d-350, d-643, d-644, d-818, e-5, f-127, f-138, f-156, f-159, f-184, f-193, f-201, f-223, f-301, f-327, f-335, f-337, f-382, f-383, f-390, f-398

\emptyset . . . . . . . . . . . . . . . . . c-656 \encoding . . . . . . . . . . . . . . . \underline{c-1}, d-54

\encoding_shape . . . . . . . . . . . . . .

. . \underline{e-70}, e-238, e-240, e-607, e-628

\encoding_switches . . . . . . \underline{e-70}, e-670

\enctoetx . . . . . . . . . . . 164, \underline{d-4}, d-34 \end . . . . . . . . . . . . . . a-150, a-582,

a-591, a-595, a-804, a-808, a-813, c-47, c-267, c-381, d-60, d-62

\end_assign_slot . . . . . c-1201, \underline{c-1215}

\end_do_character . . . . c-1474, \underline{c-1580}

\end_do_slot . . . . . . . . . . . . . c-53,

\underline{c-87}, c-1201, c-1210, c-1388, c-1474 \end_of_line . . . . . d-276, d-278, d-281

\end_parse_family . . . . . . . . e-5, e-18
\end_strip_spaces . . . . . . . . . . d-397

\end_vpl_varchar . . . . . c-1477, \underline{c-1595} \endcomment . . . . . . . . . . . . . . . \underline{b-1001} \endencoding . . . . . . . . . . . . . . . . . \underline{c-1} \endfor . . . . . . . . . \underline{b-933}, b-975, b-988 \endgroup . . . . . . . . . . . . a-291, a-

666, a-737, a-743, a-756, a-771, b-27, b-72, b-99, b-119, b-201, b-204, b-264, b-294, b-326, b-364, b-424, b-462, b-508, b-547, b-611, b-636, b-700, b-926, c-33, c-368, c-593, c-721, c-1235, c-1268, c-1399, d-80, d-225, d-963, d-977, d-987, f-66, f-222, f-281

\endinput . . . . . . . . . . . . . . . . . c-

13, c-38, c-348, c-373, c-1908, d-279

\endinstallfonts . . . . . . . . . . . . .

. . . . . . 148, \underline{c-1766}, c-2144, e-16 \endlist . . . . . . . . . . . . . . . . . . a-632 \endmetrics . . . . . . . . . . . . . . . . \underline{c-339} \endmetrics@hook . . \underline{c-339}, c-387, c-392

\endmetrics_text . . . . . . . . . . . . .

\underline{c-339}, d-257, d-473, d-854, d-1022 \@endparpenalty . . . . . . . a-617, a-622

\endrecordtransforms . . . . . . . . . . \underline{f-7}
\endreglyphfonts . . . . . . . . . . . \underline{d-956}

\endresetglyph . . . . . . . . . . . . . \underline{c-802} \endsetglyph . . . . . . . . . . . . . . . . .

. . c-775, c-783, \underline{c-802}, d-379, d-706, d-867, d-946, d-1035, d-1096

\endsetleftboundary . . . . . . . . . . .

… \underline{c-128}, c-1205, c-1212, c-1390 \endsetslot . . \underline{c-51}, c-331, c-1579, d-20 \endvarchar . . . . . . . 104, \underline{c-270}, c-1477 \ensuremath . . . . . . . . . . . . . . . . a-358

\entry_makers_list . . . . . . . . . . . .

… f-85, f-178, \underline{f-184}, f-191, f-193 environments:

IfBranch . . . . . . . . . . . . . . . \underline{a-611} IfBranchDummy . . . . . . . . . . . \underline{a-633}

\errhelp … a-751, a-765, c-1237, d-513 \errmessage … a-127, a-454, a-474,

a-753, a-770, c-1239, d-494, d-518 \error_help_a . . . . . . . . . . . . . . . .

…. \underline{a-819}, c-1064, c-1827, d-743, d-998, f-82, f-131, f-142, f-170

\error_help_c . . . . . . . . . . . . . . \underline{a-819} \error_help_d . . . . . . . . . . . . . . \underline{a-819} \error_help_e . . . . . . . . . . . . . . \underline{a-819}

                                       \errorcontextlines . . . . . . . . . . \underline{a-832}

\errorstopmode . . . . . . . . . . . . . f-194 \escapechar . . . . . . . a-129, a-134, b-91 \eTeX . . . . . . . . . . . . . . . . \underline{a-342}, a-498 \eTeXlogo . . . . . . . . . . . . . . . . . \underline{a-356} \eTeXrevision . . . . . . . . . . . . . . a-349 \eTeXversion . . . . . . . . . . a-342, a-349 \etx_to_font … c-1135, c-1148, \underline{c-1162} \etxtocmap . . . . . . . . . . . . 168, \underline{d-201} \etxtoenc 165, \underline{d-66}, d-114, f-339, f-392 \etxtopl . . . . . . . . 132, \underline{c-1125}, c-1713 \etxtovpl . . . . . . . 132, \underline{c-1125}, c-1704 \FD@eval@expr . . . . . . . . . . . . . . b-

242, \underline{b-250}, b-283, b-287, b-311, b-315, b-374, b-394, b-400, b-441, b-446, b-468, b-590, b-615, b-653, b-659, c-101, c-113, c-560

                                       \FD@eval@spec@expr . . . . . . . . . . . .

\underline{b-464}, b-488, b-527, b-550, b-562

\eval_expr . . . . . . . . . . . . . \underline{b-233}, b-275, b-302, b-386, b-432, b-477, b-516, b-644, b-726, b-789, b-937, c-92, c-469, c-497, c-821, c-984, c-997, c-1262, c-1291, c-2022, d-354, d-877, d-911, d-917, d-941, d-949, d-979, d-989

\eval_expr_to . \underline{b-233}, b-725, b-935, b-940, c-91, c-513, c-519, c-525, c-827–c-830, c-870–c-873, c-907, c-943, d-785, d-796, d-889, d-891, d-908–d-911, d-948, d-949

FD@evaluate@ switch . . . . . . . . . . \underline{b-245}

                                       \FD@evaluate@false . . b-225, \underline{b-245},

b-248, b-249, b-266, b-363, b-736, c-563, c-592, c-720, c-1083

                                       \FD@evaluate@true . . . . . . . . . . . .

. \underline{b-245}, b-247, c-100, c-112, c-559 \everyjob . . . . . . . . . . . . . . . . . a-160 \everypar . . . . . . . . c-389, c-397, c-405

                                       \ExpandAndMakePrintable . . . . . \underline{b-160}
                                       \expert_encoding . . . e-105, e-189,

e-194, e-336, e-340, e-347, e-349, e-356, e-359, e-363, e-368, e-515, e-519, e-526, e-528, e-535, e-538, e-542, e-547, e-569, e-573, \underline{e-677}

\_expert_false . . . . . . . . . . e-23, e-44 \expert_font . e-564, e-571, e-604, e-624 \_expert_true . . . . . . . e-26, e-31, e-38 \FD@expression . . . . . . . . . . . . . . .

. . . . . b-222, b-243, \underline{b-245}, b-256, b-263, b-284, b-288, b-312, b-317, b-338, b-341, b-354, b-376, b-396, b-402, b-409, b-443, b-451, b-455, b-492, b-498, b-531, b-537, b-553, b-597, b-600, b-622, b-625, b-655, b-662, b-663, b-676, b-683, c-106, c-118, c-121, c-564, c-583, c-715, c-1080

_extensions_warning_switch . . . \underline{a-339}
\_extensions_warning_false . . . . .

. . . . . . . . . . \underline{a-339}, a-341, a-397

\_extensions_warning_true \underline{a-339}, a-395
\extract_font_generation . . . . . . .

. \underline{f-14}, f-26, f-53, f-57, f-108, f-112 \EXTRASPACE . . . . . . . . . . . . . . . . \underline{d-552}

F

\f_count . . . . . . . . \underline{a-168}, d-465, d-466, d-468, d-544, d-545, d-547, d-632, d-634, d-653, d-654, d-656

\FACE . . . . . . . . . . . . . . . . . . . . . \underline{d-497}

\_fake_narrow_false . . . . . . . . . e-421
\_fake_narrow_true . . . . . . . . . . e-423
\fake_narrow_width . e-424, e-474, e-544

\fake_shape_. . . . . . . . . . . . . . . . .

. . \underline{e-95}, e-233, e-242, e-250, e-419 \fake_shape_c . . . . . . . . . . . . . . \underline{e-228}

\fake_shape_expert_encoding . . . .

. . . . . . . . . . . . . . . e-107, \underline{e-186} \fake_shape_i . . . . . . . . . . . . . . \underline{e-419} \fake_shape_o . . . . . . . . . . . . . . \underline{e-245}

\fake_shape_o_expert_encoding . .

. . . . . . . . . . . . . . . e-254, \underline{e-333}

\fake_shape_o_oldstyle_encoding .

. . . . . . . . . . . . . . . e-258, \underline{e-375}

\fake_shape_o_raw_encoding . . . . .

. . . . . . . . . . . . . . . e-252, \underline{e-263}

\fake_shape_oldstyle_encoding . .

. . . . . . . . . . . e-117, e-124, \underline{e-198}

\fake_shape_raw_encoding e-100, \underline{e-130}

\fake_width_. . . . . . . . . . . . . . . \underline{e-426} \fake_width_c . . . . . . . . . . . . . . e-427 \fake_width_n . . . . . . . . . . . . . . \underline{e-428}

\fake_width_n_expert_encoding . .

. . . . . . . . . . . . . . . e-437, \underline{e-512}

\fake_width_n_raw_encoding . . . . .

. . . . . . . . . . . . . . . e-435, \underline{e-442} \fakenarrow . . . . . . . . . . . . . . . . \underline{e-422} \FAMILY . . . . . . . . . . . . . . . . . . . \underline{d-497} \family_toks . . . . . . . . . c-1689, c-

1692, c-1697, c-1698, c-1770, c-1771 \fd_family . . . . . . . . . . c-1698, \underline{c-1875} \fd_shape . . . . . . . . . . . c-1768, \underline{c-1911} \fd_size . . . . . . . . . . . . c-1769, \underline{c-1918} \fdimen-⟨n⟩ . . . . . . . . . . . . . . . . . 179 \Fi . . . . . . . . . . . . . . . . . \underline{a-550}, a-560 \fifth_of_six . . . . . . . . . c-725, \underline{c-728}

                                       \file_list_metrics . . . . c-1729, \underline{c-1740}

\file_name . . . . . . . . . . c-1153, c-

1159, c-1780, c-1782, c-1788, c-1817 \@filef@und . . . . . . . . . . . . c-26, c-360 \finish@package . . . . . . . . . . . . \underline{c-384} finstmsc.rc file . . . . . . . . . . . . . . . 231 \first_char … \underline{a-322}, a-384, a-385,

d-312, d-321, d-322, d-484, d-486 \first_of_six . . . . . . . . . c-702, \underline{c-728} \first_of_three . . . . . . . . \underline{a-300}, f-17 \first_of_two . . . . . \underline{a-300}, d-920, f-344

                                       \first_pl_raw_glyph . . . . d-708, \underline{d-715}

\@firstofone . . . . . . . . a-413, b-71,

b-115, b-494, b-499, b-533, b-538 \five_hundred …. \underline{a-185}, b-705, b-712 \font . . . . . . . . b-59, b-62, c-244, c-307 \font_count . . . . . c-1303, c-1348–c-

1350, c-1355, \underline{c-1359}, c-1672, c-1677 \font_encoding \underline{e-554}, f-389, f-394, f-424 \font_family . . . . . . . . . \underline{e-18}, e-83,

e-89, e-97, e-104, e-114, e-121, e-132, e-139, e-141, e-146, e-151, e-160, e-162, e-172, e-174, e-188, e-193, e-201, e-208, e-210, e-215, e-220, e-230, e-247, e-265, e-269, e-276, e-278, e-285, e-288, e-292, e-297, e-306, e-308, e-318, e-320, e-335, e-339, e-346, e-348, e-355, e-358, e-362, e-367, e-378, e-382, e-389, e-391, e-398, e-401, e-405, e-410, e-431, e-444, e-448, e-455, e-457, e-464, e-467, e-471, e-476, e-485, e-487, e-497, e-499, e-514, e-518, e-525, e-527, e-534, e-537, e-541, e-546, e-568, e-572, e-580, e-585, e-595, e-597, e-614, e-617

\font_shape . . . . . . . . . . . . . . . . . . \underline{e-70}, e-160, e-269, e-276, e-285, e-292, e-306, e-308, e-318, e-320, e-339, e-346, e-355, e-362, e-382, e-389, e-398, e-405, e-444, e-448, e-455, e-457, e-464, e-467, e-471, e-476, e-485, e-487, e-497, e-499, e-514, e-518, e-525, e-527, e-534, e-537, e-541, e-546, e-595, e-614

\font_transforms . . . . . . . . . . . f-

70, f-76, f-123, f-127, f-138, \underline{f-156} \font_variant . . . . . \underline{e-18}, e-595, e-614 \font_weight . . . . . . . . . \underline{e-60}, e-83,

e-89, e-97, e-104, e-114, e-121, e-132, e-139, e-141, e-146, e-151, e-160, e-162, e-172, e-174, e-188, e-193, e-201, e-208, e-210, e-215, e-220, e-230, e-247, e-265, e-269, e-276, e-278, e-285, e-288, e-292, e-297, e-306, e-308, e-318, e-320, e-335, e-339, e-346, e-348, e-355, e-358, e-362, e-367, e-378, e-382, e-389, e-391, e-398, e-401, e-405, e-410, e-431, e-444, e-448, e-455, e-457, e-464, e-467, e-471, e-476, e-485, e-487, e-497, e-499, e-514, e-518, e-525, e-527, e-534, e-537, e-541, e-546, e-568, e-572, e-580, e-585, e-595, e-597, e-614, e-617

\font_width . . . . . . . . . . . . . . . . . .

. . \underline{e-65}, e-84, e-86, e-90, e-98, e-105, e-115, e-122, e-133, e-140, e-142, e-147, e-152, e-161, e-163, e-173, e-175, e-189, e-194, e-202, e-209, e-211, e-216, e-221, e-231, e-248, e-266, e-270, e-277, e-279, e-286, e-289, e-293, e-298, e-307, e-309, e-319, e-321, e-336, e-340, e-347, e-349, e-356, e-359, e-363, e-368, e-379, e-383, e-390, e-392, e-399, e-402, e-406, e-411, e-432, e-449, e-456, e-465, e-472, e-486, e-488, e-498, e-500, e-519, e-526, e-535, e-542, e-569, e-573, e-581, e-586, e-596, e-598, e-615, e-618

\FONTDIMEN . . . . . . . . . . . . . . . . \underline{d-551} \fontdimen . . . . . . . . b-59, b-62, c-244 fontinst.rc file . . . . . . . . . . . . 38, 134 \fontinstcc . . . . . . . . . . . . . . . . . \underline{a-44} \fontinsterror . . . . . . . . . . \underline{a-774},

c-1061, c-1787, c-1824, d-534, d-740, d-997, f-78, f-128, f-139, f-169

\fontinstinfo . . . . . . . . . . \underline{a-774}, f-28

\fontinstversion  \underline{a-7}, a-17, a-23, a-

28, c-1167, c-1883, c-1893, d-56, d-251, d-450, d-691, d-847, d-1014

\fontinstwarning . . . . . . . . . . . . .

. . . . . \underline{a-774}, c-1510, c-1680, f-31

\fontinstwarningnoline . . . . . . a-

398, \underline{a-774}, f-149, f-226, f-231, f-235 \footnote . . . . . . . . . . . . . . . . . c-183 \for . . . . . . . . . . . . . . . . . . . . . . \underline{b-933} \@for . . . . . . . b-989, c-437, c-444, c-643 \for-⟨name⟩ . . . . . . . . . . . . . . . . . 97 \for_i . . . . . . . . . . . . . . . b-946, b-950 \for_ii . . . . . . . . . b-957, b-959, b-967 \foreach . . . . . . . . . . . . . . . . . . \underline{b-973} \foreach_i . . . . . . . . . . . . . . . . \underline{b-973} \format_hex . . . . . . . . . . . . . . . . . .

\underline{a-707}, d-173, d-184, d-185, d-195

\format_hex_i . . . . . . . . . \underline{a-707}, a-726 \four_spaces . . . . . . . . . . a-776, a-

785, a-795, \underline{a-818}, d-96, d-100, d-103, d-105–d-107, d-158, d-160

\fourth_of_six . . . . . . . . c-705, \underline{c-728} \frac . . . . . . . . . . . b-598, b-623, b-663 \from . . . . . . . . . . . . . . . . . . . . . d-454 \from_mtx . . . . . . . . . . . . . f-118, \underline{f-122} \from_unknown . . . . . . . . . . . . . . . .

…. f-58, f-60, f-113, f-115, \underline{f-148} \fromafm . . . . . . . . . . . . . . 185, d-

318, \underline{d-746}, e-150, e-192, e-219, \underline{f-99} \fromany . . . . . . . c-1780, \underline{d-768}, d-993 \frommtx . . . . . . . . . . . . . . . . 185,

c-1725, \underline{d-753}, d-849, d-1016, e-296, e-366, e-409, e-475, e-545, \underline{f-107}

\frompl . 185, d-454, \underline{d-756}, \underline{f-104}, f-137 \fromplgivenetx . . . . . . . . . . . . \underline{d-756} \fromvpl . . . . . . . . . . . . . . . . . . \underline{f-126} \fulldownload . . . . . . . . . . . . . . \underline{f-240} \futurelet . . . . . . b-102, b-131, c-412

G \g-⟨name⟩ . . . . . . . . . . . . . . . . . . 120 \g_count . . . . . . . . . . . . . . . . . . \underline{a-168}

                                \g_eval_expr_to . . . . . . . . . . . . . .

\underline{b-233}, c-945, c-946, c-1034–c-1036 \g_let . . . . . . . . . . . . . . . . . \underline{a-294},

c-1906, c-1915, c-1926, f-201, f-223 \gdef . . . . . . . . a-136, a-317–a-320,

a-465, a-573, a-579, a-584, a-592, a-596, a-598, a-601, a-609, a-655, a-704, a-819, a-824, a-828, b-115, b-222, b-784, b-785, b-822, c-299, c-301, c-1080, c-1218, c-1229, c-1693, d-7, d-275, d-972, d-984, e-19–e-22, e-27, e-28, e-33, e-34, e-37, e-40, e-41, e-61, e-62, e-66, e-67, e-71–e-73, e-75, e-77, e-78, e-112, e-119, e-236, e-238, e-240, e-424, e-555, e-556, e-558, e-560, e-562, e-564, e-565, e-571, e-583, f-87, f-238

                                \generalpltomtx . . . . . . . . . . . . . .

. . 175, c-1802, c-1805, \underline{d-421}, d-432, d-759, d-765, d-772, d-779

                                \generate_off_command . . b-864, \underline{b-883}

\generic@if … \underline{a-554}, b-737, b-839, b-842, b-845, b-848, c-326, c-607, c-1108, c-1122, c-1281, c-1870

\generic_error . . . . . . . . \underline{a-745}, a-775 \generic_info . . . . . . . . . \underline{a-732}, a-794 \generic_warning . . . . . . \underline{a-739}, a-784 \get_⟨string name⟩ . . . . . . . . . . . . 232 \get_file_name . c-1154, c-1778, \underline{c-1816} \get_keyword . . . . . . . . . c-1160, c-

1818, \underline{c-1820}, c-1841, c-1845, c-1849

\get_PS_font_file . . . . . . . . . . . .

. . . . . . . f-244, \underline{f-262}, f-373, f-413

\get_PS_font_name . . . . . . . \underline{f-250},

f-251, f-256, f-268, f-361, f-409 \get_slot_num … \underline{c-1241}, c-1416, c-

1587, c-1598, c-1607, c-1616, c-1625 \global a-113, a-116, a-118, a-124, a-

297, a-442, a-445, a-448, a-455, a-469, a-481, a-483, a-586, b-223, b-224, b-235, b-237, b-247, b-248, b-255, b-257, b-258, b-262, b-265, b-276, b-289, b-291, b-293, b-304, b-320, b-323, b-325, b-345, b-346, b-361, b-362, b-371, b-377, b-378, b-387, b-411, b-413, b-423, b-434, b-449, b-459, b-461, b-478, b-490, b-504, b-506, b-507, b-517, b-529, b-543, b-545, b-546, b-569–b-571, b-573, b-579–b-581, b-583, b-596, b-604–b-606, b-608, b-621, b-629–b-631, b-633, b-645, b-670, b-673, b-688, b-690, b-693, b-694, b-696, b-698, b-705, b-707, b-709, b-925, c-22, c-44, c-83, c-96, c-97, c-103, c-106, c-107, c-115, c-118, c-167, c-304, c-393, c-572, c-590, c-591, c-718, c-719, c-788–c-790, c-792–c-794, c-910, c-920, c-927, c-929–c-931, c-949, c-951, c-965, c-971, c-986, c-991, c-1001, c-1014, c-1020, c-1023, c-1081, c-1082, c-1097– c-1099, c-1145, c-1243, c-1245, c-1253, c-1255, c-1303, c-1348, c-1355, c-1358, c-1545, c-1572, c-1634, c-1641, c-1674, c-1677, c-1682, c-1692, c-1694, c-1697, c-1699, c-1702, c-1706, c-1709, c-1720, c-1737, c-1767, c-1771, d-3, d-12, d-18, d-483, d-485, d-878, d-913, d-914, d-951, d-952

\glyph . . . . . . . . . \underline{c-904}, c-1058, c-1073 \FD@glyph@metric . . c-708–c-711, \underline{c-712}

\glyph_depth . . \underline{c-755}, c-769, c-789,

c-806, c-929, c-945, c-1035, c-1098 \glyph_height . . . . . . . . . . . . . . . .

… \underline{c-755}, c-768, c-788, c-805, c-927, c-946, c-947, c-1034, c-1097

\glyph_italic . \underline{c-755}, c-769, c-790,

c-806, c-930, c-949, c-1036, c-1099

                                \glyph_map_commands . . . . . . . . . . .

. . . . . . . \underline{c-755}, c-770, c-793, c-807, c-910, c-911, c-920, c-921, c-951, c-952, c-965, c-966, c-971, c-972, c-991, c-992, c-1001, c-1002, c-1014, c-1015, c-1023, c-1024

                                \glyph_map_fonts . . . . . . . . \underline{c-755},

c-770, c-794, c-807, c-931, c-932 \glyph_maxhpos . . . . . \underline{c-755}, c-792,

c-985, c-986, c-1019, c-1020, c-1077 \glyph_metrics … \underline{c-728}, c-906, c-1519

                                \glyph_name_modifier . . . . . . . . . .

. \underline{c-453}, c-458, c-459, c-463, c-464, c-764, c-767, c-772, c-820, c-839, c-869, c-881, c-1054, c-1058, c-1088, c-1092, c-1812, c-1844

                                \glyph_parameter . . . c-702–c-705,

c-725, c-726, \underline{c-728}, c-906, c-1519 \glyph_voffset . . . . . \underline{c-755}, c-791,

c-926, c-928, c-945, c-947, c-999 \glyph_width . . . . . . . . . . . . \underline{c-755},

c-768, c-787, c-805, c-925, c-944, c-985, c-986, c-989, c-1019, c-1020, c-1033, c-1077, c-1096

\glyphbboxright . . . . . . \underline{c-1077}, c-1089 \glyphname 197, c-786, c-804, d-1041,

d-1045, d-1054, d-1060, d-1062, d-1063, d-1066, d-1071, d-1073, d-1078, d-1081, d-1086, d-1089

\glyphpcc . . . . . . . . . . . . . \underline{c-1052},

d-419, d-865, d-954, d-1033, d-1081 \glyphrule . . . . . . . . . . . . . . . . \underline{c-941} \glyphspecial . . . . . . . . . . . . . . \underline{c-962} \glyphwarning . . . . . . . . . . . . . . \underline{c-962} \gobble_five . . . . . . . . . . . f-188, \underline{f-200} \gobble_glyph …. c-334, \underline{c-763}, d-1076 \gobble_if . . . . . . . . . . \underline{a-526}, c-1275 \gobble_keywords . . . . . \underline{c-1820}, c-1834

\gobble_one . . . . . . \underline{a-300}, a-643, a-

791, b-943, b-997, c-148, c-230, c-232, c-256, c-272–c-275, c-287, c-289, c-290, c-324, c-541, c-569, c-572, c-575, c-1213, c-1247, c-1261, c-1264, c-1266, c-1269, c-1442, d-400, d-888, d-965, d-968, f-134, f-145, f-154, f-239, f-318

\gobble_one_line . d-277, d-278, d-281 \gobble_one_semi . d-399, d-404, d-405 \gobble_parens . . . . . . . . d-477, d-479 \gobble_setslot c-1514, c-1559, \underline{c-1579} \gobble_three . \underline{a-300}, c-170, c-483,

c-625, c-1441, c-1712, d-707, f-38

\gobble_to_xrelax . . . . . . . . . . \underline{b-883}

\gobble_two … \underline{a-300}, b-953, b-962, c-231, c-240, c-317, c-598, c-602

H

\half . . . . . . . . . . . . . . . . . . . . . \underline{b-565} \half_point . . . . . \underline{a-185}, c-1322, c-1538 \hash_char . . . . . . . . . . . \underline{a-310}, b-898 \HEADER . . . . . . . . . . . . . . . . . . . \underline{d-497} \height . . . . . . . . . . . . . . \underline{c-701}, c-1566 \@height . . . . . . . . . . . . . . . b-61, b-63 \hfil . . . . . . . . . . . . . . . . . . b-60, b-64 \hrule . . . . . . . . . . . . . . . . . . . . . b-62 hypertex option . . . . . . . . . . . . . \underline{a-199}

I

\i . . . . . . . . . . . . . . . . . . d-974, d-985 \i-⟨int⟩ . . . . . . . . . . . . . . . . . . . . . 90 \identity_one . . . . . . . . . . . . . . . .

. . \underline{a-300}, a-645, a-727, b-167, c-453, c-823, c-1778, c-1812, d-401

\if . . . . . . . . . . . . . . . . . a-147, a-501, a-709, b-74, b-121, b-150, b-199, b-404, b-660, b-664, b-678, b-898, b-901, b-902, c-534, d-312, d-321, d-322, d-424, d-486

\@if . . . . . . . . . . . . . a-131, a-133–a-135 \if@ . . . . . . . . . . . . . . . . . a-135, a-136

\if@mtxpackage@headed@ . . . . . . . .

. . . . . . . . . . . \underline{c-384}, c-395, c-402 \if@tempswa . . . . . . . b-96, c-447, c-564 \if_a_. . a-183, \underline{a-183}, a-394, a-499,

a-514, c-422, c-1859, c-1865, d-190, d-825, f-77, f-176, f-372

\if_defined … \underline{a-498}, b-826–b-828,

c-1107, c-1759, c-1821, d-545, f-16 \if_equal . . . . . . . . \underline{a-538}, f-213, f-410 \if_expert_. . . . . . . . . . e-51, \underline{e-58},

e-102, e-253, e-436, e-559, e-566

\if_extensions_warning_. . . . . . .

. . . . . \underline{a-339}, a-340, a-346, a-367 \if_fake_narrow_. . . . . . \underline{e-420}, e-429 \if_false . . . . . . . . . a-402, \underline{a-494},

a-517, a-534, a-543, b-730, b-831, c-1116, c-1272, c-1725, d-886

\if_file_exists . . . . . . . . . . . . . .

…. a-60, a-67, a-161, \underline{a-539}, c-1801, c-1804, d-747, d-754, d-757, d-763, d-770, d-771, d-774, d-778, e-7, e-88, e-96, e-103, e-113, e-120, e-131, e-156, e-187, e-200, e-229, e-246, e-264, e-268, e-302, e-334, e-338, e-377, e-381, e-430, e-443, e-447, e-481, e-513, e-517, e-567, e-579, f-54, f-109

                                       \if_including_map_. . . . . . . . . . c-

1150, \underline{c-1150}, c-1180, c-1482, c-1670 \if_is_glyph . . . . . . . . . c-1112, c-1115 \if_oldstyle_. . . . . . . . . . . . . . . .

e-49, \underline{e-58}, e-74, e-111, e-237, e-257, e-557, e-578, e-599, e-619

\if_or . . . . . . . . . . . . . . . . \underline{a-527}, f-410 \if_textcomp_. . . . . . . . . e-671, \underline{e-676}

\if_true . . . . . . . . . . . . . . . \underline{a-494},

a-519, a-529, a-532, a-546, b-728, b-833, c-1113, c-1270, d-888

\if_undefined . . . . . . . . . . . \underline{a-498}, c-820, c-869, c-1088, c-1116, c-1347, c-1508, c-1746, c-1748, d-512, d-921, f-338, f-366, f-391, f-411

\ifareglyphs . . . . . . . . . . . . . . \underline{c-1110} IfBranch (environment) . . . . . . . \underline{a-611} IfBranchDummy (environment) … \underline{a-633} \ifcase . . . . . . . a-261, a-716, b-35,

b-339, b-342, b-453, b-494, b-499, b-533, b-538, b-684, d-567, d-576, d-583, d-592, d-602, d-610

\ifcat . . . . . . . . . . . . . . . b-134, b-254 \ifcsname . . . . . . . . . . . . . . . . . a-502 \ifdim . . . . . . . a-248, a-349, a-382,

c-1493, c-1547, c-1679, c-1684, c-1716, d-266, d-268, d-533, f-304, f-309, f-349, f-355, f-399, f-404

\ifdirect . . . . . . . . c-325, \underline{c-325}, c-326 \ifeof . . . . . . . . . . . . . . . . . . . . a-541 \iffalse . . . . . . . . . . . . . a-133, a-

401, a-494, a-496, b-193, b-248, b-1001, c-7, c-36, c-97, c-341, c-371, c-1109, c-1741, c-1743, d-705

                                       \ifFD@evaluate@ . . . . . . . . . . . . . .

. . . . . \underline{b-245}, b-247, b-248, b-285, b-289, b-313, b-318, b-378, b-397, b-411, b-444, b-457, b-503, b-542, b-556, b-602, b-627, b-656, b-692, c-102, c-114, c-562

                                       \ifFD@slot@known@ c-63, c-71, c-80,

\underline{c-90}, c-96, c-97, c-117, c-160, c-309 \ifFD@spec@ . . . . . . . . . a-36, \underline{a-195},

a-196, c-42, c-48, c-175, c-179 \ifFD@swa …. \underline{b-178}, b-199, b-215,

b-262, b-355, b-362, b-917, b-922 \ifFD@tight@ a-569, a-611, \underline{a-611}, a-614 \IfFileExists . . . . . . . . . . c-24, c-358 \ifiscommand . . . . . . . . . . . . 90, \underline{b-825} \ifisdim . . . . . . . . . . . . . . . 90, \underline{b-825} \ifisglyph . . c-764, c-1054, \underline{c-1107},

c-1119, c-1219, c-1337, c-1581 \ifisinslot . . . . . . . . . . . . . . . \underline{c-1260} \ifisint . . . . . . . . . . . . . . . . . 90,

\underline{b-825}, c-314, c-831, c-874, c-1252, c-1310, c-1317, c-1366, c-1381, c-1509, c-1537, c-1792, d-464

\ifiskern . . . . . . . . . . . . . . . . . \underline{c-596} \ifisstr . . . . . . . . . . . . . . . . . . . .

90, \underline{b-825}, c-1784, d-102, d-157, d-736, d-812, d-918, d-994, f-430

\IFKW- . . . . . . . . . . . . . . . . . . . \underline{c-1834} \IFKW-⟨keyword⟩ . . . . . . . . . . . . . . 151 \IFKW-encoding . . . . . . . . . . . . \underline{c-1847} \IFKW-mtxasetx . . . . . . . . . . . . \underline{c-1158} \IFKW-option . . . . . . . . . . . . . . \underline{c-1852} \IFKW-scaled . . . . . . . . . . . . . . \underline{c-1835} \IFKW-suffix . . . . . . . . . . . . . . \underline{c-1843} \ifmissingslots . . . . . . . . . . d-2, d-15 \ifnum . . . . . . . . . . . a-24, a-126, a-

266, a-272, a-275, a-284, a-370, a-371, a-383, a-434, a-441, a-443, a-453, a-460, a-473, a-479, a-564, a-577, a-590, a-604, a-657, a-671, a-678, a-687, a-689, a-695, b-6, b-11, b-15, b-21, b-22, b-74, b-83, b-121, b-150, b-172, b-175, b-190, b-257, b-290, b-316, b-322, b-375, b-395, b-401, b-404, b-405, b-412, b-416, b-417, b-442, b-447, b-448, b-478, b-489, b-504, b-517, b-528, b-543, b-557, b-561, b-591, b-593, b-599, b-616, b-618, b-624, b-654, b-660, b-664, b-671, b-675, b-678, b-679, b-687, b-696, b-707, b-714, b-721, b-727, b-791, b-792, b-890, b-938, b-943, b-944, b-952, c-562, c-822, c-908, c-927, c-929, c-985, c-988, c-998, c-1019, c-1264, c-1365, c-1382, c-1417, c-1443, c-1523, c-1526, c-1529, c-1571, c-1588, c-1599, c-1608, c-1617, c-1626, c-1635, c-1672, c-1836, c-1891, c-1892, c-2023, c-2025, c-2037, c-2076, c-2077, d-70, d-98, d-99, d-141, d-146, d-172, d-324, d-326, d-358, d-391, d-484, d-821, d-822, d-931, d-961, d-1049, d-1208, f-26, f-41, f-53, f-57, f-69, f-94, f-108, f-112, f-286, f-291 \ifnumber . . . . . . . . . . . . . . . . . \underline{b-724} \ifodd . . . . . . . . . . b-406, b-418, b-

419, b-421, b-568, b-571, b-578, b-581, b-594, b-603, b-606, b-619, b-628, b-631, b-665, b-672, b-680, b-695, b-706, b-713, b-721

\ifoption . . . . . . . . . . . . . . . . \underline{c-1855} \ifslot@comment@ . . . . . . . c-80, c-294 \iftokeep . . . . . . . . . . . . . 194, d-

961, d-1047, d-1065, d-1094, d-1208 \iftrue …. a-131, a-497, a-526, a-

555, b-247, b-1002, c-96, d-318, d-455, d-478, d-849, d-888, d-1017

\@ifundefined . . . . . . . . . b-140, b-199

\ifwarningspecials . . . . . . . . . . . .

. . . . . . . . \underline{c-1648}, c-1651, c-1656 \ifx . . a-9, a-76, a-153, a-214, a-324,

a-331, a-342, a-361, a-436, a-503, a-516, a-523, a-538, a-636, a-642, b-106, b-135, b-251, b-465, b-557, b-745, b-751, b-757, b-763, b-783, b-830, b-861, b-863, b-872, c-246, c-251, c-263, c-413, c-425, c-431, c-436, c-438, c-445, c-456, c-486, c-598, c-602, c-625, c-630, c-632, c-691, c-697, c-1261, c-1269, c-1421, c-1516, c-1558, c-1561, c-1724, c-1732, c-1776, c-1779, c-1861, c-1919, c-1931, c-1933, c-1947, c-1949, c-1983, c-1986, c-1997, c-2000, c-2011, c-2014, c-2034, d-74, d-400, d-454, d-466, d-490–d-493, d-625, d-642, d-654, d-674, d-876, d-886, e-25, e-30, e-36, e-600, e-620, f-27, f-127, f-138, f-168, f-172, f-173, f-204, f-268, f-269, f-285, f-289, f-301, f-317, f-321, f-337, f-361, f-362, f-373, f-375, f-383, f-390, f-409, f-413, f-414

\ignore_parens . . . . . d-428, d-459,

d-476, d-497–d-499, d-502–d-508 \ignorespaces . . . . . . . . . . . . . . c-564 \immediate . . . . . . a-25–a-27, a-29,

a-30, a-63, a-70, a-102, a-164, a-418, a-420–a-422, a-461, a-467, a-477, a-480, a-486, a-540, a-542, a-545, a-736, a-742, a-748, a-762, a-767, c-1312, c-1412, c-1418, c-1422, c-1591, c-1602, c-1611, c-1620, c-1629, c-1654, d-645, e-50, e-52, e-54, e-80, e-137, e-158, e-206, e-274, e-283, e-304, e-344, e-353, e-387, e-396, e-453, e-462, e-483, e-523, e-532, e-593

\includewarning . 228, f-153, \underline{f-202},

f-271, f-321, f-363, f-376, f-415 _including_map_switch . . . . . . \underline{c-1150}

\_including_map_false . c-1144, \underline{c-1150}
\_including_map_true . . \underline{c-1150}, c-1151

\init_afm . . . . . . . . . . . . d-332, d-343 \init_cc . . . . . . . . . . . . . d-334, d-373 \input . . . . . . . . . . . a-77, a-193, a-637 \input_metrics . c-1703, c-1711, \underline{c-1728}

\input_mtx_as_etx . . . . . \underline{c-327}, c-1159

\input_mtx_file . . . . . . c-1735, \underline{c-1774} \inputetx . . 100, \underline{c-1}, c-1153, d-78,

d-168, d-202, d-427, d-523, d-815

\InputIfFileExists . . . . . . . . . . a-230

\inputlineno . . . . . . . . . . . . . . . a-817 \inputmtx . . . . . . . . . . . . . . . . . . .

111, c-336, \underline{c-339}, c-422, c-431, c-439, c-448, c-1785, c-1790, d-710, d-852, d-1020, f-55, f-110

\insc@unt a-99, a-107, a-108, a-118–a-123 \insert . . . . . . . . . . . . . . . . . . . a-125 \install . . . . . . . . . . . . c-1787, c-1824 \installfamily . . . . . . 148, \underline{c-1696},

c-1765, c-2151, e-8, e-10, e-11, e-13 \installfont . . . . . . . . . . . . . . . . .

. 148, \underline{c-1701}, c-2145, e-594, e-613 \installfontas . c-1705, c-1715, \underline{c-1745} \installfonts . 148, \underline{c-1689}, c-2143, e-6

\installraw_storemap . . c-1711, \underline{c-1722}
\installrawfont . . . . . . . . . . . . . .

. . 148, \underline{c-1701}, c-2148, e-159, e-171, e-305, e-317, e-484, e-496

\int . . . . . . 90, a-250, b-167, \underline{b-349}, b-772, b-811, b-839, b-960, c-314, c-321, c-465, c-493, c-832, c-875, c-1253, c-1311, c-1318, c-1322, c-1324, c-1368, c-1382, c-1538, d-236, d-465, d-786–d-788, d-792, d-797, d-798, d-803, d-821, d-822, d-826–d-829, d-878, d-879, d-882, d-889, d-891, d-908–d-910, d-912, d-913, d-917, d-941, d-948, d-950, d-951

\FD@integer@func . b-358, \underline{b-367}, c-716

\InvisibleCharPrefix . . . . . . . . . . \underline{b-1}
\InvisibleCharSuffix . . . . . . . . . . \underline{b-1}
\italcorr_expression . . . . . . . . . .

. 174, d-234, d-355, d-392, d-394 \italic . . . . . . . . . . . . . . \underline{c-701}, c-1570

\italicslant_name . . . . . . . . . . \underline{d-873}

\item . . . . . . . . . . . . . . . . . . . . . a-631 \itemindent . . . . . . . . . . . . . . . . a-629 \itemsep . . . . . . . . . . . . . . . . . . a-626 \iterate . . . . . . . . . . . . . a-145, a-146 \itshape . . . . . . . . . . . . . b-222, b-366

J \jobname . . . . . . . . . . . . . . . . . . a-

430, c-1170, c-1882, d-33, d-112, d-238, d-437, d-694, d-837, d-1004

K \k . . . . . . . . . . . . . . . . . . . . . 114,

c-473, c-474, c-501, c-502, c-535, c-539, c-569, c-598, c-602, c-612, c-626, c-677, c-686, c-697, c-1392

\k_unless_to_U . . . . . . . . c-612, c-624 \kern . . . . . . . . . . . . . . . . . . . . . a-358 \kerning . . . . . . . . . . . . . . . . . . \underline{c-567} \kill_glyph . . . . . d-985, d-990, \underline{d-1041} \killglyph . . . . . . . . . . . . . . . . . .

194, \underline{d-982}, d-1193, d-1200–d-1202

                                       \killglyphweighted . . . . . . 194, \underline{d-982}

\KRN . . . . . . . . . . . . . . . . . . . . . . \underline{d-646}

L \l . . . . . . . . . . . . . . . . . . c-571, c-575 \l-⟨name⟩ . . . . . . . . . . . . . . . . . . 114 \l_inv_scale . . . . . \underline{b-718}, d-827, d-829

                                       \l_rounded_thousandths . . . . . . . .

. . . . . . . . . . . . \underline{b-703}, c-833– c-836, c-876–c-879, c-915–c-918

\LABEL . . . . . . . . . . . . . . . . . . . . \underline{d-625} \label . . . . . . . . . . . . . . . . . . . . \underline{c-324}

                                       \LABEL_boundarychar . . . . . . . . . \underline{d-625}

\LABEL_slot . . . . . . . . . . . . . . . . \underline{d-625} \latex_encoding . . . . . . . . . . . . \underline{e-554} \latex_family . . . . . . . . . . . . . . . .

… e-8, e-10, e-11, e-13, e-22, e-37, e-81, e-167, e-179, e-313, e-325, e-492, e-504, e-609, e-632

\latex_mtx . . . . . . . . . . . . . . . . \underline{e-554} \latex_shape . . . . . . . . . . . . . . . . .

… \underline{e-70}, e-169, e-181, e-315, e-327, e-494, e-506, e-611, e-636

\latex_variant . . . . . . . . . . . . . . \underline{e-18} \latex_weight . . . . . . . . . . . . . . . .

\underline{e-60}, e-82, e-168, e-180, e-314, e-326, e-493, e-505, e-610, e-634

\latex_width . . . . . . . . . . . . . . . . . \underline{e-65}, e-82, e-168, e-180, e-314, e-326, e-493, e-505, e-610, e-634

                                       \latin_encoding . . . . . . . . . . . . . .

. . . . . . \underline{e-554}, e-667, e-668, e-672 \latin_encodings . . . . . . . e-92, \underline{e-666} \latin_shape . . . . . . . \underline{e-70}, e-661–e-664 \latin_shapes . . . . . . . . . . e-68, \underline{e-660} \latin_weight . . . . . . \underline{e-60}, e-640–e-652 \latin_weights . . . . . . . . . e-15, \underline{e-639} \latin_width . . . . . . \underline{e-65}, e-655, e-656 \latin_widths . . . . . . . . . . e-63, \underline{e-654} \latinfamily . . . . . . . . . . . . . . . . . \underline{e-1} \lccode . . . . . . . . . . . . . c-1220, c-1230 \lccode0 register . . . . . . . . . . . . . 135 \leavevmode . . . . . . . . . . . . . . . . . . b-3

\FD@left@priority . . . . . . . . . . b-

399, b-404, b-417, b-418, b-658, b-664, b-665, b-671, b-672, b-678

\left_brace_char . \underline{a-310}, c-1913, d-93 \leftmargin . . . . . . . . . . . a-618, a-623 \@let@token . . . . . . . . . . . . . . . . . .

b-102, b-106, b-131, b-134, b-135

\lfloor . . . . . c-209, c-214, c-219, c-226 \LIG . . . . . . . . . . . . . . . . . . . . . . \underline{d-502} \FD@lig-⟨lig⟩ . . . . . . . . . . . . . . . . 105 \Ligature . . . . . . . . . . . . . . 104, \underline{c-170} \ligature . . . . . . . . . . . . . . . . . . .

104, \underline{c-170}, c-1391, c-1418, c-1422

\LIGTABLE . . . . . . . . . . . . . . . . . \underline{d-643} \linepenalty . . . . . . . . . . . . . . . c-247 \lineskiplimit . . . . . . . . . . . . . a-248 \list . . . . . . . . . . . . . . . . . . . . . a-613

\list@item@counter . . . . . . . . . . \underline{a-255}

\list_def . . . . . . . d-405–d-410, d-416 \list_of_options c-1814, c-1853, \underline{c-1855}

\list_subs_vertices . . . . . . . . c-2062
\load_file_unless_loaded c-428, c-430
\load_true_unless_loaded c-421, c-424

\long . . . . . . . . . . . c-775, c-783, c-1579 \loop …. a-145, a-147, a-434, b-73,

b-890, c-1365, c-1672, d-68, d-140 \lose_measure . . . . . . . . . . . . . . . .

\underline{a-701}, c-1298, c-1638, c-1717, f-306, f-311, f-351, f-357, f-401, f-406

\lowercase . . . . . . . . . . . . . . . . c-3, c-18, c-254, c-353, c-1221, c-1231, c-1877, c-2154, d-452, f-257

\lowercase@file . . . . . . c-18, c-19,

c-21, c-24, c-353, c-354, c-356, c-358 \lowercase_file … c-3–c-5, c-9, c-

1877–c-1881, c-1888, c-2154–c-2157

\LWFN_get_PS_font_file . . f-244, \underline{f-267}

M

\@M . . . . . . . . . . . . . . . . . . . . . . . a-90 \@m . . . . . . . . . . . . . . . . . . a-89, c-562 \m@ne . . . . . . . . a-101, a-102, a-118,

a-129, a-270, a-432, a-433, a-441, a-460, a-465, a-479, a-736, b-571, b-581, b-606, b-631, d-486, d-922, d-931, f-20, f-198, f-292 \m@th . . . . . . . . . . . . . . . . . . . . . b-190 \macroparameter . . . . . . . . . 35, \underline{b-221} \main_remove_Us … c-614, c-618, c-629 \make_⟨driver⟩ . . . . . . . . . . . . . . . 227

                                       \make_assignments . . . . c-1163, \underline{c-1199}

\make_characters . . . . . c-1183, \underline{c-1471} \make_debug . . . . . . . . . . . . . . . . \underline{f-298} \make_dvipdfm . . . . . . . . . . . . . . \underline{f-388} \make_dvips . . . . . . . . . . . . . . . . \underline{f-333} \make_enc . . . . . . . . . . . . . . d-79, \underline{d-81} \make_etx . . . . . . . . . . . . . . d-27, d-30 \make_factor . . . . . . \underline{a-669}, c-1322,

c-1342, c-1368, c-1444, c-1520, c-1524, c-1527, c-1530, c-1538, c-1644, c-1645, c-1659, c-1663, d-716, d-722–d-725, f-161, f-164

\make_factor_i … a-672, a-674, \underline{a-677} \make_factor_ii . . . . . . . a-679, \underline{a-685} \make_factor_iii . . . . . . a-681, \underline{a-692} \make_fontdimens . . . . . c-1181, \underline{c-1362} \make_header . . . . . . . . . c-1179, \underline{c-1302} \make_inputetx . c-1134, c-1147, \underline{c-1152} \make_ligtable . . . . . . . c-1182, \underline{c-1375} \make_map_entry . . . . . . . . . . f-63, \underline{f-68} \make_mapfonts . . . . . . . c-1180, \underline{c-1327} \make_pltotf . . . . . . . . . . . . . . . \underline{f-428} \make_slots_relax . c-616, c-620, c-623 \make_slots_U . . . . . c-613, c-617, c-622 \make_tidy . . . . . . . . . . c-1184, \underline{c-1668} \makebox . . . . . . . . . . . . . . . . . . . b-59 \makemapentry . . . . . . . . 221, \underline{f-51}, f-95 \MakePrintable . . . . . . . . . . . \underline{b-88},

b-162, b-180, b-196, b-213, b-261, b-353, b-912, b-919, c-58, c-136, c-581, c-582, c-645, c-714

\maker_do . . . . . . . . . . . . . f-134, f-

145, f-154, f-179, \underline{f-184}, f-187, f-192

                                       \makerightboundary . . . . . . . . . . . .

. 104, c-153, \underline{c-229}, c-1203, c-1206, c-1213, c-1239, c-1261, c-1313

\MAP . . . . . . . . . . . . . . . . . . . . . . \underline{d-506}

\mapcommands . . . . . . . . . . . . \underline{c-724},

c-909, c-919, c-1548, c-1551, c-1573 \MAPFONT . . . . . . . . . . . . . . . . . . \underline{d-506}

                                       \mapfont_scaling . . . . . . . . . . . . .

… \underline{c-1285}, c-1342, c-1347–c-1349, c-1353, c-1358, c-1634, c-1638, c-1644, c-1645, c-1659, c-1663

\mapfonts . . . . . . . . . . . . . . . . . . .

\underline{c-724}, c-913, c-923, c-1338, c-1494

                                       \mapfrags_subsystem . . . . . . . . . . .

. . \underline{f-1}, f-28, f-31, f-78, f-128, f-139, f-149, f-169, f-226, f-231, f-235 \mathchardef . . . . . . . . . a-88–a-91,

a-185–a-189, a-658, b-795, c-1348 \mathcode . . . . . . . . . . . . a-657–a-659 \mathop . . . . . . . . . . . . . . b-368, c-584 \mathrm …. b-173, b-368, c-584, c-1080 \max . . . . . . . . . . . . . . a-253, \underline{b-472},

b-557, c-945, c-947, c-1077, d-382

\max_mathchardef . . . . . . . . . . . . .

…. \underline{a-185}, b-791, c-2074, c-2077 \maxdimen . . . . . . . . . . . . b-486, b-525 \FD@maxmin@comma . b-488, b-527, \underline{b-549} \mbox . . . . . . . . . . . a-212, b-186, b-263 \meaning . . . . . . . . . . . . . . . . . . b-887 \medskipamount a-243, a-569, a-620, c-408 \message_break . . . . . . . . . . . . c-1511 \message_number . . . . . . . . . . . c-1512 \MessageBreak . . . . . b-929, c-30, c-364 \messagebreak . a-399, a-404, \underline{a-730},

a-735, a-741, a-749, a-752, a-763, a-766, a-778, a-787, a-797, a-820, a-822, a-826, c-1062, c-1791, c-1792, c-1827, d-741, f-81, f-131, f-142, f-150, f-151, f-227

\metrics . . . . . . . . . \underline{c-339}, c-1729,

c-1731, d-249, d-448, d-845, d-1012

\metrics_given_encoding c-1782, \underline{c-1799}

\min . . . . . . . . . . . . . . . . . a-254, \underline{b-511} \minimum_kern . . . . . . . . . . c-1324,

c-1443, d-236, d-260, d-324, d-326

\missingslotsfalse . . . . . . . d-12, d-18
\missingslotstrue . . . . . . . . . . . . d-3

\mkern . . . . . . . . . . b-172, b-175, b-190 \@MM . . . . . . . . a-91, a-149, a-154, c-2066 \month . . . . . . . . . . . . . . . c-1891, d-98 \movert . . . . . . . . . . . . . . . . \underline{c-982},

c-1033, c-1056, c-1071, c-1096 \moveup . . . . . . . . \underline{c-982}, c-1057, c-1072

\mtx_package_given_file c-414, c-419
\mtx_package_separate_files . . . .

. . . . . . . . . . . . . . . c-416, c-427

@mtxpackage@headed@ switch . . . . \underline{c-384}
\@mtxpackage@headed@false \underline{c-384}, c-388
\@mtxpackage@headed@true  \underline{c-384}, c-398

\mtxtomtx . . . . . . . . 189, d-737, \underline{d-811}

\mtxtomtx_endsetglyph . . d-867, \underline{d-944}
\mtxtomtx_glyphpcc . . . . . d-865, \underline{d-947}
\mtxtomtx_redefinitions d-851, \underline{d-857}
\mtxtomtx_samesize . . . . . d-866, \underline{d-944}

\mtxtomtx_setdim . . . . . . d-859, \underline{d-901}

\mtxtomtx_setglyph . . . . . d-864, \underline{d-944}

\mtxtomtx_setint . . . . . . d-858, \underline{d-873}

\mtxtomtx_setkern . . . . . d-863, \underline{d-940}
\mtxtomtx_setscaledrawglyph . . . .

. . . . . . . . . . d-861, d-862, \underline{d-907} \mtxtomtx_setstr . . . . . . d-860, \underline{d-901} \mtxtopl 183, \underline{d-686}, d-738, d-750, d-776 \mul . . . . . . . . . . . . . . . . . . . . . . \underline{b-381} \multiply . . . . . . . . . . . . . . a-713,

b-19, b-387, b-411, b-645, b-693, b-719, c-833–c-836, c-876– c-879, c-915–c-918, c-1294, c-1296, c-2072, d-180, d-878, d-880, d-912, d-913, d-950, d-951

N \@namedef . . . . . . . . . . . . . . . . . b-

85–b-87, b-149, b-195, b-212, b-227 \@nameuse . . . . . . . . c-176, c-180, c-184 \@ne . . . . . . . . . a-76, a-83, a-113, a-

259, a-265, a-266, a-280, a-435, a-442, b-82, b-172, b-175, b-176, b-188, b-190, b-262, b-316, b-346, b-362, b-395, b-401, b-404, b-416, b-417, b-442, b-461, b-507, b-546, b-569, b-579, b-591, b-593, b-604, b-616, b-618, b-629, b-654, b-660, b-671, b-675, b-678, b-690, b-696, b-714, b-721, c-83, c-167, c-591, c-719, c-1370, d-71, d-147, d-148, d-486

                                       \needsfontinstversion . . . . . \underline{a-20},

d-56, d-251, d-450, d-847, d-1014

                                       \needsTeXextension . . . . . . . . . . \underline{a-391}

\NeedsTeXFormat . . . . . . . . . a-10, a-14 \neg . . . . . . . . . . . . . . . . . a-252, \underline{b-371} \never_do . \underline{a-337}, c-2065, d-643, d-650 \newcommand . . . . . . . . . . . . a-35, a-

242, a-246, a-249, a-256, a-556, b-29, b-33, b-34, b-160, b-178, b-240, b-771, b-775, b-779, b-810, b-814, b-818, b-911, c-56, c-99, c-111, c-134, c-158, c-174, c-178, c-182, c-242, c-250, c-258, c-297, c-301, c-302, c-307, c-308, c-319, c-326, c-435, c-478, c-506, c-549, c-552, c-555, c-558, c-637, c-665, c-668, c-671, c-778, c-798, c-851, c-856, c-892, c-895, c-902, c-937, c-957, c-977, c-979, c-1008, c-1009, c-1029, c-1030, c-1039, c-1042, c-1045, c-1048, c-1103

\newcount . . . . . . . . . . . . . . a-107, a-169–a-175, a-237, a-238, a-255, a-562, b-234, b-245, b-246, b-334, c-90, c-95, c-755–c-758, c-761, c-762, c-1359–c-1361, d-260, d-335–d-341, d-1040, f-3 \newdimen . . . . . . . . . . . . . . . . . a-

108, a-138, a-139, a-176–a-179, a-190, a-239, c-1286, c-1288, c-1289, c-1300, c-1301, d-273, f-157

\newenvironment . . . . . . . a-612, a-633 \newif a-129, a-183, a-196, a-340, a-

611, c-294, c-325, c-395, c-1150, c-1656, d-2, e-58, e-59, e-420, e-676

\newinsert . . . . . . . . . . . . . . . . a-118 \newlinechar . . . . . . . . . . . . . . . \underline{a-831} \newread . . . . . . . . . . . . . . . . . . a-110 \newtoks . . . . . . . . . . a-109, a-180–

a-182, c-759, c-760, c-1689, f-329 \newwrite . . . . . . . . . . . . a-111, a-184 \next . . . . . . . . . . . . . . . . a-146, b-

886, b-887, b-903, b-906, b-946, b-947, b-975, b-979, b-988, b-994

\next_mapfont . . . . . . . . . . . . . . . .

… \underline{c-1359}, c-1634–c-1636, c-1641 \next_token . . . . . . . . . . . c-412, c-413 \NEXTLARGER . . . . . . . . . . . . . . . . \underline{d-502} \nextlarger . 104, \underline{c-229}, c-1475, c-1591 \nextslot . . . . . . . . . \underline{c-90}, c-330, d-16 \@nil . . . . . . . . . . . b-252, b-254, b-465 \no_kerning . . . . . . . c-660–c-662, \underline{c-675} \no_kerning_i . . . . . . . . . c-677, \underline{c-690} \no_kerning_ii . . . . . . . . c-686, \underline{c-696} \NOFILES . . . . . . . . . . . . . . . . . \underline{c-2137} \noindent . . . . . . . . . a-244, a-246,

a-570, a-583, a-605, b-999, c-262 \noleftkerning . . . . . . . . . . . . . \underline{c-659}

\noleftrightkerning . . . . . . . . . \underline{c-659}

\nolinebreak . . . . . . . . . . a-357, a-369 \norightkerning . . . . . . . . . . . . \underline{c-659}

\normal_get_PS_font_file . \underline{f-262}, f-270

\normalcc . . . . . . . . . . . . . . \underline{a-44}, a-73 \normalfont . b-187, b-222, b-366, b-848 Not in doc:

\dim . . . . . . . . . . . . . . . . . . . . . 92 \endfor . . . . . . . . . . . . . . . . . . 98 \foo . . . . . . . . . . . . . . . . . . . . 275 \for . . . . . . . . . . . . . . . . . . . . . 98 \unsetcommand . . . . . . . . . . . . . 93 \unsetdim . . . . . . . . . . . . . . . . . 93 \unsetint . . . . . . . . . . . . . . . . . 93 \unsetstr . . . . . . . . . . . . . . . . . 93 \usedas . . . . . . . . . . . . . . . . . 106

\notdef_name . . . . . . . . . . . c-1516,

c-1561, \underline{c-1585}, \underline{d-65}, d-69, d-74 \nullfont . . . . . . . . . . . . . . . . . c-306 \NUM . . . . . . . . . . . . . . . . . . . . . . \underline{d-566} \number . . . . . . . . . . . . . . . a-45, a-

349, a-672, a-674, a-727, b-67, b-123, b-127, b-152, b-156, b-167, c-1427, c-1452, d-721, d-1054

O \oddligature . . . . . . . . . . . . 104, \underline{c-170} \off-⟨\command⟩ . . . . . . . . . . . . . 94

                                       \off-\reglyph_setglyph . . . . . \underline{d-1069}

\offcommand . \underline{b-859}, c-333, c-335, d-965 \offmtxcommand . . . . . . . . . . . . . . .

. . . . . 194, \underline{d-964}, d-1206, d-1207 \_oldstyle_false . . . . . . . . e-24, e-45 \oldstyle_font e-565, e-583, e-605, e-625 \oldstyle_shape … e-75, e-112, \underline{e-680} \_oldstyle_true . . . . . . . . . e-32, e-39

                                       \oldstyle_variant . . . . . . . . . . . .

… e-112, e-114, e-119, e-121, e-201, e-208, e-210, e-215, e-220, e-378, e-382, e-389, e-391, e-398, e-401, e-405, e-410, e-580, e-585

\on_line . . . . . . . . a-736, a-742, \underline{a-816} \oncommand . . . . . . . . . . . \underline{b-859}, d-968 \one_hundred . . . . . . . . . . \underline{a-185}, a-687 \one_thousand . . . . . . . . . . . . . . . .

\underline{a-185}, a-678, a-695, c-534, c-817, c-822, c-866, c-908, c-1058, c-1295, c-1836, c-2023, c-2024, c-2073, d-386, d-732, d-733, d-880

\onmtxcommand . . . . . . . . . . 194, \underline{d-964}

\open_out . . . . . . \underline{a-416}, c-1164, c-

1880, c-2157, d-31, d-91, d-203, d-230, d-435, d-688, d-834, d-1002

\open_pout . . . . . . . . . \underline{a-458}, f-8, f-177 \openin . . . . . . . . . . . . . . . . . . . a-540 \openout . . . . . . . . . . . . . a-418, a-467 options:

hypertex . . . . . . . . . . . . . . . \underline{a-199} pdftex . . . . . . . . . . . . . . . . . \underline{a-199} specification . . . . . . . . . . . \underline{a-195} \options_text . f-398, f-400, f-405, f-425 \or a-261, a-263, a-716, a-717, b-36, b-

37, b-39–b-55, b-339, b-342, b-453, b-494, b-495, b-499, b-500, b-533, b-534, b-538, b-539, b-684, b-685, d-567, d-569, d-571, d-576, d-578, d-583, d-585, d-587, d-592, d-594, d-602, d-604, d-610, d-612, d-614, d-616, d-618

\or_else . . . . . . . . . . . . . . \underline{a-527}, f-410 \orig_series . . . . . . . . . . . . . . . . .

… c-1946–c-1948, c-1952, c-1953 \orig_shape . . . . . . . . . . . . . . . . . .

… c-1929–c-1932, c-1936, c-1937 \otherhalf . . . . . . . . . . . . . . . . \underline{b-565} \out_file . . \underline{a-184}, a-418, a-421, a-422 \out_filename . . . . . . . . . . . a-418,

a-420, c-1681, c-1710, c-1724, c-1725, d-100, d-128, d-131, d-153

\out_filename-⟨stream⟩ . . . . . . . . . 49

\out_filename--1 . . . . . . . . . . . \underline{a-427}
\out_filename-99 . . . . . . . . . . . \underline{a-427}

\out_liglabel . . c-1383, \underline{c-1456}, c-1468 \out_ligstop … c-1459, c-1464, \underline{c-1467} \out_line . . . . . . . . . . . . \underline{a-416}, c-

1166, c-1168–c-1173, c-1175–c-1178, c-1185, c-1186, c-1306, c-1308, c-1319, c-1325, c-1334, c-1350, c-1363, c-1373, c-1377, c-1400, c-1517, c-1562, c-1685, c-1881–c-1885, c-1887, c-1888, c-1896, c-1897, c-1900, c-1907, c-1908, c-1912, c-1913, c-1916, c-1934, c-1950, c-2158, c-2159, d-16, d-19–d-21, d-32–d-36, d-38, d-40–d-57, d-59–d-62, d-92, d-93, d-96, d-100, d-103, d-105– d-107, d-110–d-113, d-115, d-116, d-118, d-120, d-122, d-123, d-125, d-127, d-134, d-135, d-137, d-143, d-145, d-150–d-153, d-158, d-160, d-164, d-196, d-204, d-205, d-207, d-210, d-212–d-216, d-218–d-223, d-237– d-241, d-243, d-245–d-252, d-256, d-257, d-290, d-293, d-296, d-299, d-302, d-305, d-307, d-310, d-313, d-325, d-327, d-357, d-374, d-379, d-389, d-436–d-440, d-442, d-444–d-451, d-457, d-463, d-467, d-470, d-473, d-529, d-537, d-547, d-623, d-655, d-675, d-690, d-692–d-697, d-699–d-704, d-711, d-712, d-716, d-721, d-836–d-848, d-850, d-853, d-854, d-894, d-902, d-905, d-930, d-942, d-944, d-946, d-1003–d-1015, d-1018, d-1021, d-1022, d-1037–d-1039, d-1048, d-1066, d-1073, d-1096, f-44

\out_lline . . . . . . . . . . . . . . . . . .

\underline{a-416}, c-1367, c-1372, c-1398, c-1427, c-1451, c-1457, c-1462, c-1467, c-1522, c-1524, c-1527, c-1530, c-1546, c-1565, c-1567, c-1569, c-1571, c-1572, c-1582, c-1589, c-1595, c-1889, c-1920, c-1922, d-378, d-419, d-722–d-726, d-945, d-954, d-1080, d-1088

\out_llline . . . . . \underline{a-416}, c-1550, c-1552, c-1554, c-1574, c-1596, c-1600, c-1609, c-1618, c-1627, c-1636, c-1640, c-1646, c-1649, c-1652, c-1660, c-1664, c-1666, c-1667

\outer . . . . . . . . . . . . . . . a-107–a-111, a-118, a-129, a-150, a-155, c-13, c-38, c-46, c-348, c-373, c-379

\output_⟨driver⟩ . . . . . . . . . . . . . 227 \output_debug . . . . . . . . . . . . . . f-

299, f-300, f-302, f-305, f-310, f-320 \output_dvipdfm . . . . . . . . . . . . f-423 \output_dvips . . . . . . . . . . . . . . f-380 \output_pltotf . . . . . . . . . . . . . f-429

P \p . . . . . . . . . . . . . . . . . . . . . . . a-702 \p@ a-138, a-349, a-627, c-1145, c-1493,

c-1520, c-1682, c-1684, c-1716, f-158, f-164, f-304, f-349, f-399

\PackageError b-141, b-928, c-29, c-363 \pagebreak . . . . . . . . . . . . . . . . a-243 \par a-149, a-150, a-154, a-156, a-243,

a-244, a-246, a-568, a-574, a-581, a-587, a-599, a-605, b-999, c-41, c-246, c-247, c-251, c-263, c-264, c-408, c-1154, c-1778, c-1833

\PARAMETER . . . . . . . . . . . . . \underline{d-543}, d-552, d-554, d-556, d-558, d-560, d-562, d-564, d-568, d-570, d-572, d-577, d-579, d-584, d-586, d-588, d-593, d-595, d-598–d-600, d-603, d-605, d-608, d-611, d-613, d-615, d-617, d-619

\parse_family . . . . . . . . . . . . e-4, \underline{e-18} \parsep . . . . . . . . . . . . . . . . . . . a-627 \partopsep . . . . . . . . . . . . . . . . a-625 \pdfannotlink . . . . . . . . . . . . . . a-215 \pdfendlink . . . . . . . . . . . . . . . . a-225 \pdfstartlink . . . . . . . . . a-214, a-217 \pdfTeX . . . . . . . . . . . . . . . . . . . \underline{a-360} pdftex option . . . . . . . . . . . . . . . \underline{a-199} \pdftexrevision . . . . . . . . . . . . a-384 \pdftexversion . . . . . . . . a-361, a-382 \penalty . . . . . a-149, a-154, a-244,

a-667, b-554, c-586, c-654, c-655 \percent_char . . . . . . . . . . . \underline{a-310},

c-1232, c-1311, c-1317, c-1318, c-1881–c-1883, c-1885, c-2158, c-2159, d-32–d-34, d-36, d-38, d-41, d-92, d-93, d-96, d-100, d-103, d-105–d-107, d-110, d-112, d-113, d-116, d-118, d-120, d-123, d-125, d-127, d-135, d-143, d-151, d-153, d-158, d-160, d-204, d-205, d-207, d-210, d-222, d-223, d-237–d-239, d-241, d-243, d-246, d-436–d-438, d-440, d-442, d-445, d-464, d-465, d-540, d-836–d-838, d-840, d-842, d-1003–d-1005, d-1007, d-1009

PL properties:

AXISHEIGHT . . . . . . . . . . . . . . \underline{d-598} BIGOPSPACING1 . . . . . . . . . . . \underline{d-608} BIGOPSPACING2 . . . . . . . . . . . \underline{d-608} BIGOPSPACING3 . . . . . . . . . . . \underline{d-608} BIGOPSPACING4 . . . . . . . . . . . \underline{d-608} BIGOPSPACING5 . . . . . . . . . . . \underline{d-608} BOUNDARYCHAR . . . . . . . . . . . . \underline{d-539} CHARACTER . . . . . . . . . . . . . . . \underline{d-660} CHARDP . . . . . . . . . . . . . . . . . \underline{d-660} CHARHT . . . . . . . . . . . . . . . . . \underline{d-660} CHARIC . . . . . . . . . . . . . . . . . \underline{d-660} CHARWD . . . . . . . . . . . . . . . . . \underline{d-660} CHECKSUM . . . . . . . . . . . . . . . \underline{d-497} CODINGSCHEME . . . . . . . . . . . . \underline{d-509} COMMENT . . . . . . . . . . . . . . . . \underline{d-502}

DEFAULTRULETHICKNESS . . . . . \underline{d-608}

DELIM1 . . . . . . . . . . . . . . . . . \underline{d-601} DELIM2 . . . . . . . . . . . . . . . . . \underline{d-601} DENOM1 . . . . . . . . . . . . . . . . . \underline{d-566} DENOM2 . . . . . . . . . . . . . . . . . \underline{d-566} DESIGNSIZE . . . . . . . . . . . . . . \underline{d-527} DESIGNUNITS . . . . . . . . . . . . . \underline{d-531} EXTRASPACE . . . . . . . . . . . . . . \underline{d-552} FACE . . . . . . . . . . . . . . . . . . . \underline{d-497} FAMILY . . . . . . . . . . . . . . . . . \underline{d-497} FONTDIMEN . . . . . . . . . . . . . . . \underline{d-551} HEADER . . . . . . . . . . . . . . . . . \underline{d-497} KRN . . . . . . . . . . . . . . . . . . . . \underline{d-646} LABEL . . . . . . . . . . . . . . . . . . \underline{d-625} LIG . . . . . . . . . . . . . . . . . . . . \underline{d-502} LIGTABLE . . . . . . . . . . . . . . . \underline{d-643} MAP . . . . . . . . . . . . . . . . . . . . \underline{d-506} MAPFONT . . . . . . . . . . . . . . . . \underline{d-506} NEXTLARGER . . . . . . . . . . . . . . \underline{d-502} NUM1 . . . . . . . . . . . . . . . . . . . \underline{d-566} NUM2 . . . . . . . . . . . . . . . . . . . \underline{d-566} NUM3 . . . . . . . . . . . . . . . . . . . \underline{d-566} PARAMETER . . . . . . . . . . . . . . . \underline{d-543} QUAD . . . . . . . . . . . . . . . . . . . \underline{d-552} SELECTFONT . . . . . . . . . . . . . . . 147

SEVENBITSAFEFLAG . . . . . . . . . \underline{d-497}

SHRINK . . . . . . . . . . . . . . . . . \underline{d-552} SKIP . . . . . . . . . . . . . . . . . . . \underline{d-643} SLANT . . . . . . . . . . . . . . . . . . \underline{d-552} SPACE . . . . . . . . . . . . . . . . . . \underline{d-552} STOP . . . . . . . . . . . . . . . . . . . \underline{d-643} STRETCH . . . . . . . . . . . . . . . . \underline{d-552}

SUB1 . . . . . . . . . . . . . . . . . . . \underline{d-582}
SUB2 . . . . . . . . . . . . . . . . . . . \underline{d-582}
SUBDROP . . . . . . . . . . . . . . . . \underline{d-598}
SUP1 . . . . . . . . . . . . . . . . . . . \underline{d-582}
SUP2 . . . . . . . . . . . . . . . . . . . \underline{d-582}
SUP3 . . . . . . . . . . . . . . . . . . . \underline{d-582}
SUPDROP . . . . . . . . . . . . . . . . \underline{d-598}
VARCHAR . . . . . . . . . . . . . . . . \underline{d-502}
VTITLE . . . . . . . . . . . . . . . . . \underline{d-506}
XHEIGHT . . . . . . . . . . . . . . . . \underline{d-552}

\pl_encoding . . . . . . . . . . . . . . . . .

. . c-1779, c-1782, c-1813, \underline{c-1847} \pl_int . . . . . . . . . . . . . . . . \underline{d-489},

d-540, d-544, d-632, d-648, d-666 \pl_mapfont . . . . . . . . . . \underline{c-1358}, c-1499 \pl_raw_glyph …. d-717, d-718, \underline{d-720} \pl_real . . . . . . . . . . . . . \underline{d-480}, d-623 \pl_realer . . . . . . . . . . . . . . . . \underline{d-480}

                                   \pl_rounded_real . . . . . . . . . . . . .

\underline{d-482}, d-546, d-647, d-660–d-663

                                   \pl_setfontdimen . . . . . . . . . . . . .

. . d-423, \underline{d-542}, d-553, d-555, d-557, d-559, d-561, d-563, d-565

\pl_to_mtx . . . . . . . . . . . d-430, \underline{d-433} \plain . . . . . . . . . . . . . . . . . . . . a-249 \plaindiv . . . . . . . . . . . . . . . . . \underline{a-250} \plainint . . . . . . . . . . . . . . . . . \underline{a-250} \plainmax . . . . . . . . . . . . \underline{a-250}, b-493 \plainmin . . . . . . . . . . . . \underline{a-250}, b-532 \plainneg . . . . . . . . . . . . . . . . . \underline{a-250} \pltomtx . . . . . . . . . . . . . . 175, \underline{d-432} \pop . . . . . . . . . . \underline{c-1011}, c-1059, c-1074

                                   \post_first_etx_pass_hook . . . . . .

. . . . . . . . . . . . . . \underline{c-1189}, c-1209

                                   \post_fourth_etx_pass_hook . . . . .

. . . . . . . . . . . . . . \underline{c-1189}, c-1504

                                   \post_second_etx_pass_hook . . . . .

. . . . . . . . . . . . . . \underline{c-1189}, c-1333

                                   \post_third_etx_pass_hook . . . . . .

. . . . . . . . . . . . . . \underline{c-1189}, c-1397

                                   \postscript_code . . . . . . . . . . . f-

335, f-343, f-350, f-356, f-383, f-384 \pout_line . . . . . . . . . . 49, \underline{a-486},

f-42, f-95, f-299, f-380, f-423, f-429 \pout_lline . . . . . . . . . . . . . \underline{a-487},

f-300, f-302, f-305, f-310, f-320 \pout_llline . . . . . . . . . . . . . . . \underline{a-487}

                                   \pre_first_etx_pass_hook . . . . . . .

. . . . . . . . . . . . . . \underline{c-1189}, c-1207

                                   \pre_fourth_etx_pass_hook . . . . . .

. . . . . . . . . . . . . . \underline{c-1189}, c-1502

                                   \pre_second_etx_pass_hook . . . . . .

. . . . . . . . . . . . . . \underline{c-1189}, c-1331

\pre_third_etx_pass_hook . . . . . . .

. . . . . . . . . . . . . . \underline{c-1189}, c-1395 \prep_to . . . . . . . . . \underline{a-330}, c-501, c-502 \prev_file_list c-1693, c-1732, c-1737 \prev_mapfont . . . . . . . . . . \underline{c-1359},

c-1545, c-1572, c-1635, c-1641 \primitiveinput . a-61, a-68, a-162,

\underline{a-635}, c-9, c-343, d-58, d-255, d-461

\print@csep@list . . . . . . . . . . . \underline{a-652}

\FD@printable@ . . . . . . . . . . . . . . .

… b-93, b-117, b-129, \underline{b-131}, b-148, b-158, b-209, b-219, b-230

\FD@printable@⟨code⟩ . . . . . . . . . . . 68

\FD@printable@32 . . . . . . . . . . . b-116

\FD@printable@i . . . . . . . . . . . . \underline{b-131}

\FD@printable@ii . . . . . . . . . . . \underline{b-131}
\FD@printable@iii . . . . . . . . . . \underline{b-101}
\FD@printable@iv . . . . . . . . . . . \underline{b-101}

\FD@printable@v . . . . . . . . . . . . \underline{b-101} \FD@printable@vi . . . . . . \underline{b-101}, b-146

\FD@printable@vii . . . . . . . . . . \underline{b-131}

\FD@printable\⟨cs-name⟩ . . . . . . . . 71

\FD@printable\FD@printable@ . . \underline{b-147}
\FD@printable\macroparameter . \underline{b-221}
\FD@printable\PrintChar . . . . . \underline{b-149}
\FD@printable\str . . . . . . . . . . \underline{b-194}
\FD@printable\strint . . . . . . . . \underline{b-211}

\PrintChar . . \underline{b-1}, b-79, b-85–b-87,

b-123, b-149, b-152, b-198, b-924

\PrintVisibleChar . . . . . . . . . . . .

. . . . . b-9, b-12, b-15, b-31, \underline{b-34} \FD@priority . . . . . . . . . . . . . . . b-

223, \underline{b-245}, b-257, b-265, b-293, b-316, b-325, b-345, b-361, b-375, b-377, b-395, b-399, b-401, b-405, b-406, b-416, b-419, b-421, b-423, b-442, b-447, b-461, b-506, b-545, b-591, b-593, b-594, b-596, b-599, b-616, b-618, b-619, b-621, b-624, b-654, b-658, b-660, b-670, b-675, b-679, b-680, b-690, c-590, c-718, c-1081

\private@comma . . . . . . . . a-658, a-667

\process_csep_list . . . . . . . . . 57,

\underline{a-641}, b-977, c-421, c-428, c-613, c-615–c-617, c-619, c-620, c-681, c-685, c-1112, c-1134, c-1147, c-1735, c-1736, d-78, d-90

\process_generation . . . . . . . . . . .

…. \underline{f-2}, f-25, f-26, f-53, f-57, f-69, f-108, f-112, f-115, f-196–f-198

\process_generation_succ . . . . . . .

. . . . . . . . . . \underline{f-2}, f-60, f-88, f-197 \ProcessOptions . . . . . . . . . . . . a-235 \protect . . . . . . . . . . . . . . . . b-93,

b-135, b-139, b-141, b-215, b-252, b-263, b-339–b-343, b-356, b-358, b-453, b-454, b-493–b-495, b-498–b-500, b-532–b-534, b-537–b-539, b-552, b-598, b-623, b-663, b-684, b-685, c-30, c-74, c-76, c-78, c-142, c-364, c-584, c-585, c-587, c-716, c-1080

\protected@edef …. b-161, b-179, b-214, b-241, b-912, b-915, b-919, c-57, c-70, c-135, c-141, c-644

\protected@xdef b-263, b-288, b-317, b-338, b-354, b-376, b-402, b-451, b-492, b-531, b-597, b-622, b-662, b-676, c-120, c-583, c-715

                                       \providecommand . . . . . . . . . . . . . .

. . . . . . a-200, a-211, c-253, c-254 \ProvidesFile . . . . . . . . . . . . . c-1888

                                       \ProvidesMtxPackage . . . . . . . . . \underline{c-384}

\ProvidesPackage . a-9, a-11, a-15, a-16 \PS_font_file . . . . . \underline{f-261}, f-264, f-

274, f-373–f-375, f-413, f-414, f-417 \PS_font_name . . . . . . . . . . . . . . f-

102, \underline{f-249}, f-253, f-258, f-268, f-269, f-279, f-361, f-362, f-366, f-369, f-381, f-409–f-411, f-419, f-421

\pse-⟨etx⟩ . . . . . . . . . . . . . . . . . . 230 \psf-⟨PS font name⟩ . . . . . . . . . . 231 PSfontsuffix (string) . . . . . . . . . \underline{f-262} \push . . . . . . . . . \underline{c-1011}, c-1055, c-1070

Q \QUAD . . . . . . . . . . . . . . . . . . . . . \underline{d-552}

                                       \FD@quoted@PrintChar \underline{b-67}, b-198, b-924

R \r-⟨name⟩ . . . . . . . . . . . . . . . . . . 114 \raggedbottom . . . . . . . . . . . . . . a-247 \raw_encoding . . . . . . . . . . . . . e-7,

e-8, e-84, e-90, e-133, e-140, e-147, e-149, e-156, e-161, e-163– e-166, e-173, e-175–e-178, e-209, e-216, e-218, e-266, e-270, e-277, e-279, e-286, e-289, e-293, e-298, e-302, e-307, e-309–e-312, e-319, e-321–e-324, e-379, e-383, e-390, e-392, e-399, e-402, e-406, e-411, e-445, e-449, e-456, e-458, e-465, e-468, e-472, e-477, e-481, e-486, e-488–e-491, e-498, e-500–e-503, e-581, e-586, e-598, e-618, \underline{e-677}

\raw_font_name . . . . . d-231, d-317, d-364, d-434, d-677, d-835, d-936 \raw_shape . . . . . . . . . . \underline{e-70}, e-97,

e-104, e-114, e-121, e-132, e-139, e-141, e-146, e-151, e-162, e-172, e-174, e-188, e-193, e-201, e-208, e-210, e-215, e-220, e-230, e-236, e-247, e-431, e-568, e-572, e-580, e-585, e-597, e-600, e-617, e-620

\raw_variant . . . . . . . . . . . . . . . . .

. \underline{e-18}, e-84, e-90, e-97, e-104, e-132, e-139, e-141, e-146, e-151, e-160, e-162, e-172, e-174, e-188, e-193, e-230, e-247, e-265, e-269, e-276, e-278, e-285, e-288, e-292, e-297, e-306, e-308, e-318, e-320, e-335, e-339, e-346, e-348, e-355, e-358, e-362, e-367, e-431, e-444, e-448, e-455, e-457, e-464, e-467, e-471, e-476, e-485, e-487, e-497, e-499, e-514, e-518, e-525, e-527, e-534, e-537, e-541, e-546, e-568, e-572, e-581, e-586, e-597, e-617

\rawfont_scaling . . c-1145, \underline{c-1288},

c-1358, c-1493, c-1679, c-1682, c-1684, c-1685, c-1716, c-1717

\rboundary_do . . . . . . . . . . . . . . c-

1231, c-1247, c-1266, c-1394, c-1404 \rbserver_do . . . . . . . . . . . . . . . c-

1233, c-1246, c-1265, c-1393, c-1408 \read . . . . . . . . . . . . . . . . . . . . . a-110 \real_font . . . . . . . . . . . . . . . c-2066

\real_vertex_list . . . . . . . . . c-2068
\record_transform . . . . . . c-1725,

d-317, d-453, d-849, d-1016, \underline{f-39} \record_usage …. c-1354, c-1714, \underline{f-92}

\recordtransforms . . . . . . . . . . . . \underline{f-7}

\reencode_etx . . . . . . . . . . . \underline{f-157}, f-166, f-301, f-302, f-337–f-339, f-342, f-345, f-390–f-392, f-396

\reencodefont . . . . . . . 185, \underline{d-784},

d-816, e-149, e-218, \underline{f-47}, f-74

\ref_to_sourcefile . . . . . . . . . . . .

. . . . . . . d-94, d-95, d-101, \underline{d-156}

\reglyph_endsetglyph . d-1035, \underline{d-1069}

\reglyph_font . . . . . . . . d-995, \underline{d-1001}

\reglyph_glyphpcc . . . d-1033, \underline{d-1069}
\reglyph_redefinitions d-1019, \underline{d-1025}
\reglyph_samesize . . . d-1034, \underline{d-1069}

\reglyph_setdim . . . . . d-1027, \underline{d-1037}

\reglyph_setglyph . . . d-1032, \underline{d-1069}

\reglyph_setint . . . . . d-1026, \underline{d-1037} \reglyph_setkern …. d-1031, \underline{d-1058}

\reglyph_setscaledrawglyph . . . . .

. . . . . . . . d-1029, d-1030, \underline{d-1043} \reglyph_setstr . . . . . d-1028, \underline{d-1037} \reglyphfont . . . . . . . . 193, c-2142,

\underline{d-992}, d-1005, d-1016, \underline{f-47}, f-75 \reglyphfonts . . . . . . . . . . . . . . \underline{d-956} \relax . . . . . . . . a-77, a-146, a-235,

a-296, a-299, b-5, b-70, b-171, b-780, b-819, c-7, c-10, c-12, c-27, c-36, c-284, c-341, c-344, c-361, c-371, c-2034, c-2067, d-43, d-248, d-447, d-483, d-844, d-1011

\FD@relax@encoding@tricks . c-25, \underline{c-35}

\relpenalty . . . . . . . . . . . b-330, b-336 \remove_shape . . . . . . . . c-1903, \underline{c-1925} \rename_glyph … d-974, d-980, \underline{d-1041} \renameglyph . . . . . . . . 193, \underline{d-970},

d-1102–d-1127, d-1130–d-1139, d-1142–d-1192, d-1195–d-1197

\renameglyphweighted . . . . 194, \underline{d-970}

\repeat . . a-145, a-147, a-440, b-83,

b-894, c-1371, c-1676, d-72, d-149 \reportwarnings . . . . . . . . f-195, \underline{f-218} \RequirePackage . . . . . . . a-228, a-236 \reset_kern . . . . . . . c-487, c-491, c-496 \reset_kern_cs . . . . . . . . c-498, c-500

\reset_modifiers_hook . c-1775, \underline{c-1810}

\resetcommand . . . . . 90, \underline{b-787}, d-1208 \resetdepth . . . . . . . . . . . . . . . \underline{c-1032} \resetdim . . . . . . . . . . . . . . 90, \underline{b-787} \resetglyph . . . . . . . . . . . c-772, \underline{c-784} \resetheight . . . . . . . . . . . . . . \underline{c-1032} \resetint . . . . . . . . . . . . . . 90, \underline{b-787} \resetitalic . . . . . . . . . . . . . . \underline{c-1032} \resetkern . . . . . . . . . . . . . . . . \underline{c-484}

\resetslotcomment . . . . . . . . . . \underline{c-286}

\resetstr 90, \underline{b-787}, b-982, d-809, f-262 \resetwidth . . . . . . . . . . \underline{c-1032}, c-1089 \@restorepar . . . . . . . . . . . . . . . a-603 \result . . . . . . . . . . . . . . . . \underline{b-233},

b-274, b-276, b-301, b-303, b-304, b-371, b-385, b-387, b-431, b-433, b-434, b-476, b-478, b-515, b-517, b-568–b-571, b-573, b-578–b-581, b-583, b-643, b-645, b-705–b-707, b-709, b-727, b-791–b-793, b-795, b-798, b-938, b-939, c-92, c-470, c-498, c-572, c-822, c-825, c-988–c-990, c-998–c-1000, c-1243, c-1245, c-1253, c-1255, c-1264, c-1294, c-1417, c-1427, c-1588, c-1589, c-1599, c-1600, c-1608, c-1609, c-1617, c-1618, c-1626, c-1627, c-2023–c-2026, c-2037, c-2038, d-370, d-483, d-485, d-548, d-648, d-660–d-663, d-878, d-881, d-913, d-914, d-916, d-936, d-942, d-951, d-952, d-954, d-980, d-990

\FD@result . \underline{b-245}, b-255–b-257, b-285, b-289, b-313, b-319, b-320, b-378, b-397, b-411, b-444, b-458, b-459, b-504, b-543, b-557, b-558, b-603–b-606, b-608, b-628–b-631, b-633, b-656, b-693– b-696, b-698, c-103, c-115, c-562

\right_brace_char \underline{a-310}, c-1916, d-110 \rightarrow . . . . . . . . . . . . . . . . c-

188, c-192, c-197, c-202, c-208, c-213, c-218, c-224, c-480, c-508

\rightmargin . . . . . . . . . . . . . . . a-628 \romannumeral . . . . . . . . . . . . . . a-726 \round_wheight . . . . . . . . . . . . . . .

. . c-1980, c-1994, c-2008, c-2021

\rounded_thousandths . . . . . . . . . .

. . . . . b-646, \underline{b-703}, d-915, d-953

S

\FD@s-⟨name⟩ . . . . . . . . . . . . . . . . . 95 \s-⟨str⟩ . . . . . . . . . . . . . . . . . . . . . 90 \same_size . . . . . . . . . . c-1092, c-1095 \samesize . . . . . . . . . . . . . \underline{c-1086},

d-378, d-866, d-945, d-1034, d-1089 \saved-⟨\command⟩ . . . . . . . . . . . . 93 \FD@saved@fis a-592, a-593, a-596, a-605

\saved@slot@number  \underline{a-562}, a-572, a-586

\saved_mapfont . . . . . . . . . . . . . . .

…. \underline{c-745}, c-845, c-1329, c-1499 \saved_movert …. \underline{c-745}, c-990, c-1487 \saved_moveup … \underline{c-745}, c-1000, c-1488 \saved_pop . . . . . \underline{c-745}, c-1024, c-1490 \saved_push . . . . . \underline{c-745}, c-1015, c-1489 \saved_raw . . . . . . \underline{c-745}, c-844, c-1483 \saved_rule . . . . . . \underline{c-745}, c-950, c-1484 \saved_scale . . . . . . . \underline{c-745}, c-825,

c-837, c-919, c-923, c-1328, c-1500 \saved_special … \underline{c-745}, c-964, c-1485 \saved_warning … \underline{c-745}, c-970, c-1486 \scale . . . . . . . \underline{b-639}, c-465, c-493,

c-541, d-786–d-788, d-792, d-797, d-798, d-803, d-889, d-891, d-908–d-910, d-917, d-941, d-948

\scaled_design_size . . . . . . . . \underline{c-1289}

\scalefont . . . . . . . . . . . . 185, \underline{d-784} \second_of_six . . . . . . . . c-703, \underline{c-728} \second_of_two . . . . . . . . . . \underline{a-300},

a-400, c-2099, d-871, f-341, f-395 \@secondoftwo . . . . . . . . . . . . . . d-872 \set_kern … c-457, c-462, c-468, c-540 \set_kern_cs . . . . . . c-470, c-472, c-536 \set_kerning . . . . . . . . . . . . . . . . .

. c-514, c-520, c-526, c-529, c-533 \setcommand . . . . . . . . . . . . . . . 89,

\underline{b-744}, d-961, e-29, e-35, e-42, e-46 \setdim … 89, \underline{b-744}, c-1304, d-529,

d-537, d-859, d-902, d-1027, d-1038 \setfontdimen . . . . . . . . . \underline{c-312}, d-423 \setglyph . . . . . . . . . . . . . . . . . . .

c-334, \underline{c-763}, d-374, d-705, d-864, d-944, d-1032, d-1073, d-1207

\setint 89, \underline{b-744}, c-314, d-290, d-293, d-296, d-299, d-302, d-305, d-307, d-310, d-313, d-389, d-547, d-623, d-858, d-894, d-1026, d-1037

\setkern . . . . . . . . . . . . . . . . . . c-335, \underline{c-454}, d-325, d-327, d-655, d-707, d-863, d-942, d-1031, d-1066

\setleftboundary . . . . . . \underline{c-128}, c-1312 \setleftkerning . . . . . . . . . . . . \underline{c-511}

                                       \setleftrightkerning . . . . . . . . \underline{c-511}

\setlength . . . . . . . . . . . . . a-615,

a-618, a-620, a-623, a-625–a-629 \setnotglyph . . . . . . . . . . \underline{c-864}, d-361 \setrawglyph \underline{c-815}, c-899, d-359, d-675

                                       \setrightboundary . . . . . . . . . . \underline{c-151}
                                       \setrightkerning . . . . . . . . . . . \underline{c-511}

                                       \setscalednotglyph . . c-333, \underline{c-864},

d-709, d-862, d-934, d-1030, d-1050

                                       \setscaledrawglyph . . . . . . . c-329,

\underline{c-815}, c-900, d-708, d-717, d-861, d-932, d-1029, d-1052, d-1206

\setslot . . . . . . . . . . \underline{c-51}, c-331, d-19 \setslotcomment . . . . . . . . . . . . \underline{c-286}

                                       \setsomething_global . . . . . . . . . .

. . . . . . . \underline{b-742}, b-752, b-759, b-764, b-790, b-802, b-805, b-807, b-852–b-855, b-862, b-866, b-873, b-875, b-895, b-941, b-951, b-976, c-1694, c-1702, c-1706, c-1709, c-1720, c-1767, d-229, d-422, d-687, d-729, d-958

\setstr …. 89, \underline{b-744}, d-82, d-209,

d-467, d-860, d-905, d-1028, d-1039

                                       \SetStringVariable . . . . . \underline{b-910}, b-990
                                       \SEVENBITSAFEFLAG . . . . . . . . . . \underline{d-497}

\showbranches . . . . . . . . . . . . . . \underline{a-554} \SHRINK . . . . . . . . . . . . . . . . . . . \underline{d-552} \side_bearings . \underline{c-1300}, c-1322, c-1540 \FD@simple@int . . . . . . . . b-215, \underline{b-349} \sixt@@n . . . . . . . . . . . . . . a-86, a-

110, a-111, a-443, a-448, a-461, a-477, a-711, a-713, b-17, b-19

\sixth_of_six . . . . . . . . . c-726, \underline{c-728} \SKIP . . . . . . . . . . . . . . . . . . . . . \underline{d-643} \skip . . . . . . . . . . . . . . . . . . . . . a-121

\skip@mtx@preamble . . . . . c-359, c-370

\skipslots . . . . . . . . . . . . . . . . . \underline{c-90} \SLANT . . . . . . . . . . . . . . . . . . . . \underline{d-552} \slant_factor . \underline{f-157}, f-163, f-164, f-

309, f-311, f-355, f-357, f-404, f-406 \SlantAmount . e-295, e-365, e-408, \underline{e-682} \slanteditalcorr . . . . . . \underline{d-381}, d-392 \slantfont 185, \underline{d-784}, e-295, e-365, e-408 \slot@comment . . . . . . . . . . c-80, \underline{c-286}

\slot@comment@false . . . . c-295, c-303
\slot@comment@true . . . . . . . . . . c-298
\FD@slot@expression . . . . . . . . . . .

. . . . . . . . c-66, c-75, \underline{c-90}, c-163 \slot@font . . . . . . . . . . . . . . . . \underline{c-286} FD@slot@known@ switch . . . . . . . . . \underline{c-90}

\FD@slot@known@false . . . . . . . . . .

. . . . . . . \underline{c-90}, c-97, c-108, c-124

\FD@slot@known@true . . . . . . . . . . .

…. c-23, \underline{c-90}, c-96, c-98, c-104 \slot@name \underline{c-55}, c-135, c-136, c-138,

c-140, c-142, c-187, c-191, c-193, c-196, c-201, c-203, c-207, c-209, c-212, c-217, c-219, c-223, c-225

\slot@number . . . . . . . a-572, a-586, c-22, c-44, c-64, c-66, c-72, c-75, c-83, \underline{c-90}, c-161, c-163, c-167, c-309

\slot_name … \underline{c-51}, c-129, c-1219, c-1223, c-1226, c-1337, c-1338, c-1413, c-1436, c-1457, c-1462, c-1494, c-1508, c-1511, c-1516, c-1518, c-1519, c-1537, c-1538, c-1548, c-1551, c-1558, c-1561, c-1563, c-1564, c-1566, c-1568, c-1570, c-1573, c-1581, d-75, d-425, d-426, d-520, d-521, d-813

\slot_number . . . . . . . . . . . . . . . c-6, c-53, \underline{c-90}, c-154, c-1220, c-1226, c-1230, c-1232, c-1382, c-1457, c-1512, c-1517, c-1562, d-74, d-75, d-195, d-425, d-520, d-813

\slotexample . . . . . . . . . . . . . . . \underline{c-286} \slots-⟨glyph⟩ . . . . . . . . . . . . 135, 194

\source_font_name . . . . . d-232, d-318
\source_font_TeX_name . . . f-101, f-

105, \underline{f-248}, f-253, f-258, f-264, f-300 \SPACE . . . . . . . . . . . . . . . . . . . . \underline{d-552} \space … a-17, a-141, a-347, a-368,

a-370, a-371, a-423, a-425, a-427, a-446, a-487, a-489, a-593, a-731, a-754, a-768, a-818, a-821, a-823, a-825–a-827, a-829, c-30, c-64, c-78, c-161, c-364, c-1166, c-1173, c-1312, c-1350, c-1367, c-1418, c-1422, c-1427, c-1517, c-1562, c-1591, c-1602, c-1611, c-1620, c-1629, c-1646, c-1681, c-1788, c-1790, c-1892, c-1893, c-1922, c-1936, c-1952, d-52, d-93, d-110, d-112, d-113, d-116, d-118, d-120, d-123, d-125, d-127, d-137, d-143, d-153, d-174, d-186, d-721, e-138, e-159, e-207, e-275, e-287, e-305, e-345, e-357, e-388, e-400, e-454, e-466, e-484, e-524, e-536, e-594, f-79, f-80, f-130, f-141, f-151, f-343, f-346, f-351, f-352, f-357, f-358, f-381, f-384, f-400, f-405, f-424

\spacefactor . . . . . . . . . . . . . . . . .

b-172, b-175, b-176, b-188, b-190

\spaceskip . . . . . . . . . . . . . . . . c-244 FD@spec@ switch . . . . . . . . . . . . . \underline{a-195} \FD@spec@false . . . . . . . . \underline{a-195}, a-197 \FD@spec@true . . . . . . . . . \underline{a-195}, a-198 \special . . . . . . . . . . . . . a-202, a-207 specification option . . . . . . . . . \underline{a-195} \specifypsfont . . . . . . . . . . . 17, \underline{f-243} \@sptoken . . . . . . . . . . . . . . . . . b-106 \start_subs_at . . . . . . . . . . . . c-2096 \STOP . . . . . . . . . . . . . . . . . . . . . \underline{d-643} \storemapdata . . . . . . . . . . . . 220,

c-1711, c-1712, \underline{f-23}, f-42, f-44 \str . . . . . . . . . . . . . . . . 90, \underline{b-165},

\underline{b-194}, b-776, b-815, c-1308, c-1785, d-103, d-128, d-130, d-136, d-137, d-158, d-211, d-215, d-737, d-815, d-816, f-264, f-430

\STRETCH . . . . . . . . . . . . . . . . . . \underline{d-552} \FD@string@func . . \underline{b-169}, b-194, b-211 strings:

PSfontsuffix . . . . . . . . . . . . \underline{f-262} TFMfileprefix . . . . . . . . . . . \underline{f-428}

\strint . . . . . . . . . . . 90, \underline{b-165}, \underline{b-211} \strip_spaces . . . . . . . . . . . . . . d-397 \SUB . . . . . . . . . . . . . . . . . . . . . . \underline{d-582} \sub . . . . . . \underline{b-297}, c-1033, c-1096, d-382 \sub_suffix c-1982–c-1984, c-1996–c-

1998, c-2010–c-2012, c-2031, c-2032 \SUBDROP . . . . . . . . . . . . . . . . . . \underline{d-598}

\FD@subexpression . . . . . . . . . . . .

\underline{b-328}, b-341, b-498, b-537, b-552

\subs_do_arc . . . . . . . . . c-2064, c-2070 \subs_font . . . . . . . . . . c-2067, c-2080 \subs_series . . . . . . . . . c-2080, c-2097 \subs_shape . . . . . . . . . . c-2081, c-2098

\subs_vertex_list . . . . c-2063, c-2078

\subst_series . . . . . . . . . . . . . . c-

1948, c-1949, c-1951, c-1956, c-1957 \subst_shape . . . . . . . . . . . . . . . c-

1932, c-1933, c-1935, c-1940, c-1941

\substitute_series . . . . c-1930, \underline{c-1945}
\substitute_shape . . . . c-1901, \underline{c-1928}

\substitutenoisy \underline{c-1961}, c-1975, \underline{c-2043}

\substituteseries . . . . . . \underline{c-1979},

c-2044, c-2048, c-2053–c-2058

\substituteseriesshape . . . . . \underline{c-1979}
\substituteshape . . . . . . . \underline{c-1979},

c-2045, c-2049, c-2059–c-2061

\substitutesilent . . . . \underline{c-1961}, c-

1969–c-1974, c-1976, c-1977, \underline{c-2043} \SUP . . . . . . . . . . . . . . . . . . . . . . \underline{d-582} \SUPDROP . . . . . . . . . . . . . . . . . . \underline{d-598} \supereject . a-149, a-150, a-154, a-156 \FD@swap@two . . . . . . . . . . a-241, a-374 \swap_two … \underline{a-300}, a-373, f-212, f-278 switches:

_a_. . . . . . . . . . . . . . . . . . . . \underline{a-183} direct . . . . . . . . . . . . . . . . . \underline{c-325} FD@evaluate@ . . . . . . . . . . . . \underline{b-245}

_extensions_warning_. . . . . \underline{a-339}
_including_map_. . . . . . . . \underline{c-1150}
@mtxpackage@headed@ . . . . . . \underline{c-384}

FD@slot@known@ . . . . . . . . . . . \underline{c-90} FD@spec@ . . . . . . . . . . . . . . . \underline{a-195} FD@tight@ . . . . . . . . . . . . . . . \underline{a-611}

warningspecials . . . . . . . . \underline{c-1648}

T

\t . . . . . . . . . . . . . . . . . . . . . . . a-703 \temp_command . . . . . . . . . . . . . . c-

1981, c-1983, c-1995, c-1997, c-2009, c-2011, c-2031, c-2033–c-2035

\temp_prefix . . . . . . . . . . . . \underline{a-491},

d-31, d-230, d-435, d-834, d-1002 \@tempa . . . . . . a-201, a-203, a-206,

a-213, a-221, a-224, b-77, b-79, b-81, b-161, b-162, b-179, b-180, b-182, b-183, b-196, b-199, b-202, b-206, b-213–b-215, b-217, b-241, b-242, b-261, b-263, b-284, b-288, b-312, b-317, b-353, b-356, b-358, b-396, b-403, b-443, b-452, b-655, b-668, b-677, b-912, b-914–b-916, b-925, b-989, b-990, c-437–c-439, c-444, c-445, c-581, c-585, c-643– c-645, c-647, c-649, c-714, c-716

\@tempb b-919, b-921, b-925, c-582, c-587 \@tempcnta …. b-16, b-20, b-22, b-23 \@tempcntb . . . . . . . . . b-18, b-21, b-23 \@tempdima . . . . . . . . . . . . . . . . a-191 \@tempdimb . . . . . . . . . . . . . . . . a-192 \tempfileprefix . . . . . . . . . . . . \underline{a-491} \@tempswafalse …. b-92, c-443, c-562 \@tempswatrue . . . . . . . . . . . b-207,

b-218, b-229, b-917, c-445, c-561

\test_UseMtxPkg_arguments c-412, c-413

\TeX . . . . . . . . . . . . a-358, a-369, a-427 \TeX_font_name . . . . . . . f-52, f-80,

f-87, f-130, f-141, f-151, \underline{f-247}, f-299, f-381, f-424, f-429, f-431

\TeX_terminal \underline{a-427}, a-436, a-445, a-481 \text . b-222, b-356, b-368, c-585, c-587

\textasciicircum . . . . . . . . . . . . b-49

\textasciitilde . . . . . . . . . . . . . b-55 \textbackslash . . . . . . . . . . . . . . b-49 \textbar . . . . . . . . . . . . . . . . . . . b-55 \textbf . . . . . . . . . . . . . . a-244, a-246 \textbraceleft . . . . . . . . . . . . . . b-55 \textbraceright . . . . . . . . . . . . . b-55 \textcolor . . . . . . . . . . . . . . . . a-224

\_textcomp_false . . . . . . . . . . . e-662

\_textcomp_true … e-661, e-663, e-664 \textdollar . . . . . . . . . . . . . . . . . b-39 \textgreater . . . . . . . . . . . . . . . . b-43 \textit a-566, a-570, a-578, a-583, a-605 \textless . . . . . . . . . . . . . . . . . . b-43 \textquotedbl . . . . . . . . . . . . . . . b-39 \textquoteleft . . . . . . . . . . . . . . b-51 \textquoteright . . . . . . . . . . . . . b-40 \textrm . . . . . . . . . . . . . . . . . . . b-228 \textsc . . . . . . . . . . . . . . . . . . . c-254 \textsf . . . . . . a-38, c-399, c-403, c-406 \texttt . . . . . . . . . . . a-206, a-224,

a-249, b-263, b-880, b-881, c-253 \textunderscore . . . . . . . . . . . . . b-49 \textunicode . . . . . . . . . . . . . . . \underline{c-240}

\textvisiblespace . . . . . . . b-39, \underline{b-58}

\Tf-⟨font⟩ . . . . . . . . . . . . . . . . . . 221 TFMfileprefix (string) . . . . . . . . \underline{f-428} \theangle . . . . . . . d-384, d-385, d-387 \then . . . . . . . . . . . . . . . . . . . . . \underline{a-494} \thinspace . . . . . . . . . . . . . . . . . a-40 \third_of_six . . . . . . . . . c-704, \underline{c-728} \thr@@ . . . . . . . . . . . . . . . . . . . . a-

85, a-590, a-604, b-405, b-599, b-624, b-660, b-664, b-679, f-196

\tidying_up_hook . . . . . \underline{c-1189}, c-1669 FD@tight@ switch . . . . . . . . . . . . \underline{a-611}

\FD@tight@false . . . . . . . . . . . . . .

. . \underline{a-611}, c-84, c-145, c-812, c-813 \FD@tight@true . . . . . . . . . . . . . . .

. . \underline{a-611}, c-61, c-139, c-779, c-799 \times . . . . . . . . . . . . . . . . . . . . c-639 \toks . . . . . . . . . . . . . . . . . a-95, a-109 \toks@ . . . . . . . . . . . . . . b-90, b-94,

b-97, b-99, b-116, b-122, b-126, b-151, b-155, b-205, b-217, b-228, b-485, b-497, b-524, b-536, b-551, b-916, c-642, c-648, c-651

\toks_a . . . . . . . . . . . . . . . . . . c-2082 \toksdef . . . . . . . . . . . . . . . . . . a-109 \top_of_pl_hook . c-1165, \underline{c-1189}, d-689 \topsep . . . . . . . . . . . . . . a-615, a-620 \touch_file . . . . . c-2139, c-2140, c-

2142, c-2146, c-2149, c-2151, \underline{c-2153}

\tracinglostchars . . . . . . . . . . \underline{a-833}
\transform_record_file . . . . . . . .

. . . . . . . \underline{f-7}, f-41, f-42, f-94, f-95 \transformfont . . . . . . . . . . . 185,

c-2138, \underline{d-728}, d-831, e-138, e-145, e-207, e-214, e-275, e-291, e-345, e-361, e-388, e-404, e-454, e-470, e-524, e-540, \underline{f-47}, f-73

trig package . . . . . . . . . . . . . . . . . 5, 41 \tt . . . . . . . . . . . . . . . . . . . . . . . d-52 \ttfamily . . . . . . . . . . . . b-187, b-848 \tw@ . . . . . . . . . . . . . a-84, a-564, b-

59, b-62, b-570, b-573, b-580, b-583, b-605, b-608, b-630, b-633, b-698, b-709, b-716, b-722, c-1081

\two_thousand . . . . . . . . . \underline{a-185}, b-719 \typeout . . . . . . . . . . . . . . . . . . a-231 \typeset@glyph . . . . . . . . . . . . . c-

187, c-188, c-191, c-193, c-196, c-198, c-201, c-204, c-207, c-209, c-212, c-214, c-217, c-220, c-223, c-226, c-235, c-237, c-280–c-283, c-479, c-507, c-550, c-551, c-553, c-554, c-556, c-557, c-607, \underline{c-700}, c-780, c-800, c-852, c-857, c-893, c-903, c-938, c-1104, c-1108, c-1281

\FD@typeset@string . . \underline{b-178}, b-368,

c-68, c-78, c-140, c-142, c-187, c-191, c-193, c-196, c-201, c-203, c-207, c-209, c-212, c-217, c-219, c-223, c-225, c-585, c-587, c-656

\FD@typeset@string@set . . . c-639,

\underline{c-641}, c-667, c-670, c-673, c-1122

\FD@typeset@string@set@ . . . . . \underline{c-641}
\TypesetIntegerExpression . . . . . .

. . . . . . . 35, \underline{b-239}, b-738, b-772, b-773, b-811, b-812, b-839, c-321, c-480, c-508, c-853, c-858, c-958, c-959, c-1008, c-1009, c-1040, c-1043, c-1046, c-1049, c-1282

\TypesetList . . . . . \underline{a-255}, a-413, c-654

\TypesetStringExpression . . . . . . .

…. 35, \underline{b-178}, b-776, b-777, b-781, b-815, b-816, b-820, b-842, b-845, c-165, c-320, c-700, c-854, c-859, c-978, c-980, c-1870

U

\uccode . . . . . . . . . . a-136, b-76, f-286 \undefined . . . . . . . . . . . . . . . . . . a-9 \@undefined . . . . . . . . . . . . . . . . a-214

\undefined@command . . . . . . . . . . b-783
\undefined_command . . . a-76, a-153,

a-342, a-361, b-763, b-830, b-855 \Unicode 104, \underline{c-240}, c-261, d-166, d-192 \unknown_str . . . . . . . . . . . . . . . . .

232, \underline{f-245}, f-246–f-249, f-261, f-268, f-317, f-361, f-373, f-409, f-413

\unless . . . . . . . . . . . . . . . . . . . a-513 \unsetcommand . . . . . . . . . . . 90, \underline{b-851} \unsetdim . . . . . . . . . . . . . . 90, \underline{b-851} \unsetglyph . . . . . . . . . . . . . . . . \underline{c-901} \unsetint … 90, \underline{b-851}, c-1811, c-1837 \unsetkerns . . . . . . . . . . . . . . . . \underline{c-610}

\unsetslotcomment . . . . . . . . . . \underline{c-286}

\unsetstr . . . . . . . . . . . . . . . . 90,

\underline{b-851}, c-1807, d-730, d-731, d-781

\update_do_arc_list . . . . . . . . . . .

. . c-1990, c-2004, c-2018, c-2029 \uppercase . . . . . . . . . . . a-136, a-

201, a-213, b-77, c-253, d-171, f-252 \uprightitalcorr . d-234, \underline{d-381}, d-394 \usedas . . . . . . . . . . . . . . . . 104, \underline{c-229} \useexamplefont . . . . . . . . . . . . \underline{c-286} \usemtxpackage . . . . . . . . . . . . . \underline{c-411} \usepackage . . . . . . . . . . . . . . . . . d-46 \UseTan . . . . . . . . . . . . . . . . . . . d-387

V

\vadjust . . . . . . . . . . . . . . . . . . a-244 \varbot …. 108, \underline{c-270}, c-1480, c-1620 \VARCHAR . . . . . . . . . . . . . . . . . . \underline{d-502} \varchar . . . . . . . . . 104, \underline{c-270}, c-1476 \varepsilon . . . . . . . . . . . . . . . . a-358 \varmid …. 108, \underline{c-270}, c-1479, c-1611 \varrep …. 108, \underline{c-270}, c-1481, c-1629 \vartop …. 108, \underline{c-270}, c-1478, c-1602 \vbox . . . . . . . . . . . . . . . . . . . . . . b-62 \vfill . . . . . . . . . . . . . . . a-150, a-156 \vpl_call . . . . . c-1131, c-1142, c-1171 \vpl_extension . . . . . . . . . . . . . c-

1127, c-1138, c-1164, c-1169, c-1186 \vpl_Font . . . . . c-1130, c-1141, c-1187 \vpl_font c-1129, c-1140, c-1166, c-1173 \vpl_int . . . . . . . . . . . . . . \underline{c-1298},

c-1319, c-1350, c-1367, c-1427, c-1457, c-1517, c-1562, c-1636

\vpl_kern . . . . . . . . . . . c-1392, \underline{c-1440} \vpl_kern_do . . . . . . . . . c-1435, \underline{c-1449} \vpl_kerning … c-1388, c-1390, \underline{c-1434} \vpl_ligature . . . . . . . . c-1391, \underline{c-1415} \vpl_liglabel . . . . . . . . c-1383, c-

1389, c-1426, c-1450, \underline{c-1456}, c-1468 \vpl_ligstop . . . . . . . . . . . . . . . . .

. . c-1437, c-1459, c-1464, \underline{c-1467} \vpl_mapfont . . . . . . . . . c-1329, \underline{c-1345} \vpl_movert . . . . . . . . . . c-1487, \underline{c-1658} \vpl_moveup . . . . . . . . . . c-1488, \underline{c-1658} \vpl_nextlarger . . . . . . c-1475, \underline{c-1586} \vpl_pop . . . . . . . . . . . . c-1490, \underline{c-1666} \vpl_push . . . . . . . . . . . c-1489, \underline{c-1666} \vpl_raw . . . . . . . . . . . . c-1483, \underline{c-1633}

\vpl_rboundary_do . . . . c-1394, \underline{c-1402}

\vpl_rbserver_do . . . . . c-1393, \underline{c-1402} \vpl_real . . . . . . \underline{c-1298}, c-1306, c-

1352, c-1353, c-1522, c-1550, c-1552, c-1565, c-1567, c-1569, c-1571, c-1646, c-1660, c-1664, c-1685

\vpl_rule . . . . . . . . . . . c-1484, \underline{c-1643} \vpl_scale …. c-1328, \underline{c-1341}, c-1500 \vpl_special . . . . . . . . . c-1485, \underline{c-1648} \vpl_title …. c-1128, c-1139, c-1166 \vpl_to_vf …. c-1132, c-1143, c-1175 \vpl_varbot . . . . . . . . . . c-1480, \underline{c-1615} \vpl_varchar . . . . . . . . . c-1476, \underline{c-1595} \vpl_varmid . . . . . . . . . . c-1479, \underline{c-1606} \vpl_varrep . . . . . . . . . . c-1481, \underline{c-1624} \vpl_vartop . . . . . . . . . . c-1478, \underline{c-1597} \vpl_warning . . . . . . . . . c-1486, \underline{c-1648} \vrule . . . . . . . . . . . . . . . . . b-61, b-63 \VTITLE . . . . . . . . . . . . . . . . . . . \underline{d-506}

W

\warn_uncertain_data . . . . \underline{f-225}, f-271
\warn_undecided_data . . . . . . . . . .

. . \underline{f-225}, f-321, f-363, f-376, f-415

\warn_unknown_source . . . . f-153, \underline{f-225}

\warning_do . . . . . . . . . . . . \underline{f-202}, f-220 \warnings_list . . . . . . . . . . . . . . .

. . \underline{f-201}, f-211, f-212, f-221, f-223 warningspecials switch . . . . . . \underline{c-1648}

\warningspecialsfalse . . . . . . \underline{c-1648}
\warningspecialstrue . . \underline{c-1648}, c-1657

\width . . . . . . . . . . . . . . . \underline{c-701}, c-1564 \@width . . . . . . . . . . . . . . . . . . . . b-62

\width_ints_list . . . . . . . . . . . \underline{d-873}

\wlog . . . . . . a-102, a-117, a-125, a-446 \write . . . . . . a-25–a-27, a-29, a-30,

a-63, a-70, a-102, a-111, a-164, a-420, a-422, a-446, a-461, a-477, a-486, a-736, a-742, a-748, a-762, a-767, c-1312, c-1412, c-1418, c-1422, c-1591, c-1602, c-1611, c-1620, c-1629, c-1654, d-645, e-50, e-52, e-54, e-80, e-137, e-158, e-206, e-274, e-283, e-304, e-344, e-353, e-387, e-396, e-453, e-462, e-483, e-523, e-532, e-593

\write_cmap_body . . . . . . \underline{d-163}, d-217 \write_pl_glyph . . . . . . . d-671, \underline{d-673} \write_pl_krn . . . . . . . . . . . . . . \underline{d-646}

                                       \wrn_rboundary_do . . . . . . . . . \underline{c-1402}

X \x@cs . . . . . . . . . . . . . . . . . . . . . a-

240, b-81, c-38, c-186, c-190, c-195, c-200, c-206, c-211, c-216, c-222, c-373, c-393, c-438, c-445

\x@relax . . . . . . . . \underline{a-299}, a-558, a-659, b-252, b-254, b-255, b-465, c-27, c-36, c-361, c-371, c-435, c-436

\x_cs . . . . . . . . . . . . . . . . . . . . . \underline{a-294} \x_relax . . . . . . . . . . . . . . . . . . \underline{a-294}

\x_resetint . . . . . 90, b-746, \underline{b-787},

b-936, b-964, c-1226, c-1839, d-233, d-390, d-732–d-734, d-786– d-788, d-792, d-797, d-798, d-802

\x_setint . . . . . . . . . . . . . . . . 90, \underline{b-744}, c-1232, c-1311, c-1321, c-1323, d-235, d-540, d-959, d-960

\x_setstr . . . . . . . . . . . 90, \underline{b-744},

c-1307, d-748, d-754, d-758, d-764 \x_width . . . . . . . . . . . . . . . d-337,

d-345, d-355, d-367, d-406, d-407 \xdef . . a-418, a-468, b-256, c-1349,

c-1710, c-1730, c-1743, c-1752, c-1758, c-2033, f-59, f-114, f-211

\XHEIGHT . . . . . . . . . . . . . . . . . . \underline{d-552}

\xscale_factor …. \underline{f-157}, f-162, f-

304, f-306, f-349, f-351, f-399, f-401 \xscalefont … 185, \underline{d-784}, e-474, e-544 \@xxxii . . . . . . . . . . . b-6, b-121, b-150

Y \year . . . . . . . . . . . . . . . . c-1890, d-97 \yscalefont . . . . . . . . . . . . 185, \underline{d-784}

Z \z@ a-139, a-258, a-275, a-284, a-287,

a-577, a-616, a-617, a-623, a-627–a-629, a-671, b-70, b-76, b-224, b-257, b-258, b-262, b-293, b-325, b-362, b-487, b-526, c-44, c-107, c-1082, c-1523, c-1526, c-1529, c-1679, c-2026, d-67, d-139, d-142, d-822, d-1049, f-

158, f-290, f-291, f-309, f-355, f-404

\z@skip . . . . . . . . . a-615, a-625, a-626

\zap@space . . . . . . . . . . . b-140, b-143

Change History

v 1.6

General:

fontinst.rc search order changed (Thierry Bouche). . . . . . . . . . . . . . . . . . 38 AFM commands fixed, to get fontdimens comparable to EC fonts. (Thierry Bouche) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

\fromany: Search order changed to PL before AFM. (SPQR) The code wasn’t in

\fromany back then, though. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 v 1.800

General:

\textcompfamily integrated into \latinfamily. (UV) . . . . . . . . . . . . . . . 202

  fontinst.sty and fontdoc.sty now generated from fontinst.dtx. (UV) . 35

v 1.900

_including_map_switch: New switch that can inhibit writing of VPL-specific

properties. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 General:

\boundary_char count register removed. Right boundary slot number is now stored in the %boundarychar integer instead. (LH) . . . . . . . . . . . . . . . . . 138 New method of storing slot assignments. (LH) . . . . . . . . . . . . . . . . . . . . . 134 Added compability code for the old interface for boundary ligatures and kerns. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 Method of computing italic corrections changed to using an integer expression. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 fontinst.dtx split into several source files. (LH) . . . . . . . . . . . . . . . . . . . 35 Replaced \relax by \x_relax. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

  Replaced internal \setint, \resetint, and \setstr by \x_setint,

\x_resetint, and \x_setstr respectively, to make the public versions possible to turn off. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

\afm_length: Macro added, other macros modified to use it. (LH) . . . . . . . . 170 \begincomment: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 \encoding: Changed group in fontdoc to \begingroup type. (LH) . . . . . . . . 100 \endcomment: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 \endencoding: Made it outer. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 \endmetrics: Made it outer. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 \for, \endfor: Commands added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 \glyph: Avoids scaling by 1000. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 \gobble_if: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 \IFKW-scaled: Changed \setint to \resetint. (LH) . . . . . . . . . . . . . . . . . 154 \ifnumber: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 \input_metrics: Use \process_csep_list for file-list. (LH) . . . . . . . . . . . . 150

\make_header:

Made integer expression \div a dimen \divide. (LH) . . . . . . . . . . . . . . . 138 Removed test for no letterspacing. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 138

\MAP: VPL-specific properties added to those which are ignored by \pltomtx.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 \nextslot, \skipslots: Made changes of \slot@number global. (LH) . . . . . 103 \offcommand, \oncommand: Commands added. (LH) . . . . . . . . . . . . . . . . . . . 93

\pre_first_etx_pass_hook, \pre_second_etx_pass_hook,
   \pre_third_etx_pass_hook, \pre_fourth_etx_pass_hook,
   \post_first_etx_pass_hook, \post_second_etx_pass_hook,
   \post_third_etx_pass_hook, \post_fourth_etx_pass_hook,

\tidying_up_hook: ETX-to-VPL hooks added. (LH) . . . . . . . . . . . . . . . 134

\vpl_kern:

Macro modified to avoid duplicate kerns. (LH) . . . . . . . . . . . . . . . . . . . . 142 Much of the code from \vpl_kern has been moved to \vpl_kern_do. (LH) 142

v 1.901 _a_switch: Temporary switch added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 41 General:

Definition of transformable metric file added. (LH) . . . . . . . . . . . . . . . . . 184 Pooled output file allocation added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 49

\afm_font_name: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 \foreach: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

\gobble_setslot: Made \gobble_setslot a \long macro. (LH) . . . . . . . . . 145

\open_out: \xdef instead of \def on \out_filename. (LH) . . . . . . . . . . . . . . 49 \rounded_thousandths: Macro added. \scale changed to use it. (LH) . . . . . 88

v 1.902

General:

Fixed some silly markup. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Collected the material in Section 15 and moved it to ficonv.dtx. (LH) . . 164 Moved Section 16 to ficonv.dtx. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Moved Section 8 to fibasics.dtx. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 45

\fromplgivenetx: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 186 \fromvpl, \fromvplgivenetx: Commands added. (LH) . . . . . . . . . . . . . . . . 187 \generalpltomtx: Command added, removed \pltomtxgivenetx. (LH) …. 175

v 1.903

General: Introduced the \⟨letter⟩_macro temporary variables, replaced

\temp_command. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

\fromany:

Command added. (LH) Based on a suggestion by Vladimir Volovich. . . . . 187 Added behaviour for AFM not found case. (LH) . . . . . . . . . . . . . . . . . . . 187

\glyph_maxhpos: Variable added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 \glyphbboxright: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 \make_factor: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 \movert: Added update of \glyph_maxhpos. (LH) . . . . . . . . . . . . . . . . . . . 128 \pop: Added update of \glyph_maxhpos. (LH) . . . . . . . . . . . . . . . . . . . . . . 129 \reglyphfont: Using \fromany for locating font. (LH) . . . . . . . . . . . . . . . . 196 \samesize: Added behaviour for nonexistent glyph (based on a suggestion from

Hilmar Schlegel) and fixed typo in fontdoc. (LH) . . . . . . . . . . . . . . . . . . 131 \transformfont: Added behaviour for the case source file not found. (LH) . 186

v 1.904

General:

Font transformation recordings moved to fimapgen.dtx, so that the interface will be specified in a single place. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 201 Completed rudimentary map file fragment generator, made it part of finstmsc.sty. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220

\fromafm: Added call of \record_transform. (LH) . . . . . . . . . . . . . . . . . . . 186 \fromany: Added search for VPL file and calls to \record_transform. (LH) 187 \frompl: Added call of \record_transform. (LH) . . . . . . . . . . . . . . . . . . . 186 \fromplgivenetx: Added call of \record_transform. (LH) . . . . . . . . . . . . . 186 \fromvpl, \fromvplgivenetx: Commands removed. (LH) . . . . . . . . . . . . . . 187 \input_mtx_file: Now using \fromany to make an MTX file when necessary.

Furthermore testing for empty argument using \ifx rather than \if. (LH) 152 \installrawfont: Added \record_usage. (LH) . . . . . . . . . . . . . . . . . . . . . 149 \pout_lline: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 \pout_llline: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 \reglyphfont: Added \record_transform. (LH) . . . . . . . . . . . . . . . . . . . . 196 \vpl_mapfont: Added \record_usage. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 139

v 1.905 General: Different config file for finstmsc.sty. (LH) . . . . . . . . . . . . . . . . . . 38 \DESIGNUNITS: Error message added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 178

v 1.906

General:

Adaptation of L^{A}TEX’s message system completed. (LH) . . . . . . . . . . . . . . . 61 Reglyphing settings files added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

\no_kerning:

Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Macro thoroughly rewritten. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

\noleftkerning: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 \noleftrightkerning: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 119 \norightkerning: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

v 1.907 \end_assign_slot: Slots are not assigned to glyphs that do not exist. (LH) . 135 \pop: Removed the \edef. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 \push: Removed the \edef. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

v 1.908

General: Glyph commands avoid \edefing old contents of \glyph_map_commands

and \glyph_map_fonts. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 \out_lline: \edef, to save macro expansions later. (LH) . . . . . . . . . . . . . . . 49 \out_llline: \edef and don’t use \out_lline, to save macro expansions later.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 \pout_lline: \edef, to save macro expansions later. (LH) . . . . . . . . . . . . . . 51 \pout_llline: \edef and don’t use \pout_lline, to save macro expansions later.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 v 1.909

General: System for documenting both branches of if statements in ETX and

MTX files added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

\Aheading:

Use \addvspace to make space above. (LH) . . . . . . . . . . . . . . . . . . . . . . . 43 Insert a \penalty for pagebreaking after an \Aheading. (LH) . . . . . . . . . . . 43

\fontinsterror: New name for \fontinst_error. (LH) . . . . . . . . . . . . . . . . 62 \fontinstinfo: New name for \fontinst_info. (LH) . . . . . . . . . . . . . . . . . . 62

\fontinstwarning: New name for \fontinst_warning. (LH) . . . . . . . . . . . . 62
\fontinstwarningnoline: New name for \fontinst_warning_no_line. (LH) 62

\ifiscommand: Changed one fontdoc definition of \ifisglyph to a definition of

\ifiscommand, which was missing from fontdoc. . . . . . . . . . . . . . . . . . . . . 93 \int: fontdoc implementation changed to using \typeset@integer. (LH) …. 80 \kerning: A use of #1 where it should have been #2 was corrected. (LH) . . 117 \messagebreak: New name for \message_break. (LH) . . . . . . . . . . . . . . . . . . 61 \priority: Changed condition for \ifnum, so that expressions with equal priority

will not get bracketed when nested. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 89 \resetcommand: Since fontdoc adds some grouping, \resetcommand must set its

argument globally there. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 \setcommand: Since fontdoc adds some grouping, \setcommand must set its argu-

ment globally there. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

\setleftboundary, \endsetleftboundary: fontdoc definition added. (LH) . . 103

\setrightboundary: doc definition added. (LH) . . . . . . . . . . . . . . . . . . . . . 104 \strint: Change to stop it from gobbling a following space if the integer is stored

in a macro. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 \typeset@glyph: Macro added, and most commands that print a glyph name

changed to use this macro. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 v 1.910

General:

Catcodes restored after reading .rc file. (LH&UV) . . . . . . . . . . . . . . . . . . 38 Make \everyjob code optional, and simplify it a little. (LH&UV) . . . . . . . 40 Changed the way slot numbers are stored in \slots-⟨glyph⟩ control sequences. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

\do_new_slot: Macro removed. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 \generalpltomtx: Made this command the standard one, which \pltomtx calls.

(UV&LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 \get_slot_num: Removed redefinition of \do to \gobble_one from temporary

definition of \do, since a \slots- list usually contains only one or two elements anyway. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

v 1.911

General:

\storemapdata commands are also written to metric files when they are generated. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Definitions of metric file commands added to ⟨misc⟩. (LH) . . . . . . . . . . . . 111 Flag for that source font wasn’t found changed to afm-name. transform-source string completely removed. (LH) . . . . . . . . . . . . . . . 185 Recording of transformations moved to the macros that actually write the MTX files. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Definitions of encoding file commands added to ⟨misc⟩. (LH) . . . . . . . . . . 100 ETX to ENC converter added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 Comment commands included in finstmsc.sty. (LH) . . . . . . . . . . . . . . . . 99

\afm_font_name: Macro removed, since no longer needed. (LH) . . . . . . . . . . 172 \afmtomtx: Changed setting of \raw_font_name to \edef and added setting of

\source_font_name. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170

\calculate_it_slant: Stripping off the space in \afm-ItalicAngle. (LH) . . 174

\fromafm: Added test for file existence. (LH) . . . . . . . . . . . . . . . . . . . . . . . 186

\frommtx:

When map data are not known, try to get them from the MTX file before declaring the source unknown. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 Added test for file existence. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

\frompl: Added test for file existence. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 186 \fromplgivenetx: Added test for file existence. (LH) . . . . . . . . . . . . . . . . . 186 \ifisglyph: ⟨misc⟩ definition added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 131 \make_enc: Storing encoding name in string encodingname, thus allowing the

ETX file to override the default. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 166 \makemapentry: When map data are not known, try to get them from the MTX

file before declaring the source unknown. (LH) . . . . . . . . . . . . . . . . . . . 223 \mtxtomtx: \edefing \raw_font_name. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 189 \mtxtopl: Added ‘ligless’ to one of the comment lines. (LH) Clarification re-

quested by Walter Schmidt. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 \pl_to_mtx: \edefing \raw_font_name. (LH) . . . . . . . . . . . . . . . . . . . . . . . 176 \record_transform: \storemapdata lines are optionally written to the main out-

put file as well. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 \reglyph_glyphpcc: Typo corrected. (LH) Spotted by Rolf Lindgren. . . . . . 197

\reglyph_glyphpcc, \reglyph_samesize, \reglyph_setglyph: \string which

should be \noexpand corrected. (LH) Reported by Rolf Lindgren. . . . . . . 197 Reglyphing: eightoldstyle typo corrected. (LH) Spotted by Rolf Lindgren. 200

v 1.912

General:

  \install. . . commands updated to set \setsomething_global to \global

around themselves. This reduces problems with assignments “not working” due to the unintuitive grouping. (LH) Problem pointed out by Hilmar Schlegel, , and others. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 dvips mapfile fragments writer added. (LH) . . . . . . . . . . . . . . . . . . . . . . 235 AFM command StdVW now interpreted: generates \setint for integer verticalstem. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 dvipdfm mapfile fragments writer added. (LH) . . . . . . . . . . . . . . . . . . . . 238

\DESIGNUNITS: Store designunits value in \b_dimen rather than \a_dimen.

\a_dimen holds the design size throughout PL-to-MTX. (LH) . . . . . . . . . 178 \error_help_e: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 \if_equal: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 \if_defined, \if_undefined: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . 52

\ifisint, \ifisstr, \ifisdim: Reimplemented using \if_defined. (LH) . . . 93

\input_mtx_file: Added error message. (LH) Suggested by Alexei Kostin. . 152 \installfontas: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 151 \make_enc: Also calling \declarepsencoding once the encoding file has been

written. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

\reglyphfonts: Added local resetting of \setsomething_global to \relax.

It shouldn’t be needed, since \reglyphfonts should not occur between \installfonts and \endinstallfonts, but I bet someone will try. (LH) 193

\setcommand: Settings of a command already defined is diverted to \a_macro; it

used to be \a_command. Saves one hash table position. (LH) . . . . . . . . . . . 91 \setsomething_global: Control sequence introduced and added to all

\set…, \reset…, and \unset… commands, as well as \offcommand and \oncommand. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

\swap_two: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 \top_of_pl_hook: Property list hook added. (LH) . . . . . . . . . . . . . . . . . . . 134

\transformfont: Added local resetting of \setsomething_global to \relax,

since \transformfont assumes such assignments are local. (LH) . . . . . . . 186 v 1.913

General:

Using \make_factor for making PL reals, rather than

   \afm_convert+\vpl_real.  \scaled_design_size replaced by new

dimen \mapfont_scaling for determining mapfont atsize. (LH) . . . . . . . 137 Definition of transformable metric file changed to include the

   \setscaledrawglyph and \setscalednotglyph commands. (LH) . . . . . . 184

New implementation of \scalefont and \yscalefont, using the new

   \setscaledrawglyph and \setscalednotglyph commands. (LH) . . . . . . 185

Using \slots-⟨glyph⟩ control sequences for storing encoding positions of glyphs in reencoded fonts. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

\do_character: Negative italic corrections are written to the (V)PL being gen-

erated. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 \gobble_if: Macro redefined; it now works entirely in the mouth. (LH) . . . . . 53 \half_point: Constant added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

\installfont, \installrawfont: Moved some code from \install_font to these

commands. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 \installfontas: Specification changed to allow arbitrary ⟨font-info⟩s as first

argument. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 \installraw_storemap: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 150 \l_inv_scale: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 \l_rounded_thousandths: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . 88 \pl_mapfont: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 \rawfont_scaling: Dimen added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 \transformfont: Third argument removed, since it isn’t used anymore. This

change is harmless, since the worst thing that can happen to this argument is that it is typeset. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

\two_thousand: Constant added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 \vpl_kern: Using a nested \ifnum construct to test the condition |\a_count| >

\minimum_kern. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 \vpl_mapfont: Mapfont number control sequences are named \⟨scaling

factor⟩pt-⟨font⟩ instead of \⟨font⟩-⟨scaling factor⟩pt. They are also made \mathchardefs. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

warningspecials switch: Switch controlling whether \glyphwarnings should put

SPECIALS in the VPL was added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 147 v 1.914

General:

Added commands for testing for TEX extensions. (LH) . . . . . . . . . . . . . . . 46 Generating trig.sty from source. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Contents of \Tf-⟨font⟩ control sequences changed to allow processing the same file of recorded transformations several times on the same run. (LH) …. 221 The total transform applied for a font is determined before the entry makers are called. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

\concat_transformfont, \concat_reencodefont: Macros added. (LH) . . . . 226

\endmetrics_hook: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 \extract_font_generation: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . 222 \file_list_metrics: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 150 \first_of_three: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

\for, \for_i, \foreach: \setsomething_global added to assignments of the

\for-⟨name⟩ and \body-⟨name⟩ control sequences. (LH) . . . . . . . . . . . . . 96 \if_defined, \if_undefined: Automatically selecting between TEX and ε-TEX

definitions. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 \input_metrics: Redefined to suite \file_list_metrics. In particular, there

   will now be a comma at the end of \curr_file_list and \prev_file_list.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 \input_mtx_file: Can now accept arbitrary metric commands in argument.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 \inputetx, \inputmtx: New fontdoc definition, using \IfFileExists. (LH) 100, 111 \make_enc: Not writing an address entry if that string isn’t set. (LH) . . . . . 166 \metrics: Fixed typo: \x@relax instead of \x_relax. (LH) . . . . . . . . . . . . 111 \newlinechar, \errorcontextlines: Moved to error message subsection. (LH) 64 \NOFILES: Added \reglyphfont. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 \offcommand, \oncommand: fontdoc definitions added. (LH) . . . . . . . . . . . . . . 94

\process_generation, \process_generation_succ: Control sequences added.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

\ProvidesMtxPackage,

\usemtxpackage: New fontdoc implementation—the packages are actually loaded (they have to, since they can define commands). Multiple loading is prevented as in fontinst. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

\TypesetList: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

\xscale_factor, \slant_factor, \reencode_etx: Control sequences added.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 v 1.915

General:

pltotf “driver” support added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Added description of \aliased macro to the definition of transformable metric files. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

\aliased: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 \fontinstcc, \normalcc: Introduced commands for changing between fontinst

internal catcodes and normal catcodes, as suggested by Karsten Tinnefeld. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

\mtxtomtx: Locally redefining \aliased. (LH) . . . . . . . . . . . . . . . . . . . . . . 189

\mtxtomtx_setscaledrawglyph: Added local redefinition of \aliased. (LH) 191

\reglyph_setscaledrawglyph: Corrected bug in the \ifnum: it should test ar-

gument #5, not #4. (LH) Encountered by Thierry Bouche. . . . . . . . . . . 197

\spacecatcode, \nlcatcode, \atcatcode, \underscorecatcode, \tildecatcode:

Removed since the contents can just as well be stored in \normalcc. (LH) 37 \tracinglostchars: Added setting this parameter. (LH) . . . . . . . . . . . . . . . 64

v 1.916

General:

Moved Section 9 to ficommon.dtx. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Major overhaul of fontdoc mechanisms for integer and string expressions completed. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Requiring the amstext package in fontdoc. (LH) . . . . . . . . . . . . . . . . . . . . . 43

\b@count: Variable added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 \branches@fi: Commented out test which concatenates consecutive \Fis, since

that doesn’t work together with the IfBranch environment. (LH) . . . . . . . 55 \ConditionallyScaled: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . 117

\expression, \priority, \identity, \bracket: Macros removed. (LH) . . . . . 89

FD@tight@ switch: Switch added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

\FD@typeset@string@set,
   \FD@typeset@string@set@: Macros added. \FD@typeset@string@set should

be used instead of \print@csep@list in most occations. (LH) . . . . . . . . 119 \foreach: fontdoc definition added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 \half, \otherhalf: Macros added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 IfBranch: Environment added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 IfBranchDummy: Environment added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 57 \macroparameter: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 74 \setglyph: Added ‘set’ to fontdoc text. (LH) . . . . . . . . . . . . . . . . . . . . . . . 123 \SetStringVariable: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 95 \typeset@glyph: Macro redefined (made synonymous to \TypesetString-

Expression). (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

\typeset@integer, \typeset@string, \typeset@dimen: Macros removed. (LH) 92

v 1.917

General:

Rewrote the fontdimen part of the (V)PL-to-MTX converter so that the ETX can specify the fontdimens. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Option processing added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

\afmtomtx: Added resetting of \setsomething_global—assignments made here

must be local. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170

\FD@lig-/LIG>, \FD@lig-LIG/>, \FD@lig-/LIG/>, \FD@lig-/LIG/>>: Changed

how fontdoc marks the current position after a ligature instruction, from + to ∗⌊. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

\generalpltomtx: Added resetting of \setsomething_global—assignments

made here must be local. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 \ifareglyphs: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 \label: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 \Ligature: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 \mtxtomtx_setint: Redefined to allow an extensible list \width_ints_list of

integers that should be transformed as widths. (LH) . . . . . . . . . . . . . . . 191 \mtxtopl: Added resetting of \setsomething_global—assignments made here

must be local. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 \setfontdimen: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 \setleftboundary: Made the left boundary referencable using \label. (LH) 103 \setscalednotglyph: This macro should set \g-⟨glyph⟩-not, not \g-⟨glyph⟩.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 \setslot: Made slots referencable using \label. (LH) . . . . . . . . . . . . . . . . 101 \slot@name: Now storing the printable form of the name, rather than the raw

code. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

\Unicode:

Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Added setting of \linepenalty and \spaceskip. (LH) . . . . . . . . . . . . . . 106

\width_ints_list: Macro added. \verticalstem_name removed. (LH) . . . . 191

v 1.918

\encoding, \endencoding: Added \par and \addvspace to fontdoc definitions.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 \FD@charname: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 \FD@codepoint: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 hypertex option: Option added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 \needsfontinstversion: Different formatting in encoding specification files.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 \oddligature: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 \textunicode: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

v 1.919 \endencoding: Added setting of \parindent to 1 em to fontdoc definition. (LH) 100 \make_enc: Added DSC comments. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 166

v 1.920

General: The body (between \metrics and \endmetrics, and \encoding and \endencoding respectively) of a fontdoc document is now typeset in a flushleft environment. It used to be that the entire document was typeset this way. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43,

        100 (\encoding), 100 (\endencoding), 111 (\endmetrics), 111 (\metrics)

\Aheading: Encouraged page breaks before an \Aheading. (LH) . . . . . . . . . . 43 IfBranch: Removed assignment to \listparindent. I don’t know why it was

there in the first place. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 pdftex option: Option added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

v 1.921

\installfontas: Automatically doing an \installfamily if that has not been

done. (LH) Suggested by Rowland McDonnell. . . . . . . . . . . . . . . . . . . . 151 \pl_rounded_real: Macro added and is used instead of \pl_real. (LH) … 177

\pl_to_mtx: \fromvpl in \storemapdata does not have an argument. Fixed a

bug that produced such an argument anyway. (LH) . . . . . . . . . . . . . . . . 176 \textvisiblespace: Redefinition added. (LH) . . . . . . . . . . . . . . . . . . . . . . . 68 \transformfont: Corrected an error message that tried to use a variable that

wasn’t set (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 v 1.922

\setscalednotglyph: Corrected typo: should test whether the rawscale integer

exists, not whether the i-rawscale integer exists. (LH) . . . . . . . . . . . . . 125 \setscaledrawglyph: Corrected typo: should test whether the rawscale integer

exists, not whether the i-rawscale integer exists. (LH) . . . . . . . . . . . . . 124 v 1.923

General:

Added support for keywords other than scaled in the second argument of \installfont and such. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 Making sure \lineskiplimit is positive. (LH) . . . . . . . . . . . . . . . . . . . . . 43

\eTeXlogo: Added kern, to match ltugboat definition. (LH) . . . . . . . . . . . . . . 47 \etx_to_font: Made the first argument a list of commands. Renamed

\vpl_caller to \vpl_call; it is now assumed to contain the arguments as well. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

\etxtovpl: The program is called vptovf, not vpltovf. (LH) . . . . . . . . . . . 132 \etxtovpl, \etxtopl: The first argument of these macros is now a comma-

separated list of ETX files, and the items may be subjected to modifier clauses. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

\fromany: Added \pl_encoding. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 \generalpltomtx: Changed test of fourth argument to instead of \ifx use \if.

This is more versatile. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 \glyph_name_modifier: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . 114 \ifisglyph: Using \if_defined. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 \IFKW-mtxasetx: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 \input_mtx_as_etx: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . 111 \make_inputetx: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 \ProvidesMtxPackage: Redesigned the headings for metric packages, since they

interact poorly with \section headings. (LH) . . . . . . . . . . . . . . . . . . . . 112 \resetglyph: \edefing \glyphname, for consistency with \setslot. In principle,

this could break MTX files, but I doubt that it will. (LH) . . . . . . . . . . . 123 \setfontdimen: Leave the fontdimen unset when the integer variable has not

been set. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 v 1.924

General: Added mechanism for passing options to MTX and ETX files. (LH) .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 (\reset_modifiers_hook),

                154 (\IFKW-option), 154 (\ifoption), 154 (\list_of_options)

\autoinstallfamily: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . 151 direct switch: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 \mtxtomtx: Added \directfalse. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 189

v 1.925

General: Added \renameglyph for Hungarumlautsmall. Walter Schmidt noticed

it was missing. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 \glyphpcc: Added check that the glyph used is defined; we get an ugly error if

it isn’t. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

\latin_encodings: Changed from using latin.mtx to newlatin.mtx. (LH) . 218

v 1.926 General: Added some missing ˜ ’s at ends of lines. (LH) . . . . . . . . . . . . . . . . 164

\fromany:

Has to reset the afm-name string, since \input_mtx_file now uses the value. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Removed \pl_encoding; it is better to provide that functionality in a separate macro. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187

\input_mtx_file: Only looking for PL and VPL files when an encoding is spec-

ified. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 v 1.927

\declareencoding: Lowercased encoding file names. (LH) . . . . . . . . . . . . . . 162 \do_character: Added flag for emitting warning message when a glyph is miss-

ing. (LH) Requested by Werner Lemberg. . . . . . . . . . . . . . . . . . . . . . . . 143 \etxtoenc: Made the ⟨etxfile⟩ argument a comma-separated list of ETX files.

Changed \do_slot definition to get set rather than reset semantics. (LH) Feature requested by Werner Lemberg. . . . . . . . . . . . . . . . . . . . . . . . . . 165

\FD@lig-/LIG: Fixed a typo. (LH) Reported by Werner Lemberg. . . . . . . . . 105 \FD@lig-/LIG/>>: Fixed a typo. (LH) Reported by Werner Lemberg. . . . . . 105 \if_undefined: Fixed problem with \unless. (LH) . . . . . . . . . . . . . . . . . . . 52 \if_defined, \if_undefined: Modified ε-TEX definitions to make them work

with the crufty old “unset is \let to \relax” tradition of fontinst implementation. (LH) This was found to be a show-stopper for using v 1.926 with ε-TEX; Heiko Oberdiek found the cause of it. . . . . . . . . . . . . . . . . . . . . . . 52

\make_enc: Modified to handle a comma-separated list of ETX files. (LH) . . 166 \make_ligtable: Changed the surrounding group to \begingroup type. This

helps contain errors that arise when the \setslots and \endsetslots aren’t properly balanced. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

\mtxtomtx_redefinitions: Macro added. The code used to be in \mtxtomtx.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190

\reglyph_redefinitions: Macro added. The code used to be in \reglyph_font.

(LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 Reglyphing: Placed commands for letters and figures in separate modules, so

that they can be separated in generation. (LH) . . . . . . . . . . . . . . . . . . . 200 \storemapdata: Improved wording of warning message and downgraded it to an

info in the case when the two definitions are the same. (LH) . . . . . . . . . 222 v 1.928

General: ETX to CMAP converter added. (LH) . . . . . . . . . . . . . . . . . . . . . 168

\charseq:

Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Typeset form changed, from paragraph to a one-item-per-line list. (LH) . . 107

\cmap_codepoint: Added \uppercase to ensure case independence. (LH) … 168 \FD@relax@encoding@tricks: Macro added, to fix bug reported by Peter Dy-

balla. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 \format_hex: Macro added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 \fulldownload: Command added. (LH) . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 \plainneg: Added \plainneg. That the L^{A}TEX \neg is taken over by fontdoc but

is needed in oms.etx had gone unnoticed for over ten years! (LH) Problem reported by Peter Dyballa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

v 1.929

\input_mtx_file: Missing space in message inserted. (LH) Pointed out by Peter

Dyballa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 \metrics_given_encoding: The afm-name string usually has a value at this point,

so it is necessary to reset it. (LH, sighing because he knows this isn’t the first time this problem occurred) First to be hit by this bug was Michael Zedler. 153

\mtxtopl: Corrected ‘pltotf’ in comment. (LH) . . . . . . . . . . . . . . . . . . . . . 183

Internal notes

A Typographic treatment

• I have been following The L^{A}TEX Companion in that I have set all names of packages and the like—fontinst, fontdoc, trig, doc, and docstrip (I might have forgotten some)—in sans serif type. Actually, I have defined a command \package in fisource.sty (or is that fisource?) which does this, so if we decide on some other formatting, we can just change that. /LH

• It seems to me that there should indeed be some space between the ‘v’ and the digits in a version number when it is typeset, but I also think a full space is too much, so I have been using thin spaces. These are unbreakable and under L^{A}TEX you can simply use \, to get one (while you are not in math mode, that is). /LH

• While I went through (some of) the code, I came across a few inconsistencies.

A I have marked them out like this—some boldfaced text in a paragraph and a large A in the margin. I defined a command \ambiguity for doing this. /LH

• There is also a similar command \question which is intended for situations where there isn’t really an error, but something seems like it should be taken care of in some other way. The \question command puts a question

? mark in the margin.

• I also noticed that there are several fontinst commands, not all of which are

Not in doc: \foo new, which are not defined in fontdoc. To mark out such things, I have written things like the one shown in the margin by this paragraph. I defined a command \missing for doing this. /LH

B Planning topics

This section lists items in the larger design of fontinst which need to be resolved in one way or another. Debates about these items on the fontinst mailing list are welcome.

B.1 Reorganisation of the source

At the moment, all the ideas suggested have been realized.

B.2 Files

Which files should be considered temporary and placed in the location specified with \tempfileprefix? Should files be explicitly be looked for at this location or should it be assumed that fontinst users include that location in their TEX input file search path? In the former case, which files should be looked for in that location? Should files be looked for in the temporary location before they are looked for without a specified location, or should it be the other way round?

C Contributors

[The fontinst source has been pretty inconsistent in how people are credited for what they have done—some appear only as acronyms while others appear as rather striking e-mail addresses—so I thought it best that this is shaped up a bit. My suggestion is that we use names or acronyms in the source and move everything else here. I also thought it could be interesting with a short description of what each person has done and is doing, so I have started ever so slightly on something along those lines. Feel free to add things! /LH]

The following people have contributed substantial amounts of code or documentation to fontinst. They are listed in strict alphabetical order.

Thierry Bouche Thierry saw to that the T1 encoded fonts got font dimensions comparable to the ec fonts. Thierry is also the author of several papers (published in the Cahiers GUTenberg and TUGboat) which deal with nontrivial applications of fontinst, such as creating metrics for Adobe Minion Multiple Master fonts and developing a corresponding math font setup.

E-mail: Thierry.Bouche@ujf-grenoble.fr

Lars Hellström (LH) Lars is responsible for most of the things in v 1.9 that were not there in v 1.8.

Lars is currently a member of the fontinst maintenance team. He is also a Ph.D. in mathematics looking for employment.

Alan Jeffrey (ASAJ) Alan is the original author of fontinst. He is not currently on the development team, but he is still managing the fontinst mailing list.

E-mail (fontinst mailing list subscriptions):

    fontinst-request@cogs.susx.ac.uk.

Constantin Kahn (CK) Constantin is one (Sebastian is the other) of the original coauthors of the current \latinfamily command.

Rowland McDonnell Rowland rewrote Alan’s old v 1.5 documentation for fontinst and updated it for v 1.8.

Sebastian Rahtz (SPQR) Sebastian is one (Constantin is the other) of the original coauthors of the current \latinfamily command. He has also contributed numerous ETX files and made the “unofficial” v 1.6 and v 1.7, which included the first fontinst support for making TS1 encoded files.

Ulrik Vieth (UV) Ulrik converted fontinst.sty to doc/docstrip format, reunited Alan’s v 1.511 and Sebastian’s v 1.7, and made the first official release of fontinst (v 1.8) for more than two years.

Ulrik is currently a member of the fontinst maintenance team. He is also involved in the Joint TUG/L^{A}TEX 3 Project Working Group on extended math font encodings.

…

Anyone else?

D To do

This section is based on the TODO file from fontinst v 1.504, but a couple of new entries have been added and some have been equipped with comments.

D.1 Things to do in the “near” future

• Update documentation. (Lars, knowing he isn’t saying anything new)

• Rewrite the entire substitution mechanism from scratch! The main problem with the current mechanism is that it only allows one substitution per shape and one per series. One cannot substitute the it shape for both the sl and the ui shapes since each new \substitute(noisy|silent) with it in the ⟨from⟩ argument will overwrite the setting made by the previous;

    \substitutenoisy{ui}{it}
    \substitutesilent{sl}{it}

is effectively the same as

    \substitutesilent{sl}{it}

Another big problem is that it isn’t well defined what the substitution mechanism should do. (Lars)

I’ve got a sketch for a new substitution mechanism, but I’m not at all sure it will make it into any v 1.9xx. /LH (The code that was written is now in fimain.dtx, but it’s not included in any of the generated files.)

An alternative to substitutions is to use explicit \installfontas commands. This provides complete control. /LH

• Consider removing the following unreliable fakes from textcomp.mtx:

    asciiacutedbl, asciigravedbl, bardbl, openbracketleft, and
    openbracketright

and consider adding fakes for the following unavailable glyphs:

    dollaroldstyle (use dollar), centoldstyle (use cent), lira
    (use sterling), and pilcrow (use paragraph)

These suggestions are of course open for debate. (Ulrik)

• One thing I miss in [the typeset form of an encoding specification] is a simple hex/octal/decimal chart showing all the character names in their positions (and ideally even an example of the printed character, although I know that would be harder). (Karl Berry)

D.2 Things that probably won’t be done in the near future

• Find a way to automatically generate math fonts. (Alan)

I doubt that this will ever be possible to do automatically. mathptm and mathptmx are already hackish enough, not to mention the prototype implementations for new math font encodings. /UV • Investigate using Alternate sets. (Alan)

AFAIK, Thierry Bouche has done some work with alternate sets for AGaramond, ACaslon and Minion, but this implies a lot of manual work to compose the proper calls to fontinst. /UV

• Create L^{A}TEX packages? In fact, rethink the whole package interface … (Alan)

Sebastian’s Perl front-end to fontinst does create trivial L^{A}TEX packages automatically for the CTAN fonts. /UV

• Worry about excessive kern tables in T1 fonts. (Alan)

I think the best way to get at this would be to write a program that can optimize (for size) kern tables by making use of the SKIP instruction. There’s often room for quite a lot of compression. Such a program would however have to be written in some compiling language, otherwise it wouldn’t be fast enough. /LH

• Consider making \set(left|right)kerning parameterized by the size of the other glyph, eg so that faking <Asmall><T> can be different from <Aacutesmall><T>. Suggested by Hilmar Schlegel.

D.3 Things that have been done

• Update documentation (comments from Karl and Damian).

Rowland has meritoriously done the update requested here. On the other hand, it needs to be updated again, since many new features have been added. /LH

• Investigate using raw SC fonts. (Alan)

This problem comes up on the mailing list from time to time. The problem is that fontinst’s \latinfamily command is geared towards fonts that come with standard and expert font sets (as with Adobe and Monotype fonts) rather than fonts that come with standard and small caps (as with Linotype fonts). I’m afraid it would be to complicated to handle both cases in the same \latinfamily procedure. /UV

• Investigate problems with duplicate kerns appearing in VPL files (Hilmar Schlegel).

The problem has been investigated and is solved with v 1.9. /LH

• Find out why, if you have a font with both medium and light variants but no italic, you get m/it ↦ l/it ↦ l/sl rather than m/it ↦ m/sl. (Sebastian).

Because for every shape that fontinst is allowed to use a given font for, it will perform all possible series substitutions. If the \installfont for l/sl came before the \installfont for m/sl, then substitutions will be as described above. See also item about the substitution mechanism. /LH

• AFM files can contain real units, not just integers. (Gintautas Grigelionis).

This is fixed with v 1.9. /LH • Make fontdoc.sty and co. use PS fonts. (Alan)

I think \useexamplefont and friends (introduced with v 1.8) pretty much do what was intended here. /LH

• latin.mtx uses fontinst rather than fontdoc! (Rob Hutchings).

• Allow .vpl files to be read as .pl files. (Constantin)

• Richard Walker reports that if you say

    \latinfamily{mbvx}{}
    \latinfamily{mbv9}{}

then the 2nd run doesn’t use old-style digits, because the 1st run has already defined \digit. If so, this is because \latinfamily is missing a bracing level. I should investigate.

I think it is best to do oldstyle and non-oldstyle variants in two separate fontinst runs, i.e. don’t use \latinfamily more than once in a single run. (IIRC, grouping doesn’t work properly since every single font closes and reopens a \begingroup-\endgroup pair to encapsulate the kerning info^{15} or something like that.) /UV

• Consider writing an \installfontas command which doesn’t generate a (V)PL but makes an entry in the FD file. Typical usage: Install an sc shape of a TS1 font family by using the font made for the n shape. (Lars)

Done. The described installation for the m series of the ptm font family can be done through

    \installfontas{ptmr8c}{TS1}{ptm}{m}{sc}{}

Note however that you need to do it in each series explicitly. /LH

• Use the StdVW property from AFM 4.0 files instead of the width of I for standard stem fontdimen. Pointed out by Hilmar Schlegel.

Partially done. \afmtomtx writes a \setint{verticalstem}{⟨value⟩} when

it encounters a StdVW property. The ETX files have not yet (2000/05/30) been changed to use this value. /LH

• fontdoc has a problem with glyph, integer, string, etc. names that contains underscores, since these will cause TEX to jump to math mode when one tries to typeset these things. Unfortunately fontinst itself writes two such integers: descender_neg and maxdepth_neg. There are at least three solutions to this. The first is to make underscore an ‘other’ character throughout, but this might break some comments in MTX and ETX files. The second is to temporarily change the catcode in the arguments of the commands, but that will complicate the definitions of almost all fontdoc commands dramatically. The third is to declare this as unsupported by fontdoc and change fontinst so that the troublesome integers are renamed, e.g. descender-neg and maxdepth-neg, but this can break people’s code. (Lars)

15And glyph metrics info, and glyph mapcommands info … /LH

After thinking about it for a couple of months, I realized that none of the above is the right solution. That is instead to use something similar to the harmless character strings of the xdoc package when typesetting names of variables etc. in fontdoc. This got implemented in v 1.916. /LH

• Modify the (V)PL-to-MTX converter so that \setint{fontdimen(⟨n⟩)} {\int{⟨name⟩}} commands in the ETX file declare that PARAMETER (or equivalent) properties for fontdimen ⟨n⟩ should be converted to \setint commands for the integer ⟨name⟩. This ought to be particularly useful for math fonts. (Lars)

Done with v 1.917, but only for the new \setfontdimen command. /LH

• Update fontdoc.sty and co. for L^{A}TEX 2ε. (Alan)

fontdoc.sty underwent a major overhaul from v 1.916 on, so I suspect this can be said to have been done now. The basic vertical spacing put in by \Aheading and \Bheading may however need more work; sometimes it doesn’t come out as one would want it to. /LH

• latin.mtx fakes composite SC glyphs [kerning?] from the composite glyph, eg.

    \setleftrightkerning{Aacutesmall}{Aacute}{900},

rather than from the SC non-composite, eg.

    \setleftrightkerning{Aacutesmall}{Asmall}{1000}

This may cause problems with SC fonts with explicit SC–C kerns, eg.

    \setkern{V}{Asmall}{100}

This needs to be thought about. Pointed out by Hilmar Schlegel.

newlatin.mtx does this right; shrunk glyphs get shrunk kerning, whereas constructed glyphs get kerning from the base letter. /LH

D.4 Other notes

Alan’s TODO file also contains some items regarding mathptm, but that seems to have migrated out of fontinst (if it ever really was a part). The problem is that mathptm cannot be changed any more for the sake of checksum consistency and backwards compatibility. A new variant called mathptmx tries to do a little better, but there may still be room for improvements.

E Efficiency

This section records the results of some (rather simple) test runs that have been made to test the efficiency of fontinst, primarily to see how changes in the implementation affect efficiency by comparing the time and space used by different fontinst versions to complete the same task.

E.1 Alan Jeffrey’s tests

I compared the version where you try to keep ints as \mathchardefs with the version where you don’t bother, and for a sample font without \mathchardefs I got:

114673 words of memory out of 150001 Time elapsed: 135.0 seconds

and with, I got:

114050 words of memory out of 150001 Time elapsed: 134.5 seconds

so I’ve saved a little memory and time. Not brilliant, but I may as well keep it in.

Where possible, we avoid re-scaling kerns, which saves a bit of time and memory. With a sample font, the version where we didn’t avoid re-scaling used:

114050 words of memory out of 150001 Time elapsed: 134.5 seconds

whereas the version where we do avoid it used:

113786 words of memory out of 150001 Time elapsed: 124.9 seconds

We keep the names of the glyphs to kern with as \l-⟨name⟩ and \r-⟨name⟩ to save on token space, and this got the resources used down to:

88574 words of memory out of 150001 Time elapsed: 106.1 seconds

Keeping track of the kern amounts as \⟨amount⟩ got the resources used down to:

75424 words of memory out of 150001 Time elapsed: 97.2 seconds

Mind you, I then added all the \transformfont stuff, and it went back to:

77079 words of memory out of 150001 Time elapsed: 97.7 seconds

E.2 Current tests

The setup for this test is that TEX is run on a .tex file consisting of the following commands.

     \batchmode
     \input fontinst.sty
     \latinfamily{pad}{}
     \tracingstats=1\bye

All the font metrics are generated from the AFM files; temporary MTX, PL, and VPL files are deleted between test runs. The format used was generated by typing \dump at iniTEX’s ** prompt; thus there is no overhead from a typesetting format in the space requirements.

[It appears the exact data from these tests will have to wait, since I haven’t been able to get access to any computer with reliable process timing. For the next release perhaps … /LH]

References

[1] Karl Berry: Fontname, CTAN:info/fontname/fontname.texi (and most of the other files in that directory as well).

[2] Matthias Clasen and Ulrik Vieth: mfnt (their “work with math fonts”), 1997–

8, see http://www.tug.org/twg/mfg/archives/.

[3] Michel Goossens, Frank Mittelbach, Alexander Samarin: The L^{A}TEX Companion, Addison-Wesley, Reading, MA, USA, 1994.

[4] Michel Goossens, Sebastian Rahtz, Frank Mittelbach: The L^{A}TEX Graphics Companion: Illustrating Documents with TEX and PostScript, Addison-Wes-ley, Reading, MA, USA, 1997; ISBN 0-201-85469-4.

[5] Donald E. Knuth: The art of computer programming, vol. 2 (Seminumerical algorithms), 3rd ed., Addison-Wesley, 1997.

[6] Donald E. Knuth, Duane Bibby (illustrations): The TEXbook, Addison-Wes-ley, 1991, ISBN 0-201-13448-9; also volume A of Computers and typesetting, ISBN 0-201-13447-0.

[7] L^{A}TEX3 Project Team: L^{A}TEX 2ε font selection, CTAN: macros/latex/base/

fntguide.tex.