如何编写一个接受数字或 \count 寄存器作为参数的 TeX 宏?

如何编写一个接受数字或 \count 寄存器作为参数的 TeX 宏?

最简单的方法是什么,在纯 TeX 中,定义一个\macro可以用作:

\macro{10}

\macro{\mycount}

这样我就可以将该数字分配给 a\count并对其进行操作吗?

笔记:

\def\macro#1{...\number#1 ...}

不是我想要的是。

换句话说,我怎样才能修改以下 TeX 代码(参见TeXbook):

\def\tick#1{\vrule height 0pt depth #1pt}

\def\tmp{\hbox to 1cm{\hfil\tick4\hfil\tick8}}

\def\doticks#1{\count255=#1%
\ifnum\count255=1%
    \tmp%
\else%
    \advance \count255 by -1\relax%
    \tmp\doticks\count255%
\fi}

\def\ruler#1{\vbox{\hrule\hbox{\tick8\doticks\number#1}}}

以这样的方式:

\ruler{10}

\count255=10
\ruler{\count255}
\bye

输出一页画有两条 10 厘米标尺的页面?

(当前代码出现Missing number错误)。

答案1

除了@Werner 建议使用自己的计数器之外,我认为还需要用大括号括起来\number#1,否则\doticks\number作为其参数。

\def\tick#1{\vrule height 0pt depth #1pt}

\newcount\mycount
\def\tmp{\hbox to 1cm{\hfil\tick4\hfil\tick8}}

\def\doticks#1{\mycount=#1%
\ifnum\mycount=1%
    \tmp%
\else%
    \advance \mycount by -1\relax%
    \tmp\doticks\mycount%
\fi}

\def\ruler#1{\vbox{\hrule\hbox{\tick8\doticks{\number#1}}}} % <--- new braces here

\ruler{10}

\mycount=10
\ruler{\mycount}
\bye

答案2

使用\afterassignment和组,这样就不会破坏的值\count255。还可以使用尾递归。

\def\tick#1{\vrule height 0pt depth #1pt }

\def\tmp{\hbox to 1cm{\hfil\tick4\hfil\tick8}}

\def\doticks#1{\begingroup\afterassignment\dodoticks\count255=#1\endgroup}
\def\dodoticks{%
  \tmp
  \ifnum\count255=1
    \let\next\relax
  \else
    \advance \count255 by -1
    \let\next\dodoticks
  \fi
  \next
}

\def\ruler#1{\vbox{\hrule\hbox{\tick8\doticks{#1}}}}

\ruler{10}

\count255=10
\ruler{\count255}

\bigskip

{\tt\string\count255} is \number\count255

\bye

在此处输入图片描述

与某些的相同@

\def\tick#1{\vrule height 0pt depth #1pt }

\def\tmp{\hbox to 1cm{\hfil\tick4\hfil\tick8}}

\catcode`@=11
\def\doticks#1{\begingroup\afterassignment\d@ticks\count@=#1\endgroup}
\def\d@ticks{%
  \tmp
  \ifnum\count@=\@ne
    \let\next\relax
  \else
    \advance \count255 by \m@ne
    \let\next\d@ticks
  \fi
  \next
}
\catcode`@=12
\def\ruler#1{\vbox{\hrule\hbox{\tick8\doticks{#1}}}}

\ruler{10}

\count255=10
\ruler{\count255}

\bigskip

{\tt\string\count255} is \number\count255

\bye

答案3

不使用临时计数寄存器的版本。需要 etex,但 pdftex 默认包含它。

\def\tick#1{\vrule height 0pt depth #1pt}



\def\doticks #1{%
 \hbox to 1cm{\hfil\tick4\hfil\tick8}%
\ifnum#1>0
  \expandafter\doticks\expandafter{\the\numexpr#1-1\expandafter\relax\expandafter}%
\fi
}

\def\ruler#1{\vbox{\hrule\hbox{\tick8\doticks{#1}}}}

\ruler{10}

\newcount\mycnt

\mycnt=10

\ruler{\mycnt}

\nopagenumbers
\bye

答案4

您还可以采用以下(效率不高!)方式执行此操作:

\def\tick#1{\vrule height 0pt depth #1pt}

\def\tmp{\hbox to 1cm{\hfil\tick4\hfil\tick8}}

\def\doticks#1{\count255=#1\relax
\ifnum\count255=1
    \tmp
\else
    \advance \count255 by -1
    \tmp\doticks{\count255 }%
\fi}

\def\ruler#1{\vbox{\hrule\hbox{\tick8\doticks{#1}}}}

\ruler{10}

\count255=5

\ruler{\count255}

\nopagenumbers
\bye

统治者

实际上,这段代码(也许我应该读一下)确实嵌套了很多,\if..\fi为了避免这种情况,可以这样做(有点愚蠢但有效):

\def\doticks#1{\count255=#1\relax
\tmp
\ifnum\count255=1 
      \let\next\relax
\else
    \def\next {\doticks{\count255 }}%
    \advance \count255 by -1
\fi
\next }

无论如何,在 Plain 格式中有一个循环,在这里使用它非常自然:

\def\tick#1{\vrule height 0pt depth #1pt}

\def\tmp{\hbox to 1cm{\hfil\tick4\hfil\tick8}}

\def\doticks #1{\count255=#1\relax
\loop 
  \tmp
\ifnum\count255>1 
  \advance\count255 by -1
\repeat
}

\def\ruler#1{\vbox{\hrule\hbox{\tick8\doticks{#1}}}}

\ruler{10}

\newcount\mycnt

\mycnt=10

\ruler{\mycnt}

\nopagenumbers
\bye

统治者

如果想要保留egreg存储在中的值,\count 255也可以不创建组来做到这一点。这与手头的任务无关,但对于其他情况,不创建组可能会很有用。

(为了效率,也应该这样做egreg并使用\count@@nem@ne......)

\def\tick#1{\vrule height 0pt depth #1pt}

\def\tmp{\hbox to 1cm{\hfil\tick4\hfil\tick8}}

\def\doticks #1{\edef\restorecountxxlv{\count255=\the\count255\relax}%
                \count255=#1\relax \dotickticks \restorecountxxlv }

\def\dotickticks{\tmp
                 \ifnum\count255>1 
                   \advance\count255 by -1 
                   \expandafter\dotickticks
                 \fi }

\def\ruler#1{\vbox{\hrule\hbox{\tick8\doticks{#1}}}}

\count255 7

\ruler{10}

{\tt\string\count 255} stores \the\count255

\newcount\cnt
\cnt=3

\ruler{\cnt}

{\tt\string\count 255} stores \the\count255

\bye

统治者统治

相关内容