I don't know how is this feature implemented in the font, but I guess that Luaotfload is missing support for it. The following code is just quick fix for this issue, it should be fixed in Luaotfload ideally.
The full code follows, some explanation is provided bellow:
\documentclass{article}
\usepackage{fontspec}
\usepackage{luacode}
\begin{luacode*}
local hlist_id = node.id "hlist"
local glyph_id = node.id "glyph"
local utfchar = unicode.utf8.char
local hyphen_char = 45
local break_subtype = 0
charreplaces = {}
local function get_char(c)
local x = tonumber(c)
if not x then
return string.byte(c)
end
return x
end
function char_replace(old, new)
local old = get_char(old)
local new = get_char(new)
print(old, new)
charreplaces[old] = new
end
local function get_next(n)
if n and n.id == glyph_id then
return n
elseif n then
return get_next(n.prev)
end
end
local function get_last_glyph(head)
local last = node.tail(head)
return get_next(last)
end
local function fix_end_f(head)
for n in node.traverse(head) do
if n.id == hlist_id then
local last = get_last_glyph(n.head)
if last and last.subtype == break_subtype and last.char == hyphen_char then
local prev = get_next(last.prev)
local c = prev.char
print("Last char: ", c)
if charreplaces[c] then
print("Replacing", c)
prev.char = charreplaces[c]
end
end
end
end
return head
end
luatexbase.add_to_callback("post_linebreak_filter", fix_end_f, "fix_end_f")
\end{luacode*}
\newcommand\CharReplaceAtEnd[2]{
\luaexec{char_replace(\luastring{#1},\luastring{#2})}
}
\CharReplaceAtEnd{983056}{f}
\setmainfont{Alegreya}%
[Path = /usr/local/texlive/2015/texmf-dist/fonts/truetype/huerta/alegreya/,
UprightFont = Alegreya-Regular.ttf]
\begin{document}
\parbox{0pt}{\hspace{0pt}for after}
for after
\end{document}
Node processing callback is used to fix the characters. Because we need to apply the fix after linebreak, we need to use post_linebreak_filter
.
local hlist_id = node.id "hlist"
local glyph_id = node.id "glyph"
local utfchar = unicode.utf8.char
local hyphen_char = 45
local break_subtype = 0
there we define some constants, in the callback, we need to process node list. In post_linebreak_filter
this list contains hlist
nodes, each containing one line. We need to get the last glyph from the line, to test whether it is linebreak hyphen, if it is, then we get the previous glyph, we print it to the standard output and test it whether it is in the table with replacements. If it is, we can replace the bad character with the right one.
local function fix_end_f(head)
for n in node.traverse(head) do
if n.id == hlist_id then
local last = get_last_glyph(n.head)
if last and last.subtype == break_subtype and last.char == hyphen_char then
local prev = get_next(last.prev)
local c = prev.char
print("Last char: ", c)
if charreplaces[c] then
print("Replacing", c)
prev.char = charreplaces[c]
end
end
end
end
return head
end
In order to make the interface more user friendly, one LaTeX macro is provided:
\newcommand\CharReplaceAtEnd[2]{
\luaexec{char_replace(\luastring{#1},\luastring{#2})}
}
it can be used in this way:
\CharReplaceAtEnd{983056}{f}
how we found the value 983056
? Search the LaTeX output for Last char
. It will print all characters preceding linebreak hyphen.
lualatex
as well:)
.