5

I want to use "Hack" as the default font for source code. Unfortunately the font is missing some glyphs I use. If I use a glyphs that is missing in "Hack", I want it to be displayed automatically in another font (e.g. "Symbola") instead.

\documentclass{article}
\usepackage{fontspec}
\usepackage{verbatim}
\setmonofont{Hack}
%\setmonofont{Symbola} % use Symbola if glyph is missing in Hack
\begin{document}
\begin{verbatim}
- πŸ“‚ project-root
    - πŸ—Ž .gitignore (sub)
    - πŸ–Ί README.md (sub)
\end{verbatim}
\end{document}

I use this in a continuous integration process with Pandoc, so I don't know what glyphs are needed. Therefore, a general solution is needed.

So far I have only found a solution for specific glyphs.

3

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}

result

| improve this answer | |
  • @MarcelKrüger Thanks for your comment, makes sense. And I was wondering how to disable the notdef feature (should check the documentation more often...) – Robert Nov 5 '19 at 0:12
6

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}

enter image description here

| improve this answer | |
  • Works very well, thank you! I accepted Robert's solution because it works with fontspec. If you don't need it, yours is perfect. – Benjamin Buch Nov 6 '19 at 13:50

Your Answer

By clicking β€œPost Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.