更新

更新

我刚刚检查了标题等的“大写标准”,想知道是否有宏可以完成我现在不得不手动完成的相同操作。我的个人规则(欢迎提出不同意见/评论)如下:

  1. 第一个字母(根据这些规则,数字也是字母)总是大写,
  2. 每一个单词单独大写,
  3. 上述规则的例外情况(以及只是上述规则)封闭类词比如介词之类的。

换句话说:我想要一个大写命令(如\MakeUppercase),将每个单词都大写不是包含在单词列表中,并且将总是将其参数的第一个单词大写。

可行吗?

附注:可以找到一个这样的封闭类词(也称为“功能词”)“列表”这里

答案1

\documentclass[a4paper]{article}
\usepackage[latin1]{inputenc}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\capitalize}{>{\SplitList{~}}m}{
  \CapitalizeFirst#1\Capitalize\unskip
}
\ExplSyntaxOff
\def\Sentinel{\Capitalize}
\def\CapitalizeFirst#1{\MakeUppercase#1 \Capitalize}
\def\Capitalize#1{%
  \def\next{#1}%
  \ifx\next\Sentinel
    \expandafter\unskip
  \else
    \CheckInList{#1}\space\expandafter\Capitalize
  \fi}
\def\CheckInList#1{%
  \ifcsname List@\detokenize{#1}\endcsname
    #1%
  \else
    \MakeUppercase#1%
  \fi}
\makeatletter
\def\AppendToList#1{%
  \@for\next:=#1\do
  {\expandafter\let\csname List@\detokenize\expandafter{\next}\endcsname\empty}}
\makeatother
\AppendToList{a,is,of}

\begin{document}
\capitalize{here is a list of words école}
\end{document}

不适用于 UTF-8(除非使用 XeLaTeX 或 LuaLaTeX)。

它不适用于 UTF-8,pdflatex因为\MakeUppercase仅适用于可能的两个、三个或四个字节组合的第一个字节(对于西方语言可能只有两个)。要使它起作用,必须将整个字节块输入\MakeUppercase

更清楚一点:当我们说 时\MakeUppercase,LaTeX 会将参数大写;一般来说,调用是\MakeUppercase{word};这里我们改为说\MakeUppercase#1(不带括号),因此只有第一个标记(通常是一个字符)会大写;这里它会在输入诸如 时失败\'ecole:传递给 的标记\MakeUppercase将是\',它不知道该怎么做。使用école(和诸如 这样的单字节编码latin1\MakeUppercase将处理é并给出正确的结果。

使用 UTF-8 的话就会失败:就像é我们在屏幕上编写 LaTeX 文档时实际上两个字节(对于 C3 和 A9 é)并且再次\MakeUppercase只传递第一个。因此需要更复杂的例程。

为了使其与 UTF-8 兼容,上面pdflatex的定义可以更改为以下内容\CheckInList\CapitalizeFirst

\def\CapitalizeFirst#1{\expandafter\UC@next#1 \Capitalize}
\def\CheckInList#1{%
  \ifcsname List@\detokenize{#1}\endcsname
    #1%
  \else
    \expandafter\UC@next#1%
  \fi}
\def\UC@next#1{%
  \ifx#1\UTFviii@two@octets
     \expandafter\@firstoffour
  \else
    \ifx#1\UTFviii@three@octets
      \expandafter\expandafter\expandafter\@secondoffour
    \else
      \ifx#1\UTFviii@four@octets
        \expandafter\expandafter\expandafter\expandafter\expandafter
        \@thirdoffour
      \else
        \expandafter\expandafter\expandafter\expandafter\expandafter
        \expandafter\expandafter\@fourthoffour
      \fi
    \fi
  \fi
  {\UC@two}{\UC@three}{\UC@four}{\MakeUppercase}#1}
