如何确定计数使用哪个寄存器

如何确定计数使用哪个寄存器

假设有

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

每个都\newcount使用\alloc@并且 具有\wlog{\string#5=\string#2\the\allocationnumber}。因此,为了确定哪个寄存器mycountera使用,我可以查看.log文件中的 (例如) \c@mycountera=\count123

但是我如何才能自动确定 LaTeX 内部使用的寄存器的数量?(类似于\registernumber{\c@mycountera}扩展为123。)之后\newcount\c@mycountera\the\allocationnumber,但是当在和我需要信息的时间之间创建了未知数量的计数时,\newcount\c@mycountera这无济于事。(我不能\xdef\myallocationnumber{\the\allocationnumber}立即使用\newcount\c@mycountera,因为它是在包内定义的。)

(我怀疑答案也可以与 \dimen、\box 等一起使用。)

答案1

您可以使用以下事实\meaning来打印类似\countXXX寄存器的内容:

\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

我在这里使用了一个简单的循环来从数字前面删除寄存器的类型。也许有更好的方法可以做到这一点,但如果证明了原理。循环利用了事实,即\char48是 0 并且\char57是 9,因此超出此范围的任何东西都不是数字。

答案2

这是一个也适用于盒子寄存器的方法:

\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

盒子寄存器编号将采用十六进制形式,前面带有"

输出应该是(如果启动时没有任何包)

7910241 “
1A80 ​ ​


将附加代码移至另一个答案

这是 LaTeX3 版本:

\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

终端上的输出将是

36 = \dimen36
"23 = \char"23

答案3

这段评论太长了。根据 OP,计数器数字用于检查加载的包的顺序。这不太可能成为一种完整的证明技术。

LaTeX2e,将所有分配的计数器存储在\@elt名为的列表 中\cl@@ckpt

以下 MWE 将显示所有已分配的计数器及其名称,即 之后的部分c@。正如您在运行示例时所观察到的,像 Heiko 这样的 hyperTexies 会摆弄系统。不过,它主要会预测加载顺序:

% 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}  

检查文件顺序的更好方法是检查@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}

相关内容