Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Is there a way to get a macro to hide its output but still do the logic with counters etc.?

I'm stuck on the definition of macro \dontoutput below.

% \documentclass, \usepackage, ...

\newcount\innercount

\def\dontoutput#1{#1} % ???

\long\def\inner#1{\advance\innercount 1\relax}

\long\def\outer#1{
  \innercount 0\relax
  \dontoutput{#1}    % call it, increment counters in \inner, but don't output anything!
  Inner called \the\innercount times.
  \def\inner##1{##1} % we want to output it too now.
  #1                 % call again
}

\begin{document}
  \outer{
    a
    \inner{b}
    \inner{c}
    \inner{d}
    e
  }
\end{document}

% Outputs:  a e Inner called 3 times. abcde
% I'd like:     Inner called 3 times. abcde
share|improve this question
add comment

2 Answers

up vote 3 down vote accepted
\newcounter{inner}
\def\inner#1{#1}
\def\outer#1{%
  {\sbox0{\setcounter{inner}{0}\def\inner##1{\stepcounter{inner}}#1}}%
  Inner called \theinner\ times. #1}

Command on LaTeX counters act globally; so we typeset the argument of \outer in a box where we set the counter to zero and define \inner to step the counter. The default definition of \inner, which is reinstated outside the box, is to typeset its argument.

Following Martin's suggestion I have also put the box assignment in a group, for greater safety. The command \sbox builds a box saving it into a storage bin, but typesetting nothing in the document. However all commands are performed, in particular we can redefine \inner to have a different meaning, since when we enter a box construction another group is opened. The group around the \sbox operation ensures that the storage bin will be forgotten at the group's end.

Usually one writes

\newsavebox{\mybox}

in the preamble and then \sbox{\mybox}{...} in order to \usebox{\mybox} somewhere else; however, \mybox refers just to a certain internal number and the numbers 0, 2, 4, 6, and 8 are reserved for "scratch boxes" and one can freely use them for purposes such as the present one.

share|improve this answer
    
You might want to wrap the box assignment into a group as well to keep it local. –  Martin Scharrer Dec 14 '11 at 23:05
    
Thanks, this works. I had to lookup the \sbox command - do I understand it correctly - in that it sort of saves its content (whatever happens inside the braces) and doesn't print it? –  Martin Janiczek Dec 14 '11 at 23:10
    
@MartinJaniczek: It stores it in a box register which are usually declared using \newbox\mybox, but are actually just numbers. Here you store it in box #0, which is often used for temporary usages. To typeset the box (even multiple times) use \usebox{\mybox} or \usebox{0} (or even \usebox\mybox and \usebox0 ). –  Martin Scharrer Dec 14 '11 at 23:13
add comment

You can store the content into a box which is not used, as egreg already showed.

You could also use \nullfont to switch off any text output. However, paragraphs are still inserted AFAIK, so \let\par\relax would also be useful. Finally you want to disable that any command switches to a real font again, so \let\selectfont\relax should also be added. Either put these in a group or save and restore the original definitions (first \let\origfoo\foo then later \let\foo\origfoo). You should use \normalfont after restoring \selectfont in the latter case.

Usually the use of a box is preferable, I guess.

share|improve this answer
    
Thanks for the alternative way to switch off the output. The box way suits me better, but it's nice to know it can be done this way too. –  Martin Janiczek Dec 14 '11 at 23:13
    
I would not recommend this approach, as math would be typeset nonetheless. Using a box is quite safer; if paragraphs can be expected, it's sufficient to say \setbox0=\vbox{...}. –  egreg Dec 14 '11 at 23:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.