3

While improving on a class file of mine, I found that I used the multido package in just a single line of code and naturally I set out to remove that dependency.

My class uses several counters and arrays to compute and typeset a lot of information generated by comparably few user input. Thus, in the following, I cannot simply change the variable structure of my minimal example. Also, I would like to keep the mathmode to output the numbers to stay consistent with the rest of the document.

Furthermore, the actual loop-body is a lot more complicated than this example.

\documentclass{article}

\usepackage{etoolbox}%
\usepackage{multido}%
\usepackage{arrayjobx}%

\newcounter{RUNNER}%
\newcounter{THISOFTEN}%  
\setcounter{THISOFTEN}{3}%
\newarray{SHOWME}%
\readarray{SHOWME}{Item1&Item2&Item3}%
\newarray{SHOWMORE}%
\readarray{SHOWMORE}{-3&-10&55}%

\newcommand*\PrintOLD{%
  \multido{\i=1+1}{\value{THISOFTEN}}{%
    \SHOWME(\i)($\SHOWMORE(\i)$)~}}%

\newcommand*\PrintNEW{%
  \setcounter{RUNNER}{0}%
  \whileboolexpr{test{\ifnumless{\value{RUNNER}}{\value{THISOFTEN}}}}{%
    \stepcounter{RUNNER}%
      \SHOWME(\value{RUNNER})($\SHOWMORE(\value{RUNNER})$)~}}%

\begin{document}
Hello World: \PrintOLD


Hello World: \PrintNEW
\end{document}

Generated Output

enter image description here

My solution using etoolbox adds white spaces I cannot seem to get rid of.

pdflatex and xelatex (which I normally use) generated the same output.

So far I tried to circumvent the if-clause inside the boolean expression of whileboolexpr by adding a new boolean or toggle to be used there and moved the if-clause at the end of the loop-body. I also tried unlessboolexpr as well as several other if… versions. Furthermore, I played with expansion order, but I am certainly not an expert with this.

And in a more desperate attempt I shrunk the macro to a single line without any spaces at all – just to make sure.

I am currently reluctant to try recursions as I find those harder to maintain for complicated, evolving loop-bodies. Furthermore, I have a couple of ideas on using the whileboolexpr construct to implement some features still on the TODO-list which so far have caused me headaches.

Thus I would be most grateful for Ideas on making whileboolexpr work in this case or any other solution that resembles a classical loop (preferably without introducing a new package dependency).

  • Please correct your code so that it compiles without error and outputs something demonstrating the problem you are asking about. – cfr Jan 1 '15 at 2:34
  • the problem doesn't appear to be with etoolbox. It seems that between the etoolbox code and the code from arrayjobx the whitespace is entering. Replace the \SHOWME.... with any string such as hello% and you'll see that no extra white space has been generated. – A.Ellett Jan 1 '15 at 3:37
  • 2
    Why aren't you using etoolbox lists? I would never recommend arrayjobx. – egreg Jan 1 '15 at 10:24
  • @A.Ellett Yes, I should have phrased my question more precisely. Since all other macros accessing araay-elements like this seem to work fine, I opted to use in this case in my question. – Valryne Jan 1 '15 at 11:13
  • @egreg This is a project I started for learning more of Latex/Tex than using sections. I just removed ifthen and a lot of other ballast when I learned about etoolbox. arrayjobx is used so intesively, that I wanted to get rid of other packages I knew had problems before even thinking about switching to etoolbox lists. Whith what I know now, arrayjobx will have to go soon. – Valryne Jan 1 '15 at 11:32
2

The problem seems to be with the way that arrayjobx parses numbers such as in

  \SHOWME(\value{RUNNER})($\SHOWMORE(\value{RUNNER})$)~%%

\value{RUNNER} returns LaTeX's internal representationof a number and not a printable number, which is what arrayjobx is expecting

Try the following macro and everything works out fine:

\newcommand*\PrintNEWer{%
  \def\aecnt{0}%\setcounter{RUNNER}{0}%
  \whileboolexpr{
    test { \ifnumcomp{\aecnt}{<}
                     {\value{THISOFTEN}}
         }}
    {%%
      \edef\aecnt{\number\numexpr\aecnt+1\relax}%%
      \SHOWME(\aecnt)($\SHOWMORE(\aecnt)$)~%%
    }}%%

But also, just rewriting you \SHOWME slightly differently will suffice

either

\SHOWME(\number\value{RUNNER})

or

\SHOWME(\theRUNNER)

will work.

  • Yes, a simple X\SHOWME(\value{RUNNER})X (with the counter set to 1) prints “X[space][space]Item1X”. The macros are too involved to propose a fix. – egreg Jan 1 '15 at 10:23
  • I would have never guessed that arrayjobx does not expect a number as most other packages I used so far. I was aware of a difference between internal and printable numbers, but will certainly pay more attention to this in the future. I will use \theRUNNER until I have the time to switch to etoolbox lists as @egreg proposed. Just one more question: Is there a particular reason for having %% (two percentage signs) at some lines in your code? – Valryne Jan 1 '15 at 11:41
  • @Valryne there's nothing special about %% other than I find it easier to see when writing a document. The habit is old and kind of entrenched. But, other than being a habit of mine, there is no deeper significance. – A.Ellett Jan 1 '15 at 15:16

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.