4

How do I generate a command of the form \font\namefont =something so that it matches an NFSS-style font selection?

I was doing something wrong and misdiagnosed the problem I was having as a mismatch between two packages. The first required NFSS-style commands, lines of the form

\def \crdfont {\footnotesize\sffamily\bfseries}

In the other a plain TeX-style font command is required, e.g.,

\font \namefont = cmssbx8

In the actual case I had, \def\namefont{\crdfont} actually worked fine (the error came from leaving off the brackets), but it got me thinking: What is the general form of translating NFSS-style selection to plain TeX style?

Is it generally the case that \font \namefont =identifier is interchangeable with \def\namefont{NFSS commands}?

  • why does gchords require a primitive font command? what fails if you use a LaTeX font declaration? – David Carlisle Oct 7 '13 at 21:10
  • \renewcommand\namefont{\fontfamily{cmss}\fontsize{8}{8}\bfseries} does the same, I think. – egreg Oct 7 '13 at 21:10
4

Four ways:

\documentclass{article}

\usepackage{gtrcrd}
\renewcommand\crdfont{\footnotesize\sffamily\bfseries}

\usepackage{gchords}

% LaTeX savvy way
\begingroup\makeatletter\crdfont\edef\x{\endgroup
  \noexpand\DeclareFixedFont\noexpand\namefont
    {\f@encoding}{\f@family}{\f@series}{\f@shape}{\f@size}}\x

% Hackish way (quite similar to how \DeclareFixedFont works
\begingroup\crdfont
\global\font\namefont=\fontname\font
\endgroup

% More hackish way without \global (which can be useful
% if you want to make this definition of \namefont only
% local)
\begingroup\crdfont\expandafter\endgroup
\expandafter\let\expandafter\namefont\the\font

% Even more hackish way without \global and \expandafter
\begingroup\crdfont\edef\x{\endgroup
  \let\namefont=\the\font}\x % \namefont is already unexpandable

\begin{document}

\A[sus2] Fooo
\chord{t}{x,o,p2,p2,o,o}{Asus2}

\end{document}

In all four cases, \show\namefont answers with

\namefont=select font cmssbx10 at 8.0pt

But the simplest way seems to be just

\let\namefont\crdfont

or, if you want to be respectful of LaTeX conventions,

\renewcommand{\namefont}{\crdfont}

Are the last ways equivalent to the \DeclareFixedFont way (or the hackish simplified form)? Not really.

If all the gchords package does with \namefont is using the command to select a font, there should be no difference. But if \namefont is used to extract information from the font with low level commands such as

\dimen0=\fontdimen2\namefont

for storing in \dimen0 the em value for the font, then the \renewcommand (or \let) ways will fail miserably.

Since the only place in gchords.sty where \namefont appears, apart from where it is defined with \font, is

\put(\xoff,0){\hbox to \truewidth\ascale{\hss\namefont #3\hss}}

(on line 159), the \renewcommand or \let ways should suffice.


TeXnical note. Any font choice in LaTeX ultimately reduces to issuing \somefont, after that LaTeX has assigned a meaning to \somefont with a declaration that ultimately reduced to

\global\font\somefont=foo

and foo.tfm exists on the system. For example, \normalfont ends up with issuing \OT1/cmr/m/n/10 (say we are in the default situation, within a 10pt document) and the instruction

\global\font\OT1/cmr/m/n/10=cmr10

has been performed in advance. Actually a command named \OT1/cmr/m/n/10 wouldn't be legal in that context, so the real instruction was

\global\expandafter\font\csname OT1/cmr/m/n/10\endcsname=cmr10

but this is mostly irrelevant. LaTeX font assignment are always global.

There are two ways to access an already defined font; if we have issued \font\somefont=foo, then the expansion of

\the\somefont

is a control sequence equivalent to the command that chooses the external font foo.tfm, in this case exactly \somefont. One might ask why doing this and indeed this would be useless. But after \the we can use \font and, in this case, a control sequence name equivalent to choosing the current font will be generated. See The \the command

So, for instance, if one starts an interactive session in LaTeX and issues

\documentclass{article}
\edef\whatsthecurrentfont{\the\font}
\show\whatsthecurrentfont

the answer would be

> \whatsthecurrentfont=macro:
->\OT1/cmr/m/n/10 .

Similarly,

\expandafter\let\expandafter\whateverthecurrentfontis\expandafter=\the\font

would make \whateverthecurrentfontis a command to set the font that is current at the moment the instruction is performed.

There is another, less known, instruction. If \somefont is a font identifier defined with \font as above, then the expansion of

\fontname\somefont

is a string corresponding to the external font name \somefont refers to. As before, the special identifier \font can be used after \fontname and it again refers to the current font.

This should explain the three hackish ways above.

Let's look at the LaTeX savvy way. We can use the \DeclareFixedFont high level instruction that ultimately performs a \font\somefont=foo type instruction, but uses the NFSS interface.

When \selectfont is issued, maybe as part of the working of commands such as \bfseries, LaTeX updates the meaning of some control sequences, namely

\f@encoding
\f@family
\f@series
\f@shape
\f@size
\f@baselineskip

So, if we want to define a control sequence that chooses the current font independently of the context, we can use \DeclareFixedFont by using those commands. With the common \begingroup\edef\x{\endgroup...}\x trick we are able to access at the current meaning of those commands, freezing it because we use their expansion. After \begingroup, for this particular case, we issue \makeatletter for being able to use \f@... and \cdrfont for selecting the desired font.

2
\DeclareFixedFont\namefont{OT1}{cmss}{m}{n}{10}

probably works

You can of course replace say OT1 by \encodingdefault and cmss by \sfdefault if you want the declaration to adapt to other settings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.