在文档中,我想参数化代词,以便当我们改变人时文档更容易改变。
\newcommand\personname[0]{Joanna Smith}
\newcommand\personpronoun[0]{she}
这很棒,
如果 \personname{} 想要第二个 cookie,则 \personpronoun{} 可能会请求一个。
但在句首,它就变得很尴尬,因为我们希望它大写。
\personpronoun 应该用餐巾纸擦去手指上多余的巧克力。
有没有比定义两个命令更好的方法?
\newcommand\personpronounlc[0]{she}
\newcommand\personpronounuc[0]{She}
答案1
一些软件包中采用的合理解决方案确实是定义两个命令,但使用大写字母来区分它们,因此
\newcommand\personpronoun{she}
\newcommand\Personpronoun{She}
可以建立一种更自动化的方法\spacefactor
\everypar{\spacefactor3000\relax}% beginning of paragraphs
% normally after sentences, the spacefactor is 3000
\DeclareRobustCommand\personpronoun{\leavevmode\ifnum\spacefactor<3000 she\else She\fi}
但我真的不推荐这样做,因为频繁出现的异常情况使它变得太不可靠,而且比在输入命令时简单地将字母大写要麻烦得多。
答案2
在以下情况下,您可以尝试稍微自动化一些事情:
- 该宏
\personpronoun
仅用于普通文本段落。(即,游戏仅涉及(内部)垂直模式和水平模式。不涉及受限水平模式或任何数学模式。) - 标点符号
.
,:
,?
,!
具有空格因子代码\sfcode
,可以与\sfcode
所有其他字符的 区别开来。因此:\personpronoun
在这种情况下,宏仅与字体/设置一起使用。- 该宏仅在有效
\personpronoun
时使用。\nonfrenchspacing
在这些条件下,您可以让 TeX 检查它是否在内\vmode
,如果不在内,则检查当前空间因子是否等于\sfcode
其中一个标点符号的。
但这种方法并不完全可靠。很多情况下,这种检查不够充分或被人利用。
\documentclass{article}
\makeatletter
\@ifdefinable\CheckVmodeOrPunctuationSpaceFactor{%
\DeclareRobustCommand\CheckVmodeOrPunctuationSpaceFactor{%
\ifvmode\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{%
\ifnum\the\sfcode`\.=\spacefactor\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{%
\ifnum\the\sfcode`\!=\spacefactor\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{%
\ifnum\the\sfcode`\?=\spacefactor\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{%
\ifnum\the\sfcode`\:=\spacefactor\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@secondoftwo}{\@firstoftwo}%
}%
}%
}%
}%
}%
}%
\makeatother
\newcommand\personname{Joanna Smith}
\newcommand\personpronoun{\CheckVmodeOrPunctuationSpaceFactor{s}{S}he}
% \frenchspacing % <---Don't do this!
\nonfrenchspacing
\begin{document}
If \personname{} wants a second cookie, \personpronoun{} may ask for one. \personpronoun{} is expected to use a napkin to wipe excess chocolate from fingers.
\personpronoun{} is expected to use a napkin to wipe excess chocolate from fingers.
\end{document}
由于这种方法固有的不可靠性,我更喜欢采用不同的方法:
由于\personpronoun
后面跟着一个空组,为了正确获取控制字标记后面的间距,您可以定义\personpronoun
一个强制参数,该参数可用于在小写和大写变体之间进行选择。
在以下示例中,如果的参数\personpronoun
为空,则使用小写形式。否则,使用大写形式:
\documentclass{article}
\makeatletter
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% If you don't have eTeX-extensions, then do:
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
%%\newcommand\CheckWhetherNull[1]{%
%% \romannumeral0\expandafter\@secondoftwo\string{\expandafter
%% \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
%% \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
%% \@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
%% {\@firstoftwo\expandafter{} \@firstoftwo}%
%%}%
%% If you have eTeX-extensions, then do:
\newcommand\CheckWhetherNull[1]{%
\romannumeral0\ifcat$\detokenize{#1}$%
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@firstoftwo\expandafter{} \@firstoftwo}%
{\@firstoftwo\expandafter{} \@secondoftwo}%
}%
\makeatother
\newcommand\personname{Joanna Smith}
\newcommand\personpronoun[1]{\CheckWhetherNull{#1}{s}{S}he}
\begin{document}
If \personname{} wants a second cookie, \personpronoun{} may ask for one. \personpronoun{UC} is expected to use a napkin to wipe excess chocolate from fingers.
\personpronoun{UC} is expected to use a napkin to wipe excess chocolate from fingers.
\end{document}
但这仍然很麻烦。
最好只是定义\personpronoun
并\Personpronoun
按照建议唐纳德·阿瑟诺。
您可能希望加载包空间并将一个附加\xspace
到代词。在许多情况下,\xspace
当需要空格标记时,可以正确地插入空格标记,但是相应的 .tex 输入文件中的空格字符在标记化过程中被吃掉,因为它发生在被标记为控制字标记的某些东西后面,这导致 TeX 将读取装置切换到状态 S(跳过空格)。
\documentclass{article}
\usepackage{xspace}
\newcommand\personname{Joanna Smith\xspace}
\newcommand\personpronoun{she\xspace}
\newcommand\Personpronoun{She\xspace}
\begin{document}
If \personname wants a second cookie, \personpronoun may ask for one. \Personpronoun is expected to use a napkin to wipe excess chocolate from fingers.
\Personpronoun is expected to use a napkin to wipe excess chocolate from fingers.
\end{document}