summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/tagpdf/tagpdf-user.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/tagpdf/tagpdf-user.dtx')
-rw-r--r--macros/latex/contrib/tagpdf/tagpdf-user.dtx585
1 files changed, 585 insertions, 0 deletions
diff --git a/macros/latex/contrib/tagpdf/tagpdf-user.dtx b/macros/latex/contrib/tagpdf/tagpdf-user.dtx
new file mode 100644
index 0000000000..cbc6b79c33
--- /dev/null
+++ b/macros/latex/contrib/tagpdf/tagpdf-user.dtx
@@ -0,0 +1,585 @@
+% \iffalse meta-comment
+%
+%% File: tagpdf-user.dtx
+%
+% Copyright (C) 2019-2021 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>
+\RequirePackage{pdfmanagement-testphase}
+\DeclareDocumentMetadata{}
+\makeatletter
+\declare@file@substitution{doc.sty}{doc-v3beta.sty}
+\makeatother
+\documentclass{l3doc}
+\usepackage{array,booktabs,caption}
+\hypersetup{pdfauthor=Ulrike Fischer,
+ pdftitle=tagpdf-user module (tagpdf)}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \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.9, released 2021-06-29}
+% \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}
+%
+% \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}{\tagmcifin}
+% \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}
+% \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}
+% \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}{struct-stack}
+% \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,paratagging-show}
+% \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}
+%
+% \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} {2021-06-29} {0.9}
+ {tagpdf - user commands}
+%</header>
+% \end{macrocode}
+% \section{Setup and preamble commands}
+% \begin{macro}{\tagpdfsetup}
+% \begin{macrocode}
+%<*package>
+\NewDocumentCommand \tagpdfsetup { m }
+ {
+ \keys_set:nn { @@ / setup } { #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+
+% \section{Commands for the mc-chunks}
+% \begin{macro}{\tagmcbegin,\tagmcend,\tagmcuse }
+% \begin{macrocode}
+\NewDocumentCommand \tagmcbegin { m }
+ {
+ \tag_mc_begin:n {#1}%\ignorespaces
+ }
+
+
+\NewDocumentCommand \tagmcend { }
+ {
+ %\if_mode_horizontal: \unskip \fi: %
+ \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}
+\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}
+\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}
+%
+%
+% \begin{macro}{\tagpdfifluatexTF,\tagpdfifluatexT,\tagpdfifpdftexTF}
+% I should deprecate them ...
+% \begin{macrocode}
+\cs_set_eq:NN\tagpdfifluatexTF \sys_if_engine_luatex:TF
+\cs_set_eq:NN\tagpdfifluatexT \sys_if_engine_luatex:T
+\cs_set_eq:NN\tagpdfifpdftexT \sys_if_engine_pdftex:T
+% \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}
+\NewDocumentCommand\ShowTagging { m }
+ {
+ \keys_set:nn { @@ / show }{ #1}
+
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{mc-data}
+% 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}
+% 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}{struct-stack}
+% \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}
+% \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{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_show_bool,\g_@@_para_int}
+% At first some variables.
+% \begin{macrocode}
+\bool_new:N \l_@@_para_bool
+\bool_new:N \l_@@_para_show_bool
+\int_new:N \g_@@_para_int
+% \end{macrocode}
+% \end{macro}
+%
+%
+%\begin{macro}
+% {
+% paratagging,
+% paratagging-show,
+% }
+% 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.
+% \begin{macrocode}
+\keys_define:nn { @@ / setup }
+ {
+ paratagging .bool_set:N = \l_@@_para_bool,
+ paratagging-show .bool_set:N = \l_@@_para_show_bool,
+ }
+
+% \end{macrocode}
+% \end{macro}
+% This fills the para hooks with the needed code.
+% \begin{macrocode}
+\AddToHook{para/begin}
+ {
+ \int_gincr:N \g_@@_para_int
+ \bool_if:NT \l__tag_para_bool
+ {
+ \tag_struct_begin:n {tag=P}
+ \bool_if:NT \l_@@_para_show_bool
+ { \tag_mc_begin:n{artifact}
+ \llap{\color_select:n{red}\tiny\int_use:N\g_@@_para_int\ }
+ \tag_mc_end:
+ }
+ \tag_mc_begin:n {tag=P}
+ }
+ }
+\AddToHook{para/end}
+ {
+ \bool_if:NT \l__tag_para_bool
+ {
+ \tag_mc_end:
+ \bool_if:NT \l_@@_para_show_bool
+ { \tag_mc_begin:n{artifact}
+ \rlap{\color_select:n{red}\tiny\ \int_use:N\g_@@_para_int}
+ \tag_mc_end:
+ }
+ \tag_struct_end:
+ }
+ }
+% \end{macrocode}
+% \begin{macro}
+% {
+% \tagpdfparaOn,
+% \tagpdfparaOff
+% }
+% This two command switch para mode on and off. |\tagpdfsetup| could be used
+% too but is longer.
+% \begin{macrocode}
+\newcommand\tagpdfparaOn {\bool_set_true:N \l__tag_para_bool}
+\newcommand\tagpdfparaOff{\bool_set_false:N \l__tag_para_bool}
+% \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}
+%</package>
+% \end{implementation}
+% \PrintIndex