后缀宏和大写

后缀宏和大写

当我声明一个带有后缀的宏时,它在\uppercase命令中的使用不起作用。

查看 MWE

\documenclass{article}
\usepackage{suffix}
\begin{document}


\newcommand{\AcCan}{\emph{Actes des Apôtres} canoniques}
\WithSuffix\newcommand\AcCan*{\emph{Actes des Apôtres}}

{\MakeUppercase{Les \AcCan}}
\end{document}

如果删除该\WithSuffix行,就没问题了。

答案1

这里有一种方法,可以让你继续使用\AcCan\AcCan*,而不需要额外的括号。请参阅代码注释和下面的小警告。

更新中添加了额外警告

% -*- coding: iso-latin-1; -*-
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}

% First we patch LaTeX \MakeUppercase and \MakeLowercase
% As far as I can tell, these redefinitions should have nil impact 
% and very few incompatibilies, if any.
\makeatletter
\DeclareRobustCommand{\MakeUppercase}[1]{{%
      \def\i{I}\def\j{J}%
      \def\reserved@a##1##2{\let##1##2\reserved@a}%
      \expandafter\reserved@a\@uclclist\reserved@b{\reserved@b\@gobble}%
      \protected@edef\reserved@a{\uppercase{#1\empty}}% \empty added
      \reserved@a
   }}
\DeclareRobustCommand{\MakeLowercase}[1]{{%
      \def\reserved@a##1##2{\let##2##1\reserved@a}%
      \expandafter\reserved@a\@uclclist\reserved@b{\reserved@b\@gobble}%
      \protected@edef\reserved@a{\lowercase{#1\empty}}% \empty added
      \reserved@a
   }}
\makeatother

% Then we can define expandable variant \AcCan* 
% The collateral effect is that \AcCan act as a brace remover: just be aware
% that \AcCan {<stuff>} will be as original \AcCan <stuff> and never use
% \AcCan {stuff * more stuff} as it will end up in error: I am perhaps not  
% providing it the most robust way (and I don't use e-TeX whose \detokenize
%  would help for alternatives), but in 99% of cases it should be ok.

% Important caveat: if \AcCan is used as part of the argument of a macro,
% like \section then, if it *last* therein before the closing }, it *must* 
% be followed by {}, or \empty, or \relax.

\catcode`_ 11
% helper macro,
\long\def\GobToStar #1*{}
% expandably enhancing \AcCan with a starred variant
\long\def\AcCan #1{\GobToStar #1\AcCan_s *\AcCan_ns #1}
% the \long is in case \AcCan is last on a line, itself followed by empty line.
\def\AcCan_s *\AcCan_ns *{\emph{Actes des Apôtres}}% starred variant
\def\AcCan_ns {\emph{Actes des Apôtres} canoniques}% non starred variant
%
% The above could easily be automatized:
% \MakeStarredVariant\Macro{replacement text for \Macro*}
% with the same limitations as pointed above
%
\catcode`_ 8

\begin{document}

\AcCan

\AcCan*

\MakeUppercase{\AcCan}

\MakeUppercase{\AcCan*}
\end{document}

在此处输入图片描述

当我说 时in 99% of the cases it should be OK,这只是意味着:避免输入像\AcCan {stuff}\AcCan*{stuff}没有问题,只有包含\AcCan {stuff}才是问题)。一般来说,这将是自动的,因为我猜后面会跟着一个字母、标点符号或,或者如果用于例如。stuff*AcCan\par}\section

重要的: 在后一种情况下, (最后的参数\section) 或更一般地,每当\AcCan是某个宏的某个参数的最后一个组成部分时\macro {....\AcCan },建议在其后跟{}、 或\empty\relax

\macro {....\AcCan{}}

例如,这对于 来说是强制性的\section。然而,对于 来说\textbf,这并不是必需的(因为在内部,我们不会陷入\AcCan}扩展\AcCan会引发错误的情况)。

如果用作宏的最后一个参数,即使不写入文件,也存在一个较小的风险,即宏本身会在扩展之前{stuff}添加一些。如果包含,则会出现问题。这种可能性似乎很小。如果在这种不太可能的情况下出现编译错误,请替换为或,这样就没问题了。(除非宏非常顽固地做坏事)\AcCan\AcCanstuff*\AcCan\AcCan {}\AcCan\empty

\AcCan每次写入时都会扩展(aux因此写入时toc,它首先转到aux)文件,这似乎也没有问题:此时它会一劳永逸地寻找*并扩展为两种可能性之一。

但必须注意的是,最后的宏参数中的部分。其后跟{}\empty\relax

答案2

如果你\show\AcCan在这行之后这样做\WithSuffix,你会看到

> \AcCan=\protected macro:
->\WSF@suffixcheck \AcCan .

这意味着\AcCan保持不变\edef,这就是\MakeUppercase对其参数的作用(在\protected@edef形式中)。

因此,\uppercase最终执行的操作仍然可以看到\AcCan,因此不会对其执行任何操作。

如果你愿意接受写作\AcCan{}\AcCan*{}那么你可以这样做:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}

\usepackage{xparse}

\DeclareExpandableDocumentCommand{\AcCan}{sm}{%
  \emph{Actes des Apôtres}%
  \IfBooleanF{#1}{ canoniques}%
}

\begin{document}

{\MakeUppercase{Les \AcCan{}}}

{\MakeUppercase{Les \AcCan*{}}}

\end{document}

在此处输入图片描述

相关内容