summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-06-30 21:14:14 +0000
committerKarl Berry <karl@freefriends.org>2021-06-30 21:14:14 +0000
commitc604c653358384d71cfbdad75147fe6b3ef448d3 (patch)
treeaaa2eb4dac429b5bb9bdde1d867e88d75612e65d /Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty
parentf52cb629a5dd055df1ae60054f89cc718a5ce58e (diff)
tagpdf (30jun21)
git-svn-id: svn://tug.org/texlive/trunk@59769 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty')
-rw-r--r--Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty2235
1 files changed, 2128 insertions, 107 deletions
diff --git a/Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty b/Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty
index 75825724cfd..4b0623e244a 100644
--- a/Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty
+++ b/Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty
@@ -5,8 +5,16 @@
%% The original source files were:
%%
%% tagpdf.dtx (with options: `package')
+%% tagpdf-checks.dtx (with options: `package')
+%% tagpdf-user.dtx (with options: `package')
+%% tagpdf-mc-shared.dtx (with options: `shared')
+%% tagpdf.dtx (with options: `mcloading')
+%% tagpdf-tree.dtx (with options: `package')
+%% tagpdf-roles.dtx (with options: `package')
+%% tagpdf-struct.dtx (with options: `package')
+%% tagpdf-space.dtx (with options: `package')
%%
-%% 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
@@ -19,7 +27,7 @@
%% and all files in that bundle must be distributed together.
%%
%% File: tagpdf.dtx
-\ProvidesExplPackage {tagpdf} {2021-06-14} {0.82}
+\ProvidesExplPackage {tagpdf} {2021-06-29} {0.9}
{ A package to experiment with pdf tagging }
\bool_if:nF
@@ -41,29 +49,16 @@
before~\string\documentclass
}
}
-
-
\prop_if_exist:NT \g_msg_module_name_prop
{
\prop_gput:Nnn \g_msg_module_name_prop { tag }{ tagpdf }
}
-
-\cs_set_eq:NN \__tag_tex_global:D \tex_global:D
-
-%%% package options
\bool_new:N\g__tag_mode_lua_bool
-
\DeclareOption {luamode} { \sys_if_engine_luatex:T { \bool_gset_true:N \g__tag_mode_lua_bool } }
\DeclareOption {genericmode}{ \bool_gset_false:N\g__tag_mode_lua_bool }
\ExecuteOptions{luamode}
\ProcessOptions
-
-%%% some packages
\RequirePackage{l3ref-tmp}
- %================
- % temporary code
- % ===============
- % faking the LastPage label:
\cs_new_protected:Npn \__tag_lastpagelabel:
{
\legacy_if:nT { @filesw }
@@ -82,8 +77,6 @@
\AddToHook{enddocument/afterlastpage}
{\__tag_lastpagelabel:}
-
- % a command to override the general default. See issue in ref
\cs_if_exist:NF \ref_value:nnn
{
\cs_new:Npn \ref_value:nnn #1#2#3
@@ -97,66 +90,106 @@
\tl_if_exist:cTF { g__ref_label_ #1 _ #2 _tl }
{ \tl_use:c { g__ref_label_ #1 _ #2 _tl } }
{
- % test if attribute exist at all?
#3
}
}
}
- %=============
- % attributes
- %=============
-\ref_attribute_gset:nnnn {tagstruct} {0}{now} { \int_use:N \c@g__tag_struct_abs_int }
-\ref_attribute_gset:nnnn {tagstructobj} {}{now}
- {
- \exp_args:Ne
- \pdf_object_if_exist:nT {__tag/struct/\int_use:N \c@g__tag_struct_abs_int}
- {
- \pdf_object_ref:e{__tag/struct/\int_use:N \c@g__tag_struct_abs_int}
- }
- }
- % replace by abspage??
-\ref_attribute_gset:nnnn {tagabspage}{0}{shipout}{ \int_use:N \g_shipout_readonly_int }
-\ref_attribute_gset:nnnn {tagmcabs } {0}{now} { \int_use:N \c@g__tag_MCID_abs_int }
-\ref_attribute_gset:nnnn {tagmcid } {0}{now} { \int_use:N \g__tag_MCID_tmp_bypage_int }
-\clist_const:Nn \c__tag_refmc_clist {tagabspage,tagmcabs,tagmcid} %mc is new!!
+\tl_new:N \l__tag_tmpa_tl
+\str_new:N \l__tag_tmpa_str
+\prop_new:N \l__tag_tmpa_prop
+\seq_new:N \l__tag_tmpa_seq
+\seq_new:N \l__tag_tmpb_seq
+\clist_new:N \l__tag_tmpa_clist
+\int_new:N \l__tag_tmpa_int
+\clist_const:Nn \c__tag_refmc_clist {tagabspage,tagmcabs,tagmcid}
\clist_const:Nn \c__tag_refstruct_clist {tagstruct,tagstructobj}
+\int_new:N \l__tag_loglevel_int
+\bool_new:N \g__tag_active_space_bool
+\bool_new:N \g__tag_active_mc_bool
+\bool_new:N \g__tag_active_tree_bool
+\bool_new:N \g__tag_active_struct_bool
+
+\bool_new:N \l__tag_active_mc_bool
+\bool_set_true:N \l__tag_active_mc_bool
+\bool_new:N \l__tag_active_struct_bool
+\bool_set_true:N \l__tag_active_struct_bool
+\bool_new:N \g__tag_tagunmarked_bool
+\prg_generate_conditional_variant:Nnn \pdf_object_if_exist:n {e}{T,F}
+\cs_generate_variant:Nn \pdf_object_ref:n {e}
+\cs_generate_variant:Nn \pdfannot_dict_put:nnn {nnx}
+\cs_generate_variant:Nn \pdffile_embed_stream:nnn {nxx,oxx}
+\cs_generate_variant:Nn \prop_gput:Nnn {Nxx}
+\cs_generate_variant:Nn \prop_put:Nnn {Nxx}
\cs_generate_variant:Nn \ref_label:nn { nv }
+\cs_generate_variant:Nn \seq_set_split:Nnn{Nne}
+\cs_generate_variant:Nn \str_set_convert:Nnnn {Nonn, Noon, Nnon }
+
+\ref_attribute_gset:nnnn { tagstruct } {0} { now }
+ { \int_use:N \c@g__tag_struct_abs_int }
+\ref_attribute_gset:nnnn { tagstructobj } {} { now }
+ {
+ \pdf_object_if_exist:eT {__tag/struct/\int_use:N \c@g__tag_struct_abs_int}
+ {
+ \pdf_object_ref:e{__tag/struct/\int_use:N \c@g__tag_struct_abs_int}
+ }
+ }
+\ref_attribute_gset:nnnn { tagabspage } {0} { shipout }
+ { \int_use:N \g_shipout_readonly_int }
+\ref_attribute_gset:nnnn { tagmcabs } {0} { now }
+ { \int_use:N \c@g__tag_MCID_abs_int }
+\ref_attribute_gset:nnnn {tagmcid } {0} { now }
+ { \int_use:N \g__tag_MCID_tmp_bypage_int }
\cs_new_protected:Npn \__tag_ref_label:nn #1 #2 %#1 label, #2 name of list mc or struct
{
\@bsphack
\ref_label:nv {#1}{c__tag_ref#2_clist}
\@esphack
}
+\cs_generate_variant:Nn \__tag_ref_label:nn {en}
\cs_new:Npn \__tag_ref_value:nnn #1 #2 #3 %#1 label, #2 attribute, #3 default
{
\ref_value:nnn {#1}{#2}{#3}
}
+\cs_generate_variant:Nn \__tag_ref_value:nnn {enn}
\cs_new:Npn \__tag_ref_value_lastpage:nn #1 #2
{
\ref_value:nnn {__tag_LastPage}{#1}{#2}
}
-\cs_generate_variant:Nn \__tag_ref_label:nn {en}
-\cs_generate_variant:Nn \__tag_ref_value:nnn {enn}
-
-\RequirePackage{etoolbox}
+\cs_set_eq:NN \__tag_prop_new:N \prop_new:N
+\cs_set_eq:NN \__tag_seq_new:N \seq_new:N
+\cs_set_eq:NN \__tag_prop_gput:Nnn \prop_gput:Nnn
+\cs_set_eq:NN \__tag_seq_gput_right:Nn \seq_gput_right:Nn
+\cs_set_eq:NN \__tag_seq_item:cn \seq_item:cn
+\cs_set_eq:NN \__tag_prop_item:cn \prop_item:cn
+\cs_set_eq:NN \__tag_seq_show:N \seq_show:N
+\cs_set_eq:NN \__tag_prop_show:N \prop_show:N
-\cs_generate_variant:Nn \str_set_convert:Nnnn {Nonn, Noon, Nnon }
+\cs_generate_variant:Nn \__tag_prop_gput:Nnn { Nxn , Nxx, Nnx , cnn, cxn, cnx, cno}
+\cs_generate_variant:Nn \__tag_seq_gput_right:Nn { Nx , No, cn, cx }
+\cs_generate_variant:Nn \__tag_prop_new:N { c }
+\cs_generate_variant:Nn \__tag_seq_new:N { c }
+\cs_generate_variant:Nn \__tag_seq_show:N { c }
+\cs_generate_variant:Nn \__tag_prop_show:N { c }
-%%% tagpdfsetup,
-%%% TODO: checks need to be improved
-\int_new:N \l__tag_loglevel_int
-\tl_new:N \l__tag_tree_tabs_order_tl
+\cs_new_protected:Npn \tag_stop_group_begin:
+ {
+ \group_begin:
+ \bool_set_false:N \l__tag_active_struct_bool
+ \bool_set_false:N \l__tag_active_mc_bool
+ }
+\cs_set_eq:NN \tag_stop_group_end: \group_end:
\keys_define:nn { __tag / setup }
{
+ activate-space .bool_gset:N = \g__tag_active_space_bool,
activate-mc .bool_gset:N = \g__tag_active_mc_bool,
activate-tree .bool_gset:N = \g__tag_active_tree_bool,
activate-struct .bool_gset:N = \g__tag_active_struct_bool,
- activate-all .meta:n ={activate-mc,activate-tree,activate-struct},
- check-tags .bool_gset:N = \g__tag_check_tags_bool,
- check-tags .initial:n = true,
+ activate-all .meta:n =
+ {activate-mc,activate-tree,activate-struct},
+ % \end{macrocode}
log .choice:,
log / none .code:n = {\int_set:Nn \l__tag_loglevel_int { 0 }},
log / v .code:n = {\int_set:Nn \l__tag_loglevel_int { 1 }},
@@ -166,109 +199,2097 @@
tagunmarked .bool_gset:N = \g__tag_tagunmarked_bool,
tagunmarked .initial:n = true,
tabsorder .choice:,
- tabsorder / row .code:n = %{\tl_set:Nn \l__tag_tree_tabs_order_tl {/Tabs/R}},
+ tabsorder / row .code:n =
\pdfmanagement_add:nnn { Page } {Tabs}{/R},
- tabsorder / column .code:n = %{\tl_set:Nn \l__tag_tree_tabs_order_tl {/Tabs/C}},
+ tabsorder / column .code:n =
\pdfmanagement_add:nnn { Page } {Tabs}{/C},
- tabsorder / structure .code:n = %{\tl_set:Nn \l__tag_tree_tabs_order_tl {/Tabs/S}},
+ tabsorder / structure .code:n =
\pdfmanagement_add:nnn { Page } {Tabs}{/S},
- tabsorder / none .code:n = %{\tl_set:Nn \l__tag_tree_tabs_order_tl {}},
+ tabsorder / none .code:n =
\pdfmanagement_remove:nn {Page} {Tabs},
tabsorder .initial:n = structure,
- uncompress .code:n = {\pdf_uncompress: },
- global-mc .code:n =
+ uncompress .code:n = { \pdf_uncompress: },
+ }
+\sys_if_engine_luatex:T
+ {
+ \file_input:n {tagpdf-luatex.def}
+ }
+%% File: tagpdf-checks.dtx
+
+\msg_new:nnn { tag } {mc-nested} { nested~marked~content~found~-~mcid~#1 }
+\msg_new:nnn { tag } {mc-tag-missing} { required~tag~missing~-~mcid~#1 }
+\msg_new:nnn { tag } {mc-label-unknown}
+ { label~#1~unknown~or~has~been~already~used.\\
+ Either~rerun~or~remove~one~of~the~uses. }
+\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 }
+\msg_new:nnn { tag } {mc-current}
+ { current~MC:~
+ \bool_if:NTF\g__tag_in_mc_bool
+ {abscnt=\__tag_get_mc_abs_cnt:,~tag=\g__tag_mc_key_tag_tl}
+ {no~MC~open,~current~abscnt=\__tag_get_mc_abs_cnt:"}
+ }
+\msg_new:nnn { tag } {struct-no-objnum} { objnum~missing~for~structure~#1 }
+\msg_new:nnn { tag }
+ {struct-faulty-nesting}
+ { there~is~no~open~structure~on~the~stack }
+\msg_new:nnn { tag } {struct-missing-tag} { a~structure~must~have~a~tag! }
+\msg_new:nnn { tag } {struct-used-twice}
+ { structure~with~label~#1~has~already~been~used}
+\msg_new:nnn { tag } {struct-label-unknown}
+ { structure~with~label~#1~is~unknown~rerun}
+\msg_new:nnn { tag } {struct-show-closing}
+ { closing~structure~#1~tagged~\prop_item:cn{g__tag_struct_#1_prop}{S} }
+\msg_new:nnn { tag } {attr-unknown} { attribute~#1~is~unknown}
+\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-tag} { mapping~tag~#1~to~role~#2 }
+\msg_new:nnn { tag } {new-tag} { adding~new~tag~#1 }
+\msg_new:nnn { tag } {tree-mcid-index-wrong}
+ {something~is~wrong~with~the~mcid--rerun}
+\msg_new:nnn { tag } {sys-no-interwordspace}
+ {engine/output~mode~#1~doesn't~support~the~interword~spaces}
+\cs_new:Npn \tag_get:n #1 { \use:c {__tag_get_data_#1: } }
+\prg_new_conditional:Npnn \tag_if_active: { p , T , TF, F }
+ {
+ \bool_lazy_all:nTF
+ {
+ {\g__tag_active_struct_bool}
+ {\g__tag_active_mc_bool}
+ {\g__tag_active_tree_bool}
+ {\l__tag_active_struct_bool}
+ {\l__tag_active_mc_bool}
+ }
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+\prg_new_conditional:Npnn \__tag_check_if_active_mc: {T,F,TF}
+ {
+ \bool_lazy_and:nnTF { \g__tag_active_mc_bool } { \l__tag_active_mc_bool }
+ {
+ \prg_return_true:
+ }
{
- \cs_set_eq:NN\__tag_attribute_set:Nn \__tag_attribute_gset:Nn
- \cs_set_eq:NN\__tag_attribute_unset:N\__tag_attribute_gunset:N
+ \prg_return_false:
}
}
-\hook_gput_code:nnn{begindocument}{tagpdf}
+\prg_new_conditional:Npnn \__tag_check_if_active_struct: {T,F,TF}
{
- \bool_if:NT \g__tag_active_struct_bool
+ \bool_lazy_and:nnTF { \g__tag_active_struct_bool } { \l__tag_active_struct_bool }
{
- \pdfmanagement_add:nnn { Catalog / MarkInfo } { Marked } { true }
+ \prg_return_true:
}
- \keys_define:nn { __tag / setup }
+ {
+ \prg_return_false:
+ }
+ }
+\cs_new_protected:Npn \__tag_check_structure_has_tag:n #1 %#1 struct num
+ {
+ \prop_if_in:cnF { g__tag_struct_#1_prop }
+ {S}
+ {
+ \msg_error:nn { tag } {struct-missing-tag}
+ }
+ }
+\cs_new_protected:Npn \__tag_check_structure_tag:N #1
+ {
+ \prop_if_in:NoF \g__tag_role_tags_prop {#1}
+ {
+ \msg_warning:nnx { tag } {role-unknown-tag} {#1}
+ }
+ }
+\cs_new_protected:Npn \__tag_check_info_closing_struct:n #1 %#1 struct num
+ {
+ \int_compare:nNnT {\l__tag_loglevel_int} > { 0 }
+ {
+ \msg_info:nnn { tag } {struct-show-closing} {#1}
+ }
+ }
+
+\cs_generate_variant:Nn \__tag_check_info_closing_struct:n {o,x}
+\cs_new_protected:Npn \__tag_check_no_open_struct:
+ {
+ \msg_error:nn { tag } {struct-faulty-nesting}
+ }
+\cs_new_protected:Npn \__tag_check_struct_used:n #1 %#1 label
+ {
+ \prop_get:cnNT
+ {g__tag_struct_\__tag_ref_value:enn{tagpdfstruct-#1}{tagstruct}{unknown}_prop}
+ {P}
+ \l_tmpa_tl
+ {
+ \msg_warning:nnn { tag } {struct-used-twice} {#1}
+ }
+ }
+\cs_new_protected:Npn \__tag_check_add_tag_role:nn #1 #2 %#1 tag, #2 role
+ {
+ \tl_if_empty:nTF {#2}
+ {
+ \msg_warning:nnn { tag } {role-missing} {#1}
+ }
+ {
+ \prop_get:NnNTF \g__tag_role_tags_prop {#2} \l_tmpa_tl
+ {
+ \int_compare:nNnT {\l__tag_loglevel_int} > { 0 }
+ {
+ \msg_info:nnnn { tag } {role-tag} {#1} {#2}
+ }
+ }
+ {
+ \msg_warning:nnn { tag } {role-unknown} {#2}
+ }
+ }
+ }
+\cs_new_protected:Npn \__tag_check_mc_if_nested:
+ {
+ \__tag_mc_if_in:T
+ {
+ \msg_warning:nnx { tag } {mc-nested} { \__tag_get_mc_abs_cnt: }
+ }
+ }
+
+\cs_new_protected:Npn \__tag_check_mc_if_open:
+ {
+ \__tag_mc_if_in:F
+ {
+ \msg_warning:nnx { tag } {mc-not-open} { \__tag_get_mc_abs_cnt: }
+ }
+ }
+\cs_new_protected:Npn \__tag_check_mc_pushed_popped:nn #1 #2
+ {
+ \int_compare:nNnT
+ { \l__tag_loglevel_int } ={ 2 }
+ { \msg_info:nnx {tag}{mc-#1}{#2} }
+ \int_compare:nNnT
+ { \l__tag_loglevel_int } > { 2 }
+ {
+ \msg_info:nnx {tag}{mc-#1}{#2}
+ \seq_log:N \g__tag_mc_stack_seq
+ }
+ }
+\cs_new_protected:Npn \__tag_check_mc_tag:N #1 %#1 is var with a tag name in it
+ {
+ \tl_if_empty:NT #1
+ {
+ \msg_error:nnx { tag } {mc-tag-missing} { \__tag_get_mc_abs_cnt: }
+ }
+ \prop_if_in:NoF \g__tag_role_tags_NS_prop {#1}
{
- global-mc .code:n={}
+ \msg_warning:nnx { tag } {role-unknown-tag} {#1}
}
}
+\cs_new_protected:Npn \__tag_check_init_mc_used:
+ {
+ \intarray_new:Nn \g__tag_check_mc_used_intarray { 65536 }
+ \cs_gset_eq:NN \__tag_check_init_mc_used: \prg_do_nothing:
+ }
+\cs_new_protected:Npn \__tag_check_mc_used:n #1 %#1 mcid abscnt
+ {
+ \int_compare:nNnT {\l__tag_loglevel_int} > { 2 }
+ {
+ \__tag_check_init_mc_used:
+ \intarray_gset:Nnn \g__tag_check_mc_used_intarray
+ {#1}
+ { \intarray_item:Nn \g__tag_check_mc_used_intarray {#1} + 1 }
+ \int_compare:nNnT
+ {
+ \intarray_item:Nn \g__tag_check_mc_used_intarray {#1}
+ }
+ >
+ { 1 }
+ {
+ \msg_warning:nnn { tag } {mc-used-twice} {#1}
+ }
+ }
+ }
+\cs_new_protected:Npn \__tag_check_show_MCID_by_page:
+ {
+ \tl_set:Nx \l__tag_tmpa_tl
+ {
+ \__tag_ref_value_lastpage:nn
+ {abspage}
+ {-1}
+ }
+ \int_step_inline:nnnn {1}{1}
+ {
+ \l__tag_tmpa_tl
+ }
+ {
+ \seq_clear:N \l_tmpa_seq
+ \int_step_inline:nnnn
+ {1}
+ {1}
+ {
+ \__tag_ref_value_lastpage:nn
+ {tagmcabs}
+ {-1}
+ }
+ {
+ \int_compare:nT
+ {
+ \__tag_ref_value:enn
+ {mcid-####1}
+ {tagabspage}
+ {-1}
+ =
+ ##1
+ }
+ {
+ \seq_gput_right:Nx \l_tmpa_seq
+ {
+ Page##1-####1-
+ \__tag_ref_value:enn
+ {mcid-####1}
+ {tagmcid}
+ {-1}
+ }
+ }
+ }
+ \seq_show:N \l_tmpa_seq
+ }
+ }
+%% File: tagpdf-user.dtx
+\NewDocumentCommand \tagpdfsetup { m }
+ {
+ \keys_set:nn { __tag / setup } { #1 }
+ }
+\NewDocumentCommand \tagmcbegin { m }
+ {
+ \tag_mc_begin:n {#1}%\ignorespaces
+ }
-\cs_new:Nn \__tag_finish_page_hook: { }
+\NewDocumentCommand \tagmcend { }
+ {
+ %\if_mode_horizontal: \unskip \fi: %
+ \tag_mc_end:
+ }
+\NewDocumentCommand \tagmcuse { m }
+ {
+ \tag_mc_use:n {#1}
+ }
-\hook_gput_code:nnn
- { shipout/before }
- { tagpdf/cnt }
+
+\NewDocumentCommand \tagmcifinTF { m m }
{
- \__tag_finish_page_hook:
- %\int_gincr:N \g__tag_abspage_int
+ \tag_mc_if_in:TF { #1 } { #2 }
+ }
+\NewDocumentCommand \tagstructbegin { m }
+ {
+ \tag_struct_begin:n {#1}
}
-\sys_if_engine_xetex:T
- { %lets try with xelatex ...
- %\PackageError { tagpdf } { xelatex~is~not~supported~-~aborting } {}
- %\tex_endinput:D
- \file_input:n {tagpdf-pdftex.def}
+\NewDocumentCommand \tagstructend { }
+ {
+ \tag_struct_end:
+ }
+
+\NewDocumentCommand \tagstructuse { m }
+ {
+ \tag_struct_use:n {#1}
+ }
+\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
+\NewDocumentCommand\ShowTagging { m }
+ {
+ \keys_set:nn { __tag / show }{ #1}
+
+ }
+\keys_define:nn { __tag / show }
+ {
+ mc-data .code:n =
+ {
+ \sys_if_engine_luatex:T
+ {
+ \lua_now:e{ltx.__tag.trace.show_all_mc_data(#1,\__tag_get_mc_abs_cnt:,0)}
+ }
+ }
+ ,mc-data .default:n = 1
}
+\keys_define:nn { __tag / show }
+ { mc-current .code:n =
+ {
+ \bool_if:NTF \g__tag_mode_lua_bool
+ {
+ \sys_if_engine_luatex:T
+ {
+ \int_compare:nNnTF
+ { -2147483647 }
+ =
+ {
+ \lua_now:e
+ {
+ tex.print
+ (tex.getattribute
+ (luatexbase.attributes.g__tag_mc_cnt_attr))
+ }
+ }
+ {
+ \lua_now:e
+ {
+ ltx.__tag.trace.log
+ (
+ "mc-current:~no~MC~open,~current~abscnt
+ =\__tag_get_mc_abs_cnt:"
+ ,0
+ )
+ texio.write_nl("")
+ }
+ }
+ {
+ \lua_now:e
+ {
+ ltx.__tag.trace.log
+ (
+ "mc-current:~abscnt=\__tag_get_mc_abs_cnt:=="
+ ..
+ tex.getattribute(luatexbase.attributes.g__tag_mc_cnt_attr)
+ ..
+ "~=>tag="
+ ..
+ tostring
+ (ltx.__tag.func.get_tag_from
+ (tex.getattribute
+ (luatexbase.attributes.g__tag_mc_type_attr)))
+ ..
+ "="
+ ..
+ tex.getattribute
+ (luatexbase.attributes.g__tag_mc_type_attr)
+ ,0
+ )
+ texio.write_nl("")
+ }
+ }
+ }
+ }
+ {
+ \msg_note:nn{ tag }{ mc-current }
+ }
+ }
+ }
+\keys_define:nn { __tag / show }
+ {
+ struct-stack .choice:
+ ,struct-stack / log .code:n = \seq_log:N \g__tag_struct_tag_stack_seq
+ ,struct-stack / show .code:n = \seq_show:N \g__tag_struct_tag_stack_seq
+ ,struct-stack .default:n = show
+ }
+\cs_new_protected:Npn \__tag_add_document_structure:n #1
+ {
+ \hook_gput_code:nnn{begindocument}{tagpdf}{\tagstructbegin{tag=#1}}
+ \hook_gput_code:nnn{tagpdf/finish/before}{tagpdf}{\tagstructend}
+ }
+\keys_define:nn { __tag / setup}
+ {
+ activate .code:n =
+ {
+ \keys_set:nn { __tag / setup }
+ { activate-mc,activate-tree,activate-struct }
+ \__tag_add_document_structure:n {#1}
+ },
+ activate .default:n = Document
+ }
\sys_if_engine_luatex:T
{
- \file_input:n {tagpdf-luatex.def}
+ \NewDocumentCommand\pdffakespace { }
+ {
+ \__tag_fakespace:
+ }
+ }
+\bool_new:N \l__tag_para_bool
+\bool_new:N \l__tag_para_show_bool
+\int_new:N \g__tag_para_int
+\keys_define:nn { __tag / setup }
+ {
+ paratagging .bool_set:N = \l__tag_para_bool,
+ paratagging-show .bool_set:N = \l__tag_para_show_bool,
}
-\sys_if_engine_pdftex:T
+\AddToHook{para/begin}
{
- \file_input:n {tagpdf-pdftex.def}
+ \int_gincr:N \g__tag_para_int
+ \bool_if:NT \l__tag_para_bool
+ {
+ \tag_struct_begin:n {tag=P}
+ \bool_if:NT \l__tag_para_show_bool
+ { \tag_mc_begin:n{artifact}
+ \llap{\color_select:n{red}\tiny\int_use:N\g__tag_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__tag_para_show_bool
+ { \tag_mc_begin:n{artifact}
+ \rlap{\color_select:n{red}\tiny\ \int_use:N\g__tag_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}
+\hook_gput_code:nnn
+ {pdfannot/link/URI/before}
+ {tagpdf}
+ {
+ \tag_mc_end_push:
+ \tag_struct_begin:n { tag=Link }
+ \tag_mc_begin:n { tag=Link }
+ \pdfannot_dict_put:nnx
+ { link/URI }
+ { StructParent }
+ { \tag_struct_parent_int: }
}
-\sys_if_output_dvi:T
+\hook_gput_code:nnn
+ {pdfannot/link/URI/after}
+ {tagpdf}
{
- %\PackageError { tagpdf } { dvi~output~is~not~supported~-~aborting }{}
- %\tex_endinput:D
+ \tag_struct_insert_annot:xx {\pdfannot_link_ref_last:}{\tag_struct_parent_int:}
+ \tag_mc_end:
+ \tag_struct_end:
+ \tag_mc_begin_pop:n{}
}
-\cs_generate_variant:Nn \__tag_prop_gput:Nnn { Nxn , Nxx, Nnx , cnn, cxn, cnx, cno}
-\cs_generate_variant:Nn \__tag_seq_gput_right:Nn { Nx , No, cn, cx }
-\cs_generate_variant:Nn \__tag_prop_new:N { c }
-\cs_generate_variant:Nn \__tag_seq_new:N { c }
-\cs_generate_variant:Nn \__tag_seq_show:N { c }
-\cs_generate_variant:Nn \__tag_prop_show:N { c }
-\cs_generate_variant:Nn \prop_gput:Nnn {Nxx}
-\cs_generate_variant:Nn \prop_put:Nnn {Nxx}
+\hook_gput_code:nnn
+ {pdfannot/link/GoTo/before}
+ {tagpdf}
+ {
+ \tag_mc_end_push:
+ \tag_struct_begin:n{tag=Link}
+ \tag_mc_begin:n{tag=Link}
+ \pdfannot_dict_put:nnx
+ { link/GoTo }
+ { StructParent }
+ { \tag_struct_parent_int: }
+ }
-\cs_generate_variant:Nn \pdffile_embed_stream:nnn {nxx,oxx}
-\cs_generate_variant:Nn \pdf_object_ref:n {e}
+\hook_gput_code:nnn
+ {pdfannot/link/GoTo/after}
+ {tagpdf}
+ {
+ \tag_struct_insert_annot:xx {\pdfannot_link_ref_last:}{\tag_struct_parent_int:}
+ \tag_mc_end:
+ \tag_struct_end:
+ \tag_mc_begin_pop:n{}
+
+ }
+
+\pdfannot_dict_put:nnn
+ { link/URI }
+ { Contents }
+ { (url) }
+
+\pdfannot_dict_put:nnn
+ { link/GoTo }
+ { Contents }
+ { (ref) }
+
+%% File: tagpdf-mc.dtx
+
+\newcounter { g__tag_MCID_abs_int }
+\cs_new:Npn \__tag_get_mc_abs_cnt: { \int_use:N \c@g__tag_MCID_abs_int }
+\int_new:N \g__tag_MCID_tmp_bypage_int
+\__tag_prop_new:N \g__tag_mc_parenttree_prop
+\seq_new:N \g__tag_mc_stack_seq
+\tl_new:N \l__tag_mc_artifact_type_tl
+\bool_new:N \l__tag_mc_key_stash_bool
+\bool_new:N \l__tag_mc_artifact_bool
+\tl_new:N \l__tag_mc_key_tag_tl
+\tl_new:N \g__tag_mc_key_tag_tl
+\tl_new:N \l__tag_mc_key_label_tl
+\tl_new:N \l__tag_mc_key_properties_tl
+\cs_new:Nn \__tag_mc_handle_mc_label:n
+ {
+ \__tag_ref_label:en{tagpdf-#1}{mc}
+ }
+\cs_new_protected:Npn \__tag_mc_set_label_used:n #1 %#1 labelname
+ {
+ \tl_new:c { g__tag_mc_label_\tl_to_str:n{#1}_used_tl }
+ }
+\cs_new_protected:Npn \tag_mc_use:n #1 %#1: label name
+ {
+ \__tag_check_if_active_struct:T
+ {
+ \tl_set:Nx \l__tag_tmpa_tl { \__tag_ref_value:nnn{tagpdf-#1}{tagmcabs}{} }
+ \tl_if_empty:NTF\l__tag_tmpa_tl
+ {
+ \msg_warning:nnn {tag} {mc-label-unknown} {#1}
+ }
+ {
+ \cs_if_free:cTF { g__tag_mc_label_\tl_to_str:n{#1}_used_tl }
+ {
+ \__tag_mc_handle_stash:x { \l__tag_tmpa_tl }
+ \__tag_mc_set_label_used:n {#1}
+ }
+ {
+ \msg_warning:nnn {tag}{mc-used-twice}{#1}
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \tag_mc_artifact_group_begin:n #1
+ {
+ \tag_mc_end_push:
+ \tag_mc_begin:n {artifact=#1}
+ \tag_stop_group_begin:
+ }
+
+\cs_new_protected:Npn \tag_mc_artifact_group_end:
+ {
+ \tag_stop_group_end:
+ \tag_mc_end:
+ \tag_mc_begin_pop:n{}
+ }
+\cs_new_protected:Npn \tag_mc_end_push:
+ {
+ \__tag_check_if_active_mc:T
+ {
+ \__tag_mc_if_in:TF
+ {
+ \seq_gpush:Nx \g__tag_mc_stack_seq { \tag_get:n {mc_tag} }
+ \__tag_check_mc_pushed_popped:nn
+ { pushed }
+ { \tag_get:n {mc_tag} }
+ \tag_mc_end:
+ }
+ {
+ \seq_gpush:Nn \g__tag_mc_stack_seq {-1}
+ \__tag_check_mc_pushed_popped:nn { pushed }{-1}
+ }
+ }
+ }
-\tl_new:N \g__tag_tmpa_tl
-\tl_new:N \l__tag_tmpa_tl
-\tl_new:N \l__tag_tmpb_tl
-\tl_new:N \l__tag_tmpc_tl
-\tl_new:N \l__tag_tmpd_tl
-\tl_new:N \l__tag_tmpe_tl
-\str_new:N \l__tag_tmpa_str
-
-\cs_new:Nn\__tag_prop_count:nn { + 1 }
-
-%% Loading the tagpdf sub packages
-\RequirePackage { tagpdf-checks-code }
-\RequirePackage { tagpdf-user }
-\RequirePackage { tagpdf-tree-code }
-\RequirePackage { tagpdf-roles-code }
-\RequirePackage { tagpdf-attr-code }
-\RequirePackage { tagpdf-mc-code-shared }
+\cs_new_protected:Npn \tag_mc_begin_pop:n #1
+ {
+ \__tag_check_if_active_mc:T
+ {
+ \seq_gpop:NNTF \g__tag_mc_stack_seq \l__tag_tmpa_tl
+ {
+ \tl_if_eq:NnTF \l__tag_tmpa_tl {-1}
+ {
+ \__tag_check_mc_pushed_popped:nn {popped}{-1}
+ }
+ {
+ \__tag_check_mc_pushed_popped:nn {popped}{\l__tag_tmpa_tl}
+ \tag_mc_begin:n {tag=\l__tag_tmpa_tl,#1}
+ }
+ }
+ {
+ \__tag_check_mc_pushed_popped:nn {popped}{empty~stack,~nothing}
+ }
+ }
+ }
+\keys_define:nn { __tag / mc }
+ {
+ stash .bool_set:N = \l__tag_mc_key_stash_bool,
+ __artifact-bool .bool_set:N = \l__tag_mc_artifact_bool,
+ __artifact-type .choice:,
+ __artifact-type / pagination .code:n =
+ {
+ \tl_set:Nn \l__tag_mc_artifact_type_tl { Pagination }
+ },
+ __artifact-type / layout .code:n =
+ {
+ \tl_set:Nn \l__tag_mc_artifact_type_tl { Layout }
+ },
+ __artifact-type / page .code:n =
+ {
+ \tl_set:Nn \l__tag_mc_artifact_type_tl { Page }
+ },
+ __artifact-type / background .code:n =
+ {
+ \tl_set:Nn \l__tag_mc_artifact_type_tl { Background }
+ },
+ __artifact-type / notype .code:n =
+ {
+ \tl_set:Nn \l__tag_mc_artifact_type_tl {}
+ },
+ __artifact-type / .code:n =
+ {
+ \tl_set:Nn \l__tag_mc_artifact_type_tl {}
+ },
+ }
+%% File: tagpdf.dtx
\bool_if:NTF \g__tag_mode_lua_bool
{
\RequirePackage {tagpdf-mc-code-lua}
}
{
- \RequirePackage { tagpdf-mc-code-generic } %
+ \RequirePackage {tagpdf-mc-code-generic} %
+ }
+%% File: tagpdf-tree.dtx
+\hook_gput_code:nnn{begindocument}{tagpdf}
+ {
+ \bool_if:NT \g__tag_active_tree_bool
+ {
+ \sys_if_output_pdf:TF
+ {
+ \AddToHook{enddocument/end} { \__tag_finish_structure: }
+ }
+ {
+ \AddToHook{shipout/lastpage} { \__tag_finish_structure: }
+ }
+ }
+ }
+\pdf_object_new:nn { __tag/struct/0 }{ dict }
+\hook_gput_code:nnn{shipout/lastpage}{tagpdf}
+ {
+ \bool_if:NT \g__tag_active_tree_bool
+ {
+ \pdfmanagement_add:nnn { Catalog / MarkInfo } { Marked } { true }
+ \pdfmanagement_add:nnx
+ { Catalog }
+ { StructTreeRoot }
+ { \pdf_object_ref:n { __tag/struct/0 } }
+ }
+ }
+\cs_new_protected:Npn \__tag_tree_write_structtreeroot:
+ {
+ \__tag_prop_gput:cnx
+ { g__tag_struct_0_prop }
+ { ParentTree }
+ { \pdf_object_ref:n { __tag/tree/parenttree } }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_0_prop }
+ { RoleMap }
+ { \pdf_object_ref:n { __tag/tree/rolemap } }
+ \__tag_struct_write_obj:n { 0 }
+ }
+\cs_new_protected:Npn \__tag_tree_write_structelements:
+ {
+ \int_step_inline:nnnn {1}{1}{\c@g__tag_struct_abs_int}
+ {
+ \__tag_struct_write_obj:n { ##1 }
+ }
+ }
+\pdf_object_new:nn { __tag/tree/parenttree }{ dict }
+\newcounter { g__tag_parenttree_obj_int }
+\hook_gput_code:nnn{begindocument}{tagpdf}
+ {
+ \int_gset:Nn
+ \c@g__tag_parenttree_obj_int
+ { \__tag_ref_value_lastpage:nn{abspage}{100} }
+ }
+\tl_new:N \g__tag_parenttree_objr_tl
+\cs_new_protected:Npn \__tag_parenttree_add_objr:nn #1 #2 %#1 StructParent number, #2 objref
+ {
+ \tl_gput_right:Nx \g__tag_parenttree_objr_tl
+ {
+ #1 \c_space_tl #2 ^^J
+ }
+ }
+\tl_new:N \l__tag_parenttree_content_tl
+
+\cs_new_protected:Npn \__tag_tree_fill_parenttree:
+ {
+ \int_step_inline:nnnn{1}{1}{\__tag_ref_value_lastpage:nn{abspage}{-1}} %not quite clear if labels are needed. See lua code
+ { %page ##1
+ \prop_clear:N \l__tag_tmpa_prop
+ \int_step_inline:nnnn{1}{1}{\__tag_ref_value_lastpage:nn{tagmcabs}{-1}}
+ {
+ %mcid####1
+ \int_compare:nT
+ {\__tag_ref_value:enn{mcid-####1}{tagabspage}{-1}=##1} %mcid is on current page
+ {% yes
+ \prop_put:Nxx
+ \l__tag_tmpa_prop
+ {\__tag_ref_value:enn{mcid-####1}{tagmcid}{-1}}
+ {\prop_item:Nn \g__tag_mc_parenttree_prop {####1}}
+ }
+ }
+ \tl_put_right:Nx\l__tag_parenttree_content_tl
+ {
+ \int_eval:n {##1-1}\c_space_tl
+ [\c_space_tl %]
+ }
+ \int_step_inline:nnnn
+ {0}
+ {1}
+ { \prop_count:N \l__tag_tmpa_prop -1 }
+ {
+ \prop_get:NnNTF \l__tag_tmpa_prop {####1} \l__tag_tmpa_tl
+ {% page#1:mcid##1:\l__tag_tmpa_tl :content
+ \tl_put_right:Nx \l__tag_parenttree_content_tl
+ {
+ \pdf_object_if_exist:eT { __tag/struct/\l__tag_tmpa_tl }
+ {
+ \pdf_object_ref:e { __tag/struct/\l__tag_tmpa_tl }
+ }
+ \c_space_tl
+ }
+ }
+ {
+ \msg_warning:nn { tag } {tree-mcid-index-wrong}
+ }
+ }
+ \tl_put_right:Nn
+ \l__tag_parenttree_content_tl
+ {%[
+ ]^^J
+ }
+ }
+ }
+\cs_new_protected:Npn \__tag_tree_lua_fill_parenttree:
+ {
+ \tl_set:Nn \l__tag_parenttree_content_tl
+ {
+ \lua_now:e
+ {
+ ltx.__tag.func.output_parenttree
+ (
+ \int_use:N\g_shipout_readonly_int
+ )
+ }
+ }
+ }
+\cs_new_protected:Npn \__tag_tree_write_parenttree:
+ {
+ \bool_if:NTF \g__tag_mode_lua_bool
+ {
+ \__tag_tree_lua_fill_parenttree:
+ }
+ {
+ \__tag_tree_fill_parenttree:
+ }
+ \tl_put_right:NV \l__tag_parenttree_content_tl\g__tag_parenttree_objr_tl
+ \pdf_object_write:nx { __tag/tree/parenttree }
+ {
+ /Nums\c_space_tl [\l__tag_parenttree_content_tl]
+ }
+ }
+\pdf_object_new:nn { __tag/tree/rolemap }{ dict }
+\cs_new_protected:Npn \__tag_tree_write_rolemap:
+ {
+ \pdf_object_write:nx { __tag/tree/rolemap }
+ {
+ \pdfdict_use:n{g__tag_role/RoleMap_dict}
+ }
+ }
+\cs_new_protected:Npn \__tag_tree_write_classmap:
+ {
+ \tl_clear:N \l__tag_tmpa_tl
+ \seq_gremove_duplicates:N \g__tag_attr_class_used_seq
+ \seq_set_map:NNn \l__tag_tmpa_seq \g__tag_attr_class_used_seq
+ {
+ /##1\c_space_tl
+ <<
+ \prop_item:Nn
+ \g__tag_attr_entries_prop
+ {##1}
+ >>
+ }
+ \tl_set:Nx \l__tag_tmpa_tl
+ {
+ \seq_use:Nn
+ \l__tag_tmpa_seq
+ { \iow_newline: }
+ }
+ \tl_if_empty:NF
+ \l__tag_tmpa_tl
+ {
+ \pdf_object_new:nn { __tag/tree/classmap }{ dict }
+ \pdf_object_write:nx
+ { __tag/tree/classmap }
+ { \l__tag_tmpa_tl }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_0_prop }
+ { ClassMap }
+ { \pdf_object_ref:n { __tag/tree/classmap } }
+ }
+ }
+\pdf_object_new:nn{ __tag/tree/namespaces }{array}
+\cs_new_protected:Npn \__tag_tree_write_namespaces:
+ {
+ \prop_map_inline:Nn \g__tag_role_NS_prop
+ {
+ \pdfdict_if_empty:nF {g__tag_role/RoleMapNS_##1_dict}
+ {
+ \pdf_object_write:nx {__tag/RoleMapNS/##1}
+ {
+ \pdfdict_use:n {g__tag_role/RoleMapNS_##1_dict}
+ }
+ \pdfdict_gput:nnx{g__tag_role/Namespace_##1_dict}
+ {RoleMapNS}{\pdf_object_ref:n {__tag/RoleMapNS/##1}}
+ }
+ \pdf_object_write:nx{tag/NS/##1}
+ {
+ \pdfdict_use:n {g__tag_role/Namespace_##1_dict}
+ }
+ }
+ \pdf_object_write:nx {__tag/tree/namespaces}
+ {
+ \prop_map_tokens:Nn \g__tag_role_NS_prop{\use_ii:nn}
+ }
+ }
+\cs_new_protected:Npn \__tag_finish_structure:
+ {
+ \bool_if:NT\g__tag_active_tree_bool
+ {
+ \hook_use:n {tagpdf/finish/before}
+ \__tag_tree_write_parenttree:
+ \__tag_tree_write_rolemap:
+ \__tag_tree_write_classmap:
+ \__tag_tree_write_namespaces:
+ \__tag_tree_write_structelements: %this is rather slow!!
+ \__tag_tree_write_structtreeroot:
+ }
+ }
+\hook_gput_code:nnn{begindocument}{tagpdf}
+ {
+ \bool_if:NT\g__tag_active_tree_bool
+ {
+ \hook_gput_code:nnn{shipout/before} { tagpdf/structparents }
+ {
+ \pdfmanagement_add:nnx
+ { Page }
+ { StructParents }
+ { \int_eval:n { \g_shipout_readonly_int} }
+ }
+ }
+ }
+%% File: tagpdf-roles.dtx
+\__tag_seq_new:N \g__tag_role_tags_seq %to get names (type/NS) from numbers
+\__tag_prop_new:N \g__tag_role_tags_prop %to get numbers from names (type/NS)
+\prop_new:N \g__tag_role_tags_NS_prop %to namespace info
+\prop_new:N \g__tag_role_NS_prop % collect namespaces
+\tl_new:N \l__tag_role_tag_tmpa_tl
+\tl_new:N \l__tag_role_tag_namespace_tmpa_tl
+\tl_new:N \l__tag_role_role_tmpa_tl
+\tl_new:N \l__tag_role_role_namespace_tmpa_tl
+\cs_new_protected:Npn \__tag_role_NS_new:nnn #1 #2 #3
+ {
+ \pdf_object_new:nn {tag/NS/#1}{dict}
+ \pdfdict_new:n {g__tag_role/Namespace_#1_dict}
+ \pdf_object_new:nn {__tag/RoleMapNS/#1}{dict}
+ \pdfdict_new:n {g__tag_role/RoleMapNS_#1_dict}
+ \pdfdict_gput:nnn
+ {g__tag_role/Namespace_#1_dict}
+ {Type}
+ {/Namespace}
+ \pdf_string_from_unicode:nnN{utf8/string}{#2}\l_tmpa_str
+ \tl_if_empty:NF \l_tmpa_str
+ {
+ \pdfdict_gput:nnx
+ {g__tag_role/Namespace_#1_dict}
+ {NS}
+ {\l_tmpa_str}
+ }
+ %RoleMapNS is added in tree
+ \tl_if_empty:nF {#3}
+ {
+ \pdfdict_gput:nnx{g__tag_role/Namespace_#1_dict}
+ {Schema}{#3}
+ }
+ \prop_gput:Nnx \g__tag_role_NS_prop {#1}{\pdf_object_ref:n{tag/NS/#1}~}
+ }
+\str_const:Nx \c__tag_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}}
+ }
+\pdf_version_compare:NnT > {1.9}
+ {
+ \__tag_role_NS_new:nnn {pdf} {http://iso.org/pdf/ssn}{}
+ \__tag_role_NS_new:nnn {pdf2} {http://iso.org/pdf2/ssn}{}
+ \__tag_role_NS_new:nnn {mathml}{http://www.w3.org/1998/Math/MathML}{}
+ \exp_args:Nnx
+ \__tag_role_NS_new:nnn {user}{\c__tag_role_userNS_id_str}{}
+ }
+\clist_const:Nn \c__tag_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.
+ Sect, %A container for grouping related content elements.
+ Div, %A generic block-level element or group of elements
+ Caption, %A brief portion of text describing a table or figure.
+ Index,
+ NonStruct, %probably not needed
+ H,
+ H1,
+ H2,
+ H3,
+ H4,
+ H5,
+ H6,
+ P,
+ L, %list
+ LI, %list item (around label and list item body)
+ Lbl, %list label
+ LBody, %list item body
+ Table,
+ TR, %table row
+ TH, %table header cell
+ TD, %table data cell
+ THead, %table header (n rows)
+ TBody, %table rows
+ TFoot, %table footer
+ Span, %generic inline marker
+ Link, %
+ Annot,
+ Figure,
+ Formula,
+ Form,
+ % ruby warichu etc ..
+ Ruby,
+ RB,
+ RT,
+ Warichu,
+ WT,
+ WP,
+ Artifact % only MC-tag ?...
+ }
+
+\clist_const:Nn \c__tag_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__tag_role_sttags_only_pdfII_clist
+ {
+ DocumentFragment
+ ,Aside
+ ,H7
+ ,H8
+ ,H9
+ ,H10
+ ,Title
+ ,FENote
+ ,Sub
+ ,Em
+ ,Strong
+ ,Artifact
+ }
+
+\clist_const:Nn \c__tag_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__tag_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,
+ }
+
+\clist_map_inline:Nn \c__tag_role_sttags_pdf_pdfII_clist
+ {
+ \__tag_seq_gput_right:Nn \g__tag_role_tags_seq { #1 }
+ \prop_gput:Nnn \g__tag_role_tags_NS_prop { #1 }{ pdf2 }
+ }
+\clist_map_inline:Nn \c__tag_role_sttags_only_pdf_clist
+ {
+ \__tag_seq_gput_right:Nn \g__tag_role_tags_seq { #1 }
+ \prop_gput:Nnn \g__tag_role_tags_NS_prop { #1 }{ pdf }
+ }
+\clist_map_inline:Nn \c__tag_role_sttags_only_pdfII_clist
+ {
+ \__tag_seq_gput_right:Nn \g__tag_role_tags_seq { #1 }
+ \prop_gput:Nnn \g__tag_role_tags_NS_prop { #1 }{ pdf2 }
}
+\pdf_version_compare:NnT > {1.9}
+ {
+ \clist_map_inline:Nn \c__tag_role_sttags_mathml_clist
+ {
+ \__tag_seq_gput_right:Nn \g__tag_role_tags_seq { #1 }
+ \prop_gput:Nnn \g__tag_role_tags_NS_prop { #1 }{ mathml }
+ }
+ }
+\int_step_inline:nnnn { 1 }{ 1 }{ \seq_count:N \g__tag_role_tags_seq }
+ {
+ \__tag_prop_gput:Nxn \g__tag_role_tags_prop
+ {
+ \seq_item:Nn \g__tag_role_tags_seq { #1 }
+ }
+ { #1 }
+ }
+\pdfdict_new:n {g__tag_role/RoleMap_dict}
+\cs_new_protected:Nn \__tag_role_add_tag:nn %(new) name, reference to old
+ {
+ \prop_if_in:NnF \g__tag_role_tags_prop {#1}
+ {
+ \int_compare:nNnT {\l__tag_loglevel_int} > { 0 }
+ {
+ \msg_info:nnn { tag }{new-tag}{#1}
+ }
+ \__tag_seq_gput_right:Nn \g__tag_role_tags_seq { #1 }
+ \__tag_prop_gput:Nnx \g__tag_role_tags_prop { #1 }
+ {
+ \seq_count:N \g__tag_role_tags_seq
+ }
+ \prop_gput:Nnn \g__tag_role_tags_NS_prop { #1 }{ user }
+ }
+ \__tag_check_add_tag_role:nn {#1}{#2}
+ \tl_if_empty:nF { #2 }
+ {
+ \pdfdict_gput:nnx {g__tag_role/RoleMap_dict}
+ {#1}
+ {\pdf_name_from_unicode_e:n{#2}}
+ }
+ }
+\cs_generate_variant:Nn \__tag_role_add_tag:nn {VV}
+
+\pdf_version_compare:NnT < {2.0}
+ {
+ \prop_map_inline:Nn \c__tag_role_sttags_pdfII_to_pdf_prop
+ {
+ \__tag_role_add_tag:nn {#1}{#2}
+ }
+ }
+
+\cs_new_protected:Nn \__tag_role_add_tag:nnnn %tag/namespace/role/namespace
+ {
+ \int_compare:nNnT {\l__tag_loglevel_int} > { 0 }
+ {
+ \msg_info:nnn { tag }{new-tag}{#1}
+ }
+ \__tag_seq_gput_right:Nn \g__tag_role_tags_seq { #1 }
+ \__tag_prop_gput:Nnx \g__tag_role_tags_prop { #1 }
+ {
+ \seq_count:N \g__tag_role_tags_seq
+ }
+ \prop_gput:Nnn \g__tag_role_tags_NS_prop { #1 }{ #2 }
+ \__tag_check_add_tag_role:nn {#1}{#3}
+ \pdfdict_gput:nnx {g__tag_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 \__tag_role_add_tag:nnnn {VVVV}
+\keys_define:nn { __tag / tag-role }
+ {
+ ,tag .tl_set:N = \l__tag_role_tag_tmpa_tl
+ ,tag-namespace .tl_set:N = \l__tag_role_tag_namespace_tmpa_tl
+ ,role .tl_set:N = \l__tag_role_role_tmpa_tl
+ ,role-namespace .tl_set:N = \l__tag_role_role_namespace_tmpa_tl
+ }
+
+\keys_define:nn { __tag / setup }
+ {
+ add-new-tag .code:n =
+ {
+ \keys_set_known:nnnN
+ {__tag/tag-role}
+ {
+ tag-namespace=user,
+ role-namespace=, %so that we can test for it.
+ #1
+ }{__tag/tag-role}\l_tmpa_tl
+ \tl_if_empty:NF \l_tmpa_tl
+ {
+ \exp_args:NNno \seq_set_split:Nnn \l_tmpa_seq { / } {\l_tmpa_tl/}
+ \tl_set:Nx \l__tag_role_tag_tmpa_tl { \seq_item:Nn \l_tmpa_seq {1} }
+ \tl_set:Nx \l__tag_role_role_tmpa_tl { \seq_item:Nn \l_tmpa_seq {2} }
+ }
+ \tl_if_empty:NT \l__tag_role_role_namespace_tmpa_tl
+ {
+ \prop_get:NVNTF
+ \g__tag_role_tags_NS_prop
+ \l__tag_role_role_tmpa_tl
+ \l__tag_role_role_namespace_tmpa_tl
+ {
+ \prop_if_in:NVF\g__tag_role_NS_prop \l__tag_role_role_namespace_tmpa_tl
+ {
+ \tl_set:Nn \l__tag_role_role_namespace_tmpa_tl {user}
+ }
+ }
+ {
+ \tl_set:Nn \l__tag_role_role_namespace_tmpa_tl {user}
+ }
+ }
+ \pdf_version_compare:NnTF < {2.0}
+ {
+ %TODO add check for emptyness?
+ \__tag_role_add_tag:VV
+ \l__tag_role_tag_tmpa_tl
+ \l__tag_role_role_tmpa_tl
+ }
+ {
+ \__tag_role_add_tag:VVVV
+ \l__tag_role_tag_tmpa_tl
+ \l__tag_role_tag_namespace_tmpa_tl
+ \l__tag_role_role_tmpa_tl
+ \l__tag_role_role_namespace_tmpa_tl
+ }
+ }
+ }
+%% File: tagpdf-struct.dtx
+\newcounter { g__tag_struct_abs_int }
+\int_gzero:N \c@g__tag_struct_abs_int
+\__tag_seq_new:N \g__tag_struct_objR_seq
+\seq_new:N \g__tag_struct_stack_seq
+\seq_gpush:Nn \g__tag_struct_stack_seq {0}
+\seq_new:N \g__tag_struct_tag_stack_seq
+\seq_gpush:Nn \g__tag_struct_tag_stack_seq {Root}
+\tl_new:N \g__tag_struct_stack_current_tl
+\tl_new:N \l__tag_struct_stack_parent_tmpa_tl
+
+\seq_const_from_clist:Nn \c__tag_struct_StructTreeRoot_entries_seq
+ {%p. 857/858
+ Type, % always /StructTreeRoot
+ K, % kid, dictionary or array of dictionaries
+ IDTree, % currently unused
+ ParentTree, % required,obj ref to the parent tree
+ ParentTreeNextKey, % optional
+ RoleMap,
+ ClassMap,
+ Namespaces
+ }
+
+\seq_const_from_clist:Nn \c__tag_struct_StructElem_entries_seq
+ {%p 858 f
+ Type, %always /StructElem
+ S, %tag/type
+ P, %parent
+ ID, %optional
+ Ref, %optional, pdf 2.0 Use?
+ Pg, %obj num of starting page, optional
+ K, %kids
+ A, %attributes, probably unused
+ C, %class ""
+ %R, %attribute revision number, irrelevant for us as we
+ % don't update/change existing PDF and (probably)
+ % deprecated in PDF 2.0
+ T, %title, value in () or <>
+ Lang, %language
+ Alt, % value in () or <>
+ E, % abreviation
+ ActualText,
+ AF, %pdf 2.0, array of dict, associated files
+ NS, %pdf 2.0, dict, namespace
+ PhoneticAlphabet, %pdf 2.0
+ Phoneme %pdf 2.0
+ }
+\tl_new:N \g__tag_struct_tag_tl
+\tl_new:N \g__tag_struct_tag_NS_tl
+\tl_new:N \l__tag_struct_key_label_tl
+\bool_new:N \l__tag_struct_elem_stash_bool
+\cs_new:Npn \__tag_struct_output_prop_aux:nn #1 #2 %#1 num, #2 key
+ {
+ \prop_if_in:cnT
+ { g__tag_struct_#1_prop }
+ { #2 }
+ {
+ \c_space_tl/#2~ \prop_item:cn{ g__tag_struct_#1_prop } { #2 }
+ }
+ }
+
+\cs_new_protected:Npn \__tag_new_output_prop_handler:n #1
+ {
+ \cs_new:cn { __tag_struct_output_prop_#1:n }
+ {
+ \__tag_struct_output_prop_aux:nn {#1}{##1}
+ }
+ }
+\tl_gset:Nn \g__tag_struct_stack_current_tl {0}
+
+\__tag_prop_new:c { g__tag_struct_0_prop }
+\__tag_new_output_prop_handler:n {0}
+\__tag_seq_new:c { g__tag_struct_kids_0_seq }
+
+\__tag_prop_gput:cnn
+ { g__tag_struct_0_prop }
+ { Type }
+ { /StructTreeRoot }
+
+\__tag_prop_gput:cnx
+ { g__tag_struct_0_prop }
+ { Namespaces }
+ { \pdf_object_ref:n { __tag/tree/namespaces } }
+\cs_new_protected:Npn \__tag_struct_kid_mc_gput_right:nn #1 #2 %#1 structure num, #2 MCID absnum%
+ {
+ \__tag_seq_gput_right:cx
+ { g__tag_struct_kids_#1_seq }
+ {
+ <<
+ /Type \c_space_tl /MCR \c_space_tl
+ /Pg
+ \c_space_tl
+ \pdf_pageobject_ref:n { \__tag_ref_value:enn{mcid-#2}{tagabspage}{1} }
+ /MCID \c_space_tl \__tag_ref_value:enn{mcid-#2}{tagmcid}{1}
+ >>
+ }
+ }
+\cs_new_protected:Npn\__tag_struct_kid_struct_gput_right:nn #1 #2 %#1 num of parent struct, #2 kid struct
+ {
+ \__tag_seq_gput_right:cx
+ { g__tag_struct_kids_#1_seq }
+ {
+ \pdf_object_ref:n { __tag/struct/#2 }
+ }
+ }
-\RequirePackage { tagpdf-struct-code }
-\RequirePackage { tagpdf-space-code }
+\cs_generate_variant:Nn \__tag_struct_kid_struct_gput_right:nn {xx}
+\cs_new_protected:Npn\__tag_struct_kid_OBJR_gput_right:nn #1 #2 %#1 num of parent struct,
+ %#2 obj reference
+ {
+ \pdf_object_unnamed_write:nn
+ { dict }
+ {
+ /Type/OBJR/Obj~#2
+ }
+ \__tag_seq_gput_right:cx
+ { g__tag_struct_kids_#1_seq }
+ {
+ \pdf_object_ref_last:
+ }
+ }
+
+\cs_generate_variant:Nn\__tag_struct_kid_OBJR_gput_right:nn { xx }
+
+\cs_new_protected:Npn\__tag_struct_exchange_kid_command:N #1 %#1 = seq var
+ {
+ \seq_gpop_left:NN #1 \l__tag_tmpa_tl
+ \regex_replace_once:nnN
+ { \c{\__tag_mc_insert_mcid_kids:n} }
+ { \c{\__tag_mc_insert_mcid_single_kids:n} }
+ \l__tag_tmpa_tl
+ \seq_gput_left:NV #1 \l__tag_tmpa_tl
+ }
+
+\cs_generate_variant:Nn\__tag_struct_exchange_kid_command:N { c }
+\cs_new_protected:Npn \__tag_struct_fill_kid_key:n #1 %#1 is the struct num
+ {
+ \int_case:nnF
+ {
+ \seq_count:c
+ {
+ g__tag_struct_kids_#1_seq
+ }
+ }
+ {
+ { 0 }
+ { } %no kids, do nothing
+ { 1 } % 1 kid, insert
+ {
+ % in this case we need a special command in
+ % luamode to get the array right. See issue #13
+ \bool_if:NT\g__tag_mode_lua_bool
+ {
+ \__tag_struct_exchange_kid_command:c
+ {g__tag_struct_kids_#1_seq}
+ }
+ \__tag_prop_gput:cnx { g__tag_struct_#1_prop } {K}
+ {
+ \seq_item:cn
+ {
+ g__tag_struct_kids_#1_seq
+ }
+ {1}
+ }
+ } %
+ }
+ { %many kids, use an array
+ \__tag_prop_gput:cnx { g__tag_struct_#1_prop } {K}
+ {
+ [
+ \seq_use:cn
+ {
+ g__tag_struct_kids_#1_seq
+ }
+ {
+ \c_space_tl
+ }
+ ]
+ }
+ }
+ }
+
+\cs_new_protected:Npn \__tag_struct_get_dict_content:nN #1 #2 %#1: stucture num
+ {
+ \tl_clear:N #2
+ \seq_map_inline:cn
+ {
+ c__tag_struct_
+ \int_compare:nNnTF{#1}={0}{StructTreeRoot}{StructElem}
+ _entries_seq
+ }
+ {
+ \tl_put_right:Nx
+ #2
+ {
+ \prop_if_in:cnT
+ { g__tag_struct_#1_prop }
+ { ##1 }
+ {
+ \c_space_tl/##1~\prop_item:cn{ g__tag_struct_#1_prop } { ##1 }
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \__tag_struct_write_obj:n #1 % #1 is the struct num
+ {
+ \pdf_object_if_exist:nTF { __tag/struct/#1 }
+ {
+ \__tag_struct_fill_kid_key:n { #1 }
+ \__tag_struct_get_dict_content:nN { #1 } \l__tag_tmpa_tl
+ \exp_args:Nx
+ \pdf_object_write:nx
+ { __tag/struct/#1 }
+ {
+ \l__tag_tmpa_tl
+ }
+ }
+ {
+ \msg_error:nnn { tag } { struct-no-objnum } { #1}
+ }
+ }
+\cs_new_protected:Npn \__tag_struct_insert_annot:nn #1 #2 %#1 object reference to the annotation/xform
+ %#2 structparent number
+ {
+ \bool_if:NT \g__tag_active_struct_bool
+ {
+ %get the number of the parent structure:
+ \seq_get:NNF
+ \g__tag_struct_stack_seq
+ \l__tag_struct_stack_parent_tmpa_tl
+ {
+ \msg_error:nn { tag } { struct-faulty-nesting }
+ }
+ %put the obj number of the annot in the kid entry, this also creates
+ %the OBJR object
+ \__tag_struct_kid_OBJR_gput_right:xx
+ {
+ \l__tag_struct_stack_parent_tmpa_tl
+ }
+ {
+ #1 %
+ }
+ % add the parent obj number to the parent tree:
+ \exp_args:Nnx
+ \__tag_parenttree_add_objr:nn
+ {
+ #2
+ }
+ {
+ \pdf_object_ref:e { __tag/struct/\l__tag_struct_stack_parent_tmpa_tl }
+ }
+ % increase the int:
+ \stepcounter{ g__tag_parenttree_obj_int }
+ }
+ }
+\cs_new:Npn \__tag_get_data_struct_tag:
+ {
+ \exp_args:Ne
+ \tl_tail:n
+ {
+ \prop_item:cn {g__tag_struct_\g__tag_struct_stack_current_tl _prop}{S}
+ }
+ }
+\keys_define:nn { __tag / struct }
+ {
+ label .tl_set:N = \l__tag_struct_key_label_tl,
+ stash .bool_set:N = \l__tag_struct_elem_stash_bool,
+ tag .code:n = % S property
+ {
+ \seq_set_split:Nne \l__tag_tmpa_seq { / } {#1/\prop_item:Nn\g__tag_role_tags_NS_prop{#1}}
+ \tl_gset:Nx \g__tag_struct_tag_tl { \seq_item:Nn\l__tag_tmpa_seq {1} }
+ \tl_gset:Nx \g__tag_struct_tag_NS_tl { \seq_item:Nn\l__tag_tmpa_seq {2} }
+ \__tag_check_structure_tag:N \g__tag_struct_tag_tl
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { S }
+ { \pdf_name_from_unicode_e:n{ \g__tag_struct_tag_tl} } %
+ \prop_get:NVNT \g__tag_role_NS_prop\g__tag_struct_tag_NS_tl\l__tag_tmpa_tl
+ {
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { NS }
+ { \l__tag_tmpa_tl } %
+ }
+ },
+ title .code:n = % T property
+ {
+ \str_set_convert:Nnon
+ \l__tag_tmpa_str
+ { #1 }
+ { default }
+ { utf16/hex }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { T }
+ { <\l__tag_tmpa_str> }
+ },
+ title-o .code:n = % T property
+ {
+ \str_set_convert:Nnon
+ \l__tag_tmpa_str
+ { #1 }
+ { default }
+ { utf16/hex }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { T }
+ { <\l__tag_tmpa_str> }
+ },
+ alttext .code:n = % Alt property
+ {
+ \str_set_convert:Nnon
+ \l__tag_tmpa_str
+ { #1 }
+ { default }
+ { utf16/hex }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { Alt }
+ { <\l__tag_tmpa_str> }
+ },
+ alttext-o .code:n = % Alt property
+ {
+ \str_set_convert:Noon
+ \l__tag_tmpa_str
+ { #1 }
+ { default }
+ { utf16/hex }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { Alt }
+ { <\l__tag_tmpa_str> }
+ },
+ actualtext .code:n = % ActualText property
+ {
+ \str_set_convert:Nnon
+ \l__tag_tmpa_str
+ { #1 }
+ { default }
+ { utf16/hex }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { ActualText }
+ { <\l__tag_tmpa_str>}
+ },
+ actualtext-o .code:n = % ActualText property
+ {
+ \str_set_convert:Noon
+ \l__tag_tmpa_str
+ { #1 }
+ { default }
+ { utf16/hex }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { ActualText }
+ { <\l__tag_tmpa_str>}
+ },
+ lang .code:n = % Lang property
+ {
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { Lang }
+ { (#1) }
+ },
+ ref .code:n = % Lang property
+ {
+ \tl_clear:N\l__tag_tmpa_tl
+ \clist_map_inline:nn {#1}
+ {
+ \tl_put_right:Nx \l__tag_tmpa_tl
+ {~\ref_value:nn{tagpdfstruct-##1}{tagstructobj} }
+ }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { Ref }
+ { [\l__tag_tmpa_tl] }
+ },
+ E .code:n = % E property
+ {
+ \str_set_convert:Nnon
+ \l__tag_tmpa_str
+ { #1 }
+ { default }
+ { utf16/hex }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { E }
+ { <\l__tag_tmpa_str> }
+ },
+ }
+\keys_define:nn { __tag / struct }
+ {
+ AF .code:n = % AF property
+ {
+ \pdf_object_if_exist:nTF {#1}
+ {
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { AF }
+ { \pdf_object_ref:n {#1} }
+ }
+ {
+
+ }
+ },
+ ,AFinline .code:n =
+ {
+ \group_begin:
+ \pdf_object_if_exist:eF {__tag/fileobj\int_use:N\c@g__tag_struct_abs_int}
+ {
+ \pdffile_embed_stream:nxx
+ {#1}
+ {tag-AFfile\int_use:N\c@g__tag_struct_abs_int.txt}
+ {__tag/fileobj\int_use:N\c@g__tag_struct_abs_int}
+ }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_use:N\c@g__tag_struct_abs_int _prop }
+ { AF }
+ { \pdf_object_ref:e {__tag/fileobj\int_use:N\c@g__tag_struct_abs_int } }
+ \group_end:
+ }
+ ,AFinline-o .code:n =
+ {
+ \group_begin:
+ \pdf_object_if_exist:eF {__tag/fileobj\int_use:N\c@g__tag_struct_abs_int}
+ {
+ \pdffile_embed_stream:oxx
+ {#1}
+ {tag-AFfile\int_use:N\c@g__tag_struct_abs_int.txt}
+ {__tag/fileobj\int_use:N\c@g__tag_struct_abs_int}
+ }
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_use:N\c@g__tag_struct_abs_int _prop }
+ { AF }
+ { \pdf_object_ref:e {__tag/fileobj\int_use:N\c@g__tag_struct_abs_int } }
+ \group_end:
+ }
+ }
+\cs_new_protected:Npn \tag_struct_begin:n #1 %#1 key-val
+ {
+ \__tag_check_if_active_struct:T
+ {
+ \group_begin:
+ \int_gincr:N \c@g__tag_struct_abs_int
+ \__tag_prop_new:c { g__tag_struct_\int_eval:n { \c@g__tag_struct_abs_int }_prop }
+ \__tag_new_output_prop_handler:n {\int_eval:n { \c@g__tag_struct_abs_int }}
+ \__tag_seq_new:c { g__tag_struct_kids_\int_eval:n { \c@g__tag_struct_abs_int }_seq}
+ \exp_args:Ne
+ \pdf_object_new:nn
+ { __tag/struct/\int_eval:n { \c@g__tag_struct_abs_int } }
+ { dict }
+ \__tag_prop_gput:cno
+ { g__tag_struct_\int_eval:n { \c@g__tag_struct_abs_int }_prop }
+ { Type }
+ { /StructElem }
+ \keys_set:nn { __tag / struct} { #1 }
+ \__tag_check_structure_has_tag:n { \int_eval:n {\c@g__tag_struct_abs_int} }
+ \tl_if_empty:NF
+ \l__tag_struct_key_label_tl
+ {
+ \__tag_ref_label:en{tagpdfstruct-\l__tag_struct_key_label_tl}{struct}
+ }
+ %get the potential parent from the stack:
+ \seq_get:NNF
+ \g__tag_struct_stack_seq
+ \l__tag_struct_stack_parent_tmpa_tl
+ {
+ \msg_error:nn { tag } { struct-faulty-nesting }
+ }
+ \seq_gpush:NV \g__tag_struct_stack_seq \c@g__tag_struct_abs_int
+ \seq_gpush:NV \g__tag_struct_tag_stack_seq \g__tag_struct_tag_tl
+ \tl_gset:NV \g__tag_struct_stack_current_tl \c@g__tag_struct_abs_int
+ %\seq_show:N \g__tag_struct_stack_seq
+ \bool_if:NF
+ \l__tag_struct_elem_stash_bool
+ {%set the parent
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { P }
+ {
+ \pdf_object_ref:e { __tag/struct/\l__tag_struct_stack_parent_tmpa_tl }
+ }
+ %record this structure as kid:
+ %\tl_show:N \g__tag_struct_stack_current_tl
+ %\tl_show:N \l__tag_struct_stack_parent_tmpa_tl
+ \__tag_struct_kid_struct_gput_right:xx
+ { \l__tag_struct_stack_parent_tmpa_tl }
+ { \g__tag_struct_stack_current_tl }
+ %\prop_show:c { g__tag_struct_\g__tag_struct_stack_current_tl _prop }
+ %\seq_show:c {g__tag_struct_kids_\l__tag_struct_stack_parent_tmpa_tl _seq}
+ }
+ %\prop_show:c { g__tag_struct_\g__tag_struct_stack_current_tl _prop }
+ %\seq_show:c {g__tag_struct_kids_\l__tag_struct_stack_parent_tmpa_tl _seq}
+ \group_end:
+ }
+ }
+
+\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__tag_struct_stack_seq
+ \__tag_check_if_active_struct:T
+ {
+ \seq_gpop:NN \g__tag_struct_tag_stack_seq \l__tag_tmpa_tl
+ \seq_gpop:NNTF \g__tag_struct_stack_seq \l__tag_tmpa_tl
+ {
+ \__tag_check_info_closing_struct:o { \g__tag_struct_stack_current_tl }
+ }
+ { \__tag_check_no_open_struct: }
+ % get the previous one, shouldn't be empty as the root should be there
+ \seq_get:NNTF \g__tag_struct_stack_seq \l__tag_tmpa_tl
+ {
+ \tl_gset:NV \g__tag_struct_stack_current_tl \l__tag_tmpa_tl
+ }
+ {
+ \__tag_check_no_open_struct:
+ }
+ \seq_get:NNT \g__tag_struct_tag_stack_seq \l__tag_tmpa_tl
+ {
+ \tl_gset:NV \g__tag_struct_tag_tl \l__tag_tmpa_tl
+ }
+ }
+ }
+\cs_new_protected:Nn \tag_struct_use:n %#1 is the label
+ {
+ \__tag_check_if_active_struct:T
+ {
+ \prop_if_exist:cTF
+ { g__tag_struct_\__tag_ref_value:enn{tagpdfstruct-#1}{tagstruct}{unknown}_prop } %
+ {
+ \__tag_check_struct_used:n {#1}
+ %add the label structure as kid to the current structure (can be the root)
+ \__tag_struct_kid_struct_gput_right:xx
+ { \g__tag_struct_stack_current_tl }
+ { \__tag_ref_value:enn{tagpdfstruct-#1}{tagstruct}{0} }
+ %add the current structure to the labeled one as parents
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\__tag_ref_value:enn{tagpdfstruct-#1}{tagstruct}{0}_prop }
+ { P }
+ {
+ \pdf_object_ref:e { __tag/struct/\g__tag_struct_stack_current_tl }
+ }
+ }
+ {
+ \msg_warning:nnn{ tag }{struct-label-unknown}{#1}
+ }
+ }
+ }
+\cs_new_protected:Npn \tag_struct_insert_annot:nn #1 #2 %#1 should be an object reference
+ %#2 struct parent num
+ {
+ \__tag_check_if_active_struct:T
+ {
+ \__tag_struct_insert_annot:nn {#1}{#2}
+ }
+ }
+
+\cs_generate_variant:Nn \tag_struct_insert_annot:nn {xx}
+\cs_new:Npn \tag_struct_parent_int: {\int_use:c { c@g__tag_parenttree_obj_int }}
+
+
+\prop_new:N \g__tag_attr_entries_prop
+\seq_new:N \g__tag_attr_class_used_seq
+\tl_new:N \l__tag_attr_value_tl
+\prop_new:N \g__tag_attr_objref_prop %will contain obj num of used attributes
+\cs_new_protected:Npn \__tag_attr_new_entry:nn #1 #2 %#1:name, #2: content
+ {
+ \prop_gput:Nnn \g__tag_attr_entries_prop
+ {#1}{#2}
+ }
+
+\keys_define:nn { __tag / setup }
+ {
+ newattribute .code:n =
+ {
+ \__tag_attr_new_entry:nn #1
+ }
+ }
+\keys_define:nn { __tag / struct }
+ {
+ attribute-class .code:n =
+ {
+ \clist_set:No \l__tag_tmpa_clist { #1 }
+ \seq_set_from_clist:NN \l__tag_tmpa_seq \l__tag_tmpa_clist
+ \seq_map_inline:Nn \l__tag_tmpa_seq
+ {
+ \prop_if_in:NnF \g__tag_attr_entries_prop {##1}
+ {
+ \msg_error:nnn { tag } { attr-unknown } { ##1 }
+ }
+ \seq_gput_left:Nn\g__tag_attr_class_used_seq { ##1}
+ }
+ \seq_set_map:NNn \l__tag_tmpb_seq \l__tag_tmpa_seq
+ {
+ /##1
+ }
+ \tl_set:Nx \l__tag_tmpa_tl
+ {
+ \int_compare:nT { \seq_count:N \l__tag_tmpa_seq > 1 }{[}
+ \seq_use:Nn \l__tag_tmpb_seq { \c_space_tl }
+ \int_compare:nT { \seq_count:N \l__tag_tmpa_seq > 1 }{]}
+ }
+ \int_compare:nT { \seq_count:N \l__tag_tmpa_seq > 0 }
+ {
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { C }
+ { \l__tag_tmpa_tl }
+ %\prop_show:c { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ }
+ }
+ }
+\keys_define:nn { __tag / struct }
+ {
+ attribute .code:n = % A property (attribute, value currently a dictionary)
+ {
+ \clist_set:No \l__tag_tmpa_clist { #1 }
+ \seq_set_from_clist:NN \l__tag_tmpa_seq \l__tag_tmpa_clist
+ \tl_set:Nx \l__tag_attr_value_tl
+ {
+ \int_compare:nT { \seq_count:N \l__tag_tmpa_seq > 1 }{[}%]
+ }
+ \seq_map_inline:Nn \l__tag_tmpa_seq
+ {
+ \prop_if_in:NnF \g__tag_attr_entries_prop {##1}
+ {
+ \msg_error:nnn { tag } { attr-unknown } { ##1 }
+ }
+ \prop_if_in:NnF \g__tag_attr_objref_prop {##1}
+ {%\prop_show:N \g__tag_attr_entries_prop
+ \pdf_object_unnamed_write:nx
+ { dict }
+ {
+ \prop_item:Nn\g__tag_attr_entries_prop {##1}
+ }
+ \prop_gput:Nnx \g__tag_attr_objref_prop {##1} {\pdf_object_ref_last:}
+ }
+ \tl_put_right:Nx \l__tag_attr_value_tl
+ {
+ \c_space_tl
+ \prop_item:Nn \g__tag_attr_objref_prop {##1}
+ }
+ % \tl_show:N \l__tag_attr_value_tl
+ }
+ \tl_put_right:Nx \l__tag_attr_value_tl
+ { %[
+ \int_compare:nT { \seq_count:N \l__tag_tmpa_seq > 1 }{]}%
+ }
+ % \tl_show:N \l__tag_attr_value_tl
+ \__tag_prop_gput:cnx
+ { g__tag_struct_\int_eval:n {\c@g__tag_struct_abs_int}_prop }
+ { A }
+ { \l__tag_attr_value_tl }
+ },
+ }
+%% File: tagpdf-space.dtx
+\sys_if_engine_pdftex:T
+ {
+ \sys_if_output_pdf:TF
+ {
+ \pdfglyphtounicode{space}{0020}
+ \keys_define:nn { __tag / setup }
+ {
+ interwordspace .choices:nn = { true, on } { \pdfinterwordspaceon },
+ interwordspace .choices:nn = { false, off }{ \pdfinterwordspaceon },
+ interwordspace .default:n = true,
+ show-spaces .bool_set:N = \l__tag_showspaces_bool
+ }
+ }
+ {
+ \keys_define:nn { __tag / setup }
+ {
+ interwordspace .choices:nn = { true, on, false, off }
+ { \msg_warning:nnn {tag}{sys-no-interwordspace}{dvi} },
+ interwordspace .default:n = true,
+ show-spaces .bool_set:N = \l__tag_showspaces_bool
+ }
+ }
+ }
+
+\sys_if_engine_luatex:T
+ {
+ \keys_define:nn { __tag / setup }
+ {
+ interwordspace .choices:nn =
+ { true, on }
+ {
+ \bool_gset_true:N \g__tag_active_space_bool
+ \lua_now:e{ltx.__tag.func.markspaceon()}
+ },
+ interwordspace .choices:nn =
+ { false, off }
+ {
+ \bool_gset_false:N \g__tag_active_space_bool
+ \lua_now:e{ltx.__tag.func.markspaceoff()}
+ },
+ interwordspace .default:n = true,
+ show-spaces .choice:,
+ show-spaces / true .code:n =
+ {\lua_now:e{ltx.__tag.trace.showspaces=true}},
+ show-spaces / false .code:n =
+ {\lua_now:e{ltx.__tag.trace.showspaces=nil}},
+ show-spaces .default:n = true
+ }
+ }
+
+\sys_if_engine_xetex:T
+ {
+ \keys_define:nn { __tag / setup }
+ {
+ interwordspace .choices:nn = { true, on }
+ { \msg_warning:nnn {tag}{sys-no-interwordspace}{xetex} },
+ interwordspace .choices:nn = { false, off }
+ { \msg_warning:nnn {tag}{sys-no-interwordspace}{xetex} },
+ interwordspace .default:n = true,
+ show-spaces .bool_set:N = \l__tag_showspaces_bool
+ }
+ }
+\sys_if_engine_luatex:T
+ {
+ \cs_new_protected:Nn \__tag_fakespace:
+ {
+ \group_begin:
+ \lua_now:e{ltx.__tag.func.fakespace()}
+ \skip_horizontal:n{\c_zero_skip}
+ \group_end:
+ }
+ }
%%
%%
%% End of file `tagpdf.sty'.