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
10
11local boundary_code <const> = nodes.nodecodes.boundary
12local glyph_code <const> = nodes.nodecodes.glyph
13local wordboundary_code <const> = nodes.boundarycodes.word
14local userboundary_code <const> = nodes.boundarycodes.user
15
16local nuts = nodes.nuts
17
18local findtail = nuts.tail
19local getprev = nuts.getprev
20local setnext = nuts.setnext
21local getid = nuts.getid
22local getdata = nuts.getdata
23local isglyph = nuts.isglyph
24local getsubtype = nuts.getsubtype
25local getattr = nuts.getattr
26local flushnodelist = nuts.flushlist
27local traverse_boundary = nuts.traversers.boundary
28local insertnodebefore = nuts.insertbefore
29local newkern = nuts.pool.kern
30
31local fontdata = fonts.hashes.identifiers
32
33local enableaction = nodes.tasks.enableaction
34
35local implement = interfaces.implement
36
37local wrappers = { }
38typesetters.wrappers = wrappers
39
40local trace_wrappers trackers.register("typesetters.wrappers",function(v) trace_wrappers = v end)
41local report = logs.reporter("paragraphs","wrappers")
42
43
44
45
46
47
48local a_crlf <const> = attributes.private("crlf")
49
50local function remove_dangling_crlf(head,tail)
51 if head and tail then
52 if getid(tail) == boundary_code and getsubtype(tail) == wordboundary_code then
53
54 if getattr(tail,a_crlf) then
55 local t = tail
56 while t do
57 t = getprev(t)
58 if not t then
59 break
60 elseif getid(t) == boundary_code and getsubtype(t) == wordboundary_code then
61 if t ~= head then
62 if trace_wrappers then
63 report("removing a probably unwanted end-of-par break in line %s (guess)",tex.inputlineno)
64 end
65 tail = getprev(t)
66 setnext(tail)
67 flushnodelist(t)
68 end
69 break
70 end
71 end
72 end
73 end
74 end
75 return head, tail
76end
77
78implement {
79 name = "enablecrlf",
80 onlyonce = true,
81 actions = function()
82 enableaction("processors","typesetters.wrappers.handler")
83 end
84}
85
86
87
88
89local tighten = { }
90typesetters.tighten = tighten
91
92local trace_tighten trackers.register("typesetters.tighten",function(v) trace_tighten = v end)
93local report = logs.reporter("typesetters","tighten")
94
95local a_tightfit_boundary <const> = tex.boundaries.system("c_tightfit_boundary")
96
97local function bbcompensation(font,char)
98 local tfmdata = fontdata[font]
99 local character = tfmdata.characters[char]
100 if character then
101 local compensation = character.compensation
102 if not compensation then
103 local description = tfmdata.descriptions[char]
104 if description then
105 local boundingbox = description.boundingbox
106 return boundingbox and (boundingbox[3] - (description.width or 0)) * tfmdata.parameters.hfactor
107 end
108 character.compensation = compensation
109 end
110 end
111 return 0
112end
113
114function tighten.handler(head)
115 for n, subtype in traverse_boundary, head do
116 if subtype == userboundary_code and getdata(n) == a_tightfit_boundary then
117 local prev = getprev(n)
118 if prev then
119 local char, font = isglyph(prev)
120 if char then
121 local compensation = bbcompensation(font,char)
122 if compensation > 0 then
123 if trace_tighten then
124 report("compensating %p after %C",compensation,char)
125 end
126 insertnodebefore(head,n,newkern(compensation))
127 end
128 end
129 end
130 end
131 end
132 return head
133end
134
135implement {
136 name = "enabletighten",
137 onlyonce = true,
138 actions = function()
139 enableaction("processors","typesetters.tighten.handler")
140 end
141}
142
143local dimension_value <const> = tokens.values.dimension
144local texgetnest = tex.getnest
145
146implement {
147 name = "tightfitcompensation",
148 public = true,
149 protected = true,
150 usage = "value",
151 actions = function()
152 local list = texgetnest()
153 if list then
154 list = list.tail
155 end
156 return
157 dimension_value,
158 list and list.id == glyph_code and bbcompensation(list.font,list.char) or 0
159 end,
160}
161 |