symb-emj.lua /size: 2126 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['symb-emj'] = {
2    version   = 1.001,
3    comment   = "companion to symb-emj.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9local symbols        = fonts.symbols
10
11-- emoji
12
13-- processors.hpack_filter does it all
14
15local resolvedemoji   = characters.emoji.resolve
16local processfeatures = fonts.handlers.otf.featuresprocessor
17local injectspacing   = nodes.injections.handler
18local protectglyphs   = nodes.handlers.protectglyphs
19local tonodes         = nodes.tonodes
20local currentfont     = font.current
21
22local nuts            = nodes.nuts
23local tonode          = nuts.tonode
24local tonut           = nuts.tonut
25local remove_node     = nuts.remove
26local isglyph         = nuts.isglyph
27local getnext         = nuts.getnext
28
29local function removemodifiers(head)
30    local head    = tonut(head)
31    local current = head
32    while current do
33        local char, id = isglyph(current)
34        if char and char == 0x200D or (char >= 0x1F3FB and char <= 0x1F3FF) then
35            head, current = remove_node(head,current,true)
36        else
37            current = getnext(current)
38        end
39    end
40    return tonode(head)
41end
42
43-- fast enough, no need to memoize, maybe use attributes
44
45local function checkedemoji(name,id)
46    local str = resolvedemoji(name)
47    if str then
48        if not id then
49            id = currentfont()
50        end
51        local head = tonodes(str,id,nil,nil,true) -- use current attributes
52        head = processfeatures(head,id,false)
53        if head then
54            head = injectspacing(head)
55            protectglyphs(head)
56            return removemodifiers(head)
57        end
58    end
59end
60
61symbols.emoji = {
62    resolved = resolvedemoji,
63    checked  = checkedemoji,
64}
65
66interfaces.implement {
67    name      = "resolvedemoji",
68    actions   = { resolvedemoji, context.escaped },
69    arguments = "string",
70}
71
72interfaces.implement {
73    name      = "checkedemoji",
74    actions   = { checkedemoji, context },
75    arguments = "string",
76}
77
78
79