\documentclass{beery}

\begin{document}


\section*
  {%
    \SetFontStep*{1}%
    The \pkg{fontscale} package%
  }

A user interface for setting document font sizes

Oliver Beery

Version 1.0.1\quad{}8~March 2024


\section{Introduction}
\label{sec:intro}

\subsection{About}
\label{subsec:about}

\listheading{The \pkg{fontscale} package provides the following functionalities:}
\begin{itemize}
  \item
  Set document font sizes via a classic, modular, or musical typographic scale.
  \item
  Set arbitrary scales, sizes, and baselineskips for the standard font size commands \cs{tiny}, \cs{scriptsize}, \cs{footnotesize}, \cs{small}, \cs{normalsize}, \cs{large}, \cs{Large}, \cs{LARGE}, \cs{huge}, and \cs{Huge}.
  \item
  Set the font size settings mid\-/document or within a local group.
  \item
  Set the font size by setting the font step, scale, or size.
  \item
  Set the font size relative to the current font size.
  \item
  Use the current font step, scale, size, and baselineskip directly, for example, for printing or within calculations.
  \item
  Print sample text to test different font sizes.
  \item
  For advanced users, store the step, scale, size, and baselineskip of each font size command in \pkg{expl3} variables.
\end{itemize}


\subsection{Loading the package}
\label{subsec:loading}

This package requires the 10~October 2023 \pkg{l3kernel} update.
Since this update is fairly recent, you may need to ensure that your \LaTeX{} installation is up\-/to\-/date before using this package.

This package lets the user set arbitrary font sizes.
This works with most fonts produced today, but, for historical reasons, the default Computer Modern font is available only in a number of fixed sizes.
If you get a warning that Computer Modern is not available in the requested size, you may need to add the code \cs{RequirePackage{fix-cm}} before \cs{documentclass} to make Computer Modern available at arbitrary font sizes.

\cs{usepackage}\marg{fontscale}
\nopagebreak\newline
\cs{fontscalesetup}\marg{\meta{keys}}

Load the \pkg{fontscale} package via the usual command in the document preamble.
This package has no package options.
Instead, the package keys are set up via the command \cs{fontscalesetup}\marg{\meta{keys}}.
\meta{keys} must receive a comma\-/separated list of keys and their associated values.
The package keys are documented in \S\ref{sec:choosing} and \S\ref{sec:overwriting}.

Many \LaTeX{} document classes have a font size option (\Key{10pt}, \Key{11pt}, \Key{12pt}, etc.\@) which not only changes the set of document font sizes, but also modifies additional settings such as the page layout and vertical spacing which were specifically designed to work with those font sizes.
For this reason, you may want to set the document class font size option close to the value of \cs{normalsize} set by this package.

Internally, this package sets up each font size command from \cs{tiny} to \cs{Huge} using the kernel command \cs{@setfontsize}\---they have no additional functionality beyond that of \cs{@setfontsize}.
Unlike the standard document classes, the font size commands set up by this package do not change the vertical spacing for displayed math and list structures.
If the user would like to add this functionality or perhaps other features to the font size commands, they can do so via hooks, which are documented in the \LaTeX{} kernel.


\subsection{Terminology}
\label{subsec:terminology}

When using the \pkg{fontscale} package, each font size, including the standard font size commands from \cs{tiny} to \cs{Huge}, has a step, scale, size, and baselineskip.
The latter two parameters are the familiar first and second arguments to the low\-/level font command \cs{fontsize}\marg{\meta{size}}\marg{\meta{baselineskip}}.
The font scale is the relative font size; the ratio of the font size to \cs{normalsize}.
The font step is the number of font size gradations from \cs{normalsize}, which has a step of \num{0}.
Table~\ref{table:fontsteps} lists the font step of each font size command.

\input{./fontscale-manual-table-font-steps.tex}


\section{Choosing the typographic scale}
\label{sec:choosing}

\Key{typographic-scale}
  [classic-10pt, classic-11pt, classic-12pt, modular, musical]
  [classic-10pt]
\newline
\Key{modular/ratio}[\meta{number}][1.125]
\newline
\Key{musical/ratio}[\meta{number}][2]%
\nopagebreak\newline
\Key{musical/notes}[\meta{integer}][5]

