summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/minim-pdf
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2024-03-01 21:45:43 +0000
committerKarl Berry <karl@freefriends.org>2024-03-01 21:45:43 +0000
commitedfd6ab3ed7259f3284e48f303725e60a2b96cbe (patch)
tree9bac560cb75a117c116b14c85673edbd08b0b10b /Master/texmf-dist/tex/luatex/minim-pdf
parent78106bb24e28f74747fe222a8ecfe7e77dd0d1f0 (diff)
minim-pdf (1mar24)
git-svn-id: svn://tug.org/texlive/trunk@70311 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/minim-pdf')
-rw-r--r--Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua103
-rw-r--r--Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex80
2 files changed, 151 insertions, 32 deletions
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 875fd896592..101a548e4b5 100644
--- a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua
+++ b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua
@@ -229,7 +229,13 @@ local function determine_parent_node(current, se)
end
end
if not c then
- alloc.err('Structure type mismatch: %s in %s', se.struct, current.struct)
+ if tagging_enabled() then
+ alloc.err('Structure type mismatch: %s in %s',
+ pdf_name(se.struct), pdf_name(current.struct))
+ else
+ alloc.msg('Warning (minim-pdf): Structure type mismatch (%s in %s)',
+ pdf_name(se.struct), pdf_name(current.struct))
+ end
end
return c or current
end
@@ -820,6 +826,13 @@ alloc.luadef('lastdestinationname', function() tex.sprint(last_dest_name()) end)
-- provide the arguments to \pdfextension startlink
local link_types = { }
+local function make_link_attr(s)
+ local 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
+ table.insert(attr, '}')
+ return attr
+end
alloc.luadef('hyper:makelink', function()
local s = options_scanner()
:argument('alt'):argument('contents') -- same thing
@@ -832,18 +845,32 @@ alloc.luadef('hyper:makelink', function()
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)
+ local attr = make_link_attr(s)
tex.sprint(table.concat(attr, ' '))
+ tex.sprint('user {')
+ tex.write(user)
+ tex.sprint('}\\ignorespaces')
end)
+local function scan_escaped_argument(chars_to_escape)
+ local stored = { }
+ for char in string.utfvalues(chars_to_escape) do
+ stored[char] = tex.getcatcode(char)
+ tex.setcatcode(char, 12)
+ end
+ local res = token.scan_argument()
+ for char, code in pairs(stored) do
+ tex.setcatcode(char, code)
+ end
+ return res
+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()))
+ local url = scan_escaped_argument ('~#$%^&_')
+ return string.format('/Subtype/Link /A <</S/URI /URI %s>>', pdf_string(url))
end
function link_types.user() return token.scan_argument() end
@@ -855,7 +882,7 @@ function link_types.last() return '/Subtype/Link /A <</S/Named /N/LastPage>>' en
-- 1 bookmarks (outlines)
-- start with a dummy top-level bookmark
-local bookmarks = { { count = 0 } }
+local bookmarks = { { count = 0, level = 0 } }
structure[1].bookmark = bookmarks[1]
local function write_bookmarks()
@@ -870,13 +897,13 @@ local function write_bookmarks()
' <</Type /Outlines /First %s 0 R /Last %s 0 R /Count %s >> ',
bookmarks[2].outline_obj, bookmarks[1].last.outline_obj, #bookmarks - 1))
-- write bookmark objects
- for i=2, #bookmarks do
+ for i=2, #bookmarks do -- skip the root (i=1)
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, 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
+ if bm.struct and bm.struct.objnum then -- false if no structures are written out
insert_formatted(res, '/SE %s 0 R', bm.struct.objnum)
end
if bm.count > 0 then
@@ -888,37 +915,51 @@ local function write_bookmarks()
end
function M.add_bookmark(bm)
- local se = current_structure_element()
- bm.parent, bm.count = false, 0
- bm.dest = bm.dest or write_new_dest()
- se.bookmark, bm.struct = bm, se
- -- find and update the parent bookmarks
- local p = se.parent
- while p do
- local pbm = p.bookmark
- if pbm then
- if not bm.parent then
- if pbm.last then pbm.last.next = bm end
- bm.parent, bm.prev = pbm, pbm.last
- pbm.first, pbm.last = pbm.first or bm, bm
+ local pbm
+ if bm.level then
+ for i = #bookmarks, 1, -1 do
+ pbm = bookmarks[i]
+ if pbm.level < bm.level then
+ break
end
- -- update the count until the first closed bookmark
- pbm.count = pbm.count + 1
- p = pbm.open and pbm.parent
- else
- p = p.parent
end
+ else
+ local se = current_structure_element()
+ if se.bookmark then
+ return alloc.err('Structure element %s already has a bookmark', pdf_name(se.struct))
+ end
+ se.bookmark, bm.struct = bm, se
+ -- derive parent from strucrure
+ pbm = se.parent
+ while not pbm.bookmark do
+ pbm = pbm.parent
+ end
+ pbm = pbm.bookmark
end
+ -- initial values; links to other bookmarks
+ bm.parent, bm.count = false, 0
+ bm.dest = bm.dest or write_new_dest()
+ if pbm.last then pbm.last.next = bm end
+ bm.parent, bm.prev = pbm, pbm.last
+ pbm.first, pbm.last = pbm.first or bm, bm
+ bm.level = bm.level or (pbm.level + 1)
+ -- update the count until the first closed bookmarks
+ repeat
+ pbm.count = pbm.count + 1
+ pbm = pbm.open and pbm.parent
+ until not pbm
+ -- append to the list
table.insert(bookmarks, bm)
end
alloc.luadef('outline', function()
- local s = options_scanner()
+ local bm = options_scanner()
:keyword('open', 'closed')
:string('dest')
+ :int('level')
:scan()
- s.title = token.scan_string()
- M.add_bookmark(s)
+ bm.title = token.scan_string()
+ M.add_bookmark(bm)
end, 'protected')
@@ -987,7 +1028,7 @@ alloc.luadef('embedfile', function()
t.name = t.file or alloc.err('No name specified for embedded file stream')
end
t.name = pdf_string(t.name or '(unnamed)')
- local fs, ef = M.embed_file(t, t.global)
+ local fs, _ = M.embed_file(t, t.global)
-- where to attach?
if t.global then
table.insert(attached_files, { name = t.name, objnum = fs } )
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 8a5f738063f..d5300fd58f5 100644
--- a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex
+++ b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex
@@ -323,6 +323,84 @@
\markelement{Lbl}{{\stopformulatagging#1}}}
\def\tagging:ensurestopNote{\ensurestopelement{Note}}
+% \sectionstructure { subsection, section, chapter }
+\def\sectionstructure{%
+ \newtoks\tag:sect:resets \tag:sect:resets{}%
+ \splitcommalist\tag:sect:a}
+\def\tag:sect:a#1{\expandafter\tag:sect:b
+ \expandafter{\Uchar\uccode`#1}{#1}}
+\def\tag:sect:b#1#2{% Section section
+ \addstructuretype Sect #1\relax
+ \expandafter\newcount\csname #2nr\endcsname
+ \expandafter\edef\csname mark#2\endcsname{%
+ \noexpand\withoptions[]%
+ \expandafter\noexpand\csname #2:domark\endcsname}%
+ \expandafter\edef\csname #2:domark\endcsname[##1]{%
+ \unexpanded{\ifhmode\errhelp{You should place section markers
+ in the vertical list, before the header.}\errmessage
+ {Section marker in horizontal list}\fi}%
+ \global\advance\expandafter\noexpand
+ \csname #2nr\endcsname1
+ \noexpand\the\expandafter\noexpand
+ \csname #2:resets\endcsname
+ \startelement\noexpand\ifx=##1=\noexpand\else
+ title{##1}\noexpand\fi{#1}%
+ \nextpartag{H}\ignorespaces}%
+ \expandafter\newtoks\csname #2:resets\endcsname
+ \csname #2:resets\endcsname \tag:sect:resets
+ \etoksapp\tag:sect:resets{%
+ \noexpand\ensurestopelement{#1}%
+ \global\expandafter\noexpand\csname#2nr\endcsname0 }}
+
+% tagging the plain output routine
+\begingroup\catcode`\@=11
+\gdef\autotagplainoutput{%
+ \let \vfootnot = \tag:vfootnote
+ \begingroup
+ % these should not be expanded
+ \tag:mkrelax
+ \ifhmode \ifvmode \ifnum \ifdim \ifodd \ifeven
+ \ifcondition \unless \else \fi \next \tmp
+ \strut \strutbox \footstrut
+ \the \number \empty \folio
+ \line \leftline \rightline \centerline
+ \nointerlineskip \offinterlineskip
+ \textindent \narrower \hang \llap \rlap
+ \enspace \thinspace \hidewidth
+ \quad \qquad \enskip
+ \@sf \fo@t \footins
+ \tag:mkrelax
+ % redefine head- and footlines
+ \def\footline{\taggedfootline}%
+ \def\headline{\taggedheadline}%
+ \xdef\makeheadline{\makeheadline}%
+ \xdef\makefootline{\makefootline}%
+ \xdef\footnoterule{\markartifact{Layout}\footnoterule}
+ % redefine vfootnote
+ \def\textindent##1{\noexpand\nextpartag{}%
+ \noexpand\marknotelbl{\noexpand\textindent{##1}}%
+ \noexpand\startelement{P}}%
+ \xdef\vfootnote##1{\vfootnote{##1}}%
+ % redefine footnote
+ \let\vfootnote=\relax \let\textindent=\relax
+ \def\fi##1\@sf{\noexpand\fi\noexpand\marknoteref{##1}\@sf}
+ \xdef\footnote##1{\footnote{##1}}%
+ \endgroup}
+\endgroup
+\def\tag:mkrelax#1{\ifx\tag:mkrelax#1\tag:else
+ \let#1=\relax\expandafter\tag:mkrelax\tag:fi}
+\let\tag:else=\else \let\tag:fi=\fi
+\newtoks \taggedheadline \newtoks \taggedfootline
+\taggedheadline{\tagtoks:nonempty{Pagination /Subtype/Header}\headline}
+\taggedfootline{\tagtoks:nonempty{Pagination /Subtype/Footer}\footline}
+\def\tagtoks:nonempty#1#2{%
+ \edef\tagtoks:tmp{\the#2}%
+ \ifx\tagtoks:tmp\tagtoks:hfil
+ \the#2\else
+ \markartifact{#1}{\the#2}\fi}
+\def\tagtoks:hfil{\hfil}
+
+
% 1 tagging formulas
% \autotagformulas
@@ -408,7 +486,7 @@
% \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\endlink{\pdfextension endlink\ensurestopelement{Link}\relax}
\protected\def\startlink{\startelement{Link}\pdfextension startlink}
\protected\def\hyperlink{\quitvmode\startlink\hyper:makelink}