根据这个问题的精彩答案可以检查小写字母是否可用。但是,尝试实际使用此代码时,我得到了一个奇怪的结果:当字体形状不明确的替换按预期进行。当字体形状为无法使用测试表明字体形状可用,但 Latex 却使用替代品。
有没有办法使用\fakedsc
罗马版本而不是普通的无衬线小型大写字母?
在下面的代码中,你可以看到当使用T1/lmr/bx/sc
和时,小写字母会被替换(两者都是T1/lmss/bx/sc
不明确的)但不是什么时候T1/lmss/m/sc
使用(无法使用):
\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage{relsize}
\usepackage{etoolbox}
\newcommand{\fakedsc}[3][1]{#2\begingroup\smaller[#1]{\MakeUppercase{#3}}\endgroup}
\makeatletter
\def\define@newfont{%
\begingroup
\let\typeout\@font@info
\escapechar\m@ne
\expandafter\expandafter\expandafter
\split@name\expandafter\string\font@name\@nil
\try@load@fontshape % try always
\expandafter\ifx
\csname\curr@fontshape\endcsname \relax
\expandafter\gdef\csname \curr@fontshape/sub\endcsname{}% new
\wrong@fontshape\else
\extract@font\fi
\endgroup}
\newcommand\testsc[3][1]{%
\ifcsname \f@encoding/\f@family/\f@series/sc/sub\endcsname
no \fakedsc[#1]{#2}{#3}
\else
\ifcsname \f@encoding/\f@family/\f@series/sc\endcsname yes \textsc{#2#3} \else no \fakedsc[#1]{#2}{#3} \fi
\fi
}
\makeatother
\begin{document}
\detokenize{\rmfamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est} => test successful, no replacement
{\bfseries
\detokenize{\rmfamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est}} => test successful, replaced
\sffamily
\detokenize{\sffamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est} => test \textbf{not successful}, auto replacement
{\bfseries
\detokenize{\sffamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est}} => test successful, replaced
\end{document}
编辑:我发现了一些有用的东西source2e 文档。第 166 页顶部写道:
如果 \curr@fontshape 组合不可用(即未定义),我们将调用宏 \wrong@fontshape 来处理这种情况。否则 \extract@font 将为我们加载外部字体。
341 % \expandafter\ifx
342 % \csname\curr@fontshape\endcsname \relax
343 \try@load@fontshape % 总是尝试
344 % \fi
345 \expandafter\ifx
346 \csname\curr@fontshape\endcsname \relax
347 \错误@fontshape\else
为了允许替换,我们调用 curr@fontshape 宏,它通常会扩展为 \relax 但可能包含替换代码(参见 \subst@fontshape 定义)。
348 % \csname\curr@fontshape\endcsname
349 \提取@字体\fi
我们几乎已经完成,只需关闭该组即可恢复 \escapechar。
350
...所以魔法词是不明确的,这意味着字体形状的解决方案无法使用(根据 LaTeX 警告仍然需要)。
编辑2:
据我所理解,\testsc
测试替换(这会导致警告“字体形状T1/lmr/bx/sc
未定义(字体)使用T1/lmr/bx/n
改用“如果\textsc
使用)。然后,它测试字体形状是否存在。出于某些原因,这个测试对于T1/lmss/m/sc
虽然是肯定的,但对于\textsc
它还是给出了警告“字体T1/lmss/m/sc
大小 <10.95> 不可用(字体) 字体形状T1/lmr/m/sc
已尝试使用字体形状“。这个案例是否需要额外测试? 与第一个警告相反,我无法找出这个警告是如何产生的。我在字体安装指南看起来,在测试完成之前,该系列已经发生了变化,仅在这种情况下。
编辑3:
我仔细观察了“无法使用“警告。原来这是由t1lmss.fd(位于 MiKTeX 2.9/tex/latex/lm)。除了其他替换之外,它还声明:
\DeclareFontShape{T1}{lmss}{m}{sc}
{<->sub*lmr/m/sc}{}
通过在序言中添加以下代码,我能够将替换更改为无衬线字体的正常形状。
\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{lmodern} \sffamily\selectfont
\usepackage[T1]{fontenc}
\usepackage{relsize}
\usepackage{etoolbox}
\DeclareFontShape{T1}{lmss}{m}{sc}
{<->sub*lmss/m/n}{}
\normalfont
...
是否有可能对这种替代进行测试,或者“取消声明”它无需处理 .fd 文件?
免责声明: 我知道伪造小型大写字母会出现问题,但使用不同的字体对我来说并不是解决办法。
答案1
最后一步编辑3其实很简单:从t1lmss.fd并删除 tex 文件本身中不需要的代码。因此,字体形状的声明被覆盖,同时保持原始 fd 文件完好无损。完整的 tex 文件如下所示:
\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{lmodern} %\sffamily\selectfont % (not needed if the whole fd file is inserted, which uses \DeclareFontFamily{T1}{lmss}{})
\usepackage[T1]{fontenc}
\usepackage{relsize}
\usepackage{etoolbox}
%%% taken from the .fd file (MiKTeX 2.9\tex\latex\lm\t1lmss.fd) -- this overrides the definitions in the fd file while leaving the original file untouched
\DeclareFontFamily{T1}{lmss}{}
\DeclareFontShape{T1}{lmss}{m}{n}
{<-8.5> ec-lmss8
<8.5-9.5> ec-lmss9 <9.5-11> ec-lmss10
<11-15.5> ec-lmss12 <15.5-> ec-lmss17
}{}
\DeclareFontShape{T1}{lmss}{m}{it}
{<->ssub*lmss/m/sl}{}
\DeclareFontShape{T1}{lmss}{m}{sl}
{<-8.5> ec-lmsso8
<8.5-9.5> ec-lmsso9 <9.5-11> ec-lmsso10
<11-15.5> ec-lmsso12 <15.5-> ec-lmsso17
}{}
%%%%%%% Font/shape undefined, therefore substituted
%\DeclareFontShape{T1}{lmss}{m}{sc} % <-- deleted
%{<->sub*lmr/m/sc}{} % <-- deleted
\DeclareFontShape{T1}{lmss}{b}{n}
{<->ssub * lmss/bx/n}{}
\DeclareFontShape{T1}{lmss}{b}{sl}
{<->ssub * lmss/bx/sl}{}
\DeclareFontShape{T1}{lmss}{b}{it}
{<->ssub * lmss/bx/it}{}
%%%%%%%% semibold condensed series
\DeclareFontShape{T1}{lmss}{sbc}{n}
{<-> ec-lmssdc10}{}
\DeclareFontShape{T1}{lmss}{sbc}{sl}
{<-> ec-lmssdo10}{}
\DeclareFontShape{T1}{lmss}{sbc}{it}
{<->ssub*lmss/sbc/sl}{}
%%%%%%%%% bold extended series
\DeclareFontShape{T1}{lmss}{bx}{n}
{<-> ec-lmssbx10}{}
\DeclareFontShape{T1}{lmss}{bx}{sl}
{<-> ec-lmssbo10}{}
\DeclareFontShape{T1}{lmss}{bx}{it}
{<->ssub*lmss/bx/sl}{}
%%% end of fd file
\normalfont
\newcommand{\fakedsc}[3][1]{#2\begingroup\smaller[#1]{\MakeUppercase{#3}}\endgroup}
\makeatletter
\def\define@newfont{%
\begingroup
\let\typeout\@font@info
\escapechar\m@ne
\expandafter\expandafter\expandafter
\split@name\expandafter\string\font@name\@nil
\try@load@fontshape % try always
\expandafter\ifx
\csname\curr@fontshape\endcsname \relax
\expandafter\gdef\csname \curr@fontshape/sub\endcsname{}% new
\wrong@fontshape\else
\extract@font\fi
\endgroup}
\newcommand\testsc[3][1]{%
\ifcsname \f@encoding/\f@family/\f@series/sc/sub\endcsname
no \fakedsc[#1]{#2}{#3}
\else
\ifcsname \f@encoding/\f@family/\f@series/sc\endcsname yes \textsc{#2#3} \else no \fakedsc[#1]{#2}{#3} \fi
\fi
}
\makeatother
\begin{document}
\detokenize{\rmfamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est} => test successful, no replacement
{\bfseries
\detokenize{\rmfamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est}} => test successful, replaced
\sffamily
\detokenize{\sffamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est} => test finally successful, \detokenize{\fakedsc} used!!!
{\bfseries
\detokenize{\sffamily} \textsc{Test} -- \testsc{T}{ested} -- without \fakedsc{T}{est}} => test successful, replaced
\end{document}
正如你所看到的,\sffamily \textsc{Test}
现在给出了一个警告,字体形状未定义:
但是,如果\textsc{Test}
删除所有部分,则不会显示任何警告。如果需要的话,也许甚至可以警告使用了伪造的小写字母(对我来说,不需要)。
甚至更好:\sffamily \testsc{Tested}
没有给予不作为答案(意味着字体形状是没有定义的)\fakedsc
并按预期用途:
这是一项艰苦的工作,但我很高兴我终于找到了答案。如果有更简洁的解决方案,我很乐意了解它。
免责声明:
使用此解决方案需要您自行负责,并且只有您能够接受可怕结果。