最简单的方法是什么,在纯 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@
,@ne
等m@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