Ich versuche, ein benutzerdefiniertes Paket zu erstellen, das alle meine persönlichen Makros und eine benutzerdefinierte Klasse für meinen persönlichen Stil enthält. Ich wollte ein Schlüsselwortargument übergeben, notation
das den Wert math
oder annehmen kann physics
, um die Notationen für verschiedene Kurse, die ich belege, zu ändern (zum Beispiel wird in der Mathematik die komplex konjugierte Zahl oft mit einem Strich gekennzeichnet und in der Physik mit einem Sternchen). Nachdem ich herumgespielt und die Antworten befolgt hatte, erhielt ichHier. Ich habe diese 3 Dateien:
% 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}
Beim Versuch, diesen Code zu kompilieren, erhalte ich eine Fehlermeldung Key 'demo/notation' accepts only a fixed set of choices.
. Wenn ich demo-pkg
direkt Folgendes verwende:
\documentclass{article}
\usepackage[notation=math]{demo-pkg}
\begin{document}
\[ z = x + iy \Longleftrightarrow \Conjugate{z} = x - iy \]
\end{document}
es kompiliert einwandfrei und ich kann die Notation mit dem Paketparameter ändern. Die Übergabe des Parameters von der Klasse an das Paket scheint Probleme zu verursachen. Ich habe versucht \l_keys_choice_tl
, zu verwenden \tl_use:N \l_keys_choice_tl
und diesen Codeblock mit \ExplSyntaxOn
/ zu umgeben \ExplSyntaxOff
. Nichts funktioniert. Ich erhalte dieselbe Fehlermeldung. Wie kann ich den notation
Parameter von der demo-cls
Klasse an das demo-pkg
Paket übergeben?
Antwort1
Sie müssen das notation=math
„Von“ nicht \documentclass
an Ihr Paket weiterleiten. Das Paket verwendet \ProcessKeyOptions
und analysiert daher die globale Optionsliste, die diese Option enthält.
Und Sie können den Mechanismus in Ihrer Klasse verwenden \ProcessKeyOptions
, um unbekannte Optionen an weiterzuleiten article
. Die einzige Datei, die geändert werden muss, ist also Ihre Klasse:
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}
Ich denke, eine kleine Erklärung ist angebracht (auch im Nachhinein zu meiner älteren Antwort):
\ExpandArgs
ist ein Makro, das eine High-Level-Schnittstelle zur Feinsteuerung der Argumenterweiterung bietet. Ich habe es verwendet, um Ihr Paket intern \@demo@notation
auf den Wert einer L3-Variable zu setzen, ohne die L3-Sprache direkt zu verwenden (also ohne \ExplSyntaxOn
oder \ProvidesExplPackage
). Dies wurde durch die Verwendung von erreicht \ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}
, was bedeutet: Vor der Verwendung von \let
werden zwei Argumente verwendet, das erste ist ein unverändertes einzelnes Token ( N
), das zweite ist eine geschweifte Gruppe, die durch ein Makro gebildet werden soll \csname
. Dies \ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}
ist eine besser lesbare Variante dieser Low-Level-Konstruktion:
\expandafter\let\expandafter\@demo@notation\csname l_keys_choice_tl\endcsname
Ich hoffe, diese Erklärung hilft Ihnen zu verstehen, warum Ihre
\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
}
Hat nicht funktioniert. Weil l_keys_choice_tl
daraus nicht auf magische Weise der echte Auswahlwert wird, das wurde von erledigt \ExpandArgs
und müsste hier mit ähnlichen Mitteln geschehen (was mein Kommentar vorgeschlagen hat).