6

In the answer by @Johan_E to Which measurement units should one use in LaTeX?, there are useful charts showing the size, in points, of 1em, the width of an M, 1ex, and the height of an x. How can I produce such a chart? Most useful would be an example of how to produce the first row to illustrate the measurement commands and/or one other row (say bf, it) to illustrate how the font selection is done. (I know how to get a bf,it M, but how do I get a bf,it 1em?)

I am forever try to scale zlmtt to match my font, zooming in on a pdf viewer screen and eye-balling it. Having actual measurements would make such scaling much easier.

Employing the advice of @jfbu in the comment below, I have the following extracted from the xintools loop, which seems to work.

\documentclass{article}
\usepackage[T1]{fontenc}

\newcommand\oneem{}
\newcommand\oneex{}
\newcommand\Mwidth{}
\newcommand\xheight{}
\newcommand\xwidth{}
\newcommand\xdepth{}

\begin{document}
\edef\oneem{\the\dimexpr 1em\relax}%
\edef\oneex{\the\dimexpr 1ex\relax}%
\setbox0\hbox{M}%
\edef\Mwidth{\the\wd0}%
\setbox0\hbox{x}%
\edef\xheight{\the\ht0}%
\edef\xwidth{\the\wd0}%
\edef\xdepth{\the\dp0}%
%
\begin{tabular}{lllllll}
  font & 1em    & M-width & 1ex    & x-height & x-width & x-depth \\
  rm   & \oneem & \Mwidth & \oneex & \xheight & \xwidth & \xdepth
