% \iffalse meta-comment
%
%% File: ltdocinit.dtx
%
% Copyright (C) 2018-2025 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
%
%    http://www.latex-project.org/lppl.txt
%
% This file is part of the "LaTeX PDF management testphase bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
%    https://github.com/latex3/pdfresources
%
% for those people who are interested.
%
%<*driver>
\DocumentMetadata{pdfstandard=A-2b}
\documentclass[full]{l3doc}
\usepackage{array,booktabs}
\hypersetup{pdfauthor=The LaTeX Project,pdftitle=ltdocinit (LaTeX PDF management testphase bundle)}

\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
%   The \pkg{ltdocinit} module
% }
%
% \author{^^A
%  The \LaTeX{} Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Version 0.96r, released 2025-05-15}
%
% \maketitle
% \begin{documentation}
%
% \section{\pkg{ltdocinit} documentation}
% This small module defined \cs{DocumentMetadata} but the definition
% has been moved to latex-lab. The documentation can be found in
% \texttt{documentmetadata-support-doc.pdf}
%
% \cs{DocumentMetadata} is also used to
% activate the new PDF management code and it loads
% a number of required files for the PDF management code.
% As this forces the loading of the backend files, a backend
% which can't be detected automatically like |dvipdfmx|,
% must be set in the first \cs{DocumentMetadata}.
%
%
% Here only a few newer keys are defined and the older \cs{DeclareDocumentMetadata}
% is provided.
%
% The module also defines commands to store document properties in a global container.
%
% This module will slowly disappear.
%
% \subsection{\cs{DocumentMetadata}/\cs{DeclareDocumentMetadata}}
%
% \begin{function}{\DeclareDocumentMetadata}
% \begin{syntax}
%  \cs{DeclareDocumentMetadata}\Arg{key-value list} (deprecated)
% \end{syntax}
% This is an older alias for \cs{DocumentMetadata}
% \end{function}
%
% Additionally to the keys described in \texttt{documentmetadata-support-doc.pdf}
% the following keys/values are implemented
%
% \begin{description}
%
%    \item[\texttt{testphase}] This key is used to load testphase code. The values it accepts
%    and their effect will change over time, when testphase packages are added or
%    removed or when the code is moved into the kernel. A new value here is
%     \begin{description}
%      \item[latest] This loads all existing modules.
%    \end{description}
%
%    The |testphase| key can only be used in the first \cs{DocumentMetadata}.
%
% \end{description}
%
% \subsection{Container for document properties}
%
% The module provides a container where classes, packages and users can store
% properties of the document which are perhaps of interest
% or use for other packages or the author.
%
% The properties are stored with a key |label/property|. The values can be
% retrieved expandably.
%
% \begin{function}{\AddToDocumentProperties}
% \begin{syntax}
%  \cs{AddToDocumentProperties}\oarg{label}\Arg{property}\Arg{value}
% \end{syntax}
% This stores \meta{value} under the key \meta{label}/\meta{property}.
% By default \meta{label} is the current package name |\@currname|. If another
% label is chosen, it should be one which avoids clashes with other packages
% using the container. The label |document| is reserved.
% \end{function}
%
% \begin{function}[updated=2022-10-09]{\GetDocumentProperties,\pdfmanagement_get_documentproperties:n}
% \begin{syntax}
%  \cs{GetDocumentProperties}\Arg{label/property}\\
%  \cs{pdfmanagement_get_documentproperties:n}\Arg{label/property}
% \end{syntax}
% Expands to the \meta{value} corresponding to \meta{label/property}
% in the container. If \meta{label/property} is missing,
% this has an empty expansion.
% The result is returned within \cs{exp_not:n}, which means
% that the \meta{value} does not expand further
% when appearing in an x-type argument expansion.
% \end{function}
%
% \begin{function}[added=2022-10-09,TF]{\pdfmanagement_get_documentproperties:nN}
% \begin{syntax}
%  \cs{pdfmanagement_get_documentproperties:nNTF}\Arg{label/property} \meta{token list variable}\\
%  ~~~~ \Arg{true code} \Arg{false code}
% \end{syntax}
%   If the \meta{label/property} is not present in the document properties
%   container, leaves the \meta{false code} in the input stream.
%   The value of the
%   \meta{token list variable} is not defined in this case and should
%   not be relied upon.  If the \meta{label/property} is present in the
%   container, stores the corresponding \meta{value} in the
%   \meta{token list variable} without removing it from the
%   container, then leaves the \meta{true code} in the input
%   stream.  The \meta{token list variable} is assigned locally.
% \end{function}
%
% \begin{function}{\ShowDocumentProperties,\LogDocumentProperties}
% \begin{syntax}
%  \cs{ShowDocumentProperties}\\
%  \cs{LogDocumentProperties}
% \end{syntax}
% This shows/logs the current content of the container.
% \end{function}
%
% \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}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{ltdocinit} implementation}
%    \begin{macrocode}
%<@@=pdfmanagement>
%<*header>
\ProvidesExplPackage{ltdocinit}{2025-05-15}{0.96r}
  {Initialize document metadata}
%</header>
%    \end{macrocode}
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
% \subsection{Variables}
% This variable definitions can be remove 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{New, temporary testphase keys}
% TODO: remove after 2025-06-01 release
%
%    \begin{macrocode}
\msg_new:nnn { meta } { testphase-latest-loading-temp }
   {
     Loading~testphase~modules\\
     #1
   }
