我正在嘗試製作一個自訂套件來包含我所有的個人巨集和適合我個人風格的自訂類別。我想傳遞一個關鍵字參數notation
,它的值可以是math
orphysics
,以便更改我參加的不同課程的符號(例如,在數學中,複共軛通常用條形表示,在物理學中用星號表示) 。經過一番嘗試並遵循我得到的答案後這裡。我得到了這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,
notation.initial:n = physics
}
\ProcessKeyOptions[demo]
\IfStrEqCase{\@demo@notation}{
{physics}{}%
{math}{}%
}[
\PackageError{demo-pkg}{Invalid notation value: \@demo@notation}
{Choose value of: physics, math}
]
\RequirePackage{xparse}
\IfStrEqCase{\@demo@notation}{%
{physics}{%
\NewDocumentCommand{\Conjugate}{ m }{{##1}^{\ast}}%
}%
{math}{%
\NewDocumentCommand{\Conjugate}{ m }{\overline{##1}}%
}%
}%
% demo-cls.cls
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{demo-cls}[Demo class]
\DeclareKeys[demo-cls]
{
notation.choices:nn =
{ physics, math }
{\PassOptionsToPackage{notation=l_keys_choice_tl}{demo-pkg}}, % <- This seems to cause issues
notation.usage = load,
notation.initial:n = physics
}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessKeyOptions[demo-cls]
\ProcessOptions\relax
\LoadClass[a4paper, 12pt]{article}
\RequirePackage{demo-pkg}
% main.tex
\documentclass[notation=math]{demo-cls}
\begin{document}
\[ z = x + iy \Longleftrightarrow \Conjugate{z} = x - iy \]
\end{document}
嘗試編譯此程式碼給我一個錯誤Key 'demo/notation' accepts only a fixed set of choices.
。當我demo-pkg
直接使用時:
\documentclass{article}
\usepackage[notation=math]{demo-pkg}
\begin{document}
\[ z = x + iy \Longleftrightarrow \Conjugate{z} = x - iy \]
\end{document}
它編譯得很好,我可以使用包參數切換符號。將參數從類別傳遞到套件似乎會引起問題。我嘗試使用\l_keys_choice_tl
,並用/\tl_use:N \l_keys_choice_tl
包圍此程式碼塊。什麼都不起作用。我犯了同樣的錯誤。如何將參數從類別傳遞到包?\ExplSyntaxOn
\ExplSyntaxOff
notation
demo-cls
demo-pkg
答案1
您無需將寄件者轉發notation=math
至\documentclass
您的包裹。該套件使用\ProcessKeyOptions
,因此解析包含該選項的全域選項清單。
您可以使用\ProcessKeyOptions
類別中的機制將未知選項轉送到article
.所以唯一需要更改的檔案是你的類別:
demo-cls.cls
:
% demo-cls.cls
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{demo-cls}[Demo class]
\DeclareKeys[demo-cls]
{
unknown .code = \PassOptionsToClass{\CurrentOption}{article}
}
\ProcessKeyOptions[demo-cls]
\LoadClass[a4paper, 12pt]{article}
\RequirePackage{demo-pkg}
demo-pkg.sty
:
% 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,
notation.initial:n = physics
}
\ProcessKeyOptions[demo]
\IfStrEqCase{\@demo@notation}{
{physics}{}%
{math}{}%
}[
\PackageError{demo-pkg}{Invalid notation value: \@demo@notation}
{Choose value of: physics, math}
]
\RequirePackage{xparse}
\IfStrEqCase{\@demo@notation}{%
{physics}{%
\NewDocumentCommand{\Conjugate}{ m }{{##1}^{\ast}}%
}%
{math}{%
\NewDocumentCommand{\Conjugate}{ m }{\overline{##1}}%
}%
}%
main.tex
:
% main.tex
\documentclass[notation=math]{demo-cls}
\begin{document}
\[ z = x + iy \Longleftrightarrow \Conjugate{z} = x - iy \]
\end{document}
我想需要做一些解釋(也回顧我以前的答案):
\ExpandArgs
是一個宏,它提供了一個高階介面來精細控制參數擴充。我用它來將套件內部設定\@demo@notation
為 L3 變數的值,而不直接使用 L3 語言(因此沒有\ExplSyntaxOn
或\ProvidesExplPackage
)。這是透過 using 完成的\ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}
,這意味著:在使用\let
use 兩個參數之前,第一個是未更改的單一標記 ( N
),第二個是應透過 形成巨集的花括號組\csname
。\ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}
這種低級結構的一個更好可讀的變體也是如此:
\expandafter\let\expandafter\@demo@notation\csname l_keys_choice_tl\endcsname
我希望這個解釋有助於解釋為什麼你
\DeclareKeys[demo-cls]
{
notation.choices:nn =
{ physics, math }
{\PassOptionsToPackage{notation=l_keys_choice_tl}{demo-pkg}}, % <- This seems to cause issues
notation.usage = load,
notation.initial:n = physics
}
沒用。因為l_keys_choice_tl
它不會神奇地成為真正的選擇值,這是由 完成的\ExpandArgs
,並且必須在這裡通過類似的方式完成(我的評論建議)。