新增:运行时检查是否存在 TFM 文件

新增:运行时检查是否存在 TFM 文件

我已经安装了非标准字体(ISOCPEUR.TTF),它对 \showfont 命令的响应如下:

\newcommand{\showfont}{encoding: \f@encoding{},
                       family:   \f@family{},
                       series:   \f@series{},
                       shape:    \f@shape{},
                       size:     \f@size{}
                      }

在此处输入图片描述

该命令\newcommand{\iso}{\fontfamily{iso}\selectfont}设置“iso”字体,但如果没有安装,请切换到computern现代。

我想创建一个设置“iso”字体的命令,但如果没有安装这种字体,该命令必须设置 \sffamily 字体。我试过了,但没有成功

\newcommand\f@family@iso{iso}
\newcommand{\iso}{\fontfamily{iso}\selectfont%
  \ifx\f@family\f@family@iso%
    %it's ok, do nothing
  \else
    \sffamily\slshape\selectfont
  \fi
}

无论如何,\sffamily即使安装了“iso”字体,也应设置这样的代码字体。

答案1

再想想,也许你只是在寻找一个如下所示的简单解决方案:

\documentclass[a4paper]{article}                            
\usepackage[T2A,T1]{fontenc}
\usepackage{lipsum} % just to get the "Lorem ipsum..." text

\IfFileExists{t2aiso.fd}{
    \newcommand*{\iso}{\fontencoding{T2A}\fontfamily{iso}\selectfont}
}{
    \newcommand*{\iso}{\sffamily\slshape} % no "\selectfont" needed here
}

% The same thing for a font that should exist on all systems:
\IfFileExists{t1cmdh.fd}{
    \newcommand*{\dunhill}{\fontencoding{T1}\fontfamily{cmdh}\selectfont}
}{
    \newcommand*{\dunhill}{\sffamily\slshape}
}



\begin{document}

\begingroup
    \iso
    \lipsum[1]
\endgroup

\begingroup
    \dunhill
    \lipsum[2]
\endgroup

Back to default font.

\end{document}

新增:运行时检查是否存在 TFM 文件

我添加了我最初为这个问题设计的答案,因为我认为它毕竟说明了一种有趣的技术。此解决方案不依赖于.fd 描述如何实现给定字体系列的文件的存在(原则上,这对于使用字体来说不是强制性的),而是直接检查外部字体是否存在,或者更确切地说,检查其 TFM(TeX Font Metric)文件是否存在。

以下源文件应使用--restricted-shell-escape命令行选项进行编译。除其他功能外,它还实现了一个带有三个强制参数的命令,名为\IfTFMFileExists,该命令查询(通过管道输入功能)系统中是否存在 TFM 文件,该文件的基本名称在第一个参数中传递,如果找到该文件,则执行第二个参数中包含的代码,如果找不到该文件,则执行第三个参数中包含的代码。随后,此命令用于在两个\DeclareFontShape声明之间进行选择,一个声明将给定的字体形状绑定到其预期的外部字体(如果后者存在于系统中),另一个声明用另一种字体形状替换它。

请注意,第一次编译此代码时,它可能会调用mktextfm构建lasi1000.tfmTFM 文件,该文件对于用作该iso系列替代的字体(即 T2A 编码中的 Computer Modern Sans)是必需的,并且默认情况下未在标准 TeXLive 发行版中安装。

\documentclass[a4paper]{article}                            
\usepackage[T2A,T1]{fontenc}
\usepackage{lipsum} % just to get the "Lorem ipsum..." text

\makeatletter

% Mere diagnostic command:
\newcommand*\showfont{%
    \begingroup
        \def~{ }%
        \typeout{+-----> On input line \number\inputlineno:}%
        \typeout{|~~~Encoding:~~~\f@encoding,}%
        \typeout{|~~~family:~~~~~\f@family,}%
        \typeout{|~~~series:~~~~~\f@series,}%
        \typeout{|~~~shape:~~~~~~\f@shape,}%
        \typeout{|~~~size:~~~~~~~\f@size;}%
        \typeout{|~~~>>> external (TFM file) name: \fontname\font.}%
        \typeout{+-----------------------}%
    \endgroup
}

\newcommand*\IfTFMFileExists[1]{%
    % Actual usage:
    % \IfTFMFileExists{<ext. font name>}{<found code>}{<not found code>}
    \begingroup
        \openin\@inputcheck=|"kpsewhich #1.tfm"\relax % Why "\relax"?
                                                      % (Exercise... ;-)
        \ifeof\@inputcheck
            \aftergroup\@secondoftwo % kpsewhich couldn't be called
        \else
            \endlinechar \m@ne
            \readline\@inputcheck to \@tempa
            \ifx\@tempa\@empty
                \aftergroup\@secondoftwo % kpsewhich returned nothing
            \else
                \aftergroup\@firstoftwo % kpsewhich returned something
            \fi
        \fi
        \closein\@inputcheck
    \endgroup
}

\makeatother

%------ Declarations for the ISOCPEUR family follow: -----------
%
% On the generic user's system, we expect NOT to find the external font.
\DeclareFontFamily{T2A}{iso}{}
% I'm pretending that the external (TFM file) name of the relevant font is
% "fiemo6a", and that it is a fully scalable font; but please keep in mind
% that I have no idea of what is the correct binding between the NFSS font
% shapes and the external fonts for this ISOCPEUR family!
\IfTFMFileExists{fiemo6a}{
    \typeout{==> fiemo6a found!}
    % BEWARE OF SPACES in the arguments of "\DeclareFontShape":
    % they get prematurely tokenized here!
    \DeclareFontShape{T2A}{iso}{m}{n}{<->fiemo6a}{}
}{
    \typeout{==> fiemo6a NOT found!}
    % As above.
    \DeclareFontShape{T2A}{iso}{m}{n}{<->sub*cmss/m/sl}{}
}
%
%------ End of declarations for the ISOCPEUR family. -----------

%------ Declarations for the CM dunhill family follow: ---------
%
% This serves as a benchmark, to check that an external font that should be
% present on all system is actually recognized.
\DeclareFontFamily{T1}{cmdh}{}
% Assume that if "ecdh1000.tfm" is present on the system, the other sizes
% are there as well:
\IfTFMFileExists{ecdh1000}{
    \typeout{==> ecdh1000 found!}
    % As above.
    \DeclareFontShape{T1}{cmdh}{m}{n}%
        {<5><6><7><8><9><10><10.95><12><14.4>%
            <17.28><20.74><24.88><29.86><35.83>genb*ecdh}{}%
}{
    \typeout{==> ecdh1000 NOT found!}
    % As above.
    \DeclareFontShape{T1}{cmdh}{m}{n}{<->sub*cmss/m/n}{}
}
%
%------ End of declarations for the CM dunhill family. ---------



\begin{document}

\showfont
Text in normal font.

\begingroup
    \usefont{T2A}{iso}{m}{n}
    \showfont
    \lipsum[1]
\endgroup

\begingroup
    \usefont{T1}{cmdh}{m}{n}
    \showfont
    \lipsum[2]
\endgroup

Back to normal font.

\end{document}

显然,你可以通过将尺寸功能iso替换为 来避免有关使用 Computer Modern Sans 字体系列替换的警告。subssub

当然,代码也可以以文件的形式打包.fd :您只需要包含命令的定义\IfTFMFileExists和(条件)字体声明本身。

相关内容