Fonts – Identifying Ligatures Offered by Fonts in Document

fontsligaturesmicrotype

This is a follow-up question to: How do I know which ligatures are used in my document?

In order to know which ligatures I might consider disabling (I have in mind microtype's \DisableLigatures command; some important notes about selective disabling of ligatures are found under this question), knowledge about which ligatures might be applied will be very useful. Which ligatures do the fonts used in my document offer?

Best Answer

The following presents a solution for pdftex and Type 1 fonts. Since TeX does not offer any possibility to decompose a ligature into its constituent characters (this information is lost after they have been replaced by the ligature), we have to take the opposite approach: we loop over all glyph pairs in the fonts, typesetting them in a temporary box, and test, by way of etex's \lastnodetype, whether we have obtained a ligature. We can then write the slot numbers of the ligating characters to the log file and/or actually typeset the ligature and its parts, whereas the slot number of the ligature is only available with \showbox (see below).

\RequirePackage{fix-cm}
\documentclass[12pt]{article}
\usepackage[LY1,T1]{fontenc}
\usepackage{fixltx2e}[2006/09/13]
\usepackage[expansion=false]{microtype}
\usepackage{yfonts}
% enable microtype's no ligatures procedure, without actually disabling any ligatures
\DisableLigatures{encoding = }
\makeatletter
\showboxbreadth100
\showboxdepth100
\newcount\MT@ligcount
\newbox\MT@ligbox
\newtoks\MT@ligtoks
\def\MT@showligs{%
  \MT@info@nl{showing ligatures in font `\MT@@font'}%
  \let\lig@temp\@empty
  % loop over all glyph pairs in the font
  \MT@do@font{%
    %\iffontchar\MT@font\@tempcnta\relax  % only test those glyphs that
    \ifnum\tagcode\MT@font\@tempcnta=\@ne % have a "lig/kern program"
      \MT@ligcount\z@
      \loop
      \iffontchar\MT@font\MT@ligcount
        \setbox\@tempboxa\hbox{\MT@font
          \setbox\MT@ligbox\hbox{\char\@tempcnta\char\MT@ligcount}%
          \unhbox\MT@ligbox
          \ifnum\lastnodetype=7 % ligature
            \aftergroup\@firstofone
          \else
            \aftergroup\@gobble
          \fi
        }%
        {% info in the log file
        %\showbox\@tempboxa
         \MT@info@nl{\the\@tempcnta\space + \the\MT@ligcount}%
         % store information for later
         \edef\lig@temp{\lig@temp
             \noexpand\char\the\@tempcnta\noexpand\char\the\MT@ligcount
            $($\noexpand\char\the\@tempcnta$^{[\the\@tempcnta]}$%
               \noexpand\char\the\MT@ligcount$^{[\the\MT@ligcount]}),$ }%
         }%
      \fi
      \advance\MT@ligcount\@ne
      \ifnum\MT@ligcount < \@cclvi \repeat
    \fi
  }%
  \ifx\lig@temp\@empty
    \edef\lig@temp{\noexpand\normalfont No ligatures in `\MT@@font'.}
  \else
    \edef\lig@temp{\noexpand\normalfont Ligatures in `\MT@@font': \MT@font\lig@temp}%
  \fi
  \global\MT@ligtoks\expandafter\expandafter\expandafter
    {\expandafter\the\expandafter\MT@ligtoks\lig@temp\par}%
}

% hook into microtype to make sure that all fonts are caught
\let\MT@noligatures@orig\MT@noligatures
\def\MT@noligatures{\MT@noligatures@orig\MT@showligs}

\AtEndDocument{\par\hrule\the\MT@ligtoks}

\begin{document}

Selecting 
{\fontencoding{LY1}\selectfont various} 
\textit{(including $\mathrm{maths}$)} 
\textfrak{fonts:}

\end{document}

show ligatures output

Uncommenting the \showbox line will allow finding out, in a clumsy way, the slot number of the ligature, too, which will be presented in a form like this:

> \box12=
hbox(5.1654+0.0)x11.74713
.T1/cmr/m/n/12 ^^V (ligature ^^U-)

This shows the triple ligature — (emdash), composed of the ligature – (endash) and the character - (hyphen), normally written as ---, where ^^V = 22, and ^^U = 21 (conversion rules here). Other than that, getting the slot numbers of ligature requires leaving the pdftex realm and resort to inspecting the tfm file (see @egreg's solution), employing metapost (@AndrewKepert), or (probably) luatex.

Related Question