keyval と pgfkeys は同じ結果を生成できますか?

keyval と pgfkeys は同じ結果を生成できますか?

私は約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}

ここに画像の説明を入力してください

関連情報