\RequirePackage{expl3}[2018/06/14]

\ProvidesExplPackage {tagpdf} {2018/07/09} {0.2}
 {A package to experiment with pdf tagging}

% storing internal names to my name space:
\cs_set_eq:NN \__uftag_tex_pdffeedback:D         \tex_pdffeedback:D
\cs_set_eq:NN \__uftag_tex_pdfextension:D        \tex_pdfextension:D
\cs_set_eq:NN \__uftag_tex_immediate:D           \tex_immediate:D
\cs_set_eq:NN \__uftag_tex_pdfvariable:D         \tex_pdfvariable:D
\cs_set_eq:NN \__uftag_tex_global:D              \tex_global:D
\cs_set_eq:NN \__uftag_tex_the:D                 \tex_the:D
\cs_set_eq:NN \__uftag_tex_pdfliteral:D          \tex_pdfliteral:D
\cs_set_eq:NN \__uftag_tex_pdfcatalog:D          \tex_pdfcatalog:D
\cs_set_eq:NN \__uftag_tex_pdflastobj:D          \tex_pdflastobj:D
\cs_set_eq:NN \__uftag_tex_pdfobj:D              \tex_pdfobj:D
\cs_set_eq:NN \__uftag_tex_pdfpageattr:D         \tex_pdfpageattr:D
\cs_set_eq:NN \__uftag_tex_pdfpagesattr:D        \tex_pdfpagesattr:D
\cs_set_eq:NN \__uftag_tex_pdfpageref:D          \tex_pdfpageref:D
\cs_set_eq:NN \__uftag_tex_pdfcompresslevel:D    \tex_pdfcompresslevel:D
\cs_set_eq:NN \__uftag_tex_pdfobjcompresslevel:D \tex_pdfobjcompresslevel:D

%%% package options
\bool_new:N\g__uftag_mode_lua_bool

\DeclareOption{luamode}    { \sys_if_engine_luatex:T { \bool_gset_true:N \g__uftag_mode_lua_bool } }
\DeclareOption{genericmode}{ \bool_gset_false:N\g__uftag_mode_lua_bool }
\ExecuteOptions{luamode}
\ProcessOptions

%%% some packages
\RequirePackage{xparse}
\RequirePackage{atbegshi}
\RequirePackage{zref-base,zref-lastpage}
\RequirePackage{etoolbox}
\RequirePackage{pdfescape}

%%% absolute page numbers
\int_new:N   \g__uftag_abspage_int
\int_gset:Nn \g__uftag_abspage_int { 0 }
\zref@newlist {tagpdf}
\zref@newprop*{tagabspage}     [0] { \int_use:N \g__uftag_abspage_int }
\zref@addprop {tagpdf} {tagabspage}


%%% tagpdfsetup,
%%% TODO: checks need to be improved
\int_new:N  \l__uftag_loglevel_int
\tl_new:N   \l__uftag_tree_tabs_order_tl

\keys_define:nn { tagpdf-setup }
{
 activate-mc     .bool_gset:N = \g_uftag_active_mc_bool,
 activate-tree   .bool_gset:N = \g_uftag_active_tree_bool,
 activate-struct .bool_gset:N = \g_uftag_active_struct_bool,
 activate-all    .meta:n ={activate-mc,activate-tree,activate-struct},
 check-tags      .bool_set:N = \g__uftag_check_tags_bool,
 check-tags      .initial:n  = true,
 log             .choice:,
 log / none      .code:n = {\int_set:Nn \l__uftag_loglevel_int { 0 }},
 log / v         .code:n = {\int_set:Nn \l__uftag_loglevel_int { 1 }},
 log / vv        .code:n = {\int_set:Nn \l__uftag_loglevel_int { 2 }},
 log / vvv       .code:n = {\int_set:Nn \l__uftag_loglevel_int { 3 }},
 log / all       .code:n = {\int_set:Nn \l__uftag_loglevel_int { 10 }},
 tagunmarked     .bool_gset:N = \g__uftag_tagunmarked_bool,
 tagunmarked     .initial:n  = true,
 tabsorder       .choice:,
 tabsorder / row       .code:n = {\tl_set:Nn \l__uftag_tree_tabs_order_tl {/Tabs/R}},
 tabsorder / column    .code:n = {\tl_set:Nn \l__uftag_tree_tabs_order_tl {/Tabs/C}},
 tabsorder / structure .code:n = {\tl_set:Nn \l__uftag_tree_tabs_order_tl {/Tabs/S}},
 tabsorder / none      .code:n = {\tl_set:Nn \l__uftag_tree_tabs_order_tl {}},
 compresslevel   .choices:nn   = {0,1,2,3,4,5,6,7,8,9}
                                 {
                                  \__uftag_pdfcompresslevel:n    {#1}
                                  \__uftag_pdfobjcompresslevel:n {#1}
                                 },
 compresslevel  .value_required:n = true,
 uncompress     .meta:n = { compresslevel = 0 },
}


% commands to escape strings so that they can be safely used in pdf
% currently not much used. But will be needed later, when alt and actualtext are added.
% we probably need the equivalent \pdfescapestring, \pdfescapename \pdfescapehex
% the commands of pdfescape adds an additional layout to allow for babel shorthands
\cs_set_eq:NN \__uftag_pdf_escape_string:Nn \EdefEscapeString
\cs_set_eq:NN \__uftag_pdf_escape_name:Nn   \EdefEscapeName
\cs_set_eq:NN \__uftag_pdf_escape_hex:Nn    \EdefEscapeHex

% a hook for later code and an absolute page counter
% should be executed before counters are resetted.
% is it used?
\cs_new:Nn   \__uftag_finish_page_hook: { }

\AtBeginShipout
 {
  \__uftag_finish_page_hook:
  \__uftag_tree_write_pageattr:
  \int_gincr:N \g__uftag_abspage_int
 }


%testing the engines and loading the driver files
\sys_if_engine_xetex:T
 {
  \PackageError { tagpdf } { xelatex~is~not~supported~-~aborting } {}
  \tex_endinput:D
 }

\sys_if_engine_luatex:T
 {
  \file_input:n {tagpdf-luatex.def}
 }

\sys_if_engine_pdftex:T
 {
  \file_input:n {tagpdf-pdftex.def}
 }

\sys_if_output_dvi:T
 {
  \PackageError { tagpdf } { dvi~output~is~not~supported~-~aborting }{}
  \tex_endinput:D
 }

\cs_generate_variant:Nn \__uftag_prop_gput:Nnn      { Nxn , Nxx, Nnx , cnn, cxn, cnx, cno}
\cs_generate_variant:Nn \__uftag_seq_gput_right:Nn  { Nx  , No, cn, cx }
\cs_generate_variant:Nn \__uftag_prop_new:N   { c }
\cs_generate_variant:Nn \__uftag_seq_new:N    { c }
\cs_generate_variant:Nn \__uftag_seq_show:N   { c }
\cs_generate_variant:Nn \__uftag_prop_show:N  { c }
\cs_generate_variant:Nn \prop_gput:Nnn {Nxx}
\cs_generate_variant:Nn \prop_put:Nnn  {Nxx}
\cs_generate_variant:Nn \__uftag_pdfuseobjnum:Nn {Nx}
\cs_generate_variant:Nn \__uftag_pdfuseobjnum:nn {nx,xx}
\cs_generate_variant:Nn \__uftag_gset_pdfpageattr:n {x}

% few temp tl
\tl_new:N \l__uftag_tmpa_tl
\tl_new:N \l__uftag_tmpb_tl
\tl_new:N \l__uftag_tmpc_tl
\tl_new:N \l__uftag_tmpd_tl
\tl_new:N \l__uftag_tmpe_tl

% helper function to get the propcount.
% use as \prop_map_function:NN PROP { \__uftag_prop_count:nn -1 }
\cs_new:Nn\__uftag_prop_count:nn { + 1 }

%% Loading the tagpdf sub packages
\RequirePackage { tagpdf-checks-code }
\RequirePackage { tagpdf-user }
\RequirePackage { tagpdf-tree-code }
\RequirePackage { tagpdf-roles-code }
% mc-code is split:
\RequirePackage { tagpdf-mc-code-shared }
\bool_if:NTF \g__uftag_mode_lua_bool
 {
  \RequirePackage {tagpdf-mc-code-lua}
 }
 {
  \RequirePackage { tagpdf-mc-code-generic } %
 }

\RequirePackage { tagpdf-struct-code }

\endinput
