Estou tentando criar um pacote personalizado para conter todas as minhas macros pessoais e uma classe personalizada para meu estilo pessoal. Eu queria passar um argumento de palavra-chave notation
que pode assumir um valor math
ou physics
para alterar as notações dos diferentes cursos que faço (por exemplo, em matemática, o conjugado complexo é frequentemente indicado por uma barra e, em física, é indicado por um asterisco). Depois de brincar e seguir as respostas que obtiveaqui. Eu tenho esses 3 arquivos:
% 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}
Tentar compilar esse código me dá um erro Key 'demo/notation' accepts only a fixed set of choices.
. Quando eu uso demo-pkg
diretamente:
\documentclass{article}
\usepackage[notation=math]{demo-pkg}
\begin{document}
\[ z = x + iy \Longleftrightarrow \Conjugate{z} = x - iy \]
\end{document}
ele compila bem e posso alternar notações com o parâmetro package. Passar o parâmetro da classe para o pacote parece causar problemas. Tentei usar \l_keys_choice_tl
e \tl_use:N \l_keys_choice_tl
cercar esse bloco de código com \ExplSyntaxOn
/ \ExplSyntaxOff
. Nada funciona. Eu recebo o mesmo erro. Como posso passar o notation
parâmetro da demo-cls
classe para o demo-pkg
pacote?
Responder1
Você não precisa encaminhar o notation=math
from \documentclass
para o seu pacote. O pacote usa \ProcessKeyOptions
, então analisa a lista de opções globais, que contém essa opção.
E você pode usar o \ProcessKeyOptions
mecanismo da sua classe para encaminhar opções desconhecidas para article
. Portanto, o único arquivo que precisa de alterações é a sua classe:
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}
Acho que é necessária uma pequena explicação (também em retrospecto para minha resposta mais antiga):
\ExpandArgs
é uma macro que fornece uma interface de alto nível para controle preciso sobre a expansão de argumentos. Usei isso para definir seu pacote internal \@demo@notation
para o valor de uma variável L3 sem usar a linguagem L3 diretamente (portanto, sem \ExplSyntaxOn
ou \ProvidesExplPackage
). Isso foi feito usando \ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}
, o que significa: Antes de usar \let
use dois argumentos, o primeiro é um token único inalterado ( N
), o segundo é um grupo entre chaves que deve formar uma macro por \csname
. Portanto, \ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}
é uma variante mais legível desta construção de baixo nível:
\expandafter\let\expandafter\@demo@notation\csname l_keys_choice_tl\endcsname
Espero que esta explicação ajude a explicar por que o seu
\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
}
Não funcionou. Porque l_keys_choice_tl
não se torna magicamente o valor de escolha real, isso foi feito por \ExpandArgs
e teria que ser feito por meios semelhantes aqui (o que meu comentário sugeriu).