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.

Using ConTeXt, I have a macro which can be given a unique key value:

\macro{000010}
\macro{000011}
\macro{000010}
\macro{000010}
\macro{000012}
\macro{000011}

I need to be able to access information on the number of times that value has appeared so far in the document and the number of times that value appears in total. The code above would give me this information:

1/3
1/2
2/3
3/3
1/1
2/2

The information is not simply displayed in the page, I need to access this information for use in conditionals.

How can I obtain information on how many times a macro has held a certain value and how many times it will in the entire document?

share|improve this question
6  
just noticed the context tag, you should probably make it explicit in the question if you want context rather than latex. My answer below is working with latex, but most of the code is plain so would work with context if someone could fill in the context versions of AtEndDocument and \@auxout which I'm sure must exist. –  David Carlisle Apr 2 '12 at 23:53
add comment

2 Answers

up vote 9 down vote accepted

The canonical way to do this in ConTeXt is to use counters (and context takes care of the appropriate number of runs).

\unexpanded\define[1]\macro
    {\ctxcommand{doifnotstructurecounter("macro::#1")}
        {\definestructurecounter[macro::#1]}%
     \incrementstructurecounter[macro::#1]%
     \rawstructurecounter[macro::#1]/\laststructurecounter[macro::#1]}

Note: I had to use a low-level Lua function doifnotstructurecounter because there is a bug in the TeX wrapper \doifundefinedstructurecounter. Once this bug is fixed, you can replace the first line with \doifundefinedstructurecounter{macro::#1}.

You might also be interested in my experimental visualcounter module that, well, displays counters visually.

share|improve this answer
    
Do I use \rawstructurecounter[macro::#1] to obtain the value for use in a conditional e.g. within \startlua: if \rawstructurecounter[macro::#1] < 5 then? –  Village Apr 3 '12 at 0:06
1  
(Untested) \rawstructurecounter is defined as an unexpanded macro, so it will not be expanded inside \startlua. However, all the counters are stored in the counters.data table, and you should be able to access a counter using counters.value("macro::#1"). See strc-num.lua for details (look at the latest beta, because some of the old commands were dropped last week). –  Aditya Apr 3 '12 at 0:12
1  
@Aditya: would it be wise to have \unexpanded\define ? –  Taco Hoekwater Apr 3 '12 at 8:13
1  
@TacoHoekwater: I think so, it is not expandable. In any case the macro will fail miserably when placed where expandable text is desirable (section headers and such) –  Aditya Apr 3 '12 at 16:40
    
This does not seem to compile. I added the definition of the macro in the preamble, then tried some sample macros between \starttext and stoptext. system > tex > error on line 9 in file test.tex: LuaTeX error, line 9 has \macro{000010}. –  Village Apr 7 '12 at 5:54
show 1 more comment

This takes a couple of runs to get the totals:

\documentclass{article}

\makeatletter
\def\macro#1{%
\expandafter\ifx\csname count#1\endcsname\relax
  \expandafter\gdef\csname count#1\endcsname{0}%
  \AtEndDocument{%
    \immediate\write\@auxout{%
      \global\noexpand\@namedef{maxcount#1}{\csname count#1\endcsname}}}%
\fi
\count@\csname count#1\endcsname
\advance\count@\@ne
\the\count@/\csname maxcount#1\endcsname
\expandafter\xdef\csname count#1\endcsname{\the\count@}}
\makeatother
\begin{document}

\macro{000010}

\macro{000011}

\macro{000010}

\macro{000010}

\macro{000012}

\macro{000011}

\end{document}

enter image description here

share|improve this answer
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.