[Tex/LaTex] Check for missing font characters in LuaLaTeX

fontspecluatex

I have a document:

\documentclass{article}
\usepackage{fontspec}
\begin{document}
Program the μC, please.
\end{document}

When I compile with xelatex or lualatex, there is a missing "μ" character in the output. This makes sense because the default font doesn't contain that character, but I need to know when it happens.

With xelatex, the log file contains a warning:

Missing character: There is no μ in font [lmroman10-regular]:mapping=tex-text!

Cool. But with lualatex, the output is wrong and there's not a single warning or error to be found. How can I detect missing characters in LuaLaTeX?

It seems that ConTeXt can use \checkcharactersinfont or \enabletrackers[fonts.missing], while XeLaTeX controls it with \tracinglostchars=2.

Best Answer

Here is an adaptation of the Context code for missing glyphs: https://gist.github.com/phi-gamma/5812290.

As the character table shipped with luaotfload is currently experimental, it doesn’t contain the necessary metadata. Thus the code requires the full version of char-def.lua from a Context distribution (installing the Context packages from TL should suffice).

Usage: \startreportmissingglyphs initializes the tracker. Its counterpart, \stopreportmissingglyphs, disables the glyph checker. Example:

\startreportmissingglyphs
  ... some text ...
\stopreportmissingglyphs

If invoked with the optional argument [once], \startreportmissingglyphs will report each missing character only once per font. Example output:

missing font terminal output

Note that due to the nature of the Luatex callbacks involved, the glyph checker works on a per-paragraph basis, and \stopreportmissingglyphs will force a paragraph end.

For reference, I include the full example including the definitions of interface macros from the gist:

\documentclass{article}
\usepackage{luacode,fontspec}

%% 1) initialize the tracker code (could go to separate file)
\makeatletter
\directlua{dofile "track-missing-glyphs.lua"}
%% 2) Environment start: the optional argument “once”, in square
%%    brackets, requests that the missing glyph message be printed
%%    only once per character and font.
\def\startreportmissingglyphs{%
  \@ifnextchar[\missingglyphs@start@indeed%
               {\missingglyphs@start@indeed[]}%
}
\def\missingglyphs@start@indeed[#1]{%
  \directlua{documentdata.missing_glyphs.enable"\luaescapestring{#1}"}%
}
%% 3) Environment stop: we need to force a \par here to
%%    have the callback apply to the current paragraph.
\def\stopreportmissingglyphs{%
  \endgraf %% paragraph-based callback!
  \directlua{documentdata.missing_glyphs.disable()}%
}
\makeatother
%% Usage examples.
\begin{document}
  %% Latin modern lacks glyphs for the Greek script so we use that for
  %% testing.
  \startreportmissingglyphs
    Program the μC, please.
    %% Works in math mode (different font model) as well.
    $f = ma$
  \stopreportmissingglyphs

  lorem schmipsum

  \startreportmissingglyphs[once]
    %% With the “once” flag, no message is emitted for repetitions of
    %% missing chars.
    Θάλαττα, θάλαττα.
  \stopreportmissingglyphs
\end{document}
Related Question