是否可以防止类选项被传递给某些包?

是否可以防止类选项被传递给某些包?

我的文档类中有一个名为的选项indent。但是,一些已加载的包也有此选项,并且由于该选项是\documentclass[...]{myclass}作为全局选项写入的,因此会传递给所有这些包。是否可以阻止将此选项传递给这些包?

我的课程文件的开头如下:

\def\minimclass@baseclass{article}
\RequirePackage{kvoptions}
\RequirePackage{etoolbox}
\SetupKeyvalOptions{
    family = @minimclass,
    prefix = @minimclass@,
}
\DeclareBoolOption[false]{indent}
\DeclareDefaultOption{\PassOptionsToClass{\CurrentOption}{\minimclass@baseclass}}
\ProcessKeyvalOptions*\relax
\LoadClass{\minimclass@baseclass}

答案1

因此,在我开始之前,我建议你也许应该重命名文档类的选项。假设全局选项的整个概念可能没有得到很好的构思,那么你的类的用户可能会因为行为偏离常规而感到困惑。

话虽如此,解决这个问题本身就具有指导意义,值得考虑。

当您将选项传递给 时\documentclass,它们会存储在宏中\@classoptionslist以供处理。所以我们想要做的是摆脱给定的选项。我们将使用 的功能clistexpl3获取我们想要的内容(因此假设您正在使用当前的 LaTeX 格式或已加载包expl3,并且在您的类中使用\ExplSyntaxOn...\ExplSyntaxOff\ProvidesExplClass来指示整个过程正在使用expl3语法。

现在,expl3逗号列表只是一个用逗号分隔的值定义的宏,所以即使它不遵循expl3命名约定,我们也可以\@classoptionslist在任何地方使用我们想要的clist

如果字符串出现在选项列表中,我们希望将其删除,因此我们将创建一个新的逗号列表 ❶,用不是的indent所有内容填充它❷,然后将新的逗号列表值复制到❸。以下是执行此操作的代码:\@commandoptionslistindent\@commandoptionslist

\clist_new:N \l_minim_temp_clist % ❶
\clist_map_inline:Nn \@classoptionslist
{
  \str_if_eq:nnF { #1 }{ indent }
    { \clist_put_right:Nn \l_minim_temp_clist { #1 } } % ❷
}

\cs_set_eq:NN \@classoptionslist \l_minim_temp_clist % ❸

需要注意的是,这些\clist_map_*函数并不是大多数函数式语言所称的 map,因为它们不返回新的。相反,它们更像是.¹clist中元素的 foreachclist

所有这些都可以在没有的情况下实现expl3,但最终会变得更加混乱(例如,您需要使用临时宏和来\ifx比较两个字符串值,而最好忘记对逗号分隔列表进行旧式循环)。


  1. 我的预期是,地图线看起来更像

    \clist_map_inline:NNn \SOURCE_CLIST \TARGET_CLIST { MAP CODE }
    

    因此,在处理 LaTeX 代码时,最好降低对其他编程语言的期望。

相关内容