2

I am trying to calculate some width in a macro and use the macro for scalebox. However I get a flood of errors when I try to pass the macro to scalebox.

MinimalExample:

\documentclass{article}

\usepackage{pgf}

\newcounter{Counter}
\setcounter{Counter}{1}

\newcommand{\testOk}{1}
\newcommand{\testFail}{
 \theCounter
 \stepcounter{Counter}
}


\setlength\parindent{0pt}
\begin{document}
  \testFail %ok
  \scalebox{\testFail}{a} %ok
  \scalebox{\testFail}{a} %fails
\end{document}

Update

Since I want to actually use scalebox transparently in a new environment I decided to try something along the lines pointed at by Steven B. Segletes. Redefining the macro to do first the macroexpansion and then call the underlying macro with the value. I tried:

\newenvironment{imageRow}{
 \begingroup\imageRow@reset
 \LetLtxMacro{\oldScalebox}{\scalebox}
 \renewcommand{\scalebox}[2]{
    \edef\tmpValue{##1}
    \oldScalebox{\tmpValue}{##2}
 }
}{
 \imageRow@complete\endgroup
}

However I keep getting 'missing endcsname' errors. (And a flood following that).

If it matters here is the function I am currently trying to pass as first argument:

\newcommand{\getIt}{%
    \stepcounter{imageRow@getCount}%
    %   
    \expandafter\ifx\csname imageRow@scale@Image@\theimageRow@rowCount @\alph{imageRow@getCount}\endcsname\relax
        1%
        \PackageWarning{imageRow}{Return to get correct scaling factors.}%
    \else
        \csname imageRow@scale@Image@\theimageRow@rowCount @\alph{imageRow@getCount}\endcsname\relax
    \fi
}
ted
  • 3,377
  • \scalebox needs a number but you have passed it instructions to typeset a counter and then do some arithmetic to add 1 and assign that value to a counter, that is never going to work, you need to do the arithmetic fist then pass in the value. – David Carlisle Nov 05 '14 at 16:33
  • @DavidCarlisle: I am trying to write a small package to solve my old problem http://tex.stackexchange.com/a/125722/19326. The idea is to automatically do some calculation and retireve the result to pass it to a scaling package like scalebox or adjustbox. I need csname for the retrival. – ted Nov 05 '14 at 16:40
  • yes but as Steven shows below you need to pass the result not instructions to execute some arithmetic and assignments. internally it is count@=#1 which is fine if #1 is a number but if you pass it \the\mycount\relax \advance\mycount by 1 then it doesn't work. – David Carlisle Nov 05 '14 at 16:44
  • Telling what you'd like to achieve would be a big step towards a solution. – egreg Nov 05 '14 at 19:00
  • I think your update suffers the same as your original. That is, argument #1 has more than just a number... it has operations. Using the \edef in your revised \scalebox will not remedy that. Therefore, you still end up passing operations to \oldscalebox. – Steven B. Segletes Nov 05 '14 at 20:31
  • The update code is missing loads of % from ends of lines, and if I understand you correctly you are passing tokens including \setcounter and \PackageWarning into the first argument which will put them in an \edef those commands can not possibly work in that context. The first argument of \scalebox is already expanded by \scalebox anything that you could put in an \edef can be passed as the argument to \scalebox so your redefinition does not do anything other than add spaces to the output. – David Carlisle Nov 05 '14 at 21:57
  • @egreg: I am trying to wrap tex.stackexchange.com/a/125722/19326 into a package. The idea is to have an environment where I can do \addImage{someCode} to add an image and \getScale to get the factor by which the image should be scaled so that all pictures fill the row, and have equal height while keeping aspect ratios. I would like these two command so adjustbox scalbox or tikzscale can be used, depending on the situation. Take a look at https://github.com/coderinside/imageRow tp see what I got so far. – ted Nov 05 '14 at 23:53
  • @DavidCarlisle I think I still have to get my head around tex, I am thinking a little bit in c-style here so to me int func{return 2;} and int func{int i=getOneSomehow(); return i+1;} are equal in the outcome of the program. – ted Nov 06 '14 at 00:02
  • So is there someway that i can take an arbitrary defined command, execute it once and store its return in a way that it is save to pass to scalebox? – ted Nov 06 '14 at 00:04
  • @ted tex is a macro expansion language so more like the c pre-processor than C, the analogy is not putttting a function there that returns an integer its like, in fact is putting a macro their that inlines the body of the function, That wouldn't work in c either in general – David Carlisle Nov 06 '14 at 00:06
  • @DavidCarlisle regarding the missing %, I tried it out, the % is the minimum amount to have no extrawhitespace in the output. If I do \getIt\getIt I get two numbers with no space in between, e.g. 1.2349.034 (notice the second decimal dot, with space it would be 1.234 9.034) – ted Nov 06 '14 at 00:07
  • @ted there is no return it os a macro language not a functional language, if you macro leaves a value in a register or another macro, then you can pass in that result, but in general there is no result or return from an arbitrary macro – David Carlisle Nov 06 '14 at 00:08
  • @ted your redefinition of scalebox (if it deosn't die in the edef would add 2 spaces before the scaled text and one space after – David Carlisle Nov 06 '14 at 00:09
  • @ted I added an answer to the question you linked. – egreg Nov 06 '14 at 00:21

1 Answers1

1

Introduce \tfscalebox, so that the counter indexing occurs outside of the \scalebox argument.

\documentclass{article}

\usepackage{pgf}

\newcounter{Counter}
\setcounter{Counter}{1}

\newcommand{\testOk}{1}

\newcommand\tfscalebox[1]{\scalebox{\arabic{Counter}}{#1}\stepcounter{Counter}}

\setlength\parindent{0pt}
\begin{document}
  \tfscalebox{a} %ok
  \tfscalebox{a} %ok
  \tfscalebox{a} %ok
\end{document}

enter image description here

If you want the macro to perform a test before deciding to either output the \scalebox or increment Counter, then you could always pass a secondary argument to the macro on which to test. Below, I do it as an optional argument [F] to decrement the scale:

\documentclass{article}
\usepackage{pgf}
\newcounter{Counter}
\setcounter{Counter}{1}
\newcommand\tfscalebox[2][T]{\scalebox{\arabic{Counter}}{#2}%
  \if#1F\addtocounter{Counter}{-1}\else\stepcounter{Counter}\fi%
  \if0\arabic{Counter}\stepcounter{Counter}\fi}
\setlength\parindent{0pt}
\begin{document}
  \tfscalebox{a} %ok
  \tfscalebox{b} %ok
  \tfscalebox{c} %ok
  \tfscalebox[F]{d} %ok
  \tfscalebox[F]{e} %ok
  \tfscalebox{a} %ok
  \tfscalebox[F]{e} %ok
  \tfscalebox[F]{e} %ok
  \tfscalebox[F]{e} %ok
  \tfscalebox[F]{e} %ok
\end{document}

enter image description here

  • WHile this is going the right way, I updated my anwser (see update), basically I try to go with your solution of evaluating my function and then passing the value to scalebox. – ted Nov 05 '14 at 17:39