Define fallback font for missing glyphs in LuaLaTeX
While this doesn't use fontspec
, you can use Ulrike Fischer's experimental combofont
package. This uses luaotfload
's built-in support for combining fonts:
\documentclass{article}
\usepackage{verbatim}
\usepackage{combofont}
% Define a combofont for every font in the family
\setupcombofont{hack-symbola-regular}{
{Hack:\combodefaultfeat} at #1pt,
{Symbola:\combodefaultfeat} at #1pt
}{
{},
fallback
}
\setupcombofont{hack-symbola-bold}{
{Hack/B:\combodefaultfeat} at #1pt,
{Symbola:\combodefaultfeat} at #1pt
}{
{},
fallback
}
\setupcombofont{hack-symbola-italic}{
{Hack/I:\combodefaultfeat} at #1pt,
{Symbola:\combodefaultfeat} at #1pt
}{
{},
fallback
}
\setupcombofont{hack-symbola-bolditalic}{
{Hack/BI:\combodefaultfeat} at #1pt,
{Symbola:\combodefaultfeat} at #1pt
}{
{},
fallback
}
% Now set up the family
\DeclareFontFamily{TU}{hack-symbola}{}
\DeclareFontShape{TU}{hack-symbola}{m}{n} {<->combo*hack-symbola-regular}{}
\DeclareFontShape{TU}{hack-symbola}{bx}{n} {<->combo*hack-symbola-bold}{}
\DeclareFontShape{TU}{hack-symbola}{m}{it} {<->combo*hack-symbola-italic}{}
\DeclareFontShape{TU}{hack-symbola}{bx}{it} {<->combo*hack-symbola-bolditalic}{}
\renewcommand \ttdefault {hack-symbola}
\begin{document}
\begin{verbatim}
- project-root
- .gitignore (sub)
- README.md (sub)
\end{verbatim}
\end{document}
This sets up the entire family of Hack, if you only need the regular one (This is the only one used by verbatim
as far as I know) you can make it much shorter:
\documentclass{article}
\usepackage{verbatim}
\usepackage{combofont}
% Define a combofont for every font in the family
\setupcombofont{hack-symbola-regular}{
{Hack:\combodefaultfeat} at #1pt,
{Symbola:\combodefaultfeat} at #1pt
}{
{},
fallback
}
% Now set up the family
\DeclareFontFamily{TU}{hack-symbola}{}
\DeclareFontShape{TU}{hack-symbola}{m}{n} {<->combo*hack-symbola-regular}{}
\renewcommand \ttdefault {hack-symbola}
\begin{document}
\begin{verbatim}
- project-root
- .gitignore (sub)
- README.md (sub)
\end{verbatim}
\end{document}
This is what I could come up with:
\documentclass{article}
\usepackage{fontspec}
\setmonofont{Hack}
\usepackage{verbatim}
\newfontface\Symbola{Symbola}
{\Symbola\global\expandafter\let\expandafter\fallbackfont\the\font}
\usepackage{luacode}
\begin{luacode}
local fontcharacters = { }
local nullfont = 0
local glyph_t = nodes.nodecodes.glyph
local fallbackfont = font.id("fallbackfont")
table.setmetatableindex(fontcharacters, function (t, k)
if k == true then
return fontcharacters[currentfont()]
else
local tfmdata = fonts.hashes.identifiers[k]
if not tfmdata then --- unsafe
tfmdata = font.fonts[k]
if not (tfmdata and type (tfmdata) == "table") then
return false
end
end
local characters = tfmdata.characters
t[k] = characters
return characters
end
end)
local nodeprocessor = function (head)
local lastfont, characters = nil, nil
for n in node.traverse_id(glyph_t, head) do
local currfont = n.font
local char = n.char
if currfont ~= lastfont and currfont ~= nullfont then
characters = fontcharacters[currfont]
end
if characters ~= false then
lastfont = currfont
if not characters[char] then
n.font = fallbackfont
if fontcharacters[fallbackfont][char] then
node.remove(head,node.next(n)) -- remove .notdef char (new in luaotfload 2.98)
end
end
end
end
return head, false
end
luatexbase.add_to_callback("pre_linebreak_filter", nodeprocessor, "replace missing glyphs")
\end{luacode}
\begin{document}
\begin{verbatim}
- project-root
- .gitignore (sub)
- README.md (sub)
\end{verbatim}
\end{document}