我有一个宏,用于存储一些文本。我想打印该宏的文本,就像它在页眉中位于页面开头一样,以及在页脚中位于页面结尾一样。我可以像这样对计数器执行此操作:
\documentclass{article}
\usepackage{scrpage2,lipsum}
\pagestyle{scrheadings}
\makeatletter
\newcounter{ctr}
\newcounter{@ctr}
\chead{\arabic{@ctr}\setcounter{@ctr}{\value{ctr}}}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}
\makeatother
当设置页眉时(在页面末尾),它会输出内部计数器的值@ctr
,然后将该计数器设置为用户使用的计数器的值ctr
。它将其设置为页面末尾的值(这将是新页面开头的值(这是我想要的))。
当我尝试对包含文本的宏而不是计数器执行“类似”过程时,我没有得到我想要的结果:页眉设置为宏的值,因为它位于页面末尾。我该如何修复此问题?
以下 MWE 显示了问题。计数器和文本应该始终引用相同的数字,但事实并非如此。
\documentclass{article}
\usepackage{scrpage2,lipsum}
\pagestyle{scrheadings}
\ohead{}
\makeatletter
\newcounter{ctr}
\newcounter{@ctr}
\chead{\arabic{@ctr}\setcounter{@ctr}{\value{ctr}}}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}
\def\thetext{First text}
\def\@thetext{\thetext}
\ihead{\@thetext\def\@thetext{\thetext}}
\ifoot{\thetext}
\makeatother
\begin{document}
\lipsum[1-4]
{\Large Becoming Second text}\stepcounter{ctr}
\def\thetext{Second text}
\lipsum[5-7]
{\Large Becoming Third text}\stepcounter{ctr}
\def\thetext{Third text}
\lipsum[8-11]
{\Large Becoming Fourth text}\stepcounter{ctr}
\def\thetext{Fourth text}
\lipsum[12]
\end{document}
在我看来,这可能是某种扩展问题。我尝试使用\edef
而不是\def
,但是没有得到想要的结果。我做错了什么?
答案1
您需要使用\edef
(扩展\def
) 或更好的\xdef
(全局扩展) 代替\def
,否则您只是定义\@thetext
扩展到\thetext
,然后扩展到其当前定义。因此不断说\def\@thetext{\thetext}
不会改变其定义。您想要做的是分配当前的值以\thetext
不\@thetext
“引用”它。
LaTeX 提供了一个扩展版本,称为 ,\protected@xdef
它可以确保\protect
在其参数中正常工作。(还有一个\protected@edef
。)
\def\thetext{First text}
\def\@thetext{\thetext}
\ihead{\@thetext\protected@xdef\@thetext{\thetext}}
\ifoot{\thetext}
答案2
这是使用 的第一次近似值\marks
:
\documentclass{article}
\usepackage{lipsum,etex}
\usepackage{scrpage2}
\pagestyle{scrheadings}
\ohead{}
\makeatletter
\newmarks\grillmark
\newcounter{ctr}
\newcounter{@ctr}
\chead{\arabic{@ctr}\setcounter{@ctr}{\value{ctr}}}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}
\ihead{%
\ifnum\value{page}=1
\expandafter\firstmarks
\else
\expandafter\topmarks
\fi\grillmark}% changed per Martin's suggestion
\ifoot{\botmarks\grillmark}
\makeatother
\begin{document}
\marks\grillmark{First text}
\lipsum[1-4]
{\Large Becoming Second text}\stepcounter{ctr}
\marks\grillmark{Second text}
\lipsum[5-7]
{\Large Becoming Third text}\stepcounter{ctr}
\marks\grillmark{Third text}
\lipsum[8-11]
{\Large Becoming Fourth text}\stepcounter{ctr}
\marks\grillmark{Fourth text}
\lipsum[12]
{\Large Becoming Fifth text}\stepcounter{ctr}
\marks\grillmark{Fifth text}
\lipsum[13-15]
\vspace{0.75in}% Enough to get to end of page
{\Large Becoming Sixth text}\stepcounter{ctr}
\marks\grillmark{Sixth text}
\lipsum[16]
\end{document}
TeXbook 或 TeX by Topic 中有解释:通用标记与 TeX 中的标准标记相同,不同之处在于命令以“s”结尾,后面需要一个数字。此处的数字由\newmarks
提供的分配埃泰克斯。标准分数也可用于\marks0
设置分数和\firstmarks0
,\topmarks0
以及\botmarks0
检索分数。有 32767 个分数类别:我认为绰绰有余。
答案3
这不是答案,而是评论。我需要添加代码,因此将其发布在这里。
如果宏的值在页面顶部发生变化,则此解决方案似乎存在问题。以下 MWE 包括 Martin 和 Seamus 建议的修复,并附加了第五和第六测试来说明问题:
\documentclass{article}
\usepackage{lipsum}
\usepackage{scrpage2}
\pagestyle{scrheadings}
\ohead{}
\makeatletter
\newcounter{ctr}
\newcounter{@ctr}
\chead{\arabic{@ctr}\setcounter{@ctr}{\value{ctr}}}
\cfoot{\arabic{ctr}}
\setcounter{ctr}{1}
\setcounter{@ctr}{1}
\def\thetext{First text}
\xdef\@thetext{\thetext}% changed \def to \xdef per Seamus's comment
\ihead{\@thetext\protected@xdef\@thetext{\thetext}}% changed per Martin's suggestion
\ifoot{\thetext}
\makeatother
\begin{document}
\lipsum[1-4]
{\Large Becoming Second text}\stepcounter{ctr}
\def\thetext{Second text}
\lipsum[5-7]
{\Large Becoming Third text}\stepcounter{ctr}
\def\thetext{Third text}
\lipsum[8-11]
{\Large Becoming Fourth text}\stepcounter{ctr}
\def\thetext{Fourth text}
\lipsum[12]
{\Large Becoming Fifth text}\stepcounter{ctr}
\def\thetext{Fifth text}
\lipsum[13-15]
\vspace{0.75in}% Enough to get to end of page
{\Large Becoming Sixth text}\stepcounter{ctr}
\def\thetext{Sixth text}
\lipsum[16]
\end{document}
请注意,第 3 页底部应该提到5, 并不是6。