
根據這個問題的精彩答案可以檢查小型大寫字母是否可用。然而,嘗試實際使用這段程式碼時,我得到了一個奇怪的結果:當字體形狀為不明確的替換工作按預期進行。當字體形狀為無法使用測試表明字體形狀可用,但 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}
編輯:我發現了一些有用的東西來源2e文檔。第166頁上方寫著:
如果 \curr@fontshape 組合不可用(即未定義),我們呼叫巨集 \wrong@fontshape 來處理這種情況。否則 \extract@font 將為我們載入外部字體。
341 % \expandafter\ifx
342%\csname\curr@fontshape\endcsname\relax
第343章
344%\fi
第345章
[第 346 章]
第347章
為了允許替換,我們調用 curr@fontshape 宏,它通常會擴展為 \relax 但可能保存替換代碼(請參閱 \subst@fontshape 定義)。
348% \csname\curr@fontshape\endcsname
第349章
我們即將完成,只需透過關閉該群組來恢復 \escapechar。
第350章
....所以神奇的詞是不明確的,意味著字體形狀的解決方案是無法使用(根據 LaTeX 警告,仍然需要)。
編輯2:
據我了解,\testsc
測試替換(這會導致警告“字體形狀T1/lmr/bx/sc
未定義(字體)使用T1/lmr/bx/n
代替「如果\textsc
使用)。然後,它測試字體形狀是否存在。由於某些原因,此測試是肯定的T1/lmss/m/sc
,但\textsc
它給出警告「大小 <10.95> 的字體形狀T1/lmss/m/sc
無法使用(字體)T1/lmr/m/sc
嘗試使用字體形狀代替」。這種情況需要額外測試嗎? 與第一個警告相反,我無法找出這個警告是如何產生的。我在第 64 頁找到了此警告的定義字型安裝指南。看起來家庭在測試完成之前就已經改變了,僅在這種情況下。
編輯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
並如預期使用:
這是一項艱鉅的工作,但我很高興我終於弄清楚了。如果有更乾淨的解決方案,我很樂意了解。
免責聲明:
只有當您可以接受該解決方案時,您才自行負責使用此解決方案可怕結果。