
我正在寫一份報告,其中包括酶圖像,如下所示:
在\caption
我想包含一個顏色指南,以便可以用顏色描述關鍵組件/原子(該報告尚未發布,因此對於色盲來說這不是問題)。我目前正在使用這樣的命令:
\newcommand\ColourGuide{%
Colour code: \textcolor{violet}{metal ion}, \textcolor{Green3}{residue}, \textcolor{teal}{ligand}, \textcolor{Yellow3}{substrate}, \textcolor{DarkOrange1}{phosphorus}, \textcolor{red}{oxygen} and \textcolor{RoyalBlue4}{nitrogen}%
}
然而,對於某些圖像,並非所有顏色成分都存在,因此包含冗餘顏色代碼並不好。如何根據輸入創建句子?例如:
\ColourGuide{M}{R}{S}{O}{N}
會產生:
顏色代碼:金屬離子、殘留物、底物、氧氣和氮氣。
以指定的顏色。我正在使用lualatex
並查看使用lua
(這會很好),但我不知道如何正確(也不有效)地交互兩者,如何像在Python中那樣提取參數input[0]
?我很感激透過任何方法提供的任何建議或解決方案,但lua
會很好,這樣我就可以開始學習它並將其應用到我lualatex
經常使用的其他命令。
微量元素:
\documentclass{book}
\usepackage[x11names]{xcolor}
\newcommand\ColourGuide{%
Colour code: \textcolor{violet}{metal ion}, \textcolor{Green3}{residue}, \textcolor{teal}{ligand}, \textcolor{Yellow3}{substrate}, \textcolor{DarkOrange1}{phosphorus}, \textcolor{red}{oxygen} and \textcolor{RoyalBlue4}{nitrogen}%
}
\begin{document}
\ColourGuide{}
\end{document}
外觀如何:
(我不知道該貼什麼標籤)
答案1
你的回答是很好的嘗試,但是…
\documentclass{book}
\usepackage[x11names]{xcolor}
\ExplSyntaxOn
\NewDocumentCommand{\ColourGuide}{m}
{
Color~code:~\jamest_colourguide:n { #1 }
}
\seq_new:N \l__jamest_colourguide_seq
\cs_new_protected:Nn \jamest_colourguide:n
{
\seq_clear:N \l__jamest_colourguide_seq
\tl_map_function:nN { #1 } \__jamest_colourguide_add:n
\seq_use:Nnnn \l__jamest_colourguide_seq { ~and~ } { ,~ } { ~and~}
}
\cs_new_protected:Nn \__jamest_colourguide_add:n
{
\seq_put_right:Nx \l__jamest_colourguide_seq
{
\str_case:nn { #1 }
{
{a}{\textcolor{red}{oxygen},~\textcolor{DarkOrange1}{phosphorus},~
\textcolor{Yellow3}{substrate},~\textcolor{Green3}{residue},~
\textcolor{RoyalBlue4}{nitrogen},~\textcolor{teal}{ligand}~
and~\textcolor{violet}{metal~ion}.}
{M}{\textcolor{violet}{metal~ion}}
{R}{\textcolor{Green3}{residue}}
{S}{\textcolor{Yellow3}{substrate}}
{O}{\textcolor{red}{oxygen}}
{N}{\textcolor{RoyalBlue4}{nitrogen}}
{L}{\textcolor{teal}{ligand}}
{P}{\textcolor{DarkOrange1}{phosphorus}}
}
}
}
\ExplSyntaxOff
\begin{document}
\noindent\ColourGuide{MRSON}
\noindent\ColourGuide{LPON}
\noindent\ColourGuide{a}
\end{document}
不需要計數:參數逐個字元映射,並將相關代碼添加到序列中,稍後可以與合適的分隔符號一起使用。
也許更好的是,為了避免程式碼重複,如果您想要完整列表,請將參數保留為空。
\documentclass{book}
\usepackage[x11names]{xcolor}
\ExplSyntaxOn
\NewDocumentCommand{\ColourGuide}{m}
{
Color~code:~
\jamest_colourguide:n { #1 }
}
\seq_new:N \l__jamest_colourguide_seq
\cs_new_protected:Nn \jamest_colourguide:n
{
\tl_if_empty:nTF { #1 }
{
\jamest_colourguide:n { OPSRNLM }
}
{
\seq_clear:N \l__jamest_colourguide_seq
\tl_map_function:nN { #1 } \__jamest_colourguide_add:n
\seq_use:Nnnn \l__jamest_colourguide_seq { ~and~ } { ,~ } { ~and~}
}
}
\cs_new_protected:Nn \__jamest_colourguide_add:n
{
\seq_put_right:Nx \l__jamest_colourguide_seq
{
\str_case:nn { #1 }
{
{M}{\textcolor{violet}{metal~ion}}
{R}{\textcolor{Green3}{residue}}
{S}{\textcolor{Yellow3}{substrate}}
{O}{\textcolor{red}{oxygen}}
{N}{\textcolor{RoyalBlue4}{nitrogen}}
{L}{\textcolor{teal}{ligand}}
{P}{\textcolor{DarkOrange1}{phosphorus}}
}
}
}
\ExplSyntaxOff
\begin{document}
\noindent\ColourGuide{MRSON}
\noindent\ColourGuide{LPON}
\noindent\ColourGuide{}
\end{document}
輸出是相同的。
答案2
感謝這些評論,我能夠拼湊出一個不太漂亮但可以按要求工作的解決方案。將 @egreg 的答案加到如何確定命令參數中的字元數和連結的答案@John Kormylo評論了給出這個:
\documentclass{book}
\usepackage[x11names]{xcolor}
\usepackage{xstring}
\usepackage{xparse} % loads expl3
\ExplSyntaxOn
\newcounter{Chars}
\newcounter{CharsConstant}
\def\CharsCount#1{%
\setcounter{Chars}{\tl_count:n { #1 }}%
\setcounter{CharsConstant}{\tl_count:n { #1 }}%
}
\NewDocumentCommand{\punctOrAnd}{mm}
{
\int_compare:nTF { #1 > 1 }
{
\int_compare:nTF { #1 = \value{CharsConstant} }
{
#2
}
{
,~#2
}
}
{
\space and~#2.
}
}
\def\ColourGuide#1{\CharsCount{#1}Colour~code:~\scanA#1\end}
\def\scanA#1{%
\ifx\end#1\else
\IfStrEq{#1}{a}{\textcolor{red}{oxygen},~\textcolor{DarkOrange1}{phosphorus},~\textcolor{Yellow3}{substrate},~\textcolor{Green3}{residue},~\textcolor{RoyalBlue4}{nitrogen},~\textcolor{teal}{ligand}~and~\textcolor{violet}{metal~ion}.}{}%
%
\IfStrEq{#1}{M}{\punctOrAnd{\value{Chars}}{\textcolor{violet}{metal~ion}}}{}%
\IfStrEq{#1}{R}{\punctOrAnd{\value{Chars}}{\textcolor{Green3}{residue}}}{}%
\IfStrEq{#1}{S}{\punctOrAnd{\value{Chars}}{\textcolor{Yellow3}{substrate}}}{}%
\IfStrEq{#1}{O}{\punctOrAnd{\value{Chars}}{\textcolor{red}{oxygen}}}{}%
\IfStrEq{#1}{N}{\punctOrAnd{\value{Chars}}{\textcolor{RoyalBlue4}{nitrogen}}}{}%
\IfStrEq{#1}{L}{\punctOrAnd{\value{Chars}}{\textcolor{teal}{ligand}}}{}%
\IfStrEq{#1}{P}{\punctOrAnd{\value{Chars}}{\textcolor{DarkOrange1}{phosphorus}}}{}%
%
\addtocounter{Chars}{-1}%
\expandafter \scanA \fi
}
\ExplSyntaxOff
\begin{document}
\noindent\ColourGuide{MRSON}
\noindent\ColourGuide{LPON}
\noindent\ColourGuide{a}
\end{document}
答案3
這使用分號作為終止符。 \def\CGparse#1#2;
會將第一個標記(字母)放入 中#1
,並將分號之前的所有內容放入 中#2
。它遞歸地呼叫自身直到#2
is \empty
。
\documentclass{book}
\usepackage[x11names]{xcolor}
\newcommand\ColourGuide[1]{Colour code:{\count1=0\relax\CGparse#1;}}
\def\CGparse#1#2;{\def\A{#1}%
\def\B{#2}%
\ifnum\count1=0\relax
\space
\else
\ifx\B\empty\relax
{ and }%
\else
{, }%
\fi
\fi
\advance\count1 by 1
\def\C{M}\ifx\A\C\relax\textcolor{violet}{metal ion}\fi
\def\C{R}\ifx\A\C\relax\textcolor{Green3}{residue}\fi
\def\C{L}\ifx\A\C\relax\textcolor{teal}{ligand}\fi
\def\C{S}\ifx\A\C\relax\textcolor{Yellow3}{substrate}\fi
\def\C{P}\ifx\A\C\relax\textcolor{DarkOrange1}{phosphorus}\fi
\def\C{O}\ifx\A\C\relax\textcolor{red}{oxygen}\fi
\def\C{N}\ifx\A\C\relax\textcolor{RoyalBlue4}{nitrogen}\fi
\ifx\B\empty\relax
{. }%
\else
\CGparse#2;
\fi}
\begin{document}
\ColourGuide{MRSON}
\end{document}
答案4
已經有很多很好的答案,可能我的使用pgfkeys
太複雜和麻煩,但這就是我想出來的。
- 不需要
lualatex
(這裡明確要求,但也許有人可以在其他地方使用它)。 - 原子將始終以相同的順序列出,無論您是否寫
\ColourGuide[ligand,residue]
或\ColourGuide[residue,ligand]
。這可能是想要的,也可能不是,但我認為保持相同的順序是很好的風格。
\ColourGuide[L,R]
當然,可選參數/鍵可以毫不費力地縮短為例如。
\documentclass{article}
% create 'if's for each atom
\newif\ifmetalion
\newif\ifresidue
\newif\ifligand
\newif\ifsubstrate
\newif\ifphosphorus
\newif\ifoxygen
\newif\ifnitrogen
% create two counters
\newcounter{numtrue} % total number of 'if's which are true
\newcounter{currval} % counter (for correctly putting 'and' at the last atom)
% colors
\usepackage[x11names]{xcolor}
% create pgfkeys
\usepackage{pgfkeys,xcolor}
\pgfkeys{
/colourguide/.is family, /colourguide/.cd,
default/.style={
metalion=false,
residue=false,
ligand=false,
substrate=false,
phosphorus=false,
oxygen=false,
nitrogen=false,
},
metalion/.is if=metalion,
residue/.is if=residue,
ligand/.is if=ligand,
substrate/.is if=substrate,
phosphorus/.is if=phosphorus,
oxygen/.is if=oxygen,
nitrogen/.is if=nitrogen
}
% this will produce the adequate delimiter between different atoms
\def\chooseDelimiter{%
\stepcounter{currval}% increment counter
\ifnum\value{currval}<\value{numtrue}\relax% if more than one atom remains ...
,\ % ... put ',' ...
\else%
\ifnum\value{currval}=\value{numtrue}\relax% ... if only one atom remains ...
\ and\ % ... put 'and' ...
\else% ... if no atom remains ...
.% ... put '.'
\fi%
\fi%
}
% main command: \ColorGuide
\newcommand\ColourGuide[1][]{%
% do pgfkeys magic
\pgfkeys{/colourguide, default, #1}%
% get number of requested atoms
\setcounter{currval}{1}%
\setcounter{numtrue}{0}%
\ifmetalion \stepcounter{numtrue}\fi%
\ifresidue \stepcounter{numtrue}\fi%
\ifligand \stepcounter{numtrue}\fi%
\ifsubstrate \stepcounter{numtrue}\fi%
\ifphosphorus\stepcounter{numtrue}\fi%
\ifoxygen \stepcounter{numtrue}\fi%
\ifnitrogen \stepcounter{numtrue}\fi%
% build sentence
Colour code:\ %
\ifmetalion\textcolor{violet}{metal ion}\chooseDelimiter\fi%
\ifresidue\textcolor{Green3}{residue}\chooseDelimiter\fi%
\ifligand\textcolor{teal}{ligand}\chooseDelimiter\fi%
\ifsubstrate\textcolor{Yellow3}{substrate}\chooseDelimiter\fi%
\ifphosphorus\textcolor{DarkOrange1}{phosphorus}\chooseDelimiter\fi%
\ifoxygen\textcolor{red}{oxygen}\chooseDelimiter\fi%
\ifnitrogen\textcolor{RoyalBlue4}{nitrogen}\chooseDelimiter\fi%
}
\begin{document}
\paragraph{Works with one atom:}
\ColourGuide[metalion]
\paragraph{Works with two atoms:}
\noindent\ColourGuide[residue,ligand]\\ % two atoms
\paragraph{Works with many atoms:}
\ColourGuide[metalion,residue,ligand,substrate,phosphorus,oxygen,nitrogen]\\ % many atoms
\paragraph{Keeps the given order, no matter what is the order in brackets:}
\ColourGuide[ligand, residue]
\end{document}