% \iffalse meta-comment
%
%% File: pdfmanagement.dtx
%
% Copyright (C) 2019-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
%
% This file is part of the "LaTeX PDF management 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{tagging=on,pdfstandard=ua-2}
\documentclass[full]{l3doc}
\usepackage{latex-lab-testphase-l3doc}

\usepackage{tabularx,array,booktabs}
\hypersetup{pdfauthor=The LaTeX Project,pdftitle=LaTeX PDF management bundle}
\newcommand\potentialclash{\noindent\llap{\dbend\ }}
\pdfextension glyphtounicode {char7f}{2621} 
\raggedbottom
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
%
% \title{The \LaTeX{} PDF management bundle}
%
% \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.97c, released 2026-05-26}
%
% \maketitle
% \begin{documentation}
% \section*{Abstract}
%  {\em This is a temporary bundle created to allow the external
%   loading of the new \LaTeX{} PDF management code during a test phase.
%  It will disappear when the code is integrated into the \LaTeX{} format.}
%
%  \medskip
%  \noindent The PDF management code is loaded 
%  automatically if you use \cs{DocumentMetadata} before
%  \cs{documentclass}. 
%
% \begin{verbatim}
% \DocumentMetadata      % loads also the PDF management
%     {
%       % options, see documentmetadata-support.pdf
%     }
%
%  \documentclass {...}
% \end{verbatim}
% 
% 
% It is also possible to load the PDF as package, e.g. in a class. 
%  
% \begin{verbatim}
%  \RequirePackage{pdfmanagement}
% \end{verbatim}
%  
%  If the PDF management has already been loaded, e.g. in \cs{DocumentMetadata}
%  this will do nothing. The package has one option, \texttt{backend} that allows
%  to set a special backend like \texttt{dvipdfmx}. It will do nothing if the backend
%  code has already been loaded. 
%  
%  Other options, e.g., the PDF standard or the PDF version should then be set with a \cs{SetKeys} command:
%  
%  \begin{verbatim}
%  \RequirePackage{pdfmanagement}
%  \SetKeys[document/metadata]
%    {
%      pdfversion=2.0,
%      lang=de,
%      xmp=false,
%      ...
%    }  
%  \end{verbatim}
%  
%  Note that PDF management should be loaded as early as possible. 
%
%
% \section*{Feedback wanted!}
%
% Bug reports and feedback are welcome. Please open an issue at
% \url{https://github.com/latex3/pdfresources}.
%
% While the code targets PDF as output format, feedback about the
% effect on other formats is needed too.
%
% \section{Introduction}
% The \LaTeX{} format contained for a long time nearly no code specific to the now quite
% central output format, PDF. It also offered nearly no interfaces to important PDF related
% primitive commands for package writers.
%
% Important tasks like supporting PDF standards,
% creating links, adding special colors, managing the content of
% central PDF-directories or even simple tasks like setting the PDF version
% were delegated to external packages which had to recourse to
% the primitive low-level commands in their code.
%
% This was problematic for three reasons:
% \begin{itemize}
%\item At first using primitives directly can lead to clashes and duplicate
% settings with conflicting values---nothing prevent packages to add for example
% the \texttt{/Title} twice to the Info dictionary, the \texttt{/Lang} entry
% twice to the Catalog, or to add two \texttt{/ExtGState}
% resources to a page. The PDF normally doesn't break in such
% cases---the format is quite robust---but it will ignore one of the duplicates and
% the output can be wrong.
%
% \item At second the primitives differ between the various engines and backends with
% which \LaTeX{} is used. To support the engines and backend
% packages have to write and maintain
% \enquote{driver} files which they did to a varying degree. This makes it
% difficult for users to assess if a package will work with their work-flow and
% is a strain for package writers as they have to keep track of engine and backend changes.
%
% \item And at last generic hooks and configuration points to various
% PDF related structures are missing and difficult to add.
% \end{itemize}
%
% Despite the potential problems, the number of conflicts were
% small and could be resolved in an ad-hoc fashion. But the plans for
% \LaTeX{} regarding support for tagged PDF and
% PDF standards mean that much more PDF specific code has to be
% written by the kernel directly and this can not be done without proper,
% well-defined and well-behaving interfaces and hooks.
%
% Some first steps for better support of PDF related commands have been done
% with the \pkg{l3pdf} package which has then been integrated as a module
% into \pkg{l3kernel}.
% It offers backend independent commands to create
% PDF objects and destination, to set the compress level and the PDF version.
%
% The PDF management bundle extends this to more PDF related areas
% and provides interfaces to them in a backend independent way.
%
% The PDF management has three main objectives
% connected with the problems identified above:
% \begin{itemize}
% \item For commands with \enquote{clash potential} it implements commands to
% replace the primitives and so to resolve potential conflicts.
%
% \item It implements commands for a variety of PDF related tasks
% and supports a well-defined set of backends.
%
% \item If sensible this commands are enhanced by hooks from the 
% \LaTeX{} hook system. This has been e.g.\ done for annotations in the
% \pkg{l3pdfannot} bundle.
% \end{itemize}
%
% \section{\enquote{Change Strategy}: The integration into \LaTeX\label{sec:change}}
%
% The central module of this bundle, \pkg{l3pdfmanagement}, defines an interface
% for the (pdf\TeX) primitives \cs{pdfcatalog}, \cs{pdfinfo},
% \cs{pdfpagesattr}, \cs{pdfpagesattr} and \cs{pdfpageresources} and
% the analog commands from the other engines and backends.
%
% All these commands have a \enquote{clash potential}, this means that the new
% interface is incompatible with a parallel use of the primitive commands
% which it targets to replace and supersede.
% This doesn't affect many packages, but the list of package using such primitives
% contains central and important packages like \pkg{hyperref}, \pkg{tikz},
% \pkg{pdfx} and more.
%
% So while the goal is to integrate the code into the \LaTeX{} format directly,
% this can not be done immediately without conflicts with existing documents 
% and packages.
%
% The code is there not loaded by the kernel but only if the trigger command
% \cs{DocumentMetadata} is used, or if the package \texttt{pdfmanagement}
% is loaded manually.
%
%
% We hope that this setup will allow packages writers and users to test the
% PDF management code and adapt packages and documents safely.
%
%
% \section{Backend support}
% The supported backends are pdflatex, lualatex, (x)dvipdfmx (latex, xelatex,
% dvilualatex 
% and dvips with ps2pdf (not completely yet). dvips with distiller could work too
% but is untested.
%
% That the interfaces and commands are backend independent doesn't mean
% that the results and even the compilation behavior is identical.
% The backends are too different to allow this.
% Some backends expand arguments e.g. in a \cs{special} while other don't.
% Some backends can insert a resource at the first compilation, while another uses
% the aux-file and a label and so needs at least two compilation runs.
% Some backends manage some of the resources through side-effects,
% some manage them automatically.
% All this mean that package writers will still have to keep an eye on
% backend requirements and run tests for all variants. Also backend specific code
% will still be needed in some cases.
%
% \section{Use}\label{sec:use}
% The PDF management should be loaded as early as possible.
% When using \cs{DocumentMetadata}, various PDF related options can
% be set in the key-val argument.
% The options of \cs{DocumentMetadata} are described in the documentation of
% \pkg{ltdocinit} and in \pkg{documentmetadata-support}.
%
% \begin{verbatim}
% \DocumentMetadata % activates the PDF management interface
%     {
%        %options
%     }
% \documentclass {...}
% \end{verbatim}
%
% When loading the PDF management as package, options can be set with \cs{SetKeys}:
% 
% \begin{verbatim}
% \RequirePackage{pdfmanagement} %loads the PDF management interface
% \SetKeys[document/metadata]{
%        %options
%     }
% \documentclass {...}
% \end{verbatim} 
% 
% To test if the PDF management has been loaded
% \cs{IfPDFManagementActiveTF} can be used.
% 
% \section{Requirements}
% The new PDF management is developed parallel to the \LaTeX{} format
% and should be updated together with the format. 
% In some places, e.g. when writing strings to the pdf it assumes that
% the file is utf8 encoded -- ascii will naturally work too, 
% but legacy 8bit encodings are not supported.
%
% \section{Modules}
% The bundle contains a number of modules. The majority of the modules don't
% have a stand alone \texttt{sty}, their code is combined
% in one file and loaded by the main package. The organization and naming is bound
% to change over time: For almost all modules the goal is to
% integrate them into the format and the individual files to disappear.
%
% The description items give the name of the documentation
% of the modules. There doesn't exist in all cases a related |.sty|.
%
% \begin{description}
% \item[l3pdfdict] This module provides commands for PDF dictionaries. Its main
% purpose is to create name spaces. The code used e.g. by \pkg{l3pdfmanagement} and
% \pkg{l3pdfannot}.
%
% \item[l3pdfannot] This module provides commands for annotations. Currently mainly
% link annotations, widget annotations will be added later. It doesn't require
% the PDF management to be active.
%
% \item[l3pdfmanagement] This is the core code of the PDF management.
%
% \item[ltdocinit] This module provides the \cs{DocumentMetadata} command.
%
% \item[hyperref-generic] This module provides a new generic hyperref driver.
% The driver will
% be loaded automatically by hyperref if the PDF management code is active.
%
% \item[l3backend-pdfmanagement] This module contains backend code needed by the
% PDF management. It will in due time be integrated into l3backend.
%
% \item[l3pdfmeta] This module contains code to handle PDF standards.
% Currently it handles pdf/A and colorprofiles/outputintents.
%
% \item[l3pdfxform]  Commands for form XObjects (xforms).
%
% \item[l3pdf\/tool] A number of commands like text conversion commands and
% bcd/emc.  The commands will at some time be moved into the \pkg{l3pdf}
% module of l3kernel.
%
% \item[l3pdf\/file] This module provides commands for to embed files.
%
% \item[pdfmanagement-firstaid] This module provides a number of patches
% for external incompatible packages. This patches will disappear as soon as
% the packages are natively compatible. It is loaded automatically.
%
% \item[l3pdffield]  Commands for form fields. Currently it only provides commands
% for checkboxes. It must be loaded explicitly as with
% |\usepackage{l3pdffield}|.
%
% \end{description}
% \section{Incompabilities}
%
% As described in section~\ref{sec:change}, 
% the new PDF management takes over the management of core PDF dictionaries.
% All packages
% that bypass the PDF management and access these dictionaries with primitives like
% \cs{pdfcatalog}, \cs{pdfinfo}, \cs{pdfpageresources}, \cs{pdfpagesattr}
% and \cs{pdfpageattr} or similar commands from other engines and backends are
% basically incompatible: values can get lost or will be wrong.
%
% The following describes known incompatible packages along with some suggestions
% how this should or will be handled in future. The list is not exhaustive.
%
% \subsection{hyperref}
% A generic driver that can
% be used as replacement has been developed and is provided by this bundle.
% It will be loaded automatically if the pdf management is active.
%
% The generic driver differs in some points from other \pkg{hyperref} drivers:
% \begin{itemize}
% \item The code for bookmarks has been removed from this driver, instead
% the \pkg{bookmarks} is loaded and used.
% \item The driver isn't yet fully integrated into hyperref. This means that
% it doesn't react to a number of package options. Instead \cs{hypersetup} should
% be used.
% \item Incomplete is the support for form fields. Quite probably form fields will
% be extracted in a dedicated package.
% \item The driver uses for the color handling the l3color package. While normally
% it should be able to use colors defined with color and xcolor, there could be
% edge cases where it fails.
% \item The colors have been changed (this counts probably as an improvement \ldots).
% \end{itemize}
%
% More details can be found in the documentation \pkg{hyperref-generic.pdf}.
%
% \subsection{pdfx}
% \pkg{pdfx} is not compatible. It uses the commands \cs{pdfpagesattr}, \cs{pdfpageattr},
% \cs{pdfinfo} and \cs{pdfcatalog}. The needed changes are not many, but can
% not be done by external patches.
%
% The PDF management offers support for standards natively. It also writes XMP-metadata
% See the documentation of \pkg{l3pdfmeta} for details.
%
% \subsection{hyperxmp}
% \pkg{hyperxmp} uses \cs{pdfcatalog} to insert the \texttt{/MetaData} reference
% and also relies on some \pkg{hyperref} internals which are not present in the new
% generic driver used by \pkg{hyperref} when the pdfmanagement is active.
% This makes \pkg{hyperxmp} incompatible.
%
% For some time some patch code was provided by the bundle to keep \pkg{hyperxmp}
% working but starting with version  0.95s XMP-metadata are handled directly
% by the \pkg{pdfmanagement} bundle (see the documentation of \pkg{l3pdfmeta})
% and the patch code has been removed and the loading of
% \pkg{hyperxmp} has been disabled.
%
% \subsection{tikz/pgf}
% \pkg{pgf} writes to the page resources too and so is incompatible. The needed
% changes are rather small and will be done in coordination with the maintainer.
% Until this works, the PDF management will load the patches automatically.
% This can be disabled by using |debug={firstaidoff=pgf}| in \cs{DocumentMetadata}
%
% \subsection{transparent}
% The package \pkg{transparent} is compatible. 
% 
% \subsection{pdflscape}
% The package \pkg{pdflscape} is compatible. 
% 
% \subsection{colorspace}
% The package is incompatible. Some patches
% have been added to \pkg{pdfmanagement-firstaid}.
% Alternative code for spot colors is
% in the \pkg{l3color} package which has now been added to \pkg{l3kernel}.
%
% \subsection{embedfile, attachfile, attachfile2}
% Tools needed to be able to write a replacement
% to replace these packages have been developed in the \pkg{l3pdffile} package.
% Full replacements for the packages don't exist yet.
%
% \subsection{ocgx2, animate, media9}
% These package all make use of low-level PDF command and will
% have to be reviewed.
%
% \subsection{acrotex}
% The \pkg{acrotex} makes heavy use of PDF commands and so must be reviewed and
% adapted, including the currently untested route dvips + distiller.
%
% \subsection{fancytooltips}
% This package uses \cs{pdfpageattr} and \pkg{acrotex} and so must be reviewed.
% \end{documentation}
%
% \subsection{bidi}
% 
% The package \pkg{bidi} (loaded e.g. by \pkg{polyglossia} for right-to-left scripts) 
% patches and redefines internals of \pkg{hyperref} and overwrites
% definitions of the generic driver. It is therefore not guarantied to be
% compatible with the PDF management if \pkg{hyperref} is used. 
% 
% \begin{implementation}
%
% \section{Implementation}
%
%    \begin{macrocode}
%<@@=pdfmanagement>
%<*headinit>
\ProvidesExplPackage{pdfmanagement-init}{2026-05-26}{0.97c}
  {LaTeX PDF management bundle}

\DeclareOption { debug }
  {
    \msg_redirect_module:nnn { pdf } { none } { warning }
  }

\ProcessOptions\relax
%</headinit>
%<*headtestphase>
\ProvidesExplPackage{pdfmanagement-testphase}{2026-05-26}{0.97c}
  {LaTeX PDF management bundle}

\DeclareOption { debug }
  {
    \msg_redirect_module:nnn { pdf } { none } { warning }
  }

\ProcessOptions\relax
%</headtestphase>
%    \end{macrocode}
%<*standalone>
%    \begin{macrocode}
\ProvidesExplPackage{pdfmanagement}{2026-05-26}{0.97c}
  {LaTeX PDF management bundle}
%    \end{macrocode}
% The only package option is for the backend. Other options can be
% set after loading the package with \verb+\SetKeys[document/metadata]+
%    \begin{macrocode}

\DeclareKeys[pdfmanagement]
 {
   backend .code:n = 
    { 
      \str_if_exist:NTF \c_sys_backend_str
       {
        \PackageWarning{pdfmanagement}
         {
           backend~is~already~loaded.\MessageBreak
           'backend=#1'~ignored.
         }  
       }
       { 
         \tl_new:N  \l__pdfmanagement_backend_tl  
         \tl_set:Nn \l__pdfmanagement_backend_tl {#1}
       }
    },
   backend .usage = load,
 }  
\ProcessKeyOptions[pdfmanagement]

\IfPDFManagementActiveT
 {
   \endinput 
 }

\RequirePackage{pdfmanagement-init}
% the backend key must be processed first.
%    \begin{macrocode}
\tl_if_exist:NTF \l_@@_backend_tl
  {
    \exp_args:No \sys_load_backend:n { \l_@@_backend_tl }
  }  
  {
    \sys_ensure_backend:
  } 
\file_input:n {l3backend-pdf-\c_sys_backend_str.def}
\hook_use_once:n {pdfmanagement/add} 
%    \end{macrocode}
% firstaid should be loaded only after the backend has been set as
% it can contain backend dependant code.
%    \begin{macrocode}
\RequirePackage{pdfmanagement-firstaid}     
%</standalone>
%    \end{macrocode}
%
% \subsection{Loading the core file}
% This loads the core file. The backend should not be loaded
% to allow to set it in the document.
%    \begin{macrocode}
%<*header>
\ProvidesExplFile{pdfmanagement.ltx}{2026-05-26}{0.97c}
  {PDF~management~code}
%</header>  
%    \end{macrocode}
%    \begin{macrocode}
%<*package>
\RequirePackage{tagpdf-base}
\input{pdfmanagement.ltx}
%    \end{macrocode}
% These keys are also needed in documentmetadata-support, so need to be in the init-file:
%    \begin{macrocode}
\keys_define:nn { document / metadata }
  {
    ,pdfversion .code:n =
      {
        \pdf_version_gset:n { #1 }
        \AddToDocumentProperties[document]{pdfversion}{#1}
      }
    ,uncompress .code:n =
      {
        \pdf_uncompress:
      }
    ,uncompress .value_forbidden:n = true
    ,lang .code:n =
      {
        \pdfmanagement_add:nnn {Catalog} {Lang}{(#1)}
        \AddToDocumentProperties[document]{lang}{#1}
      }      
    ,pdfstandard .code:n =
      {
        \clist_map_inline:nn{#1}
         {           
           \keys_set:ne {document / metadata} {_pdfstandard=\str_uppercase:n{##1}}
         }  
      }
   }   
%</package>
%    \end{macrocode}
% \end{implementation}
% \newpage
% \PrintIndex
