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.

Suppose there is

\newcount\c@mycountera
\newcount\c@mycounterb
\newcount\c@mycounterc

Each \newcount uses \alloc@ and that has \wlog{\string#5=\string#2\the\allocationnumber}. Thus to determine which register mycountera uses I can look into the .log file for the (e.g.) \c@mycountera=\count123.

But how can I determine the number of the used register inside of LaTeX automatically? (Something like \registernumber{\c@mycountera} expanding to 123.) After \newcount\c@mycountera it is \the\allocationnumber, but when there is an unknown number of counts created between \newcount\c@mycountera and the time when I need the information this does not help. (I cannot use \xdef\myallocationnumber{\the\allocationnumber} immediatly after \newcount\c@mycountera, because it is defined inside of a package.)

(I suspect that the answer is usable with e.g. \dimen, \box,... too.)

share|improve this question
    
@Stephen Out of curiosity where are you using this? –  Yiannis Lazarides Feb 23 '12 at 15:51
    
as for example \cl@@ckpt stores all the counters in a list, you could check by inspecting the list as well. –  Yiannis Lazarides Feb 23 '12 at 17:11
    
@Sure, although one could extract those as well. Please see my answer, I think you will end up with issues in any case. –  Yiannis Lazarides Feb 23 '12 at 18:12
    
@Stephen Now that the problem is clearer, perhaps it's better to change the question's title. –  egreg Feb 23 '12 at 20:31
    
@egreg I asked a separate question for that: tex.stackexchange.com/questions/45651/… . Sorry for the mess I created her. –  Stephen Feb 24 '12 at 17:15
add comment

3 Answers

up vote 11 down vote accepted

You can use the fact that \meaning will print something like \countXXX for a register:

\def\registernumber#1{%
  \expandafter\registernumberauxi\meaning#1\halt\stop
}
\def\registernumberauxi#1#2\stop{%
  \ifx\halt#1%
    \expandafter\gobbletwo
  \else
    \expandafter\registernumberauxii
  \fi
    {#1}{#2}%
}
\def\registernumberauxii#1#2{%
  \ifnum`#1<48\else\ifnum`#1>57\else#1\fi\fi
  \registernumberauxi#2\stop
}
\def\gobbletwo#1#2{}
\def\halt{\halt}
\newcount\mycount
\registernumber\mycount
\bye

I've used a simple loop to remove the type of register from the front of the number here. There are perhaps better ways to do that, but if proves the principal. The loop uses the fact that \char48 is 0 and \char57 is 9, so anything outside of this range is not a number.

share|improve this answer
    
Quite similar to mine. I'd use `0 and `9 instead of 48 and 57, just not to look at the ASCII table. However, it fails for box registers. –  egreg Feb 23 '12 at 15:23
    
+1 After gobbling six preceding \relax (from \count) in the result your answer exactly solves my problem. Thanks! (I'll wait until tomorrow before accepting it, just in the unlikely case there would be another answer.) –  Stephen Feb 23 '12 at 15:46
1  
@Joseph a simpler (but devious) test for digits is \ifnum1<1#1 digit\else non-digit\fi. –  Bruno Le Floch Feb 23 '12 at 19:24
    
@BrunoLeFloch I was sure there shortcut, but couldn't be bothered to work it out! –  Joseph Wright Feb 23 '12 at 19:52
add comment

Here is one that works also for box registers:

\makeatletter
\def\showregister#1{\expandafter\extract@number\meaning#1\showregister}
\def\extract@number#1{%
  \ifx#1\showregister
     \expandafter\@gobbletwo
  \else
     \if\string"#1#1%
       \expandafter\expandafter\expandafter\@firstoftwo
     \else
       \ifnum`#1<`0 \else \ifnum`#1>`9 \else #1\fi\fi
       \expandafter\expandafter\expandafter\@secondoftwo
     \fi
  \fi
  \extract@rest\extract@number}
\def\extract@rest#1\showregister{#1}

\def\showcounter#1{\expandafter\showregister\csname c@#1\endcsname}
\makeatother

\newcount\AAA
\showregister\AAA

