在 pdfTeX 上使用 UTF-8 伪造小型大写字母

在 pdfTeX 上使用 UTF-8 伪造小型大写字母

我正在使用 arev 包编写一篇科学 LaTeX 文章(使用 pfdlatex 编译),并希望对某些专有名词使用小写字母。我在互联网上找到了一个代码

\def\fauxschelper#1#2\relax{%
    \ifnum`#1>``\ifnum`#1<`\{\scalebox{.87}[.79]{\uppercase{#1}}\else#1\fi\else#1\fi%
    \ifx\relax#2\relax\else\fauxschelper#2\relax\fi}
\newcommand\fauxsc[1]{\fauxschelper#1\relax\relax}

看起来不错,但当我尝试使用 UTF-8 编码的 Unicode 字符时,它不起作用。它似乎尝试按字节而不是按字符解释 Unicode 字符。

由于我需要特别的变音符号才能正常工作,因此我尝试使用 etoolbox 包进行其他操作:

\documentclass{scrartcl}

% GENERAL STUFF - ENCODING, LANGUAGE
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}

% GENERAL STUFF - FONT
\usepackage{arev}

% GENERAL STUFF - GRAPHICS
\usepackage{graphicx}
\usepackage{etoolbox}

% DEPENDS ON GRAPHICX PACKAGE (WHICH CAN BE USEPACKAGE'd LATER)
% ESSENTIALLY YOU JUST NEED TO TAKE A LOOK WHETHER \uppercase{\next} IS THE SAME AS \next. Use scalebox on the uppercase'd letter if not.
\makeatletter
\newcommand{\fsc}[1]{%
    \@tfor\next:=#1\do{%
        \edef\temp@up{\uppercase{\next}}%
        \ifdefstrequal{\temp@up}{\next}{\next}{\scalebox{.87}[.79]{\uppercase{\next}}}%
    }%
}
\makeatother

\begin{document}
The \fsc{Schr{ö}dinger} equation is \dots
\end{document}

这将生成文本“Schrödinger”,其中每个字母的大小写均采用 \fsc 命令中指定的大小写,并使用 \scalebox 缩放。预期结果是,如果字符等于其大写形式(即表示大写字母),则比较结果为真,否则为假,因此将生成大写的未缩放字母 S 和大写的缩放字母 CHRÖDINGER。

我想我的问题与 TeX 评估命令的顺序有关,但由于我对 LaTeX 宏编程还很陌生,所以我不知道如何解决这个问题。

同样好的是,有一种对命令进行编码的方法,可以避免在括号中写入多字节字符。

答案1

效率极低,无法真正替代真正的小型大写字母(我的建议是无论如何都不要伪造小型大写字母)。涵盖了所有常见的重音符号,其他重音符号可以添加。

\documentclass{scrartcl}

% GENERAL STUFF - ENCODING, LANGUAGE
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}

% GENERAL STUFF - FONT
\usepackage{arev}

% GENERAL STUFF - GRAPHICS
\usepackage{graphicx}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\fsc}{m}
 {
  \toshiki_fsc:n { #1 }
 }

\tl_new:N \l_toshiki_input_tl

\cs_set_eq:Nc \toshiki_tl_set_protecteded_x:Nn { protected@edef }

\cs_new_protected:Nn \toshiki_fsc:n
 {
  \toshiki_tl_set_protecteded_x:Nn \l_toshiki_input_tl { #1 }
  \regex_replace_all:nnN { ([a-z]+) } { \c{toshiki_fake_sc:n}\cB\{\1\cE\} } \l_toshiki_input_tl
  \regex_replace_all:nnN { (\c{[r"'`^]})\c{toshiki_fake_sc:n}\cB. }
                         { \c{toshiki_fake_sc:n}\cB\{\1 } \l_toshiki_input_tl
  \regex_replace_all:nnN { (\c{ae|oe|ss}) } { \c{toshiki_fake_sc:n}\cB\{\1\cE\} } \l_toshiki_input_tl
  \tl_use:N \l_toshiki_input_tl
 }

\cs_new_protected:Nn \toshiki_fake_sc:n
 {
  \scalebox{.87}[.79]{ \MakeUppercase{#1} }
 }
\ExplSyntaxOff

\begin{document}

The \fsc{Schr{ö}dinger} equation is \dots

\fsc{Hôpital} \fsc{Ångström} \fsc{ångström} \fsc{ŒœÆæß}

\fsc{Some Wörds To Be In Småll Cáps}

\end{document}

在此处输入图片描述

答案2

如果您只需要将这种“假小型大写字母”用于名称和单个单词(请注意,空格在您的解决方案中不起作用),那么您可以准备一个简单的宏\fcs,保持首字母不变,其余字母大写并缩放。

\def\fsc#1{\fscA#1\relax}
\def\fscA#1#2\relax{#1\scalebox{.87}[.79]{\uppercase{#2}}}

test: \fsc{Schrödinger} equation.

如果首字母带重音,那么您必须将其括在括号中,因为 LaTeX 无法正确处理 UTF-8 代码(如果您使用 csplain,则不会出现此问题)。

答案3

近似值。如果 unicode 字符不是小写字母,则无法正常工作。可能有一个解决方案,\str_case:nnF但你应该手动执行,或者直接使用 LuaTeX(或 XeTeX)。

\documentclass{scrartcl}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}

\usepackage{arev}

\usepackage{xparse} % loads expl3
\usepackage{etoolbox}
\usepackage{graphicx}
\usepackage{textcase} % to get \MakeTextUppercase

\ExplSyntaxOn
\NewDocumentCommand \fsc { m } { \toshiki_fsc:n { #1 } }
\cs_new_protected:Npn \toshiki_fsc:n #1
 {
  \tl_map_inline:nn { #1 }
   {
    \str_if_eq:eeTF { ##1 } { \text_uppercase:n { ##1 } }
     { ##1 }
     { \scalebox{.87}[.79]{ \toshiki_fsc_aux:n { ##1 } } }
   }
 }
\cs_new_protected:Npn \toshiki_fsc_aux:n #1 { \MakeTextUppercase { #1 } }
\ExplSyntaxOff

\begin{document}
The \fsc{Schr{ö}dinger} equation is\dots\ \fsc{Schr{Ö}dinger} doesn't work, though\dots
\end{document}

但如果你重新\toshiki_fsc_aux:n定义

\cs_new_protected:Npn \toshiki_fsc_aux:n #1
 {
  \str_case:nnTF { #1 }
   {
    {Ö}{}
    {Á}{}
    % etc.
   }
   { #1 }
   { \scalebox{.87}[.79]{ \MakeTextUppercase { #1 } } }
 }
\cs_new_protected:Npn \toshiki_fsc_aux:n #1
 {
  \tl_if_in:nnTF { ÖÁ } { #1 }
   { #1 }
   { \scalebox{.87}[.79]{ \MakeTextUppercase { #1 } } }
 }

那么它确实有效,但是您必须手动添加字符。

顺便说一句,这是一个混乱的解决方案,到处都有补丁……

答案4

我建议使用另一种解决方案来解决使用 UTF-8 编码时处理宏参数“每个字符一个字符”的问题\usepackage{inputenc}。您可以将我的解决方案与此处介绍的其他解决方案的简单性进行比较。

假设您已设置\usepackage[T1]{fontenc}\usepackage[utf8]{inputenc}。那么 UTF-8 代码将根据 T1 编码扩展为简单标记,并且\lccode也将设置为 T1 编码。然后您可以执行以下操作:

\def\fsc#1{\edef\tmp{#1}\expandafter\fscA\tmp\relax}
\def\fscA#1{%
   \ifx#1\relax \else
      \ifnum\lccode`#1=`#1 (small:\char\uccode`#1)\else (cap:#1)\fi
      \expandafter\fscA
\fi
}

A test: \fsc{Schrödinger} equation.

相关内容