typo-cln.lua /size: 3307 b    last modification: 2023-12-21 09:44
1if not modules then modules = { } end modules ['typo-cln'] = {
2    version   = 1.001,
3    comment   = "companion to typo-cln.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
9-- This quick and dirty hack took less time than listening to a CD (In
10-- this case Dream Theaters' Octavium). Of course extensions will take
11-- more time.
12
13-- This feature is probably never used so we can get rid of it.
14
15local tonumber = tonumber
16local utfbyte = utf.byte
17
18local trace_cleaners = false  trackers.register("typesetters.cleaners",         function(v) trace_cleaners = v end)
19local trace_autocase = false  trackers.register("typesetters.cleaners.autocase",function(v) trace_autocase = v end)
20
21local report_cleaners = logs.reporter("nodes","cleaners")
22local report_autocase = logs.reporter("nodes","autocase")
23
24typesetters.cleaners  = typesetters.cleaners or { }
25local cleaners        = typesetters.cleaners
26
27local variables       = interfaces.variables
28
29local nodecodes       = nodes.nodecodes
30
31local enableaction    = nodes.tasks.enableaction
32
33local texsetattribute = tex.setattribute
34
35local nuts            = nodes.nuts
36
37local getattr         = nuts.getattr
38local setattr         = nuts.setattr
39
40local setchar         = nuts.setchar
41
42local nextglyph       = nuts.traversers.glyph
43
44local unsetvalue      = attributes.unsetvalue
45
46local glyph_code      = nodecodes.glyph
47local uccodes         = characters.uccodes
48
49local a_cleaner       = attributes.private("cleaner")
50
51local resetter = { -- this will become an entry in char-def
52    [utfbyte(".")] = true
53}
54
55-- Contrary to the casing code we need to keep track of a state.
56-- We could extend the casing code with a status tracker but on
57-- the other hand we might want to apply casing afterwards. So,
58-- cleaning comes first.
59
60function cleaners.handler(head)
61    local inline = false
62    for n, char, font in nextglyph, head do
63        if resetter[char] then
64            inline = false
65        elseif not inline then
66            local a = getattr(n,a_cleaner)
67            if a == 1 then -- currently only one cleaner so no need to be fancy
68                local upper = uccodes[char]
69                if type(upper) == "table" then
70                    -- some day, not much change that \SS ends up here
71                else
72                    setchar(n,upper)
73                    if trace_autocase then
74                        report_autocase("")
75                    end
76                end
77            end
78            inline = true
79        end
80    end
81    return head
82end
83
84-- see typo-cap for a more advanced settings handler .. not needed now
85
86local enabled = false
87
88function cleaners.set(n)
89    if n == variables.reset or not tonumber(n) or n == 0 then
90        texsetattribute(a_cleaner,unsetvalue)
91    else
92        if not enabled then
93            enableaction("processors","typesetters.cleaners.handler")
94            if trace_cleaners then
95                report_cleaners("enabling cleaners")
96            end
97            enabled = true
98        end
99        texsetattribute(a_cleaner,tonumber(n))
100    end
101end
102
103-- interface
104
105interfaces.implement {
106    name      = "setcharactercleaning",
107    actions   = cleaners.set,
108    arguments = "string"
109}
110