未定義或不可用時替換小型大寫字母

未定義或不可用時替換小型大寫字母

根據這個問題的精彩答案可以檢查小型大寫字母是否可用。然而,嘗試實際使用這段程式碼時,我得到了一個奇怪的結果:當字體形狀為不明確的替換工作按預期進行。當字體形狀為無法使用測試表明字體形狀可用,但 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並如預期使用:

成功更換

這是一項艱鉅的工作,但我很高興我終於弄清楚了。如果有更乾淨的解決方案,我很樂意了解。

免責聲明:

只有當您可以接受該解決方案時,您才自行負責使用此解決方案可怕結果。

相關內容