Estoy intentando crear un paquete personalizado que contenga todas mis macros personales y una clase personalizada para mi estilo personal. Quería pasar un argumento de palabra clave notation
que puede tomar un valor de math
o physics
para cambiar las notaciones de los diferentes cursos que tomo (por ejemplo, en matemáticas el conjugado complejo a menudo se indica con una barra y en física se indica con un asterisco). Después de jugar y seguir las respuestas que obtuve.aquí. Obtuve estos 3 archivos:
% 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}
Al intentar compilar este código me da un error Key 'demo/notation' accepts only a fixed set of choices.
. Cuando uso demo-pkg
directamente:
\documentclass{article}
\usepackage[notation=math]{demo-pkg}
\begin{document}
\[ z = x + iy \Longleftrightarrow \Conjugate{z} = x - iy \]
\end{document}
se compila bien y puedo cambiar notaciones con el parámetro del paquete. Pasar el parámetro de la clase al paquete parece causar problemas. Intenté usar \l_keys_choice_tl
y \tl_use:N \l_keys_choice_tl
rodear este bloque de código con \ExplSyntaxOn
/ \ExplSyntaxOff
. Nada funciona. Me sale el mismo error. ¿Cómo puedo pasar el notation
parámetro de la demo-cls
clase al demo-pkg
paquete?
Respuesta1
No es necesario que reenvíe el notation=math
desde \documentclass
a su paquete. El paquete usa \ProcessKeyOptions
, por lo que analiza la lista de opciones globales, que contiene esa opción.
Y puedes usar el \ProcessKeyOptions
mecanismo de tu clase para reenviar opciones desconocidas a article
. Entonces el único archivo que necesita cambios es tu clase:
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}
Supongo que es necesaria una pequeña explicación (también en retrospectiva para mi respuesta anterior):
\ExpandArgs
es una macro que proporciona una interfaz de alto nivel para un control preciso sobre la expansión de argumentos. Lo usé para configurar su paquete interno \@demo@notation
al valor de una variable L3 sin usar el lenguaje L3 directamente (es decir, sin \ExplSyntaxOn
o \ProvidesExplPackage
). Esto se hizo usando \ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}
, lo que significa: Antes de usar \let
use dos argumentos, el primero es un token único sin cambios ( N
), el segundo es un grupo entre llaves que debería formar una macro por \csname
. También lo \ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}
es una variante mejor legible de esta construcción de bajo nivel:
\expandafter\let\expandafter\@demo@notation\csname l_keys_choice_tl\endcsname
Espero que esta explicación ayude a explicar por qué su
\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
}
No funcionó. Porque l_keys_choice_tl
no se convierte mágicamente en el valor de elección real, eso lo hizo \ExpandArgs
y debería hacerse por medios similares aquí (que sugirió mi comentario).