我正在尝试使用更简洁的接口重写我的自定义类。在其他帖子建议使用 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
变量和一个选项,用于在使用时设置变量(还有另一种使用 的方法:请参阅我在完整代码中如何定义选项)。必须为选项传递一个值(即 的含义)。但为了触发上述调用的执行,必须使用选项列表进行调用。这可以从包中完成:language
wrapper
.tl_set:N
class
.value_required:n = true
\str_gset:Nn
\keys_set:nn { wrapper } { ... }
\ProcessKeysOptions
l3keys2e
\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
语言);\LoadClass
str
期望类名的类别代码为 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}