1

In this answer, I've been conservative and used the following code:

\expandafter\scalebox\expandafter{\my@scale}{\usebox{\my@box}}

to make sure not to rely on undocumented (?) behavior of \scalebox from the graphicx package (in case you are wondering, \my@scale has been defined with \pgfmathsetmacro). However, as shown in the following example, it seems that \scalebox fully expands at least its first argument, therefore I am considering if I should simplify the above line by removing the two \expandafter calls.

\documentclass{article}
\usepackage{graphicx}
\usepackage{xfp}

\newcommand*{\scalea}{0.5}
\newcommand*{\scaleb}{\scalebaux}
\newcommand*{\scalebaux}{\fpeval{0.5^2}}

\newsavebox{\mybox}
\sbox{\mybox}{\includegraphics{example-image}} % any box would do

\begin{document}

\scalebox{1.0}{\usebox{\mybox}}\par
\scalebox{\scalea}{\usebox{\mybox}}\par
\scalebox{\scaleb}{\usebox{\mybox}}

\end{document}

Screenshot

Questions

  1. Is it considered to be part of the \scalebox API that it fully expands the two arguments giving scale factors, noted 〈h-scale〉 and 〈v-scale〉 in the below syntax reminder?

    \scalebox{〈h-scale〉}[〈v-scale〉]{〈text〉}
    
  2. If you answered “no”, is there any integer n > 0 such that at least n expansion steps are guaranteed to happen on the same two arguments?

  3. Do the previous answers also apply when using:

    \includegraphics{scale=...}{some-file}
    

    ?

Thanks!

  • 1
    It will expand its first mandatory and its optional argument, they are used inside of dimen assignments, \hbox to cases and inside a \special, in the first two they'll be expanded because that's the way TeX works, in the \special it'll be expanded \edef like (in the special your input will be wrapped inside a \def\Gscale@x and \def\Gscale@y and only those are used inside the \special). – Skillmon Jun 28 at 8:49
  • 1
    From the TeXbook: "TeX's primitive commands \mark{..}, \message{...}, \errmessage{...}, \special{...}, and \write<number>{...} all expand the token lists in braces almost exactly as \edef and \xdef do." The difference is, that you don't need to double # inside those to put a single # in the argument. – Skillmon Jun 28 at 8:55
  • 1
    classic tex has no notion of scaling, you need to use \special or an equivalent whatsit such as \pdfliteral to inject PostScript or PDF transformations around the tex-generated output – David Carlisle Jun 28 at 9:00
  • 1
    @DavidCarlisle except for font scaling, that is available in classic TeX. – Skillmon Jun 28 at 9:05
  • 1
    I was answering your What is the \special used for here question. It is not so much a matter of not breaking existing code as I don't see how you could define this and avoid expansion. It is same as say \setlength the length argument has to be expanded in the end to get a length. So even though \scalebox doesn't do anything special here the arguments get expanded because tex is a macro expansion language and that is what happens unless you stop it happening. – David Carlisle Jun 28 at 9:24
3

This is defined by graphics (not graphicx) the package does nothing to expand these arguments but expansion just happens as a natural course of TeX processing. So the \expandafter are not needed.

The subsidiary question asked in comments as to what is the syntax that the arguments may expand into is harder to answer.

The scale factor is used for two separate things:

  1. working out what size the box is (and taking care of negative scale factors etc).

    in this part of the code, TeX dimen arithmetic is used so it has to be a <factor> in TeXBook syntax notation. Specifically things like \ifdim#2\p@<\z@ have to work, where #2 is one of the supplied scale factors.

  2. The scale factor is passed to the back end code to actually scale the typeset output, here it uses \special or \pdfliteral or whatever suitable whatsit is available.

    The default definition for scaling is:

    \providecommand\Gscale@start{\@latex@error{Scaling not supported}\@ehc
                \global\let\Gscale@start\relax}
    

    That is, it gives an error on first use and does nothing otherwise.

    ie, the default definition has all input being invalid.

    So what happens in other cases depends on the driver (and in 1993-4 when this was written there was a lot more variation than there is now, with far more different dvi drivers being used.)

    Even now, dvips.def does

    \Gscale@x\GPT@space \Gscale@y\GPT@space scale
    

    which means that as well as being a legal <factor> the arguments must expand to a legal PostScript number.

    pdftex does something a bit more complicated but the end result is again that the arguments need to expand to a valid PDF number.

Examples of things that are a <factor> but do not expand to a PostScript or PDF number are \count@ or \value{section} or "FF

  • Thank you very much! As you pointed out, a 〈factor〉 (according to the TeXbook definition) is too general to define the supported syntax. Closer to the desired definition than 〈factor〉 should be 〈decimal constant〉, I suppose, but this probably isn't restrictive enough either (I see a 〈decimal constant〉 may contain commas, and there may be limits on magnitude, number of digits, etc.). The final specification depends, as I understand your answer, on the driver used. At least, I know that the arguments corresponding to scale factors will be fully expanded. :-) – frougon Jun 28 at 14:15

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.