lpdf-fix.lmt /size: 4911 b    last modification: 2025-02-21 11:03
1if not modules then modules = { } end modules ['lpdf-fix'] = {
2    version   = 1.001,
3    comment   = "companion to lpdf-ini.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 next, dofile = next, dofile
10local splitup = string.splitup
11
12-- see compactors-preset.lua for details
13
14local report = logs.reporter("graphics","compactors")
15
16do
17
18    local pdfbackend        = backends.registered.pdf
19    local codeinjections    = pdfbackend.codeinjections
20    local setmetatableindex = table.setmetatableindex
21
22    local compactors = setmetatableindex(function(t,prefix)
23        local c = nil
24        local n = "compactors-" .. prefix .. ".lua"
25        local f = resolvers.findfile(n) or ""
26        if f ~= "" then
27            c = table.load(f)
28            if c then
29                c = c.compactors
30                if c then
31                    for name, data in next, c do
32                        data.name = nil
33                        local strip = data.strip
34                        if not strip then
35                            data.strip = { marked = true }
36                        elseif strip.marked == nil then
37                            strip.marked = true
38                        end
39                        for tag, d in next, data do
40                            for k, v in next, d do
41                                if not v then
42                                    d[k] = nil
43                                end
44                            end
45                        end
46                        setmetatableindex(data,"table")
47                    end
48                    report("registered: %s : % | t",prefix,table.sortedkeys(c))
49                end
50            end
51        end
52        if not c then
53            report("unknown or invalid file: %s",n)
54            c = { }
55        end
56        t[prefix] = c
57        return c
58    end)
59
60    function codeinjections.validcompactor(name)
61        if name then
62            local prefix, name = splitup(name,":")
63            if not name then
64                prefix, name = "preset", prefix
65            end
66            local compactor = prefix and compactors[prefix][name] or false
67            if compactor then
68                if not compactor.status then
69                    compactor.status = { }
70                end
71                if not compactor.status.reported then
72                    report("using: %s : %s",prefix,name)
73                    compactor.status.reported = true
74                end
75            end
76            return compactor
77        end
78    end
79
80    function graphics.registerpdfcompactor(name,compactor)
81        if type(name )== "string" and type(compactor) == "table" then
82            local prefix, name = splitup(name,":")
83            if not name then
84                prefix, name = "preset", prefix
85            end
86            compactors[prefix][name] = compactor
87            setmetatableindex(compactor,"table")
88        end
89    end
90
91end
92
93do
94
95    local sequencers  = utilities.sequencers
96    local appendgroup = sequencers.appendgroup
97
98    local pdfcontentmanipulators = sequencers.new {
99        name      = "pdfcontentmanipulators",
100        arguments = "pdfdoc,page,pagenumber,resources,compactor",
101    }
102
103    appendgroup(pdfcontentmanipulators,"before")
104    appendgroup(pdfcontentmanipulators,"system")
105    appendgroup(pdfcontentmanipulators,"after" )
106
107    function lpdf.epdf.contentplugin(pdfdoc,page,pagenumber,resources,compactor)
108        local runner = pdfcontentmanipulators.runner
109        if runner then
110            runner(pdfdoc,page,pagenumber,resources,compactor)
111        end
112    end
113
114    -- todo: contents: table first time, concat last time .. automatic .. when
115    -- performance becomes an issue
116
117    local pdfpagemanipulators = sequencers.new {
118        name      = "pdfpagemanipulators",
119        arguments = "pdfdoc,page,pagenumber,resources,compactor",
120    }
121
122    appendgroup(pdfpagemanipulators,"before")
123    appendgroup(pdfpagemanipulators,"system")
124    appendgroup(pdfpagemanipulators,"after" )
125
126    sequencers.appendaction("pdfpagemanipulators","system","lpdf.epdf.contentplugin")
127    sequencers.enableaction("pdfpagemanipulators",         "lpdf.epdf.contentplugin")
128
129    local count = 0
130
131    function lpdf.epdf.pageplugin(pdfdoc,page,pagenumber,resources,compactor)
132        local runner = pdfpagemanipulators.runner
133        if runner then
134            count = count + 1
135            statistics.starttiming(pdfpagemanipulators)
136            runner(pdfdoc,page,pagenumber,resources,compactor)
137            statistics.stoptiming(pdfpagemanipulators)
138        end
139    end
140
141    statistics.register("pdf compacting", function()
142        if count > 0 then
143            return string.format("%s seconds for %s inclusions",statistics.elapsedtime(pdfpagemanipulators),count)
144        end
145    end)
146
147end
148