基于这问题,我创建了一个简单的宏,可以打印并存储它的参数,如果再次使用相同的参数发出它,它不会打印任何内容:
% !TEX TS-program = xelatexmk
\RequirePackage{filecontents}
\begin{filecontents}{mypackage.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}
\newenvironment{myenv}{\ignorespaces}{\par\ignorespacesafterend}
\DeclareOption{skiprepetitions}{%
\AtBeginDocument{\let\mypackage@print\mypackage@print@skip}%
}
\DeclareOption{keeprepetitions}{%
\AtBeginDocument{\let\mypackage@print\mypackage@print@keep}%
}
\ExecuteOptions{keeprepetitions}
\ProcessOptions\relax
\RequirePackage{xifthen}
\def\mypackage@storedval{} % create a macro to later store a value in
\newcommand{\mycommand}[1]{%
\ifthenelse{\isempty{#1}}
{% if empty just print an empty line
\mbox{}%
}
{% if not empty
\mypackage@print{#1}%
\def\mypackage@storedval{#1}%
}%
}
\def\mypackage@print@skip#1{%
\ifthenelse{\equal{#1}{\mypackage@storedval}}
{\mbox{}}
{#1}%
}
\def\mypackage@print@keep#1{#1\\}
\end{filecontents}
\documentclass{article}
\usepackage[skiprepetitions]{mypackage}
\begin{document}
\begin{myenv}
\mycommand{A} \\ %A
\mycommand{A} \\ %empty
\mycommand{A} \\ %empty
\mycommand{} \\ %empty
\mycommand{B} \\ %B
\mycommand{C} \\ %C
\mycommand{C} \\ %empty
\mycommand{A} \\ %A
\end{myenv}
\begin{myenv}
\mycommand{A} \\ %A
\mycommand{A} \\ %empty
\newpage
\mycommand{A} \\ %A
\end{myenv}
\end{document}
我现在想让它“重置”或“忘记”在特定环境的分页符和边界处存储的内容,以便在新页面上或在新环境中做打印其参数,即使前一个参数相同。
上面的文档中注释掉的是我希望看到的值。
答案1
据我了解,以下内容可以满足您的要求(感谢大卫·卡莱尔的评论有关提示perpage
!):
\RequirePackage{filecontents}
\begin{filecontents}{mypackage.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}
\RequirePackage{perpage}
\newcounter{mycounter}
\MakePerPage{mycounter}
\newenvironment{myenv}{%
% \mycommand is only defined inside the environment
\let\mycommand\my@command
% Make sure the next \mycommand isn't ignored, even if its argument
% matches the value stored in \mypackage@storedval.
\setcounter{mycounter}{0}%
\ignorespaces
}{%
\par\ignorespacesafterend
}
\DeclareOption{skiprepetitions}{%
\AtBeginDocument{\let\mypackage@print\mypackage@print@skip}%
}
\DeclareOption{keeprepetitions}{%
\AtBeginDocument{\let\mypackage@print\mypackage@print@keep}%
}
\ExecuteOptions{keeprepetitions}
\ProcessOptions\relax
\RequirePackage{xifthen}
\def\mypackage@storedval{} % create a macro to later store a value in
\newcommand{\my@command}[1]{%
\ifthenelse{\isempty{#1}}%
{% if empty just print an empty line
\mbox{}%
}%
{% If this is the first \stepcounter{mycounter} executed since the current
% page was started, this sets 'mycounter' to 1.
\stepcounter{mycounter}%
\mypackage@print{#1}%
\def\mypackage@storedval{#1}%
}%
}
\def\mypackage@print@skip#1{%
\ifthenelse{\cnttest{\value{mycounter}}>{1}\AND
\equal{#1}{\mypackage@storedval}}%
{\mbox{}}%
{#1}%
}
\def\mypackage@print@keep#1{#1\\}
\end{filecontents}
\documentclass{article}
\usepackage[skiprepetitions]{mypackage}
\begin{document}
\setlength{\parindent}{0pt}
\begin{myenv}
\mycommand{A}\\ %A
\mycommand{A}\\ %empty
\mycommand{A}\\ %empty
\mycommand{}\\ %empty
\mycommand{B}\\ %B
\mycommand{C}\\ %C
\mycommand{C}\\ %empty
\mycommand{A}\\ %A
\end{myenv}
\begin{myenv}
\mycommand{A}\\ %A
\mycommand{A}\\ %empty
\newpage
\mycommand{A}\\ %A
\end{myenv}
\end{document}
我使用了一个名为 的新计数器,mycounter
该计数器受 约束\MakePerPage{mycounter}
。这意味着\stepcounter{mycounter}
任何给定页面上的第一个都会重置mycounter
为 1,因为的可选参数的默认值是\MakePerPage
。
我这样设置myenv
,在 的开头,mycounter
设置为 0。此外,每当以非空参数调用 时,\stepcounter{mycounter}
就会执行。因此,执行此操作后,当且仅当以下情况时, 才等于 1:\mycommand
\stepcounter{mycounter}
mycounter
\mycommand
这是当前页面上的第一个调用,或者;\mycommand
这是当前环境中的第一次通话myenv
。
这是您需要的“忽略标准”的基础。唯一需要检查的另一件事是,当我们处于“可能忽略模式”时,传递给b 的参数\mycommand
与保存的值不同(因为所有这些都来自后空虚检查)。
请注意,我将您的\mycommand
to重命名为\my@command
并且\let\mycommand\my@command
仅在myenv
环境内执行,因此如果您调用\mycommand
任何环境之外的to myenv
,LaTeX 将报告错误(未定义的命令)。
您可能希望将\stepcounter{mycounter}
调用移到宏的开头\my@command
:这取决于传递空参数时您想要的行为。它应该使新状态成为“可能忽略模式”,还是应该让状态保持不变(在我的代码中:后者)?这是属于您的决定。但由于您只是\mbox{}
为空参数输出一个,因此差异通常不会很明显……
脚注
a. 经过两次编译运行后,由于该perpage
包依赖于该.aux
文件。
b. 即参数非空,且调用\mycommand
既不是页面上的第一个,也不是环境中的第一个。