梅威瑟:

梅威瑟:

梅威瑟:

\documentclass[a4paper,12pt,twoside]{memoir}
\usepackage{DejaVuSerifCondensed}
\usepackage[T1]{fontenc}
\begin{document}
\noindent\scshape{Hello World}\\
\textsc{Hello World}
\end{document}

解释和问题:

如您所见,我正在处理一个memoir文档类,并加载了一个字体,我试图为我的标题获取小写字母(我没有将其放置在 MWE 中,因为没有必要)。但是我无法使用命令或DejaVuSerifCondensed获得所需的效果。\scshape\textsc{}

我还看到过其他问题,例如

但是它们要么不能适应我的问题(就我所见而言),要么不能解决问题(按照那里的说明并在我的代码中“插入”一段代码)。

这里的问题是:是否有一个通用的方法(一段代码或其他东西)可以从自定义字体中获取小写字母(即使我用 ttf 上传)?如果没有,那么选择标准小型大写字体?

答案1

为了通过标准命令从字体中获取小型大写字母,例如\textsc,您加载的字体需要小型大写字母。您选择的字体,DejaVu Serif 压缩版,不会。当你编译 MWE 时,你会收到来自 LaTeX 的字体警告,提示此字体不存在小写字母,因此将使用普通字体:

LaTeX Font Warning: Font shape `T1/DejaVuSerifCondensed-TLF/m/sc' undefined
(Font)              using `T1/DejaVuSerifCondensed-TLF/m/n' instead

因此,除了通过调整全大写字母的字形来伪造小写字母外,您无法从字体中获得小写字母。但除非您出于某种原因而不得不使用 DejaVu Serif Condensed(我不明白为什么您会这样做),否则如果您想要好看的小写字母,您应该做的是切换到具有小写字母的字体。您可以浏览LaTeX 字体目录它将告诉您该字体是否有小型大写字母。

如果你需要坚持使用 DejaVu Serif,那么只有当你需要小写字母时,你才可以切换到另一种字体。如何做到这一点之前问过并回答过。我只是从下面复制了代码。

\documentclass{memoir}
\usepackage{DejaVuSerifCondensed}
\usepackage[T1]{fontenc}
\usepackage{pdftexcmds}
\makeatletter
\let\scshape\relax % to avoid a warning
\DeclareRobustCommand\scshape{%
  \not@math@alphabet\scshape\relax
  \ifnum\pdf@strcmp{\f@family}{\familydefault}=\z@
    \fontfamily{lmr}%
  \fi
  \fontshape\scdefault\selectfont}
\makeatother
\begin{document}
This text should be in DejaVuSerif\par
\textsc{While this should be in Latin Modern}
\end{document}

在此处输入图片描述

查看 egreg 的回答欲了解更多详情,请访问 Alan Munn 的回答了解如何查找字体系列名称。您需要自己决定哪种小写字体与 DejaVu Serif 搭配良好(在我的示例中,我不推荐 Latin Modern)。浏览字体目录。

答案2

一个解决方案是创建假小写字母。下面的 MWE 定义了一个命令\fakesc,将文本大写并缩小以类似于小写字母。

\documentclass[a4paper,12pt,twoside]{memoir}
\usepackage{DejaVuSerifCondensed}
\usepackage[T1]{fontenc}