\keys_define:nn { document / metadata }
  {
    ,testphase / latest .code:n =
     {
       \keys_set:nn
        {document / metadata}
        {testphase={phase-III,title,table,math,firstaid}}
       \tl_gput_right:Nn\g_@@_testphase_tl
        {
          \msg_note:nnn { meta } { testphase-latest-loading-temp }
           { phase-III,~title,~table,~math,~firstaid }
        }
     }
    ,tagging .choice:,
    ,tagging / on .code:n =
      {
        \keys_set:nn { document / metadata }{ testphase=latest }
      }
    ,tagging / off .code:n =
      {
        \keys_set:nn { document / metadata }{ testphase=latest }
        \AddToHook{class/before}
         {
           \tagpdfsetup{activate/mc=false,activate/tree=false,
                        activate/struct=false,activate/socket=false,
                        para/tagging=false,math/setup=}
           \AddToDocumentProperties [document]{tagging}{inactive}
           \AddToDocumentProperties [document]{tagging/para}{inactive}
           % perhaps, need to test
           %\tag_suspend:n {global}
           %\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_mc_begin:n #1 { \__tag_whatsits: \int_gincr:N \c@g__tag_MCID_abs_int }
           %\cs_new_protected:Nn \tag_mc_end:{ \__tag_whatsits: }
           %\cs_new_protected:Npn \tag_struct_begin:n #1 {\int_gincr:N \c@g__tag_struct_abs_int}
           %\cs_new_protected:Npn \tag_struct_end:{}
         }
      }
    ,tagging / draft .code:n =
      {
        \keys_set:nn { document / metadata }{ testphase=latest }
        \AddToHook{shipout/lastpage}[tagging-setup]{\tagpdfsetup{activate/tree=false}}
        \DeclareHookRule{shipout/lastpage}{tagging-setup}{before}{tagpdf}
      }
    ,tagging-setup .code:n =
      {
        \tl_gclear:N\g_@@_testphase_tl
        \keys_set:nn { document / metadata }{ testphase=latest }
        \keys_set_groups:nnn{__tag/setup}{load}{#1}
        \AddToHook{class/before}
         {\keys_set_exclude_groups:nnn {__tag/setup}{load}{#1}}
      }
 }
\keys_define:nn{__tag/setup}
 {
   ,modules .code:n =
     {
      \tl_gclear:N\g_@@_testphase_tl
      \keys_set:nn { document / metadata }{testphase={phase-II,#1}}
     }
   ,modules .groups:n = { load }
   ,extra-modules .code:n =
     {
       \keys_set:nn { document / metadata }{testphase={#1}}
     }
   ,extra-modules .groups:n = { load }
 }
%    \end{macrocode}
% \subsection{\cs{DeclareDocumentMetadata}}
% \cs{DocumentMetadata} is defined by the kernel.
% We only define the older alias \cs{DeclareDocumentMetadata}
%
% \begin{macro}{\DeclareDocumentMetadata}
%    \begin{macrocode}
\NewCommandCopy\DeclareDocumentMetadata\DocumentMetadata
%    \end{macrocode}
% \end{macro}
%
% \subsection{Container for document Properties}
% The container for the document properties is a prop
% \begin{variable}{\g_@@_documentproperties_prop}
%    \begin{macrocode}
\prop_new:N \g_@@_documentproperties_prop %
%    \end{macrocode}
% \end{variable}
% \begin{macro}{\AddToDocumentProperties}
%    \begin{macrocode}
\NewDocumentCommand\AddToDocumentProperties{O{\@currname}mm}
  {
    \exp_args:NNe
      \prop_gput:Nnn \g_@@_documentproperties_prop
        {
          \tl_if_blank:eTF {#1}{top-level/}{#1/} #2
        }
        { #3}
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\GetDocumentProperties}
%    \begin{macrocode}
\NewExpandableDocumentCommand\GetDocumentProperties{m}
  {
    \prop_item:Nn \g_@@_documentproperties_prop {#1}
  }
%    \end{macrocode}
% \end{macro}
% For uses in modules (e.g. l3pdfmeta)
% we provide an expl3 version without the xparse overhead:
%
% \begin{macro}[EXP]{\pdfmanagement_get_documentproperties:n}
%    \begin{macrocode}
\cs_new:Npn\pdfmanagement_get_documentproperties:n #1
  {
    \prop_item:Nn \g_@@_documentproperties_prop {#1}
  }
%    \end{macrocode}
% \end{macro}
% The following allows to retrieve the values with branching.
% \begin{macro}[added=2022-10-09]{\pdfmanagement_get_documentproperties:nNTF}
%    \begin{macrocode}
\prg_new_protected_conditional:Npnn
  \pdfmanagement_get_documentproperties:nN #1#2 { T , F , TF }
    {
     \prop_get:NnNTF \g_@@_documentproperties_prop  {#1} #2
       {
        \prg_return_true:
       }
       {
        \prg_return_false:
       }
    }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\ShowDocumentProperties}
%    \begin{macrocode}
\msg_new:nnn  { pdfmanagement } { show-properties }
  {
    The~following~document~properties~have~been~stored:
    #1
  }
\NewDocumentCommand\ShowDocumentProperties {}
  {
    \msg_show:nne {pdfmanagement}{show-properties}
      {
        \prop_map_function:NN \g_@@_documentproperties_prop \msg_show_item:nn
      }
  }
\NewDocumentCommand\LogDocumentProperties {}
  {
    \msg_log:nne {pdfmanagement}{show-properties}
      {
        \prop_map_function:NN \g_@@_documentproperties_prop \msg_show_item:nn
      }
  }
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex