% pdcfsel.dtx -- documentation & source for pdcfsel.tex -*-tex-*- %%%@TeX-document-file { %%% title = "PDCFSEL, a font selection scheme for TeX", %%% filename = "$texmf/doc/plain/pdcmac/pdcfsel.dtx", %%% version = "$Revision: 3.5 $", %%% package = "pdcmac 1.0", %%% date = "$Date: 1995/03/28 19:05:54 $", %%% author = "P. Damian Cugley", %%% email = "damian.cugley@comlab.ox.ac.uk", %%% address = "Oxford University Computing Laboratory," %%% Parks Road, Oxford OX1 3QD, UK", %%% abstract = "This document describes and defines pdcfsel.tex, %%% a file of definitions for managing font selection in %%% documents based on the plain TeX macros. %%% Running plain TeX on this file produces both the %%% definitions file and the printed documentation.", %%% copyright = "Copyright (c) 1991-1995 P. Damian Cugley", %%% copying = "This program is free software; you can redistribute %%% it and/or modify it under the terms of the GNU %%% General Public License as published by the Free %%% Software Foundation; either version 2 of the License, %%% or (at your option) any later version.", %%% notice = "This program is distributed in the hope that it will %%% be useful, but WITHOUT ANY WARRANTY; without even the %%% implied warranty of MERCHANTABILITY or FITNESS FOR A %%% PARTICULAR PURPOSE. See the GNU General Public %%% License for more details.", %%% notice = "You should have received a copy of the GNU General %%% Public License along with this program; if not, write %%% to the Free Software Foundation, Inc., 675 Mass Ave, %%% Cambridge, MA 02139, USA.", %%% codetable = "USASCII", %%% dependencies = "pdccode.tex" %%%} %{{{ pdcfsel %{{{ premable \relax \input pdccode \document \rcs$Id: pdcfsel.dtx,v 3.5 1995/03/28 19:05:54 pdc Exp $\endrcs \codefile{pdcfsel.tex} %}}} premable %{{{ intro \author{P. Damian Cugley} \title{PDCFSEL, a font-selection scheme for \TeX} \section{Introduction} This document describes PDCFSEL, a file of font selection macros designed to be used with documents using the plain \TeX\ format (rather than \LaTeX, for example). The PDCFSEL macros perform a similar function to the so-called New Font Selection Scheme~2 (used in \LaTeX~2e). PDCFSEL uses a simpler model of font selection, and so is a smaller package---about 110~lines of code---which is just as well as a copy of it will probably need to be included with documents using it. The description of which fonts are used in a document can be relatively compact, despite not using any special database files. \subsec{Organizing fonts into fontsets} We can arrange the fonts used in an imaginary \TeX\ document in a table like so (with an asterisk marking fonts that have to be scaled to fit): $$\def\*{{\rm*}} \vbox{\halign{\strut#\hfil&\quad\vrule#&&\quad\tt#\hfil\cr && |\rm|&|\it|&|\bf|&|\bi|&|\mi|&|\sy|\cr \noalign{\nointerlineskip}\omit& height \jot\cr \noalign{\hrule}\omit& height 1\jot\cr \noalign{\nointerlineskip}% body text&& cmr10& cmti10& cmbx10& cmbxti10& cmmi10& cmsy10\cr footnotes&& cmr8& cmti8& cmbx8& cmbxti10\*& cmmi8& cmsy8\cr script&& cmr7& cmti7& cmbx7& cmbxti10\*& cmmi7& cmsy7\cr scriptscript&& cmr5& cmti7\*& cmbx5& cmbxti10\*& cmmi5& cmsy5\cr \noalign{\nointerlineskip}\omit& height\jot depth\jot&\multispan6\dotfill\cr \noalign{\nointerlineskip}% heading&& cmss12& cmssi12& -&-&-&-\cr subheading&& cmss10& cmssi10& -&-&-&-\cr }} $$ The column headings are {\it font nicknames}. These nicknames are used as described in the {\it\TeX book} to switch between fonts in the same row. Each has a corresponding {\it fam} used in maths mode, with symbolic names like |\itfam| and |\bffam| (we define $\hbox{|\rmfam|}=0 $ for consistency). I~have added nicknames |\mi| and |\sy| for maths italic and maths symbol respectively. Each row of the table is a {\it fontset}. Plain \TeX\ defines a single fontset (which is like the `body text' row of this table); in Appendix~E, Knuth discusses formats that switch between different fontsets with macros like |\ninepoint| and |\eightpoint|. \LaTeX~2.09 uses many fontsets, called |\normalsize|, |\large|, and so on. (NFSS~2 uses a more complex system, where size, weight, and slant may be changed independently of each other.) In this table, subheadings and body text have different fontsets in the above, even though the fonts are the same size. Also, there are no |\sf| fonts; the headings are printed in sanserif by using a fontset with |\rm| mapped on to a sanserif font. This is more logical and flexible than the \LaTeX\ approach. We can call font families which allow this table to work tidily `regular', and families (like Computer Modern) that require exceptions `irregular'. The above table has one exception (|\it| in scriptscript must use a scaled font); the CM Bold Extended Text Italic fonts can be described as regular if we think of the `body text' entry as being `|cmbxti10 at 10pt|', so that the fonts in that column are scaled fonts without exception. To make font specification compact, we want to take advantage of regular families as much as possible, while not making it difficult to include exceptions. \subsec{Introduction to using PCDFSEL} PDCFSEL uses no databases of font families, and loads no fonts by default. This makes it more flexible, but also requires document designers to write a `mini-database' of those fonts used in the document. The above scheme might be defined as follows: \smallskip \halign{\indent#\hfil\cr |\input pdcfsel|\cr \noalign{\smallbreak}% |\newfam\bifam|\cr \noalign{\smallbreak}% |\def\texttemplate{%|\cr | \m{rm}{cmr}\m{it}{cmti}\m{bf}{cmbx}\@\m{bi}{cmbxti10}%|\cr | \M{mi}{cmmi}\M{sy}{cmsy}%|\cr |}|\cr |\loadfont\scriptscriptit{cmti7 at 5pt }|\cr |\xfontset{scriptscript}\texttemplate{5}|\cr |\xfontset{script}\texttemplate{7}|\cr |\fontset{note}\texttemplate{8}{10pt}{scriptscript}{scriptscript}|\cr |\fontset{body}\texttemplate{10}{12pt}{script}{scriptscript}|\cr \noalign{\smallbreak}% |\def\headingtemplate{%|\cr | \f{rm}{cmss}\f{it}{cmssi}%|\cr |}|\cr |\fontset{subheading}\headingtemplate{10}{12pt}{subheading}{subheading}|\cr |\fontset{heading}\headingtemplate{12}{14pt}{subheading}{subheading}|\cr \noalign{\smallbreak}% |\bodyfonts|\cr } \smallbreak \noindent This defines commands |\bodyfonts|, |\notefonts|, |\headingfonts| and |\subheadingfonts| which switch between fontsets. (The {\it script} and {\it scriptscript} fontsets, which are defined with |\xfontset|, are used only in maths mode and don't need `-|fonts|' commands.) These -|fonts| commands are not usually used directly in documents; |\notefonts| will be used in some |\footnote| command, |\headingfonts| in some heading-generating command, and so on. Changes of fontset are accompanied by changes in parameters like |\baselineskip| and pseudo-parameters like |\smallskipamount|, and give definitions to the {\it maths font tables} |\textfont\rmfam|, \dots, |\scriptscriptfont\syfam| (for those fonts that will be used in maths mode). We want font nickname commands to be efficient, because they are expected to be more common than changes between rows in the table. In this implementation, after an invocation of |\bodyfonts|, the macro |\rm| expands to exactly `|\fam\rmfam \bodyrm|'. \subsec{How the rest of this document is organized} The remainder of this document is a description of all of |pdcfsel.tex|, including more details of how the commands it defines are used. Running this document (|pdcfsel.dtx|) through plain \TeX\ creates the definitions file (|pdcfsel.tex|) in addition to the usual |dvi| and |log| files. This way the macros and their documentation may be kept together in one file. The definition lines are numbered. The definitions start with macros for loading individual fonts, followed by the macros used to group fonts into fontsets. %}}} intro %{{{ getting started \section{Getting started} \subsec{File identification} We start with some comments indentifying the file. \code |% pdcfsel.tex -- macros for loading fonts -*-tex-*- | |%%%@TeX-document-file { |%%% title = "PDC Font Selection Scheme", |%%% filename = "$texmf/tex/plain/pdcmac/pdcfsel.tex", \|\%\%\% version \space\space\space= "\fileversion", \|\%\%\% Date \space\space\space\space\space\space= "\filedate", \|\%\%\% creator\space\space\space\space= "\filename", |%%% package = "pdcmac 1.0", |%%% author = "P. Damian Cugley", |%%% email = "damian.cugley@comlab.ox.ac.uk", |%%% address = "Oxford University Computing Laboratory," |%%% Parks Road, Oxford OX1 3QD, UK", |%%% abstract = "A file of definitions for managing font |%%% selection in documents based on the plain |%%% TeX macros. |%%% This file was generated by running |%%% plain TeX on pdcfsel.dtx.", |%%% dependencies = "" |%%%} | \|\string\message\{\fileversion\space\string<% \fileauthor\space\filedate\string>\} \endcode \subsec{Private names} Macros internal to FSEL all have names starting `|\FSEL|'. \subsec{Macros for edefs} These save typing |\expandafter| a lot. The expression `|\expcs|\\arg{\}', creates a csname from \ and applies \ to the result. In the body of an |\edef|, The expression `|\noexpcs|\arg{\}' converts \ to a csname without expanding the result. \code |\def\expcs#1#2{\expandafter#1\csname#2\endcsname} |\def\noexpcs{\expcs\noexpand} \endcode %}}} getting started %{{{ selecting demand-loading \section{Selecting auto-loading mode} The flag |\ifFSELautoload| is true, fonts are auto-loaded when they first used instead of all at the start. This is useful when not all the fonts described by the fontsets will be needed. The flag is set with the user command |\autoloadfonts|. When demand-loading, the fonts used are written to a file named after the document with a |.fnt| suffix. This checklist might be used to decide which fonts need to be sent with the document if it is being sent to someone to compile on a different \TeX\ system. \code |\newif\ifFSELautoload |\def\autoloadfonts{ | \FSELautoloadtrue | \csname newwrite\endcsname \FSELfile | \immediate\openout\FSELfile=\jobname.fnt |} \endcode %}}} selecting demand-loading %{{{ making csname for one font \section{How to set up the csname for one font} The macro |\loadfont| is used to load individual fonts, defining a control sequence name (csname) which may be used later to switch to that font. When not demand-loading fonts, this is just like |\global\font| followed by expanding the |\everyloadfont| macro. If the csname is already defined, then this command does nothing. This is so that irregularities in the font scheme for the document can be allowed for. Parameter |#1| is the csname, for example `|\bodyrm|', and |#2| is the external name, for example `|cmr10|' or `|cmr10 at 12pt|'. \code |\def\loadfont#1#2{% | \ifx#1\relax | \FSELloadfont#1{#2}% | \else\ifx#1\UNDEFINED | \FSELloadfont#1{#2}% | \fi\fi |} \endcode (We have to compare |#1| against both |\relax|, which is produced by |\csname|--|\endcsname|, and a completely undefined csname.) The macro |\FSELloadfont| doesa the actual work of loading the font. \code |\def\FSELloadfont#1#2{% | \ifFSELautoload \endcode \begingroup \leftskip=\parindent \advance\leftskip4\fontdimen6\tentt \noindent{\it Demand-loading}. We don't load the font, instead we define a csname as a macro. When expanded this new macro will (a)~write the font name to the |fnt| file; (b)~define the macro |\subfont| to load |cmr10| instead (in case \TeX\ stops with a `font not loadable' message); (c)~load the font for real (this overwrites the macro); (d)~call |\everyloadfont| for per-font customization and (e)~switch to the new font. \par\endgroup \code | \edef#1{% | \write\FSELfile{#2}% | \def\noexpand\subfont{\global\font\noexpand#1cmr10 }% | \global\font\noexpand#1#2\relax | \noexpand\everyloadfont\noexpand#1{#2}% | \noexpand#1% | }% | \else \endcode \leftline{\hskip4\fontdimen6\tentt \indent{\it Immediate loading}.} \code | \global\font#1#2\relax \everyloadfont#1{#2}% | \fi |} \endcode The macro |\everyloadfont| is expanded immediately after actually loading a font. (The definition used is that one current when the font is actually loaded, not the one current when |\loadfont| was executed.) Its |#1| parameter is always a \, i.e., it can be to used as a parameter to |\fontdimen1|. The |#2| parameter is the external name of the font. \code |\def\everyloadfont#1#2{} \endcode For example, in a document with a ragged-right margin, this might be used to suppress the stretch and shrink of interword spaces by being defined as follows $$ \vbox{\halign{#\hfil\cr |\def\everyloadfont#1#2{%|\cr | \fontdimen3#1=0pt \fontdimen4#1=0pt|\cr |}|\cr }} $$ %}}} making csname for one font %{{{ making a fontset \section{How to set up a fontset} Now that we know how to define individual font csnames, we need the mechanism for grouping them in to fontsets. A fontset is defined by a template macro which says what font nicknames are defined and gives part of the external font name. The template macro takes no parameters and expands to a list each of whose elements are of the form $$ \vbox{\halign{$#$\hfil&\quad#\hfil\cr \ \arg{\} \arg{\}& or\cr \cs{@} \ \arg{\} \arg{\}& for a scaled font.\cr }} $$ where a \ is one of the control sequences |\f|, |\m| or |\M|, and \ is the two- or three-letter nickname used for the font (without any leading backslash), for example |rm|, |it|, |bf|. There must be a font fam called |\|\|fam| (|\rmfam|, |\itfam| etc.\ are already defined). If there is no |\@|, then the \ is a font name sans the size specification, such as |cmr|. The size in points will be appended to this (|cmr| + $10\pt$ = |cmr10|). If |\@| is included then the \ is the complete font name, such as |cmr10| or |ptmr|. This will be followed by `{\tt\char32 at\char32 10pt\char32 }', say. The \ specifies how much support for mathematics this font requires. This is because maths mode requires that all fonts that might be used in a formula be loaded (because the font tables |\textfont|, |\scriptfont| and |\scriptscriptfont| must be set). The code |\f| means that the font is not used in maths, |\m| means that |\textfont| and |\scriptfont| will be set correctly for this fam, and |\M| means that |\scriptscriptfont| will also be set. In these cases there must be a corresponding token ending in `-|fam|' that expands to the fam number. The fontset name is a sequence of \s, like `|body|', `|note|', `|script|', `|heading|'. This is turned into a fontset selection macro by adding `|\|' to the front and `|fonts|' to the end (e.g., |\bodyfonts|). The csnames for loaded fonts are formed from the fontset name + the nickname (e.g., |\bodyrm|). \subsec{Defining the csnames for a fontset} The macro |\xfontset| defines all the csnames for the fonts in a fontset, without defining a `-|fonts|' macro. This is used to define a fontset that is never selected in its own right (e.g., its fonts are used only as subscripts and superscripts), and also used internally by the |\fontset| command. Its arguments are |#1| the fontset name, |#2| the csname of a template macro, and |#3| a \ that specifies the font size (sans the `|pt|'). \code |\def\xfontset#1#2#3{ | \def\f##1##2{\expcs\loadfont{#1##1}{##2#3}} | \let\m=\f \let\M=\f | \def\@##1##2##3{\expcs\loadfont{#1##2}{##3 at #3pt }} | #2 |} \endcode \subsec{Defining a complete fontset} The user command |\fontset| is used to define a complete fontset. Its parameters are |#1| (a string of letters) is the fontset name, |#2| (a csname) is a template macro, |#3| (a \) is size in points, |#4| (a \) is baseline skip, |#5| (a fontset name) is the scriptstyle fontset, and |#6| (a fontset name) is the scriptscriptstyle fontset. \code |% Set up a fontset -- define \#1fonts |\def\fontset#1#2#3#4#5#6{% | \xfontset{#1}{#2}{#3}% \endcode \begingroup\leftskip=\parindent \advance\leftskip2\fontdimen6\tentt \noindent Now to define the |\#1fonts| macro. When demand-loading, this macro will call |\#1mathfonts| (to ensure the fonts needed for maths are loaded). Then it will call |\FSELnicknames| to define |\rm|, |\it|, etc., and to define |\textfont\rmfam|, etc. Finally it will set the baseline skip and related parameters and switch to the new |\rm| font. \par\endgroup \code | \expcs\edef{#1fonts}{% | \ifFSELautoload \noexpcs{#1mathsfonts}\fi | \noexpand\FSELnicknames{#1}{#5}{#6}\noexpand#2% | \noexpand\setbaselineskip{#4}% | \noexpand\rm | }% \endcode \begingroup\leftskip=\parindent \advance\leftskip2\fontdimen6\tentt \noindent If we are demand-loading, we must define |\#1mathsfonts| as well. \par\endgroup \code | \ifFSELautoload | \expcs\def{#1mathsfonts}{\FSELloadmaths{#1}{#5}{#6}#2}% | \fi |} \endcode \subsec{Setting font nicknames} |\FSELnicknames| gives definitions to |\f|, |\m| and |\M| so that expanding the template macro defines |\rm| and the like. If the fontset name is |ffff|, and a nickname |xx| is introduced with |\f|, the macro |\xx| is defined to |\ffffxx|. If it is introduced with |\m|, then the font table entries |\textfont\xxfam| and |\scriptfont\xxfam| are also set, and |\xx| expands to `|\fam\xxfam \ffffxx|'. If it is introduced with |\M| then |\scriptscriptfont\xxfam| is also set. The parameters are |#1| the fontset name, |#2| the fontset name for scriptstyle, and |#3| the fontset name for scriptscriptstyle. The implicit fourth parameter is the template macro. \code |\def\FSELnicknames#1#2#3{% | \let\@\relax | \def\f##1##2{% | \expcs\edef{##1}{\noexpcs{#1##1}}% | }% | \def\m##1##2{% | \expcs\textfont{##1fam}\csname#1##1\endcsname | \expcs\scriptfont{##1fam}\csname#2##1\endcsname | \expcs\edef{##1}{% | \fam\expcs\noexpand{##1fam}% | \expcs\noexpand{#1##1}% | }% | }% | \def\M##1{% | \expcs\scriptscriptfont{##1fam}\csname#3##1\endcsname | \m{##1}% | }% |} \endcode \subsec{Setting the baseline skip} The second helper macro, |\setbaselineskip|, sets |\baselineskip| and a bunch of related paramaters and pseudo-parameters like |\smallskipamount|. It takes one parameter, a \. \notepar My definitions for the skips that go before and after displays put less white\-space around displays than is set in plain \TeX. This can be changed by redefining this macro in a style file. \endnotepar \code |\def\setbaselineskip#1{% | \baselineskip#1\relax \normalbaselineskip\baselineskip | \jot0.25\baselineskip | \smallskipamount 0.25\baselineskip plus 0.083\baselineskip | minus 0.083\baselineskip | \medskipamount 0.5\baselineskip plus 0.167\baselineskip | minus 0.167\baselineskip | \bigskipamount 1\baselineskip plus 0.333\baselineskip | minus 0.333\baselineskip | \abovedisplayskip\medskipamount | \abovedisplayshortskip\abovedisplayskip | \advance\abovedisplayshortskip-1\abovedisplayskip | \belowdisplayskip\medskipamount | \belowdisplayshortskip\smallskipamount |} \endcode \subsec{Loading maths fonts} Finally, we need to force the fonts used in maths at a given size to be loaded. for |\f| fonts this does nothing; for |\m| fonts it loads the text and script fonts; for |\M| fonts it also loads the scriptscript font. This is done the first time this fontset is selected, even if no formulas are used (rather than trying to do something complicated like use |\everymath|\dots). Because this macro only needs to be used once for each fontset, it finishes by redefining |\#1mathfonts| to be the same as |\relax|. Its parameters are |#1| the fontset name, |#2| the fontset name for scriptstyle, and |#3| the fontset name for scriptscriptstyle. \code |\def\FSELloadmaths#1#2#3{% | \let\@\relax \def\f##1##2{}% | \def\m##1##2{\csname#1##1\endcsname \csname#2##1\endcsname}% | \def\M##1{\csname#3##1\endcsname \m{##1}}% | \global\expcs\let{#1mathsfonts}\relax |} \endcode %}}} making a fontset %{{{ finishing up \section{Finishing up} We define |\rmfam|, |\mifam| and |\syfam| as aliases for the numbers $0$, $1$ and $2$. This is so that the maths fonts may be included in the font templates without any special arrangements. The names |\itfam|, |\bffam|, |\ttfam|, and |\slfam| are set in |plain.tex|. \code |\chardef\rmfam=0 \chardef\mifam=1 \chardef\syfam=2 \endcode Note that we do not include an alias for the the maths extension font's fam number. This is because there is only one maths extension font---|cmex10|---used for all sizes, so it does not belong in any fontset. \section{Summary of user commands} The following lists the user commands provided by FSEL. A \ is a sequence of letters like |note|; \ is a \TeX\ \ representing size in points (without any final |pt|); an \ is the external name for a font (e.g., `|cmr12|'). \medskip\hrule\medskip \begingroup \parindent=0pt |\autoloadfonts| |\loadfont|\\arg{\} |\xfontset|\arg{\}\\arg{\} |\fontset|\arg{\}\\arg{\}\arg{\}\arg{\}\arg{\} |\def\everyloadfont#1#2{| \dots\ |}| |\def\setbaselineskip#1{| \dots\ |}| \medskip\hrule\medskip \endgroup %}}} finishing up %{{{ bugs \section{Bugs} FSEL clobbers the macros |\f|, |\m|, |\M| and |\@|. %}}} bugs \endcodefile \enddocument \bye %}}} pdcfsel %Local variables: %fold-folded-p: t %fill-prefix: " " %End: