% \iffalse meta-comment
%
%% File: tagpdf-user.dtx
%
% Copyright (C) 2019-2023 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.
%<*driver>
\DocumentMetadata{}
\documentclass{l3doc}
\usepackage{array,booktabs,caption}
\hypersetup{pdfauthor=Ulrike Fischer,
pdftitle=tagpdf-user module (tagpdf)}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%
% \fi
% \title{^^A
% The \pkg{tagpdf-user} module\\ Code related to \LaTeX2e user commands and document commands ^^A
% \\ Part of the tagpdf package
% }
%
% \author{^^A
% Ulrike Fischer\thanks
% {^^A
% E-mail:
% \href{mailto:fischer@troubleshooting-tex.de}
% {fischer@troubleshooting-tex.de}^^A
% }^^A
% }
%
% \date{Version 0.98e, released 2023-03-07}
% \maketitle
% \begin{documentation}
% \section{Setup commands}
% \begin{function}{\tagpdfsetup}
% \begin{syntax}
% \cs{tagpdfsetup}\Arg{key val list}
% \end{syntax}
% This is the main setup command to adapt the behaviour of tagpdf.
% It can be used in the preamble and in the document (but not all keys make sense there).
% \end{function}
%
% \begin{function}{activate (setup-key)}
% And additional setup key which combine the other activate keys
% |activate-mc|, |activate-tree|, |activate-struct| and additionally
% add a document structure.
% \end{function}
%
% \begin{function}{\tag_tool:n,\tagtool}
% \begin{syntax}
% \cs{tag_tool:n}\Arg{key val}
% \end{syntax}
% The tagging of basic document elements will require a variaty of small commands
% to configure and adapt the tagging. This command will collect them under a command
% interface. The argument is \emph{one} key-value like string. This is work in progress
% and both syntax, known arguments and implementation can change!
% \end{function}
%
% \section{Commands related to mc-chunks}
% \begin{function}{\tagmcbegin, \tagmcend,\tagmcuse}
% \begin{syntax}
% \cs{tagmcbegin} \Arg{key-val}\\
% \cs{tagmcend}\\
% \cs{tagmcuse}\Arg{label}
% \end{syntax}
% These are wrappers around |\tag_mc_begin:n|, |\tag_mc_end:| and |\tag_mc_use:n|.
% The commands and their argument are documentated in the \pkg{tagpdf-mc} module.
% In difference to the expl3 commands, \cs{tagmcbegin} issues also an \cs{ignorespaces},
% and \cs{tagmcend} will issue in horizontal mode an \cs{unskip}.
% \end{function}
%
% \begin{function}{\tagmcifinTF}
% \begin{syntax}
% \cs{tagmcifin} \Arg{true code}\Arg{false code}
% \end{syntax}
% This is a wrapper around |\tag_mc_if_in:TF|.
% and tests if an mc is open or not. It is mostly of
% importance for pdflatex as lualatex doesn't mind much if a mc tag is not
% correctly closed. Unlike the expl3 command it is not expandable.
%
% The command is probably not of much use and will perhaps disappear in future
% versions. It normally makes more sense to push/pop an mc-chunk.
% \end{function}
%
% \section{Commands related to structures}
% \begin{function}{\tagstructbegin, \tagstructend,\tagstructuse}
% \begin{syntax}
% \cs{tagstructbegin} \Arg{key-val}\\
% \cs{tagstructend}\\
% \cs{tagstructuse}\Arg{label}
% \end{syntax}
% These are direct wrappers around |\tag_struct_begin:n|,
% |\tag_struct_end:| and |\tag_struct_use:n|.
% The commands and their argument are documentated in the \pkg{tagpdf-struct} module.
% \end{function}
% \section{Debugging}
% \begin{function}{\ShowTagging}
% \begin{syntax}
% \cs{ShowTagging} \Arg{key-val}
% \end{syntax}
% This is a generic function to output various debugging helps. It not
% necessarly stops the compilation. The keys and their function are described below.
% \end{function}
%
% \begin{function}{mc-data (show-key)}
% \begin{syntax}
% |mc-data| = \meta{number}
% \end{syntax}
% This key is (currently?) relevant for lua mode only.
% It shows the data of all mc-chunks created so far.
% It is accurate only after shipout (and perhaps a second compilation),
% so typically should be issued after a
% newpage. The value is a positive integer and sets the first mc-shown. If no value
% is given, 1 is used and so all mc-chunks created so far are shown.
% \end{function}
% \begin{function}{mc-current (show-key)}
% \begin{syntax}
% |mc-current|
% \end{syntax}
% This key shows the number and the tag of the currently open mc-chunk. If no
% chunk is open it shows only the state of the abs count. It works in all mode,
% but the output in luamode looks different.
% \end{function}
% \begin{function}{mc-marks (show-key)}
% \begin{syntax}
% |mc-marks| = |show|\verb+|+|use|
% \end{syntax}
% This key helps to debug the page marks. It should only be used at shipout in
% header or footer.
% \end{function}
% \begin{function}{struct-stack (show-key)}
% \begin{syntax}
% |struct-stack| = |log|\verb+|+|show|
% \end{syntax}
% This key shows the current structure stack. With |log| the info is only
% written to the log-file, |show| stops the compilation and shows on the terminal.
% If no value is used, then the default is |show|.
% \end{function}
%
% \section{Extension commands}
% The following commands and code parts are not core command of tagpdf.
% They either provide work-arounds for missing functionality elsewhere,
% or do a first step to apply tagpdf commands to document commands.
%
% The commands and keys should be view as experimental!
%
% This part will be regularly revisited to check if the code should go to a
% better place or can be improved and so can change easily.
%
% \subsection{Fake space}
% \begin{function}{\pdffakespace}
% (lua-only) This provides a lua-version of the |\pdffakespace| primitive of
% pdftex.
% \end{function}
%
% \subsection{Paratagging}
%
% This is a first try to make use of the new paragraph hooks in a current LaTeX to
% automate the tagging of paragraph. It requires sane paragraph nesting,
% faulty code, e.g. a missing |\par| at the end of a low-level vbox can highly
% confuse the tagging. The tags should be carefully checked if this is used.
%
% \begin{function}{paratagging (setup-key),paratagging-show (setup-key)}
% \begin{syntax}
% |paratagging| = |true|\verb+|+|false|\\
% |paratagging-show| = |true|\verb+|+|false|\\
% \end{syntax}
% This keys can be used in |\tagpdfsetup| and enable/disable paratagging.
% |paratagging-show| puts small red numbers at the begin and end of a paragraph.
% This is meant as a debugging help. The number are boxes and have a (tiny) height,
% so they can affect typesetting.
% \end{function}
%
% \begin{function}{\tagpdfparaOn,\tagpdfparaOff}
% These commands allow to enable/disable para tagging too and are a bit
% faster then |\tagpdfsetup|. But I'm not sure if the names are good.
% \end{function}
%
% \begin{function}{\tagpdfsuppressmarks}
% This command allows to suppress the creation of the marks. It takes an argument
% which should normally be one of the mc-commands, puts a group around it and
% suppress the marks creation in this group. This command should be used if
% the begin and end command are at different boxing levels. E.g.
% \begin{verbatim}
% \@hangfrom
% {
% \tagstructbegin{tag=H1}%
% \tagmcbegin {tag=H1}%
% #2
% }
% {#3\tagpdfsuppressmarks{\tagmcend}\tagstructend}%
% \end{verbatim}
% \end{function}
%
% \subsection{Header and footer}
% Header and footer are automatically excluded from tagging. This can
% be disabled with the following key.
% If some real content is in the header and
% footer, tagging must be restarted there explicitly.
% The key accepts the values |true| which surrounds the header with an artifact
% mc-chunk, |false| which disables the automatic tagging, and |pagination| which
% additionally adds an artifact structure with an pagination attribute.
%
% \begin{function}{exclude-header-footer (setup-key)}
% \begin{syntax}
% |exclude-header-footer| = |true|\verb+|+|false|\verb+|+pagination
% \end{syntax}%
% \end{function}
% \subsection{Link tagging}
% Links need a special structure and cross reference system.
% This is added through hooks of the l3pdfannot module and will work
% automatically if tagging is activated.
%
% Links should (probably) have an alternative text in the Contents
% key. It is unclear which text this should be and
% how to get it. Currently the code simply adds the fix texts |url| and |ref|.
% Another text can be added by changing the dictionary value:
% \begin{verbatim}
% \pdfannot_dict_put:nnn
% { link/GoTo }
% { Contents }
% { (ref) }
% \end{verbatim}
% \end{documentation}
%
% \begin{implementation}
% \section{User commands and extensions of document commands}
% \begin{macrocode}
%<@@=tag>
%<*header>
\ProvidesExplPackage {tagpdf-user} {2023-03-07} {0.98e}
{tagpdf - user commands}
%
% \end{macrocode}
% \section{Setup and preamble commands}
% \begin{macro}{\tagpdfsetup}
% \begin{macrocode}
%\NewDocumentCommand \tagpdfsetup { m }{}
%<*package>
\RenewDocumentCommand \tagpdfsetup { m }
{
\keys_set:nn { @@ / setup } { #1 }
}
%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tag_tool:n,\tagtool}
% This is a first definition of the tool command.
% Currently it uses key-val, but this should be probably
% be flattened to speed it up.
% \begin{macrocode}
%\cs_new_protected:Npn\tag_tool:n #1 {}
%\cs_set_eq:NN\tagtool\tag_tool:n
%<*package>
\cs_set_protected:Npn\tag_tool:n #1
{
\tag_if_active:T { \keys_set:nn {tag / tool}{#1} }
}
\cs_set_eq:NN\tagtool\tag_tool:n
%
% \end{macrocode}
% \end{macro}
% \section{Commands for the mc-chunks}
% \begin{macro}{\tagmcbegin,\tagmcend,\tagmcuse }
% \begin{macrocode}
%<*base>
\NewDocumentCommand \tagmcbegin { m }
{
\tag_mc_begin:n {#1}
}
\NewDocumentCommand \tagmcend { }
{
\tag_mc_end:
}
\NewDocumentCommand \tagmcuse { m }
{
\tag_mc_use:n {#1}
}
%
% \end{macrocode}
% \end{macro}
% \begin{macro}{\tagmcifinTF}
% This is a wrapper around |\tag_mc_if_in:| and tests if an mc is open or not. It is mostly of
% importance for pdflatex as lualatex doesn't mind much if a mc tag is not
% correctly closed. Unlike the expl3 command it is not expandable.
% \begin{macrocode}
%<*package>
\NewDocumentCommand \tagmcifinTF { m m }
{
\tag_mc_if_in:TF { #1 } { #2 }
}
%
% \end{macrocode}
% \end{macro}
%
% \section{Commands for the structure}
% \begin{macro}{\tagstructbegin,\tagstructend,\tagstructuse }
%
% These are structure related user commands. There are direct wrapper around the
% expl3 variants.
% \begin{macrocode}
%<*base>
\NewDocumentCommand \tagstructbegin { m }
{
\tag_struct_begin:n {#1}
}
\NewDocumentCommand \tagstructend { }
{
\tag_struct_end:
}
\NewDocumentCommand \tagstructuse { m }
{
\tag_struct_use:n {#1}
}
%
% \end{macrocode}
% \end{macro}
%
%
%
% \section{Debugging}
% \begin{macro}{\ShowTagging}
% This is a generic command for various show commands.
% It takes a keyval list, the various keys are implemented below.
% \begin{macrocode}
%<*package>
\NewDocumentCommand\ShowTagging { m }
{
\keys_set:nn { @@ / show }{ #1}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{mc-data (show-key)}
% This key is (currently?) relevant for lua mode only.
% It shows the data of all mc-chunks created so far.
% It is accurate only after shipout, so typically should be issued after a
% newpage. With the optional argument the minimal number can be set.
% \begin{macrocode}
\keys_define:nn { @@ / show }
{
mc-data .code:n =
{
\sys_if_engine_luatex:T
{
\lua_now:e{ltx.@@.trace.show_all_mc_data(#1,\@@_get_mc_abs_cnt:,0)}
}
}
,mc-data .default:n = 1
}
% \end{macrocode}
% \end{macro}
% \begin{macro}{mc-current (show-key)}
% This shows some info about the current mc-chunk. It works in generic and lua-mode.
% \begin{macrocode}
\keys_define:nn { @@ / show }
{ mc-current .code:n =
{
\bool_if:NTF \g_@@_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.@@.trace.log
(
"mc-current:~no~MC~open,~current~abscnt
=\@@_get_mc_abs_cnt:"
,0
)
texio.write_nl("")
}
}
{
\lua_now:e
{
ltx.@@.trace.log
(
"mc-current:~abscnt=\@@_get_mc_abs_cnt:=="
..
tex.getattribute(luatexbase.attributes.g_@@_mc_cnt_attr)
..
"~=>tag="
..
tostring
(ltx.@@.func.get_tag_from
(tex.getattribute
(luatexbase.attributes.g_@@_mc_type_attr)))
..
"="
..
tex.getattribute
(luatexbase.attributes.g_@@_mc_type_attr)
,0
)
texio.write_nl("")
}
}
}
}
{
\msg_note:nn{ tag }{ mc-current }
}
}
}
% \end{macrocode}
% \end{macro}
% \begin{macro}{mc-marks (show-key)}
% It maps the mc-marks into the sequences and then shows them.
% This allows to inspect the first and last mc-Mark on a page.
% It should only be used in the shipout (header/footer).
% \begin{macrocode}
\keys_define:nn { @@ / show }
{
mc-marks .choice: ,
mc-marks / show .code:n =
{
\@@_mc_get_marks:
\@@_check_if_mc_in_galley:TF
{
\iow_term:n {Marks~from~this~page:~}
}
{
\iow_term:n {Marks~from~a~previous~page:~}
}
\seq_show:N \l_@@_mc_firstmarks_seq
\seq_show:N \l_@@_mc_botmarks_seq
\@@_check_if_mc_tmb_missing:T
{
\iow_term:n {BDC~missing~on~this~page!}
}
\@@_check_if_mc_tme_missing:T
{
\iow_term:n {EMC~missing~on~this~page!}
}
},
mc-marks / use .code:n =
{
\@@_mc_get_marks:
\@@_check_if_mc_in_galley:TF
{ Marks~from~this~page:~}
{ Marks~from~a~previous~page:~}
\seq_use:Nn \l_@@_mc_firstmarks_seq {,~}\quad
\seq_use:Nn \l_@@_mc_botmarks_seq {,~}\quad
\@@_check_if_mc_tmb_missing:T
{
BDC~missing~
}
\@@_check_if_mc_tme_missing:T
{
EMC~missing
}
},
mc-marks .default:n = show
}
% \end{macrocode}
% \end{macro}
% \begin{macro}{struct-stack (show-key)}
% \begin{macrocode}
\keys_define:nn { @@ / show }
{
struct-stack .choice:
,struct-stack / log .code:n = \seq_log:N \g_@@_struct_tag_stack_seq
,struct-stack / show .code:n = \seq_show:N \g_@@_struct_tag_stack_seq
,struct-stack .default:n = show
}
% \end{macrocode}
% \end{macro}
%
% \section{Commands to extend document commands}
% The following commands and code parts are not core command of tagpdf.
% The either provide work arounds for missing functionality elsewhere,
% or do a first step to apply tagpdf commands to document commands.
% This part should be regularly revisited to check if the code should go to a
% better place or can be improved.
% \subsection{Document structure}
% \begin{macro}{\@@_add_document_structure:n,activate (setup-key)}
% \begin{macrocode}
\cs_new_protected:Npn \@@_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 { @@ / setup}
{
activate .code:n =
{
\keys_set:nn { @@ / setup }
{ activate-mc,activate-tree,activate-struct }
\@@_add_document_structure:n {#1}
},
activate .default:n = Document
}
% \end{macrocode}
% \end{macro}
% \subsection{Structure destinations}
% In TeXlive 2022 pdftex and luatex will offer support for structure destinations.
% The pdfmanagement has already backend support. We activate them if the
% prerequisites are there: structures should be activated,
% the code in the pdfmanagement must be there.
% Structure destinations are actually PDF 2.0 only but they don't harm in
% older PDF and can improve html export.
% \begin{macrocode}
\AddToHook{begindocument/before}
{
\bool_lazy_all:nT
{
{ \g_@@_active_struct_dest_bool }
{ \g_@@_active_struct_bool }
{ \cs_if_exist_p:N \pdf_activate_structure_destination: }
}
{
\tl_set:Nn \l_pdf_current_structure_destination_tl { __tag/struct/\g_@@_struct_stack_current_tl }
\pdf_activate_structure_destination:
}
}
% \end{macrocode}
% \subsection{Fake space}
% \begin{macro}{\pdffakespace}
% We need a luatex variant for |\pdffakespace|. This should probably go into
% the kernel at some time.
% \begin{macrocode}
\sys_if_engine_luatex:T
{
\NewDocumentCommand\pdffakespace { }
{
\@@_fakespace:
}
}
% \end{macrocode}
% \end{macro}
%
% \subsection{Paratagging}
% The following are some simple commands to enable/disable paratagging.
% Probably one should add some checks if we are already in a paragraph.
%
%
% \begin{macro}{
% \l_@@_para_bool,
% \l_@@_para_flattened_bool,
% \l_@@_para_show_bool,
% \g_@@_para_begin_int,
% \g_@@_para_end_int,
% \g_@@_para_main_begin_int,
% \g_@@_para_main_end_int,
% \l_@@_para_tag_default_tl,
% \l_@@_para_tag_tl,
% \l_@@_para_main_tag_tl}
% At first some variables.
% \begin{macrocode}
\bool_new:N \l_@@_para_bool
%
%\bool_new:N \l_@@_para_flattened_bool
%<*package>
\bool_new:N \l_@@_para_show_bool
\int_new:N \g_@@_para_begin_int
\int_new:N \g_@@_para_end_int
\int_new:N \g_@@_para_main_begin_int
\int_new:N \g_@@_para_main_end_int
\tl_new:N \l_@@_para_tag_default_tl
\tl_set:Nn \l_@@_para_tag_default_tl { text }
\tl_new:N \l_@@_para_tag_tl
\tl_set:Nn \l_@@_para_tag_tl { \l_@@_para_tag_default_tl }
\tl_new:N \l_@@_para_main_tag_tl
\tl_set:Nn \l_@@_para_main_tag_tl {text-unit}
% \end{macrocode}
% \end{macro}
%
%
%\begin{macro}
% {
% paratagging (setup-key),
% paratagging-show (setup-key),
% paratag (setup-key),
% paratag (tool-key),
% unittag (tool-key),
% para-flattened (tool-key),
% }
% These keys enable/disable locally paratagging, and the debug modus.
% It can affect the typesetting if |paratagging-show| is used. The small numbers
% are boxes and they have a (small) height. The |paratag| key sets the tag used by
% the next automatic paratagging, it can also be changed with |\tag_tool:n|
% \begin{macrocode}
\keys_define:nn { @@ / setup }
{
paratagging .bool_set:N = \l_@@_para_bool,
paratagging-show .bool_set:N = \l_@@_para_show_bool,
paratag .tl_set:N = \l_@@_para_tag_tl
}
\keys_define:nn { tag / tool}
{
paratag .tl_set:N = \l_@@_para_tag_tl,
unittag .tl_set:N = \l_@@_para_main_tag_tl,
para-flattened .bool_set:N = \l_@@_para_flattened_bool
}
% \end{macrocode}
% \end{macro}
% This fills the para hooks with the needed code.
% \begin{macrocode}
\cs_new_protected:Npn \@@_check_para_begin_show:nn #1 #2
%#1 color, #2 prefix
{
\bool_if:NT \l_@@_para_show_bool
{
\tag_mc_begin:n{artifact}
\llap{\color_select:n{#1}\tiny#2\int_use:N\g_@@_para_begin_int\ }
\tag_mc_end:
}
}
\cs_new_protected:Npn \@@_check_para_end_show:nn #1 #2
%#1 color, #2 prefix
{
\bool_if:NT \l_@@_para_show_bool
{
\tag_mc_begin:n{artifact}
\rlap{\color_select:n{#1}\tiny\ #2\int_use:N\g_@@_para_end_int}
\tag_mc_end:
}
}
\AddToHook{para/begin}
{
\bool_if:NT \l_@@_para_bool
{
\bool_if:NF \l_@@_para_flattened_bool
{
\int_gincr:N \g_@@_para_main_begin_int
\tag_struct_begin:n
{
tag=\l_@@_para_main_tag_tl,
}
}
\int_gincr:N \g_@@_para_begin_int
\tag_struct_begin:n {tag=\l_@@_para_tag_tl}
\@@_check_para_begin_show:nn {green}{}
\tag_mc_begin:n {}
}
}
\AddToHook{para/end}
{
\bool_if:NT \l_@@_para_bool
{
\int_gincr:N \g_@@_para_end_int
\tag_mc_end:
\@@_check_para_end_show:nn {red}{}
\tag_struct_end:
\bool_if:NF \l_@@_para_flattened_bool
{
\int_gincr:N \g_@@_para_main_end_int
\tag_struct_end:
}
}
}
\AddToHook{enddocument/info}
{
\int_compare:nNnF {\g_@@_para_main_begin_int}={\g_@@_para_main_end_int}
{
\msg_error:nnxxx
{tag}
{para-hook-count-wrong}
{\int_use:N\g_@@_para_main_begin_int}
{\int_use:N\g_@@_para_main_end_int}
{text-unit}
}
\int_compare:nNnF {\g_@@_para_begin_int}={\g_@@_para_end_int}
{
\msg_error:nnxxx
{tag}
{para-hook-count-wrong}
{\int_use:N\g_@@_para_begin_int}
{\int_use:N\g_@@_para_end_int}
{text}
}
}
% \end{macrocode}
% In generic mode we need the additional code from the ptagging tests.
% \begin{macrocode}
\AddToHook{begindocument/before}
{
\@ifundefined{@mult@ptagging@hook}{\RequirePackage{output-patches-tmp-ltx}}{} %
\bool_if:NF \g_@@_mode_lua_bool
{
\cs_if_exist:NT \@kernel@before@footins
{
\tl_put_right:Nn \@kernel@before@footins
{ \@@_add_missing_mcs_to_stream:Nn \footins {footnote} }
\tl_put_right:Nn \@kernel@before@cclv
{
\@@_check_typeout_v:n {====>~In~\token_to_str:N \@makecol\c_space_tl\the\c@page}
\@@_add_missing_mcs_to_stream:Nn \@cclv {main}
}
\tl_put_right:Nn \@mult@ptagging@hook
{
\@@_check_typeout_v:n {====>~In~\string\page@sofar}
\process@cols\mult@firstbox
{
\@@_add_missing_mcs_to_stream:Nn \count@ {multicol}
}
\@@_add_missing_mcs_to_stream:Nn \mult@rightbox {multicol}
}
}
}
}
%
% \end{macrocode}
% \begin{macro}
% {
% \tagpdfparaOn,
% \tagpdfparaOff
% }
% This two command switch para mode on and off. |\tagpdfsetup| could be used
% too but is longer. An alternative is |\tag_tool:n{para=false}|
% \begin{macrocode}
%\newcommand\tagpdfparaOn {}
%\newcommand\tagpdfparaOff{}
%<*package>
\renewcommand\tagpdfparaOn {\bool_set_true:N \l_@@_para_bool}
\renewcommand\tagpdfparaOff{\bool_set_false:N \l_@@_para_bool}
\keys_define:nn { tag / tool}
{
para .bool_set:N = \l_@@_para_bool,
para-flattened .bool_set:N = \l_@@_para_flattened_bool,
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}
% {
% \tagpdfsuppressmarks
% }
% This command allows to suppress the creation of the marks. It takes an argument
% which should normally be one of the mc-commands, puts a group around it and
% suppress the marks creation in this group. This command should be used if
% the begin and end command are at different boxing levels. E.g.
% \begin{verbatim}
% \@hangfrom
% {
% \tagstructbegin{tag=H1}%
% \tagmcbegin {tag=H1}%
% #2
% }
% {#3\tagpdfsuppressmarks{\tagmcend}\tagstructend}%
% \end{verbatim}
% \begin{macrocode}
\NewDocumentCommand\tagpdfsuppressmarks{m}
{{\use:c{@@_mc_disable_marks:} #1}}
% \end{macrocode}
% \end{macro}
% \subsection{Header and footer}
% Header and footer should normally be tagged as artifacts. The following code
% requires the new hooks.
% For now we allow to disable this function, but probably the code should always there at
% the end.
% TODO check if Pagination should be changeable.
% \begin{macrocode}
\cs_new_protected:Npn\@@_hook_kernel_before_head:{}
\cs_new_protected:Npn\@@_hook_kernel_after_head:{}
\cs_new_protected:Npn\@@_hook_kernel_before_foot:{}
\cs_new_protected:Npn\@@_hook_kernel_after_foot:{}
\AddToHook{begindocument}
{
\cs_if_exist:NT \@kernel@before@head
{
\tl_put_right:Nn \@kernel@before@head {\@@_hook_kernel_before_head:}
\tl_put_left:Nn \@kernel@after@head {\@@_hook_kernel_after_head:}
\tl_put_right:Nn \@kernel@before@foot {\@@_hook_kernel_before_foot:}
\tl_put_left:Nn \@kernel@after@foot {\@@_hook_kernel_after_foot:}
}
}
\bool_new:N \g_@@_saved_in_mc_bool
\cs_new_protected:Npn \@@_exclude_headfoot_begin:
{
\bool_set_false:N \l_@@_para_bool
\bool_if:NTF \g_@@_mode_lua_bool
{
\tag_mc_end_push:
}
{
\bool_gset_eq:NN \g_@@_saved_in_mc_bool \g_@@_in_mc_bool
\bool_gset_false:N \g_@@_in_mc_bool
}
\tag_mc_begin:n {artifact}
}
\cs_new_protected:Npn \@@_exclude_headfoot_end:
{
\tag_mc_end:
\bool_if:NTF \g_@@_mode_lua_bool
{
\tag_mc_begin_pop:n{}
}
{
\bool_gset_eq:NN \g_@@_in_mc_bool\g_@@_saved_in_mc_bool
}
}
% \end{macrocode}
% This version allows to use an Artifact structure
% \begin{macrocode}
\@@_attr_new_entry:nn {@@/attr/pagination}{/O/Artifact/Type/Pagination}
\cs_new_protected:Npn \@@_exclude_struct_headfoot_begin:n #1
{
\bool_set_false:N \l_@@_para_bool
\bool_if:NTF \g_@@_mode_lua_bool
{
\tag_mc_end_push:
}
{
\bool_gset_eq:NN \g_@@_saved_in_mc_bool \g_@@_in_mc_bool
\bool_gset_false:N \g_@@_in_mc_bool
}
\tag_struct_begin:n{tag=Artifact,attribute-class=@@/attr/#1}
\tag_mc_begin:n {artifact=#1}
}
\cs_new_protected:Npn \@@_exclude_struct_headfoot_end:
{
\tag_mc_end:
\tag_struct_end:
\bool_if:NTF \g_@@_mode_lua_bool
{
\tag_mc_begin_pop:n{}
}
{
\bool_gset_eq:NN \g_@@_in_mc_bool\g_@@_saved_in_mc_bool
}
}
% \end{macrocode}
% And now the keys
% \begin{macro}{exclude-header-footer (setup-key)}
% \begin{macrocode}
\keys_define:nn { @@ / setup }
{
exclude-header-footer .choice:,
exclude-header-footer / true .code:n =
{
\cs_set_eq:NN \@@_hook_kernel_before_head: \@@_exclude_headfoot_begin:
\cs_set_eq:NN \@@_hook_kernel_before_foot: \@@_exclude_headfoot_begin:
\cs_set_eq:NN \@@_hook_kernel_after_head: \@@_exclude_headfoot_end:
\cs_set_eq:NN \@@_hook_kernel_after_foot: \@@_exclude_headfoot_end:
},
exclude-header-footer / pagination .code:n =
{
\cs_set:Nn \@@_hook_kernel_before_head: { \@@_exclude_struct_headfoot_begin:n {pagination} }
\cs_set:Nn \@@_hook_kernel_before_foot: { \@@_exclude_struct_headfoot_begin:n {pagination} }
\cs_set_eq:NN \@@_hook_kernel_after_head: \@@_exclude_struct_headfoot_end:
\cs_set_eq:NN \@@_hook_kernel_after_foot: \@@_exclude_struct_headfoot_end:
},
exclude-header-footer / false .code:n =
{
\cs_set_eq:NN \@@_hook_kernel_before_head: \prg_do_nothing:
\cs_set_eq:NN \@@_hook_kernel_before_foot: \prg_do_nothing:
\cs_set_eq:NN \@@_hook_kernel_after_head: \prg_do_nothing:
\cs_set_eq:NN \@@_hook_kernel_after_foot: \prg_do_nothing:
},
exclude-header-footer .default:n = true,
exclude-header-footer .initial:n = true
}
% \end{macrocode}
% \end{macro}
% \subsection{Links}
% We need to close and reopen mc-chunks around links.
% Currently we handle URI and GoTo (internal) links.
% Links should have an alternative text in the Contents
% key. It is unclear which text this should be and
% how to get it.
% \begin{macrocode}
\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: }
}
\hook_gput_code:nnn
{pdfannot/link/URI/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{}
}
\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: }
}
\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{}
}
% "alternative descriptions " for PAX3. How to get better text here??
\pdfannot_dict_put:nnn
{ link/URI }
{ Contents }
{ (url) }
\pdfannot_dict_put:nnn
{ link/GoTo }
{ Contents }
{ (ref) }
% \end{macrocode}
%
% \end{implementation}
% \PrintIndex