
I recently started to look at xparse for some additional features such as multiple optional arguments, as well as keyval -- which works as I want it to, as long as each option is just one keyword.

What I would ultimately like to have is a way to address certain options by name and assign values and strings like so:

\MyCommand[
opt1="this is val1",
opt4="this is val4",
optN="this is valN"
]{argument1}


Or maybe even:

\MyCommand{
arg1="this is val1",
arg4="this is val4",
argN="this is valN"
}


(I know that "this is val" is not LaTeX syntax, maybe {this is val}?)

I am still fairly new to LaTeX, and I am not sure how to properly search for this. So I hope someone here can point me in the right direction.

You can have multiple "keywords" assigned to each option as long as entries with commas are enclosed in braces {...}. Also, you'll have to stick to alphabetic characters for the option names:

\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}


Reference: How to create a command with key values?

You may do this kind of thing with l3keys from interface3.pdf. Here is an example:

\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}


• Thank you for your answer. Werners answer fit my use-case better and is closer to the syntax I am comfortable with, that is why I accepted it. But I will definitely keep this in mind for the future and I will probably use this as I get into more advanced LaTeX. – omnesia Jun 22 '18 at 6:40
• Okay... since your question mentioned xparse, I thought you were looking for a LaTeX3-ish way of parsing the key/value mapping. Anyway, l3keys from interface3.pdf is very convenient and powerful in my opinion; it's probably a good idea to read its documentation, or at least skim through it, when you have some time. :) [starts p. 166 in the current version] – frougon Jun 22 '18 at 7:26

This?

\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}

• Thank you for your answer. I accepted Werners answer as it seemed simpler and sufficed for what I needed to do. – omnesia Jun 22 '18 at 6:42
• I still don't know for sure what you wanted. If you wanted to use #1 or \opt1 as arguments. – Manuel Jun 22 '18 at 6:43
• Maybe the mention of \newcommand[<arg_num>]{#1 ... #n} was a little misleading. I wanted to address the arguments by name, meaning e.g. \opt1. But I was also not really sure what would be possible at all. – omnesia Jun 22 '18 at 6:55
• Okey, I will update the answer anyways. – Manuel Jun 22 '18 at 6:56
• Now you can use \opt1 in the same way as #1, both options possible. – Manuel Jun 22 '18 at 7:01