Skip to content

Instantly share code, notes, and snippets.

@phi-gamma
Last active December 18, 2015 20:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phi-gamma/5840851 to your computer and use it in GitHub Desktop.
Save phi-gamma/5840851 to your computer and use it in GitHub Desktop.
documentdata = documentdata or { }
documentdata.color_ligatures = { }
local color_ligatures = documentdata.color_ligatures
color_ligatures.color = { r = 0xee/255,
g = 0x31/255,
b = 0x09/255, }
local stringformat = string.format
local copynode = node.copy
local insertnodeafter = node.insert_after
local insertnodebefore = node.insert_before
local newnode = node.new
local traversenodes = node.traverse
local traversenodetype = node.traverse_id
local nodecodes = nodes.nodecodes
local glyph_t = nodecodes.glyph
local disc_t = nodecodes.disc
local hlist_t = nodecodes.hlist
local whatsit_t = nodecodes.whatsit
local pdf_literal_t = 8
local get_color = function ()
local color = color_ligatures.color
local push = stringformat ("%.3g %.3g %.3g rg",
color.r,
color.g,
color.b)
local pop = "0 g"
return push, pop
end
local pdf_literal = newnode(whatsit_t, pdf_literal_t)
local cbk = function (hd)
local pushcolor, popcolor = get_color()
local push, pop = copynode(pdf_literal), copynode(pdf_literal)
push.mode, push.data = 1, pushcolor
pop.mode, pop.data = 1, popcolor
for line in traversenodetype(hlist_t, hd) do
local hlist = line.list
for n in traversenodes(hlist) do
--- locate ligatures
if n.id == glyph_t and n.components then
--- surround with color literals
local before, after = copynode(push), copynode(pop)
hlist = insertnodebefore(hlist, n, before)
hlist = insertnodeafter (hlist, n, after)
elseif n.id == disc_t then
local replace = n.replace
if replace and replace.components then
local before, after = copynode(push), copynode(pop)
hlist = insertnodebefore(hlist, n, before)
hlist = insertnodeafter (hlist, n, after)
end
end
end
end
return hd
end
local hook = "post_linebreak_filter"
local active = false
color_ligatures.enable = function ()
if active == false then
luatexbase.add_to_callback (hook, cbk, "my.color_ligatures")
active = true
end
end
color_ligatures.disable = function ()
if active == true then
luatexbase.remove_from_callback (hook, "my.color_ligatures")
active = false
end
end
color_ligatures.set_color = function (r, g, b)
color_ligatures.color = { r = (tonumber(r, 16) or 0) / 255,
g = (tonumber(g, 16) or 0) / 255,
b = (tonumber(b, 16) or 0) / 255, }
end
%% http://tex.stackexchange.com/q/120397/14066
\input luaotfload.sty
%% uncomment this for node mode (default in luaotfload):
%\font\mainfont="file:Iwona-Regular.otf" at 30pt \mainfont
\directlua{dofile "color-ligatures.lua"}
\def\startcolorligatures{%
\directlua{documentdata.color_ligatures.enable()}%
}
\def\stopcolorligatures{%
\endgraf %% paragraph-based callback
\directlua{documentdata.color_ligatures.disable()}%
}
\def\setligaturecolor#1#2#3{%%-> rgb values
\directlua{documentdata.color_ligatures.set_color("#1", "#2", "#3")}
}
before a ff b ffi c ffl d
\startcolorligatures
during a ff b ffi c ffl d
\setligaturecolor{0}{0}{bb}
different color a ff b ffi c ffl d
\stopcolorligatures
after a ff b ffi c ffl d
\bye
@vermiculus
Copy link

Absolutely amazing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment