typo-wrp.lua /size: 3415 b    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['typo-wrp'] = {
2    version   = 1.001,
3    comment   = "companion to typo-wrp.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-- begin/end par wrapping stuff ... more to come
10
11local nodecodes              = nodes.nodecodes
12local gluecodes              = nodes.gluecodes
13local penaltycodes           = nodes.penaltycodes
14local boundarycodes          = nodes.boundarycodes
15
16local glue_code              = nodecodes.glue
17local penalty_code           = nodecodes.penalty
18local boundary_code          = nodecodes.boundary
19
20local parfillskip_code       = gluecodes.parfillskip
21
22local userpenalty_code       = penaltycodes.userpenalty
23local linepenalty_code       = penaltycodes.linepenalty
24local linebreakpenalty_code  = penaltycodes.linebreakpenalty
25
26local wordboundary_code      = boundarycodes.word
27
28local nuts                   = nodes.nuts
29
30local find_node_tail         = nuts.tail
31local getprev                = nuts.getprev
32local getid                  = nuts.getid
33local getsubtype             = nuts.getsubtype
34local getpenalty             = nuts.getpenalty
35local remove_node            = nuts.remove
36
37local enableaction           = nodes.tasks.enableaction
38
39local wrappers               = { }
40typesetters.wrappers         = wrappers
41
42local trace_wrappers         = trackers.register("typesetters.wrappers",function(v) trace_wrappers = v end)
43
44local report                 = logs.reporter("paragraphs","wrappers")
45
46-- we really need to pass tail too ... but then we need to check all the plugins
47-- bah ... slowdown
48
49-- This check is very tight to the crlf definition. We check for:
50--
51-- [break -10000] [wordboundary] [line(break)penalty] [parfillskip]
52--
53-- If needed we can extend this checker for other cases but then we will also
54-- use attributes.
55
56-- we can actually do better in lmtx
57
58local function remove_dangling_crlf(head,tail)
59    if head and tail and getid(tail) == glue_code and getsubtype(tail) == parfillskip_code then
60        tail = getprev(tail)
61        if tail and getid(tail) == penalty_code then
62            local subtype = getsubtype(tail)
63            if subtype == linepenalty_code or subtype == linebreakpenalty_code then
64                tail = getprev(tail)
65                if tail and getid(tail) == boundary_code and getsubtype(tail) == wordboundary_code then
66                    tail = getprev(tail)
67                    if tail ~= head and getid(tail) == penalty_code and getsubtype(tail) == userpenalty_code and getpenalty(tail) == -10000 then
68                        if trace_wrappers then
69                            report("removing a probably unwanted end-of-par break in line %s (guess)",tex.inputlineno)
70                        end
71                        remove_node(head,tail,true)
72                        return head, tail
73                    end
74                end
75            end
76        end
77    end
78    return head, tail
79end
80
81function wrappers.handler(head)
82    if head then
83        local tail = find_node_tail(head)
84        head, tail = remove_dangling_crlf(head,tail) -- will be action chain
85    end
86    return head
87end
88
89interfaces.implement {
90    name     = "enablecrlf",
91    onlyonce = true,
92    actions  = function()
93        enableaction("processors","typesetters.wrappers.handler")
94    end
95}
96