summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2024-01-08 21:47:22 +0000
committerKarl Berry <karl@freefriends.org>2024-01-08 21:47:22 +0000
commit218e823b3c691868564686239bf240745742eda6 (patch)
tree3f7ce282bd8fe2d756cafac2a4ce7467aa5f77a7 /Master/texmf-dist/tex/luatex
parent5cbbbf546da0983be4c134a518ea8da7f71ae963 (diff)
minim (8jan24)
git-svn-id: svn://tug.org/texlive/trunk@69352 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
-rw-r--r--Master/texmf-dist/tex/luatex/minim-math/minim-math.tex2
-rw-r--r--Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua340
-rw-r--r--Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty19
-rw-r--r--Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua135
-rw-r--r--Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex53
-rw-r--r--Master/texmf-dist/tex/luatex/minim-xmp/minim-xmp.lua6
-rw-r--r--Master/texmf-dist/tex/luatex/minim/minim-doc.sty36
-rw-r--r--Master/texmf-dist/tex/luatex/minim/minim-pdfresources.lua6
-rw-r--r--Master/texmf-dist/tex/luatex/minim/minim-pdfresources.tex1
9 files changed, 470 insertions, 128 deletions
diff --git a/Master/texmf-dist/tex/luatex/minim-math/minim-math.tex b/Master/texmf-dist/tex/luatex/minim-math/minim-math.tex
index 1a8f1157c11..7029952418a 100644
--- a/Master/texmf-dist/tex/luatex/minim-math/minim-math.tex
+++ b/Master/texmf-dist/tex/luatex/minim-math/minim-math.tex
@@ -468,6 +468,8 @@
\def\braket#1#2{\left⟨#1\middle\vert#2\right⟩}
\def\norm#1{\left\vert#1\right\vert} \let \abs=\norm
\def\Norm#1{\left\Vert#1\right\Vert}
+\def\ceil#1{\left⌈#1\right⌉}
+\def\floor#1{\left⌊#1\right⌋}
% a slightly smaller unary minus
\def\unaryminus{\mathord{\mathpalette\unaryminus:make{}}}
diff --git a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua
index f1cfd493887..9069ab7147e 100644
--- a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua
+++ b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua
@@ -4,7 +4,9 @@ local cb = require('minim-callbacks')
local pdfres = require('minim-pdfresources')
alloc.remember ('minim-mp')
-local M = {}
+local M = { } -- module contents
+local E = { } -- runscript environment
+local A = { } -- postprocessing functions
-- 1 AUXILIARY FUNCTIONS
@@ -29,7 +31,6 @@ end
-- We can call append:somefunction(...) to append a node or append:somevariable
-- to query the graphics state. These go via its metatable:
-local A = { } -- appending functions
local append_meta =
{
-- Either return an appending function or an entry in the graphics state.
@@ -48,6 +49,7 @@ local function init_append()
node_count = 0, -- node count
state = { }, -- graphics state variables
user = { }, -- user data for extensions
+ object_info = { }, -- data for current object
}, append_meta)
end
@@ -78,7 +80,8 @@ end
-- The following callback is executed just before the final step of surrounding
-- the image in properly-dimensioned boxes. It receives the processed image
--- object as argument. That object has the following fields:
+-- object as argument. That object may have the following fields (which can be
+-- changed):
-- head the head of the node list
-- name the image name
-- user the image user table
@@ -97,6 +100,7 @@ function M.enable_debugging()
pdf.setcompresslevel(0)
pdf.setobjcompresslevel(0)
end
+E.enable_debugging = M.enable_debugging
local function print_prop(append, obj, prop)
if obj[prop] then
@@ -179,7 +183,8 @@ end
local function format_numbers(...)
return (string.format(...)
:gsub('[.]0+ ', ' ')
- :gsub('([.][1-9]+)0+ ', '%1 '))
+ :gsub('([.][1-9]+)0+ ', '%1 ')
+ :gsub(' +$', ''))
end
-- Only to be used for coordinates: ‘cm’ parameters should not be rounded.
@@ -188,6 +193,12 @@ local function pdfnum(operator, ...)
return format_numbers(fmt, ...)
end
+local function make_pdf_dashpattern(dl)
+ return string.format('[%s] %s',
+ table.concat(dl.dashes or {},' '),
+ pdfnum('d', dl.offset))
+end
+
local function point_fmt(operator, ...)
local dd = pdf.getdecimaldigits()
local fmt = string.format('%%.%sf %%.%sf %s', dd, dd, operator)
@@ -212,6 +223,43 @@ function A.literal(append, fmt, ...)
append:node(lit)
end
+-- 2 parsing helpers
+
+local function parse_lua_table(name, str)
+ local f, msg = load('return '..str, name, 't')
+ if msg then return alloc.err(msg) end
+ t = f()
+ if not t or type(t) ~= 'table' then
+ return alloc.err('%s attributes must be given as lua table', name)
+ end
+ -- format all numbers with pdfnum
+ for k, v in pairs(t) do
+ if type(v) == 'number' then
+ t[k] = pdfnum('', v)
+ end
+ end
+ return t
+end
+
+-- 2 boxing helpers
+
+local function make_surrounding_box(nd_id, head)
+ local nd = node.new(nd_id)
+ nd.dir, nd.head = 'TLT', head
+ return nd
+end
+
+local function wrap_picture(head, x0, y0)
+ -- Note: this does not set the image dimensions
+ local horizontal = make_surrounding_box('hlist', head)
+ local vertical = make_surrounding_box('vlist', horizontal)
+ local outer = make_surrounding_box('hlist', vertical)
+ vertical.shift = -y0
+ horizontal.shift = x0
+ return outer
+end
+M.wrap_picture = wrap_picture
+
-- 2 colour conversion
local function rgb_to_gray (r,g,b)
@@ -219,6 +267,7 @@ local function rgb_to_gray (r,g,b)
+ tex.count['GtoG'] * g / 10000
+ tex.count['BtoG'] * b / 10000 )
end
+E.rgb_to_gray = rgb_to_gray
local function cmyk_to_rgb (c,m,y,k)
return (1-k)*(1-c), (1-k)*(1-m), (1-k)*(1-y)
@@ -283,7 +332,7 @@ local colour_fill_operators = { 'g', nil, 'rg', 'k' }
local colour_pattern_spaces = { 'PsG', nil, 'PsRG', 'PsK' }
local function get_colour_params(cr)
- return format_numbers(colour_template[#cr], table.unpack(cr))
+ return format_numbers(colour_template[#cr], table.unpack(cr)) .. ' '
end
local function get_stroke_colour(cr)
@@ -362,7 +411,7 @@ function A.linestate (append, object)
end
local dl = object.dash
if dl then
- local d = string.format('[%s] %s', table.concat(dl.dashes or {},' '), pdfnum('d', dl.offset))
+ local d = make_pdf_dashpattern(dl)
if d ~= append.dashed then
append.dashed = d
table.insert(res, d)
@@ -653,6 +702,105 @@ specials.BASELINE = function(append, _, object)
append.baseline = object.path[1].y_coord
end
+-- 2 box resources (xforms)
+
+-- The first problem that we run into is that we want to refer to xforms (from
+-- the metapost side) whose numerical id* we do know know yet (because the
+-- xform will only be made at the end of the run, during the lua-side
+-- processing of mplib output).
+--
+-- Our solution is using negative ids for metapost-defined xforms, which will
+-- be converted to actual boxresource ids by means of a conversion table.
+--
+-- The second problem is the need to position metapost-defined xforms by their
+-- original (metapost) origin. This necessitates storing extra information
+-- lua-side.
+--
+-- * Not to be confused with the object number which we, due to pdftex’s
+-- special handling of xforms, will never come to know.
+
+local xform_nr_shim = { }
+
+local function resolve_xform_id(nr)
+ nr = tonumber(nr)
+ if nr < 0 then
+ return xform_nr_shim[-nr]
+ else
+ return nr
+ end
+end
+
+local function reserve_xform_id()
+ xform_nr_shim[1+#xform_nr_shim] = false
+ return -#xform_nr_shim
+end
+
+M.resolve_xform_id = resolve_xform_id
+E.resolve_xform_id = resolve_xform_id
+E.reserve_xform_id = reserve_xform_id
+
+-- When using xforms in metapost, the positive numbers refer to tex-defined and
+-- the negative to metapost-defined box resources.
+
+specials.BOXRESOURCE = function(append, id, object)
+ local realid = resolve_xform_id(id)
+ local rule = tex.useboxresource(realid)
+ append:box(object, node.hpack(rule))
+end
+
+local xform_sizes = { }
+local xform_center = { }
+
+local function set_boxresource_dimensions (id, transf, center)
+ xform_sizes[id] = transf
+ xform_center[id] = center
+end
+
+local function get_boxresource_dimensions (id)
+ if xform_sizes[id] then
+ return xform_sizes[id]
+ else
+ return { 'box_size', tex.getboxresourcedimensions(id) }
+ end
+end
+
+local function get_boxresource_center (id)
+ if xform_center[id] then
+ return xform_center[id]
+ else
+ return "(0,0)"
+ end
+end
+
+E.set_boxresource_dimensions = set_boxresource_dimensions
+E.get_boxresource_dimensions = get_boxresource_dimensions
+E.get_boxresource_center = get_boxresource_center
+
+local function save_as_boxresource(pic)
+ -- attributes
+ local attrs = { '/Subtype/Form', bbox_fmt(0, -pic.dp, pic.wd, pic.ht) }
+ for k, v in pairs(pic.user.xform_attrs or { }) do
+ table.insert(attrs, string.format('%s %s', alloc.pdf_name(k), v))
+ end
+ -- box to-be-saved
+ local box = wrap_picture(node.copy_list(pic.head), pic.x0, pic.y0)
+ box.width, box.height, box.depth = pic.wd, pic.ht, pic.dp
+ -- save the box
+ local xform = tex.saveboxresource(box,
+ table.concat(attrs, ' '), nil, false, 4) -- 4: no /Type, /BBox or /Matrix
+ xform_nr_shim[-pic.user.xform_id] = xform
+end
+
+specials.XFORMINDEX = function(append, id, object)
+ append.user.xform_id = tonumber(id)
+ append.user.save_fn = save_as_boxresource
+end
+
+specials.XFORMATTRS = function(append, attrs, object)
+ local t = parse_lua_table('XForm attributes', attrs)
+ append.user.xform_attrs = t or { }
+end
+
-- 2 patterns
-- Saved patterns have the following fields:
@@ -678,27 +826,20 @@ prescripts.fillpattern = function(append, str, object)
end
end
-specials.definepattern = function(append, str, object)
- local nr, tiling, paint, xs, ys, xx, xy, yx, yy = table.unpack(str:explode())
- append.user.pattern_info = { nr = nr, xstep = xs, ystep = ys,
- tilingtype = tiling, painttype = paint,
- matrix = { xx = xx, xy = xy, yx = yx, yy = yy, x = 0, y = 0 } }
-end
-
local function make_pattern_xform(head, bb)
-- regrettably, pdf.refobj does not work with xforms, so we must
-- write it to the pdf immediately, whether the pattern will be
-- used or not.
- local xform = tex.saveboxresource(node.hpack(node.copy_list(head)),
- '/Subtype/Form '..bb, nil, true, 4)
+ local xform = tex.saveboxresource((node.hpack(node.copy_list(head))),
+ '/Subtype/Form '..bb, nil, true, 4) -- 4: no /Type, /BBox or /Matrix
return string.format(' /Resources << /XObject << /PTempl %d 0 R >> >>', xform), '/PTempl Do'
end
-local function definepattern(head, user, bbox)
- local bb = bbox_fmt(table.unpack(bbox))
+local function definepattern(pic)
+ local bb = bbox_fmt(table.unpack(pic.bbox))
local pat, literals, resources = { write = write_pattern_object }, { }
-- pattern content
- for n in node.traverse(head) do
+ for n in node.traverse(pic.head) do
-- try if we can construct the content stream ourselves; otherwise,
-- stuff the pattern template into an xform.
if n.id == WHATSIT_NODE then
@@ -710,18 +851,18 @@ local function definepattern(head, user, bbox)
elseif n.subtype == node.subtype 'restore' then
table.insert(literals, 'Q')
else
- resources, pat.stream = make_pattern_xform(head, bb)
+ resources, pat.stream = make_pattern_xform(pic.head, bb)
goto continue
end
else
- resources, pat.stream = make_pattern_xform(head, bb)
+ resources, pat.stream = make_pattern_xform(pic.head, bb)
goto continue
end
pat.stream = table.concat(literals, '\n')
end
::continue::
-- construct the pattern object
- local i = user.pattern_info
+ local i = pic.user.pattern_info
local m = i.matrix
pat.painttype = tonumber(i.painttype)
pat.attr = table.concat({
@@ -733,12 +874,88 @@ local function definepattern(head, user, bbox)
pdfres.add_resource('Pattern', 'MnmP'..i.nr, pat)
end
-cb.register('finish_mpfigure', function(img)
- if img.user.pattern_info then
- definepattern(img.head, img.user, img.bbox)
- img.discard = true
+specials.definepattern = function(append, str, object)
+ local nr, tiling, paint, xs, ys, xx, xy, yx, yy = table.unpack(str:explode())
+ append.user.pattern_info = { nr = nr, xstep = xs, ystep = ys,
+ tilingtype = tiling, painttype = paint,
+ matrix = { xx = xx, xy = xy, yx = yx, yy = yy, x = 0, y = 0 } }
+ append.user.save_fn = definepattern
+end
+
+-- 2 extgstates
+
+-- Specials for the graphics state:
+--
+-- gstate:save q
+-- gstate:restore Q
+--
+-- extgstate:label /label gs
+-- extgstate:{...} /newlabel gs
+--
+-- If a lua table is passed to the extgstate, minim will try and find an
+-- earlier-defined matching ExtGState object. If it cannot be found, a new one
+-- will be created and used. The values of the table will be written to the pdf
+-- as-they-are (this means booleans and numbers are alright), but the keys will
+-- be converted to pdf name objects.
+
+prescripts.gstate = function(append, str, object)
+ if str == 'save' or str == 'store' then
+ append:save()
+ elseif str == 'restore' then
+ append:restore()
+ else
+ alloc.err('Unknown gstate operator: »%s«', str)
end
-end)
+end
+postscripts.gstate = prescripts.gstate
+
+local gs_next, gs_index = 1, { }
+
+function M.get_gstate_name(t)
+ -- format the pdf dict
+ local d = { }
+ for k,v in pairs(t) do
+ if type(v) == 'table' and t.dashes then
+ v = '[ '..make_pdf_dashpattern(v)..' ]'
+ end
+ table.insert(d, string.format('%s %s', alloc.pdf_name(k), v))
+ end
+ table.sort(d)
+ d[0] = '<<'; table.insert(d, '>>')
+ t.value = table.concat(d, ' ', 0)
+ -- check the index
+ if not gs_index[t.value] then
+ local name = string.format('MnmGs%d', gs_next)
+ gs_index[t.value] = name
+ gs_next = gs_next + 1
+ pdfres.add_resource('ExtGState', name, t)
+ end
+ -- return the resource name
+ return gs_index[t.value]
+end
+
+prescripts.extgstate = function(append, str, object)
+ -- determine resource name
+ local name, t = str
+ if string.find(str, '^[A-Za-z0-9_]+$') then
+ t = pdfres.get_resource('ExtGState', name)
+ if not t then return alloc.err('Unknown named ExtGState: %s', name) end
+ else
+ t = parse_lua_table('ExtGState', str)
+ if not t then return end
+ name = M.get_gstate_name(t)
+ end
+-- -- update state parameters (disabled for now; may be enabled if it has practical use)
+-- if t.LW then append.linewidth = t.LW end
+-- if t.ML then append.miterlimit = t.LW end
+-- if t.LJ then append.linejoin = t.LW end
+-- if t.LC then append.linecap = t.LW end
+-- if t.D and type(t.D) == 'table' then append.dashed = make_pdf_dashpattern(t.D) end
+ -- apply the state change
+ append:literal('%s gs', alloc.pdf_name(name))
+ append:node(pdfres.use_resource_node('ExtGState', name))
+end
+postscripts.extgstate = prescripts.extgstate
-- 2 text
@@ -758,26 +975,13 @@ local function get_transform(rect)
return sx, rx, ry, sy, tx, ty
end
-local function make_surrounding_box(nd_id, head)
- local nd = node.new(nd_id)
- nd.dir, nd.head = 'TLT', head
- return nd
-end
-
-local function wrap_picture(head, tx, ty)
- local horizontal = make_surrounding_box('hlist', head)
- local vertical = make_surrounding_box('vlist', horizontal)
- local outer = make_surrounding_box('hlist', vertical)
- vertical.shift = tex.sp('-'..ty..'bp')
- horizontal.shift = tex.sp(''..tx..'bp')
- return outer
-end
-
local function apply_transform(rect, box)
local sx, rx, ry, sy, tx, ty = get_transform(rect)
local transform = node.new('whatsit', 'pdf_setmatrix')
transform.next, box.prev = box, transform
transform.data = string.format('%f %f %f %f', sx, rx, ry, sy)
+ tx = tex.sp(''..tx..'bp')
+ ty = tex.sp(''..ty..'bp')
return wrap_picture(transform, tx, ty)
end
@@ -803,11 +1007,6 @@ specials.CHAR = function(append, data, object)
append:box(object, node.hpack(n))
end
-specials.BOXRESOURCE = function(append, resource, object)
- local rule = tex.useboxresource(tonumber(resource))
- append:box(object, rule)
-end
-
--
-- 1 METAPOST INSTANCES
@@ -935,8 +1134,12 @@ local function process_results(nr, res)
pic.y0 = tex.sp(string.format('%s bp', -bas ))
end
cb.call_callback('finish_mpfigure', pic)
+ if pic.user.save_fn then
+ pic.discard = true
+ pic.user.save_fn(pic)
+ end
if not pic.discard then
- pic.head = wrap_picture(append.head, -llx, -bas)
+ pic.head = wrap_picture(pic.head, pic.x0, pic.y0)
end
if debugging then
alloc.msg('┌ image %s, with %s objects, %s nodes',
@@ -967,11 +1170,11 @@ end
-- a string that metapost can understand.
--
-- Tables of the form { 'box_size', width, height, depth, margin } are
--- converted to a transformation. (The margin will be ignored for now, this may
+-- converted to a transform. (The margin will be ignored for now, this may
-- change in the future.)
local function mkluastring(s)
- return "'"..(s:gsub('\\', '\\\\'):gsub("'", "\\'")).."'"
+ return "'"..(s:gsub('\\', '\\\\'):gsub("'", "\\'"):gsub('\n', '\\n')).."'"
end
local function runscript(code)
@@ -991,15 +1194,22 @@ local function runscript(code)
return string.format('%.16f', result)
elseif t == 'string' then
return result
- elseif t == 'table' and t[1] == 'box_size' then
- -- TODO: take the margin into account if present (t[5])?
- return make_transform(t[2], t[3], t[4])
- elseif t == 'table' and #t < 5 then
- local fmt = #t == 1 and '%.16f'
- or #t == 2 and '(%.16f, %.16f)'
- or #t == 3 and '(%.16f, %.16f, %.16f)'
- or #t == 4 and '(%.16f, %.16f, %.16f, %.16f)'
- return fmt:format(table.unpack(t))
+ elseif t == 'table' and result[1] == 'box_size' then
+ return make_transform(result[2], result[3], result[4])
+ elseif t == 'table' and #result < 5 then
+ local fmt = #result == 1 and '%.16f'
+ or #result == 2 and '(%.16f, %.16f)'
+ or #result == 3 and '(%.16f, %.16f, %.16f)'
+ or #result == 4 and '(%.16f, %.16f, %.16f, %.16f)'
+ return fmt:format(table.unpack(result))
+ elseif t == 'table' and #result == 6 then
+ return table.concat({
+ 'begingroup save t; transform t;',
+ 'xxpart t = %.16f', 'xypart t = %.16f',
+ 'yxpart t = %.16f', 'yypart t = %.16f',
+ 'xpart t = %.16f', 'ypart t = %.16f',
+ 't endgroup' },
+ ';'):format(table.unpack(result))
else
return tostring(result)
end
@@ -1016,8 +1226,8 @@ end
-- environment. The runscript environment will then be extended with all
-- elements of the M.mp_functions table.
-local E = { }
M.mp_functions = E
+E.texmessage = alloc.msg
local function prepare_env(e) -- in M.open()
local env = e or copy_table(_G, { })
@@ -1038,9 +1248,6 @@ function E.quote_for_lua(s)
return E.quote(mkluastring(s))
end
-E.rgb_to_gray = rgb_to_gray
-E.enable_debugging = M.enable_debugging
-
-- 2 typesetting with tex
-- The result of the maketext function is fed back into metapost; on that side,
@@ -1065,9 +1272,8 @@ local function maketext(text, mode)
local assignment = string.format('\\global\\setbox%s=\\hbox{\\the\\everymaketext %s}', nr, text)
tex.runtoks(function() tex.print(current_instance.catcodes, assignment:explode('\n')) end)
local box = tex.box[nr]
- return 'image ( fill unitsquare withprescript "TEXBOX:' ..nr..'";'..
- 'setbounds currentpicture to unitsquare transformed '..
- make_transform(box.width, box.height, box.depth) .. ';)'
+ return string.format('_set_maketext_result_(%d, %s)', nr,
+ make_transform(box.width, box.height, box.depth))
elseif mode == 1 then -- verbatimtex
tex.runtoks(function() tex.print(current_instance.catcodes, text:explode('\n')) end)
end
@@ -1311,7 +1517,7 @@ end
function M.get_image(nr, name)
local image = retrieve(nr, name)
if image then
- local box = node.hpack(image.head)
+ local box = image.head
box.width = image.wd
box.height = image.ht
box.depth = image.dp
@@ -1329,7 +1535,7 @@ function M.shipout(nr)
tex.pageheight = (image.ht + image.dp)
tex.pagewidth = image.wd
tex.voffset = image.ht
- tex.box[255] = node.vpack(node.hpack(image.head))
+ tex.box[255] = image.head
tex.shipout(255)
tex.count[0] = tex.count[0] + 1
end
diff --git a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty
index ae0312b5609..250e86668e0 100644
--- a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty
+++ b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty
@@ -3,10 +3,6 @@
\input minim-mp
-\makeatletter
-
-\RequirePackage{environ}
-
% work around latex’s \protect mechanism
\let\mnm@protect=\protect
\everymaketext{\let\protect=\mnm@protect}
@@ -21,12 +17,12 @@
\let\mpcolor = \minimpcolor
\csname:metapost:\endcsname[#1]}
{\csname end:metapost:\endcsname \endgroup}
-\NewEnviron{:metapost:}[1][]{%
+\NewDocumentEnvironment{:metapost:}{O{}+b}{%
\mnm@setnormalfont
\let\protect=\noexpand
\directmetapost[#1]{%
- defaultfont:="\mnm@normalfont"; \BODY; }%
- \let\protect=\mnm@protect}
+ defaultfont:="\mnm@normalfont"; #2; }%
+ \let\protect=\mnm@protect}{}
% separate metapost instances
\newcommand\newmetapostenvironment[2][]{%
@@ -37,13 +33,13 @@
\let\mpcolor = \minimpcolor
\csname:#2:\endcsname}
{\csname end:#2:\endcsname \endgroup}%
- \NewEnviron{:#2:}{%
+ \NewDocumentEnvironment{:#2:}{+b}{%
\mnm@setnormalfont
\let\protect=\noexpand
\runmetapostimage
\csname #2@instance\endcsname
- {defaultfont:="\mnm@normalfont";\BODY;}%
- \let\protect=\mnm@protect}}
+ {defaultfont:="\mnm@normalfont";##1;}%
+ \let\protect=\mnm@protect}{}}
% \mpcolor support
\def\minimpcolor#1#{\dominimpcolor{#1}}
@@ -54,6 +50,3 @@
\newtoks\mpcolorspectoks \newtoks\mpcolorruntoks \newtoks\mpcolorvaltoks
\mpcolorruntoks{\expandafter\extractcolorspec\the\mpcolorspectoks\mptmpcolor
\expandafter\mpcolorvaltoks\expandafter\@gobble\mptmpcolor}
-
-\makeatother
-
diff --git a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua
index 74d56eeaac2..875fd896592 100644
--- a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua
+++ b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua
@@ -7,9 +7,11 @@ alloc.remember('minim-pdf')
-- 1 helper functions
+local HLIST_NODE = node.id 'hlist'
local GLUE_NODE = node.id 'glue'
local GLYPH_NODE = node.id 'glyph'
local RULE_NODE = node.id 'rule'
+local DISC_NODE = node.id 'disc'
local WHATSIT_NODE = node.id 'whatsit'
local USER_DEFINED = node.subtype 'user_defined'
local START_LINK = node.subtype 'pdf_start_link'
@@ -51,9 +53,8 @@ local function singleton(t)
return one
end
--- in-depth node list traversal
--- returns current and parent node
--- only dives into hbox, vbox and ins nodes
+-- in-depth node list traversal; returns current and parent node
+-- only dives into hbox, vbox and ins nodes, and in disc no-break text
-- returns node and enclosing box
local function full_traverse(head)
return function(stack, last)
@@ -178,7 +179,7 @@ local structure_types = alloc.saved_table('structure types', {
-- inline structure elements ILSE
Span = { type = 'inline' },
Quote = { type = 'inline' },
- Note = { type = 'inline' },
+ Note = { type = 'extern' },
Reference = { type = 'inline' },
BibEntry = { type = 'inline' },
Code = { type = 'inline', attributes = { ['CSS-2.00'] = { ['white-space'] = '(pre)' } } },
@@ -198,9 +199,10 @@ local structure_type_compatibility = {
none = { none=1, section=1, group=1, block=1, inline=1, contain=1 },
section = { none=1, section=1, group=1, block=1 },
group = { none=1, group=1, block=1 },
- block = { none=1, inline=1 },
- inline = { none=1, inline=1 },
- contain = { none=1, inline=1, block=1, group=1 },
+ extern = { none=1, group=1, block=1 },
+ block = { none=1, inline=1, extern=1 },
+ inline = { none=1, inline=1, extern=1 },
+ contain = { none=1, inline=1, block=1, group=1, extern=1 },
}
local function check_structure_compatibility(parent, child, childtype)
@@ -354,10 +356,19 @@ local function write_structure()
local id_tree, id_tree_obj = { }, pdf.reserveobj()
structure[1].parent = { objnum = root_obj }
for _, se in ipairs(structure) do
- if not se.hidden then se.objnum = pdf.reserveobj() end
+ if not se.hidden then
+ se.objnum = pdf.reserveobj()
+ if se.id then
+ id_tree[se.id] = se.objnum
+ end
+ end
end
-- update the document catalog
- add_to_catalog('/MarkInfo << /Marked true >>')
+ if tex.count['pdfuaconformancelevel'] > 0 then
+ add_to_catalog('/MarkInfo << /Marked true /Suspects false >>')
+ else
+ add_to_catalog('/MarkInfo << /Marked true >>')
+ end
add_to_catalog('/StructTreeRoot %s 0 R', root_obj)
-- write the structure tree root
pdf.immediateobj(root_obj, string.format(
@@ -368,10 +379,11 @@ local function write_structure()
if not se.hidden then
local res = { '<<' }
insert_formatted(res, '/Type/StructElem /S%s /P %d 0 R', pdf_name(se.struct), se.parent.objnum)
- if se.id then id_tree[se.id] = se.objnum; insert_formatted(res, '/ID %s', pdf_string(se.id)) end
- if se.lang and se.lang ~= se.parent.lang then insert_formatted(res, '/Lang (%s)', se.lang) end
+ if se.id then insert_formatted(res, '/ID %s', pdf_string(se.id)) end
+ if se.lang and se.lang ~= se.parent.lang then insert_formatted(res, '/Lang %s', pdf_string(se.lang)) end
if se.alt then insert_formatted(res, '/Alt %s', pdf_string(se.alt)) end
if se.actual then insert_formatted(res, '/ActualText %s', pdf_string(se.actual)) end
+ if se.title then insert_formatted(res, '/T %s', pdf_string(se.title)) end
if #se.children > 0 then insert_formatted(res, '\n/K %s', format_K_array(se)) end
if se.mainpage then insert_formatted(res, '/Pg %d 0 R', se.mainpage) end
if se.class then
@@ -382,6 +394,19 @@ local function write_structure()
end
if #se.class > 1 then table.insert(res, ']') end
end
+ if se.ref then
+ table.insert(res, '/Ref')
+ table.insert(res, '[')
+ for _, c in ipairs(se.ref) do
+ local onum = id_tree[c]
+ if onum then
+ insert_formatted(res, '%d 0 R', onum)
+ else
+ alloc.err('Invalid structure element ID: %s', c)
+ end
+ end
+ table.insert(res, ']')
+ end
if not is_empty(se.attributes) then
table.insert(res, '/A')
make_attributes(res, se.attributes)
@@ -481,7 +506,7 @@ cb.register('uselanguage', function(name)
end)
local function write_language()
- add_to_catalog('/Lang (%s)', structure[1].lang or 'und')
+ add_to_catalog('/Lang %s', pdf_string(structure[1].lang or 'und'))
end
-- 1 marking structure elements
@@ -559,9 +584,11 @@ end
alloc.luadef('tagging:startelement', function()
local s = options_scanner()
:string('id')
+ :string('ref', true)
:string('type') -- 'section', 'group', 'block' etc.
:argument('alt')
:argument('actual')
+ :argument('title')
:string('lang')
:subtable('attr')
:string('class', true)
@@ -736,7 +763,7 @@ function M.mark_content_items(box)
elseif marker and marker.what == 'mci_stop' then
end_node = end_node and n; insert_tags(b)
-- finally, see if we need to intervene between content nodes
- elseif n.id == RULE_NODE or n.id == GLYPH_NODE
+ elseif n.id == RULE_NODE or n.id == GLYPH_NODE or n.id == DISC_NODE
or marker and marker.what == 'content' then
local _se, _order = n[current_struct], n[current_order]
if n.id == RULE_NODE and (n.width == 0 or n.height == 0 and n.depth == 0) then
@@ -768,7 +795,7 @@ cb.register('pre_shipout', function(nr)
end
end)
--- 1 destinations
+-- 1 links and destinations
local dest_count = alloc.new_count('link dest count')
local function new_dest_name()
@@ -791,7 +818,41 @@ end
alloc.luadef('newdestinationname', function() tex.sprint(new_dest_name()) end)
alloc.luadef('lastdestinationname', function() tex.sprint(last_dest_name()) end)
--- 1 bookmarks
+-- provide the arguments to \pdfextension startlink
+local link_types = { }
+alloc.luadef('hyper:makelink', function()
+ local s = options_scanner()
+ :argument('alt'):argument('contents') -- same thing
+ :argument('attr')
+ :scan()
+ local type = token.scan_word()
+ local userf = link_types[type]
+ if not userf then
+ alloc.err('Unknown hyperlink type: %s', type)
+ userf = link_types.first
+ end
+ local user = userf()
+ attr = { 'attr {\\csname minim:linkattr\\endcsname' }
+ if s.attr then table.insert(attr, s.attr) end
+ if s.alt or s.contents then insert_formatted(attr, '/Contents %s', pdf_string(s.alt or s.contents)) end
+ insert_formatted(attr, '} user {%s}', user)
+ tex.sprint(table.concat(attr, ' '))
+end)
+
+function link_types.dest()
+ return string.format('/Subtype/Link /A <</S/GoTo /D %s>>', pdf_string(token.scan_argument()))
+end
+function link_types.url()
+ return string.format('/Subtype/Link /A <</S/URI /URI %s>>', pdf_string(token.scan_argument()))
+end
+
+function link_types.user() return token.scan_argument() end
+function link_types.next() return '/Subtype/Link /A <</S/Named /N/NextPage>>' end
+function link_types.prev() return '/Subtype/Link /A <</S/Named /N/PrevPage>>' end
+function link_types.first() return '/Subtype/Link /A <</S/Named /N/FirstPage>>' end
+function link_types.last() return '/Subtype/Link /A <</S/Named /N/LastPage>>' end
+
+-- 1 bookmarks (outlines)
-- start with a dummy top-level bookmark
local bookmarks = { { count = 0 } }
@@ -811,8 +872,8 @@ local function write_bookmarks()
-- write bookmark objects
for i=2, #bookmarks do
local bm, res = bookmarks[i], { }
- insert_formatted(res, '<< /Title %s\n/Parent %s 0 R /Dest (%s)', pdf_string(bm.title),
- bm.parent and bm.parent.outline_obj or bookmarks[1].outline_obj, bm.dest)
+ insert_formatted(res, '<< /Title %s\n/Parent %s 0 R /Dest %s', pdf_string(bm.title),
+ bm.parent and bm.parent.outline_obj or bookmarks[1].outline_obj, pdf_string(bm.dest))
if bm.next then insert_formatted(res, '/Next %s 0 R', bm.next.outline_obj) end
if bm.prev then insert_formatted(res, '/Prev %s 0 R', bm.prev.outline_obj) end
if bm.struct and bm.struct.objnum then
@@ -945,13 +1006,13 @@ end, 'protected')
function M.mark_discretionaries(head, gc)
if not spaces_enabled() then return end
- for disc in node.traverse_id(7, head) do
+ for disc in node.traverse_id(DISC_NODE, head) do
if disc.subtype ~= 2 then -- ‘automatic’ (exclude explicit hyphens)
local pre, post, replace = disc.pre, disc.post, disc.replace
local se, order = disc[current_struct], disc[current_order]
-- get the replacement text
local actual = { }
- for c in node.traverse_id(29, replace) do
+ for c in node.traverse_id(GLYPH_NODE, replace) do
table.insert(actual, c.char)
end
-- special case: a single hyphen
@@ -982,7 +1043,7 @@ local space_attr = alloc.new_attribute('space insertion marker')
function M.mark_spaces(head, gc)
if not spaces_enabled() then return end
- for g in node.traverse_id(12, head) do -- glue
+ for g in node.traverse_id(GLUE_NODE, head) do
if g.prev and g.subtype == 13 or g.subtype == 14 then -- (x)spaceskip
local p = g.prev
p[space_attr] = p.id == GLYPH_NODE and p.font
@@ -1011,7 +1072,7 @@ end
function M.insert_spaces(head, gc)
if not spaces_enabled() then return end
- for line in node.traverse_id(0, head) do
+ for line in node.traverse_id(HLIST_NODE, head) do
insert_spaces(line.head)
end
return true
@@ -1085,10 +1146,10 @@ local function write_output_intents()
attr = string.format('/N %d', oi.N),
immediate = true }
insert_formatted(res, '<< /Type/OutputIntent /DestOutputProfile %d 0 R', p)
- insert_formatted(res, '/S/%s /OutputConditionIdentifier (%s)', oi.subtype, oi.id)
- if oi.info then insert_formatted(res, '/Info (%s)', oi.info) end
- if oi.condition then insert_formatted(res, '/OutputCondition (%s)', oi.condition) end
- if oi.registry then insert_formatted(res, '/RegistryName (%s)', oi.registry) end
+ insert_formatted(res, '/S/%s /OutputConditionIdentifier %s', oi.subtype, pdf_string(oi.id))
+ if oi.info then insert_formatted(res, '/Info %s', pdf_string(oi.info)) end
+ if oi.condition then insert_formatted(res, '/OutputCondition %s', pdf_string(oi.condition)) end
+ if oi.registry then insert_formatted(res, '/RegistryName %s', pdf_string(oi.registry)) end
table.insert(res, '>>')
end
table.insert(res, ']')
@@ -1121,9 +1182,31 @@ end
alloc.luadef('minim:default:rgb:profile', function() M.add_default_rgb_output_intent() end)
alloc.luadef('minim:default:cmyk:profile', function() M.add_default_cmyk_output_intent() end)
+-- 1 pdf/ua
+
+alloc.luadef('tagging:enablepdfua', function()
+ add_to_catalog('/ViewerPreferences << /DisplayDocTitle true >>')
+ local pageattr = pdf.getpageattributes()
+ if pageattr then
+ pdf.setpageattributes(pageattr .. ' /Tabs /S')
+ else
+ pdf.setpageattributes('/Tabs /S')
+ end
+end)
+
+local function perform_pdfua_checks()
+ local xmp = require 'minim-xmp'
+ if xmp.get_metadata('dc:title') == '' then
+ alloc.err('PDF/UA error: no dc:title metadata')
+ end
+end
+
--
-cb.register ('finish_pdffile', function()
+cb.register('finish_pdffile', function()
+ if tex.count['pdfuaconformancelevel'] > 0 then
+ perform_pdfua_checks()
+ end
if tagging_enabled() then
write_language()
write_structure()
diff --git a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex
index d8b06255bab..8a5f738063f 100644
--- a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex
+++ b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex
@@ -167,8 +167,8 @@
\newcount\tagging:tablecolspan \tagging:tablecolspan 1
\newcount\tagging:tablerowspan \tagging:tablerowspan 1
\newcount\tagging:i
-\def\tagging:TH{TH}
-\def\tagging:TD{TD}
+\def\tagging:TH{{TH}\markcolumnhead}
+\def\tagging:TD{{TD}}
% initialising variables
\def\marktable{\startelement{Table}%
\global\advance\tagging:tablec1
@@ -205,7 +205,7 @@
\def\marktablecell{%
\global\advance\tagging:tablecol1
\continueelementfrom\tagging:row
- \startelement{\tagging:cell}%
+ \expandafter\startelement\tagging:cell%
\tagging:assignheaders}
% spans
@@ -301,13 +301,27 @@
\def\marktocentry#1#2#3#4#5{%
\ifx\marktocentry#1\marktocentry
\def\marktocentry:link##1{##1}\else
- \def\marktocentry:link##1{\hyperlink dest{#1}##1\endlink}\fi
+ \def\marktocentry:link##1{\hyperlink
+ alt{\csname minim:str:page\endcsname#5}
+ dest{#1}##1\endlink}\fi
\markelement{TOCI}{\nextpartag{}\quitvmode
\ifx\marktocentry#2\marktocentry\else
\markelement{Lbl}{\marktocentry:link{#2}}\fi
\markelement{Reference}{\marktocentry:link{#3%
\ifx\marktocentry#4\marktocentry\else
\markartifact{Layout}{#4}\fi#5}}}}
+\def\minim:str:page{Page }
+
+% \marknoteref {*}
+\def\marknoteref#1{%
+ \startelement ref{\newdestinationname}{Reference}%
+ {\stopformulatagging#1}\stopelement{Reference}}
+% \marknotelbl {*}
+\def\marknotelbl#1{%
+ \startelement id{\lastdestinationname}{Note}%
+ \aftergroup\tagging:ensurestopNote
+ \markelement{Lbl}{{\stopformulatagging#1}}}
+\def\tagging:ensurestopNote{\ensurestopelement{Note}}
% 1 tagging formulas
@@ -351,7 +365,7 @@
\def\formulasource:set#1{%
\begingroup
% strip \setalttext, \setactualtext
- \def\setalttext#1{}\def\setactualtext#1{}%
+ \def\setalttext##1{}\def\setactualtext##1{}%
\xdef\formulasource:thesource{#1}%
\endgroup
\expandafter\splitcommalist
@@ -370,6 +384,7 @@
relation Source desc {Equation source}
name {\formulafilename.tex}
string {\tagging:formulasource{#1}}\fi}
+\def\formulasource:none#1{}
\newtoks\includeformulasources
\includeformulasources{actualtext,attachment}
@@ -390,17 +405,18 @@
\def\linkdest:h#1{\vadjust pre{\linkdest:v{#1}}}
\def\linkdest:v#1{\pdfextension dest name {#1} xyz\nobreak}
-% \hyperlink dest {name} ... \endlink
-% \hyperlink url {url} ... \endlink
+% \hyperlink <args> ... \endlink
+% args: alt {...} attr {...} <type>
+% type: dest {name} | url {url} | next | prev | first | last
\protected\def\endlink{\pdfextension endlink\stopelement{Link}\relax}
\protected\def\startlink{\startelement{Link}\pdfextension startlink}
-\def\hyperlink#1#{\quitvmode\hyperlink:rmspace#1 \hyperlink:rmspace}
-\def\hyperlink:rmspace#1 #2\hyperlink:rmspace{%
- \startlink attr {\minim:linkattr}%
- \csname hyperlink:#1\endcsname}
-\def\hyperlink:dest#1{user {/Subtype/Link /F 4 /A <</S/GoTo /D (#1)>>}}
-\def\hyperlink:url#1{user {/Subtype/Link /F 4 /A <</S/URI /URI (#1)>>}}
-\def\minim:linkattr{/Border [0 0 0]}
+\protected\def\hyperlink{\quitvmode\startlink\hyper:makelink}
+
+% \hyperlinkstyle { ... }
+\def\minim:linkattr{\the\hyperlinkstyle\the\minim:pdfalinkattr}
+\newtoks\hyperlinkstyle
+\newtoks\minim:pdfalinkattr
+\hyperlinkstyle{/Border [0 0 0]}
% 1 languages
@@ -449,9 +465,12 @@
\newcount \pdfaconformancelevel
\pdfaconformancelevel = 0
+\newcount \pdfuaconformancelevel
+\pdfuaconformancelevel = 0
% \pdfalevel 2b
\def\pdfalevel#1#2{%
+ \minim:pdfalinkattr{ /F 4}% hyperlinks must be printed
\global\pdfaconformancelevel=#1\relax
\ifcsname minim:pdfa:#1#2\endcsname \lastnamedcs\else
\errmessage{Unknown pdf/a standard pdf/a-#1}\fi}
@@ -474,6 +493,12 @@
\expandafter\def\csname minim:pdfa:3b\endcsname{\minim:pdfasettings 7B3}
\expandafter\def\csname minim:pdfa:3u\endcsname{\minim:pdfasettings 7U3}
+% \pdfualavel 1
+\def\pdfualevel{\input minim-xmp
+ \setmetadata pdfuaid:part {1}
+ \tagging:enablepdfua
+ \global\pdfuaconformancelevel= }
+
% 
\catcode`\: = \minimpdfloaded
diff --git a/Master/texmf-dist/tex/luatex/minim-xmp/minim-xmp.lua b/Master/texmf-dist/tex/luatex/minim-xmp/minim-xmp.lua
index d6867a4c9bf..e3b7a8de70c 100644
--- a/Master/texmf-dist/tex/luatex/minim-xmp/minim-xmp.lua
+++ b/Master/texmf-dist/tex/luatex/minim-xmp/minim-xmp.lua
@@ -158,6 +158,12 @@ M.add_namespace('PDF/A Identification', 'pdfaid', 'http://www.aiim.org/pdfa/ns/i
part = { 'Integer', 'Version identifier', true },
}, nil, true)
+M.add_namespace('PDF/UA Identification', 'pdfuaid', 'http://www.aiim.org/pdfua/ns/id/', {
+ amd = { 'Text', 'Amendment identifier', true },
+ corr = { 'Text', 'Corrigendum identifier', true },
+ part = { 'Integer', 'Version identifier', true },
+})
+
M.add_namespace('Dublin Core', 'dc', 'http://purl.org/dc/elements/1.1/', {
contributor = { 'Bag ProperName', 'Other contributors' },
coverage = { 'Text', 'Extent or scope' },
diff --git a/Master/texmf-dist/tex/luatex/minim/minim-doc.sty b/Master/texmf-dist/tex/luatex/minim/minim-doc.sty
index 97b173beac0..93d807f16a3 100644
--- a/Master/texmf-dist/tex/luatex/minim/minim-doc.sty
+++ b/Master/texmf-dist/tex/luatex/minim/minim-doc.sty
@@ -9,6 +9,7 @@
%\decompressedpdf
\pdfalevel 3a
+\pdfualevel 1
\overfullrule = 0pt
% 1 page layout
@@ -124,8 +125,22 @@ endfig;}
% page artifacts
\edef\tmp{\markartifact{Pagination /Subtype/Footer}{\the\footline}}
\footline\expandafter{\tmp}
-\def\footnoterule{\markartifact{Layout}{\kern-3\p@
- \hrule width 2truein \kern 2.6\p@}} % the \hrule is .4pt high
+
+% footnotes
+\edef\footnoterule{\markartifact{Layout}\footnoterule}
+\catcode`\@=11
+\def\footnote#1{\let\@sf\empty % parameter #2 (the text) is read later
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi
+ \marknoteref{#1}\@sf\vfootnote{#1}}
+\def\vfootnote#1{%
+ \insert\footins\bgroup
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox \floatingpenalty\@MM
+ \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip
+ \nextpartag{}\marknotelbl{#1}\enspace\startelement{P}%
+ \footstrut\futurelet\next\fo@t}
+\catcode`\@=12
% \startlist \item x. ... \stoplist
\def\listskip{\vskip 3pt plus 2pt\vskip-\parskip}
@@ -141,22 +156,26 @@ endfig;}
\protected\def\chapter#1 \par{%
\vfil\break
\ensurestopelement{Section}%
- \startelement{Chapter}%
+ \global\advance\chapterno1 \global\sectionno0
+ \startelement title{Chapter \the\chapterno}{Chapter}%
\outline open {#1}%
\addtotoc{\chapter{#1}{\lastdestinationname}}%
\nextpartag{H}\quitvmode
\red{\Title#1\hfill\copy\notehead}\bigskip\nobreak}
+\newcount \chapterno
% \section Title \par
\addstructuretype Sect Section
\protected\def\section#1 \par{%
\bigskip\penalty-50\relax
- \startelement{Section}%
+ \global\advance\sectionno1
+ \startelement title{Section \the\chapterno.\the\sectionno}{Section}%
\outline closed {#1}%
\addtotoc{\section{#1}{\lastdestinationname}}%
\nextpartag{H}\quitvmode
\red{\title#1}%
\par\nobreak}
+\newcount \sectionno
% table of contents
\newtoks\toc \newif\iftoc \toctrue
@@ -186,7 +205,9 @@ endfig;}
\tocfalse \chapter \getmetadata title
\hfill \tenrm version \getmetadata version
\par\endgroup
- \marktableaslist \halign {\strut
+ \marktableaslist
+ \tagattribute List ListNumbering /None
+ \halign {\strut
\qquad##\quad&##\hfil\cr
author&\getmetadata author\cr
contact&{\def\tmp{@}\def\TMP{.}%
@@ -207,8 +228,9 @@ Licence (EUPL) version 1.2 or later. An english version of this licence has
been included as an attachment to this file; copies in other languages can be
obtained at
\stopformulatagging$$\hbox
-{\hyperlink url {https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12}%
-https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\endlink}$$\startformulatagging}
+{\hyperlink alt{Link to the website of the EUPL.}
+ url {https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12}%
+ https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12\endlink}$$\startformulatagging}
% for identifying which file we are typesetting
\edef\thejobname{\expandafter\scantextokens\expandafter{\jobname}}
diff --git a/Master/texmf-dist/tex/luatex/minim/minim-pdfresources.lua b/Master/texmf-dist/tex/luatex/minim/minim-pdfresources.lua
index e6a06e783e1..468da03b485 100644
--- a/Master/texmf-dist/tex/luatex/minim/minim-pdfresources.lua
+++ b/Master/texmf-dist/tex/luatex/minim/minim-pdfresources.lua
@@ -50,7 +50,7 @@ function M.use_resource(kind, name)
return res._entry_
end
--- global resources are mainly for pgf compatibility: contains adds entries to
+-- global resources are mainly for pgf compatibility: it contains entries to
-- the resource dictionaries that will be added for every page.
--
local global_resources = init_resources() -- name ↦ '/Key <value>'
@@ -87,6 +87,10 @@ function M.use_resource_node(kind, name)
return n
end
+alloc.luadef('withpdfresource', function()
+ node.write(M.use_resource_node(token.scan_string(), token.scan_string()))
+end, 'protected')
+
-- construction and caching of resource dictionaries.
--
local previous_dicts = init_resources() -- pdf dict ↦ objnum
diff --git a/Master/texmf-dist/tex/luatex/minim/minim-pdfresources.tex b/Master/texmf-dist/tex/luatex/minim/minim-pdfresources.tex
index 6b8dc29577f..57e9d8f012f 100644
--- a/Master/texmf-dist/tex/luatex/minim/minim-pdfresources.tex
+++ b/Master/texmf-dist/tex/luatex/minim/minim-pdfresources.tex
@@ -13,6 +13,7 @@
% 1 pgf compatibility
% this ballet inserts our fix directly at the end of pgfsys-luatex.def
+% (see the \ProvidesFile redefinition in minim-alloc.tex)
\expandafter\def\csname minim:intercept:pgfsys-luatex.def\endcsname
{\wlog{minim: applying pgf patches...}\newtoks\minim:pgf:fix:toks
\minim:pgf:fix:toks\csname pgfutil@everybye\endcsname