From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/tagpdf/tagpdf-tree-code.sty | 210 +++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 macros/latex/contrib/tagpdf/tagpdf-tree-code.sty (limited to 'macros/latex/contrib/tagpdf/tagpdf-tree-code.sty') diff --git a/macros/latex/contrib/tagpdf/tagpdf-tree-code.sty b/macros/latex/contrib/tagpdf/tagpdf-tree-code.sty new file mode 100644 index 0000000000..af8ec11aa9 --- /dev/null +++ b/macros/latex/contrib/tagpdf/tagpdf-tree-code.sty @@ -0,0 +1,210 @@ +\ProvidesExplPackage {tagpdf-tree-code} {2019/07/02} {0.61} + {part of tagpdf - code related to writing trees and dictionaries to the pdf} + +%this does the actual finishing: +\AtBeginDocument + { + \bool_if:NT \g_uftag_active_tree_bool + { + \AfterEndDocument { \uftag_finish_structure: } + } + } + + +% the StructTreeRoot +% we better get the object number in any case: +\__uftag_pdfreserveobjnum:N \l_tmpa_tl +\tl_const:Nx \c_uftag_tree_obj_structtreeroot_tl { \l_tmpa_tl } + + +\cs_new:Nn \__uftag_tree_write_structtreeroot: + { + \__uftag_pdfcatalog:n { /StructTreeRoot~\c_uftag_tree_obj_structtreeroot_tl\c_space_tl0~R } + \__uftag_struct_write_obj:n { 0 } + } + +\cs_new:Nn \__uftag_tree_write_structelements: + { + \int_step_inline:nnnn {1}{1}{\c@g__uftag_struct_abs_int} + { + %\prop_show:c {g__uftag_struct_##1_prop} + \__uftag_struct_write_obj:n { ##1 } %write the object + } + } + + +%the ParentTree +\__uftag_pdfreserveobjnum:N \l_tmpa_tl +\tl_const:Nx \c__uftag_tree_obj_parenttree_tl { \l_tmpa_tl } + +% 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__uftag_parenttree_obj_int } +\AtBeginDocument + { \int_gset:Nn \c@g__uftag_parenttree_obj_int + { \zref@extractdefault{LastPage}{abspage}{100} } + } + +% we need to record the obj references: + +\tl_new:N \g__uftag_parenttree_objr_tl + +\cs_new:Nn \__uftag_parenttree_add_objr:nn %#1 Structparent number, #2 obj number +{ + \tl_gput_right:Nx \g__uftag_parenttree_objr_tl + { + #1 \c_space_tl #2\c_space_tl 0 \c_space_tl R\c_space_tl ^^J + } +} + +\tl_new:N \l__uftag_parenttree_content_tl + +\cs_new:Nn \__uftag_tree_fill_parenttree: + { + \int_step_inline:nnnn{1}{1}{\zref@extractdefault{LastPage}{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}{\zref@extractdefault{LastPage}{tagmcabs}{-1}} + { + %mcid####1 + \int_compare:nT%F + {\zref@extractdefault{mcid-####1}{tagabspage}{-1}=##1} %mcid is on current page + {% yes\par + \prop_put:Nxx \l_tmpa_prop + {\zref@extractdefault{mcid-####1}{tagmcid}{-1}} + {\prop_item:Nn \g__uftag_mc_parenttree_prop {####1}} + } + } + %\prop_show:N \l_tmpa_prop + \tl_put_right:Nx\l__uftag_parenttree_content_tl + {\int_eval:n {##1-1}\c_space_tl[\c_space_tl} %%brackt + \int_step_inline:nnnn {0}{1}{ \prop_map_function:NN \l_tmpa_prop\__uftag_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__uftag_parenttree_content_tl + { + \prop_item:cn { g__uftag_struct_\l_tmpb_tl _prop } {objnum}~0~R~ + } + } + {\msg_warning:nn {uftag} {tree-mcid-index-wrong} } + } + \tl_put_right:Nn \l__uftag_parenttree_content_tl {]^^J} % + } + } + +%lua mode must/can do it differently +\cs_new:Nn \__uftag_tree_lua_fill_parenttree: + { + \tl_set:Nn \l__uftag_parenttree_content_tl + { + \directlua{uftag.func.output_parenttree(\int_use:N\g__uftag_abspage_int)} + } + } + + + +\cs_new:Nn \__uftag_tree_write_parenttree: + { + \bool_if:NTF \g__uftag_mode_lua_bool + { + \__uftag_tree_lua_fill_parenttree: + } + { + \__uftag_tree_fill_parenttree: + } + \tl_put_right:NV \l__uftag_parenttree_content_tl\g__uftag_parenttree_objr_tl + \__uftag_pdfuseobjnum:xx { \c__uftag_tree_obj_parenttree_tl } + { + <<\c_space_tl/Nums\c_space_tl [\l__uftag_parenttree_content_tl] \c_space_tl >> + } + } + +%the Rolemap tree +\__uftag_pdfreserveobjnum:N \l_tmpa_tl +\tl_const:Nx \c__uftag_tree_obj_rolemap_tl { \l_tmpa_tl } +\tl_new:N \l__uftag_rolemap_content_tl + +\cs_new:Nn \__uftag_tree_fill_rolemap: + { + \prop_map_inline:Nn \g__uftag_role_rolemap_prop + { + \tl_put_right:Nx \l__uftag_rolemap_content_tl + { + /##1\c_space_tl/##2^^J + } + } + } + +\cs_new:Nn \__uftag_tree_write_rolemap: + { + \__uftag_tree_fill_rolemap: + \__uftag_pdfuseobjnum:xx { \c__uftag_tree_obj_rolemap_tl } + { + <<\l__uftag_rolemap_content_tl >> + } + } + +%classmap, should only be written, if values has been used + +\cs_new_protected:Nn \__uftag_tree_class_write_map: + { + \tl_gclear:N \g__uftag_attr_class_content_tl + \seq_gremove_duplicates:N \g__uftag_attr_class_used_seq + \seq_set_map:NNn \l_tmpa_seq \g__uftag_attr_class_used_seq + { + /##1\c_space_tl + \prop_item:Nn \g__uftag_attr_entries_prop + {##1} + } + \tl_gset:Nx \g__uftag_attr_class_content_tl + { + \seq_use:Nn \l_tmpa_seq + { \iow_newline: } + } + \tl_if_empty:NF \g__uftag_attr_class_content_tl + { + \__uftag_pdfreserveobjnum:N \l_tmpa_tl + \tl_const:Nx \c__uftag_tree_obj_classmap_tl { \l_tmpa_tl } + \__uftag_pdfuseobjnum:Nx \c__uftag_tree_obj_classmap_tl + { <<\g__uftag_attr_class_content_tl>> } + + \__uftag_prop_gput:cnx + { g__uftag_struct_0_prop } + { ClassMap } + { \c__uftag_tree_obj_classmap_tl\c_space_tl0\c_space_tl R } + } + } + + +\cs_new:Nn \uftag_finish_structure: + { + \__uftag_pdfcatalog:n {^^J/MarkInfo\c_space_tl<> } + \__uftag_tree_write_parenttree: + \__uftag_tree_write_rolemap: + \__uftag_tree_class_write_map: + \__uftag_tree_write_structelements: + \__uftag_tree_write_structtreeroot: + } + + +%StructParents + tabs order. Tabs order should be probably be changeable by page. + +\cs_new:Nn \__uftag_tree_write_pageattr: + { + \__uftag_get_pdfpageattr:N \l_tmpa_tl + \regex_replace_once:nnN {/StructParents\s*\d+} {}\l_tmpa_tl + \regex_replace_once:nnN {/Tabs\s*/[SCR]} {}\l_tmpa_tl + \__uftag_gset_pdfpageattr:x + { + \l_tmpa_tl / StructParents \c_space_tl + \int_eval:n { \g__uftag_abspage_int } + \l__uftag_tree_tabs_order_tl + } + } + +\endinput -- cgit v1.2.3