1if not modules then modules = { } end modules ['meta-imp-txt'] = {
2 version = 1.001,
3 comment = "companion to meta-imp-txt.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 setmetatableindex = table.setmetatableindex
10local settings_to_array = utilities.parsers.settings_to_array
11
12local texget = tex.get
13local texset = tex.set
14local texgetcount = tex.getcount
15local texgetglue = tex.getglue
16
17local expandmacro = token.expandmacro or token.expand_macro
18
19local implement = interfaces.implement
20
21local scan = mp.scan
22local scannumeric = scan.numeric
23local scaninteger = scan.integer
24local scanboolean = scan.boolean
25local scanstring = scan.string
26
27local bpfactor <const> = number.dimenfactors.bp
28
29local context = context
30
31local parshapes = { }
32local properties = { }
33
34metapost.registerscript("setparshapeproperty", function()
35 local k = scanstring()
36 if k == "line" then
37 local entry = properties.shape[scannumeric()]
38 local indent = scannumeric() / bpfactor
39 local width = scannumeric() / bpfactor
40 entry[1] = indent
41 entry[2] = width
42 elseif k == "lines" then
43 properties.lines = scaninteger()
44 properties.shape = setmetatableindex(function(t,k)
45 local v = { 0, properties.width or 0 }
46 t[k] = v
47 return v
48 end)
49 elseif k == "first" then
50 properties[k] = scanboolean()
51 elseif k == "inspect" then
52 inspect(properties)
53 else
54 properties[k] = scannumeric() / bpfactor
55 end
56end)
57
58implement {
59 name = "setparagraphmetashape",
60 public = true,
61 protected = true,
62 arguments = { "optional", "optional" },
63 actions = function(list,options)
64 if list and list ~= "" then
65 list = settings_to_array(list)
66 options = settings_to_array(options)
67 if #list > 0 then
68 parshapes = { }
69 properties = { }
70 for i=1,#list do
71 properties = { }
72 parshapes[i] = properties
73 expandmacro("spac_shapes_calculate","{"..list[i].."}")
74 end
75 local t, n = { }, 0
76 for i=1,#parshapes do
77 local p = parshapes[i]
78 local s = p.shape
79 if s then
80 for i=1,(p.lines or #s) do
81 n = n + 1
82 t[n] = s[i]
83 end
84 end
85 end
86 if n > 0 then
87 for i=1,#options do
88 t[options[i]] = true
89 end
90 texset("parshape",t)
91 end
92 end
93 end
94 end
95}
96
97
98
99
100
101
102
103
104
105
106
107implement {
108 name = "getshapeparameter",
109 public = true,
110 arguments = "string",
111 actions = function(name)
112 local index = texgetcount("shapetextindex")
113 local value = parshapes[index][name]
114 if type(value) == "boolean" then
115 value = value and 1 or 0
116 end
117 context(value or 0)
118 end
119}
120
121
122
123
124
125
126do
127
128 local scanners = tokens.scanners
129 local scanword = scanners.word
130 local scandimension = scanners.dimension
131 local scanstring = scanners.string
132 local scancardinal = scanners.cardinal
133
134 implement {
135 name = "setparagraphshape",
136 protected = true,
137 actions = function()
138 local t = { }
139 local n = 0
140 local h = texget("hsize")
141 local a = 0
142 while true do
143 local key = scanword()
144 ::AGAIN::
145 if key == "left" then
146 local l = scandimension()
147 key = scanword()
148 if key == "right" then
149 n = n + 1 ; t[n] = { l, a + h - l - scandimension() }
150 elseif key == "hsize" then
151 n = n + 1 ; t[n] = { l, a + scandimension() }
152 else
153 n = n + 1 ; t[n] = { l, a + h }
154 goto AGAIN
155 end
156 elseif key == "right" then
157 n = n + 1 ; t[n] = { 0, a + h - scandimension() }
158 elseif key == "both" then
159 local b = scandimension()
160 n = n + 1 ; t[n] = { b, a + h - b - b }
161 elseif key == "copy" then
162 local c = scancardinal()
163 for i=1,c do
164 local m = n + 1
165 t[m] = t[n]
166 n = m
167 end
168 elseif key == "done" then
169
170 scanword()
171 break
172 elseif key == "metapost" then
173 local list = settings_to_array(scanstring())
174 properties = { }
175 parshapes = { }
176 for i=1,#list do
177 properties = { }
178 parshapes[i] = properties
179 expandmacro("spac_shapes_calculate","{"..list[i].."}")
180 end
181 for i=1,#parshapes do
182 local p = parshapes[i]
183 local s = p.shape
184 if s then
185 for i=1,(p.lines or #s) do
186 local si = s[i]
187 n = n + 1 ; t[n] = { si[1], a + si[2] }
188 end
189 end
190 end
191 elseif key == "repeat" then
192 t["repeat"] = true
193 elseif key == "delete" then
194 local c = scancardinal()
195 for i=1,c do
196 if n > 0 then
197 t[n] = nil
198 n = n - 1
199 else
200 break
201 end
202 end
203 elseif key == "reset" then
204 n = n + 1 ; t[n] = { 0, a + h }
205 break
206 elseif key == "absolute" then
207 local s = scanword()
208 local l = texgetglue("leftskip")
209 local r = texgetglue("rightskip")
210 if s == "left" then
211 a = l
212 elseif s == "right" then
213 a = r
214 elseif s == "both" then
215 a = l + r
216 else
217 a = l + r
218 goto AGAIN
219 end
220 elseif key == "inspect" then
221 inspect(t)
222 else
223 logs.report("system","bad key %a in paragraphshape",key)
224 break
225 end
226 end
227 texset("parshape",t)
228 end,
229 }
230
231 local NC = context.NC
232 local NR = context.NR
233 local VL = context.VL
234
235 implement {
236 name = "showparagraphshape",
237 protected = true,
238 public = true,
239 actions = function()
240 local p = texget("parshape")
241 if p then
242
243 context.inleftmargin(
244 {
245 align = "flushright",
246 strut = "no",
247 width = "0pt",
248
249 }, function()
250 context.starttabulate {
251 before = "",
252 after = "",
253 unit = "2pt",
254 rulethickness = ".1pt",
255 format = "|rb{\\smallinfofont}|lb{\\smallinfofont}|"
256 }
257 for i=1,#p do
258 NC() context("%P",p[i][1])
259 VL() context("%P",p[i][2])
260 NC() NR()
261 end
262 context.stoptabulate()
263 end
264 )
265 end
266 end
267 }
268
269end
270 |