我知道要 \newcommand[<arg_num>]{#1 ... #n}
定义一个最多有 9 个参数的简单宏。(如果将多个参数链接newcommands
在一起,则更多)
我最近开始寻找xparse
一些附加功能,例如多个可选参数,以及keyval
——只要每个选项只是一个关键字,它就可以按照我想要的方式工作。
我最终想要的是一种通过名称来处理某些选项并分配值和字符串的方法,如下所示:
\MyCommand[
opt1="this is val1",
opt4="this is val4",
optN="this is valN"
]{argument1}
甚至可能是:
\MyCommand{
arg1="this is val1",
arg4="this is val4",
argN="this is valN"
}
(我知道这"this is val"
不是 LaTeX 语法,也许{this is val}
?)
我对 LaTeX 还不太熟悉,不知道如何正确搜索。所以我希望这里有人能给我指明正确的方向。
答案1
你可以为每个选项分配多个“关键字”,只要用逗号括在括号中即可{
。}
此外,选项名称必须使用字母:
\documentclass{article}
\usepackage{xkeyval}
\makeatletter
% ========= KEY DEFINITIONS =========
\define@cmdkey{mycmd}[mycmd@]{argA}{}% Creates \mycmd@argA
\define@cmdkey{mycmd}[mycmd@]{argB}{}% Creates \mycmd@argB
\define@cmdkey{mycmd}[mycmd@]{argC}{}% Creates \mycmd@argC
\define@cmdkey{mycmd}[mycmd@]{argD}{}% Creates \mycmd@argD
% ========= KEY DEFAULTS =========
\setkeys{mycmd}{
argA = ARG-A,
argB = arg-B,
argC = ARG-c,
argD = A R G - D}%
\newcommand{\MyCommand}[1]{%
\begingroup%
\setkeys{mycmd}{#1}% Set new keys
Argument 1/2/3/4: \mycmd@argA /\mycmd@argB /\mycmd@argC /\mycmd@argD
\endgroup%
}
\makeatother
\begin{document}
\MyCommand{}
\MyCommand{
argB = BbBbBb,% Change from default
argC = CcCcC cCcCc CcCcC% Multiple words
}
\MyCommand{
argA = {AaAaA, aAaAa},% Multiple words separated by comma
argD = "DdDdD dDdDd"% Multiple words in quotes
}
\end{document}
参考:如何创建带有键值的命令?
答案2
您可以使用 l3keys 执行此类操作界面3.pdf。下面是一个例子:
\documentclass[a4paper,12pt]{article}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\bool_new:N \g_my_bool
\tl_new:N \g_some_tl
\tl_new:N \g_other_tl
\keys_define:nn { mymodule }
{
choiceKey .choice:,
choiceKey / firstChoice .code:n = {
\tl_gset:Nn \g_some_tl { whatever~you~want } },
choiceKey / secondChoice .code:n = {
\tl_gset:Nn \g_some_tl { with~commas,~too } },
choiceKey / thirdChoice .code:n = {
\tl_gset:Nn \g_some_tl { blah! } },
choiceKey .initial:n = { thirdChoice },
booleanKey .bool_gset:N = \g_my_bool,
% Value used when the key is passed with no value
booleanKey .default:n = { true },
booleanKey .initial:n = { false },
tokenListKey .tl_gset:N = \g_other_tl,
tokenListKey .initial:n = { some~default }
}
\cs_new:Nn \__mymodule_print_result:
{
Choice~key:~``\g_some_tl'' \\
Boolean~key:~\bool_if:NTF \g_my_bool { set } { unset } \\
Token~list~key:~``\g_other_tl''
}
\NewDocumentCommand \MyModuleSetup { m }
{
\keys_set:nn { mymodule } {#1}
}
\NewDocumentCommand \MyModulePrintResult { }
{
\__mymodule_print_result:
}
\ExplSyntaxOff
\begin{document}
\setlength{\parindent}{0pt}%
%
\MyModulePrintResult % Work with the default (“initial”) values
\bigskip
\MyModuleSetup{
choiceKey=secondChoice,
booleanKey=true, % “=true“ may be omitted because of the
% “booleanKey .default:n = { true }” above
tokenListKey={Yes, you may put commas in there. Outer braces, if any, are
automatically removed. } % The space following the period is part of
% the value
}%
\MyModulePrintResult % Work with the values just set
\end{document}
答案3
这?
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \kvargcommand { +m +m }
{
\omnesia_kvargcommand:nn { #1 } { #2 }
}
\cs_new_protected:Npn \omnesia_kvargcommand:nn #1 #2
{
\group_begin:
\keys_set:nn { omnesia / kvargcommand } { #1 }
\cs_set:Npn \omnesia_action:nnnnnnnnn ##1 ##2 ##3 ##4 ##5 ##6 ##7 ##8 ##9 { #2 }
\cs_set:Npn \opt ##1 { \tl_use:c { l_omnesia_arg_ \int_to_roman:n {##1} _tl } }
\tl_set:Nx \l_tmpa_tl
{
\exp_not:N \omnesia_action:nnnnnnnnn
{ \exp_not:V \l_omnesia_arg_i_tl }
{ \exp_not:V \l_omnesia_arg_ii_tl }
{ \exp_not:V \l_omnesia_arg_iii_tl }
{ \exp_not:V \l_omnesia_arg_iv_tl }
{ \exp_not:V \l_omnesia_arg_v_tl }
{ \exp_not:V \l_omnesia_arg_vi_tl }
{ \exp_not:V \l_omnesia_arg_vii_tl }
{ \exp_not:V \l_omnesia_arg_viii_tl }
{ \exp_not:V \l_omnesia_arg_ix_tl }
}
\tl_use:N \l_tmpa_tl
\group_end:
}
\keys_define:nn { omnesia / kvargcommand }
{
opt1 .tl_set:N = \l_omnesia_arg_i_tl ,
opt2 .tl_set:N = \l_omnesia_arg_ii_tl ,
opt3 .tl_set:N = \l_omnesia_arg_iii_tl ,
opt4 .tl_set:N = \l_omnesia_arg_iv_tl ,
opt5 .tl_set:N = \l_omnesia_arg_v_tl ,
opt6 .tl_set:N = \l_omnesia_arg_vi_tl ,
opt7 .tl_set:N = \l_omnesia_arg_vii_tl ,
opt8 .tl_set:N = \l_omnesia_arg_viii_tl ,
opt9 .tl_set:N = \l_omnesia_arg_ix_tl ,
}
\ExplSyntaxOff
\begin{document}
\kvargcommand{
opt1 = this is val1,
opt4 = this is val4,
opt7 = this is val7,
opt6 = {this is val6, that contains a comma, so it has to be enclosed in braces},
}
{do something with one [#1] and four [\opt4] and seven [\opt7], the special case six [[#6]]
and also some empty ones by default like (\opt2) and (#3), as you can see you can use \texttt{\string\opt} or just normal arguments}
\end{document}
答案4
您可以使用expkv-cs
及其哈希变体。这样设置就非常简单了。生成的宏将完全可扩展。顺便提一下,以下代码还包括拆分变体,expkv-cs
通过该变体可以访问键值作为位置参数。
\documentclass{article}
\usepackage{expkv-cs}
% splits the keys into separate arguments to be referred by #1...#9
\ekvcSplit\mymacroA
{
argA = ARG-A
,argB = argB
,argC = A-R-G--C
,a long key name with spaces = a long value with spaces
}
{Arguments: #1/#2/#3/#4}
% stores all keys into #1 (in a way they can be accessed pretty fast), so we can
% access them by names.
% \ekvcValue will need exactly two steps of expansion.
\ekvcHash\mymacroB
{
argA = ARG-A
,argB = argB
,argC = A-R-G--C
,a long key name with spaces = a long value with spaces
}
{%
Arguments:
\ekvcValue{argA}{#1}/%
\ekvcValue{argB}{#1}/%
\ekvcValue{argC}{#1}/%
\ekvcValue{a long key name with spaces}{#1}%
}
\begin{document}
\mymacroA{}\par
\mymacroB{}\par
\mymacroB{argC=ccc, a long key name with spaces = a b c}
\end{document}