1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
if not modules then modules = { } end modules ['typo-wrp'] = {
version = 1.001,
comment = "companion to typo-wrp.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
-- begin/end par wrapping stuff ... more to come
local boundary_code = nodes.nodecodes.boundary
local glyph_code = nodes.nodecodes.glyph
local wordboundary_code = nodes.boundarycodes.word
local userboundary_code = nodes.boundarycodes.user
local nuts = nodes.nuts
local findtail = nuts.tail
local getprev = nuts.getprev
local setnext = nuts.setnext
local getid = nuts.getid
local getdata = nuts.getdata
local isglyph = nuts.isglyph
local getsubtype = nuts.getsubtype
local getattr = nuts.getattr
local flushnodelist = nuts.flushlist
local traverse_boundary = nuts.traversers.boundary
local insertnodebefore = nuts.insertbefore
local newkern = nuts.pool.kern
local fontdata = fonts.hashes.identifiers
local enableaction = nodes.tasks.enableaction
local implement = interfaces.implement
local wrappers = { }
typesetters.wrappers = wrappers
local trace_wrappers trackers.register("typesetters.wrappers",function(v) trace_wrappers = v end)
local report = logs.reporter("paragraphs","wrappers")
-- In luametatex we don't have the parfilskip attached yet but we can have final glue
-- anyway. This check is very bound to the \crlf definition where we get:
--
-- ... boundary [strut: hlist] [break: glue penalty] boundary
local a_crlf = attributes.private("crlf")
local function remove_dangling_crlf(head,tail)
if head and tail then
if getid(tail) == boundary_code and getsubtype(tail) == wordboundary_code then
-- findnode could run backwards
if getattr(tail,a_crlf) then
local t = tail
while t do
t = getprev(t)
if not t then
break
elseif getid(t) == boundary_code and getsubtype(t) == wordboundary_code then
if t ~= head then
if trace_wrappers then
report("removing a probably unwanted end-of-par break in line %s (guess)",tex.inputlineno)
end
tail = getprev(t)
setnext(tail)
flushnodelist(t)
end
break
end
end
end
end
end
return head, tail
end
implement {
name = "enablecrlf",
onlyonce = true,
actions = function()
enableaction("processors","typesetters.wrappers.handler")
end
}
-- Here's a solution for a trivial challenge by MS who got it from the internet
-- (SE). If needed we can make it a bit more granular.
local tighten = { }
typesetters.tighten = tighten
local trace_tighten trackers.register("typesetters.tighten",function(v) trace_tighten = v end)
local report = logs.reporter("typesetters","tighten")
local a_tightfit_boundary = tex.boundaries.system("c_tightfit_boundary") -- private, not defined with \defineboundary
local function bbcompensation(font,char)
local tfmdata = fontdata[font]
local character = tfmdata.characters[char]
if character then
local compensation = character.compensation
if not compensation then
local description = tfmdata.descriptions[char]
if description then
local boundingbox = description.boundingbox
return boundingbox and (boundingbox[3] - (description.width or 0)) * tfmdata.parameters.hfactor
end
character.compensation = compensation
end
end
return 0
end
function tighten.handler(head)
for n, subtype in traverse_boundary, head do
if subtype == userboundary_code and getdata(n) == a_tightfit_boundary then
local prev = getprev(n)
if prev then
local char, font = isglyph(prev)
if char then
local compensation = bbcompensation(font,char)
if compensation > 0 then
if trace_tighten then
report("compensating %p after %C",compensation,char)
end
insertnodebefore(head,n,newkern(compensation))
end
end
end
end
end
return head
end
implement {
name = "enabletighten",
onlyonce = true,
actions = function()
enableaction("processors","typesetters.tighten.handler")
end
}
local dimension_value = tokens.values.dimension
local texgetnest = tex.getnest
implement {
name = "tightfitcompensation",
public = true,
protected = true,
usage = "value",
actions = function()
local list = texgetnest()
if list then
list = list.tail
end
return
dimension_value,
list and list.id == glyph_code and bbcompensation(list.font,list.char) or 0
end,
}
|