\def\UC@two#1#2#3{\MakeUppercase{#1#2#3}}
\def\UC@three#1#2#3#4{\MakeUppercase{#1#2#3#4}}
\def\UC@four#1#2#3#4#5{\MakeUppercase{#1#2#3#4#5}}
\providecommand\@firstoffour[4]{#1}
\providecommand\@secondoffour[4]{#2}
\providecommand\@thirdoffour[4]{#3}
\providecommand\@fourthoffour[4]{#4}

但是不允许使用重音命令(在其他版本中也不允许)。


更新

几年后,由于新expl3功能的出现,我们有了更好的实现;它适用于所有引擎。

\documentclass[a4paper]{article}

\usepackage{ifxetex}

\ifxetex
  \usepackage{fontspec}
\else
  \usepackage[T1]{fontenc}
  \usepackage[utf8]{inputenc}
\fi

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\capitalize}{>{\SplitList{~}}m}
 {
  \seq_clear:N \l_capitalize_words_seq
  \ProcessList{#1}{\CapitalizeFirst}
  \seq_use:Nn \l_capitalize_words_seq { ~ }
 }
\NewDocumentCommand{\CapitalizeFirst}{m}
 {
  \capitalize_word:n { #1 }
 }

\sys_if_engine_pdftex:TF
 {
  \cs_set_eq:Nc \capitalize_tl_set:Nn { protected@edef }
 }
 {
  \cs_set_eq:NN \capitalize_tl_set:Nn \tl_set:Nn
 }

\cs_new_protected:Nn \capitalize_word:n
 {
  \capitalize_tl_set:Nn \l_capitalize_word_tl { #1 }
  \seq_if_in:NfTF \g_capitalize_exceptions_seq { \tl_to_str:n { #1 } }
   % exception word
   { \seq_put_right:Nn \l_capitalize_words_seq { #1 } } % exception word
   % to be uppercased
   { \seq_put_right:Nx \l_capitalize_words_seq { \tl_mixed_case:V \l_capitalize_word_tl } }
 }
\cs_generate_variant:Nn \tl_mixed_case:n { V }
\NewDocumentCommand{\AppendToList}{m}
 {
  \clist_map_inline:nn { #1 }
   {
    \seq_gput_right:Nx \g_capitalize_exceptions_seq { \tl_to_str:n { ##1 } }
   }
 }
\cs_generate_variant:Nn \seq_if_in:NnTF { Nf }
\seq_new:N \l_capitalize_words_seq
\seq_new:N \g_capitalize_exceptions_seq
\ExplSyntaxOff

\AppendToList{a,is,of,óf}

\begin{document}
X\capitalize{here is a list of words óf école}X
\end{document}

在此处输入图片描述

答案2

ConTeXt 解决方案:

\applytosplitstringwordspaced您可以使用以下命令:

\def\IgnoredWords
  {a,is,to,of,or,and}

\define[1]\CapitalizeWithIgnoreWord
  {\doifinsetelse{#1}\IgnoredWords{#1}{\Words{#1}}}

\def\CapitalizeWithIgnore
  {\applytosplitstringwordspaced\CapitalizeWithIgnoreWord}

\starttext
  \CapitalizeWithIgnore{This is some of my input or another and to the end.}
\stoptext

这使

在此处输入图片描述

\applytosplitstringwordspaced命令将输入​​分成单词,并将每个单词应用到宏\CapitalizeWithIgnoreWord,该宏接受一个参数。然后我只需测试给定的单词是否是单词列表的成员,然后打印它,或者将其大写打印。

答案3

titlecaps包是新推出的,并在此处演示:大写标题。它将负责为变音符号(例如,变音符号等)和国家符号(例如,oe)添加标题,并与更改字体特征的命令兼容(即,可以包含在其参数中),例如\textit{}\scshape\footnotesize。此外,它允许将单词指定为小写,例如介词和连词,这些单词将被筛选出来而不是标题。标点符号的存在不应影响包将单词大写或将其检测为预先指定的小写单词的能力。

答案4

使用 csplain 您可以通过几行基本宏来实现这一点(它们仅使用 TeX 原语):

\def\capitalize#1{\capitA#1 {} }
\def\capitA#1 {\capitW#1 \capitB}
\def\capitB#1 {\ifx\relax#1\relax \else \space
   \isinlist\extrawords{ #1 }\iftrue #1\else \capitW#1 \fi
   \expandafter \capitB \fi
}
\def\capitW#1#2 {\uppercase{#1}#2}   
\def\isinlist#1#2#3{\begingroup \long\def\tmp##1#2##2\end{\def\tmp{##2}%
   \ifx\tmp\empty \endgroup \csname iffalse\expandafter\endcsname \else
                  \endgroup \csname iftrue\expandafter\endcsname \fi}%
   \expandafter\tmp#1\endlistsep#2\end
}

\def\extrawords{ a is of óf }

X\capitalize{here is a list of words óf école}X

\bye

相关内容