% \iffalse meta-comment
%
%% File: documentmetadata-support.dtx
% Copyright (C) 2021-2026 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file
%
%    https://www.latex-project.org/lppl.txt
%
%
% The development version of the bundle can be found below
%
%    https://github.com/latex3/latex2e
%
% for those people who are interested or want to report an issue.
%
%    \begin{macrocode}
\def\documentmetadatasupportversion{1.1d}
\def\documentmetadatasupportdate{2026-06-15}
%    \end{macrocode}
%
%
%<*driver>
\DocumentMetadata{tagging=on,pdfstandard=ua-2}
\documentclass[kernel]{l3in2edoc}

\EnableCrossrefs
\CodelineIndex
\begin{document}
  \DocInput{documentmetadata-support.dtx}
\end{document}
%</driver>
%
% \fi
%
%
%\NewDocElement[macrolike = false ,
%		 toplevel  = true,
%                idxtype   =  key  ,
%                noprint   = true  ,
%                idxgroup  = metadata keys ,
%                printtype = \textit{key}
%               ]{Mkey}{mkey}
%
%
% \title{The \texttt{documentmetadata-support} code\thanks{This file
%      has version \documentmetadatasupportversion\ dated
%      \documentmetadatasupportdate,  \copyright\ \LaTeX\
%    Project.}}
% \author{Frank Mittelbach, Ulrike Fischer, \LaTeX{} Project}
%
% \maketitle
%
%
% \section{Introduction}
%
%    The kernel command \cs{DocumentMetadata}, which can be used as
%    the very first declaration in a document (i.e., before
%    \cs{documentclass}), defines metadata and other configuration
%    data that applies to the document as a whole (using a key/value
%    syntax). It loads and activates
%    the PDF management code from the \pkg{pdfmanagement} package and loads
%    and activated code currently stored in latex-lab modules
%    needed for various features developed as part of the multi-year ``Tagged PDF''
%    project.~\cite{blueprint}
%
%    While the underlying functionality is still under
%    development (e.g., further keys will be added over time and keys
%    marked temporary may vanish again) the code for
%    \cs{DocumentMetadata} is placed in a separate bundle, so that it
%    is easier to update it without the need to build a full \LaTeX{}
%    release. Over time the functionality will move fully into the
%    kernel.
%
%    As the loading of the PDF management forces the loading of the \pkg{l3backend} files,
%    a backend that can't be detected automatically like |dvipdfmx|,
%    must be set in the first \cs{DocumentMetadata}.
%
%    From a process perspective \cs{DocumentMetadata} loads the
%    \pkg{pdfmanagement} code and the latex-lab modules
%    the first time it is called and then
%    redefines itself to error if
%    called more than once. In particular, this means that a document
%    without a \cs{DocumentMetadata} declaration has no code available
%    for extended management of PDF output and for tagging support.
%
% \section{The \cs{DocumentMetadata} command}
%
% \begin{function}{\DocumentMetadata}
% \begin{syntax}
% \cs{DocumentMetadata}\Arg{key-value list}
% \end{syntax}
%
% The command should be used as the first command in a document, before
% \cs{documentclass}. It takes a key-value argument.
% \end{function}
%
% Starting with the release 2025-11-01 \cs{DocumentMetadata} will always load
% the new modules which changes \LaTeX{} internals and add tagging support code.
%
% For documents that want to load the PDF management but do not want the new tagging support
% code we provide a dedicated package. Such documents should replace
% \begin{verbatim}
% \DocumentMetadata{pdfversion=1.7,
%   pdfstandard=a-3b}
% \end{verbatim}
% by
% \begin{verbatim}
% \RequirePackage{pdfmanagement}
% \SetKeys[document/metadata]{pdfversion=1.7,
%  pdfstandard=a-3b}
% \end{verbatim}
%
% Currently the modules loaded by \cs{DocumentMetadata} are the following.
% Details and documentation can be found in the various \texttt{latex-lab-\meta{module}.pdf}:
%
%   \begin{description}
%    \item[\texttt{names}] This module declares tag names for the structures.
%    \item[\texttt{new-or-2}] This module changes output routine sockets and adds support
%    for the paragraph tagging. It also loads the new footnote code.
%    \item[\texttt{block}] This module reimplements lists and blocks environments and
%    adds tagging support.
%    \item[\texttt{context}] This module provides context for template instances and code that needs
%    to know where and when it is executed.
%    \item[\texttt{sec},\texttt{sec-template}] These modules reimplement heading commands
%    and make them tagging aware.
%    \item[\texttt{toc}] This module adapts commands related to the table of contents and
%    similar list to make them tagging aware.
%    \item[\texttt{minipage}] This module adds tagging support to \texttt{minipage}
%    and \cs{parbox}.%
%    \item[\texttt{graphic}] This module enables tagging support for
%    the \cs{includegraphics} command and the \texttt{picture} environment.
%    \item[\texttt{float}] This module adds tagging support to floats.
%    \item[\texttt{bib}] This module adds tagging support to citations and bibliographies.
%    \item[\texttt{text}] This module adds tagging support to small text commands like
%    the \LaTeX{} logo, the \cs{emph} command and super and sub scripts.
%    \item[\texttt{marginpar}] This module adds tagging support to the \cs{marginpar}
%    command.
%    \item[\texttt{title}] This module adds tagging support to the \cs{maketitle}
%    command if a standard class is used. It also enhances the \cs{title}
%    and \cs{author} commands to fill the XMP-metadata and set the window title.
%    It is not compatible with packages and classes which redefine these commands
%    too.
%    \item[\texttt{table}] This module provides tagging for
%    \texttt{tabular}, \texttt{longtable} and similar table environments.
%    Its use and restrictions are documented in \texttt{latex-lab-table.pdf}.
%    \item[\texttt{math}] This module adapts math for tagging.
%    \item[\texttt{firstaid}] This module contains small adjustments to external packages.
%    \item[\texttt{tikz}] This module adds support for the \pkg{tikz} package.
%    \end{description}
%
%
% \section{Keys and values}
%
% Currently the following keys are implemented for \cs{DocumentMetadata}:
% \DescribeMkey{backend}
% \DescribeMkey{pdfversion}
% \DescribeMkey{uncompress}
% \DescribeMkey{language}
% \DescribeMkey{other-languages}
% \DescribeMkey{lang}
% \DescribeMkey{pdfstandard}
% \DescribeMkey{xmp}
% \DescribeMkey{colorprofiles}
% \DescribeMkey{tagging}
% \DescribeMkey{tagging-setup}
% \DescribeMkey{check-tagging-status}
% \DescribeMkey{testphase}
% \DescribeMkey{debug}
%
% \begin{description}
%    \item[\texttt{backend}] Passes the backend name to expl3. This is
%      needed only if the correct backend can't be automatically
%      determined or if the workflow requires a special backend.
%
%^^A    This will probably be extended to  pass the value also to
%^^A      packages.
%
%    \item[\texttt{pdfversion}] Sets the PDF version explicitly, e.g., \texttt{pdfversion=1.7}.
%    The key definition is in the pdfmanagement in l3pdfmeta.
%
%    \item[\texttt{uncompress}] (no value) Forces an uncompressed pdf
%      --- mainly for debugging purposes. Do not unnecessarily set it in normal production
%      because it increases the size of the final PDF considerably.
%
%    \item[\texttt{language}]
%    The language key should be used to set the main language of the
%    document. The value is given in BCP~47 format,
%    so, e.g, \texttt{languade=de-DE} or \texttt{language=fr}.
%    The value is stored in the document properties and can be retrieved (expandably) with
%    \verb+\GetDocumentProperty{document/language}+.
%
%    The key does \emph{not} change the language setup of a document: it doesn't change the
%    hyphenation patterns or the fix names or forces the loading of a language package.
%    The expectation is that packages that need to know the document language, like \pkg{babel} or
%    \pkg{polyglossia}, read the value and react accordingly.
%    The BCP~47 value,e.g., can be parsed with \cs{text_bcp_parse:n} which produces
%    7 brace groups, see interface3.
%    To extract, for example, the main language in the first group this code could be used:
%    \begin{verbatim}
%    \cs_generate_variant:Nn\text_bcp_parse:n{e}
%    \tl_if_empty:eTF { \GetDocumentProperty{document/language} }
%     {
%       % other code to set the main language
%     }
%     {
%       \tl_set:Ne\mainlanguage
%        {\exp_last_unbraced:Ne\use_i:nnnnnnn
%        {\text_bcp_parse:e{\GetDocumentProperty{document/language}}}}
%     }
%    \end{verbatim}
%    Note that \cs{text_bcp_parse:e} will error if the argument is empty
%    so it is necessary to test this case.
%
%    The key updates the default \cs{BCPdata} command to use with the give language value.
%    Note that this can lead to empty fields for region or script, if, e.g., only
%    \texttt{language=de} instead of \texttt{language=de-Latn-AT} is used.
%    This is only relevant if neither \pkg{babel} nor \pkg{polyglossia}
%    are used as both packages overwrite the \cs{BCPdata} command with their own version.
%
%    The value of the \texttt{language} key is also used to set the \texttt{/Lang} key in the PDF.
%    If a different (shorter) value is wanted there, an optional argument can be used:
%    \verb+language=[de]{de-DE}+, or the \texttt{lang} key can be
%     used to overwrite the value: \verb+language=de-DE,lang=de+.
%
%     \item[\texttt{otherlanguage}]
%     The \texttt{other-languages} key can be used to declare more languages that are used
%     in the document. The argument is a comma list of languages in BCP~47 format:
%     \verb+other-languages={fr,en-US,ar}+.
%     The comma list is stored in the document properties and can be retrieved
%     (expandably) with \verb+\GetDocumentProperty{document/other-languages}+.
%     As with the \texttt{language} key the expectation is, that language packages
%     read the value and react accordingly.
%
%    \item[\texttt{lang}] Explicitly sets the Lang entry in the Catalog,
%     e.g., \texttt{lang=de-DE}. If not given, the value of \verb+\BCPdata{language}+
%     or \verb+ \BCPdata{main.language}+ at the beginning of the document is used (these
%     commands are set by \pkg{babel}, the default value is |en-US|).
%     The key is implicitly set if the \texttt{language} key is used.
%
%    \item[\texttt{pdfstandard}] Choice key to set the pdf standard.
%      Currently |A-1b|, |A-2a|, |A-2b|, |A-2u|, |A-3a|, |A-3b|, |A-3u|, |A-4|, |A-4E|
%      and |A-4F| are accepted as A-standard.
%      values. The casing is irrelevant, |a-1b| works too.
%      Note that using this
%      key doesn't mean that the document actually follows the standard. \LaTeX{}
%      can neither ensure nor check all requirements of a standard, and not everything
%      it can do theoretically has already been implemented.
%      When setting an A-standard a color profile is included and the
%      \texttt{/OutputIntent} is set and any javascript action in hyperref are suppressed.
%      The |u| variants do not enforce unicode,
%      but they will pass the information to hyperref. The |a| variants
%      do \emph{not} enforce (or even test) a tagged pdf yet.
%
%      Beside the A-standards it is also possible to use the values
%      |X-4|, |X-4p|, |X-5g|, |X-5n|, |X-5pg|, |X-6|, |X-6n|, |X-6p| for
%      a PDF/X and |UA-1|  and |UA-2| for PDF/UA standard.
%      |UA-2| should only be used together with PDF 2.0.
%      Currently these keys set \emph{only} the relevant XMP-metadata.
%      They do not validate or enforce special requirements
%      (e.g., the |UA| standards do not automatically activate tagging).
%
%      |pdfstandard| can be used more than once to set overlapping standards, e.g:\\
%      |pdfstandard=A-2b,pdfstandard=X-4,pdfstandard=UA-1|. It is also possible
%      to pass a list like |pdfstandard={UA-2,A-4F}|.
%
%      If XMP-metadata are added (see the following key \texttt{xmp})
%      the necessary conformance markers for the standards are set.
%
%      Standards can require some minimal or maximal PDF version and the keys will try to
%      adjust the PDF version as necessary. At the beginning of the document the versions are checked
%      again a warning is issued if PDF version and standard conflicts.
%
%      The key is defined in the pdfmanagement in \pkg{l3pdfmeta} and more
%      information can be found in the documentation.
%
%    \item[\texttt{xmp}] A boolean, if set to false no XMP metadata are added to the PDF.
%    The initial value is true. Details are described in the documentation of \pkg{l3pdfmeta}.
%
%    \item[\texttt{colorprofiles}] This allows to load icc-colorprofiles. Details
%       are described in the documentation of \pkg{l3pdfmeta}.
%
%    \item[\texttt{tagging}] This key allows to activate, deactivate or partially deactivate the tagging support.
%    It accepts the three values \texttt{on}, \texttt{off} and \texttt{draft}.
%    The tagpdf package and all standard modules of the tagging support are loaded regardless of the use and the
%    value of the key!
%    \begin{itemize}
%    \item |tagging=on| activates tagging.
%    \item |tagging=off| deactivates in the \texttt{class/before} hook the tagging commands,
%    including the \cs{tagpdfsetup} command. It also deactivates the use of real space chars.
%    This can be reactivated by using |tagging-setup={activate/spaces}|.
%    \item |tagging=draft| leaves the
%    tagging commands active  but it deactivates the writing of the structure tree
%    at the end of the compilation. This can save
%    time when drafting a longer document but preserves, e.g., MC-content marker
%    in the PDF stream and warnings and errors from \pkg{tagpdf} if the structure is faulty.
%    \end{itemize}
%
%    \item[\texttt{tagging-setup}] This key allows to configure the tagging. It accepts all
%    keys that can also be used in \cs{tagpdfsetup}; see the \pkg{tagpdf} documentation.
%    Additionally, it accepts two keys to extend the list of modules loaded:
%     \begin{description}
%        \item[\texttt{modules}] This key previously allowed to change the
%        list of modules. Starting with the release 2025-11-01 all standard modules
%        are loaded always, so its only use is to load a non-standard module, e.g.
%        |modules=verbatim-af| will load an experimental module changing the verbatim tagging.
%
%        \item[\texttt{extra-modules}] This key allows to load non-standard modules and
%        starting with the release 2025-11-01 it is an alias of |modules|.
%      \end{description}
%
%    \item[\texttt{check-tagging-status}] This key is provided to help to
%    identify packages that are potentially problematic when used with the tagging code.
%    When used (with no value or with the value |listfiles|,
%    it reads the file |latex-tagging-status.ltx|
%    from the \pkg{latex-tagging-status} package and then writes at the end of the compilation
%    a report about the compatibility of the class and the packages with the tagging project.
%    It follows the classification done at \url{https://latex3.github.io/tagging-project/tagging-status}.
%
%    This is only a rough overview and a debugging aid, not a final report!
%    Using packages that are classified as incompatible or partially incompatible
%    does not mean that the tagging is necessarily broken. For example, \pkg{hyperref}
%    is partially incompatible as the form fields are not properly tagged (this requires the use
%    of the \pkg{l3pdffield} package), but in documents without form fields it is unproblematic.
%    (In case of partially-compatible or incompatible packages check the table at
%    \url{https://latex3.github.io/tagging-project/tagging-status} as it often contains
%    an explanation what is not yet working.)
%
%    The package \pkg{latex-tagging-status} will be regularly updated to reflect changes
%    in package. Erroneous messages should be reported
%    at \url{https://github.com/latex3/tagging-project/issues}. It is also possible
%    to create a pull request which updates the data.
%
%    \item[\texttt{testphase}] This key loaded in older \LaTeX{} versions
%    specific sets of modules from the testphase code.
%    Starting with the release 2025-11-01 all standard modules are
%    loaded automatically by \cs{DocumentMetadata} and with this change the key
%    lost most of its original purpose.
%    The values \texttt{phase-I}, \texttt{phase-II}, \texttt{phase=III} of the
%    \texttt{testphase} key will no longer load different code variants but only
%    activate tagging. The key can still be used to load additional experimental modules,
%    it then works similar to the \texttt{modules} and \texttt{extra-modules} key and does
%    not automatically activate tagging.
%
%    \item[\texttt{debug}] This key activates some debug options. It takes a list of key-values
%    as value. Currently the following keys are known:
%     \begin{description}
%     \item[\texttt{para}] with the default and only value |show|. It will activate the |debug/show=para|
%       option of \pkg{tagpdf};
%     \item[\texttt{log}]  with the values as described in the documentation of \pkg{tagpdf};
%     \item[\texttt{uncompress}] which does the same as |uncompress| as main key;
%     \item[\texttt{pdfmanagement}] a boolean which allows to deactivate the pdfmanagement (deprecated);
%     \item[\texttt{firstaidoff}] this accepts a comma lists of keywords and disables the patches
%       related to them. More information can be found in the documentation of
%       \pkg{pdfmanagement-firstaid};
%     \item[\texttt{xmp-export}] this will export the XMP-metadata to a file \verb+\jobname.xmpi+.
%     With \texttt{debug=\{xmp-export=filename\}} the file name can be changed;
%     More information can be found in the documentation of \pkg{l3pdfmeta} of the \pkg{pdfmanagement-testphase}
%     bundle;
%     \item[\texttt{tagpdf}] This loads the package tagpdf-debug which enhances
%     various commands from tagpdf with additional debugging options. This can slow down
%     the compilation!
%     \item[\texttt{BBox}] This helps to debug BBox values of graphics, see the documentation
%     of latex-lab-graphic.
%    \end{description}
% \end{description}
%
% \bibliographystyle{plain}
%
% \begin{thebibliography}{9}
%
% \bibitem{blueprint} Frank Mittelbach and Chris Rowley:
%   \emph{\LaTeX{} Tagged PDF\,---\,A blueprint for a large project}.
%   \url{https://latex-project.org/publications/indexbyyear/2020/}
%
% \end{thebibliography}
%
%
%
% \MaybeStop{\setlength\IndexMin{200pt}  \PrintIndex  }
%
% \begin{implementation}
%
% \section{The Implementation}
%
%
%    \begin{macrocode}
%<@@=pdfmanagement>
%<*code>
%    \end{macrocode}
%
%    \begin{macrocode}

\RequirePackage{pdfmanagement-init}
%    \end{macrocode}
%
%    \begin{macrocode}
\ExplSyntaxOn\makeatletter
%    \end{macrocode}

% \subsection{Variables}
% These variable definitions are currently also done in ltdocinit.
% They can be removed from there once latex-lab has been updated to
% provide them too.
%  \begin{variable}{\g_@@_firstaidoff_clist}
%  A list to store the firstaid code which should be disabled
%    \begin{macrocode}
\clist_if_exist:NF \g_@@_firstaidoff_clist
  { \clist_new:N \g_@@_firstaidoff_clist }
%    \end{macrocode}
%  \end{variable}
%  \begin{variable}{\g_@@_testphase_tl}
%  a tl to store the testphase loading code so that we can load them at
%  the end of the command.
%    \begin{macrocode}
\tl_if_exist:NF \g_@@_testphase_tl
 { \tl_new:N \g_@@_testphase_tl }
%    \end{macrocode}
% \end{variable}
%
% \subsection{Kernel changes with \cs{DocumentMetadata}}
% \begin{macro}{\@kernel@before@DocumentMetadata}
%    \begin{macrocode}
\cs_new_protected:Npn \@kernel@before@DocumentMetadata
  {
    \ifx\Umathcode\@undefined
    \fontencoding{T1}
    \renewcommand\encodingdefault{T1}
    \fi
  }
%    \end{macrocode}
% \end{macro}

% \subsection{\cs{DocumentMetadata}}
%
%  \begin{macro}{\DocumentMetadata}
%
%    \cs{DocumentMetadata} should not be used after
%    \cs{documentclass} so we error in this case.
%    It can be used more than once
%     but follow-up calls should not do the initialization code.
%    \begin{macrocode}
\cs_set_protected:Npn \DocumentMetadata #1
  {
    \cs_if_eq:NNTF \documentclass \@twoclasseserror
      { \msg_error:nn { meta } { after-class } }
      {
%    \end{macrocode}
% Load general format changes
%    \begin{macrocode}
        \@kernel@before@DocumentMetadata
%    \end{macrocode}
%
%    The wanted backend must be detected first, we read the init
%    key and then force the loading of the backend.
%    The backend can contain management commands, so the boolean should
%    be set to true first.
%    \begin{macrocode}
        \bool_gset_true:N \g_@@_active_bool
        \keys_set_groups:nnn { document / metadata} {init}{ #1 }
        %if no backend has been loaded force it now:
        \str_if_exist:NF \c_sys_backend_str
          {
            \sys_load_backend:n {}
          }
%    \end{macrocode}
%    Now we load the extra backend code:
%    \begin{macrocode}
        \ExplSyntaxOn\makeatletter
          \file_input:n {l3backend-testphase-\c_sys_backend_str.def}
        \ExplSyntaxOff\makeatother
%    \end{macrocode}
% \changes{v1.0m}{2025/02/17}{Set PDF 2.0 as default}
%    \begin{macrocode}
          \pdf_version_gset:n { 2.0 }
%    \end{macrocode}
% tagpdf currently requires that the pdf version is set first.
%    \begin{macrocode}
          \keys_set_groups:nnn { document / metadata} {pdf}{ #1 }
%    \end{macrocode}
% Load the latex-lab modules:
% \changes{v1.0s}{2025/07/07}{Load latest set always.}
%    \begin{macrocode}
          \RequirePackage{latex-lab-testphase-latest}
          \AddToDocumentProperties [document]{tagging}{inactive}
          \AddToDocumentProperties [document]{tagging/para}{inactive}
%    \end{macrocode}
%    Process the non-init keys.
% \changes{v1.0s}{2025/07/07}{hyperref loads the generic driver itself}
% \changes{v1.0s}{2025/07/07}{pdf management is always active, so test removed}
%    \begin{macrocode}
        \keys_set_exclude_groups:nnn  { document / metadata } { init,pdf } { #1 }
%    \end{macrocode}
% Finally we set up the language default.
% If the \texttt{language} key hasn't been set yet, we set it
% to the value of the \texttt{lang} key and so to empty if this key hasn't be set either.
% This way a language package like \pkg{babel} can correctly react to the situation
% that neither language nor lang has been explicitly set.
% % \changes{v1.1d}{2026-06-15}{Leave language default empty if not set}
%    \begin{macrocode}
        \tl_if_empty:eTF{\GetDocumentProperty{document/language}}
         {
           \tl_set:Ne\l_@@_tmpa_tl{\GetDocumentProperty{document/lang}}
           \tl_if_empty:NF\l_@@_tmpa_tl
            {
             \keys_set:ne{document/metadata}{language=\l_@@_tmpa_tl}
             \@@_update_BCPdata:
            }
         }
         {
           \@@_update_BCPdata:
         }
%    \end{macrocode}
% At last we set up the lang default.
% This is done after the begindocument hook so that it can pick up settings
% from babel. If the Catalog dictionary already contains a lang value we do nothing,
% otherwise we use the value stored in \cs{BCPdata}, either the main language
% (if its exists) or the fall back language.
% Note: if babel is loaded without a language this gives the language \texttt{und}.
% \changes{v1.0x}{2025/12/15}{Remove warning, issue tagging/1115}
%    \begin{macrocode}
        \g@addto@macro\@kernel@after@begindocument
         {
           \pdfdict_get:nnN {g__pdf_Core/Catalog}{Lang}\l_@@_tmpa_tl
           \quark_if_no_value:NT\l_@@_tmpa_tl
            {
              \tl_if_empty:eTF { \BCPdata{main.language} }
               { \tl_set:Ne \l_@@_tmpb_tl { \BCPdata{language} } }
               { \tl_set:Ne \l_@@_tmpb_tl { \BCPdata{main.language} } }
              \exp_last_unbraced:Ne
               \AddToDocumentProperties{[document]{lang}{\l_@@_tmpb_tl}}
              \pdfmanagement_add:nne {Catalog} {Lang}{(\l_@@_tmpb_tl)}
            }
         }
%    \end{macrocode}
%    \cs{pdfmanagement_add:nnn} has collected values in this hook.
%    \begin{macrocode}
        \hook_use_once:n {pdfmanagement/add}
%    \end{macrocode}
%    Now we redefine \cs{DocumentMetadata} so that it errors on future calls
% \changes{1.0z}{2026-04-22}{Error if two \cs{DocumentMetadata} declarations are used.}
%    \begin{macrocode}
        \cs_set_protected:Npn \DocumentMetadata ##1
          {
            \@latex@error
              {Two~\noexpand\DocumentMetadata~declarations}%
              {The~document~may~use~only~one~\noexpand\DocumentMetadata~declaration.}
          }
%    \end{macrocode}
% Load more modules, the testphase code and the firstaid code.
%    \begin{macrocode}
        \g_@@_testphase_tl
        \RequirePackage{pdfmanagement-firstaid}
      }
  }
%    \end{macrocode}
%  \end{macro}

% \subsection{Tagging status report}
% Hide our own files
%    \begin{macrocode}
\clist_map_inline:nn
 {
   pdfmanagement-init.sty,
   color-ltx.sty,
   xcolor-patches-tmp-ltx.sty,
   tagpdf-base.sty,
   latex-lab-testphase-latest.sty,
   tagpdf.sty,
   tagpdf-mc-code-generic.sty,
   tagpdf-mc-code-lua.sty,
   luamml-patches-kernel.sty,
   luamml-patches-amsmath.sty,
   latex-lab-enumitem.sty,
   latex-lab-kernel-changes.sty,
   latex-lab-testphase-names.sty,
   latex-lab-testphase-new-or-2.sty,
   latex-lab-testphase-block.sty,
   latex-lab-testphase-context.sty,
   latex-lab-testphase-sec.sty,
   latex-lab-testphase-sec-template.sty,
   latex-lab-testphase-toc.sty,
   latex-lab-testphase-minipage.sty,
   latex-lab-testphase-graphic.sty,
   latex-lab-testphase-float.sty,
   latex-lab-testphase-bib.sty,
   latex-lab-testphase-text.sty,
   latex-lab-testphase-marginpar.sty,
   latex-lab-testphase-title.sty,
   latex-lab-testphase-table.sty,
   latex-lab-testphase-math.sty,
   latex-lab-testphase-firstaid.sty,
   latex-lab-testphase-tikz.sty,
   pdfmanagement-firstaid.sty,
    }
 {\expandafter\chardef\csname t@status@#1\endcsname8\relax }
%    \end{macrocode}
%    \begin{macrocode}
\tl_new:c {l__tag_status_0_tl}
\tl_new:c {l__tag_status_1_tl}
\tl_new:c {l__tag_status_2_tl}
\tl_new:c {l__tag_status_3_tl}
\tl_new:c {l__tag_status_4_tl}
\tl_new:c {l__tag_status_-1_tl}
\cs_new_protected:Npn\__tag_status_sort:
 {
   \clist_map_inline:Nn\g__tag_status_filelist_tl
     {
       \filename@parse{##1}
       \cs_if_exist:cTF { t@status@##1 }
         {
          \str_if_eq:onF{\filename@ext}{cls}
           {
            \tl_put_right:cn
              {l__tag_status_\int_use:c { t@status@##1 }_tl}
              {~~##1\iow_newline:}
           }
         }
         {
          \str_if_eq:onT{\filename@ext}{sty}
           {
             \tl_put_right:cn
               {l__tag_status_-1_tl}
               {~~##1\iow_newline:}
           }
         }
     }
 }
\cs_new_protected:Npn \__tag_status_type:nn #1 #2
% #1 number, -1 for not listed, #2 title
 {
   \iow_term:n{~~#2}
   \iow_term:n{~~--------------------------}
   \tl_if_empty:cTF{l__tag_status_#1_tl}
    {
      \iow_term:e{~~NONE\iow_newline:}
    }
    {
      \iow_term:e{\tl_use:c{l__tag_status_#1_tl}}
    }
 }
\cs_new_protected:Npn \__tag_status_log:
 {
   \file_if_exist_input:n {latex-tagging-status.ltx}
   \AddToHookNext{class/before}
     {
       \tl_const:Ne \c__tag_current_class_tl{\@currname.\@currext}
       \tl_const:Ne \c__tag_status_class_tl
        {
          \cs_if_exist:cTF { t@status@\@currname.\@currext }
           {
             \int_case:nn { \int_use:c { t@status@\@currname.\@currext } }
              {
                {0}{unknown}
                {1}{unsupported}
                {2}{currently~incompatible}
                {3}{partially~compatible}
                {4}{compatible}
              }
           }
           { not~in~the~status~list}
        }
     }
   \AddToHook{begindocument}{\tl_gset_eq:NN \g__tag_status_filelist_tl\@filelist}
   \AddToHook{enddocument/info}
     {
      \iow_term:n{}
      \iow_term:n
       {======================================}
      \iow_term:n{~~Status~report~of~the~tagging~support}
      \iow_term:n{======================================}
      \iow_term:n{~~Details~at~https://latex3.github.io/tagging-project/tagging-status}
      \iow_term:n{~~Report~erroneous~entries~at~https://github.com/latex3/tagging-project}
      \iow_term:n{}
      \iow_term:n{~~A.~CLASS}
      \iow_term:n{~~********}
      \iow_term:n{}
      \iow_term:e{~~\c__tag_current_class_tl\c_space_tl is~\c__tag_status_class_tl}
      \iow_term:n{}
      \iow_term:n{~~B.~PACKAGES,~LIBRARIES,~etc}
      \iow_term:n{~~***********}
      \iow_term:n{}
      \__tag_status_sort:
      \__tag_status_type:nn{1}{1.~Unsupported}
      \__tag_status_type:nn{2}{2.~Currently~incompatible}
      \__tag_status_type:nn{3}{3.~Partially~compatible}
      \__tag_status_type:nn{4}{4.~Compatible}
      \__tag_status_type:nn{0}{5.~Unknown}
      \__tag_status_type:nn{-1}{6.~Unclassified~files~with~extension~.sty}
       \iow_term:n{====================================}
      \iow_term:n{~~End~of~status~report}
      \iow_term:n{====================================}
    }
 }
%    \end{macrocode}
%\subsection{\cs{DocumentMetadata} keys}
%\changes{1.0k}{2024-12-17}{added latest value for testphase key.}
%\changes{1.0n}{2025/03/25}{Allow a list as pdfstandard value.}
%\changes{1.0n}{2025/03/25}{Add tagging key}
%\changes{1.0n}{2025/03/25}{Add tagging-setup}
%\changes{1.0o}{2025/04/03}{Add debug=BBox}
%\changes{1.0p}{2025/04/28}{Add tikz module to latest key}
%\changes{1.0u}{2025/10/09}{Added check-tagging-status}
%\changes{1.0v}{2025/10/12}{Extend check-tagging-status to libraries}
%\changes{1.0z}{2026-04-22}{Removed duplicated key definitions that are already done in pdfmanagement-init}
%
% \begin{macro}{\@@_update_BCPdata:n}
% A helper command for the language key.
% This command updates the \cs{BCPdata} command.
%    \begin{macrocode}
\cs_generate_variant:Nn \text_bcp_parse:n {e}
\cs_new_protected:Npn\@@_update_BCPdata:
 {
   \tl_set:Ne\l_@@_tmpa_tl { \text_bcp_parse:e{\GetDocumentProperty{document/language}} }
   \use:e
    {
     \exp_not:N\renewcommand*\exp_not:N\BCPdata[1]
      {
       \exp_not:N \str_case:nn {##1}
        {
         { language } %was en
           { \exp_last_unbraced:No\use_i:nnnnnnn { \l_@@_tmpa_tl} }
         { region }   %was US
           { \exp_last_unbraced:No\use_iv:nnnnnnn { \l_@@_tmpa_tl} }
         { script }   %was Latn
           { \exp_last_unbraced:No\use_iii:nnnnnnn { \l_@@_tmpa_tl} }
         { tag }      %was en-US
           { \exp_last_unbraced:No\use_i:nnnnnnn { \l_@@_tmpa_tl}-
             \exp_last_unbraced:No\use_iv:nnnnnnn { \l_@@_tmpa_tl}
           }
        }
      }
   }
 }
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\@@_language_set:n,\@@_language_set_aux:wn}
% Command to handle the optional argument of the \texttt{language} key.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_language_set:n #1
 {
   \tl_if_head_eq_charcode:nNTF {#1}[ %]
    {
      \@@_language_set_aux:wn  #1
    }
    {
      \AddToDocumentProperties[document]{language}{#1}
      \keys_set:ne{document/metadata}{lang={#1}}
    }
 }

\cs_new_protected:Npn \@@_language_set_aux:wn [#1] #2
  {
     \AddToDocumentProperties[document]{language}{#2}
     \keys_set:ne{document/metadata}{lang={#1}}
  }
%    \end{macrocode}
% \end{macro}
% The key definition:
% \changes{1.1b}{2026-05-02}{Add keys \texttt{language} and \texttt{other-languages}.}
%    \begin{macrocode}
\keys_define:nn { document / metadata }
 {
   language      .code:n =
    {
      \@@_language_set:n {#1}
    },
   other-languages.code:n = {\AddToDocumentProperties [document]{other-languages}{#1}},
 }
%    \end{macrocode}
%    \begin{macrocode}
\keys_define:nn { document / metadata }
  {
    backend .choices:nn =
      { dvipdfmx , dvips , dvisvgm , luatex , pdftex , pdfmode , xdvipdfmx , xetex }
      {
        \sys_load_backend:n {#1}
      },
    backend .groups:n = { init } ,
  }
\keys_define:nn { document / metadata }
 {
    ,check-tagging-status .choice:
    ,check-tagging-status / off .code:n = {}
    ,check-tagging-status / listfiles .code:n =
      {
        \__tag_status_log:
      }
    ,check-tagging-status .default:n = {listfiles}
 }
\keys_define:nn { document / metadata }
  {
    ,pdfversion .groups:n = { pdf }
    ,pdfstandard .groups:n = { pdf }
    ,lang .code:n =
      {
        \pdfmanagement_add:nnn {Catalog} {Lang}{(#1)}
        \AddToDocumentProperties[document]{lang}{#1}
      }
%    \end{macrocode}
% As the latest set of modules is loaded by default, many testphase keys only activate tagging.
% \changes{v1.0s}{2025/07/07}{Adapted testphase keys to the default loading of the tagging code}
%    \begin{macrocode}
    ,testphase .multichoices:nn =
     {latest,tagpdf,phase-I,phase-II,phase-III}
     {
       \keys_set:nn
        {document / metadata}
        {tagging=on}
     }
%    \end{macrocode}
% The following modules are all always loaded, therefore they can be ignored when used in a testphase key:
% \changes{v1.1a}{2026-04-23}{Make testphase values for loaded modules noop}
%    \begin{macrocode}
    ,testphase .multichoices:nn =
     {math,new-or,sec,sec-template,toc,graphic,block,minipage,float,
      bib,context,text,firstaid,table,title,marginpar,tikz}
     {}
    ,testphase / unknown .code:n =
      {
        \tl_gput_right:Nn\g_@@_testphase_tl
           {
             \tl_if_empty:eT{\GetDocumentProperty{document/testphase/#1}}
              {
                \AddToDocumentProperties [document]{testphase/#1}{loaded}
                \file_if_exist_input:nF {#1-latex-lab-testphase.ltx}
                 {
                  \msg_warning:nnn{meta}{latex-lab-pkg-missing}{#1}
                  \AddToDocumentProperties [document]{testphase/#1}{missing}
                 }
              }
           }
      }
  }
%    \end{macrocode}
% Activating and deactivating tagging after tagpdf has been loaded requires a redefinition
% of various commands. We store the needed settings in auxiliaries that we
% can redefine if tagging should be used.
% \changes{1.0w}{2025-10-13}{Use commands to set tagging, tagging issue \#994}
% \begin{macro}{\__tag_document_set_tagging_off:,
%               \__tag_document_set_tagging_on:,
%               \__tag_document_set_tagging:}
%    \begin{macrocode}
\cs_new_protected:Npn \__tag_document_set_tagging_off:
 {
%    \end{macrocode}
%   Avoid warning from non-existing hook label. This can be removed after the
%   next tagpdf update (2025-10-13).
%    \begin{macrocode}
    \sys_if_engine_luatex:F
     { \AddToHook{shipout/firstpage}[tagpdf/space]{} }
    \tagpdfsetup{activate/mc=false,activate/tree=false,
       activate/struct=false,activate/socket=false,
       activate/spaces=false,
       para/tagging=false,math/setup=}
    \AddToDocumentProperties [document]{tagging}{inactive}
    \AddToDocumentProperties [document]{tagging/para}{inactive}
    \AddToDocumentProperties [document]{tagging/interwordspace}{inactive}
%    \end{macrocode}
% \changes{v1.0r}{2025/07/03}{Start a global suspend}
% We must avoid that a command like \cs{LaTeX} which contains a \cs{ResumeTagging} command restarts
% tagging, so we start a global suspend. Perhaps the commands should even be set to noop.
%    \begin{macrocode}
    \tag_suspend:n {global}
%    \end{macrocode}
% \changes{v1.0t}{2025/09/25}{Disable \cs{tagpdfsetup}}
% We disable the setup command, as various keys assume that the tagging structure is there,
% see tagging-project issue \#994.
%    \begin{macrocode}
           \cs_set_protected:Npn\tagpdfsetup##1{}
%    \end{macrocode}
%
%    perhaps, need to test:
%    \begin{macrocode}
%\cs_set_eq:NN\tag_suspend:n\use_none:n
%\cs_set_eq:NN\tag_resume:n \use_none:n
 }
\cs_new_protected:Npn \__tag_document_set_tagging_on:
 {
   \tagpdfsetup{activate,para/tagging,activate/spaces}
   \AddToDocumentProperties [document]{tagging}{active}
   \AddToDocumentProperties [document]{tagging/para}{active}
   \AddToDocumentProperties [document]{tagging/interwordspace}{active}
 }
%    \end{macrocode}
% By default tagging is off.
%    \begin{macrocode}
\cs_new_eq:NN \__tag_document_set_tagging:\__tag_document_set_tagging_off:
\AddToHookNext{class/before}{\__tag_document_set_tagging:}
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\keys_define:nn { document / metadata }
  {
    ,tagging .choice:,
    ,tagging / on .code:n =
      {
        \cs_set_eq:NN \__tag_document_set_tagging:\__tag_document_set_tagging_on:
      }
    ,tagging / off .code:n =
      {
        \cs_set_eq:NN \__tag_document_set_tagging:\__tag_document_set_tagging_off:
      }
    ,tagging / draft .code:n =
      {
        \keys_set:nn { document / metadata }{ tagging=on }
        \AddToHook{shipout/lastpage}[tagging-setup]{\tagpdfsetup{activate/tree=false}}
        \DeclareHookRule{shipout/lastpage}{tagging-setup}{before}{tagpdf}
      }
    ,tagging-setup .code:n =
      {
        \keys_set:nn { document / metadata }{ tagging=on }
        \tl_gclear:N\g_@@_testphase_tl
        \keys_set_groups:nnn{__tag/setup}{load}{#1}
        \AddToHook{class/before}
         {\keys_set_exclude_groups:nnn {__tag/setup}{load}{#1}}
      }
    ,debug .code:n =
      {
        \keys_set:nn { document / metadata / debug } {#1}
      }
    ,debug / para .code:n =
      {
        \AddToHook
          {
            package/tagpdf/after
          }
          {
             \tagpdfsetup{debug/show=para}
          }
      }
    ,debug / log .code:n =
      {
        \AddToHook
          {
           package/tagpdf/after
          }
          {
             \tagpdfsetup{debug/log=#1}
          }
      }
    ,debug / tagpdf .code:n =
      {
        \AddToHook
          {
           package/tagpdf/after
          }
          {
             \RequirePackage{tagpdf-debug}
          }
      }
    ,debug / uncompress .code:n =
      {
        \pdf_uncompress:
      }
    ,debug / pdfmanagement .bool_gset:N = \g_@@_active_bool
    ,debug / firstaidoff .clist_gset:N = \g_@@_firstaidoff_clist
    ,debug / BBox .code:n =
      {
        \AddToHook{package/latex-lab-testphase-graphic/after}
         { \bool_set_true:N \l__tag_graphic_debug_bool}
      }
  }
\keys_define:nn{__tag/setup}
 {
   ,modules .code:n =
     {
      \keys_set:nn { document / metadata }{testphase={#1}}
     }
   ,modules .groups:n = { load }
   ,extra-modules .code:n =
     {
       \keys_set:nn { document / metadata }{testphase={#1}}
     }
   ,extra-modules .groups:n = { load }
 }
%    \end{macrocode}
% \subsection{Messages}
%    \begin{macrocode}
%UFi is meta the right module name here?
\prop_gput:Nnn \g_msg_module_type_prop { meta } { LaTeX }
\prop_gput:Nnn \g_msg_module_name_prop { meta } { DocumentMetadata }

\msg_new:nnn { meta } { after-class }
             {
                \token_to_str:N \DocumentMetadata \c_space_tl
                should~be~used~only~before~\token_to_str:N\documentclass
             }
\msg_new:nnn { meta } { latex-lab-pkg-missing }
             {
               LaTeX-lab~package~'#1'~not~found.
              }
%    \end{macrocode}
%
%    \begin{macrocode}
\ExplSyntaxOff\makeatother
%    \end{macrocode}
%
%
%    \begin{macrocode}
%</code>
%    \end{macrocode}
%
% \end{implementation}
%
% \Finale
%
