Substituição de versalete quando indefinido ou não disponível

Substituição de versalete quando indefinido ou não disponível

De acordo coma resposta brilhante para esta perguntaé possível verificar se versaletes estão disponíveis ou não. No entanto, tentando realmente usar esse código, obtenho um resultado estranho: quando o formato da fonte éindefinidoa substituição funciona conforme o esperado. Quando o formato da fonte énão disponívelo teste diz que o formato da fonte está disponível, mas o Latex usa um substituto.

Existe uma maneira de usar \fakedscem vez da versão romana para as letras maiúsculas normais sem serifa?

No código a seguir você pode ver que versaletes são substituídos quando T1/lmr/bx/sce T1/lmss/bx/scsão usados ​​(ambosindefinido) mas não quando T1/lmss/m/scé usado (não disponível):

\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}

Os resultados são mostrados aqui: Substituições

EDITAR:Encontrei algo útil nodocumentação source2e. No topo da página 166 diz:

Se a combinação \curr@fontshape não estiver disponível (ou seja, indefinida) chamamos a macro \wrong@fontshape para cuidar deste caso. Caso contrário, \extract@font carregará a fonte externa para nós.

341% \expandafter\ifx

342%\csname\curr@fontshape\endcsname\relax

343 \try@load@fontshape % tente sempre

344% \fi

345 \expandafter\ifx

346 \csname\curr@fontshape\endcsname \relax

347 \wrong@fontshape\else

Para permitir a substituição chamamos a macro curr@fontshape que normalmente se expandirá para \relax mas pode conter código para substituição (veja a definição de \subst@fontshape).

348% \csname\curr@fontshape\endcsname

349 \extract@fonte\fi

Estamos quase terminando e só precisamos restaurar o \escapechar fechando o grupo.

350\endgroup}

... então a palavra mágica éindefinido, significando uma solução para um formato de fonte que énão disponível(de acordo com os avisos do LaTeX ainda é necessário).

EDITAR2:

Pelo que entendi, \testscos testes para uma substituição (o que leva ao aviso "Formato da fonte T1/lmr/bx/scindefinido (Fonte) usando T1/lmr/bx/nem vez disso" if \textscé usado). Em seguida, testa se o formato da fonte existe. Por alguns motivos, este teste é positivo para T1/lmss/m/scembora, com \textscele dá o aviso "Formato da fonte T1/lmss/m/scem tamanho <10,95> não disponível (Fonte) T1/lmr/m/scFoi tentado o formato da fonte".É necessário um teste extra para este caso? Ao contrário do primeiro aviso, não consegui descobrir como este aviso é produzido. Encontrei uma definição deste aviso na página 64 doguia de instalação de fontes. Parece que a família mudou antes da realização do teste, apenas neste caso.

EDITAR3:

Eu dei uma olhada mais de perto no "não disponível" aviso. Acontece que isso é produzido port1lmss.fd(localizado em MiKTeX 2.9/tex/latex/lm). Além de outras substituições, declara:

\DeclareFontShape{T1}{lmss}{m}{sc}
{<->sub*lmr/m/sc}{}

Ao adicionar o código a seguir ao preâmbulo, consegui alterar a substituição para o formato normal da fonte sem serifa.

\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
...

Esta é a nova saída: Novas substituições

É possível fazer um teste para esse tipo de substituição também, ou “desdeclará-la”sem mexer no arquivo .fd?

Isenção de responsabilidade: Estou ciente dos problemas que surgem ao falsificar versaletes, mas usar uma fonte diferente não é solução para mim.

Responder1

O último passo depoisEDITAR3foi bem simples: copie e cole o código dot1lmss.fde exclua o código indesejado no próprio arquivo tex. Assim, a declaração do formato da fonte é substituída, deixando o arquivo fd original intacto. O arquivo tex completo é o seguinte:

\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}

Como você pode ver, \sffamily \textsc{Test}agora avisa que o formato da fonte estáindefinido:

Avisos indefinidos

No entanto, se todas \textsc{Test}as partes forem excluídas, nenhum aviso será mostrado. Talvez se possa até alertar que se usam versaletes falsificadas, se assim for desejado (para mim não é).

Melhor ainda: \sffamily \testsc{Tested}não dánãocomo resposta (o que significa que o formato da fonte énão definido) e usa \fakedscconforme pretendido:

Substituições bem-sucedidas

Foi um trabalho árduo, mas estou feliz por finalmente ter descoberto. Se houver uma solução mais limpa, ficarei feliz em saber mais sobre ela.

Isenção de responsabilidade:

Use esta solução sob sua própria responsabilidade e somente se você puder conviver com ohorrívelresultados.

informação relacionada