Невозможно передать опции выбора в пакет

Невозможно передать опции выбора в пакет

Я пытаюсь создать пользовательский пакет, который будет содержать все мои личные макросы и пользовательский класс для моего личного стиля. Я хотел передать ключевой аргумент, notationкоторый может принимать значение mathили physicsдля того, чтобы изменить обозначения для разных курсов, которые я прохожу (например, в математике комплексное сопряжение часто обозначается чертой, а в физике — звездочкой). Поигравшись и проследив за ответами, я получилздесь. У меня есть эти 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=mathfrom \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). Это было сделано с помощью \ExpandArgs{Nc}\let\@demo@notation{l_keys_choice_tl}, что означает: перед использованием \letиспользуйте два аргумента, первый — это неизменный одиночный токен ( 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, и должно было быть сделано аналогичными способами здесь (что и предполагал мой комментарий).

Связанный контент