我有一些 LaTeX3 代码,我想添加一个新功能。这将涉及在特定点选择各种操作。有两个选择,这两个选择是独立的。我读入选择的时间和执行选择的时间是不同的,所以我需要先存储选择一段时间,然后再读回。由于列表中的每个术语都有一个选择,所以我需要将选择存储在类似的列表中。我可以想到各种方法来做到这一点,我想知道是否存在当前正确的方法(在 中找不到texdoc interface3
),或者,如果没有,是否有比其他方法更好的特定方法。
以下是一些想法:
- 这是我在 lua 等语言中执行的操作:存储 0-3 范围内的整数或字符串并测试位。不过,对于整数来说,这有点混乱(
if i%2 == 0 then
很简单,但第二位更像if (i/2)%2 < 1 then
),而对于字符串来说则更容易if s:sub(1,1) == 0 then
)。 - 定义两个新的布尔值并存储必要的“设置”宏。因此,在标记列表中,我存储标记
\bool_set_true:N \l_bool_a \bool_set_false:N \l_bool_b
,然后在执行之前执行它\bool_if:NTF
以确定要采取的操作。
以下是我在一次性版本的 LaTeX2 场景中可能做的事情:
\documentclass{article}
\newif\ifchoicea
\newif\ifchoiceb
\def\saveifs{%
\edef\restoreifs{\expandafter\noexpand\csname choicea\ifchoicea
true\else false\fi\endcsname\expandafter\noexpand\csname
choiceb\ifchoiceb true\else false\fi\endcsname}
}
\def\stateofifs{%
Choice A is \ifchoicea true\else false\fi,
choice B is \ifchoiceb true\else false\fi.
}
\begin{document}
\stateofifs
\choiceatrue
\saveifs
\stateofifs
\emph{You wait.
Time passes}
\choicebtrue
\choiceafalse
\stateofifs
\restoreifs
\stateofifs
\end{document}
得出的结果为:
Choice A is false, choice B is false.
Choice A is true, choice B is false.
You wait. Time passes
Choice A is false, choice B is true.
Choice A is true, choice B is false.
在我的实际用例中,我会将“状态”存储在一个数组中。因此,在伪代码中,它可能类似于:
while (getting_data) do
process_data
convert_choice_to_storable_form
push(choice_array,storeable_form)
end
do
something_complicated
end
while (rendering_data) do
pop(choice_array,storeable_form)
convert_storable_form_to_choices
foreach choice do
if choice then
do_something_stupid
else
do_something_clever
fi
end
end
答案1
我将维护两个属性列表;一个在设置条件时更新,第二个在发出条件时加载第一个的状态\saveifs
。然后可以使用“静态”属性列表将条件恢复到固定状态。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% Document commands
\NewDocumentCommand{\setchoice}{ m m }
{
(Setting~#1~to~#2)\par
\andrew_setchoice:nn { #1 } { #2 }
}
\NewDocumentCommand{\saveifs}{ }
{
(Saving ifs)\par
\andrew_saveifs:
}
\NewDocumentCommand{\restoreifs}{ }
{
(Restoring ifs)\par
\andrew_restoreifs:
}
\NewDocumentCommand{\stateofifs}{} % no internal version, it's just for showing the situation
{
State of ifs:\par
\prop_if_empty:NT \l__andrew_conditionals_prop { *Still~no~conditionals* }
\prop_map_inline:Nn \l__andrew_conditionals_prop
{
Choice~##1~is~##2\par
}
}
% Variables
\prop_new:N \l__andrew_conditionals_prop
\prop_new:N \l__andrew_saved_conditionals_prop
% Functions
\cs_new_protected:Npn \andrew_setconditional:nn #1 #2
{
\use:c { bool_set_#2:c } { l__andrew_cond_ #1 _bool }
\prop_put:Nnn \l__andrew_conditionals_prop { #1 } { #2 }
}
\cs_new_protected:Npn \andrew_setchoice:nn #1 #2
{
\cs_if_free:cT { l__andrew_cond_ #1 _bool }
{
\bool_new:c { l__andrew_cond_ #1 _bool }
}
\andrew_setconditional:nn { #1 } { #2 }
}
\cs_new_protected:Npn \andrew_saveifs:
{
\prop_set_eq:NN \l__andrew_saved_conditionals_prop \l__andrew_conditionals_prop
}
\cs_new_protected:Npn \andrew_restoreifs:
{
\prop_map_inline:Nn \l__andrew_saved_conditionals_prop
{
\andrew_setconditional:nn { ##1 } { ##2 }
}
}
\ExplSyntaxOff
\begin{document}
\stateofifs
\setchoice{a}{true}
\saveifs
\stateofifs
\setchoice{b}{true}
\setchoice{a}{false}
\stateofifs
\saveifs
\setchoice{a}{true}
\restoreifs
\stateofifs
\end{document}
条件是动态创建的。因此,如果需要,\setchoice{foo}{true}
它会创建\l__andrew_cond_foo_bool
,但不必知道该名称。它还将更新属性列表\l__andrew_conditionals_prop
。
该命令\saveifs
将设置\l__andrew_saved_conditionals_prop
为等于当前值\l__andrew_conditionals_prop
。要恢复值,只需从此属性列表进行映射即可。