\newcommand\fakesc[1]{\uppercase{{\scriptsize #1}}}

\begin{document}
The sign on the door said \fakesc{keep out}, so we left.
\end{document}

输出: 在此处输入图片描述

这是第二个更复杂的解决方案,它仅将伪小型大写字母效果应用于输入字符串中的小写字母。这允许输入字符串混合大写字母和小写字母,并且只有小写字母会转换为伪小型大写字母。请参阅下面的 MWE。

\documentclass[a4paper,12pt,twoside]{memoir}
\usepackage{DejaVuSerifCondensed}
\usepackage[T1]{fontenc}

\usepackage{xstring} % needed for IfEqCase
\usepackage{forloop}

\newcounter{sccounter}
\newcounter{tempStringLength}

\newcommand{\betterfakesc}[1]{%
    % this \betterfakesc command requires these two packages:
    %   xstring
    %   forloop
    %
    % First, we obtain the length of the input string.
    \StrLen{#1}[\stringLength]%
    %
    % Our main forloop will be using a condition of “while less than \stringLength”,
    % so we’ll need to increase \stringLength by 1 so the forloop will be able to iterate 
    % over the entire string. we’ll use a temporary counter tempStringLength to make
    % this increase. That’s what the next three lines are about.
    \setcounter{tempStringLength}{\stringLength}%
    \addtocounter{tempStringLength}{1}%
    \def\stringLength{\arabic{tempStringLength}}%
    %
    % Here is our main loop. We iterate over the characters in the input string,
    % and the currentLetter is compared to the case rules we have defined. Basically
    % if the currentLetter is any of the lowercase a-z letters, then we apply a 
    % “fake small caps” effect to it and output it.
    \forloop[1]{sccounter}{1}{\value{sccounter}<\stringLength}{%
        \StrChar{#1}{\value{sccounter}}[\currentLetter]%
        %
        \IfEqCase*{\currentLetter}{%
        % The lines below are the rules. Obviously more could be added.
        {a}{{\uppercase{\scriptsize a}}}%
        {b}{{\uppercase{\scriptsize b}}}%
        {c}{{\uppercase{\scriptsize c}}}%
        {d}{{\uppercase{\scriptsize d}}}%
        {e}{{\uppercase{\scriptsize e}}}%
        {f}{{\uppercase{\scriptsize f}}}%
        {g}{{\uppercase{\scriptsize g}}}%
        {h}{{\uppercase{\scriptsize h}}}%
        {i}{{\uppercase{\scriptsize i}}}%
        {j}{{\uppercase{\scriptsize j}}}%
        {k}{{\uppercase{\scriptsize k}}}%
        {l}{{\uppercase{\scriptsize l}}}%
        {m}{{\uppercase{\scriptsize m}}}%
        {n}{{\uppercase{\scriptsize n}}}%
        {o}{{\uppercase{\scriptsize o}}}%
        {p}{{\uppercase{\scriptsize p}}}%
        {q}{{\uppercase{\scriptsize q}}}%
        {r}{{\uppercase{\scriptsize r}}}%
        {s}{{\uppercase{\scriptsize s}}}%
        {t}{{\uppercase{\scriptsize t}}}%
        {u}{{\uppercase{\scriptsize u}}}%
        {v}{{\uppercase{\scriptsize v}}}%
        {w}{{\uppercase{\scriptsize w}}}%
        {x}{{\uppercase{\scriptsize x}}}%
        {y}{{\uppercase{\scriptsize y}}}%
        {z}{{\uppercase{\scriptsize z}}}%
        }%
        % if our \currentLetter isn’t any of the letters we have rules for,
        % then just output it now
        [{\currentLetter}]%
    }%
}

\begin{document}
The sign on the door said \betterfakesc{Keep Out}, so we left.
\end{document}

输出:

在此处输入图片描述

请注意,可以轻松地将附加规则添加到 IfEqCase 结构中以处理标点符号等。(另请注意,此命令甚至可以重新用于其他类型的文本或格式转换。)

请注意,字体设计纯粹主义者会抱怨通过减小字体大小来伪造小写字母会产生比真正的小写字母笔画粗细更细的字母形式,他们的说法是正确的。伪造小写字母的主要优点是它们适用于任何字体,并且是一种易于实施的解决方案。

答案3

代码:

好吧,我搜索了很多脚本来识别大写字母和小写字母,但没有成功(如何在宏中检查选定的字母是大写还是小写?)但后来我发现了一种更优雅的方法来制作假小写字母(和假中写字母)。在 XeLaTeX 中伪造小写字母

\documentclass[a4paper,12pt,twoside]{memoir}
\usepackage{DejaVuSerifCondensed}
\usepackage[T1]{fontenc}
\usepackage{fontspec}

\ExplSyntaxOn
\NewDocumentCommand{\fakesc}{ o m }
 {
  \guido_fakesc:n { #2 }
  \IfNoValueTF{#1}
   {
    \tl_use:N \l__guido_temp_tl
   }
   {
    \cs_set_eq:NN #1 \l__guido_temp_tl
   }
 }
\cs_new_protected:Npn \guido_fakesc:n #1
 {
  \tl_set:Nn \l__guido_text_tl { #1 }
  \tl_replace_all:Nnn \l__guido_text_tl { ~ } { \q_space }
  \tl_set:Nn \l__guido_temp_tl { \group_begin: \footnotesize }
  \tl_map_inline:Nn \l__guido_text_tl
   {
    \token_if_eq_meaning:NNTF ##1 \q_space
     {
      \tl_put_right:Nn \l__guido_temp_tl { ~ }
     }
     {
      \int_compare:nTF { \char_value_uccode:n { `##1 } = `##1 }
       {
        \tl_put_right:Nn \l__guido_temp_tl { {\normalsize ##1} }
       }
       {
        \tl_put_right:Nn \l__guido_temp_tl { \tl_to_uppercase:n { ##1 } }
       }
     }
   }
  \tl_put_right:Nn \l__guido_temp_tl { \group_end: }
 }
\quark_new:N \q_space
\tl_new:N \l__guido_text_tl
\tl_new:N \l__guido_temp_tl
\ExplSyntaxOff

\begin{document}
\noindent\scshape{Hello World}\\
\textsc{Hello World}\\
\fakesc{Hello World}%---mid caps---
\end{document}

说实话,我不知道它是如何工作的,我只知道它可以工作并使用命令生成小写字母(使用自定义字体),\textsc\scshape使用命令生成中写字母\fakesc。重要的是它与调用的参数(如章节和部分)一起使用,在我的例子中,我调用章节编号和名称,此代码将使小写字母显示为小写字母,大写字母显示为普通大写字母。

输出:

在此处输入图片描述

答案4

这是我在 stackexchange 上找到的唯一一篇关于如何创建假小写字母的讨论帖子,所以我想我可以附和一下我发现的另一种方法在 latex.org 论坛上。我在这里重新转录,以防将来链接失效,并进行微小修改以提高可读性。

\def\fakesc{\bgroup\obeyspaces\helpersc}
\def\helpersc#1{\helperscii #1\relax\relax\egroup}
\def\helperscii#1{%
\ifx\relax#1\else \ifcat#1\@sptoken{} \expandafter\expandafter\expandafter\helperscii\else
\ifnum`#1=\uccode`#1 {\normalsize #1}\else {\footnotesize \uppercase{#1}}\fi \expandafter\expandafter\expandafter\helperscii\expandafter\fi\fi}

\fakesc{Any Text that needs Small Caps}

该代码显然最初来自法国编程支持论坛零点网站最终发展成为 OpenClassrooms,现在主要提供实际课程。虽然没有被搜索引擎索引,但其中一些旧论坛内容可用——但我找不到此代码来自的具体帖子。

相关内容