summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/scrn-wid.lua
blob: 5b70bec75563261259bb51a3a2fd29095f087fd2 (plain)
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
if not modules then modules = { } end modules ['scrn-wid'] = {
    version   = 1.001,
    comment   = "companion to scrn-wid.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- Support for interactive features is handled elsewhere. Now that is some mess! In
-- the early days one had media features like sound and movies that were easy to set
-- up. Then at some point renditions came around which were more work and somewhat
-- unreliable. Now, both mechanism are obsolete and replaced by rich media which is
-- a huge mess and has no real concept of what media are supported. There's flash
-- cq. shockwave (basically obsolete too), and for instance mp4 needs to be handled
-- by a swf player, and there's u3d which somehow has its own specification. One
-- would expect native support for video and audio to be en-par with browsers but
-- alas ... pdf has lost the battle with html here due to a few decades of
-- unstability and changing support. So far we could catch on and even were ahead
-- but I wonder if we should keep doing that. As we can't trust support for media we
-- can better not embed anything and just use a hyperlink to an external resource. No
-- sane person will create media rich pdf's as long as it's that unpredictable. Just
-- look at the specification and viewer preferences and decide.

local next = next

interactions             = interactions or { }
local interactions       = interactions

local context            = context
local implement          = interfaces.implement

local allocate           = utilities.storage.allocate

local attachments        = allocate()
local comments           = allocate()
local soundclips         = allocate()
local renderings         = allocate()
local linkedlists        = allocate()

interactions.attachments = attachments
interactions.soundclips  = soundclips
interactions.renderings  = renderings
interactions.linkedlists = linkedlists

local texsetbox          = tex.setbox

local jobpasses          = job.passes

local texgetcount        = tex.getcount

local codeinjections     = backends.codeinjections
local nodeinjections     = backends.nodeinjections

local variables          = interfaces.variables
local v_auto             = variables.auto

local trace_attachments = false  trackers.register("widgets.attachments", function(v) trace_attachments = v end)

local report_attachments = logs.reporter("widgets","attachments")

-- Symbols

implement {
    name      = "presetsymbollist",
    arguments = "string",
    actions   = function(list)
        codeinjections.presetsymbollist(list)
    end
}

-- Attachments
--
-- registered : unique id
-- tag        : used at the tex end
-- file       : name that the file has on the filesystem
-- name       : name that the file will get in the output
-- title      : up to the backend
-- subtitle   : up to the backend
-- author     : up to the backend
-- method     : up to the backend (hidden == no rendering)

local nofautoattachments, lastregistered = 0, nil

local function checkregistered(specification)
    local registered = specification.registered
    if not registered or registered == "" or registered == v_auto then
        nofautoattachments = nofautoattachments + 1
        lastregistered = "attachment-" .. nofautoattachments
        specification.registered = lastregistered
        return lastregistered
    else
        return registered
    end
end

local function checkbuffer(specification)
    local buffer = specification.buffer
    if buffer ~= "" then
        specification.data = buffers.getcontent(buffer) or "<no data>"
    end
end

function attachments.register(specification) -- beware of tag/registered mixup(tag is namespace)
    local registered = checkregistered(specification)
    checkbuffer(specification)
    attachments[registered] = specification
    if trace_attachments then
        report_attachments("registering %a",registered)
    end
    return specification
end

function attachments.insert(specification)
    local registered = checkregistered(specification)
    local r = attachments[registered]
    if r then
        if trace_attachments then
            report_attachments("including registered %a",registered)
        end
        for k, v in next, r do
            local s = specification[k]
            if s == "" then
                specification[k] = v
            end
        end
    elseif trace_attachments then
        report_attachments("including unregistered %a",registered)
    end
    checkbuffer(specification)
    return nodeinjections.attachfile(specification)
end

implement {
    name      = "registerattachment",
    actions   = attachments.register,
    arguments = {
        {
            { "tag" },
            { "registered" },
            { "title" },
            { "subtitle" },
            { "author" },
            { "file" },
            { "name" },
            { "buffer" },
        }
    }
}

implement {
    name      = "insertattachment",
    actions   = function(specification)
                    texsetbox("b_scrn_attachment_link",(attachments.insert(specification)))
                end,
    arguments = {
        {
            { "tag" },
            { "registered" },
            { "method" },
            { "width", "dimen" },
            { "height", "dimen" },
            { "depth", "dimen" },
            { "colormodel", "integer" },
            { "colorvalue", "integer" },
            { "color" },
            { "transparencyvalue", "integer" },
            { "symbol" },
            { "layer" },
            { "title" },
            { "subtitle" },
            { "author" },
            { "file" },
            { "name" },
            { "buffer" },
        }
    }
}

-- Comment

function comments.insert(specification)
    local buffer = specification.buffer
    if buffer ~= "" then
        specification.data = buffers.getcontent(buffer) or ""
    end
    return nodeinjections.comment(specification)
end

implement {
    name      = "insertcomment",
    actions   = function(specification)
                    texsetbox("b_scrn_comment_link",(comments.insert(specification)))
                end,
    arguments = {
        {
            { "tag" },
            { "title" },
            { "subtitle" },
            { "author" },
            { "width", "dimen" },
            { "height", "dimen" },
            { "depth", "dimen" },
            { "nx" },
            { "ny" },
            { "colormodel", "integer" },
            { "colorvalue", "integer" },
            { "transparencyvalue", "integer" },
            { "option" },
            { "symbol" },
            { "buffer" },
            { "layer" },
            { "space" },
        }
    }
}

-- Soundclips

function soundclips.register(specification)
    local tag = specification.tag
    if tag and tag ~= "" then
        local filename = specification.file
        if not filename or filename == "" then
            filename = tag
            specification.file = filename
        end
        soundclips[tag] = specification
        return specification
    end
end

function soundclips.insert(tag)
    local sc = soundclips[tag]
    if not sc then
        -- todo: message
        return soundclips.register { tag = tag }
    else
        return sc
    end
end

implement {
    name      = "registersoundclip",
    actions   = soundclips.register,
    arguments = {
        {
            { "tag" },
            { "file" }
        }
    }
}

implement {
    name      = "insertsoundclip",
    actions   = soundclips.insert,
    arguments = {
        {
            { "tag" },
            { "repeat" }
        }
    }
}

-- Renderings

function renderings.register(specification)
    if specification.label then
        renderings[specification.label] = specification
        return specification
    end
end

function renderings.rendering(label)
    local rn = renderings[label]
    if not rn then
        -- todo: message
        return renderings.register { label = label }
    else
        return rn
    end
end

function renderings.var(label,key)
    local rn = renderings[label]
    return rn and rn[key] or ""
end

implement {
    name      = "renderingvar",
    actions   = { renderings.var, context },
    arguments = "2 strings",
}

implement {
    name      = "registerrendering",
    actions   = renderings.register,
    arguments = {
        {
            { "type" },
            { "label" },
            { "mime" },
            { "filename" },
            { "option" },
        }
    }
}

-- Rendering:

implement {
    name      = "insertrenderingwindow",
    actions   = function(specification)
                    codeinjections.insertrenderingwindow(specification)
                end,
    arguments = {
        {
            { "label" },
            { "width", "dimen" },
            { "height", "dimen"  },
            { "option" },
            { "page", "integer" },
        }
    }
}

-- Linkedlists (only a context interface)

implement {
    name      = "definelinkedlist",
    arguments = "string",
    actions   = function(tag)
                    -- no need
                end
}

implement {
    name      = "enhancelinkedlist",
    arguments = { "string", "integer" },
    actions   = function(tag,n)
                    local ll = jobpasses.gettobesaved(tag)
                    if ll then
                        ll[n] = texgetcount("realpageno")
                    end
                end
}

implement {
    name      = "addlinklistelement",
    arguments = "string",
    actions   = function(tag)
                    local tobesaved   = jobpasses.gettobesaved(tag)
                    local collected   = jobpasses.getcollected(tag) or { }
                    local currentlink = #tobesaved + 1
                    local noflinks    = #collected
                    tobesaved[currentlink] = 0
                    local f = collected[1] or 0
                    local l = collected[noflinks] or 0
                    local p = collected[currentlink-1] or f
                    local n = collected[currentlink+1] or l
                    context.setlinkedlistproperties(currentlink,noflinks,f,p,n,l)
                 -- context.ctxlatelua(function() commands.enhancelinkedlist(tag,currentlink) end)
                end
}