如何定义一个命令来将列表的内容输入到 \ifcase 构造中?

如何定义一个命令来将列表的内容输入到 \ifcase 构造中?

通常使用\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

这使

在此处输入图片描述

相关内容