![如何定义一个命令来将列表的内容输入到 \ifcase 构造中?](https://linux22.com/image/249024/%E5%A6%82%E4%BD%95%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AA%E5%91%BD%E4%BB%A4%E6%9D%A5%E5%B0%86%E5%88%97%E8%A1%A8%E7%9A%84%E5%86%85%E5%AE%B9%E8%BE%93%E5%85%A5%E5%88%B0%20%5Cifcase%20%E6%9E%84%E9%80%A0%E4%B8%AD%EF%BC%9F.png)
通常使用\ifcase
构造根据计数器的值重新定义命令。以下示例说明了这一点:
\documentclass{article}
\usepackage{xcolor}
\usepackage{etoolbox}
\newcommand\sectioncolor{}
\renewcommand\sectioncolor{%
\ifcase\value{section} brown\or red\or blue\else olive\fi}
\pretocmd{\section}{\color{\sectioncolor}}{}{}
\begin{document}
\section{Section One}
\section{Section Two}
\section{Section Three}
\section{Section Four}
\end{document}
上述\sectioncolor
使用重新定义\ifcase
意味着手动输入构造中的颜色\ifcase
。我想要实现的是有一个命令,比如\ColorList
,以逗号分隔的可变长度列表作为参数,其中包含要使用的颜色,然后重新定义\sectioncolor
为根据节计数器使用列表中的颜色。例如,参考我的示例代码,使用
\ColorList{brown,red,blue,olive}
相当于
\renewcommand\sectioncolor{%
\ifcase\value{section} brown\or red\or blue\else olive\fi}
和
\ColorList{yellow,magenta,cyan,orange,blue}
相当于
\renewcommand\sectioncolor{%
\ifcase\value{section} yellow\or magenta\or cyan\or orange \else blue\fi}
但。当然,无需手动将颜色输入\ifcase
。如何做到这一点?
答案1
这与@egreg 的解决方案类似,避免\ifcase
仅仅循环列表,但编码可能更简单一些(除非您已经因为其他原因加载了 expl3)
\documentclass{article}
\usepackage{xcolor}
\def\ColorList#1{\def\xcolorlist{#1}}
\let\xsection\section
\def\section{\expandafter\xxcycle\xcolorlist,\xcolorlist\xsection}
\def\xxcycle#1,#2{%
\ifx\relax#1\relax\else
\color{#1}%
\ifx\xcolorlist#2\else
\xcycle#1,#2%
\fi
\fi}
\def\xcycle#1,#2\fi\fi#3\xcolorlist{\fi\fi\ColorList{#2#3#1}}
\ColorList{yellow,magenta,cyan,orange,blue,green!30,red!50!black}
%\ColorList{yellow}
%\ColorList{}
\begin{document}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\end{document}
答案2
由于您正在使用etoolbox
已经,您可以适当使用\docsvlist
并重新定义\do
。
\documentclass{article}
\usepackage{xcolor}% http://ctan.org/pkg/xcolor
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcounter{listitem}
\newcommand\sectioncolor{%
\setcounter{listitem}{-1}% At this point, section counter has not been incremented
\renewcommand*{\do}[1]{%
\stepcounter{listitem}% Increment list counter
\ifnum\value{listitem}=\value{section}\color{##1}\fi% Match list counter with section counter
}
\docsvlist{yellow,magenta,cyan,orange,blue,green!30,red!50!black}%
}
\pretocmd{\section}{\sectioncolor}{}{}
\begin{document}
\section{Section One}
\section{Section Two}
\section{Section Three}
\section{Section Four}
\section{Section Five}
\section{Section Six}
\section{Section Seven}
\end{document}
答案3
这将循环列出的颜色:
\documentclass[convert,border=2,varwidth]{standalone}
\usepackage{xcolor,xpatch,xparse}
\xpretocmd{\section}{\sectioncolor}{}{}
\ExplSyntaxOn
\NewDocumentCommand{\ColorList}{m}
{
\seq_gset_split:Nnn \g_gonzalo_colors_seq { , } { #1 }
}
\seq_new:N \g_gonzalo_colors_seq
\NewDocumentCommand{\sectioncolor}{ }
{
\seq_gpop_left:NN \g_gonzalo_colors_seq \l_tmpa_tl
\seq_gput_right:NV \g_gonzalo_colors_seq \l_tmpa_tl
\color { \l_tmpa_tl }
}
\ExplSyntaxOff
\ColorList{yellow,magenta,cyan,orange,blue,green!30,red!50!black}
\begin{document}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\section{Title}
\end{document}
每次调用时,\sectioncolor
要使用的颜色都会从序列的顶部弹出并放回底部。
答案4
ConTeXt 提供\defineconversion
和\convertnumber
命令,用于循环遍历元素列表(或将宏应用于数字)。这对于脚注标记(\dagger
、\star
等)等非常有用,但也可以轻松重载用于其他任务。
\defineconversion
[colors]
[red,blue,green]
\setuphead
[section]
[color={\convertnumber{colors}{\currentsectioncountervalue}}]
\starttext
\dorecurse{10}
{\section{Section \recurselevel}}
\stoptext
这使