summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx')
-rw-r--r--macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx442
1 files changed, 442 insertions, 0 deletions
diff --git a/macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx b/macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx
new file mode 100644
index 0000000000..12680109a0
--- /dev/null
+++ b/macros/latex/contrib/tagpdf/tagpdf-mc-shared.dtx
@@ -0,0 +1,442 @@
+% \iffalse meta-comment
+%
+%% File: tagpdf-mc.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-mc module (tagpdf)}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+% \title{^^A
+% The \pkg{tagpdf-mc-shared} module\\ Code related to Marked Content (mc-chunks), code shared by all modes ^^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{Public Commands}
+% \begin{function}{\tag_mc_begin:n,\tag_mc_end:}
+% \begin{syntax}
+% \cs{tag_mc_begin:n}\Arg{key-values}\\
+% \cs{tag_mc_end:}
+% \end{syntax}
+% These commands insert the end code of the marked content.
+% They don't end a group and in generic mode it doesn't matter
+% if they are in another group as the starting commands.
+% In generic mode both commands check if they are correctly nested
+% and issue a warning if not.
+% \end{function}
+%
+% \begin{function}{\tag_mc_use:n}
+% \begin{syntax}
+% \cs{tag_mc_use:n}\Arg{label}
+% \end{syntax}
+% These command allow to record a marked content that was stashed away before
+% into the current structure. A marked content can be used only once --
+% the command will issue a warning if an mc is use a second time.
+% \end{function}
+%
+% \begin{function}[added = 2019-11-20]
+% {
+% \tag_mc_artifact_group_begin:n, \tag_mc_artifact_group_end:
+% }
+% \begin{syntax}
+% \cs{tag_mc_artifact_group_begin:n} \Arg{name}\\
+% \cs{tag_mc_artifact_group_end:}
+% \end{syntax}
+% This command pair creates a group with an artifact marker at the begin
+% and the end. Inside the group the tagging commands are disabled.
+% It allows to mark a complete region as artifact without having to worry
+% about user commands with tagging commands.
+% \meta{name} should be a value allowed also for the |artifact| key.
+% It pushes and pops mc-chunks at the begin and end.
+% TODO: document is in tagpdf.tex
+% \end{function}
+%
+% \begin{function}[added = 2021-04-22]
+% {
+% \tag_mc_end_push:, \tag_mc_begin_pop:n
+% }
+% \begin{syntax}
+% \cs{tag_mc_end_push:} \\
+% \cs{tag_mc_begin_pop:n}\Arg{key-values}
+% \end{syntax}
+% If there is an open mc chunk,
+% \cs{tag_mc_end_push:} ends it and pushes its tag of the (global) stack.
+% If there is no open chunk, it puts $-1$ on the stack (for debugging)
+% \cs{tag_mc_begin_pop:n} removes a value from the stack. If it is different from
+% $-1$ it opens a tag with it.
+% The reopened mc chunk looses info like the alttext for now.
+% \end{function}
+%
+% \begin{function}[pTF, EXP]{\tag_mc_if_in:}
+% \begin{syntax}
+% \cs{tag_mc_if_in:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Determines if a mc-chunk is open.
+% \end{function}
+
+%
+% \section{Public keys}
+% The following keys can be used with |\tag_mc_begin:n|, |\tagmcbegin|,
+% |\tag_mc_begin_pop:n|,
+%
+% \begin{function}{tag}
+% This key is required, unless artifact is used.
+% The value is a tag like |P| or |H1| without a slash at the begin,
+% this is added by the code.
+% It is possible to setup new tags.
+% The value of the key is expanded, so it can be a command.
+% The expansion is passed unchanged to the PDF,
+% so it should with a starting slash give a valid PDF name
+% (some ascii with numbers like \texttt{H4} is fine).
+% \end{function}
+%
+% \begin{function}{artifact}
+% This will setup the marked content as an artifact. The key should be used
+% for content that should be ignored.
+% The key can take one of the values |pagination|,
+% |layout|, |page|, |background| and |notype|
+% (this is the default).
+% \end{function}
+%
+% \begin{function}{raw}
+% This key allows to add more entries to the properties dictionary.
+% The value must be correct, low-level PDF. E.g.
+% \verb+raw=/Alt (Hello)+ will insert an alternative Text.
+% \end{function}
+%
+% \begin{function}{alttext,alttext-o}
+% This key inserts an \texttt{/Alt} value in the property dictionary of the BDC operator.
+% The value is handled as verbatim string, commands are not expanded. With |alttext-o|
+% the value is expanded once.
+% \end{function}
+%
+% \begin{function}{actualtext,actualtext-o}
+% This key inserts an \texttt{/ActualText} value in the property dictionary
+% of the BDC operator. The value is handled as verbatim string,
+% commands are not expanded.With |actualtext-o|
+% the value is expanded once.
+% \end{function}
+%
+% \begin{function}{label}
+% This key sets a label by which one can call the marked content
+% later in another structure
+% (if it has been stashed with the |stash| key).
+% Internally the label name will start with \texttt{tagpdf-}.
+% \end{function}
+%
+% \begin{function}{stash}
+% This \enquote{stashes} an mc-chunk: it is not inserted into the current structure.
+% It should be normally be used along with a label to be able to use the mc-chunk
+% in another place.
+% \end{function}
+% \end{documentation}
+% \begin{implementation}
+% The code is splitted into three parts: code shared by all engines,
+% code specific to luamode and code not used by luamode.
+% \section{Marked content code -- shared}
+% \begin{macrocode}
+%<@@=tag>
+%<*header>
+\ProvidesExplPackage {tagpdf-mc-code-shared} {2021-06-29} {0.9}
+ {part of tagpdf - code related to marking chunks -
+ code shared by generic and luamode }
+%</header>
+% \end{macrocode}
+%
+% \subsection{Variables and counters}
+% MC chunks must be counted.
+% I use a latex counter for the absolute count, so that it is added to
+% |\cl@@ckpt| and restored e.g. in tabulars and align.
+% |\int_new:N \c@g_@@_MCID_int| and
+% |\tl_put_right:Nn\cl@@ckpt{\@elt{g_uf_test_int}}|
+% would work too, but as the name is not expl3 then too, why bother?
+% The absolute counter can be used to label and to check if the page
+% counter needs a reset.
+%
+% \begin{variable}{g_@@_MCID_abs_int}
+% \begin{macrocode}
+%<*shared>
+\newcounter { g_@@_MCID_abs_int }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\_@@_get_mc_abs_cnt:}
+% A (expandable) function to get the current value of the cnt.
+% \begin{macrocode}
+\cs_new:Npn \_@@_get_mc_abs_cnt: { \int_use:N \c@g_@@_MCID_abs_int }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_MCID_tmp_bypage_int}
+% The following hold the temporary by page number assigned to a mc.
+% It must be defined in the shared code to avoid problems with labels.
+% \begin{macrocode}
+\int_new:N \g_@@_MCID_tmp_bypage_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_mc_parenttree_prop}
+% For every chunk we need to know the structure it is in, to
+% record this in the parent tree. We store this in a property.\\
+% key: absolute number of the mc (tagmcabs)\\
+% value: the structure number the mc is in
+% \begin{macrocode}
+\@@_prop_new:N \g_@@_mc_parenttree_prop
+% \end{macrocode}
+% \end{variable}
+%
+%\begin{variable}{\g_@@_mc_parenttree_prop}
+% Some commands (e.g. links) want to close a previous mc and reopen it after
+% they did their work. For this we create a stack:
+% \begin{macrocode}
+\seq_new:N \g_@@_mc_stack_seq
+% \end{macrocode}
+% \end{variable}
+%
+%\begin{variable}{\l_@@_mc_artifact_type_tl}
+% Artifacts can have various types like Pagination or Layout. This stored
+% in this variable.
+% \begin{macrocode}
+\tl_new:N \l_@@_mc_artifact_type_tl
+% \end{macrocode}
+% \end{variable}
+%
+%\begin{variable}{\l_@@_mc_key_stash_bool,\l_@@_mc_artifact_bool}
+%This booleans store the stash and artifact status of the mc-chunk.
+% \begin{macrocode}
+\bool_new:N \l_@@_mc_key_stash_bool
+\bool_new:N \l_@@_mc_artifact_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_mc_key_tag_tl,
+% \g_@@_mc_key_tag_tl,
+% \l_@@_mc_key_label_tl,
+% \l_@@_mc_key_properties_tl
+% }
+% Variables used by the keys. |\l_@@_mc_key_properties_tl|
+% will collect a number of values. TODO: should this be a pdfdict now?
+% \begin{macrocode}
+\tl_new:N \l_@@_mc_key_tag_tl
+\tl_new:N \g_@@_mc_key_tag_tl
+\tl_new:N \l_@@_mc_key_label_tl
+\tl_new:N \l_@@_mc_key_properties_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Functions}
+% \begin{macro}{\_@@_mc_handle_mc_label:n}
+% The commands labels a mc-chunk. It is used if the user explicitly
+% labels the mc-chunk with the |label| key. The argument is the
+% value provided by the user. It stores the attributes\\
+% |tagabspage|: the absolute page, |\g_shipout_readonly_int|,\\
+% |tagmcabs|: the absolute mc-counter |\c@g_@@_MCID_abs_int|,\\
+% |tagmcid|: the ID of the chunk on the page |\g_@@_MCID_tmp_bypage_int|, this
+% typically settles down after a second compilation.
+% The reference command is defined in tagpdf.dtx and is based on l3ref.
+% \begin{macrocode}
+\cs_new:Nn \_@@_mc_handle_mc_label:n
+ {
+ \@@_ref_label:en{tagpdf-#1}{mc}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_mc_set_label_used:n}
+% Unlike with structures we can't check if a labeled mc has been used by
+% looking at the P key, so we use a dedicated csname for the test
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_mc_set_label_used:n #1 %#1 labelname
+ {
+ \tl_new:c { g_@@_mc_label_\tl_to_str:n{#1}_used_tl }
+ }
+% \end{macrocode}
+%
+% \end{macro}
+% \begin{macro}{\tag_mc_use:n}
+% These command allow to record a marked content that was stashed away before
+% into the current structure. A marked content can be used only once --
+% the command will issue a warning if an mc is use a second time.
+% The argument is a label name set with the |label| key.
+%
+% TODO: is testing for struct the right test?
+% \begin{macrocode}
+\cs_new_protected:Npn \tag_mc_use:n #1 %#1: label name
+ {
+ \@@_check_if_active_struct:T
+ {
+ \tl_set:Nx \l_@@_tmpa_tl { \@@_ref_value:nnn{tagpdf-#1}{tagmcabs}{} }
+ \tl_if_empty:NTF\l_@@_tmpa_tl
+ {
+ \msg_warning:nnn {tag} {mc-label-unknown} {#1}
+ }
+ {
+ \cs_if_free:cTF { g_@@_mc_label_\tl_to_str:n{#1}_used_tl }
+ {
+ \@@_mc_handle_stash:x { \l_@@_tmpa_tl }
+ \@@_mc_set_label_used:n {#1}
+ }
+ {
+ \msg_warning:nnn {tag}{mc-used-twice}{#1}
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}
+% {
+% \tag_mc_artifact_group_begin:n,
+% \tag_mc_artifact_group_end:
+% }
+% This opens an artifact of the type given in the argument,
+% and then stops all tagging. It creates a group.
+% It pushes and pops mc-chunks at the begin and end.
+% \begin{macrocode}
+\cs_new_protected:Npn \tag_mc_artifact_group_begin:n #1
+ {
+ \tag_mc_end_push:
+ \tag_mc_begin:n {artifact=#1}
+ \tag_stop_group_begin:
+ }
+
+\cs_new_protected:Npn \tag_mc_artifact_group_end:
+ {
+ \tag_stop_group_end:
+ \tag_mc_end:
+ \tag_mc_begin_pop:n{}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tag_mc_end_push:, \tag_mc_begin_pop:n}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \tag_mc_end_push:
+ {
+ \@@_check_if_active_mc:T
+ {
+ \@@_mc_if_in:TF
+ {
+ \seq_gpush:Nx \g_@@_mc_stack_seq { \tag_get:n {mc_tag} }
+ \@@_check_mc_pushed_popped:nn
+ { pushed }
+ { \tag_get:n {mc_tag} }
+ \tag_mc_end:
+ }
+ {
+ \seq_gpush:Nn \g_@@_mc_stack_seq {-1}
+ \@@_check_mc_pushed_popped:nn { pushed }{-1}
+ }
+ }
+ }
+
+\cs_new_protected:Npn \tag_mc_begin_pop:n #1
+ {
+ \@@_check_if_active_mc:T
+ {
+ \seq_gpop:NNTF \g_@@_mc_stack_seq \l_@@_tmpa_tl
+ {
+ \tl_if_eq:NnTF \l_@@_tmpa_tl {-1}
+ {
+ \@@_check_mc_pushed_popped:nn {popped}{-1}
+ }
+ {
+ \@@_check_mc_pushed_popped:nn {popped}{\l_@@_tmpa_tl}
+ \tag_mc_begin:n {tag=\l_@@_tmpa_tl,#1}
+ }
+ }
+ {
+ \@@_check_mc_pushed_popped:nn {popped}{empty~stack,~nothing}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Keys}
+% This are the keys where the code can be shared between the modes.
+%
+% \begin{macro}{stash,__artifact-bool,__artifact-type}
+% the two internal artifact keys are use to define the public |artifact|.
+% \begin{macrocode}
+\keys_define:nn { @@ / mc }
+ {
+ stash .bool_set:N = \l_@@_mc_key_stash_bool,
+ __artifact-bool .bool_set:N = \l_@@_mc_artifact_bool,
+ __artifact-type .choice:,
+ __artifact-type / pagination .code:n =
+ {
+ \tl_set:Nn \l_@@_mc_artifact_type_tl { Pagination }
+ },
+ __artifact-type / layout .code:n =
+ {
+ \tl_set:Nn \l_@@_mc_artifact_type_tl { Layout }
+ },
+ __artifact-type / page .code:n =
+ {
+ \tl_set:Nn \l_@@_mc_artifact_type_tl { Page }
+ },
+ __artifact-type / background .code:n =
+ {
+ \tl_set:Nn \l_@@_mc_artifact_type_tl { Background }
+ },
+ __artifact-type / notype .code:n =
+ {
+ \tl_set:Nn \l_@@_mc_artifact_type_tl {}
+ },
+ __artifact-type / .code:n =
+ {
+ \tl_set:Nn \l_@@_mc_artifact_type_tl {}
+ },
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+%</shared>
+% \end{macrocode}
+% \end{implementation}
+% \PrintIndex