\end{tabular}
\end{document}
  • I think you should tell how you scale zlmtt; there's probably some automatic method to find the correct factor without looking at tables or eyeballing. – egreg Feb 18 '16 at 14:03
  • @dedded You can directly link to the answer tex.stackexchange.com/a/97970/36296 – user36296 Feb 18 '16 at 14:05
  • @egreg, I'd still like to know the answer to this question (as it's more general), but automatic scaling to equivalent x-heights would be the best solution for (most of?) my use cases. I currently scale with `\usepackage[scale=x.x]{zlmtt}, where x.x is determined by trial-and-error. @samcarter, thank you, I've edited the question. How did you determine the link to the answer? – dedded Feb 18 '16 at 14:18
  • 1
    well, LaTeX makes public only a subset of the underlying TeX language. Among the things hidden to the average user are the token list registers and variables and, relevant here, the \edef primitive. LaTeX's \newcommand is a wrapper for \def, but there is no one for \edef. Replace all your \renewcommand's by \edef's and it should work. By the way, do leave the \newcommand in the preamble, to check that nothing defined in packages is overwritten. I should have chosen longer names, like \heightofletterx. (my answer uses \xdef which is \global\edef, needed due to cell scope). – user4686 Feb 19 '16 at 7:52
  • "I should have chosen longer names, like \heightofletterx" I like the emacs convention of a my prefix when I want to avoid collisions with my own personal code and published code, which helps preserve brevity. – dedded Feb 19 '16 at 12:45
6

Here you go:

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage[margin=1cm]{geometry}
\usepackage{xinttools}

\newcommand\WithFont [4]{%
   \csname text#1\endcsname {%
      \csname text#3\endcsname {%
         \csname text#2\endcsname {#4}}}}

\begin{document}
\begin{table}
  \centering
\Large\textbf{Computer Modern fonts (pdf\LaTeX) [10pt]}\\
\small
Selected using \detokenize{\textA{\textB{\textC{(some text)}}}},\\
with A in \detokenize{{rm, sf, tt}}; B in \detokenize{{md, bf}}; C in
\detokenize{{up, it, sl, sc}}\\
  \begin{tabular}{*{9}{l}}
    \bf Font&\bf 1em&&\bf M-width&\bf 1ex&&\bf x-height&\bf x-width&\bf x-depth\\
\hline
\xintForpair #1#2 in {(Roman,rm), (Sans,sf), (Typewriter,tt)} \do
{%
\xintFor #3 in {up, it, sl, sc}\do
  {%
    \xintFor #4 in {md, bf}\do
    {%
      \WithFont {#2}{#3}{#4}{#1, #3, #4\normalsize
                             \xdef\oneem{\the\dimexpr 1em\relax}%
                             \xdef\oneex{\the\dimexpr 1ex\relax}%
                             \setbox0\hbox{M}\xdef\Mwidth{\the\wd0}%
                             \setbox0\hbox{x}\xdef\xheight{\the\ht0}%
                                             \xdef\xwidth{\the\wd0}%
                                             \xdef\xdepth{\the\dp0}}%
      &\oneem&\WithFont{#2}{#3}{#4}{\normalsize\strut M}&\Mwidth
      &\oneex&\WithFont{#2}{#3}{#4}{\normalsize x}&\xheight&\xwidth&\xdepth
     \\
     }%
   }\hline
}\hline
  \end{tabular}
\end{table}
\end{document}

(\normalsize added in edit, because all the table was produced earlier under \small regime, including computation of dimensions).

enter image description here


Attention that in the table above, there are a number of font substitutions going on :

LaTeX Font Warning: Font shape `T1/cmss/m/sc' in size <9> not available
(Font)              Font shape `T1/cmr/m/sc' tried instead on input line 55.

LaTeX Font Warning: Font shape `T1/cmss/m/sc' in size <10> not available
(Font)              Font shape `T1/cmr/m/sc' tried instead on input line 55.

LaTeX Font Warning: Font shape `T1/cmss/bx/sc' undefined
(Font)              using `T1/cmss/bx/n' instead on input line 55.

LaTeX Font Info:    Font shape `T1/cmtt/bx/n' in size <9> not available
(Font)              Font shape `T1/cmtt/m/n' tried instead on input line 55.
LaTeX Font Info:    Font shape `T1/cmtt/bx/n' in size <10> not available
(Font)              Font shape `T1/cmtt/m/n' tried instead on input line 55.
LaTeX Font Info:    Font shape `T1/cmtt/bx/it' in size <9> not available
(Font)              Font shape `T1/cmtt/m/it' tried instead on input line 55.
LaTeX Font Info:    Font shape `T1/cmtt/bx/it' in size <10> not available
(Font)              Font shape `T1/cmtt/m/it' tried instead on input line 55.

LaTeX Font Warning: Font shape `T1/cmtt/bx/sl' undefined
(Font)              using `T1/cmtt/bx/n' instead on input line 55.

LaTeX Font Info:    Font shape `T1/cmtt/bx/sl' in size <10> not available
(Font)              Font shape `T1/cmtt/m/n' tried instead on input line 55.
LaTeX Font Info:    Font shape `T1/cmtt/bx/sl' in size <9> not available
(Font)              Font shape `T1/cmtt/m/n' tried instead on input line 55.

LaTeX Font Warning: Font shape `T1/cmtt/bx/sc' undefined
(Font)              using `T1/cmtt/bx/n' instead on input line 55.

LaTeX Font Info:    Font shape `T1/cmtt/bx/sc' in size <10> not available
(Font)              Font shape `T1/cmtt/m/n' tried instead on input line 55.
LaTeX Font Info:    Font shape `T1/cmtt/bx/sc' in size <9> not available
(Font)              Font shape `T1/cmtt/m/n' tried instead on input line 55.

I thought about for example drawing a strike-through line across the full row, but doing this automatically has complications. As this is not the main focus of the OP, I just leave standing as is.


For automatic determination, shamelessly copying over egreg's answer into another syntax. Notice that xinttools used above is a separate package from xintfrac used below.

\documentclass[border=4pt]{standalone}

\usepackage{zlmtt}
\usepackage{xintfrac}


\makeatletter
\newcommand{\scalezlmtt}[2][1]{%
   {\setbox0\hbox{\normalfont #2}%
    \setbox2\hbox{\fontfamily{lmtt}\selectfont #2}%
    \xdef\zlmtt@scale {\xintPFloat {\xintMul{#1}{\ht0/\ht2}}}%
    \typeout{zlmtt scaling factor: \zlmtt@scale}% 
   }%
}%
\makeatother

\AtBeginDocument{\scalezlmtt[.9]{a}}

\begin{document}

TT font scaled to 90\% lowercase: A\texttt{A}a\texttt{a}

\end{document}

enter image description here

You will find in the log:

zlmtt scaling factor: 0.9143980556305698

This differs in the last digit from l3fp's calculation, but that's not so much typographically relevant...

(try it with \xintPFloat [32]... for example if you want more --irrelevant-- digits, well ok I did it:

zlmtt scaling factor: 0.91439805563056980826357007831488

I would really need a scaling factor of 0.1 to hide my irrelevant toying here)

  • 1
    Well, that's going to take some study! Thank you, I'm sure I'll have some follow-up questions. – dedded Feb 18 '16 at 14:24
  • Ugh, maybe I declared victory too soon. My results are quite similar to Johan_E's original, as I said, but larger than yours. I chalked it up to possible differences in our systems. But when I run your code, I get your results. (I'm only looking at the first row, and I also generated a bfseries row.) Now I'm not sure which numbers to believe. – dedded Feb 19 '16 at 12:51
  • 1
    I think the \small is still in effect in your loop when the font is sampled. – dedded Feb 19 '16 at 13:13
  • @dedded yes good point. That was sort of on purpose but the [10pt] is then inadequate. I thought I needed the small to fit the table on the page. ... well ok I will fix it. Thanks for pointing that out. – user4686 Feb 19 '16 at 14:19
  • sorry about the generated confusion ... – user4686 Feb 19 '16 at 14:27
4

I can offer a macro for deciding the scale factor as automatically as possible:

\documentclass{article}

\usepackage{zlmtt}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\scalezlmtt}{O{1}m}
 {
  \hbox_set:Nn \l_tmpa_box { \normalfont #2 }
  \hbox_set:Nn \l_tmpb_box { \fontfamily{lmtt}\selectfont #2 }
  \tl_set:cx { zlmtt@scale }
   {
    \fp_eval:n
     {
      #1 *
      \dim_to_fp:n { \box_ht:N \l_tmpa_box } /
      \dim_to_fp:n { \box_ht:N \l_tmpb_box }
     }
   }
  \typeout{ zlmtt~scaling:~\tl_use:c { zlmtt@scale } }
 }
\ExplSyntaxOff

\AtBeginDocument{\scalezlmtt{A}}

\begin{document}

TT font scaled to uppercase: A\texttt{A}a\texttt{a}

\end{document}

enter image description here

If I change the call to \scalezlmtt{a},

\AtBeginDocument{\scalezlmtt{a}}

\begin{document}

TT font scaled to lowercase: A\texttt{A}a\texttt{a}

\end{document}

I get

enter image description here

There's also a “correction factor”

\AtBeginDocument{\scalezlmtt[.9]{a}}

\begin{document}

TT font scaled to 90\% lowercase: A\texttt{A}a\texttt{a}

\end{document}

enter image description here

This should be flexible enough for avoiding lookups in tables or eyeballing. By doing the job \AtBeginDocument, the call to \normalfont will be the right one. Just load other font packages before this instruction, because some of them do actions at begin document too.

The trick is to use lmtt for the measurement, so this doesn't yet trigger the loading of <encoding>zlmtt.fd.

In the log file you'll see something like

zlmtt scaling: 0.9143980556305699

(this is the value used for the last example) and you may be wanting to round it and use in the package option once you're sure it will suit you.

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.