% \iffalse meta-comment
%
%% File: latex-lab-title.dtx (C) Copyright 2023-2026 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 latex-lab bundle is developed in the LaTeX2e GitHub.
% Issues may be reported at
%
%    https://github.com/latex3/latex2e/issues
%
\def\ltlabtitledate{2026-05-27}
\def\ltlabtitleversion{0.85g}

%<*driver>
\documentclass{l3in2edoc}
\EnableCrossrefs
\CodelineIndex
\begin{document}
  \DocInput{latex-lab-title.dtx}
\end{document}
%</driver>
%
% \fi
%
% \title{The \textsf{latex-lab-title} package\\
% Changes related to the tagging of the title}
% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}}
% \date{v\ltlabtitleversion\ \ltlabtitledate}
%
% \maketitle
%
% \newcommand{\xt}[1]{\textsl{\textsf{#1}}}
% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}}
% \newcommand{\docclass}{document class \marginpar{\raggedright document class
% customizations}}
%
% \providecommand\hook[1]{\texttt{#1}}
%
% \begin{abstract}
% \end{abstract}
%
% \section{Introduction}
%
% This module contains changes to improve the tagging (in the standard classes) of
% the title created with the \cs{maketitle} command. It also improves the
% setting of the metadata related to the title and the author.
% 
% For basic tagging of the printed title there are basically three things to do:
% 
% \begin{itemize}
% \item The actual title should be tagged with the \texttt{Title} tag.
% \item The tabular used to format the author list should \emph{not} be tagged as a tabular.
% \item \cs{maketitle} redefines footnote internals. These must be made tagging aware.
% \end{itemize} 
% 
% A second task related to title is to store the authors and the title text 
% (or a shorter version) inside the  XMP-metadata and (in PDF 1.7 or lower) in
% the Info dictionary. Currently this can only be set if hyperref
% is loaded and requires the use of the \texttt{pdftitle} and \texttt{pdfauthor} keys. 
% The new code therefore extends the \cs{title} and \cs{author} commands: They
% stores their argument and use them at the end of the document 
% for the PDF metadata if the data hasn't been given in another way. 
% The code also gives \cs{title} and \cs{author} 
% an optional argument where the PDF title or author can be given with
% in a key-value syntax. As with hyperref it is possible to store titles 
% in more than one language:
%  
% \begin{verbatim}
% \title
%   [pdftitle = 
%      {[en]English Title,[de] Deutscher Titel,[fr]{titre français, avec comma}}]
%   {Document title} 
% \end{verbatim}
% 
% It is also possible to set a subtitle which is then stored in the XMP-metadata:
% 
% \begin{verbatim}
% \title
%   [pdfsubtitle = 
%      {[en]English Subtitle,[de] Deutscher Subtitel,[fr]{subtitre français, avec comma}}]
%   {Document title} 
% \end{verbatim}
 
% 
% If using the \texttt{pdfauthor} key authors should be separated
% by commas, and to hide commas in a name inside braces if needed:
%
%  \begin{verbatim}
%  \author[pdfauthor = {Bär, Peter Anteater, {Riley, the sloth}}]{\ldots}
%  \end{verbatim}
% 
% If hyperref is loaded there is no difference to the \texttt{pdftitle} and
% \texttt{pdfauthor} key used in \cs{hypersetup}. Both can be used (and the last
% key used will win). 
% 
% \subsection{Open questions and TODOs}
% 
% \begin{itemize}
% \item Writing into the Info dictionary needs to convert the input into a PDF string.
% This is here done with a simple version of hyperref's \cs{pdfstringdef}, similar code
% exist also in the generic hyperref driver. This should be moved into a better place
% module. 
% 
% \item Is it sensible to enhance \cs{author} and \cs{title} with an optional argument as done here?
% An advantage is that it is rather light-weight and
% doesn't require to decide how this values should be set in \cs{DocumentMetadata} (and would also work
% without \cs{DocumentMetadata}. But a problem could be that various classes and packages already
% extend this commands with other optional arguments.
% 
% \item Some of the definitions related to metadata should perhaps be moved into l3pdfmeta.
% 
% \item Are the names \texttt{pdftitle} and \texttt{pdfauthor} ok? 
% 
% \item The patch for \cs{thanks} to get a rlap-footnotemarker looks wrong. This 
% probably means that some configuration option is missing in the footnote code.
% \end{itemize}
% 
%   
% 
% \section{Implementation}
%    \begin{macrocode}
%<*package>
%<@@=tag>
%    \end{macrocode}
%    \begin{macrocode}
\ProvidesExplPackage {latex-lab-testphase-title} {\ltlabtitledate} {\ltlabtitleversion}
  {Changes related to the tagging of the title}
%    \end{macrocode}
%
% \subsection{\cs{maketitle} in article class}
% 
%    \begin{macrocode}
\cs_new_protected:Npn \@@_patch_thanks:n #1
  {
    \rlap{\footnotemark}
    \protected@xdef\@thanks{\@thanks
      \protect\footnotetext[\the\c@footnote]{#1}}
  }
%    \end{macrocode}
% The no-titlepage version of article, report and book
%    \begin{macrocode}
\cs_new_protected:Npn \@@_patch_maketitle:
  {
    \par
    \begingroup
%    \end{macrocode}
% Disable table tagging
%    \begin{macrocode}
      \tagpdfsetup{table/tagging=false}%
      \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
%    \end{macrocode}
% the original definition redefines \cs{@makefnmark} and
% \cs{@makefntext} to get an rlap-mark in the text without 
% affecting the mark in the note (which gives by the way
% a wrong link area with hyperref). There seem to be currently
% no good way in the footnote to configure this, so we redefine 
% \cs{thanks} instead 
%    \begin{macrocode}
      \cs_set_eq:NN \thanks \@@_patch_thanks:n
      \if@twocolumn
        \ifnum \col@number=\@ne
          \@maketitle
        \else
          \twocolumn[\@maketitle]%
        \fi
      \else
      \newpage
        \global\@topnum\z@   % Prevents figures from going at top of page.
        \@maketitle
      \fi
      \thispagestyle{plain}\@thanks
    \endgroup
    \setcounter{footnote}{0}%
    \global\let\thanks\relax
    \global\let\maketitle\relax
    \global\let\@maketitle\relax
    \global\let\@thanks\@empty
    \global\let\@author\@empty
    \global\let\@date\@empty
    \global\let\@title\@empty
    \global\let\title\relax
    \global\let\author\relax
    \global\let\date\relax
    \global\let\and\relax
  }
%    \end{macrocode}
% We must also change \cs{@maketitle} to insert a \texttt{Title} tag.
% We have here two options: We can surround the whole block with a \texttt{Title}
% or only the title text (but not both).
% As default the title text has the \texttt{Title} tag and the block is a \texttt{Part} (from
% the symbolic name \texttt{para/semantic}), 
% but this can be changed by reassigning the symbolic name \texttt{title/block}
% and changing the plug of the tagging socket to the transparent plug, e.g., 
% \begin{verbatim}
% \AssignStructureRole{title/block}{Title}
% \AssignTaggingSocketPlug{title}{transparent}
% \end{verbatim}
% Note that in PDF 1.7 the \texttt{Title} tag is not a standard tag, it is a user defined
% and by default rolemapped to \texttt{P}. If \texttt{Title} should be used for the 
% title block the rolemapping must be adjusted, e.g., to \texttt{Part} or \texttt{Sect}.
% 
%    \begin{macrocode}
\AssignStructureRole{title/block}{\UseStructureName{para/semantic}}
\IfSocketExistsF{tagsupport/title}
 {
  \NewTaggingSocket{title}{2}
 } 
\NewTaggingSocketPlug{title}{kernel}
 {
   \pdf_version_compare:NnTF > {1.7}
    {\tag_struct_begin:n{tag=\UseStructureName{title/text}}#2\tag_struct_end:}
    {\AssignStructureRole{para/textblock}{\UseStructureName{title/text}}#2}%
 }
\AssignTaggingSocketPlug{title}{kernel}  
\cs_new_protected:Npn \@@_patch_@maketitle:
 {
  \newpage
  \null
  \vskip 2em%
  \begin{center}%
   [tagging-suppress-paras=true,
    tagging-recipe=standalone,
    tag-name=\UseStructureName{title/block}]
  \let \footnote \thanks
%    \end{macrocode}
% By default this socket adds \texttt{Title} around the title text. 
% In PDF 1.7 \texttt{Title} is rolemapped to P and the socket
% adapts the \texttt{para/textblock} to avoid 
% that we get an \texttt{P} inside a \texttt{P}.
% One can assign the \texttt{transparent} plug to the socket if
% \texttt{Title} should be used for the title block instead.
%    \begin{macrocode}
  {\LARGE\UseTaggingSocket{title}{}{\@title}\par}  
   \vskip 1.5em%
    {\large
      \lineskip .5em%
      \begin{tabular}[t]{c}%
        \@author
      \end{tabular}\par}%
    \vskip 1em%
    {\large \@date}%
  \end{center}%
  \par
  \vskip 1.5em
  }
 
%    \end{macrocode}
% The titlepage variant:
% \changes{0.85f}{2026-05-07}{Added support for title/block tag}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_patch_maketitle_page:
  {\begin{titlepage}%
%    \end{macrocode}
% disable table tagging
%    \begin{macrocode}
  \tagpdfsetup{table/tagging=false}%
  \let\footnotesize\small
  \let\footnoterule\relax
  \let \footnote \thanks
  \null\vfil
  \vskip 60\p@
%    \end{macrocode}
%    \begin{macrocode}
  \begin{center}%
   [tagging-suppress-paras=true,
    tagging-recipe=standalone,
    tag-name=\UseStructureName{title/block}]
%    \end{macrocode}
% By default this socket adds \texttt{Title} around the title text. 
% In PDF 1.7 \texttt{Title} is rolemapped to P and the socket
% adapts the \texttt{para/textblock} to avoid 
% that we get an \texttt{P} inside a \texttt{P}.
% One can assign the \texttt{transparent} plug to the socket if
% \texttt{Title} should be used for the title block instead.
%    \begin{macrocode}
   {\LARGE\UseTaggingSocket{title}{}{\@title}\par}
   \vskip 3em%
    {\large
     \lineskip .75em%
      \begin{tabular}[t]{c}%
        \@author
      \end{tabular}\par}%
      \vskip 1.5em%
    {\large \@date \par}%       % Set date in \large size.
  \end{center}\par
  \@thanks
  \vfil\null
  \end{titlepage}%
  \setcounter{footnote}{0}%
  \global\let\thanks\relax
  \global\let\maketitle\relax
  \global\let\@thanks\@empty
  \global\let\@author\@empty
  \global\let\@date\@empty
  \global\let\@title\@empty
  \global\let\title\relax
  \global\let\author\relax
  \global\let\date\relax
  \global\let\and\relax
  }

%    \end{macrocode}
% Map the new commands onto \cs{maketitle}:
%    \begin{macrocode}
\AddToHook{class/article/after}
  {
    \if@titlepage
     \cs_set_eq:NN \maketitle \@@_patch_maketitle_page:
    \else
     \cs_set_eq:NN \maketitle \@@_patch_maketitle:
     \cs_set_eq:NN \@maketitle \@@_patch_@maketitle:
    \fi
  } 
\AddToHook{class/report/after}
  {
    \if@titlepage
     \cs_set_eq:NN \maketitle \@@_patch_maketitle_page:
    \else
    \cs_set_eq:NN \maketitle \@@_patch_maketitle:
    \cs_set_eq:NN \@maketitle \@@_patch_@maketitle:
    \fi
  } 
\AddToHook{class/book/after}
  {
    \if@titlepage
     \cs_set_eq:NN \maketitle \@@_patch_maketitle_page:
    \else
    \cs_set_eq:NN \maketitle \@@_patch_maketitle:
    \cs_set_eq:NN \@maketitle \@@_patch_@maketitle:   
    \fi
  } 
%    \end{macrocode}
%
% \subsection{Helper commands to set metadata}
% 
% Some temp variables
%    \begin{macrocode}
\str_new:N \g_@@_title_tmpa_str
\str_new:N \l_@@_title_tmpa_str
\tl_new:N  \l_@@_title_tmpa_tl
\seq_new:N \l_@@_title_tmpa_seq
%    \end{macrocode}
%
% We ensure that the default definitions
% of \cs{@title} and \cs{@author} are robust:
%    \begin{macrocode}
\protected\def\@title{\@latex@error{No~\noexpand\title given}\@ehc}
\protected\def\@author{\@latex@warning@no@line{No~\noexpand\author given}}
%    \end{macrocode}
% A helper command to convert the title into a pdfstring similar to 
% \cs{pdfstringdef}.
%\changes{0.85e}{2026-04-29}{The command makes now use of \cs{pdf_purify:nN}}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_title_pdfstring:nnN #1 #2 #3 % #1 text, #2 e.g. utf16/hex
  {
    \group_begin:
    \pdf_purify:nN {#1}\l_@@_title_tmpa_tl
    \pdf_string_from_unicode:nVN { #2 } \l_@@_title_tmpa_tl \l_@@_title_tmpa_str
    \str_gset_eq:NN \g_@@_title_tmpa_str\l_@@_title_tmpa_str
    \group_end:
    \str_set_eq:NN #3 \g_@@_title_tmpa_str
  }
\cs_generate_variant:Nn\@@_title_pdfstring:nnN {e} 
%    \end{macrocode}

% \subsection{Extend title to set metadata}
% At first a variable to store the title, as \cs{@title} is emptied by \LaTeX. 
%    \begin{macrocode}
\tl_new:N \g_@@_title_title_tl 
%    \end{macrocode}
% Now we redefine \cs{title} so that it stores the title, and processes
% keys in the optional argument. We use \texttt{hyp} as module
% name for the key as this means that if hyperref is loaded its definition
% of \texttt{pdftitle} will be used -- at some time probably this
% should be moved out of hyperref so that we have only one definition.
% 
%    \begin{macrocode}
\RenewDocumentCommand\title{O{}m}
 {
    \gdef\@title{#2}
    \tl_gset_eq:NN\g_@@_title_title_tl\@title
    \keys_set:nn {hyp}{#1}
 } 
%    \end{macrocode}
% Now we define the \texttt{pdftitle} key. This is more or less
% the same definition as in the generic hyperref driver. 
%    \begin{macrocode}
\regex_new:N\l_@@_title_optlang_regex
\regex_set:Nn\l_@@_title_optlang_regex {\A\[([A-Za-z\-]+)\](.*)}
\cs_generate_variant:Nn \clist_item:nn {on}
%    \end{macrocode}
% and now the keys.
%    \begin{macrocode}
\keys_define:nn { hyp }
   {
     pdftitle  .code:n =
       {
         \tl_if_blank:nTF {#1}
           {
             \pdfmanagement_remove:nn {Info}{Title}
           }
           {
             \tl_set:Ne\l_@@_title_tmpa_tl {\clist_item:on{#1}{1}}           
             \regex_extract_once:NVN 
                \l_@@_title_optlang_regex 
                \l_@@_title_tmpa_tl
                \l_@@_title_tmpa_seq
             \seq_if_empty:NTF\l_@@_title_tmpa_seq
              {
                \@@_title_pdfstring:nnN {#1}{utf16/hex}\l_@@_title_tmpa_str
              }
              {         
                \@@_title_pdfstring:enN 
                   {\seq_item:Nn \l_@@_title_tmpa_seq{3}}{utf16/hex}\l_@@_title_tmpa_str
              }
             \str_if_eq:VnF\l_@@_title_tmpa_str{<FEFF>}
               {
                 \pdfmanagement_add:nne {Info}{Title}{\l_@@_title_tmpa_str}
               }
           }
          \AddToDocumentProperties[hyperref]{pdftitle}{#1}
       }
   ,pdfsubtitle .code:n = { \AddToDocumentProperties[hyperref]{pdfsubtitle}{#1} }    
   }
%    \end{macrocode}
%
% \subsection{Extend \cs{author} to set metadata}
% 
% At first a variable to store the authors, as \cs{@author} is emptied by \LaTeX. 
%    \begin{macrocode}
\tl_new:N \g_@@_title_author_tl 
%    \end{macrocode}
% Now we redefine \cs{author} so that it stores the authors, and processes
% keys in the optional argument. We use \texttt{hyp} as module
% name for the key as this means that if hyperref is loaded its definition
% of \texttt{pdfauthor} will be used -- at some time probably this
% should be moved out of hyperref so that we have only one definition.
% 
%    \begin{macrocode}
\RenewDocumentCommand\author{O{}m}
 {
    \gdef\@author{#2}
    \tl_gset_eq:NN\g_@@_title_author_tl\@author
    \keys_set:nn {hyp}{#1}
 } 
%    \end{macrocode}
%
% Now we define the \texttt{pdfauthor} key. This is more or less
% the same definition as in the generic hyperref driver. 

%    \begin{macrocode}
\keys_define:nn { hyp }
   {
     pdfauthor  .code:n =
       {
         \tl_if_blank:nTF {#1}
           {
             \pdfmanagement_remove:nn {Info}{Author}
           }
           {
             \tl_set:Ne\l_@@_title_tmpa_tl {\clist_item:on{#1}{1}}           
             \regex_extract_once:NVN 
                \l_@@_title_optlang_regex 
                \l_@@_title_tmpa_tl
                \l_@@_title_tmpa_seq
             \seq_if_empty:NTF\l_@@_title_tmpa_seq
              {
                \@@_title_pdfstring:nnN {#1}{utf16/hex}\l_@@_title_tmpa_str
              }
              {         
                \@@_title_pdfstring:enN 
                   {\seq_item:Nn \l_@@_title_tmpa_seq{3}}{utf16/hex}\l_@@_title_tmpa_str
              }
             \str_if_eq:VnF\l_@@_title_tmpa_str{<FEFF>}
               {
                 \pdfmanagement_add:nne {Info}{Author}{\l_@@_title_tmpa_str}
               }
           }
          \AddToDocumentProperties[hyperref]{pdfauthor}{#1}
       }
   }
%    \end{macrocode}
% \subsection{Fallback for classes and packages that redefine \cs{title} or \cs{author}}
% If a class redefines \cs{author} and \cs{title} again, we try to retrieve at
% least the values. 
%    \begin{macrocode}
\AddToHook{cmd/maketitle/before}
  {
   \tl_gset_eq:NN \g_@@_title_author_tl\@author
   \tl_gset_eq:NN \g_@@_title_title_tl\@title
  }  
%    \end{macrocode}
%
% \subsection{Finalize document}
% At last we set the title and the author at the end of document 
% if that hasn't happened yet:
%    \begin{macrocode}
\AddToHook{shipout/lastpage}
 {
   \tl_if_empty:eT{\GetDocumentProperty{hyperref/pdftitle}}
      { 
        \group_begin:
        \cs_set_eq:NN\thanks \use_none:n
        \str_set:Ne \l_@@_title_tmpa_str {\text_purify:n { \g_@@_title_title_tl } }
        \keys_set:ne{hyp}{pdftitle={\exp_not:V\l_@@_title_tmpa_str}}
        \group_end:
      }
   \tl_if_empty:eT{\GetDocumentProperty{hyperref/pdfauthor}}
      { 
        \group_begin:
        \cs_set_eq:NN\thanks \use_none:n
        \cs_set:Npn \and {,}
        \str_set:Ne \l_@@_title_tmpa_str {\text_purify:n { \g_@@_title_author_tl } }
        \keys_set:ne{hyp}{pdfauthor={\exp_not:V\l_@@_title_tmpa_str}}
        \group_end:
      }
%    \end{macrocode}
% force display title, if an UA-standard is detected.
%    \begin{macrocode}
   \tl_if_empty:eF{\GetDocumentProperty{document/pdfstandard-UA}}
     {
       \pdfmanagement_add:nnn {Catalog / ViewerPreferences } { DisplayDocTitle } { true }
     }            
 }
\DeclareHookRule{shipout/lastpage}{latex-lab-testphase-title}{before}{pdfmanagement-testphase}
%</package>  
%    \end{macrocode}

%    \begin{macrocode}
%<*latex-lab>
\ProvidesFile{title-latex-lab-testphase.ltx}
        [\ltlabtitledate\space v\ltlabtitleversion\space
         Changes related to the tagging of the title]

\RequirePackage{latex-lab-testphase-title}

%</latex-lab>
%    \end{macrocode}
