将选项传递给类并使用 latex3 接口进行评估

将选项传递给类并使用 latex3 接口进行评估

我正在尝试使用更简洁的接口重写我的自定义类。在其他帖子建议使用 latex3 项目提供的功能。全面概述CTAN latex3 项目的 LATEX3 接口

假设我为两种语言创建两个示例文档并对其进行处理(lualatex / texlive 2020):lualatex --shell-escape

\documentclass{scrartcl}
\usepackage{shellesc}

\begin{filecontents}[overwrite]{manual_de.tex}
  \documentclass{scrartcl}

  \usepackage{polyglossia}
  \setdefaultlanguage{german}
  \setkeys{german}{
    spelling=new,
  }

  \usepackage[toc]{blindtext}

  \begin{document}
  \Blinddocument
  \end{document}
\end{filecontents}


\begin{filecontents}[overwrite]{manual_en.tex}
  \documentclass{scrartcl}

  \usepackage{polyglossia}
  \setdefaultlanguage{english}
  \setkeys{english}{
    variant=english,
  }

  \usepackage[toc]{blindtext}

  \begin{document}
  \Blinddocument
  \end{document}
\end{filecontents}

\begin{document}
\ShellEscape{lualatex manual_de.tex}
\ShellEscape{lualatex manual_en.tex}
\end{document}

现在我想将其转移到一个类并通过传递一个选项来改变语言:

\documentclass{scrartcl}
\usepackage{shellesc}

\begin{filecontents}[overwrite]{wrapper.cls}
  \NeedsTeXFormat{LaTeX2e}
  \RequirePackage{expl3}
  \ProvidesExplClass{wrapper}{2020/05/15}{0.1}{Testclass}

  \keys_define:nn {wrapper}
  { 
    language .default:n = {deutsch} % how to define a variable
  }

  \RequirePackage{polyglossia}

  \str_case:nnF { wrapper.language ??? } % how to access language in wrapper ?
  {
    {deutsch} % wrapper.language == deutsch
    {
      \setdefaultlanguage{german}
      \setkeys{german}{
        spelling=new,
      }
    }
    {english} % wrapper.language == english
    {
      \setdefaultlanguage{english}
      \setkeys{english}{
        variant=english,
      }
    }
  }{\ClassError{wrapper}{unknown language - aborting}}
\end{filecontents}

\begin{filecontents}[overwrite]{useWrapper.tex}
\documentclass{wrapper}

\usepackage[toc]{blindtext}

\begin{document}
\blindtext
\end{document}
\end{filecontents}



\begin{document}
\ShellEscape{lualatex useWrapper.tex}
\end{document}

我已经陷入两个问题(实际上是简单的问题):

  • 如何正确设置包含“语言”的变量?这应该是字符串还是值:键语法?
  \keys_define:nn {wrapper}
  { 
    language .default:n = {deutsch} % how to define a variable
  }
  • 我如何访问此字符串或键:值构造?
  \str_case:nnF { wrapper.language ??? } % how to access language in wrapper ?

答案1

在 中\keys_define:nn.default:n用于说明选项(键)在未传递任何值时执行的操作,例如\documentclass[language]{wrapper}与 相对\documentclass[language=english]{wrapper}。您想要的设置是使用.initial:n;例如,我的以下代码具有:

\str_new:N \g__wrapper_language_str

\keys_define:nn { wrapper }
  {
    language .code:n = { \str_gset:Nn \g__wrapper_language_str {#1} },
    language .initial:n = deutsch,
    language .value_required:n = true,
  }

这为包或类定义了一个str变量和一个选项,用于在使用时设置变量(还有另一种使用 的方法:请参阅我在完整代码中如何定义选项)。必须为选项传递一个值(即 的含义)。但为了触发上述调用的执行,必须使用选项列表进行调用。这可以从包中完成:languagewrapper.tl_set:Nclass.value_required:n = true\str_gset:Nn\keys_set:nn { wrapper } { ... }\ProcessKeysOptionsl3keys2e

\ProcessKeysOptions { wrapper }

此时,您已\g__wrapper_language_str包含所选(或默认)语言。因此,您可以使用以下命令根据选项值执行代码:

\str_case:VnF \g__wrapper_language_str
  {
    { deutsch }
    { ... }
    { english }
    { ... }
  }
  {
    \ClassError { wrapper } { Unknown~language~setting }
      { ... }
  }

参数V类型\str_case:VnF \g__wrapper_language_str { ... } { ... }表示我们传递价值\g__wrapper_language_str基本形式\str_case:nnF

这基本上就是您所需要的,但由于工作方式的不同,还有一些微妙之处polyglossia

  • 在调用之前,必须加载定义 的类\normalsize,例如article或;scrartcl\RequirePackage{polyglossia}

  • \setdefaultlanguage仅在\ExplSyntaxOff类别代码制度下可靠地工作(尝试使用该german语言);

  • \LoadClassstr期望类名的类别代码为 11 个字母,如果我使用变量来保存类,情况就不会如此(因此,我使用了一个tl变量,它比str类型“更通用” - 在str变量中,每个字符的类别代码都是 12,除了空格,它的类别代码是 10)。

完整代码:

\documentclass{article}
\usepackage{shellesc}

\begin{filecontents}[overwrite]{wrapper.cls}
  \NeedsTeXFormat{LaTeX2e}
  \RequirePackage{expl3}
  \RequirePackage{l3keys2e} % for \ProcessKeysOptions
  \ProvidesExplClass{wrapper}{2020/05/15}{0.1}{Test class}

  \str_new:N \g__wrapper_language_str
  \tl_new:N \g__wrapper_class_tl

  \keys_define:nn { wrapper }
    {
      language .code:n = { \str_gset:Nn \g__wrapper_language_str {#1} },
      language .initial:n = deutsch,
      language .value_required:n = true,
      class    .tl_gset:N = \g__wrapper_class_tl,
      class    .initial:n = scrartcl,
      class    .value_required:n = true,
    }
  \ProcessKeysOptions { wrapper } % process the keys that were passed to us
  \exp_args:NV \LoadClass \g__wrapper_class_tl

  \AtEndOfClass
    {
      \RequirePackage{polyglossia}
      \ExplSyntaxOff % Needed for \setdefaultlanguage to work properly

      \str_case:VnF \g__wrapper_language_str
        {
          { deutsch }
          { \setdefaultlanguage [spelling=new] { german } }
          { english }
          { \setdefaultlanguage [variant=british] { english } }
        }
        {
          \ClassError { wrapper } { Unknown~language~setting }
            {
               Invalid~value~for~the~'language'~option:~
               '\g__wrapper_language_str'.
            }
        }
    }
\end{filecontents}

\begin{filecontents}[overwrite]{useWrapper.tex}
\documentclass[language=english, class=article]{wrapper}
\usepackage[toc]{blindtext}

\begin{document}
\blindtext
\end{document}
\end{filecontents}

\begin{document}
\ShellEscape{lualatex useWrapper.tex}
\end{document}

在此处输入图片描述

相关内容