使用 LaTeX2e 的内置机制

使用 LaTeX2e 的内置机制

我有一个课程beamer-rl用于为 RTL 语言(如波斯语)创建 beamer 演示文稿,我需要一种方法将 RTL 语言作为课程选项包含在内,就像这样\documentclass[persian]{beamer-rl}

因此,类将测试是否persian在 RTL 语言列表中,例如:{arabic,arabic-DZ,arabic-MA,persian,hebrew,....}然后将处理命令

\AddToHook{env/document/before}{\babelprovide[import,main]{#1}} % #1 will hold persian 

最终结果是一个类,用户可以将 RTL 主语言添加为类的选项,如下所示

\documentclass[persian]{beamer-rl} % or arabic, hebrew, ...
\usetheme{Warsaw}
\begin{document}
\begin{frame}{}
سلام
\end{fram}
\end{document}

类文件开头如下

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{beamer-rl}
[2022/12/17 v1.7  LaTeX class to patch beamer for right to left presentation with babel]

\RequirePackage{kvoptions}
\RequirePackage{kvsetkeys}

\SetupKeyvalOptions{
    family=beamer-rl,
    prefix=beamer-rl@,
    setkeys=\kvsetkeys,
}

% babel options:
\define@key{beamer-rl}{babel}{%
    \PassOptionsToPackage{#1}{babel}%
}

DeclareDefaultOption{%
    \PassOptionsToClass{\CurrentOption}{beamer}%
}

\ProcessKeyvalOptions*\relax

\RequirePackage{ifluatex}

\ifluatex
\else
\ClassError{beamer-rl}{beamer-rl require lualatex}
\fi

\LoadClass[hyperref={unicode}]{beamer}

\RequirePackage[nil,bidi=basic]{babel}

对于单个选项(语言),我可以使用以下方式定义它

 \DeclareVoidOption{persian}{%
        \AddToHook{env/document/before}{\babelprovide[import,main]{persian}}}

但是当使用有错误的\@for循环时,事情就不会奏效Missing \endcsname inserted

\def\langlist{arabic,arabic-MA,arabic-DZ,persian,hebrew}
\@for \next:=\langlist\do{%
\DeclareVoidOption{\next}{%
\AddToHook{env/document/before}{\babelprovide[import,main]{\next}}}}

答案1

我假设您不想更改选项中使用的包。现在我会选择内置的 LaTeX2e/ 机制expl3\ProcessKeyOptionsexpkv-opt(我是其作者)。无论如何,您的问题\@for是您需要扩展\next,下面将执行此操作。

\newcommand*\langlist{arabic,arabic-MA,arabic-DZ,persian,hebrew}
\@for \next:=\langlist\do
  {%
    \expanded{\noexpand\DeclareVoidOption{\next}
      {%
        \noexpand\AddToHook{env/document/before}%
          {\noexpand\babelprovide[import,main]{\next}}%
      }}%
  }

不过,我建议\@for在这种情况下不要使用,而是使用更容易正确使用的方式\clist_map_inline:nn

\ExplSyntaxOn
\clist_map_inline:nn {arabic,arabic-MA,arabic-DZ,persian,hebrew}
  {
    \DeclareVoidOption{#1}{
      \AddToHook{env/document/before}{\babelprovide[import,main]{#1}}}
  }
\ExplSyntaxOff

你的完整最小类文件将是:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{beamer-rl}
[2022/12/17 v1.7  LaTeX class to patch beamer for right to left presentation with babel]

\RequirePackage{kvoptions}
\RequirePackage{kvsetkeys}

\SetupKeyvalOptions{
    family=beamer-rl,
    prefix=beamer-rl@,
    setkeys=\kvsetkeys,
}

% babel options:
\define@key{beamer-rl}{babel}{\PassOptionsToPackage{#1}{babel}}

\DeclareDefaultOption{\PassOptionsToClass{\CurrentOption}{beamer}}

\ExplSyntaxOn
\clist_map_inline:nn {arabic,arabic-MA,arabic-DZ,persian,hebrew}
  {
    \DeclareVoidOption{#1}{
      \AddToHook{env/document/before}{\babelprovide[import,main]{#1}}}
  }
\ExplSyntaxOff

\ProcessKeyvalOptions*\relax

\RequirePackage{ifluatex}

\ifluatex
\else
\ClassError{beamer-rl}{beamer-rl require lualatex}
\fi

\LoadClass[hyperref={unicode}]{beamer}

\RequirePackage[nil,bidi=basic]{babel}

使用 LaTeX2e 的内置机制

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{beamer-rl}
[2022/12/17 v1.7  LaTeX class to patch beamer for right to left presentation with babel]

\DeclareKeys
  {
     babel   .code:n = \PassOptionsToPackage{#1}{babel}
    ,unknown .code:n = \PassOptionsToClass{\CurrentOption}{beamer}
  }
\ExplSyntaxOn
\clist_map_inline:nn {arabic,arabic-MA,arabic-DZ,persian,hebrew}
  {
    \DeclareKeys
      {
         #1 .code:n = 
          \AddToHook{env/document/before}{\babelprovide[import,main]{#1}}
        ,#1 .value_forbidden:n = true
      }
  }
\ExplSyntaxOff

\ProcessKeyOptions

\RequirePackage{ifluatex}

\ifluatex
\else
\ClassError{beamer-rl}{beamer-rl require lualatex}
\fi

\LoadClass[hyperref={unicode}]{beamer}

\RequirePackage[nil,bidi=basic]{babel}

使用expkv-opt

示例文件使用expkv-defexpkv-opt(所示\ekvoProcessOptions是尚未发布的版本的一部分,但我估计将在接下来的几天内发生,您可以改用\ekvoProcessGlobalOptions\ekvoProcessLocalOptions)。

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{beamer-rl}
[2022/12/17 v1.7  LaTeX class to patch beamer for right to left presentation with babel]

\RequirePackage{expkv-def,expkv-opt}

\ekvdefinekeys{beamer-rl}
  {
     code    babel = \PassOptionsToPackage{#1}{babel}
    ,unknown code  = \PassOptionsToClass{\CurrentOption}{beamer}
    ,unknown noval = \PassOptionsToClass{\CurrentOption}{beamer}
  }
% expkv has its own csv-loop, but you could still use \clist_map_inline:nn
% instead
\def\beamerRL@tmp#1
  {%
    \ekvdefNoVal{beamer-rl}{#1}%
      {\AddToHook{env/document/before}{\babelprovide[import,main]{#1}}}%
  }
\ekvcsvloop\beamerRL@tmp{arabic,arabic-MA,arabic-DZ,persian,hebrew}
\ekvoUseUnknownHandlers*
\ekvoProcessOptions{beamer-rl}

\RequirePackage{ifluatex}

\ifluatex
\else
\ClassError{beamer-rl}{beamer-rl require lualatex}
\fi

\LoadClass[hyperref={unicode}]{beamer}

\RequirePackage[nil,bidi=basic]{babel}

相关内容