diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx new file mode 100644 index 00000000000..35f622ca1c9 --- /dev/null +++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx @@ -0,0 +1,294 @@ +% \iffalse meta-comment +% +%% File: tagpdf-tree.dtx +% +% Copyright (C) 2019-2020 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 +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% This file is part of the "tagpdf bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/u-fischer/tagpdf +% +% for those people who are interested. +% +% \fi +% +% \begin{macrocode} +%<@@=tag> +%<*tree> +\ProvidesExplPackage {tagpdf-tree-code} {2021/02/23} {0.80} + {part of tagpdf - code related to writing trees and dictionaries to the pdf} + +%this does the actual finishing: +%Is \AfterEndDocument the best places?? +\hook_gput_code:nnn{begindocument}{tagpdf} + { + \bool_if:NT \g_@@_active_tree_bool + { + \AfterEndDocument { \tag_finish_structure: } + } + } + + +% the StructTreeRoot +% we better get the object number in any case: +% deprecated +%\@@_pdfreserveobjnum:N \l_tmpa_tl +%\tl_const:Nx \c_@@_tree_obj_structtreeroot_tl { \l_tmpa_tl } + +%new +\pdf_object_new:nn { c_@@_struct_0_obj }{ dict } + + %need to think about the best place ... +\hook_gput_code:nnn{begindocument}{tagpdf} + { + \bool_if:NT \g_@@_active_struct_bool + { + \pdfmanagement_add:nnx + { Catalog } + { StructTreeRoot } + { \pdf_object_ref:n { c_@@_struct_0_obj } } + } + } +\cs_new_protected:Nn \@@_tree_write_structtreeroot: + { + \@@_struct_write_obj:n { 0 } + } + +\cs_new_protected:Nn \@@_tree_write_structelements: + { + \int_step_inline:nnnn {1}{1}{\c@g_@@_struct_abs_int} + { + %\prop_show:c {g_@@_struct_##1_prop} + \@@_struct_write_obj:n { ##1 } %write the object + } + } + + +%the ParentTree +% deprecated +%\@@_pdfreserveobjnum:N \l_tmpa_tl +%\tl_const:Nx \c_@@_tree_obj_parenttree_tl { \l_tmpa_tl } + +%new +\pdf_object_new:nn { c_@@_tree_parenttree_obj }{ dict } + +% we have two sets of entries in the parent tree: +% page streams and real objects. +% The numbers must be distinct and ordered +% So we rely on abspage and put the real objects at the end +% I use a counter to have a chance to get the correct number +% if code is process twice. +\newcounter { g_@@_parenttree_obj_int } +\hook_gput_code:nnn{begindocument}{tagpdf} + { + \int_gset:Nn + \c@g_@@_parenttree_obj_int + { \@@_ref_value_lastpage:nn{abspage}{100} } + } + +% we need to record the obj references: + +\tl_new:N \g_@@_parenttree_objr_tl + +\cs_new_protected:Nn \@@_parenttree_add_objr:nn %#1 Structparent number, #2 objref + { + \tl_gput_right:Nx \g_@@_parenttree_objr_tl + { + #1 \c_space_tl #2 ^^J + } + } + +\tl_new:N \l_@@_parenttree_content_tl + +\cs_new_protected:Nn \@@_tree_fill_parenttree: + { + \int_step_inline:nnnn{1}{1}{\@@_ref_value_lastpage:nn{abspage}{-1}} %not quite clear if labels are needed. See lua code + { %page ##1\par + \prop_clear:N \l_tmpa_prop + \int_step_inline:nnnn{1}{1}{\@@_ref_value_lastpage:nn{tagmcabs}{-1}} + { + %mcid####1 + \int_compare:nT%F + {\@@_ref_value:enn{mcid-####1}{tagabspage}{-1}=##1} %mcid is on current page + {% yes\par + \prop_put:Nxx + \l_tmpa_prop + {\@@_ref_value:enn{mcid-####1}{tagmcid}{-1}} + {\prop_item:Nn \g_@@_mc_parenttree_prop {####1}} + } + } + %\prop_show:N \l_tmpa_prop + \tl_put_right:Nx\l_@@_parenttree_content_tl + { + \int_eval:n {##1-1}\c_space_tl + [\c_space_tl %] + } + \int_step_inline:nnnn + {0} + {1} + { \prop_map_function:NN \l_tmpa_prop\@@_prop_count:nn -1 } + { + \prop_get:NnNTF \l_tmpa_prop {####1} \l_tmpb_tl + {% page#1:mcid##1:\l_tmpb_tl :content + \tl_put_right:Nx \l_@@_parenttree_content_tl + { + \prop_item:cn { g_@@_struct_\l_tmpb_tl _prop } {objref} + \c_space_tl + } + %\tl_show:N \l_@@_parenttree_content_tl + } + { + \msg_warning:nn { tag } {tree-mcid-index-wrong} + } + } + \tl_put_right:Nn + \l_@@_parenttree_content_tl + {%[ + ]^^J + } + } + } + +%lua mode must/can do it differently +\cs_new_protected:Nn \@@_tree_lua_fill_parenttree: + { + \tl_set:Nn \l_@@_parenttree_content_tl + { + \directlua + { + ltx.@@.func.output_parenttree + ( + \int_use:N\g_shipout_readonly_int + ) + } + } + } + + + +\cs_new_protected:Nn \@@_tree_write_parenttree: + { + \bool_if:NTF \g_@@_mode_lua_bool + { + \@@_tree_lua_fill_parenttree: + } + { + \@@_tree_fill_parenttree: + } + \tl_put_right:NV \l_@@_parenttree_content_tl\g_@@_parenttree_objr_tl + \pdf_object_write:nx { c_@@_tree_parenttree_obj } + { + /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 + } + } + } + +\cs_new_protected:Nn \@@_tree_write_rolemap: + { + \@@_tree_fill_rolemap: + \pdf_object_write:nx { c_@@_tree_rolemap_obj } + { + \l_@@_rolemap_content_tl + } + } + +%classmap, should only be written, if values has been used + +\cs_new_protected:Nn \@@_tree_write_classmap: + { + \tl_gclear:N \g_@@_attr_class_content_tl + \seq_gremove_duplicates:N \g_@@_attr_class_used_seq + \seq_set_map:NNn \l_tmpa_seq \g_@@_attr_class_used_seq + { + /##1\c_space_tl + << + \prop_item:Nn + \g_@@_attr_entries_prop + {##1} + >> + } + \tl_gset:Nx \g_@@_attr_class_content_tl + { + \seq_use:Nn + \l_tmpa_seq + { \iow_newline: } + } + \tl_if_empty:NF + \g_@@_attr_class_content_tl + { + \pdf_object_new:nn { c_@@_tree_classmap_obj }{ 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 } + { \g_@@_attr_class_content_tl } + \@@_prop_gput:cnx + { g_@@_struct_0_prop } + { ClassMap } + { \pdf_object_ref:n { c_@@_tree_classmap_obj } } + } + } + + +\cs_new_protected:Nn \tag_finish_structure: + { + \@@_tree_write_parenttree: + \@@_tree_write_rolemap: + \@@_tree_write_classmap: + \@@_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 +\hook_gput_code:nnn{begindocument}{tagpdf} + { + \bool_if:NT\g_@@_active_tree_bool + { + \hook_gput_code:nnn{shipout/before} { tagpdf/structparents } + { + \pdfmanagement_add:nnx + { Page } + {StructParents} + {\int_eval:n { \g_shipout_readonly_int}} + } + } + } + +%</tree> +% \end{macrocode} |