keyval과 pgfkeys가 동일한 결과를 생성할 수 있습니까?

keyval과 pgfkeys가 동일한 결과를 생성할 수 있습니까?

나는 약 5시간(!) 공부했어요키 값을 사용하여 명령을 만드는 방법은 무엇입니까?(및 기타 리소스) 키 값을 구현하는 방법을 이해하려고 노력했지만 매우 혼란스러웠습니다. 나는 본질적으로 사소한(여기 있는 대부분의 사람들에게는) 테스트 케이스를 작성했는데 설명할 수 없는 몇 가지 불일치가 있습니다.

다음은 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}

그리고 여기에 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

초기값과 기본값을 혼동하고 있습니다. 두 번째는 값을 제공하지 않고 키를 사용하는 경우에 사용됩니다. 이 외에도 명령을 사용하여 키 값을 저장하는 경우 먼저 로 정의하는 것이 좋습니다 \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}

여기에 이미지 설명을 입력하세요

관련 정보