summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/tagpdf/tagpdf-tree-code.sty
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/tagpdf/tagpdf-tree-code.sty
Initial commit
Diffstat (limited to 'macros/latex/contrib/tagpdf/tagpdf-tree-code.sty')
-rw-r--r--macros/latex/contrib/tagpdf/tagpdf-tree-code.sty210
1 files changed, 210 insertions, 0 deletions
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<</Marked\c_space_tl true>> }
+ \__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