\newdimen\AAB
\showregister\AAB

\newlength\AAC
\showregister\AAC

\newsavebox\AAD
\showregister\AAD

\newcount{AAE}
\showcounter{AAE} % or \expandafter\showregister\csname c@AAE\endcsname

Box register numbers will be in hexadecimal form, preceded by "

The output should be (if starting without any package)

79
102
41
"1A
80

(Moved additional code to this other answer)

Here's a LaTeX3 version:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\showcounter} { m }
  { \exp_args:Nc \showregister { c@#1 } }
\DeclareExpandableDocumentCommand{\showregister} { m }
  {
   \tl_map_function:fN { \cs_meaning:N #1 } \showreg_scan:n
  }
\cs_generate_variant:Nn \tl_map_function:nN { f }
\cs_new:Npn \showreg_scan:n #1
  {
   \bool_if:nT
     {
      (  \int_compare_p:n { `#1 >= `0 } && \int_compare_p:n { `#1 <= `9 } )
      ||
      \int_compare_p:n { `#1 = `" }
      ||
      ( \int_compare_p:n { `#1 >= `A } && \int_compare_p:n { `#1 <= `F } )
     }
     { #1 }
  }
\ExplSyntaxOff

\def\test#1{\edef\x{\showregister#1}\message{\x\space = \meaning#1}}

\test\fboxsep

\newbox\mybox

\test\mybox

The output on the terminal will be

36 = \dimen36
"23 = \char"23
share|improve this answer
    
@egreg: nitpicking, once more, but variables normally (i.e., in the LaTeX3 naming convention) start with \l_ or \g_ or \c_ depending on whether they are to be modified locally, globally, or not at all (constants). –  Bruno Le Floch Feb 23 '12 at 19:26
    
@BrunoLeFloch You're right, of course –  egreg Feb 23 '12 at 20:22
add comment

This is too long for a comment. As per the OP the counter number is to be used for checking the order of packages loaded. This is highly unlikely that it can be a full proof technique.

LaTeX2e, stores all the counters allocated in an \@elt list called \cl@@ckpt.

The following MWE will display all counters allocated and the name of the counter i.e., the part after c@. As you will observe by running the example, hyperTexies like Heiko will fiddle the system. Mostly though, it will predict order of loading:

% See all the counters in LaTeX2e
% and their allocation numbers
\documentclass{book}
\usepackage{graphicx}
\usepackage{longtable}
\usepackage{verse}
\usepackage{hyperref}
\usepackage{caption}
\newcounter{ZZZ}
\begin{document}
\makeatletter
\def\Z{%
   \def\@elt##1{%
       \expandafter\meaning
       \csname c@##1\endcsname
       \space = ##1,\par
    }%
   \cl@@ckpt%
}
All counter in article class plus one!
Expand list.

\Z

\section{Test}
\ifcsname c@section@level\endcsname 
   hyperef package has been loaded
    \else 
   not loaded
\fi
%\expandafter\let\csname c@section@level\endcsname\undefined 
\the\count118

\the\c@section@level

\end{document}  

A better way to check for file order is to check the @filelist.

\documentclass{book}
\usepackage{graphicx}
\usepackage{longtable}
\usepackage{verse}
\usepackage{hyperref}
\usepackage{caption}
\newcounter{ctr}
\makeatletter
\let\afilelist\@filelist
\begin{document}
% Just to see files
\@for\next:=\afilelist\do{%
 \next, \par
}
% Command factory
\stepcounter{ctr}
\@for\next:=\afilelist\do{%
      \expandafter\edef\csname @\next\endcsname{\thectr}
     \stepcounter{ctr}
}

% Define macro to check order
\def\checkpkgorder#1#2{%
   \edef\X{\csname @#1\endcsname}
    \edef\Y{\csname @#2\endcsname}
    \expandafter\ifnum\X\expandafter<\Y
      Yes loaded earlier \X, \Y
     \else
      No loaded later \X, \Y
   \fi
}

\checkpkgorder{book.cls}{ifxetex.sty}
\end{document}
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.