
私は約5時間(!)勉強しましたキー値を使用してコマンドを作成するにはどうすればよいですか?(およびその他のリソース) を調べ、キー値の実装方法を理解しようとしましたが、非常に混乱しています。基本的に些細な (少なくともここにいるほとんどの人にとっては) テスト ケースを作成しましたが、説明できない矛盾がいくつかあります。
以下は を使用した MWE ですkeyval
。
% !TEX TS-program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{keyval}
\makeatletter
% Key definitions
\define@key{sayhello}{towhom}{\def\sh@towhom{#1}}
% Key defaults
\setkeys{sayhello}{towhom=Michael}
% Define the command that uses the key
\newcommand{\sayhello}[2][]{%
%\begingroup% localizes the new settings w/o calling the defaults
\setkeys{sayhello}{towhom=Michael} % Reset defaults w/o localizing
\setkeys{sayhello}{#1} % Set new keys
Say hello to \sh@towhom\ #2.
%\endgroup%
}%
\makeatother
\begin{document}
\sayhello{tomorrow}
%\sayhello[towhom]{today} % throws no value specified for towhom
\sayhello[towhom=Jill]{tomorrow}
%\sayhello[towhom]{today} % throws no value specified for towhom
\sayhello[towhom=Joe]{tomorrow}
%\sayhello[towhom]{tomorrow} % throws no value specified for towhom
\sayhello{today}
\end{document}
以下は を使用した MWE ですpgfkeys
。
% !TEX TS-program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{pgfkeys}
\pgfkeys{%
/sayhello/.is family, /sayhello,
towhom/.default=Michael,
towhom/.store in=\sayto
}%
\newcommand*{\sayhello}[2][]{%
\pgfkeys{/sayhello,#1}
Say hello to \sayto\ #2.
}%
\begin{document}
%\sayhello{tomorrow} % throws undefined control sequence
\sayhello[towhom]{today}
\sayhello[towhom=Jill]{tomorrow}
\sayhello[towhom]{today}
\sayhello[towhom=Joe]{tomorrow}
\sayhello[towhom]{tomorrow}
\sayhello{today} % works perfectly
\end{document}
両方の実装で同じ結果が得られることを期待していました。結果は同じではありませんでした。keyval
値のないキーを指定することは好まれないようです。オプションがまったく指定されていないpgfkeys
場合は動作に一貫性がありませんが、オプションが指定されていない場合は完全に動作しますkeyval
。私の例は間違ってコード化されていますか? 一貫性がないのは想定された動作ですか? 完全に混乱しています。
答え1
初期値とデフォルト値を混同しています。値を指定せずにキーを使用する場合は、2 番目が使用されます。これに加えて、コマンドを使用してキー値を保存する場合は、最初に で定義することをお勧めします\newcommand
。これにより、既存のコマンドが上書きされるのを防ぐことができます。
個人的には、キーの定義と設定に同じコマンドが使用され、一部のハンドラの動作を理解するのが必ずしも簡単ではないため、より混乱していると感じていますpgfkeys
。例を参照してください。pgfkeys キー ハンドラー .get および .store は何を行いますか?。
\documentclass{article}
\usepackage{keyval}
\makeatletter
\newcommand\sh@towhom{}
\define@key{sayhello}{towhom}[Default]{\def\sh@towhom{#1}}
\setkeys{sayhello}{towhom=Initial}
\newcommand{\sayhello}[2][]{%
\begingroup
\setkeys{sayhello}{#1} % Set new keys
keyval, say hello to \sh@towhom\ #2.
\endgroup%
}%
\makeatother
\usepackage{pgfkeys}
\newcommand\sayto{}
\pgfkeys{%
/sayhello/.is family, /sayhello,
towhom/.store in=\sayto,
towhom/.default=Default,
towhom = Initial,
}%
\newcommand*{\sayhellopgf}[2][]{%
\begingroup
\pgfkeys{/sayhello,#1}%
pgfkeys, say hello to \sayto\ #2.
\endgroup
}%
\ExplSyntaxOn
\tl_new:N \l_sayhello_towhom_tl
\keys_define:nn {sayhello}
{
towhom .tl_set:N = \l_sayhello_towhom_tl,
towhom .initial:n = Initial,
towhom .default:n = Default
}
\NewDocumentCommand\sayhelloexpl{O{}m}
{
\group_begin:
\keys_set:nn{sayhello}{#1}
l3keys,~say~hello~to~\l_sayhello_towhom_tl\c_space_tl#2
\group_end:
}
\ExplSyntaxOff
\begin{document}
\sayhello{tomorrow}
\sayhello[towhom]{today}
\sayhello[towhom=Jill]{tomorrow}
\sayhello[towhom]{today}
\sayhello[towhom=Joe]{tomorrow}
\sayhello[towhom]{tomorrow}
\sayhello{today}
\sayhellopgf{tomorrow}
\sayhellopgf[towhom]{today}
\sayhellopgf[towhom=Jill]{tomorrow}
\sayhellopgf[towhom]{today}
\sayhellopgf[towhom=Joe]{tomorrow}
\sayhellopgf[towhom]{tomorrow}
\sayhellopgf{today}
\sayhelloexpl{tomorrow}
\sayhelloexpl[towhom]{today}
\sayhelloexpl[towhom=Jill]{tomorrow}
\sayhelloexpl[towhom]{today}
\sayhelloexpl[towhom=Joe]{tomorrow}
\sayhelloexpl[towhom]{tomorrow}
\sayhelloexpl{today}
\end{document}