내가 던진 오류가 아닌 사용자 정의 패키지에 이상한 오류가 있습니까?

내가 던진 오류가 아닌 사용자 정의 패키지에 이상한 오류가 있습니까?

모든 개인 명령에 대한 사용자 정의 패키지를 만들고 있으며, 섹션 4.4에 설명된 대로 일부 키워드 인수를 패키지에 전달하려고 합니다.clsguide. 내 사용 사례는 수학과 물리학 과정을 수강하고 그 때문에 종종 표기법을 변경해야 한다는 것입니다. 나는 내가 원하는 대로 거의 작동하는 이 작은 템플릿을 만들었습니다.

% demo-pkg.sty
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{demo-pkg}[Demo]

\RequirePackage{xstring}

\DeclareKeys[demo]
{
    notation.store = \@demo@notation,
    notation.usage = load
}

\SetKeys[demo]{notation=physics} % Default to physics notation

\ProcessKeyOptions[demo]

\IfStrEqCase{\@demo@notation}{
    {physics}{}
    {math}{}
}[
    \PackageError{demo-pkg}{Invalid notation value: \@demo@notation}
    {Choose value of: physics, math}
]

\RequirePackage{xparse}

\NewDocumentCommand{\Conjugate}{ m }{
    \IfStrEqCase{\@demo@notation}{
        {physics}{{#1}^{\ast}}
        {math}{\overline{#1}}
    }
}

% main.tex
\documentclass{article}

\usepackage[notation=math]{demo-pkg}

\begin{document}
\[ z = x + iy \Longleftrightarrow \Conjugate{z} = x - iy \]
\end{document}

physicsor 와 같은 유효한 값을 주면 math예상대로 작동합니다. 그러나 와 같이 잘못된 값을 지정하면 engineer오류가 발생하지만 내가 지정한 오류는 아닙니다.

Runaway argument?
 \PackageError {demo-pkg}{Invalid notation value: \@demo@notation } {\ETC.
! File ended while scanning use of \xs_testcase.
<inserted text> 
\par 
l.4 
  
I suspect you have forgotten a `}', causing me
to read past where you wanted me to stop.
I'll try to recover; but if the error is serious,
you'd better type `E' or `X' now and fix your file.

이 오류에서는 잘못된 값이 무엇인지 확인할 수 없으며 오류 메시지나 도움말도 볼 수 없습니다. 왜 이런 일이 발생하며 잘못된 인수를 가져올 때 오류를 올바르게 발생시키려면 어떻게 해야 합니까?

답변1

\IfStrEqCase마음에 들지 않는 비교 사례 사이에 공백이 있습니다 xstring.

\begin{filecontents*}[overwrite]{demo-pkg.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{demo-pkg}[Demo]

\RequirePackage{xstring}

\DeclareKeys[demo]
{
    notation.store = \@demo@notation,
    notation.usage = load
}

\SetKeys[demo]{notation=physics} % Default to physics notation

\ProcessKeyOptions[demo]

\IfStrEqCase{\@demo@notation}{
    {physics}{}%
    {math}{}%
}[
    \PackageError{demo-pkg}{Invalid notation value: \@demo@notation}
    {Choose value of: physics, math}
]

\RequirePackage{xparse}

\NewDocumentCommand{\Conjugate}{ m }{%
    \IfStrEqCase{\@demo@notation}{%
        {physics}{{#1}^{\ast}}%
        {math}{\overline{#1}}%
    }%
}
\end{filecontents*}
\documentclass{article}

\usepackage[notation=aa]{demo-pkg}

\begin{document}
\[ z = x + iy \Longleftrightarrow \Conjugate{z} = x - iy \]
\end{document}

선택 키를 사용하면 코드를 약간 단순화할 수 있습니다( 를 사용할 때마다 비교가 발생하지 않으므로 더욱 효율적입니다 \Conjugate).

\begin{filecontents*}[overwrite]{demo-pkg.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{demo-pkg}[Demo]

\DeclareKeys[demo]
{
    notation.choice:,
    notation/physics.code = \DeclareDocumentCommand\Conjugate{ m }{{##1}^{\ast}},
    notation/math.code = \DeclareCommandCopy\Conjugate\overline,
    notation/unknown.code = 
        \PackageError{demo-pkg}{Invalid notation value: #1}
                     {Choose value of: physics, math},
    notation.initial:n = physics,
    notation.usage = load
}

\ProcessKeyOptions[demo]

\end{filecontents*}
\documentclass{article}

\usepackage[notation=math]{demo-pkg}

\begin{document}
\[ z = x + iy \Longleftrightarrow \Conjugate{z} = x - iy \]
\end{document}

답변2

에 설명된 것보다 더 많은 키 속성을 사용할 수 있으며 clsguide, 다른 속성은 interface3.pdf섹션 27.1에 설명되어 있습니다. 그 중 하나는 .choices:nn섹션 27.3에 사용 예가 나와 있습니다.

오류 메시지는 코드에 지정한 것과 정확히 일치하지는 않지만 충분할 것으로 예상됩니다.

% demo-pkg.sty
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{demo-pkg}[Demo]

\RequirePackage{xstring}

\DeclareKeys[demo]
{
  notation .choices:nn =
    {physics,math}
    {\ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}}
  ,notation.usage = load
}

\SetKeys[demo]{notation=physics} % Default to physics notation
\ProcessKeyOptions[demo]

% \RequirePackage{xparse} % not needed with recent kernel versions

\NewDocumentCommand{\Conjugate}{ m }{%
    \IfStrEqCase{\@demo@notation}{%
        {physics}{{#1}^{\ast}}%
        {math}{\overline{#1}}%
    }%
}

@UdiFogiel과 마찬가지로 여기서는 값의 약간 다른 사용법을 제안하고 패키지를 xstring.

% demo-pkg.sty
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{demo-pkg} {2024-01-06} {0.0} {Demo}

% assuming that you always need only two different notations, the following
% changes it to a boolean variable
\bool_new:N \l__demopkg_notation_physics_bool
\DeclareKeys[demo]
  {
    notation .choice:
    ,notation / physics .code:n =
      \bool_set_true:N  \l__demopkg_notation_physics_bool
    ,notation / maths   .code:n =
      \bool_set_false:N \l__demopkg_notation_physics_bool
    ,notation .usage:n   = load
    ,notation .initial:n = physics
  }

\ProcessKeyOptions[demo]

% since `load` doesn't allow changes after the package got loaded, we can just
% hard code the implementations here, instead of deciding on each call
\bool_if:NTF \l__demopkg_notation_physics_bool
  { \NewDocumentCommand \Conjugate { m } { #1 \sp { \ast } } }
  { \NewDocumentCommand \Conjugate { m } { \overline {#1} } }

\begin{advertisement}

옵션 구문 분석을 위해 -family of packages를 사용할 수도 있습니다 expkv(제가 저자입니다). 어떤 것들은 에서 더 쉬울 수도 있고 expkv, 다른 것들은 더 어려울 수도 있습니다(또는 내장되지 않은 것). 그렇지 않으면 선호하는 구문에 대한 자세한 내용입니다.

% demo-pkg.sty
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{demo-pkg}[2024-01-06 v0.0 Demo]
\RequirePackage{expkv-def,expkv-opt}

\ekvdefinekeys{demo}
  {
     choice notation =
      {
        % expkv allows much freedom regarding the protected prefix because it
        % can work by expansion only (if it's not processing package
        % options...), therefore we need to set the protected prefix ourselves
        % here if we want to play nice.
         protected physics = \let\@demo@physicsTF\@firstoftwo
        ,protected maths   = \let\@demo@physicsTF\@secondoftwo
      }
    ,initial notation = physics
  }
\ekvoProcessGlobalOptions{demo} % options provided to \documentclass
\ekvoProcessLocalOptions{demo}  % options provided while loading this package
% future options will throw an option conflict error, since we only have a
% single load-time only option this is to be preferred over manually handling
% this. Else we could use `\ekvoProcessFutureOptions` (or combine all three
% calls by using `\ekvoProcessOptions` instead), but we'd need to redefine all
% the keys we don't want to be usable on a second time usage, because there is
% nothing like the `.usage`-property in `expkv`. This could look like the
% following:
%   \newcommand\@demo@aux[1]
%     {%
%       \protected\long\ekvdef{demo-pkg}{#1}
%         {%
%           \PackageError{demo-pkg}
%             {Option `#1' only usable on first package load}{}%
%         }%
%     }
%   \ekvcsvloop\@demo@aux{notation}% if you 
%   \let\@demo@aux\@demo@undefined

% since `load` doesn't allow changes after the package got loaded, we can just
% hard code the implementations here, instead of deciding on each call
\@demo@physicsTF
  {\NewDocumentCommand \Conjugate { m } {#1^{\ast}}}
  {\NewDocumentCommand \Conjugate { m } {\overline{#1}}}

\end{advertisement}

관련 정보