我有一个课程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
和\ProcessKeyOptions
或expkv-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-def
和expkv-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}