为包编写多选项命令

为包编写多选项命令

我是 LaTeX 编程的新手,所以请耐心等待。:-)

我正在编写一个.sty文件,我想在其中包含一个命令\dan,该命令会根据使用零个、一个还是两个参数调用而重载三个不同的版本。

例如我想要:

\dan

生成

全英语

\dan{streaky}

或者

\dan{back}

生成

五花肉

或者

背部培根

分别和

\dan{streaky}{fried}

生成

五花熏肉配煎蛋。

“五花肉”、“油炸”等只是例子,用户应该能够输入任何争论。

我查看了该xparse软件包,但发现文档难以理解。您能建议如何编码吗?

答案1

就是这样。

\documentclass[a4paper]{article}
\usepackage{xparse}

\NewDocumentCommand{\dan}{gg}
  {\IfNoValueTF{#2}
     {\IfNoValueTF{#1}
        {Full English}
        {#1 Bacon}%
     }
     {#1 Bacon with #2 Eggs}%
  }

\begin{document}

\dan

\dan{streaky}

\dan{back}

\dan{streaky}{fried}

\end{document}

话虽如此,我还是建议你不要这样做。你的软件包的用户将很难弄清楚如何使用命令。只需更改参数说明符{oo}而不是{gg}语法,就会更符合 LaTeX 惯例:

\dan

\dan[streaky]

\dan[back]

\dan[streaky][fried]

如果您能更精确地表达您的意图,可能会建议采用不同的策略。

答案2

正如评论中所述,我建议使用更传统的 LaTeX 语法。@egreg 给出了 LaTeX3 版本,因此这里使用 LaTeX2e 中的循环:

\documentclass{article}

\makeatletter

\newcommand\dan[1][full]{%
\def\dansep{\def\dansep{, }}%
\@for\x:=#1\do{%
\dansep
\@nameuse{dan:\x}}}

\@namedef{dan:full}{Full English}
\@namedef{dan:streaky}{Streaky Bacon}
\@namedef{dan:back}{Back Bacon}
\@namedef{dan:fried}{Fried Egg}
\@namedef{dan:mushrooms}{Grilled Mushrooms}

\makeatother

\begin{document}

a \dan

b \dan[streaky]

c \dan[back]

e \dan[streaky,fried]

f \dan[streaky,fried,mushrooms]

\end{document}

答案3

正如评论中所述,使用键值接口更为可取,而 David Carlisle 给出的答案给出了传统的 LaTeX2e 方式。对于更复杂的包,我会倾向于使用 PGF 样式的键。即使没有在这个网站上询问有关 TikZ 的问题的用户数量,也表明有大量用户熟悉 PGF 样式的键值接口。

\documentclass{article}
\usepackage[latin]{babel}
\usepackage{pgfkeys}
\begin{document}
%% Step one define family
\pgfkeys{/bacon/.is family}
%% Define your keys
\pgfkeys{/bacon
     type/.store in=\type,
     type/.default=streaky,
     cook/.store in=\cook,
     cook/.default=fried
}
%% Process keys and set defaults, for later use
\def\setdefaults{\pgfkeys{/bacon  
     type,cook
  }%
}
%
\setdefaults
\newcommand{\dan}[2][]{%
  \setdefaults
  \pgfkeys{/bacon #1}
   \def\baconfoods{
      \type\ cook \cook,
   }
  \baconfoods
}
\dan[type=shoulder bacon, cook=well]{}
\dan[type=streaky,cook]{}
\dan[type=streaky]{}
\dan{}
\end{document}

采用这种方法您可以获得极大的灵活性。

答案4

这是一个使用的解决方案期权包裹:

\documentclass{article}
\usepackage{catoptions}
\makeatletter
\newcommand*\dan[1][full]{%
  \def\do##1{%
    \ifnum\indrisnr>\@ne
      ,\space\iflastindris and\space\fi
    \fi
    \uselivecsn{dan:##1}%
  }%
  \indrisloop{#1}\do
}
% Default inner list parser = , (comma)
% Default outer list parser = ; (semicolon)
\newcommand*\setupdan[2][,;]{%
  \def\reserved@a##1##2##3\@nil{%
    \def\do####1##1####2##1####3\@nil{%
      \csn@edef{dan:\cpttrimspace{####1}}{\cpttrimspace{####2}}%
    }%
    \def\csv@do####1{\do####1##1##1\@nil}%
    \csv@@parse[##2]{#2}%
  }%
  \reserved@a#1,;\@nil
}
\makeatother

% Example:
\setupdan{%
  full,      Full English;
  streaky,   Streaky Bacon;
  back,      Back Bacon;
  fried,     Fried Egg;
  mushrooms, Grilled Mushrooms
}

\commentBegin
% The following is also possible:
\setupdan[=,]{%
  full       =Full English,
  streaky    =Streaky Bacon,
  back       =Back Bacon,
  fried      =Fried Egg,
  mushrooms  =Grilled Mushrooms
}
\commentEnd


\begin{document}
\begin{enumerate}
\item\dan
\item\dan[streaky]
\item\dan[back]
\item\dan[streaky, fried]
\item\dan[streaky, fried, mushrooms]
%\item\dan[xstreaky] % error: undefined
\end{enumerate}
\end{document}

在此处输入图片描述

相关内容