抱歉,标题不清楚;我不确定如何描述我想做的事情(请随意编辑我的标签)。但这是我最好的想法:
我有一组数据;每个数据都是一对有序的文本。假设对于每个数据,我都可以创建一个相应的宏,该宏“知道”其两个文本部分。我不知道这样的宏如何工作,但假设该宏\mynumber
表示(six
,two
)和\mycolor
表示(blue
,red
)。
我想要的是一个宏,\arrange
这样编译
Lorem ipsum \mynumber, dolor sit amet \mycolor, etc...
\arrange
生产
Lorem ipsum six, dolor sit amet blue, etc...
two, red
我正在寻找的关键属性是\arrange
显示第二个条目按照上文中提到的数据的顺序。也就是说,如果我编辑文档的第一部分,使得\mycolor
出现在之前\mynumber
,那么我希望two
和red
在下面交换位置。
我希望避免必须单独指定我在文本第一部分中提及数据的顺序,然后将其传递给\arrange
;关键是我希望能够无忧无虑地编辑文档的第一部分,并让数据的第二个条目以正确的顺序显示在下面,而不必费力地重新排序任何事物文档的其他地方用手写方式。
输出格式的灵活性越高越好\arrange
——例如,如果我改变主意并想\arrange
将其结果放在单独的行上而不是用逗号分隔,我希望这是可能的。
答案1
您需要以有意义的方式重新排列数据。您描述的是元组,它们只是键值对,例如
two=red
six=blue
处理它们的一个简单方法是使用宏输入这些信息:
\newcommand\two{red}
\newcomand\six{blue}
但是,这可能有点难以输入,而且可能有一种方法可以实现自动化,所以让我们假设宏one, two, three etc
是颜色,然后我们可以将它们保存在逗号分隔的列表中:
\colorlist{one,two,three,four,five,six}
和颜色作为\colorlistvalues{green,blue,yellow,orange,purple,red}
,
然后,我们可以自动迭代这两个列表以自动创建宏\one,\two
等,或者创建一个实用程序来添加键值对。后者更灵活且语义正确:
\addacolor{one}{red}
\addacolor{two}{blue}
\addacolor{three}{purple}
以下是完整的极简版:
\documentclass{article}
\makeatletter
\def\colorlist{}
\def\colorlistvalues{}
\def\addacolor#1#2{%
\g@addto@macro\colorlist{#1,}
\g@addto@macro\colorlistvalues{#2,}
\expandafter\def\csname#1\endcsname{#2}
}
\makeatother
\begin{document}
\addacolor{one}{red}
\addacolor{two}{blue}
\addacolor{three}{purple}
\one,\two
\colorlist
\colorlistvalues
\end{document}
另请参阅如何设置属性https://tex.stackexchange.com/a/37096/963,这与你想要的非常相似,以及向书籍类添加传记列表。
答案2
\arrangement
下面的代码通过在调用\mynumber
and/or时构建一个列表 ( ) 来实现你想要的功能\mycolor
。因此,无论你以何种顺序调用它们,列表都是在那命令。
\documentclass{article}
\makeatletter
\def\storenumber(#1,#2){%
\def\mynumber@one{#1}% Store first argument
\def\mynumber@two{#2}% Store second argument
}
\def\storecolor(#1,#2){%
\def\mycolor@one{#1}% Store first argument
\def\mycolor@two{#2}% Store second argument
}
\let\arrangement\relax% Empty arrangement
\def\mynumber{%
\mynumber@one% Set first number
\setbox0=\hbox{\arrangement}%
\ifdim\wd0=0pt % Check if \arrangement already has an item
\edef\arrangement{\mynumber@two}%
\else % \arrangement DOES have an item
\edef\arrangement{\arrangement, \mynumber@two}%
\fi%
}
\def\mycolor{%
\mycolor@one% Set first colour
\setbox0=\hbox{\arrangement}%
\ifdim\wd0=0pt % Check if \arrangement already has an item
\edef\arrangement{\mycolor@two}%
\else % \arrangement DOES have an item
\edef\arrangement{\arrangement, \mycolor@two}%
\fi%
}
\def\arrange{%
\arrangement% Set \arrangement
\let\arrangement\relax% Clear/erase arrangement
}
\makeatother
\begin{document}
% Setup number/colour
\storenumber(six,two) \storecolor(blue,red)
Lorem ipsum \mynumber, dolor sit amet \mycolor, etc\ldots
\arrange % Print \arrangement
Lorem ipsum \mycolor, dolor sit amet \mynumber, etc\ldots
\arrange % Print \arrangement
\end{document}
宏\storenumber(<one>,<two>)
和\storecolor(<one>,<two>)
设置了两对数据点。\mynumber
每个\mycolor
设置它们的第一个对,同时还检查它应该如何添加到一个调用的宏中\arrangement
(它可能是第一个或后面的项目)。\arrange
设置第二个项目对的构造/有序排列。
答案3
\documentclass[a4paper]{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newpair}{ m m m }
{
\cs_new_protected:Npn #1 { \zevc_print_and_add:nn { #2 } { #3 } }
}
\cs_new:Npn \zevc_print_and_add:nn #1 #2
{
#1 % print the first element
\cs_if_exist:cF { zevc_ \tl_to_str:n { #1 + #2 } _tl } % store the second element
{
\seq_gput_right:Nn \g_zevc_keys_seq { #2 }
\tl_new:c { zevc_ \tl_to_str:n { #1 + #2 } _tl } % only once
}
}
\seq_new:N \g_zevc_keys_seq
\NewDocumentCommand{\arrange}{ }
{
\seq_gpop_right:NN \g_zevc_keys_seq \l_tmpa_tl % detach the last element
\seq_map_inline:Nn \g_zevc_keys_seq { ##1,~ } \tl_use:N \l_tmpa_tl
\seq_gput_right:NV \g_zevc_keys_seq \l_tmpa_tl % restore for possible future use
}
\ExplSyntaxOff
\newpair{\mycolor}{blue}{red}
\newpair{\mynumber}{six}{two}
\begin{document}
Lorem ipsum \mynumber, dolor sit amet \mycolor, etc...
\arrange
\end{document}
该\newpair
命令定义宏:它将名称、第一个值和第二个值作为参数:
\newpair{\mynumber}{six}{two}
当您使用 时\mynumber
,则会打印“six”,并将“two”添加到序列 中\g_zevc_keys_seq
,但前提是它之前没有被添加过。为了检查这一点,我们设置了一个新的标记列表变量,其名称由 和 组成,zev_c
以确保唯一性(我们假设有序对都是不同的)。当然,如果您希望稍后打印所有第二个元素(而不考虑重复项),则这不是必需的。six+two
_tl
该\arrange
命令只是按顺序打印迄今为止逐步添加的所有项目。为了打印它们并用逗号分隔,我们分离最后一个元素,打印所有剩余元素,后跟一个逗号和一个空格,然后打印最后一个元素。然后我们恢复序列,以备将来使用。顺序将是文本中出现的顺序。