The key \Key{typographic\-/scale} sets the font sizes using a classic, modular, or musical typographic scale.
These are common methods of choosing a set of document font sizes.
The choice of typographic scale initializes to \Key{classic\-/10pt}.

The key \Key{typographic\-/scale} can also be set in a condensed format via the keys \Key{classic\-/10pt}, \Key{classic\-/11pt}, \Key{classic\-/12pt}, \Key{modular}, or \Key{musical}, which set the key \Key{typographic\-/scale} to the corresponding value.

The classic typographic scale consists of the traditional font sizes
\numlist{6;7;8;9;10;11;12;14;16;18;21;24;36;48;60;72}.%
\footnote{See \S{}3.1 of \textit{The Elements of Typographic Style} by Robert Bringhurst.}
They have been used since the sixteenth century and are the default font sizes on most computer software.
The keys \Key{classic-10pt, classic-11pt, classic-12pt} set the size of each font size command to values based on their position in the classic typographic scale.
The size of \cs{normalsize} is the named point size.
The sizes of the other font size commands are the adjacent font sizes in the scale.
Table~\ref{table:classicscales} lists the size of each font size command when using a classic typographic scale.

\input{./fontscale-manual-table-classic.tex}

The key \Key{modular} sets the font sizes from \cs{tiny} to \cs{Huge} using a modular typographic scale.
In a modular scale, each font size is a fixed ratio from the adjacent font sizes.%
\footnote{\url{https://alistapart.com/article/more-meaningful-typography/}}
Here, the base font size is the size of \cs{normalsize}, which can be set via the key \Key{normalsize/size}[\meta{size}], more documented in \S\ref{sec:overwriting}.
If not set, \cs{normalsize} initializes to \qty{10}{pt}.
The modular ratio can be set via the key \Key{modular\slash{}ratio}.
The initial modular ratio is \num{1.125}.

\input{./fontscale-manual-table-modular-musical.tex}

The key \Key{musical} sets the font sizes according to their position in a musical typographic scale.
The font size is calculated using the formula:%
\footnote
  {%
    I have referenced this article by Spencer Mortensen:
    \newline
    \url{https://spencermortensen.com/articles/typographic-scale/}%
  }
\[ f_i = f_0 \times r ^ { i / n } \]
$f_0$ is the base font size, the size of \cs{normalsize}.
$f_i$ is the font size with font step~$i$.
$n$ is the number of notes in the musical scale\---the number of font size gradations or steps above \cs{normalsize}.
$r$ is the ratio of the musical scale, the ratio of the highest to the lowest note $ f_n / f_0 $.
(The modular typographic scale is actually a special case of the musical typographic scale where $n=1$.)

The musical ratio~$r$ and the number of notes~$n$ can be set via the keys \Key{musical\slash{}ratio} and \Key{musical\slash{}notes}.
The initial musical ratio\---\num{2}\---and the initial number of notes\---\num{5}\---are the same as that of the classic typographic scale.%
\footnote{Ibid.}
Conveniently, \cs{Huge} is \num{5} steps above \cs{normalsize}.
The font size of \cs{normalsize}~$f_0$ can be set using the key \Key{normalsize/size}[\meta{size}], more documented in \S\ref{sec:overwriting}.
When using a musical typographic scale, \cs{normalsize} initializes to \qty{10}{pt}.%
\footnote {I have set the initial value to \qty{10}{pt} instead of the \qty{12}{pt} recommended by the Spencer Mortensen article because this matches the default settings of the standard \LaTeXe{} document classes.}

\Key{baselineskip-size-ratio}[\meta{number}][1.2]
\KeepNextPar*

The key \Key{baselineskip\-/size\-/ratio} sets the ratio of the font baselineskip to the font size.
By default, the font baselineskip of each font size command equals its font size times \Key{baselineskip\-/size\-/ratio}.
Users should not adjust this value unless they really know what they are doing.
When using increased line spacing, users should prefer the low\-/level font command \cs{linespread} or the \pkg{setspace} package.


\section{Overwriting the typographic scale}
\label{sec:overwriting}

In some situations, users may need to explicitly set the scale, size, or baselineskip of a font size command, overwriting the value set by the keys in \S\ref{sec:choosing}.
Note that the font steps and the scale of \cs{normalsize} are constants and cannot be changed.

\Key{\meta{font size command}/scale}[\meta{number}]
\KeepNextPar*

The keys \Key{\meta{font size command}\slash{}scale} set the scale of \meta{font size command} to \meta{number}, ignoring the value set by the key \Key{typographic-scale}.
The key \Key{normalsize\slash{}scale} is not defined.

\Key{\meta{font size command}/size}[\meta{size}]
\KeepNextPar*

The keys \Key{\meta{font size command}\slash{}size} set the size of \meta{font size command} to \meta{size}, ignoring the values set by the keys \Key{typographic-scale} and \Key{\meta{font size command}\slash{}scale}.
\meta{size} supplies a default unit of \unit{pt}.

The package will issue a warning if the user sets the keys \Key{\meta{font size command}\slash{}size} and \Key{\meta{font size command}\slash{}scale} for the same \meta{font size command} since the latter key will be ignored.

\Key{\meta{font size command}/baselineskip}[\meta{skip}]
\KeepNextPar*

The keys \Key{\meta{font size command}\slash{}baselineskip} set the font baselineskip of \meta{font size command} to \meta{skip} instead of calculating it from the size of \meta{font size command} and \Key{baselineskip\-/size\-/ratio}.
\meta{skip} supplies a default unit of \unit{pt}.

\Key{\meta{font size command}}[\meta{size}]
\nopagebreak\newline
\Key{\meta{font size command}}[\meta{size}/\meta{baselineskip}]

The keys \Key{\meta{font size command}} set the keys \Key{\meta{font size command}\slash{}size} or \Key{\meta{font size command}\slash{}baselineskip} in a condensed format.
The latter format resembles traditional typographic notation where the size and leading of a text can be expressed as, for example, $10/12$ or $11/13$.
The number before/after the slash is the size/leading in \unit{pts}.

\Key{ignore-order}[true, false][false]
\KeepNextPar*

The user should take care to ensure that the font sizes and font baselineskips remain in the correct order when directly setting the scales, sizes, or baselineskips of the different font size commands.
The magnitudes of the sizes and baselineskips should be ordered from \cs{tiny} to \cs{normalsize} to \cs{Huge}.
This is important for typographic and syntactic consistency.
This package will issue a warning if they are not in the correct order.
The user can disable this warning via the key \Key{ignore\-/order}[true] or just \Key{ignore\-/order}.


\section{User commands}
\label{sec:usercommands}

\subsection{Expandable font parameters}
\label{subsec:fontparameters}

\cs{CurrentFontStep}
\nopagebreak\newline
\cs{CurrentFontScale}
\newline
\cs{CurrentFontSize}
\nopagebreak\newline
\cs{CurrentFontBaselineskip}

These are fully expandable commands that expand to the current font step, scale, size, or baselineskip.
They can be used for printing or within calculations.
Caution: \cs{CurrentFontStep} will expand to nothing if the current step is undefined.

Internally, \cs{CurrentFontStep}, \cs{CurrentFontScale}, and \cs{CurrentFontSize} use the kernel command \cs{f@size}.
\cs{CurrentFontSize} expands to \texttt{f@size pt}.
\cs{CurrentFontBaselineskip} expands to the kernel command \cs{f@baselineskip}.
Note that the low\-/level font command \cs{fontsize}\marg{\meta{size}}\allowbreak\marg{\meta{baselineskip}} sets \cs{f@size} before expanding its second argument.
This means that \cs{CurrentFontStep}, \cs{CurrentFontScale}, and \cs{CurrentFontSize} may need to be first expanded if used in \meta{baselineskip}.
This package provides the command \cs{SetFontSizeBaselineskip} as an alternative to \cs{fontsize} + \cs{selectfont} that avoids this issue (\S\ref{subsec:fontsize}).

\subsection{More font sizing commands}
\label{subsec:fontsize}

The \pkg{fontscale} package provides the commands \cs{SetFontStep}, \cs{SetFontScale}, \cs{SetFontSize}, \cs{ScaleFont}, and \cs{SetFontSizeBaselineskip} which set the font size in different ways.
The first three commands have a starred version which sets the font size relative to the current font size.
Internally, these commands all use the low\-/level font commands \cs{fontsize}\marg{\meta{size}}\allowbreak\marg{\meta{baselineskip}} and \cs{selectfont}.
These commands should be used only in special cases.
Generally, users should prefer the font size commands from \cs{tiny} to \cs{Huge} for typographic and syntactic consistency, although \cs{SetFontStep*}\marg{\meta{integer}} can use a font size command directly.

\cs{SetFontStep}\marg{\meta{number}}
\nopagebreak\newline
\cs{SetFontStep*}\marg{\meta{number}}

\cs{SetFontStep} sets the font size by setting the font step to \meta{number}.
The starred version \cs{SetFontStep*} adds \meta{number} to the current font step.
If the choice of typographic scale is not modular or musical, then the only valid values for \meta{number} are the integers from \num{-4} to \num{5}, corresponding to the font size commands from \cs{tiny} to \cs{Huge}.
\cs{SetFontStep} will issue an error if the step is invalid.
\cs{SetFontStep} sets the font baselineskip to the calculated font size \texttimes{} \Key{baselineskip\-/size\-/ratio}.
If the step matches the step of any font size command, then that font size command will be used directly.

\listheading{Examples:}
\begin{itemize}
  \item
  For example, \cs{SetFontStep}\marg{-2} and \cs{SetFontStep}\marg{2} use \cs{footnotesize} and \cs{Large}.
  Note that it is typically better to use the equivalent font size command in place of \cs{SetFontStep}\marg{\meta{integer}}.
  \item
  If the current font size is \cs{normalsize}, \cs{SetFontStep*}\marg{1} and \cs{SetFontStep*}\marg{-1} use \cs{large} and \cs{small}.
  This is useful for moving up or down a note on the typographic scale.
  \item
  If the choice of typographic scale is modular or musical, \cs{SetFontStep*}\marg{-0.5} sets the font size and font baselineskip to values between that of \cs{normalsize} and \cs{small}.
  Otherwise, it produces an error.
\end{itemize}

\cs{SetFontScale}\marg{\meta{number}}
\nopagebreak\newline
\cs{SetFontScale*}\marg{\meta{number}}

\cs{SetFontScale} sets the font size by setting the font scale to \meta{number}.
The font baselineskip is set to the calculated font size \texttimes{} \Key{baselineskip\-/size\-/ratio}.
The starred version \cs{SetFontScale*} adds \meta{number} to the current font scale.
For example, \cs{SetFontScale}\marg{1.25} makes the font size 25\% larger than \cs{normalsize}.
If the current font size is \cs{normalsize}, \cs{SetFontScale*}\marg{0.25} is equivalent to \cs{SetFontScale}\marg{1.25}.

\cs{SetFontSize}\marg{\meta{size}}
\nopagebreak\newline
\cs{SetFontSize*}\marg{\meta{size}}

\cs{SetFontSize} sets the font size to \meta{size}.
\meta{size} supplies a default unit of \unit{pt}.
The font baselineskip is set to the font size \texttimes{} \Key{baselineskip\-/size\-/ratio}.
The starred version \cs{SetFontSize*} adds \meta{size} to the current size.
For example, \cs{SetFontSize*}\marg{1} and \cs{SetFontSize*}\marg{-1pt} increase and decrease the current font size by a \unit{pt}.

\cs{ScaleFont}\marg{\meta{number}}
\KeepNextPar*

Scales the current font size and the current font baselineskip by \meta{number}.
\cs{ScaleFont} resembles the \cs{scalefont} command provided by the \pkg{scalefnt} package, except that it uses floating point calculations and clears the stretch and shrink components of the font baselineskip.
For example, if the current font size and font baselineskip are \qty{10}{pt} and \qty{12}{pt}, using \cs{ScaleFont}\marg{0.8} will reduce them proportionally to \qty{8}{pt} and \qty{9.6}{pt}.

\cs{SetFontSizeBaselineskip}\marg{\meta{size}}\marg{\meta{baselineskip}}
\KeepNextPar*

Sets the font size and font baselineskip to \meta{size} and \meta{baselineskip}.
Both \meta{size} and \meta{baselineskip} supply a default unit of \unit{pt}.
\cs{SetFontSizeBaselineskip} can be used as an alternative to \cs{fontsize} + \cs{selectfont} as it avoids the issue with \cs{f@size} discussed in \S\ref{subsec:fontparameters}
\vfill\pagebreak%manual

\subsection{Testing and debugging}
\label{subsec:debug}

The commands documented here are intended primarily for testing and debugging.
I have used them often when developing this package so I think users will find them helpful.

\cs{PrintFontParameters}
\nopagebreak\newline
\cs{PrintAllFontParameters}

\cs{PrintFontParameters} prints the current step, scale, size, and baselineskip in this order in a comma\-/separated list of key = value pairs.
If the current step is undefined (as explained for \cs{SetFontStep} in \S\ref{subsec:fontsize}), it will be left blank.
\cs{PrintAllFontParameters} prints the step, scale, size, and baselineskip of each font size command.

\cs{PrintSampleText}\oarg{\meta{text}}
\nopagebreak\newline
\cs{PrintSampleText*}\oarg{\meta{text}}

\cs{PrintSampleText} prints \meta{text} in each font size ordered from \cs{tiny} to \cs{Huge} each followed by a paragraph break.
The starred version \cs{PrintSampleText*} reverses the sizing order.
The \meta{text} can be changed via the optional argument, but cannot contain \cs{par} tokens.
The default \meta{text} is \enquote{The \texttt{fontscale} package: A user interface for setting document font sizes}.

\cs{PrintFontSizeCommand}
\KeepNextPar*

\cs{PrintFontSizeCommand} tests whether the current font size and font baselineskip match that of any font size command.
If so, it prints the name of that font size command.
If not, it instead prints \enquote{UNDEFINED\@}.
One useful way of printing example text is by using
\cs{PrintSampleText}\allowbreak\oarg{\cs{PrintFontSizeCommand}:\textvisiblespace{}\cs{PrintFontParameters}}.

\subsection
  {%
    \texorpdfstring
      {More on \cs{fontscalesetup}}
      {More on \textbackslash{}fontscalesetup}%
  }
\label{subsec:fontscalesetup}

\cs{fontscalesetup}\marg{\meta{keys}}
\KeepNextPar*

Sets and processes the \pkg{fontscale} package keys and uses \cs{normalsize}.
\cs{fontscalesetup} can be applied mid\-/document or locally within the current \TeX{} group.
The key \Key{reset} is also available.
Its value must be either \texttt{initial} or \texttt{preamble}.
The key \Key{reset}[initial] or just \Key{reset} sets all the keys to their initial values.
The key \Key{reset}[preamble] sets all the keys to their values at the end of the preamble (or does nothing if used before the end of the preamble).


\section{Programming}
\label{sec:programming}

For \LaTeX3 programmers, the \pkg{fontscale} package provides some public \pkg{expl3} variables.
No public \pkg{expl3} functions are provided.
The package stores in public variables the step, scale, size, and baselineskip of each font size command.
These variables should not be modified directly.
Instead, they should be modified only indirectly via the command \cs{fontscalesetup}.

Each takes the form:

\begingroup
  \ttfamily
  \textbackslash{}c\_fontscale\_\meta{font size command}\_step\_fp
  \nopagebreak\newline
  \textbackslash{}l\_fontscale\_\meta{font size command}\_scale\_fp
  \newline
  \textbackslash{}l\_fontscale\_\meta{font size command}\_size\_dim
  \nopagebreak\newline
  \textbackslash{}l\_fontscale\_\meta{font size command}\_baselineskip\_skip
\endgroup

Exception:
\cs{l_fontscale_normalsize_scale_fp} is not defined.
The scale of \cs{normalsize} is instead stored as the constant \cs{c_fontscale_normalsize_scale_fp}, which always equals \num{1}.

The step, scale, size, and baselineskip of each font size command are also stored in property lists, one for each font size command:

\texttt{\textbackslash{}l\_fontscale\_\meta{font size command}\_prop}

\end{document}