1

I currently have this code from a previous question (link here)

\NewDocumentCommand \IfFontTF {mmmmmm}
{%
  \begingroup
  \fontencoding{#1}\fontfamily{#2}\fontseries{#3}\fontshape{#4}\try@load@fontshape
  \expandafter\ifx\csname\curr@fontshape\endcsname\relax
    #6%
  \else
    #5%
  \fi
  \endgroup
}

How to write the same functionality in expl3, in particular the line: \expandafter\ifx\csname\curr@fontshape\endcsname\relax

I am not sure which function to use in interface3?

7
  • 1
    \cs_if_exist:cTF{curr@fontshape}{#5}{#6}
    – cabohah
    Commented Oct 17 at 12:26
  • Alternatively you could use \cs_if_free:cTF{curr@fontshape}{#6}{#5}, but I prefer the other way around.
    – cabohah
    Commented Oct 17 at 12:35
  • 3
    @cabohah Wouldn't that be \cs_if_exist:cTF{\curr@fontshape}{#5}{#6}?
    – gusbrs
    Commented Oct 17 at 13:22
  • Also, the linked question itself seems to already provide expl3 based alternatives...
    – gusbrs
    Commented Oct 17 at 13:25
  • 3
    please could you update this to use the code from my amended answer?
    – cfr
    Commented Oct 18 at 5:41

2 Answers 2

5

[expl3 error corrected thanks to Skillman. Output is unchanged.]

Here's a version which is technically1 expl32,3,4,5:

\documentclass{article}
% ateb: https://tex.stackexchange.com/a/727927/
% ateb: https://tex.stackexchange.com/a/728868/
\usepackage{nfssext-cfr}
\makeatletter
\ExplSyntaxOn
\NewDocumentCommand \IfFontTF {mmmmmm}
{
  \group_begin:
  \fontencoding{#1}\fontfamily{#2}\fontseries{#3}\fontshape{#4}\try@load@fontshape
  % sylwad Skillman: https://tex.stackexchange.com/questions/729130/problem-with-conditional-tf-version-working-but-not-the-p-version?noredirect=1#comment1815533_729130
  \exp_args:Nc \if_meaning:w { \curr@fontshape } \relax
    \group_end:
    #6
  \else:
    \fontencoding{#1}\fontfamily{#2}\fontseries{#3}\fontshape{#4}\selectfont
    \if_cs_exist:w  exfs@fake@\curr@fontshape \cs_end:
      \group_end:
      #6
    \else:
      \group_end:
      #5
    \fi:
  \fi:
}
\NewDocumentCommand \FontIfExists {ommmm}
{
  \group_begin:
  \fontencoding{#2}\fontfamily{#3}\fontseries{#4}\fontshape{#5}\try@load@fontshape
  % sylwad Skillman: https://tex.stackexchange.com/questions/729130/problem-with-conditional-tf-version-working-but-not-the-p-version?noredirect=1#comment1815533_729130
  \exp_args:Nc \if_meaning:w { \curr@fontshape } \relax
    \group_end:
    \IfValueT{#1}{#1}
  \else:
    \fontencoding{#2}\fontfamily{#3}\fontseries{#4}\fontshape{#5}\selectfont
    \if_cs_exist:w  exfs@fake@\curr@fontshape \cs_end:
      \group_end:
      \IfValueT{#1}{#1}
    \else:
      \group_end:
      \fontencoding{#2}\fontfamily{#3}\fontseries{#4}\fontshape{#5}\selectfont
    \fi:
  \fi:
}
\cs_new_eq:NN \ShowFont\curr@fontshape
\makeatother
\ExplSyntaxOff
\begin{document}
\IfFontTF{OT1}{cmr}{m}{sc}{OT1/cmr/m/sc exists}{OT1/cmr/m/sc is non-existent.}

\IfFontTF{T1}{clm}{bx}{n}{T1/clm/bx/n exists}{T1/clm/bx/n is non-existent.}

\IfFontTF{T1}{clm}{bz}{n}{T1/clm/bz/n exists}{T1/clm/bz/n is non-existent.}

\IfFontTF{T1}{clmx}{bx}{n}{T1/clmx/bx/n exists}{T1/clmx/bx/n is non-existent.}

\IfFontTF{T1}{clm}{bx}{blurb}{T1/clm/bx/blurb exists}{T1/clm/bx/blurb is non-existent.}

\IfFontTF{OT1}{cmr}{m}{blurb}{YES}{NO}

\FontIfExists{OT1}{cmr}{m}{sc}
\ShowFont

\FontIfExists{T1}{clm}{bx}{n}
\ShowFont

\FontIfExists{T1}{clmx}{bx}{n}
\ShowFont

\FontIfExists[Oh, no!]{OT1}{cmr}{m}{sc}
\ShowFont

\FontIfExists[Oh, dear!]{T1}{clm}{bx}{n}
\ShowFont

\FontIfExists[Oops!]{T1}{clmx}{bx}{n}
\ShowFont


\FontIfExists[egreg says `no']{OT1}{cmr}{m}{blurb}
\ShowFont

\thispagestyle{empty}
\end{document}

Proof in pudding:

exactly similar output

1Note that I do not claim it is in the spirit of the enterprise, but only that the replacement code technically qualifies.

2Except for font macros and \relax.

3In case wipet ever reads this: you need not say it. I concede your point in advance.

4Do not try this at home without professional supervision. This code is not intended for domestic use.

5There is a 99% chance I will delete this later. The other 1% involves Virgin Media and/or Acts of Fate.

2
  • I like expl3, but I have to admit that answering this question leaves me rather more sceptical than I expected. which is not to say it isn't great. but insisting on expl3 here seems ... pointless? dubious? I'm left wondering what the advantage of expl3 versions of these macros is supposed to be. but perhaps I just don't get it. (besides, of course, answering questions demanding expl3 translations, but it seems a lot of trouble for that. it doesn't even provide a consistent syntax as far as I can tell.)
    – cfr
    Commented Oct 18 at 6:33
  • doubtless the code can be rendered more in the spirit of expl3, but it is certainly harder to do that here and I somehow doubt the result would be clearer. is it just to eliminate %s?
    – cfr
    Commented Oct 18 at 6:41
2

Note that your example code tries to test font existence based on old method how LaTeX works with old 8bit fonts (it means .fd files, short and unclear filenames, .tfm files, .vf files, .map files, .enc files, obscure encodings and other complications). Today, we are using Unicode fonts in Unicode TeX engines. We can forget the ancient complications. We are asking for existence the font directly by font filename of font name using \font primitive while \suppressfontnotfounderror=1. Simply try to use \font TeX primitive and then ask if the result is \nullfont.

For example, you can implement a macro \isfont similar like in OpTeX by:

\initunifonts % or another initializing of Unicode `\font` primitive

\def\isfont#1{%
   \begingroup
       \suppressfontnotfounderror=1
       \font\testfont={#1}\_relax
       \ifx\testfont\nullfont \endgroup \expandafter \unless
       \else \endgroup \_fi
}

\isfont{TeXGyreTermes-Bold}\iftrue yes \else no \fi % prints yes

\isfont{TeXGyreTomos-Bold}\iftrue  yes \else no \fi % prints no

\bye

And to the question from the title of this thread: Of course, there is expl3 alternative but also we have primitive equivalent of \expandafter\ifx\csname which sounds \ifcsname (available in all today's TeX engines because it is from eTeX). The usage is

\ifcsname name of control sequence\endcsname is defined \else isn't defined \fi
3
  • it isn't testing whether the cs is defined. it is testing whether it is equivalent to \relax. substituting \ifcsname ... will not work. I didn't use \ifcsname here precisely because it won't work. that's why this test differs from the other one (which does use \ifcsname.) could you please explain this in your answer?
    – cfr
    Commented Oct 27 at 3:26
  • @cfr OK, this is fully explained in your comment. My notice about \ifcsname is related only to the title of the question, isolated from the context of the example used in the question.
    – wipet
    Commented Oct 27 at 5:36
  • well, you say it is 'equivalent', which it isn't. and it cannot be substituted into the example the OP gives in the question because the difference matters. comments are intended to be ephemeral. according to SE, I should probably just have edited your answer. but I don't generally do that except for clear typos, format or language fixes.
    – cfr
    Commented Oct 27 at 6:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .