summaryrefslogtreecommitdiff
path: root/macros/latex-dev/required/latex-lab/latex-lab-title.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex-dev/required/latex-lab/latex-lab-title.dtx')
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-title.dtx518
1 files changed, 518 insertions, 0 deletions
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-title.dtx b/macros/latex-dev/required/latex-lab/latex-lab-title.dtx
new file mode 100644
index 0000000000..757bb284a4
--- /dev/null
+++ b/macros/latex-dev/required/latex-lab/latex-lab-title.dtx
@@ -0,0 +1,518 @@
+% \iffalse meta-comment
+%
+%% File: latex-lab-title.dtx (C) Copyright 2023-2024 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/required/latex-lab
+%
+% for those people who are interested or want to report an issue.
+%
+\def\ltlabtitledate{2024-02-09}
+\def\ltlabtitleversion{0.85c}
+
+%<*driver>
+\documentclass{l3doc}
+\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 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}
+ \cs_if_exist_use:N\__tag_tbl_disable:
+ \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 Title tag
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_@maketitle:
+ {
+ \newpage
+ \null
+ \vskip 2em%
+ \begin{center}%
+ \let \footnote \thanks
+% \end{macrocode}
+% use Title around the title. As in PDF 1.7 this is
+% rolemapped to P we change the text-unit tag there.
+% \begin{macrocode}
+ \pdf_version_compare:NnTF > {1.7}
+ {{\LARGE \tag_struct_begin:n{tag=Title}\@title \par\tag_struct_end:}}
+ {{\LARGE \tagtool{paratag=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
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_maketitle_page:
+ {\begin{titlepage}%
+% \end{macrocode}
+% disable table tagging
+% \begin{macrocode}
+ \cs_if_exist_use:N\__tag_tbl_disable:
+ \let\footnotesize\small
+ \let\footnoterule\relax
+ \let \footnote \thanks
+ \null\vfil
+ \vskip 60\p@
+% \end{macrocode}
+% use Title around the title. As in PDF 1.7 this is
+% rolemapped to P we change the text-unit tag there.
+% \begin{macrocode}
+ \begin{center}%
+ \pdf_version_compare:NnTF > {1.7}
+ {{\LARGE \tag_struct_begin:n{tag=Title}\@title \par\tag_struct_end:}}
+ {{\LARGE \tagtool{paratag=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}
+% Support for \cs{texorpdfstring}
+% \begin{macrocode}
+\providecommand\texorpdfstring[2]{#1}%
+% \end{macrocode}
+%
+% A helper command to convert the title into a pdfstring similar to
+% \cs{pdfstringdef}.
+% As we use \cs{text_purify} we must 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}
+% TODO: This should be improved and moved into the pdf module so that
+% it is generally available.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_title_pdfstring:nnN #1 #2 #3 % #1 text, #2 e.g. utf16/hex
+ {
+ \group_begin:
+% \end{macrocode}
+% TODO: we need probably a common boolean to handle
+% \cs{texorpdfstring} also without hyperref.
+% \begin{macrocode}
+ \cs_set_eq:NN\texorpdfstring\use_ii:nn
+ \str_set:Ne \l_@@_title_tmpa_str {\text_purify:n { #1 } }
+ \pdf_string_from_unicode:nVN { #2 } \l_@@_title_tmpa_str \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 \regex_extract_once:NnN{NVN}
+\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{\GetDocumentProperties{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{\GetDocumentProperties{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{\GetDocumentProperties{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}