.sty 文件中的命令不“合法”

.sty 文件中的命令不“合法”

考虑以下样式文件goat.sty

\NeedsTeXFormat{LaTeX2e}[2014/05/01]
\ProvidesPackage{goat}[2014/10/16 goat]

\DeclareOption{mammalbirdfish}{
\makeatletter
 \begingroup
  \catcode`\_=\active
  \protected\gdef_{\@ifnextchar|\subtextup\sb}
 \endgroup
\def\subtextup|#1|{\sb{\textup{#1}}}
\AtBeginDocument{\catcode`\_=12 \mathcode`\_=32768}
\makeatother}

\ExecuteOptions{mammalbirdfish}
\ProcessOptions

当我尝试在 LaTeX 文档中加载该包并执行时\usepackage{goat},出现以下错误:

! Missing control sequence inserted.
<inserted text> 
                \inaccessible 
l.13 \ExecuteOptions{mammalbirdfish}

如何将上面的代码块放入我的样式文件中?

PS:我之前从来没有写过样式文件,所以如果我的问题答案很简单,请原谅我。

更新

我也不能把

\ExplSyntaxOn
  \cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff

进入我的风格文件

\NeedsTeXFormat{LaTeX2e}[2014/05/01]
\ProvidesPackage{goat}[2014/10/16 goat]

\RequirePackage{expl3}

\DeclareOption{macros}{
\ExplSyntaxOn
  \cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
}

\ExecuteOptions{macros}
\ProcessOptions

当我编写文档时

\documentclass{article}

\usepackage{goat}

\begin{document}

test

\end{document}

它给出了错误

! Undefined control sequence.
\ds@makroer ...scriptfalse \par \ExplSyntaxOn \cs 
                                                  _new_eq:NN \calc \fp _eval...

我该如何解决?

(如果我应该把更新问题作为一个新问题提出,请告诉我;它被放在这里是因为我思考这可能是一个类似的问题。

答案1

让我们看看会发生什么

\DeclareOption{mammalbirdfish}{
\makeatletter
 \begingroup
  \catcode`\_=\active
  \protected\gdef_{\@ifnextchar|\subtextup\sb}
 \endgroup
\def\subtextup|#1|{\sb{\textup{#1}}}
\AtBeginDocument{\catcode`\_=12 \mathcode`\_=32768}
\makeatother}

\ExecuteOptions{mammalbirdfish}
\ProcessOptions

\makeatletter从到 的代码\makeatother是作为 的参数给出的\DeclareOption,因此它已经被标记化,特别是,_之后的\gdef类别代码为 8,因此\gdef当代码为执行(存储它不是问题,因为 TeX 此时不会解释命令)。

在类或包文件中,几乎不需要发出\makeatletterand ,因为它们是在末尾隐式使用and读取的。更准确地说,类或包文件中的这些命令通常是错误的,除非它们作为宏定义的一部分出现。在这种情况下,它们是\makeatother\makeatletter\makeatother错误的,因为当\ProcessOptions扩展选项的代码时mammalbirdfish\makeatother将破坏对类或包中代码的所有后续读取。

请注意,将该代码设置为无论如何都会执行的选项是无稽之谈:这样的选项永远不应该传递给\ExecuteOptions

然而,最重要的问题是的类别代码_。我将展示一种不同于设置条件并在\ProcessOptions条件为真后执行代码的策略。

\begingroup\lccode`\~=`\_
\lowercase{\endgroup
  \DeclareOption{mammalbirdfish}{%
    \protected\gdef~{\@ifnextchar|\subtextup\sb}%
    \def\subtextup|#1|{\sb{\textup{#1}}}%
    \AtBeginDocument{\catcode`\_=12 \mathcode`\_=\string"8000 }%
  }%
}

之所以有效,是因为代码中没有大写字符标记,因此只有~(已经处于活动状态) 才会转换为 (活动) _

类似的问题还有

\DeclareOption{macros}{
\ExplSyntaxOn
  \cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff
}

应该是

\ExplSyntaxOn
\DeclareOption{macros}{
  \cs_new_eq:NN \calc \fp_eval:n
}
\ExplSyntaxOff

否则字符:_将被标记为“其他字符”。

答案2

我不确定我的评论是否比泥巴还不清楚,但对于评论来说代码太多了——抱歉。如果可以的话,我很乐意稍后删除它。

\NeedsTeXFormat{LaTeX2e}[2014/05/01]
\ProvidesPackage{goat}[2014/10/16 goat]

\newif\ifmammalbirdfish
\mammalbirdfishfalse
\DeclareOption{mammalbirdfish}{%
  \mammalbirdfishtrue}

\ExecuteOptions{mammalbirdfish}
\ProcessOptions
\ifmammalbirdfish
  \begingroup
    \catcode`\_=\active
    \protected\gdef_{\@ifnextchar|\subtextup\sb}%
  \endgroup
  \def\subtextup|#1|{\sb{\textup{#1}}}%
  \AtBeginDocument{%
    \catcode`\_=12 \mathcode`\_=32768}%
\fi

相关内容