6

This answer shows how to get the current font size, using \makeatletter\f@size\makeatother.

This answer shows how to parse and evaluate a mathematical expression before printing it, using for example \pgfmathparse{sin(60)}\pgfmathresult.

Now I want to combine both and set the font size for a section 1pt smaller than the current font size. This is what I have so far:

\documentclass[11pt]{article}
\usepackage{pgf}

\begin{document}
Before
\makeatletter\fontsize{\pgfmathparse{\f@size - 1}\pgfmathresult pt}{10pt}\selectfont\makeatother
After
\end{document}

I tried to place \makeatletter and \makeatother in different positions (because I don't really understand how they work) but I always get a Missing number, treated as zero error.

Any help is welcome!

PS: I found the package relsize, which does what I want, but I would still want to understand why what I wrote doesn't work.

optical
  • 263

2 Answers2

3

As explained in the other answer, \pgfmathparse cannot be in the argument to \fontsize, which needs something that directly expands to a decimal number (point units are implied).

Here's an implementation that also allows to change the model of the baseline skip set to 1.2 times the font size by adding another optional argument (in parentheses). The default value of the bracketed optional argument is 1 (to be subtracted to the current size).

\documentclass{article}
\usepackage{ebgaramond} % fully scalable font
\usepackage{xparse}

\ExplSyntaxOn

% make an expl3 equivalent available
\cs_new_eq:NN \optical_fontsize:nn \fontsize
\cs_generate_variant:Nn \optical_fontsize:nn { ee }

\NewDocumentCommand{\changesize}{O{1}D(){1.2}}
 {
  \optical_fontsize:ee
   { \fp_eval:n { \use:c { f@size } - #1 } }
   { \fp_eval:n { ( \use:c { f@size } - #1 ) * ( #2 ) } }
  \selectfont
 }

\ExplSyntaxOff

% for testing
\makeatletter
\newcommand{\printsize}{\f@size/\f@baselineskip}
\makeatother

\begin{document}

Standard size \printsize

\changesize One point less \printsize

\changesize[3] Three point less \printsize

\changesize[-4] Standard size \printsize

\changesize[-10](1.1) Bigger size, but let's also check the baseline skip \printsize

\end{document}

The indirect approach of expanding first both arguments to \fontsize is needed, because when LaTeX is evaluating the second argument to \fontsize it has already set \f@size.

enter image description here

egreg
  • 1,121,712
1

This is to explain why your approach does not work, not to advocate this as the best way to decrease the font size. It does not work because \fontsize expects a number, and \pgfmathparse is in "its way". The solution is as simple as moving \pgfmathparse{...} upfront.

\documentclass[11pt]{article}
\usepackage{pgf}

\begin{document}
Before
\makeatletter\pgfmathparse{\f@size - 1}\fontsize{\pgfmathresult pt}{10pt}\selectfont\makeatother
After
\end{document}