与使用第三方宏 \addmoretexcs 的 \spacefactor 相关的错误

与使用第三方宏 \addmoretexcs 的 \spacefactor 相关的错误

我正在使用列表命令\addmoretexcs,它的起源这里。随着 TeX Live 2014 的更新(可能也包括 的更新listings),以下代码返回错误:

\documentclass{minimal}
\usepackage{ltxcmds}
\usepackage{listings}

\makeatletter
\newcommand{\IfPackageLoaded}[2]{\ltx@ifpackageloaded{#1}{#2}{}}
\makeatother


\IfPackageLoaded{listings}{%

\makeatletter
\newcommand*{\addmoretexcs}[2][common]{%
  \lowercase{\@ifundefined{lstlang@tex$#1}}{%
    \lstloadlanguages{[#1]TeX}%
  }{}%
  \lowercase{\expandafter\g@addto@macro\csname lstlang@tex$#1\endcsname}{%
    \lstset{moretexcs={#2}}%
  }%
}
\makeatother

}% End of \IfPackageLoaded

\addmoretexcs[LaTeX]{setlength}

\begin{document}
\end{document}

有问题的错误是

! You can't use `\spacefactor' in vertical mode.
\@->\spacefactor 
\@m 
l.23 \addmoretexcs[LaTeX]{setlength}

请注意,如果我用 替换\IfPackageLoadedltx@ifpackageloaded错误就会消失。然而,这并不是解决方案。

实际错误可能出在包内;我无法进一步调试。关于此错误的来源有什么提示吗?

答案1

我怀疑在更新到 TeX Live 2014 之前代码是否能正常工作,因为无论如何它都是错误的。

\IfPackageLoaded{listings}{%

\makeatletter
\newcommand*{\addmoretexcs}[2][common]{%
  \lowercase{\@ifundefined{lstlang@tex$#1}}{%
    \lstloadlanguages{[#1]TeX}%
  }{}%
  \lowercase{\expandafter\g@addto@macro\csname lstlang@tex$#1\endcsname}{%
    \lstset{moretexcs={#2}}%
  }%
}
\makeatother

}% End of \IfPackageLoaded

替换文本\addmoretexcs(实际上是内部宏,因为您的命令有一个可选参数)由以下标记组成(为了清楚起见,使用• 来分隔标记)

\lowercase • { • \@ • i • f • u • ...

因为作为参数给出的文本\IfPackageLoaded已经被标记并且 TeX没有\makeatletter在吸收这个论点时执行。

正确代码:

\makeatletter
\IfPackageLoaded{listings}{%
  \newcommand*{\addmoretexcs}[2][common]{%
    \lowercase{\@ifundefined{lstlang@tex$#1}}{%
      \lstloadlanguages{[#1]TeX}%
    }{}%
    \lowercase{\expandafter\g@addto@macro\csname lstlang@tex$#1\endcsname}{%
      \lstset{moretexcs={#2}}%
    }%
  }%
}% End of \IfPackageLoaded
\makeatother

现在,当该论点被吸收时,\@ifundefined它被标记为一个单独的标记,而不是十二个。


还有一些话

如果将原始代码包含在文件中,它似乎可以工作,因为这些文件是在开头和结尾处都.sty使用隐式声明读入的(更准确地说,的类别代码恢复为文件打开时的值)。\makeatletter\makeatother@.sty

作为一般规则,\makeatletter\makeatother永远不应出现在.sty文件中(除非属于某些宏的替换文本,但此处并非如此)。在文件中\makeatother,在 的第二个参数中使用\IfPackageLoaded是错误的,因为如果已经加载,它将从此时.sty起更改 的类别代码。@listings

因此,如果你要在文件中使用上面的代码.sty消除\makeatletter声明\makeatother

相关内容