![내가 던진 오류가 아닌 사용자 정의 패키지에 이상한 오류가 있습니까?](https://rvso.com/image/472717/%EB%82%B4%EA%B0%80%20%EB%8D%98%EC%A7%84%20%EC%98%A4%EB%A5%98%EA%B0%80%20%EC%95%84%EB%8B%8C%20%EC%82%AC%EC%9A%A9%EC%9E%90%20%EC%A0%95%EC%9D%98%20%ED%8C%A8%ED%82%A4%EC%A7%80%EC%97%90%20%EC%9D%B4%EC%83%81%ED%95%9C%20%EC%98%A4%EB%A5%98%EA%B0%80%20%EC%9E%88%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
모든 개인 명령에 대한 사용자 정의 패키지를 만들고 있으며, 섹션 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}
physics
or 와 같은 유효한 값을 주면 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}