texlive[64070] Master/texmf-dist: tagpdf (7aug22)

commits+karl at tug.org commits+karl at tug.org
Sun Aug 7 23:41:10 CEST 2022


Revision: 64070
          http://tug.org/svn/texlive?view=revision&revision=64070
Author:   karl
Date:     2022-08-07 23:41:10 +0200 (Sun, 07 Aug 2022)
Log Message:
-----------
tagpdf (7aug22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/tagpdf/README.md
    trunk/Master/texmf-dist/doc/latex/tagpdf/tagpdf-code.pdf
    trunk/Master/texmf-dist/doc/latex/tagpdf/tagpdf.pdf
    trunk/Master/texmf-dist/doc/latex/tagpdf/tagpdf.tex
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-backend.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-generic.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-luacode.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-shared.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-roles.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-space.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-struct.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-user.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf.dtx
    trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf.ins
    trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-base.sty
    trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-debug-generic.sty
    trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-debug.sty
    trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-luatex.def
    trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-mc-code-generic.sty
    trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-mc-code-lua.sty
    trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf.lua
    trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty
    trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdfdocu-patches.sty

Modified: trunk/Master/texmf-dist/doc/latex/tagpdf/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tagpdf/README.md	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/doc/latex/tagpdf/README.md	2022-08-07 21:41:10 UTC (rev 64070)
@@ -1,6 +1,6 @@
 #tagpdf — A package to create tagged pdf
-Packageversion: 0.95 
-Packagedate: 2022/05/29
+Packageversion: 0.96 
+Packagedate: 2022/08/06
 Author: Ulrike Fischer
 
 ## License

Modified: trunk/Master/texmf-dist/doc/latex/tagpdf/tagpdf-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tagpdf/tagpdf.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tagpdf/tagpdf.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tagpdf/tagpdf.tex	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/doc/latex/tagpdf/tagpdf.tex	2022-08-07 21:41:10 UTC (rev 64070)
@@ -4,8 +4,8 @@
 \DocumentMetadata{pdfversion=2.0,lang=en-UK,testphase=phase-II}
 
 \makeatletter
-\def\UlrikeFischer at package@version{0.95}
-\def\UlrikeFischer at package@date{2022-05-29}
+\def\UlrikeFischer at package@version{0.96}
+\def\UlrikeFischer at package@date{2022-08-06}
 \makeatother
 
 \documentclass[DIV=12,parskip=half-,bibliography=totoc]{scrartcl}
@@ -14,10 +14,10 @@
 
 \usepackage{unicode-math}
 \setmainfont{Heuristica}
-\usepackage{microtype}
+\usepackage[nopatch]{microtype}
 \makeatletter
 % see https://github.com/schlcht/microtype/issues/8
-\patchcmd{\MT at get@prot}{\noindent}{\RawNoindent}{}{\fail}
+%\patchcmd{\MT at get@prot}{\noindent}{\RawNoindent}{}{\fail}
 \makeatother
 
 \usepackage{scrlayer-scrpage}
@@ -99,7 +99,7 @@
 \tagstructbegin{tag=Title}
 \tagmcbegin{tag=Title}
 
-\begin{center}\let\thanks\par
+\begin{center}%\let\thanks\par
 \makeatletter
   \usekomafont{title}{\huge \@title \par}
 
@@ -127,7 +127,8 @@
       You need a very current L3 programming layer.
       You need the new \LaTeX{} PDF management bundle.
 
-This package is incomplete, experimental and quite probably contains bugs.
+This package is incomplete, experimental and quite probably contains bugs. It is in parts
+quite slow as the code prefers readability over speed.
       At some time it will disappear when the code has been integrated into the \LaTeX{} format.
 
 This package can change in an incompatible way.
@@ -147,63 +148,31 @@
 
 
 \tableofcontents
-\section{Preface to version 0.94}
 
-In this version a small package, \pkg{tagpdf-base} has been added. It provides
-no-op versions of the main expl3 user commands for packages that want to support
-tagging but can't be sure if the \pkg{tagpdf} package has been loaded.
 
+\section{Introduction}
 
+Since many years the creation of accessible \PDF{}-files with \LaTeX\ which conform to the PDF/UA standard has been on the agenda of \TeX-meetings. Many people agree that this is important and Ross Moore has done quite some work on it. There is also a TUG-mailing list and a webpage \parencite{tugaccess} dedicated to this theme.
 
-\section{Preface to version 0.93}
-The main change in the package itself in this version is the support for structure destinations.
-This is a new type of destinations in \PDF~2.0.
-For pdftex and luatex this requires new binaries. They will be included
-in texlive 2022, miktex already has the new pdftex, the new luatex will probably follow soon.
+But in my opinion missing were means to \emph{experiment} with tagging and accessibility. Means to try out, how difficult it is to tag some structures, means to try out, how much tagging is really needed (standards and validators don't need to be right \ldots), means to test what else is needed so that a \PDF{} works e.g. with a screen reader. Without such experiments it is imho quite difficult to get a feeling about what has to be done, which kernel changes are needed, how packages should be adapted.
 
-Beside this mostly some clean up and bug fixes has been done.
 
-A more important step will be done in \LaTeX{} itself in the next dev-release: The command \cs{DocumentMetadata} will be
-added to the format and will take over the role of \cs{DeclareDocumentMetadata} from \pkg{pdfmanagement-testphase} and additionally
-will also load the pdf management code. This will simplify the documents as it will no longer be needed to load
-a package.
+This package were developped to close this gap by offering \emph{core} commands to tag a \PDF{}%
+\footnote{In case you don't know what this means: there will be some explanations later on.}.
+My hope was that the knowledge gained by the use of this package will at the end allow to decide if and how code to do tagging should be part of the \LaTeX\ kernel.
 
 
+The code has been written with the goal to extend \LaTeX{} itself.
+It therefore quite does not patch commands from other packages and is also not an aim of the package to develop such patches. While at the end changes to various commands in many classes and packages will be needed to get tagged \PDF{} files -- and the examples accompanying the package try (or will try) to show various strategies -- these changes should in my opinion be done by the class, package and document writers themselves using a sensible API provided by the kernel and not by some external package that adds patches everywhere and would need constant maintenance -- one only need to look at packages like tex4ht or bidi or hyperref to see how difficult and sometimes fragile this is.
 
-\section{Preface to version 0.92}
 
-In this version support for page breaks in pdftex has been added. As described in section~\ref{sec:splitpara},
-tagging markers must be added by \emph{page}. That means that a paragraph that goes over two pages must get an end
-marker at the end on the first page and a new begin marker on the next page.
+The package is now a part of the Tagged PDF project and triggered already various changes in the LaTeX kernel and the engines: There is a new PDF management,
+the new para hooks allows to automatically tag paragraphs, after changes in the output routine
+page breaks and header and footer are handled correctly, the engines support
+now structure destinations.
 
-With lualatex that is rather easy to ensure, with pdflatex it requires quite sophisticated code.
-The method is described in Frank Mittelbach's talk at TUG~2021
-\enquote{Taming the beast — Advances in paragraph tagging with pdfTeX and XeTeX}
-\url{https://youtu.be/SZHIeevyo3U?t=19551}. The new code requires a new version of the pdfmanagement-testphase package.
+I'm sure that it still has bugs. Bugs reports, suggestions and comments can be added to the issue tracker on github. \url{https://github.com/u-fischer/tagpdf}.
 
-Please check also section~\ref{sec:splitpara} for possible pitfalls.
-
-Also new in this version is the handling of header and footer: they will now be tagged as artifacts automatically.
-See section~\ref{sec:header-footer}.
-
-
-\section{Introduction}
-
-Since many year the creation of accessible \PDF{}-files with \LaTeX\ which conform to the PDF/UA standard has been on the agenda of \TeX-meetings. Many people agree that this is important and Ross Moore has done quite some work on it. There is also a TUG-mailing list and a webpage \parencite{tugaccess} dedicated to this theme.
-
-But in my opinion missing are means to \emph{experiment} with tagging and accessibility. Means to try out, how difficult it is to tag some structures, means to try out, how much tagging is really needed (standards and validators don't need to be right \ldots), means to test what else is needed so that a \PDF{} works e.g. with a screen reader. Without such experiments it is imho quite difficult to get a feeling about what has to be done, which kernel changes are needed, how packages should be adapted.
-
-This package tries to close this gap by offering \emph{core} commands to tag a \PDF{}%
-\footnote{In case you don't know what this means: there will be some explanations later on.}.
-
-My hope is that the knowledge gained by the use of this package will at the end allow to decide if and how code to do tagging should be part of the \LaTeX\ kernel.
-
-The package does not patch commands from other packages. It is also not an aim of the package to develop such patches. While at the end changes to various commands in many classes and packages will be needed to get tagged \PDF{} files -- and the examples accompanying the package try (or will try) to show various strategies -- these changes should in my opinion be done by the class, package and document writers themselves using a sensible API provided by the kernel and not by some external package that adds patches everywhere and would need constant maintenance -- one only need to look at packages like tex4ht or bidi or hyperref to see how difficult and sometimes fragile this is.
-
-So this package deliberately concentrates on the basics -- and this already quite a lot, there are much more details involved as I expected when I started.
-
-I'm sure that it has bugs. Bugs reports, suggestions and comments can be added to the issue tracker on github. \url{https://github.com/u-fischer/tagpdf}.
-
 Please also check the github site for new examples and improvements.
 
 \subsection{Tagging and accessibility}
@@ -215,7 +184,9 @@
 
 \subsection{Engines and modes}
 
-The package works currently with pdflatex and lualatex. First steps have been done to also enable support for xelatex and the latex-dvips-route; but this isn't yet much tested.
+The package theoretically with all engines, 
+But the xelatex and the latex-dvips-route are not much tested and they also don't support 
+real space glyphs. lualatex is the most powerful and safe modus, but pdflatex works ok too.
 
 The package has two modes: the \emph{generic mode} which should work in theory with every engine and the \emph{lua mode} which works only with lualatex.
 
@@ -223,7 +194,8 @@
 
 While the generic mode is not bad and I spent quite some time to get it working I nevertheless think that the lua mode is the future and the only one that will be usable for larger documents. \PDF{} is a page orientated format and so the ability of luatex to manipulate pages and nodes after the \TeX-processing is really useful here. Also with luatex characters are normally already given as unicode.
 
-The package uses quite a lot labels (in generic mode more than with luamode). At the begin it relied on the \pkg{zref} package, but switched now to a new experimental implementation for labels. The drawback of the new method is that they don't give yet good rerun messages if they have changed. I advise to use the \pkg{rerunfilecheck} package as a intermediate work-around.
+The package uses quite a lot labels (in generic mode more than with luamode). At the begin it relied on the \pkg{zref} package, but switched now to a new experimental implementation for labels. The drawback of the new method is that they don't give yet good rerun messages if they have changed. I advise to use the \pkg{rerunfilecheck} package as a intermediate work-around and when using pdflatex compile
+at best at least once or twice more often then normal. 
 
 
 \subsection{References and target PDF version}
@@ -283,7 +255,8 @@
 \end{tcolorbox}
 
 
-All examples should use the \cs{tagpdfsetup} key \PrintKeyName{uncompress} described in the next section so that uncompressed \PDF{} are created and the internal objects and structures can be inspected and -- hopefully soon -- be compared by the l3build checks.%
+All examples should use the \cs{DocumentMetadata} key \PrintKeyName{uncompress} 
+so that uncompressed \PDF{} are created and the internal objects and structures can be inspected and -- hopefully soon -- be compared by the l3build checks.%
 
 
 \section{Changes}
@@ -290,7 +263,7 @@
 \subsection{Changes in 0.3}
 
 
-In this version I improved the handling of alternative and actual text. See section~\ref{sec:alttext}. This change meant that the package relied on the module \texttt{l3str-convert}.
+In this version I improved the handling of alternative and actual text. See section~\ref{sec:alt}. This change meant that the package relies on the module \texttt{l3str-convert}.
 
 I no longer try to (pdf-)escape the tag names: it is a bit unclear how to do it at best with luatex. This will perhaps later change again.
 
@@ -307,7 +280,7 @@
 \subsection{Changes in 0.6}
 
 
-\textbf{Breaking change!} The attributes used in luamode to mark the MC-chunks are no longer set globally. I thought that global attribute would make it easier to tag, but it only leads to problem when e.g. header and footer are inserted. So from this version on the attributes are set locally and the effect of a \verb+\tagmcbegin+ ends with the current group. This means that in some cases more \verb+\tagmcbegin+ are needed and  this affected some of the examples, e.g. the patching commands for sections with KOMA. On the other side it means that quite often one can omit the \verb+\tagmcend+ command.
+\textbf{Breaking change!} The attributes used in luamode to mark the MC-chunks are no longer set globally. I thought that global attributes would make it easier to tag, but it only leads to problem when e.g. header and footer are inserted. So from this version on the attributes are set locally and the effect of a \verb+\tagmcbegin+ ends with the current group. This means that in some cases more \verb+\tagmcbegin+ are needed and  this affected some of the examples, e.g. the patching commands for sections with KOMA. On the other side it means that quite often one can omit the \verb+\tagmcend+ command.
 
 
 \subsection{Changes in version 0.61}
@@ -401,8 +374,8 @@
 
 \begin{itemize}
 \item support for page breaks in pdftex has been added, see  section~\ref{sec:splitpara},
-This requires a new version of the pdfmanagement-testphase package.
 
+
 \item header and footer are tagged as artifacts automatically, see section~\ref{sec:header-footer}.
 
 \item keys \texttt{alttext-o} and \texttt{actualtext-o} has been removed. \texttt{alttext} and \texttt{actualtext}
@@ -410,6 +383,9 @@
 
 \end{itemize}
 
+
+
+
 \subsection{Changes in version 0.93}
 
 \begin{itemize}
@@ -417,8 +393,12 @@
 has been added. This allow e.g. to add a css-file which is be used if the \PDF\ is converted to
 html.
 
-\item First steps have been done to adapt the package to planed changes in \LaTeX{}: The command \cs{DocumentMetadata} will be
-added to the format and will take over the role of \cs{DeclareDocumentMetadata} from \pkg{pdfmanagement-testphase}.
+\item First steps have been done to adapt the package to planed changes in \LaTeX{}:
+The command \cs{DocumentMetadata} will be
+added to the format and will take over the role of \cs{DeclareDocumentMetadata}
+from \pkg{pdfmanagement-testphase} and additionally
+will also load the pdf management code. This will simplify the documents
+as it will no longer be needed to load the package.
 
 \item The package has now support for \enquote{structure destinations}.
 This is a new type of destinations in \PDF~2.0.
@@ -429,6 +409,36 @@
 
 \end{itemize}
 
+\subsection{Changes in version 0.94}
+
+In this version a small package, \pkg{tagpdf-base} has been added. It provides
+no-op versions of the main expl3 user commands for packages that want to support
+tagging but can't be sure if the \pkg{tagpdf} package has been loaded.
+
+\subsection{Changes in version 0.95}
+
+Small bug fixes.
+
+\subsection{Changes in version 0.96}
+
+\begin{itemize}
+\item The \texttt{alttext} key has been renamed to \texttt{alt}, the other key name exists as alias.
+
+\item The new command |\tag_struct_object_ref:n| allows to 
+   create the object reference of a structure.
+ 
+\item a new key \texttt{parent} has been added 
+   to allow structures to choose their parent structure.
+
+\item a new option \texttt{paratag} allows to change the tag name used for the
+   automatically tagged paragraphs.
+
+\item the commands |\tag_start:|, |\tag_stop:n| and |\tag_start:n| allow
+    to stop and start tagging for example in trial typesetting.
+
+\item Small bug fixes.    
+\end{itemize}
+
 \subsection{Proof of concept: the tagging of the documentation itself}
 
 Starting with version 0.6 the documentation itself has been tagged. The tagging wasn't (and isn't) in no way perfect. The validator from Adobe didn't complain, but PAX3 wanted alternative text for all links (no idea why) and so I put everywhere simple text like \enquote{link} and \enquote{ref}. The links to footnotes gave warnings, so I disabled them. I used types from the \PDF{} version 1.7, mostly as I have no idea what should be used for code in 2.0. Margin notes were simply wrong \ldots
@@ -443,36 +453,25 @@
 
 \tagpdfparaOff
 
-\tagstructbegin{tag=Figure,alttext=PAC3 report,attribute=bbox}\tagmcbegin{tag=Figure}
+\tagstructbegin{tag=Figure,alt=PAC3 report,attribute=bbox}\tagmcbegin{tag=Figure}
 \includegraphics{pac3}
 \tagmcend\tagstructend
 
 \tagpdfparaOn
 
-\section{Setup}
+\section{Loading}
 
-The package requires the new PDF management. With a current version of \pkg{pdfmanagement-testphase} it can be loaded and
-activated like this:
+The package requires the new PDF management. With a current \LaTeX{} (2022-06-01 or newer)
+the PDF management is loaded if you use the \cs{DocumentMetadata} command before \cs{documentclass}.
+The \texttt{tagpdf} package can then be loaded and activated by using the \texttt{testphase} key. The exact behaviour of
+the \texttt{testphase} key is documented in \texttt{documentmetadata-support-doc.pdf} which
+is part of the \texttt{latex-lab} bundle.
 
 \begin{lstlisting}
-\RequirePackage{pdfmanagement-testphase}
-\DeclareDocumentMetadata
- {
-  testphase = tagpdf, % load
-  activate  = tagging % activate and create the document structure
- }
-\documentclass{article}
-\begin{document}
-some text
-\end{document}
-\end{lstlisting}
-
-With  \LaTeX{} 2022-06-01 (or a current \LaTeX-dev) the call will be simpler
-
-\begin{lstlisting}
 \DocumentMetadata
  {
-  testphase = tagpdf, % load + activate
+  % testphase = phase-I, % tagging without paragraph tagging
+  testphase = phase-II % tagging with paragraph tagging and other new stuff.
  }
 \documentclass{article}
 \begin{document}
@@ -482,14 +481,18 @@
 
 \minisec{Activation needed!}
 
+The package can also be loaded normally with |\usepackage| (but it is 
+still required to use \cs{DocumentMetadata} to load the pdfmanagement) but
+it will then -- apart from loading more packages and defining a lot of things -- not do much. You will have to \emph{activate} it with \verb+\tagpdfsetup+.
 
-When the package is loaded it will -- apart from loading more packages and defining a lot of things -- not do much. You will have to activate it with \verb+\tagpdfsetup+ or as shown above in \verb+\DeclareDocumentMetadata+/\verb+\DocumentMetadata+.
+The pdfmanagement loaded with \cs{DocumentMetadata} will in any case load \texttt{tagpdf-base} a
+small package that provides no-op versions of the main tagging commands. 
 
 Most commands do nothing if tagging is not activated, but in case a test is needed a command (with the usual p,T,F variants) is provided:
 
 \begin{docCommand}{tag_if_active:TF}{}\end{docCommand}
 
-The check is true only if \emph{everything} is activated. In all other cases (also if tagging has been stopped locally) it will be false.
+The check is true only if \emph{everything} is activated. In all other cases (including if tagging has been stopped locally) it will be false.
 
 \subsection{Modes and package options}
 
@@ -555,7 +558,9 @@
 
 \item[\PrintKeyName{paratagging-show}] Boolean. This activate/deactivates small red numbers in the places where the paratagging hook code is used.
 
+\item[\PrintKeyName{paratag}] String. This key changes the tag used by the paratagging code. The default tag is \texttt{P}. A useful local setting here can be \texttt{NonStruct}, which creates a structure \enquote{without meaning}.
 
+
 \item[\PrintKeyName{tabsorder}]
  Choice key, possible values are \PrintKeyName{row}, \PrintKeyName{column}, \PrintKeyName{structure}, \PrintKeyName{none}.  This decides if a \verb+/Tabs+ value is written to the dictionary of the page objects. Not really needed for tagging itself, but one of the things you probably need for accessibility checks. So I added it. Currently the tabsorder is the same for all pages. Perhaps this should be changed \ldots.
 \item[\PrintKeyName{tagunmarked}]
@@ -625,7 +630,7 @@
 
 \tagpdfparaOff
 
-\tagstructbegin{tag=Figure,alttext={Illustration of page stream with marked content},attribute=bbox}%
+\tagstructbegin{tag=Figure,alt={Illustration of page stream with marked content},attribute=bbox}%
 \tagmcbegin{tag=Figure}%
 \begin{tikzpicture}[baseline=(a.north),node distance=2pt,remember picture]
 \node(start){\ldots~\ldots~\ldots};
@@ -645,7 +650,7 @@
 \tagpdfparaOff
 
 \newlength\ydistance\setlength\ydistance{-0.8cm}
-\tagstructbegin{tag=Figure,alttext={Illustration of structure},attribute=bbox}%
+\tagstructbegin{tag=Figure,alt={Illustration of structure},attribute=bbox}%
 \tagmcbegin{tag=Figure}%
 \begin{tikzpicture}[remember picture,baseline=(root.north)]
 
@@ -847,14 +852,14 @@
   \item[\PrintKeyName{label}]
   This key sets a label by which you can call the marked content later in another structure (if it has been stashed with the previous key). Internally the label name will start with \texttt{tagpdf-}.
 
-  \item[\PrintKeyName{alttext}]
-   This key inserts an \texttt{/Alt} value in the property dictionary of the BDC operator. See section~\ref{sec:alttext}. The value is handled as verbatim string, commands are not expanded but the value will be expanded first once (so works like the key \texttt{alttext-o} in previous versions which has been removed).
+  \item[\PrintKeyName{alt}]
+   This key inserts an \texttt{/Alt} value in the property dictionary of the BDC operator. See section~\ref{sec:alt}. The value is handled as verbatim string, commands are not expanded but the value will be expanded first once (so works like the key \texttt{alttext-o} in previous versions which has been removed).
   That means that you can do something like in the following listing
   and it will insert \verb+\frac{a}{b}+  (hex encoded) in the \PDF{}.
 
   \begin{lstlisting}
   \newcommand\myalttext{\frac{a}{b}}
-  \tagmcbegin{tag=P,alttext=\myalttext}
+  \tagmcbegin{tag=P,alt=\myalttext}
   \end{lstlisting}
 
 
@@ -861,7 +866,7 @@
 
 
   \item[\PrintKeyName{actualtext}]
-  This key inserts an \texttt{/ActualText} value in the property dictionary of the BDC operator. See section~\ref{sec:alttext}. The value is handled as verbatim string, commands are not expanded but the value will be expanded first once (so works like the key \texttt{actualtext-o} in previous versions which has been removed).
+  This key inserts an \texttt{/ActualText} value in the property dictionary of the BDC operator. See section~\ref{sec:alt}. The value is handled as verbatim string, commands are not expanded but the value will be expanded first once (so works like the key \texttt{actualtext-o} in previous versions which has been removed).
 
   That means that you can do something like in the following listing and and it will insert \verb+X+ (hex encoded)  in the \PDF{}.
 
@@ -936,8 +941,11 @@
 
 \begin{docCommand}{tag_get:n}{\marg{key word}}\end{docCommand}
 
-This command give back some variables. Currently the only working key words are \verb+mc\_tag+, \verb+struct\_tag+ and \verb+struct\_num+. The last returns a number works also if only \pkg{tagpdf-base} has been loaded.
+This command give back some variables. Currently the only working key words are \verb+mc_tag+, \verb+struct_tag+ and \verb+struct_num+. The last returns a number and works also if only \pkg{tagpdf-base} has been loaded, but then doesn't give the same output: if \pkg{tagpdf} is loaded and tagging is active, \verb+struct_num+ gives the number of currently
+active structure, so it reverts to the parent number if a structure is closed. If only \pkg{tagpdf-base} is loaded
+nesting of structure is not tracked and so the command gives back the number of the last structure that has been created.
 
+
 \subsubsection{Luamode: global or not global -- that is the question}\label{sec:global-local}
 
 In\sidenote{Luamode mode only} luamode the mc-commands set and unset an attribute to mark the nodes. One can view such an attribute like a font change or a color: they affect all following chars and glue nodes until stopped.
@@ -994,7 +1002,7 @@
 like.
 
 \tagpdfparaOff
-\tagstructbegin{tag=Figure,alttext=Show tags of examples,attribute=bbox}\tagmcbegin{tag=Figure}
+\tagstructbegin{tag=Figure,alt=Show tags of examples,attribute=bbox}\tagmcbegin{tag=Figure}
 \includegraphics{global-ex}
 \tagmcend\tagstructend
 
@@ -1025,7 +1033,7 @@
 \begin{figure}
 \tagpdfparaOff
 
-\tagstructbegin{tag=Figure,alttext={Illustration of link annotation structure},attribute=bbox}\tagmcbegin{tag=Figure}
+\tagstructbegin{tag=Figure,alt={Illustration of link annotation structure},attribute=bbox}\tagmcbegin{tag=Figure}
 \ExplSyntaxOn
 \tag_stop_group_begin:
 \ExplSyntaxOff
@@ -1161,7 +1169,7 @@
 
 But I'm not sure that this is the best way to do math. It looks rather odd that a document should have to tell a screen reader in such detail how to read an equation. It would be much more efficient, sensible and flexible if a complete representation of the equation in mathML could be stored in the \PDF{} and the task how to read this aloud delegated to the screen reader. As \PDF{}~2.0 introduced associated files it is probable that this will be the way to go but more investigations are needed here.
 
-See also section~\ref{sec:alttext} for some more remarks and tests.
+See also section~\ref{sec:alt} for some more remarks and tests.
 
 
 \subsubsection{Split paragraphs}\label{sec:splitpara}
@@ -1186,14 +1194,18 @@
 sit amet, lacus.\tagmcend
 \end{lstlisting}
 
-Starting with version 0.91 there is code which tries to resolve this problem. Basically it works like this: every mc-command
+Starting with version 0.92 there is code which tries to resolve this problem. Basically it works like this: every mc-command
 issues a mark command (actually two slightly different). When the page is built in the output routine this mark commands are inspected
 and from them \LaTeX{} can deduce if there is a mc-chunk which must be closed or reopened.
+The method is described in Frank Mittelbach's talk at TUG~2021
+\enquote{Taming the beast — Advances in paragraph tagging with pdfTeX and XeTeX}
+\url{https://youtu.be/SZHIeevyo3U?t=19551}.
 
+
 Please note
 
 \begin{itemize}
-\item The code requires the pdfmanagement-testphase version v0.95i.
+\item The code requires a pdfmanagement-testphase version v0.95i or newer.
 \item Typically you will need more compilations than previously, don't rely on the rerun messages, but if something looks wrong
 rerun.
 \item The code relies on that related |\tagmcbegin| and |\tagmcend| are in the same boxing level. If one is in a box (which hides the marks) and the other in the main galley, things will go wrong.
@@ -1206,13 +1218,17 @@
 
 Another feature that emerged from the \LaTeX{} tagged PDF project are hooks at the begin and end of paragraphs.
 \pkg{tagpdf} makes use of these hooks to tag paragraphs. This can be activated/deactivated (also locally) with
-options of \cs{tagpdfsetup} or with the two commands above. \emph{This is very experimental and it requires a new \LaTeX!}
+options of \cs{tagpdfsetup} or with the two commands above.
 
 The automatic tagging require that for every begin of a paragraph with the begin hook code
 there a corresponding end with the closing hook code. This can fail, e.g if a |vbox| doesn't correctly issue a |\par| at the end.
-If this happens the tagging structure can get every confused. It is therefore needed to check the structure carefully as currently
-no checks are implemented to check this automatically.
+If this happens the tagging structure can get every confused. At the end of the document \pkg{tagpdf} checks if
+the number of start and end paragraph structures created here are equal and it will error if not.
 
+Nesting the activation and deactivation of the tagging of paragraphs can be quite difficult. For example if it is unclear if the inner code issues a |\par| or not it is not trivial to exclude an end hook for every excluded begin hook.
+In such cases it can be easier to use the new |paratag| key with the value |NonStruct| to convert some |P|-structures
+into |NonStruct|-structures without real meaning.
+
 \subsection{Task 2: Marking the structure}
 
 
@@ -1296,16 +1312,29 @@
    Normally a new structure inserts itself as a kid into the currently active structure. This key prohibits this. The structure is nevertheless from now on \enquote{the current active structure} and parent for following  marked content and structures.
 
   \item[\PrintKeyName{label}]
-   This key sets a label by which you can use the structure later in another structure. Internally the label name will start with \texttt{tagpdfstruct-}.
+   This key sets a label by which one can refer to the structure. It is e.g.
+   used by \cs{tag\_struct\_use:n} (where a real label is actually not
+   needed as you can only use structures already defined), and by the
+   |ref| key (which can refer to future structures).
+   Internally the label name will start with \texttt{tagpdfstruct-} and it stores
+   the two attributes \texttt{tagstruct} (the structure number) and \texttt{tagstructobj} (the
+   object reference).
 
+  \item[\PrintKeyName{parent}]
+  % By default a structure is added as kid to the currently active structure.
+   With the parent key one can choose another parent. The value is a structure number which
+   must refer to an already existing, previously created structure. Such a structure
+   number can for example be have been stored with \cs{tag\_get:n}, but one can also use
+   a label on the parent structure and then use
+   \cs{ref\_value:nn}\verb+{tagpdfstruct-label}{tagstruct}+ to retrieve it.
 
-  \item[\PrintKeyName{alttext}]
-   This key inserts an \texttt{/Alt} value in the dictionary of structure object, see section~\ref{sec:alttext}. The value is handled as verbatim string and hex encoded. The value will be expanded first once (so works like the key \texttt{alttext-o} in previous versions which has been removed). That means that you can do something like this:
+  \item[\PrintKeyName{alt}]
+   This key inserts an \texttt{/Alt} value in the dictionary of structure object, see section~\ref{sec:alt}. The value is handled as verbatim string and hex encoded. The value will be expanded first once (so works like the key \texttt{alttext-o} in previous versions which has been removed). That means that you can do something like this:
 
 
       \begin{lstlisting}
       \newcommand\myalttext{\frac{a}{b}}
-      \tagstructbegin{tag=P,alttext=\myalttext}
+      \tagstructbegin{tag=P,alt=\myalttext}
       \end{lstlisting}
 
 
@@ -1315,7 +1344,7 @@
 
 
   \item[\PrintKeyName{actualtext}]
-   This key inserts an \texttt{/ActualText} value in the dictionary of structure object,  see section~\ref{sec:alttext}. The value is handled as verbatim string, The value will be expanded first once (so works like the key \texttt{alttext-o} in previous versions which has been removed). That means that you can do something like this:
+   This key inserts an \texttt{/ActualText} value in the dictionary of structure object,  see section~\ref{sec:alt}. The value is handled as verbatim string, The value will be expanded first once (so works like the key \texttt{alttext-o} in previous versions which has been removed). That means that you can do something like this:
 
       \begin{lstlisting}
       \newcommand\myactualtext{X}
@@ -1398,7 +1427,8 @@
    \item[\PrintKeyName{ref}]
      This key allows to add references to other structure elements, it adds the |/Ref| array to the structure.
        The value should be a comma separated list of structure labels set with the |label| key.
-     e.g. |ref={label1,label2}|.
+     e.g. |ref={label1,label2}|. It can be used more than once in the key/value argument and combines the
+     references.
 
    \item[\PrintKeyName{E}]
      This key sets the |/E| key, the expanded form of an abbreviation or an acronym (I couldn't think of a better name, so I sticked to E).
@@ -1548,7 +1578,7 @@
 \subsection{Lazy and automatic tagging}\label{sec:lazy}
 
 
-A number of features of \PDF{} readers need a fully tagged \PDF{}. As an example screen readers tend to ignore alternative text (see section~\ref{sec:alttext}) if the \PDF{} is not fully tagged. Also reflowing a \PDF{} only works for me (even if real space chars are in the \PDF{}) if the \PDF{} is fully tagged.
+A number of features of \PDF{} readers need a fully tagged \PDF{}. As an example screen readers tend to ignore alternative text (see section~\ref{sec:alt}) if the \PDF{} is not fully tagged. Also reflowing a \PDF{} only works for me (even if real space chars are in the \PDF{}) if the \PDF{} is fully tagged.
 
 This means that even if you don't care about a proper structure you should try to add at least some minimal tagging. With pdflatex this is not easy due to the page break problem. But with lualatex you can use an \texttt{Document} structure and inside it rather large mc-chunks. This minimizes the needed work.
 
@@ -1576,7 +1606,7 @@
 
 
 
-\section{Alternative text, ActualText and text-to-speech software}\label{sec:alttext}
+\section{Alternative text, ActualText and text-to-speech software}\label{sec:alt}
 
 
 
@@ -1586,7 +1616,7 @@
 
 The value of \PrintKeyName{/ActualText} (inserted by \texttt{tagpdf} with \PrintKeyName{actualtext}) is meant to replace single characters or rather small pieces of text. It can be used also without any tagging (e.g. with the package accsupp). If the \PDF{} reader support this (adobe reader does, sumatra not) one can change with it how a piece of text is copied and pasted e.g. to split up a ligature.
 
-\PrintKeyName{/Alt} (inserted by \texttt{tagpdf} with \PrintKeyName{alttext}) is a key to improve accessibility: with it one can add to a picture or something else an alternative text.
+\PrintKeyName{/Alt} (inserted by \texttt{tagpdf} with \PrintKeyName{alt}) is a key to improve accessibility: with it one can add to a picture or something else an alternative text.
 
 The file \texttt{ex-alt-actualtext.tex} shows some experiments I made with with both keys and text-to-speech software (the in-built of adobe and nvda).
 To sum them up:
@@ -1839,7 +1869,7 @@
 
 \tagpdfparaOff
 
-\tagstructbegin{tag=Figure,alttext={Illustration of postfix notation},attribute=bbox}\tagmcbegin{tag=Figure}
+\tagstructbegin{tag=Figure,alt={Illustration of postfix notation},attribute=bbox}\tagmcbegin{tag=Figure}
 \begin{tikzpicture}[baseline=(c.base)]
 \node[arg](a1) {18};
 \node[arg,right=of a1.east](a2) {0};
@@ -1912,7 +1942,7 @@
 
 \tagpdfparaOff
 
-    \tagstructbegin{tag=Figure,alttext={Illustration of array},attribute=bbox}\tagmcbegin{tag=Figure}
+    \tagstructbegin{tag=Figure,alt={Illustration of array},attribute=bbox}\tagmcbegin{tag=Figure}
     \begin{tikzpicture}[baseline=(c.base)]
     \node[arg](a1) {0};
     \node[arg,right = of a1.east](a2) {15 0 R};

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-backend.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-backend.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-backend.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -47,13 +47,13 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{implementation}
 %    \begin{macrocode}
 %<@@=tag>
 %<*luatex>
-\ProvidesExplFile {tagpdf-luatex.def} {2022-05-29} {0.95}
+\ProvidesExplFile {tagpdf-luatex.def} {2022-08-06} {0.96}
   {tagpdf~driver~for~luatex}
 %    \end{macrocode}
 % \section{Loading the lua}
@@ -157,8 +157,8 @@
 
 local ProvidesLuaModule = {
     name          = "tagpdf",
-    version       = "0.95",       --TAGVERSION
-    date          = "2022-05-29", --TAGDATE
+    version       = "0.96",       --TAGVERSION
+    date          = "2022-08-06", --TAGDATE
     description   = "tagpdf lua code",
     license       = "The LATEX Project Public License 1.3c"
 }

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -48,7 +48,7 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{documentation}
 % \section{Commands}
@@ -60,9 +60,10 @@
 %  \begin{syntax}
 %  \cs{tag_get:n}\Arg{keyword}
 %  \end{syntax}
-% This is a generic command to retrieve data. Currently
+% This is a generic command to retrieve data for the current structure or
+% mc-chunk. Currently
 % the only sensible values for the argument \meta{keyword}
-% are |mc_tag| and |struct_tag|.
+% are |mc_tag| and |struct_tag| and |struct_num|.
 % \end{function}
 %
 % \section{Description of log messages}
@@ -294,7 +295,7 @@
 %    \begin{macrocode}
 %<@@=tag>
 %<*header>
-\ProvidesExplPackage {tagpdf-checks-code} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-checks-code} {2022-08-06} {0.96}
  {part of tagpdf - code related to checks, conditionals, debugging and messages}
 %</header>
 %    \end{macrocode}
@@ -355,7 +356,14 @@
   }
 %    \end{macrocode}
 % \end{macro}
-% \subsection{Messages related to mc-chunks}
+% \subsection{Messages related to structures}
+% \begin{macro}{struct-unknown}
+% if for example a parent key value points to structure that doesn't exist (yet)
+%    \begin{macrocode}
+\msg_new:nnn { tag } {struct-unknown}
+   { structure~with~number~#1~doesn't~exist\\ #2 }
+%    \end{macrocode}
+% \end{macro}
 % \begin{macro}{struct-no-objnum}
 % Should not happen \ldots
 %    \begin{macrocode}
@@ -463,7 +471,7 @@
 % This retrieves some data.
 % This is a generic command to retrieve data. Currently
 % the only sensible values for the argument are |mc_tag|, |struct_tag|
-% and |struct-num|.
+% and |struct_num|.
 %    \begin{macrocode}
 %<base>\cs_new:Npn \tag_get:n #1   { \use:c {@@_get_data_#1: } }
 %    \end{macrocode}
@@ -883,7 +891,7 @@
 %    \begin{macrocode}
 \msg_new:nnn { tag / debug } {struct-begin}
   {
-    Struct~begin~#1~with~options:~\tl_to_str:n{#2}~[\msg_line_context:]
+    Struct~\tag_get:n{struct_num}~begin~#1~with~options:~\tl_to_str:n{#2}~[\msg_line_context:]
   }
 \msg_new:nnn { tag / debug } {struct-end}
   {

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-generic.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-generic.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-generic.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{documentation}
 % \end{documentation}
@@ -55,11 +55,11 @@
 %    \begin{macrocode}
 %<@@=tag>
 %<*generic>
-\ProvidesExplPackage {tagpdf-mc-code-generic} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-mc-code-generic} {2022-08-06} {0.96}
  {part of tagpdf - code related to marking chunks - generic mode}
 %</generic>
 %<*debug>
-\ProvidesExplPackage {tagpdf-debug-generic} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-debug-generic} {2022-08-06} {0.96}
  {part of tagpdf - debugging code related to marking chunks - generic mode}
 %</debug>
 %    \end{macrocode}
@@ -353,7 +353,7 @@
 %    for boxes produced for columns in that environment. Other streams
 %    may follow over time.
 %    \begin{macrocode}
-\cs_new:Npn\@@_add_missing_mcs:Nn #1 #2 {
+\cs_new_protected:Npn\@@_add_missing_mcs:Nn #1 #2 {
   \vbadness \@M
   \vfuzz    \c_max_dim
   \vbox_set_to_ht:Nnn #1 { \box_ht:N #1 } {
@@ -752,7 +752,7 @@
 %  {
 %   tag (mc-key),
 %   raw (mc-key),
-%   alttext (mc-key),
+%   alt (mc-key),
 %   actualtext (mc-key),
 %   label (mc-key),
 %   artifact (mc-key)
@@ -770,7 +770,7 @@
       {
         \tl_put_right:Nx \l_@@_mc_key_properties_tl { #1 }
       },
-    alttext .code:n      = % Alt property
+    alt .code:n      = % Alt property
       {
         \str_set_convert:Noon
           \l_@@_tmpa_str
@@ -780,6 +780,7 @@
         \tl_put_right:Nn \l_@@_mc_key_properties_tl { /Alt~< }
         \tl_put_right:No \l_@@_mc_key_properties_tl { \l_@@_tmpa_str>~ }
       },
+    alttext .meta:n = {alt=#1},
     actualtext .code:n      = % ActualText property
       {
         \str_set_convert:Noon

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-luacode.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-luacode.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-luacode.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{implementation}
 % The code is splitted into three parts: code shared by all engines,
@@ -86,7 +86,7 @@
 %    \begin{macrocode}
 %<@@=tag>
 %<*luamode>
-\ProvidesExplPackage {tagpdf-mc-code-lua} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-mc-code-lua} {2022-08-06} {0.96}
   {tagpdf - mc code only for the luamode }
 %</luamode>
 %    \end{macrocode}
@@ -355,7 +355,7 @@
 %   {
 %    tag (mc-key),
 %    raw (mc-key),
-%    alttext (mc-key),
+%    alt (mc-key),
 %    actualtext (mc-key),
 %    label (mc-key),
 %    artifact (mc-key)
@@ -381,7 +381,7 @@
             ltx.@@.func.store_mc_data(\@@_get_mc_abs_cnt:,"raw","#1")
           }
       },
-    alttext .code:n      = % Alt property
+    alt .code:n      = % Alt property
       {
         \str_set_convert:Noon
           \l_@@_tmpa_str
@@ -398,6 +398,7 @@
               )
           }
       },
+    alttext .meta:n = {alt=#1},  
     actualtext .code:n      = % Alt property
       {
         \str_set_convert:Noon

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-shared.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-shared.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-mc-shared.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{documentation}
 % \section{Public Commands}
@@ -101,7 +101,7 @@
 % 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.
+% The reopened mc chunk looses info like the alt text for now.
 % \end{function}
 %
 % \begin{function}[pTF, EXP]{\tag_mc_if_in:}
@@ -141,7 +141,7 @@
 % \verb+raw=/Alt (Hello)+ will insert an alternative Text.
 % \end{function}
 %
-% \begin{function}{alttext (mc-key)}
+% \begin{function}{alt (mc-key)}
 %  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.
 %  The value will be expanded first once.
@@ -174,7 +174,7 @@
 %    \begin{macrocode}
 %<@@=tag>
 %<*header>
-\ProvidesExplPackage {tagpdf-mc-code-shared} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-mc-code-shared} {2022-08-06} {0.96}
   {part of tagpdf - code related to marking chunks -
    code shared by generic and luamode }
 %</header>

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-roles.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-roles.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-roles.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{documentation}
 % \begin{function}
@@ -87,7 +87,7 @@
 %    \begin{macrocode}
 %<@@=tag>
 %<*header>
-\ProvidesExplPackage {tagpdf-roles-code} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-roles-code} {2022-08-06} {0.96}
  {part of tagpdf - code related to roles and structure names}
 %</header>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-space.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-space.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-space.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{documentation}
 % \begin{function}{interwordspace (setup-key)}
@@ -64,7 +64,7 @@
 %    \begin{macrocode}
 %<@@=tag>
 %<*header>
-\ProvidesExplPackage {tagpdf-space-code} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-space-code} {2022-08-06} {0.96}
  {part of tagpdf - code related to real space chars}
 %</header>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-struct.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-struct.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-struct.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{documentation}
 % \section{Public Commands}
@@ -67,6 +67,18 @@
 % A structure should be used only once,
 % if the structure already has a parent a warning is issued.
 % \end{function}
+%  \begin{function}{\tag_struct_object_ref:n,\tag_struct_object_ref:e}
+%   \begin{syntax}
+%     \cs{tag_struct_object_ref:n}\Arg{struct number}
+%   \end{syntax}
+%   This is a small wrapper around |\pdf_object_ref:n| to retrieve the
+%   object reference of the structure with the number \meta{struct number}.
+%   This number can be retrieved and stored for the current structure
+%   for example with \cs{tag_get:n}\Arg{struct_num}. Be aware that it can only
+%   be used if the structure has already been created and that it doesn't check
+%   if the object actually exists!
+%  \end{function}
+%
 % The following two functions are used to add annotations. They must be used
 % together and with care to get the same numbers. Perhaps some improvements are needed
 % here.
@@ -109,9 +121,22 @@
 % \end{function}
 % \begin{function}{label (struct-key)}
 % This key sets a label by which
-% one can use the structure later in another structure.
-% Internally the label name will start with \texttt{tagpdfstruct-}.
+% one can refer to the structure. It is e.g.
+% used by \cs{tag_struct_use:n} (where a real label is actually not
+% needed as you can only use structures already defined), and by the
+% |ref| key (which can refer to future structures).
+% Internally the label name will start with \texttt{tagpdfstruct-} and it stores
+% the two attributs |tagstruct| (the structure number) and |tagstructobj| (the
+% object reference).
 % \end{function}
+% \begin{function}{parent (struct-key)}
+% By default a structure is added as kid to the currently active structure.
+% With the parent key one can choose another parent. The value is a structure number which
+% must refer to an already existing, previously created structure. Such a structure
+% number can for example be have been stored with \cs{tag_get:n}, but one can also use
+% a label on the parent structure and then use
+% \cs{ref_value:nn}|{tagpdfstruct-label}{tagstruct}| to retrieve it.
+% \end{function}
 % \begin{function}{title (struct-key),title-o (struct-key)}
 % This keys allows to set the dictionary entry
 % \texttt{/Title} in the structure object.
@@ -119,7 +144,7 @@
 % Commands are not expanded. |title-o| will expand the value once.
 % \end{function}
 %
-% \begin{function}{alttext (struct-key)}
+% \begin{function}{alt (struct-key)}
 % This key inserts an \texttt{/Alt} value in the dictionary of structure object.
 % The value is handled as verbatim string and hex encoded.
 % The value will be expanded first once.
@@ -217,7 +242,7 @@
 %    \begin{macrocode}
 %<@@=tag>
 %<*header>
-\ProvidesExplPackage {tagpdf-struct-code} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-struct-code} {2022-08-06} {0.96}
  {part of tagpdf - code related to storing structure}
 %</header>
 %    \end{macrocode}
@@ -274,10 +299,14 @@
 % \end{variable}
 %
 % \begin{variable}{\g_@@_struct_stack_current_tl,\l_@@_struct_stack_parent_tmpa_tl}
-% The global variable will hold the current structure number.
+% The global variable will hold the current structure number. It is already
+% defined in \texttt{tagpdf-base}.
 % The local temporary variable will hold the parent when we fetch it from the stack.
 %    \begin{macrocode}
-\tl_new:N     \g_@@_struct_stack_current_tl
+%</package>
+%<base>\tl_new:N  \g_@@_struct_stack_current_tl
+%<base>\tl_gset:Nn \g_@@_struct_stack_current_tl {\int_use:N\c at g_@@_struct_abs_int}
+%<*package>
 \tl_new:N     \l_@@_struct_stack_parent_tmpa_tl
 %    \end{macrocode}
 % \end{variable}
@@ -617,6 +646,7 @@
 
 %    \end{macrocode}
 % \end{macro}
+%  \subsection{Output of the object}
 % \begin{macro}{\@@_struct_get_dict_content:nN}
 % This maps the dictionary content of a structure into a tl-var.
 % Basically it does what |\pdfdict_use:n| does.
@@ -639,7 +669,18 @@
                { g_@@_struct_#1_prop }
                { ##1 }
                {
-                 \c_space_tl/##1~\prop_item:cn{ g_@@_struct_#1_prop } { ##1 }
+                 \c_space_tl/##1~
+%    \end{macrocode}
+% Some keys needs the option to format the key, e.g. add brackets for an
+% array
+%    \begin{macrocode}
+                 \cs_if_exist_use:cTF {@@_struct_format_##1:e}
+                   {
+                     { \prop_item:cn{ g_@@_struct_#1_prop } { ##1 } }
+                   }
+                   {
+                     \prop_item:cn{ g_@@_struct_#1_prop } { ##1 }
+                   }
                }
           }
       }
@@ -646,6 +687,14 @@
   }
 %    \end{macrocode}
 % \end{macro}
+% \begin{macro}{\@@_struct_format_Ref:n}
+% Ref is an array, we store only the content to be able to extend it
+% so the formatting command adds the brackets:
+%    \begin{macrocode}
+\cs_new:Nn\__tag_struct_format_Ref:n{[#1]}
+\cs_generate_variant:Nn\__tag_struct_format_Ref:n{e}
+%    \end{macrocode}
+% \end{macro}
 % \begin{macro}{\@@_struct_write_obj:n}
 % This writes out the structure object.
 % This is done in the finish code, in the tree module and
@@ -658,7 +707,7 @@
         \@@_struct_fill_kid_key:n { #1 }
         \@@_struct_get_dict_content:nN { #1 } \l_@@_tmpa_tl
         \exp_args:Nx
-          \pdf_object_write:nx
+          \pdf_object_write_dict:nx
             { @@/struct/#1 }
             {
               \l_@@_tmpa_tl
@@ -744,7 +793,7 @@
     \exp_args:Ne
     \tl_tail:n
      {
-       \prop_item:cn {g_@@_struct_\g__tag_struct_stack_current_tl _prop}{S}
+       \prop_item:cn {g_@@_struct_\g_@@_struct_stack_current_tl _prop}{S}
      }
   }
 %</package>
@@ -758,7 +807,7 @@
 %<*base>
 \cs_new:Npn \@@_get_data_struct_num:
   {
-    \int_use:N\c at g_@@_struct_abs_int
+    \g_@@_struct_stack_current_tl
   }
 %</base>
 %    \end{macrocode}
@@ -772,10 +821,11 @@
 %  {
 %    label (struct-key),
 %    stash (struct-key),
+%    parent (struct-key),
 %    tag (struct-key),
 %    title (struct-key),
 %    title-o (struct-key),
-%    alttext (struct-key),
+%    alt (struct-key),
 %    actualtext (struct-key),
 %    lang (struct-key),
 %    ref (struct-key),
@@ -787,9 +837,26 @@
   {
     label .tl_set:N      = \l_@@_struct_key_label_tl,
     stash .bool_set:N    = \l_@@_struct_elem_stash_bool,
+    parent .code:n       =
+      {
+        \bool_lazy_and:nnTF
+          {
+            \prop_if_exist_p:c { g_@@_struct_\int_eval:n {#1}_prop }
+          }
+          {
+            \int_compare_p:nNn {#1}<{\c at g_@@_struct_abs_int}
+          }
+          { \tl_set:Nx \l_@@_struct_stack_parent_tmpa_tl { \int_eval:n {#1} } }
+          {
+            \msg_warning:nnxx { tag } { struct-unknown }
+              { \int_eval:n {#1} }
+              { parent~key~ignored }
+          }
+      },
+    parent .default:n    = {-1},
     tag   .code:n        = % S property
       {
-        \seq_set_split:Nne \l_@@_tmpa_seq { / } {#1/\prop_item:Nn\g__tag_role_tags_NS_prop{#1}}
+        \seq_set_split:Nne \l_@@_tmpa_seq { / } {#1/\prop_item:No\g__tag_role_tags_NS_prop{#1}}
         \tl_gset:Nx \g_@@_struct_tag_tl    { \seq_item:Nn\l_@@_tmpa_seq {1} }
         \tl_gset:Nx \g_@@_struct_tag_NS_tl { \seq_item:Nn\l_@@_tmpa_seq {2} }
         \@@_check_structure_tag:N \g_@@_struct_tag_tl
@@ -829,7 +896,7 @@
           { T }
           { <\l_@@_tmpa_str> }
       },
-    alttext .code:n      = % Alt property
+    alt .code:n      = % Alt property
       {
         \str_set_convert:Noon
           \l_@@_tmpa_str
@@ -841,6 +908,7 @@
           { Alt }
           { <\l_@@_tmpa_str> }
       },
+    alttext .meta:n = {alt=#1},
     actualtext .code:n  = % ActualText property
       {
         \str_set_convert:Noon
@@ -860,18 +928,18 @@
           { Lang }
           { (#1) }
       },
-    ref .code:n        = % Lang property
+%    \end{macrocode}
+% Ref is an array, the brackets are added through the formatting command.
+%    \begin{macrocode}
+    ref .code:n        = % ref property
       {
         \tl_clear:N\l_@@_tmpa_tl
-        \clist_map_inline:nn {#1}
+        \clist_map_inline:on {#1}
           {
             \tl_put_right:Nx \l_@@_tmpa_tl
               {~\ref_value:nn{tagpdfstruct-##1}{tagstructobj} }
           }
-        \@@_prop_gput:cnx
-          { g_@@_struct_\int_eval:n {\c at g_@@_struct_abs_int}_prop }
-          { Ref }
-          { [\l_@@_tmpa_tl] }
+        \@@_struct_gput_data_ref:ee { \int_eval:n {\c at g_@@_struct_abs_int} } {\l_@@_tmpa_tl}
       },
     E .code:n        = % E property
       {
@@ -1044,6 +1112,7 @@
           { g_@@_struct_\int_eval:n { \c at g_@@_struct_abs_int }_prop }
           { Type }
           { /StructElem }
+        \tl_set:Nn \l_@@_struct_stack_parent_tmpa_tl {-1}
         \keys_set:nn { @@ / struct} { #1 }
         \@@_check_structure_has_tag:n { \int_eval:n {\c at g_@@_struct_abs_int} }
         \tl_if_empty:NF
@@ -1051,13 +1120,19 @@
           {
             \@@_ref_label:en{tagpdfstruct-\l_@@_struct_key_label_tl}{struct}
           }
-        %get the potential parent from the stack:
-        \seq_get:NNF
-          \g_@@_struct_stack_seq
-          \l_@@_struct_stack_parent_tmpa_tl
+%    \end{macrocode}
+% The structure number of the parent is either taken from the stack or
+% has been set with the parent key.
+%    \begin{macrocode}
+        \int_compare:nNnT { \l_@@_struct_stack_parent_tmpa_tl } = { -1 }
           {
-            \msg_error:nn { tag } { struct-faulty-nesting }
-          }
+            \seq_get:NNF
+              \g_@@_struct_stack_seq
+              \l_@@_struct_stack_parent_tmpa_tl
+              {
+                \msg_error:nn { tag } { struct-faulty-nesting }
+              }
+           }
         \seq_gpush:NV \g_@@_struct_stack_seq        \c at g_@@_struct_abs_int
         \seq_gpush:NV \g_@@_struct_tag_stack_seq    \g_@@_struct_tag_tl
         \tl_gset:NV   \g_@@_struct_stack_current_tl \c at g_@@_struct_abs_int
@@ -1151,9 +1226,61 @@
           }
       }
   }
+%</package>
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[EXP]{\tag_struct_object_ref:n}
+% This is a command that allows to reference a structure. The argument is the
+% number which can be get for the current structure with |\tag_get:n{struct_num}|
+% TODO check if it should be in base too.
+%    \begin{macrocode}
+%<*package>
+\cs_new:Npn \tag_struct_object_ref:n #1
+ {
+   \pdf_object_ref:n {@@/struct/#1}
+ }
+\cs_generate_variant:Nn \tag_struct_object_ref:n {e}
+%    \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\tag_struct_gput:nnn}
+% This is a command that allows to update the data of a structure.
+% The first argument is the
+% number of the structure, the second a keyword referring to a function,
+% the third the value. Currently the only keyword is \texttt{ref}
+%    \begin{macrocode}
+\cs_new_protected:Npn \tag_struct_gput:nnn #1 #2 #3
+ {
+   \cs_if_exist_use:cF {@@_struct_gput_data_#2:nn}
+    { %warning??
+      \use_none:nn
+    }
+    {#1}{#3}
+ }
+\cs_generate_variant:Nn \tag_struct_gput:nnn {ene,nne}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_struct_gput_data_ref:nn}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_struct_gput_data_ref:nn #1 #2
+   % #1 receiving struct num, #2 list of object ref
+   {
+     \prop_get:cnN
+        { g_@@_struct_#1_prop }
+        {Ref}
+        \l_@@_tmpb_tl
+     \@@_prop_gput:cnx
+        { g_@@_struct_#1_prop }
+        { Ref }
+        { \quark_if_no_value:NF\l_@@_tmpb_tl { \l_@@_tmpb_tl\c_space_tl }#2 }
+    }
+\cs_generate_variant:Nn \@@_struct_gput_data_ref:nn {ee}
+%    \end{macrocode}
+% \end{macro}
+
 % \begin{macro}
 %   {
 %     \tag_struct_insert_annot:nn,
@@ -1192,7 +1319,7 @@
 % \section{Attributes and attribute classes}
 %    \begin{macrocode}
 %<*header>
-\ProvidesExplPackage {tagpdf-attr-code} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-attr-code} {2022-08-06} {0.96}
   {part of tagpdf - code related to attributes and attribute classes}
 %</header>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-tree.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -47,13 +47,13 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{implementation}
 %    \begin{macrocode}
 %<@@=tag>
 %<*header>
-\ProvidesExplPackage {tagpdf-tree-code} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-tree-code} {2022-08-06} {0.96}
  {part of tagpdf - code related to writing trees and dictionaries to the pdf}
 %</header>
 %    \end{macrocode}
@@ -285,7 +285,7 @@
         \@@_tree_fill_parenttree:
       }
     \tl_put_right:NV \l_@@_parenttree_content_tl\g_@@_parenttree_objr_tl
-    \pdf_object_write:nx  { @@/tree/parenttree }
+    \pdf_object_write_dict:nx  { @@/tree/parenttree }
       {
         /Nums\c_space_tl [\l_@@_parenttree_content_tl]
       }
@@ -310,7 +310,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_tree_write_rolemap:
   {
-    \pdf_object_write:nx  { @@/tree/rolemap }
+    \pdf_object_write_dict:nx  { @@/tree/rolemap }
       {
         \pdfdict_use:n{g_@@_role/RoleMap_dict}
       }
@@ -346,7 +346,7 @@
       \l_@@_tmpa_tl
       {
         \pdf_object_new:nn { @@/tree/classmap }{ dict }
-        \pdf_object_write:nx
+        \pdf_object_write_dict:nx
           { @@/tree/classmap }
           { \l_@@_tmpa_tl }
         \@@_prop_gput:cnx
@@ -373,7 +373,7 @@
       {
         \pdfdict_if_empty:nF {g_@@_role/RoleMapNS_##1_dict}
           {
-            \pdf_object_write:nx {@@/RoleMapNS/##1}
+            \pdf_object_write_dict:nx {@@/RoleMapNS/##1}
               {
                 \pdfdict_use:n {g_@@_role/RoleMapNS_##1_dict}
               }
@@ -380,12 +380,12 @@
             \pdfdict_gput:nnx{g_@@_role/Namespace_##1_dict}
               {RoleMapNS}{\pdf_object_ref:n {@@/RoleMapNS/##1}}
           }
-        \pdf_object_write:nx{tag/NS/##1}
+        \pdf_object_write_dict:nx{tag/NS/##1}
           {
              \pdfdict_use:n {g_@@_role/Namespace_##1_dict}
           }
       }
-    \pdf_object_write:nx {@@/tree/namespaces}
+    \pdf_object_write:nx {@@/tree/namespaces} %array
       {
         \prop_map_tokens:Nn \g_@@_role_NS_prop{\use_ii:nn}
       }

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-user.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-user.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf-user.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -46,7 +46,7 @@
 %    }^^A
 % }
 %
-% \date{Version 0.95, released 2022-05-29}
+% \date{Version 0.96, released 2022-08-06}
 % \maketitle
 % \begin{documentation}
 % \section{Setup commands}
@@ -246,7 +246,7 @@
 %    \begin{macrocode}
 %<@@=tag>
 %<*header>
-\ProvidesExplPackage {tagpdf-user} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-user} {2022-08-06} {0.96}
   {tagpdf - user commands}
 %</header>
 %    \end{macrocode}
@@ -253,11 +253,13 @@
 % \section{Setup and preamble commands}
 % \begin{macro}{\tagpdfsetup}
 %    \begin{macrocode}
+%<base>\NewDocumentCommand \tagpdfsetup { m }{}
 %<*package>
-\NewDocumentCommand \tagpdfsetup { m }
+\RenewDocumentCommand \tagpdfsetup { m }
   {
     \keys_set:nn { @@ / setup } { #1 }
   }
+%</package>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -265,15 +267,15 @@
 % \section{Commands for the mc-chunks}
 % \begin{macro}{\tagmcbegin,\tagmcend,\tagmcuse  }
 %    \begin{macrocode}
+%<*base>
 \NewDocumentCommand \tagmcbegin { m }
   {
-    \tag_mc_begin:n {#1}%\ignorespaces
+    \tag_mc_begin:n {#1}
   }
 
 
 \NewDocumentCommand \tagmcend {  }
   {
-    %\if_mode_horizontal: \unskip \fi: %
     \tag_mc_end:
   }
 
@@ -281,7 +283,7 @@
   {
     \tag_mc_use:n {#1}
   }
-
+%</base>
 %    \end{macrocode}
 % \end{macro}
 
@@ -290,10 +292,12 @@
 % 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 }
   }
+%</package>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -303,6 +307,7 @@
 % 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}
@@ -317,6 +322,7 @@
   {
     \tag_struct_use:n {#1}
   }
+%</base>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -327,6 +333,7 @@
 % 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}
@@ -559,6 +566,8 @@
 \bool_new:N \l_@@_para_show_bool
 \int_new:N  \g_@@_para_begin_int
 \int_new:N  \g_@@_para_end_int
+\tl_new:N   \l_@@_para_tag_tl
+\tl_set:Nn  \l_@@_para_tag_tl { P }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -576,6 +585,7 @@
   {
     paratagging      .bool_set:N = \l_@@_para_bool,
     paratagging-show .bool_set:N = \l_@@_para_show_bool,
+    paratag          .tl_set:N   = \l_@@_para_tag_tl
   }
 
 %    \end{macrocode}
@@ -587,13 +597,13 @@
    \bool_if:NT \l_@@_para_bool
      {
        \int_gincr:N \g_@@_para_begin_int
-       \tag_struct_begin:n {tag=P}
+       \tag_struct_begin:n {tag=\l_@@_para_tag_tl}
        \bool_if:NT \l_@@_para_show_bool
         { \tag_mc_begin:n{artifact}
           \llap{\color_select:n{red}\tiny\int_use:N\g_@@_para_begin_int\ }
           \tag_mc_end:
         }
-       \tag_mc_begin:n {tag=P}
+       \tag_mc_begin:n {tag=\l_@@_para_tag_tl}
      }
   }
 \AddToHook{para/end}
@@ -649,6 +659,7 @@
          }
      }
   }
+%</package>
 %    \end{macrocode}
 % \begin{macro}
 %   {
@@ -658,8 +669,11 @@
 %  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_@@_para_bool}
-\newcommand\tagpdfparaOff{\bool_set_false:N \l_@@_para_bool}
+%<base>\newcommand\tagpdfparaOn {}
+%<base>\newcommand\tagpdfparaOff{}
+%<*package>
+\renewcommand\tagpdfparaOn {\bool_set_true:N \l_@@_para_bool}
+\renewcommand\tagpdfparaOff{\bool_set_false:N \l_@@_para_bool}
 %    \end{macrocode}
 % \end{macro}
 %

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf.dtx	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf.dtx	2022-08-07 21:41:10 UTC (rev 64070)
@@ -33,12 +33,23 @@
 % \end{syntax}
 % \end{function}
 %
-% \begin{function}{ \tag_stop_group_begin:, \tag_stop_group_end:, \tag_stop: }
-% We need a command to stop tagging in some places.
-% This simply switches the two local booleans. The grouping commands
+% \begin{function}{ \tag_stop_group_begin:, \tag_stop_group_end:,
+%  \tag_stop:, \tag_start:, \tag_stop:n, \tag_start:n }
+% We need commands to stop tagging in some places.
+% There simply switches the two local booleans. The grouping commands
 % can be used to group the effect.
 % \end{function}
 %
+% \begin{function}{\tag_stop:n, \tag_start:n }%
+% \begin{syntax}
+% \cs{tag_stop:n}\Arg{label}
+% \cs{tag_start:n}\Arg{label}\\
+% \end{syntax}
+% This commands are intended as a pair. The start command
+% will only restart tagging if the previous stop command
+% with the same label actually stopped tagging.
+% \end{function}
+%
 % \begin{function}{activate-space (setup-key)}
 %  |activate-space| activates the additional parsing needed for
 %  interword spaces. It is not documented, the parsing is currently
@@ -81,7 +92,7 @@
 %    \begin{macrocode}
 %<@@=tag>
 %<*package>
-\ProvidesExplPackage {tagpdf} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf} {2022-08-06} {0.96}
   { A package to experiment with pdf tagging }
 
 \bool_if:nF
@@ -107,10 +118,10 @@
 %    \end{macrocode}
 %<*debug>
 %    \begin{macrocode}
-\ProvidesExplPackage {tagpdf-debug} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-debug} {2022-08-06} {0.96}
   { debug code for tagpdf }
 \@ifpackageloaded{tagpdf}{}{\PackageWarning{tagpdf-debug}{tagpdf~not~loaded,~quitting}\endinput}
-    \end{macrocode}
+%    \end{macrocode}
 %</debug>
 % We map the internal module name \enquote{tag} to \enquote{tagpdf} in messages.
 %    \begin{macrocode}
@@ -148,7 +159,7 @@
 %    \end{macrocode}
 %    \begin{macrocode}
 %<*base>
-\ProvidesExplPackage {tagpdf-base} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-base} {2022-08-06} {0.96}
   {part of tagpdf - provide base, no-op versions of the user commands }
 %</base>
 %    \end{macrocode}
@@ -171,6 +182,50 @@
 %    \end{macrocode}
 % \section{Temporary code}
 % This is code which will be removed when proper support exists in LaTeX
+% \subsection{Faster object writing}
+%
+%    \begin{macrocode}
+%<*package>
+\cs_if_free:NT \pdf_object_write_dict:nn
+ {
+   \cs_set_eq:NN \pdf_object_write_dict:nn \pdf_object_write:nn
+ }
+\cs_generate_variant:Nn \pdf_object_write_dict:nn {nx}
+
+\str_if_eq:VnT \c_sys_backend_str {pdftex}
+ {
+   \cs_if_free:NT \__pdf_backend_object_write_dict:nn
+    {
+      \cs_new_protected:Npn \__pdf_backend_object_write_dict:nn #1#2
+       {
+         \tex_immediate:D \tex_pdfobj:D
+         useobjnum ~
+         \int_use:c
+          { c__pdf_backend_object_ \tl_to_str:n {#1} _int }
+          { << ~ \exp_not:n {#2} ~ >> }
+      }
+     \cs_set_eq:NN \pdf_object_write_dict:nn \__pdf_backend_object_write_dict:nn
+    }
+ }
+
+\str_if_eq:VnT \c_sys_backend_str {luatex}
+ {
+   \cs_if_free:NT \__pdf_backend_object_write_dict:nn
+    {
+      \cs_new_protected:Npn \__pdf_backend_object_write_dict:nn #1#2
+        {
+          \tex_immediate:D \tex_pdfextension:D obj ~
+            useobjnum ~
+            \int_use:c
+            { c__pdf_backend_object_ \tl_to_str:n {#1} _int }
+            { << ~ \exp_not:n {#2} ~ >> }
+        }
+      \cs_set_eq:NN \pdf_object_write_dict:nn \__pdf_backend_object_write_dict:nn
+    }
+ }
+%</package>
+%    \end{macrocode}
+
 % \subsection{a LastPage label}
 % See also issue \#2 in Accessible-xref
 % \begin{macro}{\@@_lastpagelabel:}
@@ -225,6 +280,7 @@
 % \begin{variable}
 %  {
 %    \l_@@_tmpa_tl,
+%    \l_@@_tmpb_tl
 %    \l_@@_tmpa_str,
 %    \l_@@_tmpa_prop,
 %    \l_@@_tmpa_seq,
@@ -237,6 +293,7 @@
 % A few temporary variables
 %    \begin{macrocode}
 \tl_new:N    \l_@@_tmpa_tl
+\tl_new:N    \l_@@_tmpb_tl
 \str_new:N   \l_@@_tmpa_str
 \prop_new:N  \l_@@_tmpa_prop
 \seq_new:N   \l_@@_tmpa_seq
@@ -333,9 +390,11 @@
 \cs_generate_variant:Nn \pdffile_embed_stream:nnn {nxx,oxx}
 \cs_generate_variant:Nn \prop_gput:Nnn {Nxx,Nen}
 \cs_generate_variant:Nn \prop_put:Nnn  {Nxx}
+\cs_generate_variant:Nn \prop_item:Nn {No}
 \cs_generate_variant:Nn \ref_label:nn { nv }
 \cs_generate_variant:Nn \seq_set_split:Nnn{Nne}
 \cs_generate_variant:Nn \str_set_convert:Nnnn {Nonn, Noon, Nnon }
+\cs_generate_variant:Nn \clist_map_inline:nn {on}
 %    \end{macrocode}
 
 % \section{Setup label attributes}
@@ -444,10 +503,16 @@
 % \end{macro}
 %
 % \section{General tagging commands}
-
-% \begin{macro}{ \tag_stop_group_begin:, \tag_stop_group_end: }
-% We need a command to stop tagging in some places.
+%
+% \begin{macro}{\tag_stop_group_begin:,
+%   \tag_stop_group_end:,
+%   \tag_stop:,\tag_start:,
+%   \tag_stop:n,\tag_start:n}
+% We need commands to stop tagging in some places.
 % This simply switches the two local booleans.
+% In some cases tagging should only restart, if
+% it actually was stopped before. For this it is possible
+% to label a stop.
 %    \begin{macrocode}
 \cs_new_protected:Npn \tag_stop_group_begin:
   {
@@ -456,14 +521,49 @@
     \bool_set_false:N \l_@@_active_mc_bool
   }
 \cs_set_eq:NN \tag_stop_group_end: \group_end:
-\cs_new_protected:Npn \tag_stop:
+\cs_set_protected:Npn \tag_stop:
   {
     \bool_set_false:N \l_@@_active_struct_bool
     \bool_set_false:N \l_@@_active_mc_bool
   }
+\cs_set_protected:Npn \tag_start:
+  {
+    \bool_set_true:N \l_@@_active_struct_bool
+    \bool_set_true:N \l_@@_active_mc_bool
+  }
+\prop_new:N\g_@@_state_prop
+\cs_set_protected:Npn \tag_stop:n #1
+  {
+    \tag_if_active:TF
+      {
+        \bool_set_false:N \l_@@_active_struct_bool
+        \bool_set_false:N \l_@@_active_mc_bool
+        \prop_gput:Nnn \g_@@_state_prop { #1 }{ 1 }
+      }
+      {
+        \prop_gremove:Nn \g_@@_state_prop { #1 }
+      }
+  }
+\cs_set_protected:Npn \tag_start:n #1
+  {
+    \prop_gpop:NnN \g_@@_state_prop {#1}\l_@@_tmpa_tl
+     \quark_if_no_value:NF \l_@@_tmpa_tl
+      {
+        \bool_set_true:N \l_@@_active_struct_bool
+        \bool_set_true:N \l_@@_active_mc_bool
+      }
+  }
+%</package>
+%<*base>
+\cs_new_protected:Npn \tag_stop:{}
+\cs_new_protected:Npn \tag_start:{}
+\cs_new_protected:Npn \tag_stop:n{}
+\cs_new_protected:Npn \tag_start:n{}
+%</base>
 %    \end{macrocode}
 % \end{macro}
 %
+%
 % \section{Keys for tagpdfsetup}
 
 % TODO: the log-levels must be sorted
@@ -484,6 +584,7 @@
 %  perhaps move to some other place, now that it is better separated.
 %  |no-struct-dest| allows to suppress structure destinations.
 %    \begin{macrocode}
+%<*package>
 \keys_define:nn { @@ / setup }
   {
     activate-space  .bool_gset:N = \g_@@_active_space_bool,

Modified: trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf.ins	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/source/latex/tagpdf/tagpdf.ins	2022-08-07 21:41:10 UTC (rev 64070)
@@ -77,6 +77,7 @@
     \from{tagpdf-mc-shared.dtx}{base}
     \from{tagpdf-struct.dtx}{base}
     \from{tagpdf-checks.dtx}{base}
+    \from{tagpdf-user.dtx}{base}
    }
  }
 

Modified: trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-base.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-base.sty	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-base.sty	2022-08-07 21:41:10 UTC (rev 64070)
@@ -9,6 +9,7 @@
 %% tagpdf-mc-shared.dtx  (with options: `base')
 %% tagpdf-struct.dtx  (with options: `base')
 %% tagpdf-checks.dtx  (with options: `base')
+%% tagpdf-user.dtx  (with options: `base')
 %% 
 %% Copyright (C) 2019-2022 Ulrike Fischer
 %% 
@@ -23,7 +24,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: tagpdf.dtx
-\ProvidesExplPackage {tagpdf-base} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-base} {2022-08-06} {0.96}
   {part of tagpdf - provide base, no-op versions of the user commands }
 \AddToHook{begindocument}
  {
@@ -36,6 +37,12 @@
      \cs_new_protected:Npn \__tag_whatsits: {\tex_special:D {} }
    }
  }
+
+\cs_new_protected:Npn \tag_stop:{}
+\cs_new_protected:Npn \tag_start:{}
+\cs_new_protected:Npn \tag_stop:n{}
+\cs_new_protected:Npn \tag_start:n{}
+
 %% File: tagpdf-mc-generic.dtx
 \cs_new_protected:Npn \tag_mc_begin:n #1 { \__tag_whatsits: }
 \cs_new_protected:Nn \tag_mc_end:{ \__tag_whatsits: }
@@ -50,9 +57,11 @@
 %% File: tagpdf-struct.dtx
 \newcounter  { g__tag_struct_abs_int }
 \int_gzero:N \c at g__tag_struct_abs_int
+\tl_new:N  \g__tag_struct_stack_current_tl
+\tl_gset:Nn \g__tag_struct_stack_current_tl {\int_use:N\c at g__tag_struct_abs_int}
 \cs_new:Npn \__tag_get_data_struct_num:
   {
-    \int_use:N\c at g__tag_struct_abs_int
+    \g__tag_struct_stack_current_tl
   }
 \cs_new_protected:Npn \tag_struct_begin:n #1 {\int_gincr:N \c at g__tag_struct_abs_int}
 \cs_new_protected:Npn \tag_struct_end:{}
@@ -62,6 +71,42 @@
 \cs_new:Npn \tag_get:n #1   { \use:c {__tag_get_data_#1: } }
 \prg_new_conditional:Npnn \tag_if_active: { p , T , TF, F }
   { \prg_return_false: }
+%% File: tagpdf-user.dtx
+
+
+\NewDocumentCommand \tagpdfsetup { m }{}
+
+\NewDocumentCommand \tagmcbegin { m }
+  {
+    \tag_mc_begin:n {#1}
+  }
+
+\NewDocumentCommand \tagmcend {  }
+  {
+    \tag_mc_end:
+  }
+
+\NewDocumentCommand \tagmcuse { m }
+  {
+    \tag_mc_use:n {#1}
+  }
+
+\NewDocumentCommand \tagstructbegin { m }
+  {
+    \tag_struct_begin:n {#1}
+  }
+
+\NewDocumentCommand \tagstructend {  }
+  {
+   \tag_struct_end:
+  }
+
+\NewDocumentCommand \tagstructuse { m }
+  {
+    \tag_struct_use:n {#1}
+  }
+\newcommand\tagpdfparaOn {}
+\newcommand\tagpdfparaOff{}
 %% 
 %%
 %% End of file `tagpdf-base.sty'.

Modified: trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-debug-generic.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-debug-generic.sty	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-debug-generic.sty	2022-08-07 21:41:10 UTC (rev 64070)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: tagpdf-mc-generic.dtx
-\ProvidesExplPackage {tagpdf-debug-generic} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-debug-generic} {2022-08-06} {0.96}
  {part of tagpdf - debugging code related to marking chunks - generic mode}
 \cs_set_protected:Npn \tag_mc_begin:n #1 %#1 keyval
   {

Modified: trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-debug.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-debug.sty	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-debug.sty	2022-08-07 21:41:10 UTC (rev 64070)
@@ -26,12 +26,13 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: tagpdf.dtx
-\ProvidesExplPackage {tagpdf-debug} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-debug} {2022-08-06} {0.96}
   { debug code for tagpdf }
 \@ifpackageloaded{tagpdf}{}{\PackageWarning{tagpdf-debug}{tagpdf~not~loaded,~quitting}\endinput}
-    \end{macrocode}
 \prop_gput:Nnn \g_msg_module_type_prop { tag / debug} {}
 \prop_gput:Nnn \g_msg_module_name_prop { tag / debug }{tagpdf~DEBUG}
+
+
 \bool_if:NTF \g__tag_mode_lua_bool
   {
    \RequirePackage {tagpdf-debug-lua}
@@ -73,7 +74,7 @@
  }
 \msg_new:nnn { tag / debug } {struct-begin}
   {
-    Struct~begin~#1~with~options:~\tl_to_str:n{#2}~[\msg_line_context:]
+    Struct~\tag_get:n{struct_num}~begin~#1~with~options:~\tl_to_str:n{#2}~[\msg_line_context:]
   }
 \msg_new:nnn { tag / debug } {struct-end}
   {
@@ -113,6 +114,8 @@
 %% File: tagpdf-user.dtx
 
 
+
+
 %% File: tagpdf-mc-shared.dtx
 
 %% File: tagpdf-tree.dtx
@@ -135,6 +138,7 @@
           { g__tag_struct_\int_eval:n { \c at g__tag_struct_abs_int }_prop }
           { Type }
           { /StructElem }
+        \tl_set:Nn \l__tag_struct_stack_parent_tmpa_tl {-1}
         \keys_set:nn { __tag / struct} { #1 }
         \__tag_check_structure_has_tag:n { \int_eval:n {\c at g__tag_struct_abs_int} }
         \tl_if_empty:NF
@@ -142,13 +146,15 @@
           {
             \__tag_ref_label:en{tagpdfstruct-\l__tag_struct_key_label_tl}{struct}
           }
-        %get the potential parent from the stack:
-        \seq_get:NNF
-          \g__tag_struct_stack_seq
-          \l__tag_struct_stack_parent_tmpa_tl
+        \int_compare:nNnT { \l__tag_struct_stack_parent_tmpa_tl } = { -1 }
           {
-            \msg_error:nn { tag } { struct-faulty-nesting }
-          }
+            \seq_get:NNF
+              \g__tag_struct_stack_seq
+              \l__tag_struct_stack_parent_tmpa_tl
+              {
+                \msg_error:nn { tag } { struct-faulty-nesting }
+              }
+           }
         \seq_gpush:NV \g__tag_struct_stack_seq        \c at g__tag_struct_abs_int
         \seq_gpush:NV \g__tag_struct_tag_stack_seq    \g__tag_struct_tag_tl
         \tl_gset:NV   \g__tag_struct_stack_current_tl \c at g__tag_struct_abs_int

Modified: trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-luatex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-luatex.def	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-luatex.def	2022-08-07 21:41:10 UTC (rev 64070)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: tagpdf-backend.dtx
-\ProvidesExplFile {tagpdf-luatex.def} {2022-05-29} {0.95}
+\ProvidesExplFile {tagpdf-luatex.def} {2022-08-06} {0.96}
   {tagpdf~driver~for~luatex}
 {
   \fontencoding{TU}\fontfamily{lmr}\fontseries{m}\fontshape{n}\fontsize{10pt}{10pt}\selectfont

Modified: trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-mc-code-generic.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-mc-code-generic.sty	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-mc-code-generic.sty	2022-08-07 21:41:10 UTC (rev 64070)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: tagpdf-mc-generic.dtx
-\ProvidesExplPackage {tagpdf-mc-code-generic} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-mc-code-generic} {2022-08-06} {0.96}
  {part of tagpdf - code related to marking chunks - generic mode}
 \__tag_prop_new:N \g__tag_MCID_byabspage_prop
 
@@ -178,7 +178,7 @@
        \__tag_check_typeout_v:n {=>~ TME~ not~ missing}
      }
  }
-\cs_new:Npn\__tag_add_missing_mcs:Nn #1 #2 {
+\cs_new_protected:Npn\__tag_add_missing_mcs:Nn #1 #2 {
   \vbadness \@M
   \vfuzz    \c_max_dim
   \vbox_set_to_ht:Nnn #1 { \box_ht:N #1 } {
@@ -388,7 +388,7 @@
       {
         \tl_put_right:Nx \l__tag_mc_key_properties_tl { #1 }
       },
-    alttext .code:n      = % Alt property
+    alt .code:n      = % Alt property
       {
         \str_set_convert:Noon
           \l__tag_tmpa_str
@@ -398,6 +398,7 @@
         \tl_put_right:Nn \l__tag_mc_key_properties_tl { /Alt~< }
         \tl_put_right:No \l__tag_mc_key_properties_tl { \l__tag_tmpa_str>~ }
       },
+    alttext .meta:n = {alt=#1},
     actualtext .code:n      = % ActualText property
       {
         \str_set_convert:Noon

Modified: trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-mc-code-lua.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-mc-code-lua.sty	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf-mc-code-lua.sty	2022-08-07 21:41:10 UTC (rev 64070)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: tagpdf-mc-luacode.dtx
-\ProvidesExplPackage {tagpdf-mc-code-lua} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf-mc-code-lua} {2022-08-06} {0.96}
   {tagpdf - mc code only for the luamode }
 \hook_gput_code:nnn{begindocument}{tagpdf/mc}
   {
@@ -232,7 +232,7 @@
             ltx.__tag.func.store_mc_data(\__tag_get_mc_abs_cnt:,"raw","#1")
           }
       },
-    alttext .code:n      = % Alt property
+    alt .code:n      = % Alt property
       {
         \str_set_convert:Noon
           \l__tag_tmpa_str
@@ -249,6 +249,7 @@
               )
           }
       },
+    alttext .meta:n = {alt=#1},
     actualtext .code:n      = % Alt property
       {
         \str_set_convert:Noon

Modified: trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf.lua
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf.lua	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf.lua	2022-08-07 21:41:10 UTC (rev 64070)
@@ -24,8 +24,8 @@
 
 local ProvidesLuaModule = {
     name          = "tagpdf",
-    version       = "0.95",       --TAGVERSION
-    date          = "2022-05-29", --TAGDATE
+    version       = "0.96",       --TAGVERSION
+    date          = "2022-08-06", --TAGDATE
     description   = "tagpdf lua code",
     license       = "The LATEX Project Public License 1.3c"
 }

Modified: trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdf.sty	2022-08-07 21:41:10 UTC (rev 64070)
@@ -27,7 +27,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: tagpdf.dtx
-\ProvidesExplPackage {tagpdf} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdf} {2022-08-06} {0.96}
   { A package to experiment with pdf tagging }
 
 \bool_if:nF
@@ -57,6 +57,44 @@
 \ProcessOptions
 \RequirePackage{l3ref-tmp}
 \RequirePackage{tagpdf-base}
+\cs_if_free:NT \pdf_object_write_dict:nn
+ {
+   \cs_set_eq:NN \pdf_object_write_dict:nn \pdf_object_write:nn
+ }
+\cs_generate_variant:Nn \pdf_object_write_dict:nn {nx}
+
+\str_if_eq:VnT \c_sys_backend_str {pdftex}
+ {
+   \cs_if_free:NT \__pdf_backend_object_write_dict:nn
+    {
+      \cs_new_protected:Npn \__pdf_backend_object_write_dict:nn #1#2
+       {
+         \tex_immediate:D \tex_pdfobj:D
+         useobjnum ~
+         \int_use:c
+          { c__pdf_backend_object_ \tl_to_str:n {#1} _int }
+          { << ~ \exp_not:n {#2} ~ >> }
+      }
+     \cs_set_eq:NN \pdf_object_write_dict:nn \__pdf_backend_object_write_dict:nn
+    }
+ }
+
+\str_if_eq:VnT \c_sys_backend_str {luatex}
+ {
+   \cs_if_free:NT \__pdf_backend_object_write_dict:nn
+    {
+      \cs_new_protected:Npn \__pdf_backend_object_write_dict:nn #1#2
+        {
+          \tex_immediate:D \tex_pdfextension:D obj ~
+            useobjnum ~
+            \int_use:c
+            { c__pdf_backend_object_ \tl_to_str:n {#1} _int }
+            { << ~ \exp_not:n {#2} ~ >> }
+        }
+      \cs_set_eq:NN \pdf_object_write_dict:nn \__pdf_backend_object_write_dict:nn
+    }
+ }
+
  \cs_new_protected:Npn \__tag_lastpagelabel:
    {
      \legacy_if:nT { @filesw }
@@ -94,6 +132,7 @@
    }
 
 \tl_new:N    \l__tag_tmpa_tl
+\tl_new:N    \l__tag_tmpb_tl
 \str_new:N   \l__tag_tmpa_str
 \prop_new:N  \l__tag_tmpa_prop
 \seq_new:N   \l__tag_tmpa_seq
@@ -123,9 +162,11 @@
 \cs_generate_variant:Nn \pdffile_embed_stream:nnn {nxx,oxx}
 \cs_generate_variant:Nn \prop_gput:Nnn {Nxx,Nen}
 \cs_generate_variant:Nn \prop_put:Nnn  {Nxx}
+\cs_generate_variant:Nn \prop_item:Nn {No}
 \cs_generate_variant:Nn \ref_label:nn { nv }
 \cs_generate_variant:Nn \seq_set_split:Nnn{Nne}
 \cs_generate_variant:Nn \str_set_convert:Nnnn {Nonn, Noon, Nnon }
+\cs_generate_variant:Nn \clist_map_inline:nn {on}
 
 \ref_attribute_gset:nnnn { tagstruct } {0} { now }
   { \int_use:N \c at g__tag_struct_abs_int }
@@ -174,7 +215,6 @@
 \cs_generate_variant:Nn \__tag_seq_new:N    { c }
 \cs_generate_variant:Nn \__tag_seq_show:N   { c }
 \cs_generate_variant:Nn \__tag_prop_show:N  { c }
-
 \cs_new_protected:Npn \tag_stop_group_begin:
   {
     \group_begin:
@@ -182,11 +222,38 @@
     \bool_set_false:N \l__tag_active_mc_bool
   }
 \cs_set_eq:NN \tag_stop_group_end: \group_end:
-\cs_new_protected:Npn \tag_stop:
+\cs_set_protected:Npn \tag_stop:
   {
     \bool_set_false:N \l__tag_active_struct_bool
     \bool_set_false:N \l__tag_active_mc_bool
   }
+\cs_set_protected:Npn \tag_start:
+  {
+    \bool_set_true:N \l__tag_active_struct_bool
+    \bool_set_true:N \l__tag_active_mc_bool
+  }
+\prop_new:N\g__tag_state_prop
+\cs_set_protected:Npn \tag_stop:n #1
+  {
+    \tag_if_active:TF
+      {
+        \bool_set_false:N \l__tag_active_struct_bool
+        \bool_set_false:N \l__tag_active_mc_bool
+        \prop_gput:Nnn \g__tag_state_prop { #1 }{ 1 }
+      }
+      {
+        \prop_gremove:Nn \g__tag_state_prop { #1 }
+      }
+  }
+\cs_set_protected:Npn \tag_start:n #1
+  {
+    \prop_gpop:NnN \g__tag_state_prop {#1}\l__tag_tmpa_tl
+     \quark_if_no_value:NF \l__tag_tmpa_tl
+      {
+        \bool_set_true:N \l__tag_active_struct_bool
+        \bool_set_true:N \l__tag_active_mc_bool
+      }
+  }
 
 \keys_define:nn { __tag / setup }
   {
@@ -243,6 +310,8 @@
       {abscnt=\__tag_get_mc_abs_cnt:,~tag=\g__tag_mc_key_tag_tl}
       {no~MC~open,~current~abscnt=\__tag_get_mc_abs_cnt:"}
   }
+\msg_new:nnn { tag } {struct-unknown}
+   { structure~with~number~#1~doesn't~exist\\ #2 }
 \msg_new:nnn { tag } {struct-no-objnum} { objnum~missing~for~structure~#1 }
 \msg_new:nnn { tag }
   {struct-faulty-nesting}
@@ -630,6 +699,8 @@
       },
   }
 %% File: tagpdf.dtx
+
+
 \bool_if:NTF \g__tag_mode_lua_bool
   {
    \RequirePackage {tagpdf-mc-code-lua}
@@ -772,7 +843,7 @@
         \__tag_tree_fill_parenttree:
       }
     \tl_put_right:NV \l__tag_parenttree_content_tl\g__tag_parenttree_objr_tl
-    \pdf_object_write:nx  { __tag/tree/parenttree }
+    \pdf_object_write_dict:nx  { __tag/tree/parenttree }
       {
         /Nums\c_space_tl [\l__tag_parenttree_content_tl]
       }
@@ -780,7 +851,7 @@
 \pdf_object_new:nn { __tag/tree/rolemap }{ dict }
 \cs_new_protected:Npn \__tag_tree_write_rolemap:
   {
-    \pdf_object_write:nx  { __tag/tree/rolemap }
+    \pdf_object_write_dict:nx  { __tag/tree/rolemap }
       {
         \pdfdict_use:n{g__tag_role/RoleMap_dict}
       }
@@ -808,7 +879,7 @@
       \l__tag_tmpa_tl
       {
         \pdf_object_new:nn { __tag/tree/classmap }{ dict }
-        \pdf_object_write:nx
+        \pdf_object_write_dict:nx
           { __tag/tree/classmap }
           { \l__tag_tmpa_tl }
         \__tag_prop_gput:cnx
@@ -824,7 +895,7 @@
       {
         \pdfdict_if_empty:nF {g__tag_role/RoleMapNS_##1_dict}
           {
-            \pdf_object_write:nx {__tag/RoleMapNS/##1}
+            \pdf_object_write_dict:nx {__tag/RoleMapNS/##1}
               {
                 \pdfdict_use:n {g__tag_role/RoleMapNS_##1_dict}
               }
@@ -831,12 +902,12 @@
             \pdfdict_gput:nnx{g__tag_role/Namespace_##1_dict}
               {RoleMapNS}{\pdf_object_ref:n {__tag/RoleMapNS/##1}}
           }
-        \pdf_object_write:nx{tag/NS/##1}
+        \pdf_object_write_dict:nx{tag/NS/##1}
           {
              \pdfdict_use:n {g__tag_role/Namespace_##1_dict}
           }
       }
-    \pdf_object_write:nx {__tag/tree/namespaces}
+    \pdf_object_write:nx {__tag/tree/namespaces} %array
       {
         \prop_map_tokens:Nn \g__tag_role_NS_prop{\use_ii:nn}
       }
@@ -1372,7 +1443,6 @@
 \seq_gpush:Nn \g__tag_struct_stack_seq {0}
 \seq_new:N    \g__tag_struct_tag_stack_seq
 \seq_gpush:Nn \g__tag_struct_tag_stack_seq {Root}
-\tl_new:N     \g__tag_struct_stack_current_tl
 \tl_new:N     \l__tag_struct_stack_parent_tmpa_tl
 
 \seq_const_from_clist:Nn \c__tag_struct_StructTreeRoot_entries_seq
@@ -1588,11 +1658,20 @@
                { g__tag_struct_#1_prop }
                { ##1 }
                {
-                 \c_space_tl/##1~\prop_item:cn{ g__tag_struct_#1_prop } { ##1 }
+                 \c_space_tl/##1~
+                 \cs_if_exist_use:cTF {__tag_struct_format_##1:e}
+                   {
+                     { \prop_item:cn{ g__tag_struct_#1_prop } { ##1 } }
+                   }
+                   {
+                     \prop_item:cn{ g__tag_struct_#1_prop } { ##1 }
+                   }
                }
           }
       }
   }
+\cs_new:Nn\__tag_struct_format_Ref:n{[#1]}
+\cs_generate_variant:Nn\__tag_struct_format_Ref:n{e}
 \cs_new_protected:Npn \__tag_struct_write_obj:n #1 % #1 is the struct num
   {
     \pdf_object_if_exist:nTF { __tag/struct/#1 }
@@ -1600,7 +1679,7 @@
         \__tag_struct_fill_kid_key:n { #1 }
         \__tag_struct_get_dict_content:nN { #1 } \l__tag_tmpa_tl
         \exp_args:Nx
-          \pdf_object_write:nx
+          \pdf_object_write_dict:nx
             { __tag/struct/#1 }
             {
               \l__tag_tmpa_tl
@@ -1660,9 +1739,26 @@
   {
     label .tl_set:N      = \l__tag_struct_key_label_tl,
     stash .bool_set:N    = \l__tag_struct_elem_stash_bool,
+    parent .code:n       =
+      {
+        \bool_lazy_and:nnTF
+          {
+            \prop_if_exist_p:c { g__tag_struct_\int_eval:n {#1}_prop }
+          }
+          {
+            \int_compare_p:nNn {#1}<{\c at g__tag_struct_abs_int}
+          }
+          { \tl_set:Nx \l__tag_struct_stack_parent_tmpa_tl { \int_eval:n {#1} } }
+          {
+            \msg_warning:nnxx { tag } { struct-unknown }
+              { \int_eval:n {#1} }
+              { parent~key~ignored }
+          }
+      },
+    parent .default:n    = {-1},
     tag   .code:n        = % S property
       {
-        \seq_set_split:Nne \l__tag_tmpa_seq { / } {#1/\prop_item:Nn\g__tag_role_tags_NS_prop{#1}}
+        \seq_set_split:Nne \l__tag_tmpa_seq { / } {#1/\prop_item:No\g__tag_role_tags_NS_prop{#1}}
         \tl_gset:Nx \g__tag_struct_tag_tl    { \seq_item:Nn\l__tag_tmpa_seq {1} }
         \tl_gset:Nx \g__tag_struct_tag_NS_tl { \seq_item:Nn\l__tag_tmpa_seq {2} }
         \__tag_check_structure_tag:N \g__tag_struct_tag_tl
@@ -1702,7 +1798,7 @@
           { T }
           { <\l__tag_tmpa_str> }
       },
-    alttext .code:n      = % Alt property
+    alt .code:n      = % Alt property
       {
         \str_set_convert:Noon
           \l__tag_tmpa_str
@@ -1714,6 +1810,7 @@
           { Alt }
           { <\l__tag_tmpa_str> }
       },
+    alttext .meta:n = {alt=#1},
     actualtext .code:n  = % ActualText property
       {
         \str_set_convert:Noon
@@ -1733,18 +1830,15 @@
           { Lang }
           { (#1) }
       },
-    ref .code:n        = % Lang property
+    ref .code:n        = % ref property
       {
         \tl_clear:N\l__tag_tmpa_tl
-        \clist_map_inline:nn {#1}
+        \clist_map_inline:on {#1}
           {
             \tl_put_right:Nx \l__tag_tmpa_tl
               {~\ref_value:nn{tagpdfstruct-##1}{tagstructobj} }
           }
-        \__tag_prop_gput:cnx
-          { g__tag_struct_\int_eval:n {\c at g__tag_struct_abs_int}_prop }
-          { Ref }
-          { [\l__tag_tmpa_tl] }
+        \__tag_struct_gput_data_ref:ee { \int_eval:n {\c at g__tag_struct_abs_int} } {\l__tag_tmpa_tl}
       },
     E .code:n        = % E property
       {
@@ -1888,6 +1982,7 @@
           { g__tag_struct_\int_eval:n { \c at g__tag_struct_abs_int }_prop }
           { Type }
           { /StructElem }
+        \tl_set:Nn \l__tag_struct_stack_parent_tmpa_tl {-1}
         \keys_set:nn { __tag / struct} { #1 }
         \__tag_check_structure_has_tag:n { \int_eval:n {\c at g__tag_struct_abs_int} }
         \tl_if_empty:NF
@@ -1895,13 +1990,15 @@
           {
             \__tag_ref_label:en{tagpdfstruct-\l__tag_struct_key_label_tl}{struct}
           }
-        %get the potential parent from the stack:
-        \seq_get:NNF
-          \g__tag_struct_stack_seq
-          \l__tag_struct_stack_parent_tmpa_tl
+        \int_compare:nNnT { \l__tag_struct_stack_parent_tmpa_tl } = { -1 }
           {
-            \msg_error:nn { tag } { struct-faulty-nesting }
-          }
+            \seq_get:NNF
+              \g__tag_struct_stack_seq
+              \l__tag_struct_stack_parent_tmpa_tl
+              {
+                \msg_error:nn { tag } { struct-faulty-nesting }
+              }
+           }
         \seq_gpush:NV \g__tag_struct_stack_seq        \c at g__tag_struct_abs_int
         \seq_gpush:NV \g__tag_struct_tag_stack_seq    \g__tag_struct_tag_tl
         \tl_gset:NV   \g__tag_struct_stack_current_tl \c at g__tag_struct_abs_int
@@ -1980,6 +2077,34 @@
           }
       }
   }
+\cs_new:Npn \tag_struct_object_ref:n #1
+ {
+   \pdf_object_ref:n {__tag/struct/#1}
+ }
+\cs_generate_variant:Nn \tag_struct_object_ref:n {e}
+\cs_new_protected:Npn \tag_struct_gput:nnn #1 #2 #3
+ {
+   \cs_if_exist_use:cF {__tag_struct_gput_data_#2:nn}
+    { %warning??
+      \use_none:nn
+    }
+    {#1}{#3}
+ }
+\cs_generate_variant:Nn \tag_struct_gput:nnn {ene,nne}
+\cs_new_protected:Npn \__tag_struct_gput_data_ref:nn #1 #2
+   % #1 receiving struct num, #2 list of object ref
+   {
+     \prop_get:cnN
+        { g__tag_struct_#1_prop }
+        {Ref}
+        \l__tag_tmpb_tl
+     \__tag_prop_gput:cnx
+        { g__tag_struct_#1_prop }
+        { Ref }
+        { \quark_if_no_value:NF\l__tag_tmpb_tl { \l__tag_tmpb_tl\c_space_tl }#2 }
+    }
+\cs_generate_variant:Nn \__tag_struct_gput_data_ref:nn {ee}
+
 \cs_new_protected:Npn \tag_struct_insert_annot:nn #1 #2 %#1 should be an object reference
                                                         %#2 struct parent num
   {
@@ -2163,46 +2288,16 @@
 %% File: tagpdf-user.dtx
 
 
-\NewDocumentCommand \tagpdfsetup { m }
+\RenewDocumentCommand \tagpdfsetup { m }
   {
     \keys_set:nn { __tag / setup } { #1 }
   }
 
-\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}
-  }
-
-
 \NewDocumentCommand \tagmcifinTF { m m }
   {
     \tag_mc_if_in:TF { #1 } { #2 }
   }
-\NewDocumentCommand \tagstructbegin { m }
-  {
-    \tag_struct_begin:n {#1}
-  }
-
-\NewDocumentCommand \tagstructend {  }
-  {
-   \tag_struct_end:
-  }
-
-\NewDocumentCommand \tagstructuse { m }
-  {
-    \tag_struct_use:n {#1}
-  }
 \NewDocumentCommand\ShowTagging { m }
   {
     \keys_set:nn { __tag / show }{ #1}
@@ -2373,10 +2468,13 @@
 \bool_new:N \l__tag_para_show_bool
 \int_new:N  \g__tag_para_begin_int
 \int_new:N  \g__tag_para_end_int
+\tl_new:N   \l__tag_para_tag_tl
+\tl_set:Nn  \l__tag_para_tag_tl { P }
 \keys_define:nn { __tag / setup }
   {
     paratagging      .bool_set:N = \l__tag_para_bool,
     paratagging-show .bool_set:N = \l__tag_para_show_bool,
+    paratag          .tl_set:N   = \l__tag_para_tag_tl
   }
 
 \AddToHook{para/begin}
@@ -2384,13 +2482,13 @@
    \bool_if:NT \l__tag_para_bool
      {
        \int_gincr:N \g__tag_para_begin_int
-       \tag_struct_begin:n {tag=P}
+       \tag_struct_begin:n {tag=\l__tag_para_tag_tl}
        \bool_if:NT \l__tag_para_show_bool
         { \tag_mc_begin:n{artifact}
           \llap{\color_select:n{red}\tiny\int_use:N\g__tag_para_begin_int\ }
           \tag_mc_end:
         }
-       \tag_mc_begin:n {tag=P}
+       \tag_mc_begin:n {tag=\l__tag_para_tag_tl}
      }
   }
 \AddToHook{para/end}
@@ -2443,8 +2541,8 @@
          }
      }
   }
-\newcommand\tagpdfparaOn {\bool_set_true:N \l__tag_para_bool}
-\newcommand\tagpdfparaOff{\bool_set_false:N \l__tag_para_bool}
+\renewcommand\tagpdfparaOn {\bool_set_true:N \l__tag_para_bool}
+\renewcommand\tagpdfparaOff{\bool_set_false:N \l__tag_para_bool}
 \NewDocumentCommand\tagpdfsuppressmarks{m}
   {{\use:c{__tag_mc_disable_marks:} #1}}
 \cs_new_protected:Npn\__tag_hook_kernel_before_head:{}

Modified: trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdfdocu-patches.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdfdocu-patches.sty	2022-08-07 21:40:43 UTC (rev 64069)
+++ trunk/Master/texmf-dist/tex/latex/tagpdf/tagpdfdocu-patches.sty	2022-08-07 21:41:10 UTC (rev 64070)
@@ -1,5 +1,5 @@
 %\RequirePackage[enable-debug]{expl3}[2018/06/14]
-\ProvidesExplPackage {tagpdfdocu-patches} {2022-05-29} {0.95}
+\ProvidesExplPackage {tagpdfdocu-patches} {2022-08-06} {0.96}
  {patches/commands for the tagpdf documentation}
 \RequirePackage{etoolbox}
 



More information about the tex-live-commits mailing list.