[Tex/LaTex] Set \sffamily if needed font is not installed

fonts

I have installed non standard font (ISOCPEUR.TTF) whiсh respond to \showfont command like this:

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

enter image description here

The command \newcommand{\iso}{\fontfamily{iso}\selectfont} set "iso" font, but if such is not installed switch to computern modern.

I want to create a command which set "iso" font, but if such font is not installed, the command must set \sffamily font.
I tried but my efforts have not been successful

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

In any case such code set \sffamily font even if "iso" font is installed.

Best Answer

On second thought, maybe you are just looking for a simple solution like the following:

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

Addition: Run-time check for the presence of a TFM file

I’m adding the answer I had originally devised for this problem, because I think that, after all, it illustrates an interesting technique. This solution doesn’t rely on the presence of a .fd file that describes how to implement a given font family (in principle, this is not mandatory in order to be able to use a font), but checks directly for the existence of the external font, or, more exactly, of its TFM (TeX Font Metric) file.

The following source file should be compiled with the --restricted-shell-escape command-line option. Among other things, it implements a command with three mandatory arguments named \IfTFMFileExists, which queries (via the piped input feature) the system for the existence of the TFM file whose basename is passed in the first argument, and executes the code contained in the second argument if the file is found, and the code contained in the third argument if it is not. This command is subsequently used to choose between two \DeclareFontShape declarations, one that binds the given font shape to its intended external font (if the latter is present on the system), and the other that substitutes for it another font shape.

Note that the first time you compile this code, it will probably invoke mktextfm to build the lasi1000.tfm TFM file, that is necessary for the font used as a substitute for the iso family, that is, Computer Modern Sans in the T2A encoding, and which is not installed by default in the standard TeXLive distribution.

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

Obviously, you can avoid warnings about the substitution of Computer Modern Sans for the iso family by replacing the sub size function with ssub.

The code could also be packaged in the form of a .fd file, of course: you would need to include only the defintion of the \IfTFMFileExists command and the (conditional) font declarations themselves.

Related Question