summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-05-15 20:37:46 +0000
committerKarl Berry <karl@freefriends.org>2021-05-15 20:37:46 +0000
commit449b126a17ce3ea3c78f166b93b59470ffa01abf (patch)
tree6e5985ca4eec7a1b2ca662e1f1ec9eae67753031 /Master/texmf-dist/source
parente04026bae8d6038a4ba422e41af58d1743178733 (diff)
tagpdf (15may21)
git-svn-id: svn://tug.org/texlive/trunk@59214 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r--Master/texmf-dist/source/latex/tagpdf/tagpdf-backend.dtx61
-rw-r--r--Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx36
-rw-r--r--Master/texmf-dist/source/latex/tagpdf/tagpdf-mc.dtx73
-rw-r--r--Master/texmf-dist/source/latex/tagpdf/tagpdf-roles.dtx590
-rw-r--r--Master/texmf-dist/source/latex/tagpdf/tagpdf-space.dtx2
-rw-r--r--Master/texmf-dist/source/latex/tagpdf/tagpdf-struct.dtx120
-rw-r--r--Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx79
-rw-r--r--Master/texmf-dist/source/latex/tagpdf/tagpdf.dtx298
8 files changed, 1034 insertions, 225 deletions
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf-backend.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf-backend.dtx
index d80d56778bc..42620d46e5e 100644
--- a/Master/texmf-dist/source/latex/tagpdf/tagpdf-backend.dtx
+++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf-backend.dtx
@@ -27,7 +27,7 @@
% \begin{macrocode}
%<@@=tag>
%<*luatex>
-\ProvidesExplFile {tagpdf-luatex.def} {2021/02/23} {0.80}
+\ProvidesExplFile {tagpdf-luatex.def} {2021/05/14} {0.81}
{tagpdf~driver~for~luatex}
\newattribute \l_@@_mc_type_attr %the value represent the type
@@ -55,41 +55,32 @@
% Old code, I'm not quite sure if this was a good idea. Now I have mix of table in
% ltx.@@.tables and ltx.@@.mc/struct. And a lot is probably not needed.
-\cs_new:Nn \@@_luatex_get_table_name:Nn
- {
- \tl_set_rescan:Nnn #1 { \char_set_catcode_ignore:N \\ } { #2 }
- }
-
-\cs_new:Nn \@@_prop_new:N
+\cs_new_protected:Nn \@@_prop_new:N
{
\prop_new:N #1
- \@@_luatex_get_table_name:Nn \l_tmpa_tl { #1 }
- \directlua { ltx.@@.tables.\l_tmpa_tl = {} }
+ \directlua { ltx.@@.tables.\cs_to_str:N#1 = {} }
}
-\cs_new:Nn \@@_seq_new:N
+\cs_new_protected:Nn \@@_seq_new:N
{
\seq_new:N #1
- \@@_luatex_get_table_name:Nn \l_tmpa_tl { #1 }
- \directlua { ltx.@@.tables.\l_tmpa_tl = {} }
+ \directlua { ltx.@@.tables.\cs_to_str:N#1 = {} }
}
-\cs_new:Nn \@@_prop_gput:Nnn
+\cs_new_protected:Nn \@@_prop_gput:Nnn
{
\prop_gput:Nnn #1 { #2 } { #3 }
- \@@_luatex_get_table_name:Nn \l_tmpa_tl { #1 }
- \directlua { ltx.@@.tables.\l_tmpa_tl["#2"] = "#3" }
+ \directlua { ltx.@@.tables.\cs_to_str:N#1 ["#2"] = "#3" }
}
-\cs_new:Nn \@@_seq_gput_right:Nn
+\cs_new_protected:Nn \@@_seq_gput_right:Nn
{
\seq_gput_right:Nn #1 { #2 }
- \@@_luatex_get_table_name:Nn \l_tmpa_tl { #1 }
- \directlua { table.insert(ltx.@@.tables.\l_tmpa_tl, "#2") }
+ \directlua { table.insert(ltx.@@.tables.\cs_to_str:N#1, "#2") }
}
%Hm not quite sure about the naming
@@ -105,27 +96,25 @@
}
%for debugging commands that show both the seq/prop and the lua tables
-\cs_new:Nn \@@_seq_show:N
+\cs_new_protected:Nn \@@_seq_show:N
{
\seq_show:N #1
- \@@_luatex_get_table_name:Nn \l_tmpa_tl { #1 }
- \directlua { ltx.@@.trace.log ("lua~sequence~array~\l_tmpa_tl",1) }
- \directlua { ltx.@@.trace.show_seq (ltx.@@.tables.\l_tmpa_tl) }
+ \directlua { ltx.@@.trace.log ("lua~sequence~array~\cs_to_str:N#1",1) }
+ \directlua { ltx.@@.trace.show_seq (ltx.@@.tables.\cs_to_str:N#1) }
}
-\cs_new:Nn \@@_prop_show:N
+\cs_new_protected:Nn \@@_prop_show:N
{
\prop_show:N #1
- \@@_luatex_get_table_name:Nn \l_tmpa_tl { #1 }
- \directlua {ltx.@@.trace.log ("lua~property~table~\l_tmpa_tl",1) }
- \directlua {ltx.@@.trace.show_prop (ltx.@@.tables.\l_tmpa_tl) }
+ \directlua {ltx.@@.trace.log ("lua~property~table~\cs_to_str:N#1",1) }
+ \directlua {ltx.@@.trace.show_prop (ltx.@@.tables.\cs_to_str:N#1) }
}
%</luatex>
% \end{macrocode}
%
% \begin{macrocode}
%<*pdftex>
-\ProvidesExplFile {tagpdf-pdftex.def} {2021/02/23} {0.80}
+\ProvidesExplFile {tagpdf-pdftex.def} {2021/05/14} {0.81}
{tagpdf~driver~for~pdftex}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -160,8 +149,8 @@
local ProvidesLuaModule = {
name = "tagpdf",
- version = "0.80", --TAGVERSION
- date = "2021-02-23", --TAGDATE
+ version = "0.81", --TAGVERSION
+ date = "2021-05-14", --TAGDATE
description = "tagpdf lua code",
license = "The LATEX Project Public License 1.3c"
}
@@ -237,6 +226,7 @@ local nodeid = node.id
local nodecopy = node.copy
local nodegetattribute = node.get_attribute
local nodesetattribute = node.set_attribute
+local nodehasattribute = node.has_attribute
local nodenew = node.new
local nodetail = node.tail
local nodeslide = node.slide
@@ -361,6 +351,17 @@ local function @@_mark_spaces (head)
nodesetattribute(kern.next,iwfontattributeid,glyph.font)
end
end
+ -- look also back
+ if glyph.prev and (glyph.prev.id == GLUE)
+ and not inside_math and (glyph.prev.width >0) and not nodehasattribute(glyph.prev,iwspaceattributeid)
+ then
+ nodesetattribute(glyph.prev,iwspaceattributeid,1)
+ nodesetattribute(glyph.prev,iwfontattributeid,glyph.font)
+ -- for debugging
+ if ltx.__tag.trace.showspaces then
+ __tag_show_spacemark (head,glyph)
+ end
+ end
elseif id == PENALTY then
local glyph = n
-- ltx.@@.trace.log ("PENALTY ".. n.subtype.."VALUE"..n.penalty,3)
@@ -770,7 +771,7 @@ function ltx.@@.func.fill_parent_tree_line (page)
local structnum = ltx.@@.mc[mcnum]["parent"]
local propname = "g_@@_struct_"..structnum.."_prop"
local objref = ltx.@@.tables[propname]["objref"] or "XXXX"
- texio.write_nl("=====>"..tostring(objref))
+ ltx.@@.trace.log("=====>"..tostring(objref),5)
numsentry = pdfpage .. " [".. objref .. "]"
ltx.@@.trace.log("PAGETREE PAGE" .. page.. " NUM ENTRY = ".. numsentry,3)
else
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx
index ad3866ed76c..eb0f41e89b1 100644
--- a/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx
+++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx
@@ -2,7 +2,7 @@
%
%% File: tagpdf-checks.dtx
%
-% Copyright (C) 2019-2020 Ulrike Fischer
+% Copyright (C) 2019-2021 Ulrike Fischer
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -27,7 +27,7 @@
% \begin{macrocode}
%<@@=tag>
%<*checks>
-\ProvidesExplPackage {tagpdf-checks-code} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-checks-code} {2021/05/14} {0.81}
{part of tagpdf - code related to checks and messages}
@@ -39,6 +39,8 @@
\msg_new:nnn { tag } {mc-label-unknown} { label~#1~unknown~-~rerun }
\msg_new:nnn { tag } {mc-used-twice} { mc~#1~has~been~already~used }
\msg_new:nnn { tag } {mc-not-open} { there~is~no~mc~to~end~at~#1 }
+\msg_new:nnn { tag } {mc-pushed} { #1~has~been~pushed~to~the~mc~stack}
+\msg_new:nnn { tag } {mc-popped} { #1~has~been~removed~from~the~mc~stack }
% structures
\msg_new:nnn { tag } {struct-no-objnum} { objnum~missing~for~structure~#1 }
@@ -56,7 +58,8 @@
\msg_new:nnn { tag } {role-missing} { tag~#1~has~no~role~assigned }
\msg_new:nnn { tag } {role-unknown} { role~#1~is~not~known }
\msg_new:nnn { tag } {role-unknown-tag} { tag~#1~is~not~known }
-\msg_new:nnn { tag } {role-new-tag} { adding~new~tag~#1~mapped~to~role~#2 }
+\msg_new:nnn { tag } {role-tag} { mapping~tag~#1~to~role~#2 }
+\msg_new:nnn { tag } {new-tag} { adding~new~tag~#1 }
% trees
@@ -88,6 +91,15 @@
}
}
+\cs_new:Nn \@@_check_structure_tag:NN %_protected?
+ {
+ \exp_args:NNx
+ \prop_if_in:NnF \g_@@_role_tags_prop {#1/#2}
+ {
+ \msg_warning:nnx { tag } {role-unknown-tag} {#1}
+ }
+ }
+
\cs_new_protected:Nn \@@_check_info_closing_struct:n %#1 struct num
{
\msg_info:nnn { tag } {struct-show-closing} {#1}
@@ -122,7 +134,7 @@
{
\prop_get:NnNTF \g_@@_role_tags_prop {#2} \l_tmpa_tl
{
- \msg_info:nnnn { tag } {role-new-tag} {#1} {#2}
+ \msg_info:nnnn { tag } {role-tag} {#1} {#2}
}
{
\msg_warning:nnn { tag } {role-unknown} {#2}
@@ -147,13 +159,27 @@
}
}
+\cs_new_protected:Nn \@@_check_mc_pushed_popped:nn
+ {
+ \int_compare:nNnT
+ { \l_@@_loglevel_int } ={ 2 }
+ { \msg_info:nnx {tag}{mc-#1}{#2} }
+ \int_compare:nNnT
+ { \l_@@_loglevel_int } > { 2 }
+ {
+ \msg_warning:nnx {tag}{mc-#1}{#2}
+ \seq_log:N \g_@@_mc_stack_seq
+ }
+ }
+
+
\cs_new:Nn \@@_check_mc_tag:N %protected??
{
\tl_if_empty:NT #1
{
\msg_error:nnx { tag } {mc-tag-missing} { \@@_get_mc_abs_cnt: }
}
- \prop_if_in:NoF \g_@@_role_tags_prop {#1}
+ \prop_if_in:NoF \g_@@_role_tags_NS_prop {#1}
{
\msg_warning:nnx { tag } {role-unknown-tag} {#1}
}
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc.dtx
index a2cc7f349dc..565e41b372c 100644
--- a/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc.dtx
+++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc.dtx
@@ -27,7 +27,7 @@
% \begin{macrocode}
%<@@=tag>
%<*shared>
-\ProvidesExplPackage {tagpdf-mc-code-shared} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-mc-code-shared} {2021/05/14} {0.81}
{part of tagpdf - code related to marking chunks -
code shared by generic and luamode }
% I use a latex counter for the absolute count, so that it is added to
@@ -56,6 +56,9 @@
% value: the structure number the mc is in
\_@@_prop_new:N \g_@@_mc_parenttree_prop
+% some commands (e.g. links) want to close a previous mc and reopen it after
+% there work. For this we create a stack:
+\seq_new:N \g_@@_mc_stack_seq
% shared keys
% the rest are in the splitted code
\tl_new:N \l_@@_mc_artifact_type_tl
@@ -119,11 +122,58 @@
% we need to define it for both modes to avoid a problem with the label
\int_new:N \g_@@_MCID_tmp_bypage_int
+% \end{macrocode}
+
+% \begin{function}[added = 2021-04-22]
+% {
+% \tag_mc_end_push:, \tag_mc_begin_pop:n
+% }
+% \begin{syntax}
+% \cs{tag_mc_end_push:} \\
+% \cs{tag_mc_begin_pop:n}\Arg{key-values}
+% \end{syntax}
+% If there is an open mc chunk,
+% \cs{tag_mc_end_push:} ends it and pushes its tag of the stack. If there is no
+% open chunk, it puts -1 on the stack (for debugging)
+% \cs{tag_mc_begin_pop:n} removes a value from the stack. If it is different from
+% -1 it opens a tag with it.
+% The reopened mc chunk looses info like the alttext for now.
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \tag_mc_end_push:
+ {
+ \@@_mc_if_in:TF
+ {
+ \seq_gpush:Nx \g_@@_mc_stack_seq { \tag_get:n {mc_tag} }
+ \@@_check_mc_pushed_popped:nn {pushed}{\tag_get:n {mc_tag}}
+ \tag_mc_end:
+ }
+ {
+ \@@_check_mc_pushed_popped:nn {pushed}{-1}
+ \seq_gpush:Nn \g_@@_mc_stack_seq{ -1 }
+ }
+ }
+\cs_new_protected:Npn \tag_mc_begin_pop:n #1
+ {
+ \seq_gpop:NNTF \g_@@_mc_stack_seq \l_@@_tmpa_tl
+ {
+ \tl_if_eq:NnTF \l_@@_tmpa_tl {-1}
+ {
+ \@@_check_mc_pushed_popped:nn {popped}{-1}
+ }
+ {
+ \@@_check_mc_pushed_popped:nn {popped}{\l_@@_tmpa_tl}
+ \tag_mc_begin:n {tag=\l_@@_tmpa_tl,#1}
+ }
+ }
+ { \@@_check_mc_pushed_popped:nn {popped}{empty~stack,~nothing} } %message?
+ }
+
%</shared>
% \end{macrocode}
% \begin{macrocode}
%<*generic>
-\ProvidesExplPackage {tagpdf-mc-code-generic} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-mc-code-generic} {2021/05/14} {0.81}
{part of tagpdf - code related to marking chunks - generic mode}
% for the label system
@@ -148,8 +198,6 @@
\prg_new_eq_conditional:NNn \tag_mc_if_in: \@@_mc_if_in: {p,T,F,TF}
-%deprecated
-\prg_new_eq_conditional:NNn \uftag_mc_if_in: \@@_mc_if_in: {p,T,F,TF}
% this are the low level mc command.
@@ -381,8 +429,6 @@
\group_end:
}
-%deprecated
-\cs_set_eq:NN \uftag_mc_begin:n \tag_mc_begin:n
\cs_new_protected:Nn \tag_mc_end:
{
@@ -392,7 +438,7 @@
\@@_mc_emc:
}
-\cs_set_eq:NN \uftag_mc_end: \tag_mc_end:
+
\cs_new_protected:Nn \tag_mc_use:n %#1: label name
{
@@ -420,16 +466,13 @@
}
}
-%deprecated
-\cs_set_eq:NN \uftag_mc_use:n \tag_mc_use:n
\cs_new:Nn \@@_get_data_mc_tag: { \g_@@_mc_key_tag_tl }
-
%</generic>
% \end{macrocode}
% \begin{macrocode}
%<*luamode>
-\ProvidesExplPackage {tagpdf-mc-code-lua} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-mc-code-lua} {2021/05/14} {0.81}
{tagpdf - mc code only for the luamode }
% the two attibutes are defined in the driver file.
@@ -500,8 +543,6 @@
\prg_new_eq_conditional:NNn \tag_mc_if_in: \@@_mc_if_in: {p,T,F,TF}
-%deprecated
-\prg_new_eq_conditional:NNn \uftag_mc_if_in: \@@_mc_if_in: {p,T,F,TF}
% the keys
\tl_new:N \l_@@_mc_key_tag_tl
@@ -746,8 +787,6 @@
%\group_end:
}
-%deprecated
-\cs_set_eq:NN \uftag_mc_begin:n \tag_mc_begin:n
\cs_new_protected:Nn \tag_mc_end:
{
@@ -758,7 +797,7 @@
\tl_set:Nn \l_@@_mc_key_tag_tl { }
}
-\cs_set_eq:NN \uftag_mc_end: \tag_mc_end:
+
\cs_new_protected:Nn \tag_mc_use:n %#1: label name
{
@@ -772,7 +811,7 @@
}
}
-\cs_set_eq:NN \uftag_mc_use:n \tag_mc_use:n
+
\cs_new:Nn \@@_get_data_mc_tag: { \l_@@_mc_key_tag_tl }
%</luamode>
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf-roles.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf-roles.dtx
index 920c6345ca8..2254ad420a4 100644
--- a/Master/texmf-dist/source/latex/tagpdf/tagpdf-roles.dtx
+++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf-roles.dtx
@@ -2,7 +2,7 @@
%
%% File: tagpdf-roles.dtx
%
-% Copyright (C) 2019 Ulrike Fischer
+% Copyright (C) 2019-2021 Ulrike Fischer
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -27,30 +27,145 @@
% \begin{macrocode}
%<@@=tag>
%<*roles>
-\ProvidesExplPackage {tagpdf-roles-code} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-roles-code} {2021/05/14} {0.81}
{part of tagpdf - code related to roles and structure names}
-
-\@@_seq_new:N \g_@@_role_tags_seq %to get names from numbers
-\@@_prop_new:N \g_@@_role_tags_prop %to get numbers from names
-
-%The list of standard adobe tags.
-\clist_const:Nn \c_@@_role_sttags_clist
- {%possible root elements
+% \end{macrocode}
+% \section{Variables}
+% Tags have both a name (a string) and a number (for the lua attribute).
+% Testing a name is easier with a prop, while accessing with a number is
+% better done with a seq. So both are used and must be kept in sync if a new
+% tag is added. The number is only relevant for the MC type, tags with the same
+% name from different names spaces can have the same number.
+% \begin{macro}{\g_@@_role_tags_seq,\g_@@_role_tags_prop}
+% \begin{macrocode}
+\@@_seq_new:N \g_@@_role_tags_seq %to get names (type/NS) from numbers
+\@@_prop_new:N \g_@@_role_tags_prop %to get numbers from names (type/NS)
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\g_@@_role_tags_NS_prop}
+% in pdf 2.0 tags belong to a name space. For every tag we store a default
+% name space.
+% The keys are the tags, the value shorthands like pdf2, or mathml.
+% There is no need to access this from lua, so we use the standard prop commands.
+% \begin{macrocode}
+\prop_new:N \g_@@_role_tags_NS_prop %to namespace info
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\g_@@_role_NS_prop}
+% The standard names spaces are the following. The keys are the name
+% tagpdf will use, the urls are the identifier in the namespace object.
+% \begin{description}
+% \item[mathml] http://www.w3.org/1998/Math/MathML
+% \item[pdf2] http://iso.org/pdf2/ssn
+% \item[pdf] http://iso.org/pdf/ssn (default)
+% \item[user] \cs{c_@@_role_userNS_id_str} (random id, for user tags)
+% \end{description}
+% More namespaces are possible and
+% their objects references and the ones of the namespaces must be collected
+% so that an array can be written to the StructTreeRoot at the end (see tagpdf-tree).
+% We use a prop to store also the object reference as it will be needed rather
+% often.
+% \begin{macrocode}
+\prop_new:N \g_@@_role_NS_prop % collect namespaces
+% \end{macrocode}
+% \end{macro}
+% \section{Namesspaces}
+% The following commands setups a names space. Namespace dictionaries can
+% contain an optional |/Schema| and |/RoleMapNS| entry. We only reserve the
+% objects but delay the writing to the finish code, where we can test if the
+% keys and the name spaces are actually needed
+% \begin{macro}{\@@_role_NS_new:nn}
+% This commands setups objects for the name space and its rolemap. It also
+% initialize a prop to collect the rolemaps if needed.
+% \begin{function}{\@@_role_NS_new:nnn}
+% \begin{syntax}
+% \cs{@@_role_NS_new:nnn}\Arg{shorthand}\Arg{URI-ID}{Schema}
+% \end{syntax}
+% \end{function}
+% \begin{macro}{\@@_role_NS_new:nnn}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_role_NS_new:nnn #1 #2 #3
+ { \msg_redirect_name:nnn { pdfdict } { empty-value } { none }
+ \pdf_object_new:nn {tag/NS/#1}{dict}
+ \pdfdict_new:n {g_@@_role/Namespace_#1_dict}
+ \pdf_object_new:nn {@@/RoleMapNS/#1}{dict}
+ \pdfdict_new:n {g_@@_role/RoleMapNS_#1_dict}
+ \pdfdict_gput:nnn
+ {g_@@_role/Namespace_#1_dict}
+ {Type}
+ {/Namespace}
+ \pdf_string_from_unicode:nnN{utf8/string}{#2}\l_tmpa_str
+ \pdfdict_gput:nnx
+ {g_@@_role/Namespace_#1_dict}
+ {NS}
+ {\l_tmpa_str}
+ %RoleMapNS is added in tree
+ \pdfdict_gput:nnx{g_@@_role/Namespace_#1_dict}
+ {Schema}{#3}
+ \prop_gput:Nnx \g_@@_role_NS_prop {#1}{\pdf_object_ref:n{tag/NS/#1}~}
+ \msg_redirect_name:nnn { pdfdict } { empty-value } { warning }
+ }
+% \end{macrocode}
+% \end{macro}
+% We need an id for the user space. For the tests it should be possible
+% to set it to a fix value. So we use random numbers which can
+% be fixed by setting a seed. We fake a sort of
+% GUID but not try to be really exact as it doesn't matter ...
+%
+% \begin{macrocode}
+\str_const:Nx \c_@@_role_userNS_id_str
+ { data:,
+ \int_to_Hex:n{\int_rand:n {65535}}
+ \int_to_Hex:n{\int_rand:n {65535}}
+ -
+ \int_to_Hex:n{\int_rand:n {65535}}
+ -
+ \int_to_Hex:n{\int_rand:n {65535}}
+ -
+ \int_to_Hex:n{\int_rand:n {65535}}
+ -
+ \int_to_Hex:n{\int_rand:n {16777215}}
+ \int_to_Hex:n{\int_rand:n {16777215}}
+ }
+% \end{macrocode}
+% Now we setup the standard names spaces. Currently only if we detect pdf2.0 but
+% this will perhaps have to change if the structure code gets to messy.
+% \begin{macrocode}
+\pdf_version_compare:NnT > {1.9}
+ {
+ \@@_role_NS_new:nnn {pdf} {http://iso.org/pdf/ssn}{}
+ \@@_role_NS_new:nnn {pdf2} {http://iso.org/pdf2/ssn}{}
+ \@@_role_NS_new:nnn {mathml}{http://www.w3.org/1998/Math/MathML}{}
+ \exp_args:Nnx
+ \@@_role_NS_new:nnn {user}{\c_@@_role_userNS_id_str}{}
+ }
+% \end{macrocode}
+%
+% \section{Data}
+% In this section we setup the standard data.
+% At first the list of structure types. We split them in three lists,
+% the tags with which are both in the pdf and pdf2 namespace,
+% the one only in pdf and the one with the tags only in pdf2.
+% We also define a rolemap for the pdfII only type to pdf so that
+% they can always be used.
+% \begin{macro}
+% {
+% \c_@@_role_sttags_pdf_pdfII_clist,
+% \c_@@_role_sttags_only_pdf_clist,
+% \c_@@_role_sttags_only_pdfII_clist,
+% \c_@@_role_sttags_mathml_clist,
+% \c_@@_role_sttags_pdfII_to_pdf_prop
+% }
+% \begin{macrocode}
+%
+\clist_const:Nn \c_@@_role_sttags_pdf_pdfII_clist
+ {
Document, %A complete document. This is the root element of any structure tree containing
%multiple parts or multiple articles.
Part, %A large-scale division of a document.
- Art, %A relatively self-contained body of text constituting a single narrative or exposition
- %subelements
Sect, %A container for grouping related content elements.
Div, %A generic block-level element or group of elements
- BlockQuote, %A portion of text consisting of one or more paragraphs attributed to someone other
- %than the author of the surrounding text.
Caption, %A brief portion of text describing a table or figure.
- TOC, %A list made up of table of contents item entries (structure tag TOCI; see below)
- %and/or other nested table of contents entries
- TOCI, %An individual member of a table of contents. This entry's children can be any of
- %the following structure tags:
- %Lbl,Reference,NonStruct,P,TOC
Index,
NonStruct, %probably not needed
H,
@@ -73,29 +188,301 @@
TBody, %table rows
TFoot, %table footer
Span, %generic inline marker
- Quote, %inline quote
- Note, % footnote, endnote. Lbl can be child
- Reference, % A citation to content elsewhere in the document.
- BibEntry, %bibentry
- Code, %
Link, %
Annot,
Figure,
Formula,
Form,
- Artifact
+ % ruby warichu etc ..
+ Ruby,
+ RB,
+ RT,
+ Warichu,
+ WT,
+ WP,
+ Artifact % only MC-tag ?...
}
+\clist_const:Nn \c_@@_role_sttags_only_pdf_clist
+ {
+ Art,%A relatively self-contained body of text constituting a single narrative or exposition
+ BlockQuote, %A portion of text consisting of one or more paragraphs attributed to someone other
+ %than the author of the surrounding text.
+ TOC, %A list made up of table of contents item entries (structure tag TOCI; see below)
+ %and/or other nested table of contents entries
+ TOCI, %An individual member of a table of contents. This entry's children can be any of
+ %the following structure tags:
+ %Lbl,Reference,NonStruct,P,TOC
+ Index,
+ Private,
+ Quote, %inline quote
+ Note, %footnote, endnote. Lbl can be child
+ Reference, %A citation to content elsewhere in the document.
+ BibEntry, %bibentry
+ Code
+ }
+
+\clist_const:Nn \c_@@_role_sttags_only_pdfII_clist
+ {
+ DocumentFragment
+ ,Aside
+ ,H7
+ ,H8
+ ,H9
+ ,H10
+ ,Title
+ ,FENote
+ ,Sub
+ ,Em
+ ,Strong
+ ,Artifact
+ }
+
+\clist_const:Nn \c_@@_role_sttags_mathml_clist
+ {
+ abs
+ ,and
+ ,annotation
+ ,apply
+ ,approx
+ ,arccos
+ ,arccosh
+ ,arccot
+ ,arccoth
+ ,arccsc
+ ,arccsch
+ ,arcsec
+ ,arcsech
+ ,arcsin
+ ,arcsinh
+ ,arctan
+ ,arctanh
+ ,arg
+ ,bind
+ ,bvar
+ ,card
+ ,cartesianproduct
+ ,cbytes
+ ,ceiling
+ ,cerror
+ ,ci
+ ,cn
+ ,codomain
+ ,complexes
+ ,compose
+ ,condition
+ ,conjugate
+ ,cos
+ ,cosh
+ ,cot
+ ,coth
+ ,cs
+ ,csc
+ ,csch
+ ,csymbol
+ ,curl
+ ,declare
+ ,degree
+ ,determinant
+ ,diff
+ ,divergence
+ ,divide
+ ,domain
+ ,domainofapplication
+ ,emptyset
+ ,eq
+ ,equivalent
+ ,eulergamma
+ ,exists
+ ,exp
+ ,exponentiale
+ ,factorial
+ ,factorof
+ ,false
+ ,floor
+ ,fn
+ ,forall
+ ,gcd
+ ,geq
+ ,grad
+ ,gt
+ ,ident
+ ,image
+ ,imaginary
+ ,imaginaryi
+ ,implies
+ ,in
+ ,infinity
+ ,int
+ ,integers
+ ,intersect
+ ,interval
+ ,inverse
+ ,lambda
+ ,laplacian
+ ,lcm
+ ,leq
+ ,limit
+ ,ln
+ ,log
+ ,logbase
+ ,lowlimit
+ ,lt
+ ,maction
+ ,maligngroup
+ ,malignmark
+ ,math
+ ,matrix
+ ,matrixrow
+ ,max
+ ,mean
+ ,median
+ ,menclose
+ ,merror
+ ,mfenced
+ ,mfrac
+ ,mglyph
+ ,mi
+ ,min
+ ,minus
+ ,mlabeledtr
+ ,mlongdiv
+ ,mmultiscripts
+ ,mn
+ ,mo
+ ,mode
+ ,moment
+ ,momentabout
+ ,mover
+ ,mpadded
+ ,mphantom
+ ,mprescripts
+ ,mroot
+ ,mrow
+ ,ms
+ ,mscarries
+ ,mscarry
+ ,msgroup
+ ,msline
+ ,mspace
+ ,msqrt
+ ,msrow
+ ,mstack
+ ,mstyle
+ ,msub
+ ,msubsup
+ ,msup
+ ,mtable
+ ,mtd
+ ,mtext
+ ,mtr
+ ,munder
+ ,munderover
+ ,naturalnumbers
+ ,neq
+ ,none
+ ,not
+ ,notanumber
+ ,notin
+ ,notprsubset
+ ,notsubset
+ ,or
+ ,otherwise
+ ,outerproduct
+ ,partialdiff
+ ,pi
+ ,piece
+ ,piecewise
+ ,plus
+ ,power
+ ,primes
+ ,product
+ ,prsubset
+ ,quotient
+ ,rationals
+ ,real
+ ,reals
+ ,reln
+ ,rem
+ ,root
+ ,scalarproduct
+ ,sdev
+ ,sec
+ ,sech
+ ,selector
+ ,semantics
+ ,sep
+ ,set
+ ,setdiff
+ ,share
+ ,sin
+ ,sinh
+ ,subset
+ ,sum
+ ,tan
+ ,tanh
+ ,tendsto
+ ,times
+ ,transpose
+ ,true
+ ,union
+ ,uplimit
+ ,variance
+ ,vector
+ ,vectorproduct
+ ,xor
+ }
+
+\prop_const_from_keyval:Nn \c_@@_role_sttags_pdfII_to_pdf_prop
+ {
+ DocumentFragment = Art,
+ Aside = Note,
+ Title = H1,
+ Sub = Span,
+ H7 = H6 ,
+ H8 = H6 ,
+ H9 = H6 ,
+ H10 = H6,
+ FENote= Note,
+ Em = Span,
+ Strong= Span,
+ }
+% \end{macrocode}
+% \end{macro}
+% We fill the structure tags in to the seq. We allow all pdf1.7 and pdf2.0,
+% and role map if needed the 2.0 tags.
+% \begin{macrocode}
% get tag name from number: \seq_item:Nn \g_@@_role_tags_seq { n }
-%\seq_gset_from_clist:NN \g_@@_role_tags_seq \c_@@_role_tags_clist
+% get tag number from name: \prop_item:Nn \g_@@_role_tags_prop { name }
-\clist_map_inline:Nn \c_@@_role_sttags_clist
+\clist_map_inline:Nn \c_@@_role_sttags_pdf_pdfII_clist
{
\@@_seq_gput_right:Nn \g_@@_role_tags_seq { #1 }
+ \prop_gput:Nnn \g_@@_role_tags_NS_prop { #1 }{ pdf2 }
}
+\clist_map_inline:Nn \c_@@_role_sttags_only_pdf_clist
+ {
+ \@@_seq_gput_right:Nn \g_@@_role_tags_seq { #1 }
+ \prop_gput:Nnn \g_@@_role_tags_NS_prop { #1 }{ pdf }
+ }
+\clist_map_inline:Nn \c_@@_role_sttags_only_pdfII_clist
+ {
+ \@@_seq_gput_right:Nn \g_@@_role_tags_seq { #1 }
+ \prop_gput:Nnn \g_@@_role_tags_NS_prop { #1 }{ pdf2 }
+ }
+\pdf_version_compare:NnT > {1.9}
+ {
+ \clist_map_inline:Nn \c_@@_role_sttags_mathml_clist
+ {
+ \@@_seq_gput_right:Nn \g_@@_role_tags_seq { #1 }
+ \prop_gput:Nnn \g_@@_role_tags_NS_prop { #1 }{ mathml }
+ }
+ }
+% \end{macrocode}
+% For luatex and the MC we need a name/number relation.
+% The name space is not relevant.
+% \begin{macrocode}
-
-% get tag number from name: \prop_item:Nn \g_@@_role_tags_prop { name }
\int_step_inline:nnnn { 1 }{ 1 }{ \seq_count:N \g_@@_role_tags_seq }
{
\@@_prop_gput:Nxn \g_@@_role_tags_prop
@@ -104,51 +491,146 @@
}
{ #1 }
}
-
-\cs_new:Nn \@@_role_get_tag_from_index:nn
+% \end{macrocode}
+%
+% \section{Adding new tags and rolemapping}
+%
+% \subsection{pdf 1.7 and earlier}
+% With this versions only RoleMap is filled.
+% At first the dictionary:
+% \begin{macrocode}
+\pdfdict_new:n {g_@@_role/RoleMap_dict}
+% \end{macrocode}
+% \begin{macro}{\@@_role_add_tag:nn}
+% The pdf 1.7 version has only two arguments: new and rolemap name.
+% To make pdf 2.0 types usable we directly define a rolemapping for them.
+% TODO: add checks
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_role_add_tag:nn %(new) name, reference to old
{
- \@@_seq_item:cn { #1_seq } { #2 }
+ \prop_if_in:NnF \g_@@_role_tags_prop {#1}
+ {
+ \msg_info:nnn { tag }{new-tag}{#1}
+ \@@_seq_gput_right:Nn \g_@@_role_tags_seq { #1 }
+ \@@_prop_gput:Nnx \g_@@_role_tags_prop { #1 }
+ {
+ \seq_count:N \g_@@_role_tags_seq
+ }
+ \prop_gput:Nnn \g_@@_role_tags_NS_prop { #1 }{ user }
+ }
+ %\@@_check_add_tag_role:nn {#1}{#2} %%!TODO
+ \tl_if_empty:nF { #2 }
+ {
+ \pdfdict_gput:nnx {g_@@_role/RoleMap_dict}
+ {#1}
+ {\pdf_name_from_unicode_e:n{#2}}
+ }
}
+\cs_generate_variant:Nn \@@_role_add_tag:nn {VV}
-\cs_new:Nn \@@_role_get_index_from_tag:nn
+\pdf_version_compare:NnT < {2.0}
{
- \@@_prop_item:cn { #1_prop } { #2 }
+ \prop_map_inline:Nn \c_@@_role_sttags_pdfII_to_pdf_prop
+ {
+ \@@_role_add_tag:nn {#1}{#2}
+ }
}
-% new tags and the rolemap
-
-\@@_prop_new:N \g_@@_role_rolemap_prop
-
-\cs_new_protected:Nn \@@_role_add_tag:nn %new name, reference to old
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_role_add_tag:nnnn}
+% The pdf 2.0 version takes for arguments:
+% tag/namespace/role/namespace
+% TODO: add checks
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_role_add_tag:nnnn %tag/namespace/role/namespace
{
+ \msg_info:nnn { tag }{new-tag}{#1}
\@@_seq_gput_right:Nn \g_@@_role_tags_seq { #1 }
\@@_prop_gput:Nnx \g_@@_role_tags_prop { #1 }
- {
- \seq_count:N \g_@@_role_tags_seq
- }
- \@@_check_add_tag_role:nn {#1}{#2}
- \tl_if_empty:nF { #2 }
- {
- \@@_prop_gput:Nnn \g_@@_role_rolemap_prop
- { #1 } { #2 }
- }
- }
+ {
+ \seq_count:N \g_@@_role_tags_seq
+ }
+ \prop_gput:Nnn \g_@@_role_tags_NS_prop { #1 }{ #2 }
+ %\@@_check_add_tag_role:nn {#1}{#3} %TODO
+ \pdfdict_gput:nnx {g_@@_role/RoleMapNS_#2_dict}{#1}
+ {
+ [
+ \pdf_name_from_unicode_e:n{#3}
+ \c_space_tl
+ \pdf_object_ref:n {tag/NS/#4}
+ ]
+ }
+ }
+\cs_generate_variant:Nn \@@_role_add_tag:nnnn {VVVV}
+% \end{macrocode}
+% \end{macro}
+% The user interface use the key add-new-tag, which takes either a
+% keyval list as argument, or a tag/role.
+% \begin{macrocode}
-\cs_generate_variant:Nn \@@_role_add_tag:nn {xx}
+\tl_new:N \l_@@_role_tag_tmpa_tl
+\tl_new:N \l_@@_role_tag_namespace_tmpa_tl
+\tl_new:N \l_@@_role_role_tmpa_tl
+\tl_new:N \l_@@_role_role_namespace_tmpa_tl
+
+\keys_define:nn { @@ / tag-role }
+ {
+ ,tag .tl_set:N = \l_@@_role_tag_tmpa_tl
+ ,tag-namespace .tl_set:N = \l_@@_role_tag_namespace_tmpa_tl
+ ,role .tl_set:N = \l_@@_role_role_tmpa_tl
+ ,role-namespace .tl_set:N = \l_@@_role_role_namespace_tmpa_tl
+ }
\keys_define:nn { @@ / setup }
{
add-new-tag .code:n =
{
- \seq_set_split:Nnn \l_tmpa_seq { / } {#1/}
- \@@_role_add_tag:xx
+ \keys_set_known:nnnN
+ {@@/tag-role}
+ {
+ tag-namespace=user,
+ role-namespace=, %so that we can test for it.
+ #1
+ }{@@/tag-role}\l_tmpa_tl
+ \tl_if_empty:NF \l_tmpa_tl
{
- \seq_item:Nn \l_tmpa_seq {1}
+ \exp_args:NNno \seq_set_split:Nnn \l_tmpa_seq { / } {\l_tmpa_tl/}
+ \tl_set:Nx \l_@@_role_tag_tmpa_tl { \seq_item:Nn \l_tmpa_seq {1} }
+ \tl_set:Nx \l_@@_role_role_tmpa_tl { \seq_item:Nn \l_tmpa_seq {2} }
}
+ \tl_if_empty:NT \l_@@_role_role_namespace_tmpa_tl
{
- \seq_item:Nn \l_tmpa_seq {2}
+ \prop_get:NVNTF
+ \g_@@_role_tags_NS_prop
+ \l_@@_role_role_tmpa_tl
+ \l_@@_role_role_namespace_tmpa_tl
+ {
+ \prop_if_in:NVF\g_@@_role_NS_prop \l_@@_role_role_namespace_tmpa_tl
+ {
+ \tl_set:Nn \l_@@_role_role_namespace_tmpa_tl {user}
+ }
+ }
+ {
+ \tl_set:Nn \l_@@_role_role_namespace_tmpa_tl {user}
+ }
}
- }
+ \pdf_version_compare:NnTF < {2.0}
+ {
+ %TODO add check for emptyness?
+ \@@_role_add_tag:VV
+ \l_@@_role_tag_tmpa_tl
+ \l_@@_role_role_tmpa_tl
+ }
+ {
+ \@@_role_add_tag:VVVV
+ \l_@@_role_tag_tmpa_tl
+ \l_@@_role_tag_namespace_tmpa_tl
+ \l_@@_role_role_tmpa_tl
+ \l_@@_role_role_namespace_tmpa_tl
+ }
+ }
}
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf-space.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf-space.dtx
index edc5e445c70..bfe85344b64 100644
--- a/Master/texmf-dist/source/latex/tagpdf/tagpdf-space.dtx
+++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf-space.dtx
@@ -27,7 +27,7 @@
% \begin{macrocode}
%<@@=tag>
%<*space>
-\ProvidesExplPackage {tagpdf-space-code} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-space-code} {2021/05/14} {0.81}
{part of tagpdf - code related to real space chars}
% luatex uses an attribute (declared in the driver file) and some luacode in tagpdf.lua
% perhaps I will split the code by engine in the future
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf-struct.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf-struct.dtx
index 09ea3511882..9e66d4913d6 100644
--- a/Master/texmf-dist/source/latex/tagpdf/tagpdf-struct.dtx
+++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf-struct.dtx
@@ -27,30 +27,37 @@
% \begin{macrocode}
%<@@=tag>
%<*struct>
-\ProvidesExplPackage {tagpdf-struct-code} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-struct-code} {2021/05/14} {0.81}
{part of tagpdf - code related to storing structure}
-
+% \end{macrocode}
% I will use a latex counter for the structure count
% to have a chance to avoid double structures in align etc
-
+% \begin{macrocode}
\newcounter { g_@@_struct_abs_int }
\int_gzero:N \c@g_@@_struct_abs_int
-
-% ref code is in tagpdf.dtx
-
-% a sequence stores structnum -> the obj numbers
+% \end{macrocode}
+% a sequence to store structnum -> the obj numbers
% to allow easy mapping over the structures
-
+% \begin{macrocode}
\@@_seq_new:N \g_@@_struct_objR_seq
-
-% a sequence for the structure stack. When a sequence is opened it's number is put on the stack.
+% \end{macrocode}
+% a sequence for the structure stack.
+% When a sequence is opened it's number is put on the stack.
+% \begin{macrocode}
\seq_new:N \g_@@_struct_stack_seq
\seq_gpush:Nn \g_@@_struct_stack_seq {0}
-
-%this variables will hold the top entry and the parent on the stack
+% \end{macrocode}
+% We will perhaps also need the tags. While it is possible to get them from the
+% numbered stack, lets build a tag stack too.
+% \begin{macrocode}
+\seq_new:N \g_@@_struct_tag_stack_seq
+\seq_gpush:Nn \g_@@_struct_tag_stack_seq {Root}
+% \end{macrocode}
+%this variables will hold the number of top entry and the parent on the stack
+% \begin{macrocode}
\tl_new:N \l_@@_struct_stack_parent_tmp_tl
\tl_new:N \g_@@_struct_stack_current_tl
-
+% \end{macrocode}
% I need at least one structure: the StructTreeRoot
% normally it should have only one kid, e.g. the document element.
@@ -65,8 +72,7 @@
% (the root has a special set of properties).
% the values of the prop should be already escaped properly
% when the entries are created (title,lange,alt,E,actualtext)
-
-
+% \begin{macrocode}
\seq_const_from_clist:Nn \c_@@_struct_StructTreeRoot_entries_seq
{%p. 857/858
Type, % always /StructTreeRoot
@@ -75,7 +81,8 @@
ParentTree, % required,obj ref to the parent tree
ParentTreeNextKey, %optional
RoleMap,
- ClassMap
+ ClassMap,
+ Namespaces
}
\seq_const_from_clist:Nn \c_@@_struct_StructElem_entries_seq
@@ -131,19 +138,13 @@
\@@_seq_new:c { g_@@_struct_kids_0_seq }
-% deprecated
-%\@@_prop_gput:cno
-% { g_@@_struct_0_prop }
-% { objnum}
-% { \c_@@_tree_obj_structtreeroot_tl }
-
% new
-\@@_prop_gput:cno
+\@@_prop_gput:cnx
{ g_@@_struct_0_prop }
{ objref}
- { \pdf_object_ref:n { c_@@_struct_0_obj } }
+ { \pdf_object_ref:n { @@/struct/0 } }
-\@@_prop_gput:cno
+\@@_prop_gput:cnn
{ g_@@_struct_0_prop }
{ Type }
{ /StructTreeRoot }
@@ -152,23 +153,30 @@
\@@_prop_gput:cnx
{ g_@@_struct_0_prop }
{ ParentTree }
- { \pdf_object_ref:n { c_@@_tree_parenttree_obj } }
+ { \pdf_object_ref:n { @@/tree/parenttree } }
\@@_prop_gput:cnx
{ g_@@_struct_0_prop }
{ RoleMap }
- { \pdf_object_ref:n { c_@@_tree_rolemap_obj } }
+ { \pdf_object_ref:n { @@/tree/rolemap } }
-\@@_prop_gput:cno
+\@@_prop_gput:cnn
{ g_@@_struct_0_prop }
{ entries }
{ StructTreeRoot }
-\@@_prop_gput:cno
+\@@_prop_gput:cnn
{ g_@@_struct_0_prop }
{ num }
{ 0 }
+%Namespaces are pdf 2.0 but it doesn't harm to have an empty entry
+\@@_prop_gput:cnx
+ { g_@@_struct_0_prop }
+ { Namespaces }
+ { \pdf_object_ref:n { @@/tree/namespaces } }
+
+
% commands to store the kids
% I don't compare the page objects number yet, but always add the /Pg key, perhaps later
@@ -316,7 +324,7 @@
\@@_struct_get_dict_content:n { #1 }
\exp_args:Nx
\pdf_object_write:nx
- { c_@@_struct_#1_obj }
+ { @@/struct/#1 }
{
\l_@@_struct_dict_content_tl
}
@@ -326,23 +334,48 @@
}
}
+% this command allows to get the current structure tag. We will need to handle nesting
+% P
+\cs_new:Nn \@@_get_data_struct_tag:
+ {
+ \exp_args:Ne
+ \tl_tail:n
+ {
+ \prop_item:cn {g_@@_struct_\g__tag_struct_stack_current_tl _prop}{S}
+ }
+ }
+
% keys for the user commands
% should I pass the values (e.g. the tag) through an escape command?
+% we store the tag in a variable. But we should be careful, it is only reliable
+% at the begin
+\tl_new:N \g_@@_struct_tag_tl
+\tl_new:N \g_@@_struct_tag_NS_tl
+\cs_generate_variant:Nn \seq_set_split:Nnn{Nne}
\keys_define:nn { @@ / struct }
{
label .tl_set:N = \l_@@_struct_key_label_tl,
stash .bool_set:N = \l_@@_struct_elem_stash_bool,
tag .code:n = % S property
- {%%????????? \pdfescapename??
- \tl_set:Nx \l_@@_tmpa_tl { #1 }
+ {%%????????? \pdfescapename?? slash/not slash is here the question ...
+ \seq_set_split:Nne \l_tmpa_seq { / } {#1/\prop_item:Nn\g__tag_role_tags_NS_prop{#1}}
+ \tl_gset:Nx \g_@@_struct_tag_tl { \seq_item:Nn\l_tmpa_seq {1} }
+ \tl_gset:Nx \g_@@_struct_tag_NS_tl { \seq_item:Nn\l_tmpa_seq {2} }
\bool_if:NT \g_@@_check_tags_bool
{
- \@@_check_structure_tag:N \l_@@_tmpa_tl
+ \@@_check_structure_tag:N \g_@@_struct_tag_tl
}
\@@_prop_gput:cnx
{ g_@@_struct_\int_eval:n {\c@g_@@_struct_abs_int}_prop }
{ S }
- { /\exp_not:V\l_@@_tmpa_tl }
+ { \pdf_name_from_unicode_e:n{ \g_@@_struct_tag_tl} } %
+ \prop_get:NVNT \g_@@_role_NS_prop\g_@@_struct_tag_NS_tl\l_@@_tmpa_tl
+ {
+ \@@_prop_gput:cnx
+ { g_@@_struct_\int_eval:n {\c@g_@@_struct_abs_int}_prop }
+ { NS }
+ { \l_@@_tmpa_tl } %
+ }
},
title .code:n = % T property
{
@@ -513,7 +546,7 @@
%\@@_pdfreserveobjnum:N \l_tmpa_tl
\exp_args:Ne
\pdf_object_new:nn
- { c_@@_struct_\int_eval:n { \c@g_@@_struct_abs_int }_obj }
+ { @@/struct/\int_eval:n { \c@g_@@_struct_abs_int } }
{ dict }
\@@_prop_gput:cnx
{ g_@@_struct_\int_eval:n { \c@g_@@_struct_abs_int }_prop }
@@ -521,7 +554,7 @@
{
\exp_args:Ne
\pdf_object_ref:n
- {c_@@_struct_\int_eval:n { \c@g_@@_struct_abs_int }_obj}
+ {@@/struct/\int_eval:n { \c@g_@@_struct_abs_int }}
}
% \prop_show:c { g_@@_struct_\int_eval:n { \c@g_@@_struct_abs_int }_prop }
\@@_prop_gput:cnx
@@ -551,6 +584,7 @@
\msg_error:nn { tag } { struct-faulty-nesting }
}
\seq_gpush:NV \g_@@_struct_stack_seq \c@g_@@_struct_abs_int
+ \seq_gpush:NV \g_@@_struct_tag_stack_seq \g_@@_struct_tag_tl
\tl_gset:NV \g_@@_struct_stack_current_tl \c@g_@@_struct_abs_int
%\seq_show:N \g_@@_struct_stack_seq
\bool_if:NF
@@ -578,13 +612,12 @@
\group_end:
}
-%deprecated
-\cs_set_eq:NN \uftag_struct_begin:n \tag_struct_begin:n
\cs_new_protected:Nn \tag_struct_end:
{ %take the current structure num from the stack:
%the objects are written later, lua mode hasn't all needed info yet
%\seq_show:N \g_@@_struct_stack_seq
+ \seq_gpop:NN \g_@@_struct_tag_stack_seq \l_tmpa_tl
\seq_gpop:NNTF \g_@@_struct_stack_seq \l_tmpa_tl
{
\int_compare:nNnT {\l_@@_loglevel_int} > { 0 }
@@ -601,10 +634,13 @@
{
\@@_check_no_open_struck:
}
+ \seq_get:NNT \g_@@_struct_tag_stack_seq \l_tmpa_tl
+ {
+ \tl_gset:NV \g_@@_struct_tag_tl \l_tmpa_tl
+ }
}
-%deprecated
-\cs_set_eq:NN \uftag_struct_end: \tag_struct_end:
+
\cs_new_protected:Nn \tag_struct_use:n %#1 is the label
{
@@ -631,8 +667,6 @@
}
}
-\cs_set_eq:NN \uftag_struct_use:n \tag_struct_use:n
-
%%%% Code to tag links
%%%% this works for url, see exp-link.pdf.
@@ -677,7 +711,7 @@
% \end{macrocode}
% \begin{macrocode}
%<*attr>
-\ProvidesExplPackage {tagpdf-attr-code} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-attr-code} {2021/05/14} {0.81}
{part of tagpdf - code related to attributes and attribute classes}
% the obj is written in tagpdf-tree-code.
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx
index 35f622ca1c9..dd6b7863c79 100644
--- a/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx
+++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx
@@ -27,16 +27,22 @@
% \begin{macrocode}
%<@@=tag>
%<*tree>
-\ProvidesExplPackage {tagpdf-tree-code} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-tree-code} {2021/05/14} {0.81}
{part of tagpdf - code related to writing trees and dictionaries to the pdf}
%this does the actual finishing:
-%Is \AfterEndDocument the best places??
+%Is \AddToHook{enddocument/end} the best places??
\hook_gput_code:nnn{begindocument}{tagpdf}
{
\bool_if:NT \g_@@_active_tree_bool
{
- \AfterEndDocument { \tag_finish_structure: }
+ \sys_if_output_pdf:TF
+ {
+ \AddToHook{enddocument/end} { \tag_finish_structure: }
+ }
+ {
+ \AddToHook{shipout/lastpage} { \tag_finish_structure: }
+ }
}
}
@@ -48,7 +54,7 @@
%\tl_const:Nx \c_@@_tree_obj_structtreeroot_tl { \l_tmpa_tl }
%new
-\pdf_object_new:nn { c_@@_struct_0_obj }{ dict }
+\pdf_object_new:nn { @@/struct/0 }{ dict }
%need to think about the best place ...
\hook_gput_code:nnn{begindocument}{tagpdf}
@@ -58,7 +64,7 @@
\pdfmanagement_add:nnx
{ Catalog }
{ StructTreeRoot }
- { \pdf_object_ref:n { c_@@_struct_0_obj } }
+ { \pdf_object_ref:n { @@/struct/0 } }
}
}
\cs_new_protected:Nn \@@_tree_write_structtreeroot:
@@ -82,7 +88,7 @@
%\tl_const:Nx \c_@@_tree_obj_parenttree_tl { \l_tmpa_tl }
%new
-\pdf_object_new:nn { c_@@_tree_parenttree_obj }{ dict }
+\pdf_object_new:nn { @@/tree/parenttree }{ dict }
% we have two sets of entries in the parent tree:
% page streams and real objects.
@@ -188,39 +194,21 @@
\@@_tree_fill_parenttree:
}
\tl_put_right:NV \l_@@_parenttree_content_tl\g_@@_parenttree_objr_tl
- \pdf_object_write:nx { c_@@_tree_parenttree_obj }
+ \pdf_object_write:nx { @@/tree/parenttree }
{
/Nums\c_space_tl [\l_@@_parenttree_content_tl]
}
}
%the Rolemap tree
-%deprecated
-%\@@_pdfreserveobjnum:N \l_tmpa_tl
-%\tl_const:Nx \c_@@_tree_obj_rolemap_tl { \l_tmpa_tl }
-
-%new
-\pdf_object_new:nn { c_@@_tree_rolemap_obj }{ dict }
-\tl_new:N \l_@@_rolemap_content_tl
-
-\cs_new_protected:Nn \@@_tree_fill_rolemap:
- {
- \prop_map_inline:Nn \g_@@_role_rolemap_prop
- {
- \tl_put_right:Nx \l_@@_rolemap_content_tl
- {
- /##1\c_space_tl/##2^^J
- }
- }
- }
+\pdf_object_new:nn { @@/tree/rolemap }{ dict }
\cs_new_protected:Nn \@@_tree_write_rolemap:
{
- \@@_tree_fill_rolemap:
- \pdf_object_write:nx { c_@@_tree_rolemap_obj }
+ \pdf_object_write:nx { @@/tree/rolemap }
{
- \l_@@_rolemap_content_tl
+ \pdfdict_use:n{g_@@_role/RoleMap_dict}
}
}
@@ -248,16 +236,42 @@
\tl_if_empty:NF
\g_@@_attr_class_content_tl
{
- \pdf_object_new:nn { c_@@_tree_classmap_obj }{ dict }
+ \pdf_object_new:nn { @@/tree/classmap }{ dict }
% \@@_pdfreserveobjnum:N \l_tmpa_tl
% \tl_const:Nx \c_@@_tree_obj_classmap_tl { \l_tmpa_tl }
\pdf_object_write:nx
- { c_@@_tree_classmap_obj }
+ { @@/tree/classmap }
{ \g_@@_attr_class_content_tl }
\@@_prop_gput:cnx
{ g_@@_struct_0_prop }
{ ClassMap }
- { \pdf_object_ref:n { c_@@_tree_classmap_obj } }
+ { \pdf_object_ref:n { @@/tree/classmap } }
+ }
+ }
+
+% namespaces are only relevant for pdf2.0 but we don't care
+\pdf_object_new:nn{ @@/tree/namespaces }{array}
+\cs_new_protected:Npn \@@_tree_write_namespaces:
+ {
+ \prop_map_inline:Nn \g_@@_role_NS_prop
+ {
+ \pdfdict_if_empty:nF {g_@@_role/RoleMapNS_##1_dict}
+ {
+ \pdf_object_write:nx {@@/RoleMapNS/##1}
+ {
+ \pdfdict_use:n {g_@@_role/RoleMapNS_##1_dict}
+ }
+ \pdfdict_gput:nnx{g_@@_role/Namespace_##1_dict}
+ {RoleMapNS}{\pdf_object_ref:n {@@/RoleMapNS/##1}}
+ }
+ \pdf_object_write:nx{tag/NS/##1}
+ {
+ \pdfdict_use:n {g_@@_role/Namespace_##1_dict}
+ }
+ }
+ \pdf_object_write:nx {@@/tree/namespaces}
+ {
+ \prop_map_tokens:Nn \g_@@_role_NS_prop{\use_ii:nn}
}
}
@@ -267,12 +281,11 @@
\@@_tree_write_parenttree:
\@@_tree_write_rolemap:
\@@_tree_write_classmap:
+ \@@_tree_write_namespaces:
\@@_tree_write_structelements: %this is rather slow!!
\@@_tree_write_structtreeroot:
}
-%deprecated
-\cs_set_eq:NN \uftag_finish_structure: \tag_finish_structure:
%StructParents !!! we need a better hook for \g__pdf_BACKEND_thispage_shipout_tl!!
% No actually
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf.dtx
index 145b1509712..ba473d7022f 100644
--- a/Master/texmf-dist/source/latex/tagpdf/tagpdf.dtx
+++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf.dtx
@@ -27,7 +27,7 @@
% \begin{macrocode}
%<@@=tag>
%<*package>
-\ProvidesExplPackage {tagpdf} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf} {2021/05/14} {0.81}
{ A package to experiment with pdf tagging }
\bool_if:nF
@@ -122,9 +122,9 @@
\ref_attribute_gset:nnnn {tagstructobj} {}{now}
{
\exp_args:Ne
- \pdf_object_if_exist:nT {c__tag_struct_ \int_use:N \c@g__tag_struct_abs_int _obj}
+ \pdf_object_if_exist:nT {@@/struct/\int_use:N \c@g__tag_struct_abs_int}
{
- \pdf_object_ref:e{c__tag_struct_ \int_use:N \c@g_@@_struct_abs_int _obj}
+ \pdf_object_ref:e{@@/struct/\int_use:N \c@g_@@_struct_abs_int}
}
}
% replace by abspage??
@@ -208,6 +208,11 @@
\pdfmanagement_remove:nn {Page} {Tabs},
tabsorder .initial:n = structure,
uncompress .code:n = {\pdf_uncompress: },
+ global-mc .code:n =
+ {
+ \cs_set_eq:NN\@@_attribute_set:Nn \@@_attribute_gset:Nn
+ \cs_set_eq:NN\@@_attribute_unset:N\@@_attribute_gunset:N
+ }
}
%need to think about the right place ...
%\AtBeginDocument
@@ -217,6 +222,10 @@
{
\pdfmanagement_add:nnn { Catalog / MarkInfo } { Marked } { true }
}
+ \keys_define:nn { @@ / setup }
+ {
+ global-mc .code:n={}
+ }
}
% escape commands are a bit engine specific so have been moved to the backend files.
% commands to escape strings so that they can be safely used in pdf
@@ -326,9 +335,12 @@
%
% \begin{macrocode}
%<*user>
-\ProvidesExplPackage {tagpdf-user} {2021/02/23} {0.80}
+\ProvidesExplPackage {tagpdf-user} {2021/05/14} {0.81}
{tagpdf - user commands}
+% \end{macrocode}
+% \begin{macro}{\tagpdfsetup}
+% \begin{macrocode}
\NewDocumentCommand \tagpdfsetup { m }
{
\keys_set:nn { @@ / setup } { #1 }
@@ -337,8 +349,12 @@
\cs_set_eq:NN\tagpdfifluatexTF \sys_if_engine_luatex:TF
\cs_set_eq:NN\tagpdfifluatexT \sys_if_engine_luatex:T
\cs_set_eq:NN\tagpdfifpdftexT \sys_if_engine_pdftex:T
-
-%%% stop tagging
+% \end{macrocode}
+% \end{macro}
+% We need a command to stop tagging in some places.
+%
+% \begin{macro}{ \tag_stop_group_begin:, \tag_stop_group_end: }
+% \begin{macrocode}
\bool_new:N \l_@@_stop_bool
\prg_new_conditional:Nnn \@@_if_stop: {p,T,F,TF}
@@ -359,13 +375,6 @@
\cs_set_eq:NN \tag_struct_begin:n \use_none:n
\cs_set_eq:NN \tag_struct_end: \prg_do_nothing:
\cs_set_eq:NN \tag_struct_use:n \use_none:n
- %deprecated
- \cs_set_eq:NN \uftag_mc_begin:n \tag_mc_begin:n
- \cs_set_eq:NN \uftag_mc_end: \tag_mc_end:
- \cs_set_eq:NN \uftag_mc_use:n \tag_mc_use:n
- \cs_set_eq:NN \uftag_struct_begin:n \tag_struct_begin:n
- \cs_set_eq:NN \uftag_struct_end: \tag_struct_end:
- \cs_set_eq:NN \uftag_struct_use:n \tag_struct_use:n
}
\cs_new_protected:Npn \tag_stop_group_begin:
@@ -375,23 +384,34 @@
}
\cs_set_eq:NN \tag_stop_group_end: \group_end:
-
-
-%%% a generic command to retrieve data
-
+% \end{macrocode}
+% \end{macro}
+% We need a command to stop tagging in some places.
+%
+% \begin{macro}{ \tagpdfget, \tag_get:n }
+% This is a generic command to retrieve data. Currently
+% the only sensible value for the argument is |mc_tag|
+% \begin{macrocode}
\cs_new:Npn \tagpdfget #1 { \use:c {@@_get_data_#1: } }
\cs_new:Npn \tag_get:n #1 { \use:c {@@_get_data_#1: } }
-%deprecated:
-\cs_new:Npn \uftag_get:n #1 { \use:c {@@_get_data_#1: } }
-
-%%%% mc related user commands
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tagmcifinTF}
+% This is a test if an mc is open or not. It is mostly of
+% importance for pdflatex as lualatex doesn't mind much if a mc tag is not
+% correctly closed.
+% \begin{macrocode}
\NewDocumentCommand \tagmcifinTF { m m }
{
\@@_mc_if_in:TF { #1 } { #2 }
}
-
-
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{tagmcartifact}
+% \begin{macrocode}
\NewDocumentEnvironment{tagmcartifact}{m}
{
\tag_mc_artifact_group_begin:n { #1}\ignorespaces
@@ -400,6 +420,11 @@
\tag_mc_artifact_group_end:
}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tagmcbegin,\tagmcend,\tagmcuse }
+% \begin{macrocode}
\NewDocumentCommand \tagmcbegin { m }
{
\tag_mc_begin:n {#1}\ignorespaces
@@ -408,7 +433,7 @@
\NewDocumentCommand \tagmcend { }
{
- \unskip % this unskip appears to mess up some spacing; can we do this in another way?
+ \if_mode_horizontal: \unskip \fi: %
\tag_mc_end:
}
@@ -417,9 +442,13 @@
\tag_mc_use:n {#1}
}
-
-%%%% structure related commands
-
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tagstructbegin,\tagstructend,\tagstructuse }
+%
+% These are structure related user commands
+% \begin{macrocode}
\NewDocumentCommand \tagstructbegin { m }
{
\tag_struct_begin:n {#1}
@@ -435,9 +464,14 @@
\tag_struct_use:n {#1}
}
-
-
-%%%% debug/show commands
+% \end{macrocode}
+% \end{macro}
+%
+% \section{Debugging}
+%
+% \begin{macro}{\showtagpdfmcdata,\showtagpdfattributes }
+% This commands are lua only
+% \begin{macrocode}
\NewDocumentCommand\showtagpdfmcdata { O {\@@_tag_get_mc_abs_cnt:} }
{
\bool_if:NT \g_@@_mode_lua_bool
@@ -473,6 +507,15 @@
}
}
+\NewDocumentCommand\showtagstack {}
+ {
+ \seq_show:N \g_@@_struct_tag_stack_seq
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{ }
+% \begin{macrocode}
\sys_if_engine_luatex:T
{
\NewDocumentCommand\pdffakespace { }
@@ -480,19 +523,190 @@
\@@_fakespace:
}
}
+% \end{macrocode}
+% \end{macro}
+% \section{Paratagging}
+% The following are some simple commands to enable/disable paratagging.
+% Probably one should add some checks if we are already in a paragraph.
+% \begin{macrocode}
+\bool_new:N \l_@@_para_bool
+\bool_new:N \l_@@_para_show_bool
+\int_new:N \g_@@_para_int
+
+\keys_define:nn { @@ / setup }
+ {
+ paratagging .bool_set:N = \l_@@_para_bool,
+ paratagging-show .bool_set:N = \l_@@_para_show_bool,
+ }
+
+\AddToHook{para/begin}
+ {
+ \int_gincr:N \g_@@_para_int
+ \bool_if:NT \l__tag_para_bool
+ {
+ \tag_struct_begin:n {tag=P}
+ \bool_if:NT \l_@@_para_show_bool
+ { \tag_mc_begin:n{artifact}
+ \llap{\color_select:n{red}\tiny\int_use:N\g_@@_para_int\ }
+ \tag_mc_end:
+ }
+ \tag_mc_begin:n {tag=P}
+ }
+ }
+\AddToHook{para/end}
+ {
+ \bool_if:NT \l__tag_para_bool
+ {
+ \tag_mc_end:
+ \bool_if:NT \l_@@_para_show_bool
+ { \tag_mc_begin:n{artifact}
+ \rlap{\color_select:n{red}\tiny\ \int_use:N\g_@@_para_int}
+ \tag_mc_end:
+ }
+ \tag_struct_end:
+ }
+ }
+
+
+\newcommand\tagpdfparaOn {\bool_set_true:N \l__tag_para_bool}
+\newcommand\tagpdfparaOff{\bool_set_false:N \l__tag_para_bool}
-%</user>
% \end{macrocode}
-%
+% \section{Links}
+% We need to close and reopen mc-chunks around links.
+% With luatex the push/pop command must be outside groups,
+% so we add also code to the generic commands in the hyperref driver.
% \begin{macrocode}
-%<*deprecated>
-% \uftag_get:n
-% \uftag_mc_if_in:
-% \uftag_mc_begin:n
-% \uftag_mc_end:
-% \uftag_mc_use:n
-% \uftag_struct_begin:n
-% \uftag_struct_end:
-% \uftag_finish_structure:
-%</deprecated>
+\cs_generate_variant:Nn \pdfannot_dict_put:nnn {nnx}
+\hook_gput_code:nnn
+ {pdfannot/link/URI/before}
+ {tagpdf}
+ {
+ \bool_if:NT \g_@@_active_struct_bool
+ {
+ \tag_mc_end_push:
+ \tag_struct_begin:n { tag=Link }
+ \tag_mc_begin:n { tag=Link }
+ \pdfannot_dict_put:nnx
+ { link/URI }
+ { StructParent }
+ { \int_use:N\c@g_@@_parenttree_obj_int }
+ }
+ }
+
+\hook_gput_code:nnn
+ {pdfannot/link/URI/after}
+ {tagpdf}
+ {
+ \bool_if:NT \g_@@_active_struct_bool
+ {
+ \@@_struct_finish_link:
+ \tag_mc_end:
+ \tag_struct_end:
+ \tag_mc_begin_pop:n{}
+ }
+ }
+
+\hook_gput_code:nnn
+ {pdfannot/link/GoTo/before}
+ {tagpdf}
+ {
+ \bool_if:NT \g_@@_active_struct_bool
+ {
+ \tag_mc_end_push:
+ \tag_struct_begin:n{tag=Link}
+ \tag_mc_begin:n{tag=Link}
+ \pdfannot_dict_put:nnx
+ { link/GoTo }
+ { StructParent }
+ { \int_use:N\c@g_@@_parenttree_obj_int }
+ }
+ }
+
+\hook_gput_code:nnn
+ {pdfannot/link/GoTo/after}
+ {tagpdf}
+ {
+ \bool_if:NT \g_@@_active_struct_bool
+ {
+ \@@_struct_finish_link:
+ \tag_mc_end:
+ \tag_struct_end:
+ \tag_mc_begin_pop:n{}
+ }
+ }
+
+\hook_gput_code:nnn
+ {cmd/url/before}
+ {tagpdf}
+ {\tag_mc_end_push:}
+
+\hook_gput_code:nnn
+ {cmd/url/after}
+ {tagpdf}
+ {\tag_mc_begin_pop:n{}}
+
+\hook_gput_code:nnn
+ {cmd/href/before}
+ {tagpdf}
+ {\tag_mc_end_push:}
+
+\hook_gput_code:nnn
+ {cmd/href/after}
+ {tagpdf}
+ {\tag_mc_begin_pop:n{}}
+
+\hook_gput_code:nnn
+ {cmd/hrefurl/before}
+ {tagpdf}
+ {\tag_mc_end_push:}
+
+\hook_gput_code:nnn
+ {cmd/hrefurl/after}
+ {tagpdf}
+ {\tag_mc_begin_pop:n{}}
+
+%this will go when references are improved
+\hook_gput_code:nnn
+ {cmd/T@ref/before}
+ {tagpdf}
+ {\tag_mc_end_push:}
+
+\hook_gput_code:nnn
+ {cmd/T@ref/after}
+ {tagpdf}
+ {\tag_mc_begin_pop:n{}}
+
+\hook_gput_code:nnn
+ {cmd/T@pageref/before}
+ {tagpdf}
+ {\tag_mc_end_push:}
+
+\hook_gput_code:nnn
+ {cmd/T@pageref/after}
+ {tagpdf}
+ {\tag_mc_begin_pop:n{}}
+
+\hook_gput_code:nnn
+ {cmd/T@nameref/before}
+ {tagpdf}
+ {\tag_mc_end_push:}
+
+\hook_gput_code:nnn
+ {cmd/T@nameref/after}
+ {tagpdf}
+ {\tag_mc_begin_pop:n{}}
+% "alternative descriptions " for PAX3. How to get better text here??
+\pdfannot_dict_put:nnn
+ { link/URI }
+ { Contents }
+ { (url) }
+
+\pdfannot_dict_put:nnn
+ { link/GoTo }
+ { Contents }
+ { (ref) }
+
% \end{macrocode}
+%</user>
+%