2

This is what I'm trying to do:

\documentclass{article}
\usepackage{setspace}
\begin{document}
\begin{center}
  \setstretch{1.2}
  \begin{center}
    \setstretch{0.9} // here I need it to become 0.9 * 1.2
  \end{center}
\end{center}
\end{document}
yegor256
  • 12,021

1 Answers1

4

You can define a \setrelativestretch command using xfp facilities for the computations with floating points.

The trick is that the current factor is stored in \baselinestretch, but we need to ensure it is expanded before calling \setstretch.

In the example I have exaggerated the factors just to make the result more evident.

After the inner \end{center} the stretch factor will automatically return to its previous value.

\documentclass{article}
\usepackage{setspace}
\usepackage{xfp}

\usepackage{lipsum} % for mock text

\newcommand{\setrelativestretch}[1]{%
  \begingroup\edef\x{\endgroup
    \noexpand\setstretch{\fpeval{(#1)*(\baselinestretch)}}%
  }\x
}

\begin{document}
\begin{center}
\setstretch{1.5}
\lipsum[3][1-5]
\begin{center}
\setrelativestretch{0.7}
\lipsum[4][1-5]
\end{center}
\lipsum[5][1-5]
\end{center}

\end{document}

enter image description here

A conceptually better solution using expl3 features:

\documentclass{article}
\usepackage{setspace}
\usepackage{xparse}

\usepackage{lipsum} % for mock text

\ExplSyntaxOn
\cs_new_eq:NN \yegor_setstretch:n \setstretch
\cs_generate_variant:Nn \yegor_setstretch:n { e }

\NewDocumentCommand{\setrelativestretch}{m}
 {
  \yegor_setstretch:e { \fp_eval:n {(#1)*(\baselinestretch)} }
 }
\ExplSyntaxOff

\begin{document}
\begin{center}
\setstretch{1.5}
\lipsum[3][1-5]
\begin{center}
\setrelativestretch{0.7}
\lipsum[4][1-5]
\end{center}
\lipsum[5][1-5]
\end{center}

\end{document}

I define an alias for \setstretch so I can also define a variant for it that first expands its argument.

egreg
  • 1,121,712