不允许在宏或环境参数中使用 \textbf、\it、\sffamily 等

不允许在宏或环境参数中使用 \textbf、\it、\sffamily 等

我想要一个命令,\newcommand{\restricted}[1]{...}它不允许您使用类似

\restricted{calling me {\bf like} this \textit{is} not allowed}

即,应禁止在其参数中使用\bf、、\textbf和朋友。\tt

当然,我可以,正如仅允许在自己的环境中执行某些命令,重新定义所有这些命令以在我的命令内部抛出错误,但这非常不雅致。

因为它们都是字体更改命令,所以我希望它们都调用一些内部命令,这样本地重新定义这个命令就可以给我我想要的行为。

不幸的是,我不知道它\textbf是如何实现的,在谷歌上找不到关于其内部运作的任何文档,而且\show\textbf信息量也不大。

澄清一下:我不仅想抑制这些宏的效果,而且真的想禁止它们。背景是我正在编写一个 documentclass,并且由于的内容\title{}应该始终相同并且还用于自动设置 pdf 元数据,因此作者不应该能够说类似这样的话\title{\textbf{I want my title bold}}

答案1

没有可用的字体更改命令列表,但您可以\selectfont在组内重新定义,除了发出错误消息外不执行任何操作。

\documentclass{article}

\makeatletter
\newcommand{\restricted}[1]{%
  \begingroup
  \let\selectfont\cgogolin@error
  #1%
  \endgroup
}
\newcommand{\cgogolin@error}{%
  \@latex@error{Font change not allowed}
    {You used a font changing command, which is\MessageBreak
     not permitted here}%
}
\makeatother

\begin{document}

\restricted{calling me {\bfseries like} this \textit{is} not allowed}

\end{document}

这是终端上的输出:

! LaTeX Error: Font change not allowed.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.19 ...series like} this \textit{is} not allowed}

在此处输入图片描述

答案2

以下最小示例通过使用以下方式提供选择性字体切换检查etoolbox\patchcmd。每个字体开关用于修补的参数\restricted。如果成功,则生成错误,否则不发生任何事情。

\documentclass{article}

\usepackage{etoolbox}

\makeatletter
\newcommand{\restricted}[1]{%
  \def\restricted@arg{#1}%
  \renewcommand{\do}[1]{%
    \patchcmd{\restricted@arg}% <cmd>
      {##1}{##1}% <search><replace>
      {\cgogolin@error}{}% <success><failure>
  }
  \docsvlist{\bfseries,\textit}% Check for certain font uses... add more
  % <do stuff with #1>
}
\newcommand{\cgogolin@error}{%
  \@latex@error{Font change not allowed}
    {You used a font changing command, which is\MessageBreak
     not permitted here}%
}
\makeatother

\begin{document}

Calling me {\bfseries like} this \textit{is} allowed.

\restricted{Calling me {\bfseries like} this \textit{is} not allowed.}

\end{document}

但需要注意的是,它需要测试明确的使用任何特定的字体开关。例如,\bfseries如果仅检查,则允许使用\textbf。此外,不会对参数执行任何扩展,因此不会拾取隐藏的字体开关(例如,如果\let\mybfseries\bfseries使用)。

相关内容