diff options
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.dtx | 518 |
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} |