% \iffalse meta-comment % %% File: ltdocinit.dtx % % Copyright (C) 2018-2022 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> \RequirePackage{pdfmanagement-testphase} \DocumentMetadata{pdfstandard=A-2b} \documentclass[full]{l3doc} \usepackage{array,booktabs,hyperxmp} \hypersetup{pdfauthor=The LaTeX Project,pdftitle=ltdocinit (LaTeX PDF management testphase bundle)} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \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.95r, released 2022-08-24} % % \maketitle % \begin{documentation} % % \section{\pkg{ltdocinit} documentation} % This small module defines \cs{DocumentMetadata} and the older alias % \cs{DeclareDocumentMetadata} and the related keys. % It also defines commands to store document properties in a global container. % % When the kernel will provide \cs{DocumentMetadata} directly % this module will slowly disappear. % % \subsection{\cs{DocumentMetadata}/\cs{DeclareDocumentMetadata}} % % \begin{function}{\DocumentMetadata,\DeclareDocumentMetadata} % \begin{syntax} % \cs{DocumentMetadata}\Arg{key-value list}\\ % \cs{DeclareDocumentMetadata}\Arg{key-value list} (deprecated) % \end{syntax} % \end{function} % % Currently there is no dedicated location to declare settings concerning % a document as a whole. Settings are placed somewhere in the preamble or % with the class options or even with some package options. % For some settings this can be too late, % for example the pdf version can no longer be changed if a % package has used code which already opened the PDF. % % \cs{DocumentMetadata} as a new command % should unify such settings in one place. % It should be used before \cs{documentclass}. % \cs{DocumentMetadata} can be used more than once. % % With a \LaTeX{} 2022-06-01 or newer (currently provided as |latex-dev|) the command % is provided by the kernel and will load the pdfmanagement, % with older \LaTeX{} the pdfmanagement must be loaded % first manually with |\RequirePackage{pdfmanagement-testphase}|. % % The keys defined for \cs{DocumentMetadata} % currently allows to set the PDF version, to set the PDF \texttt{/Lang}, % to uncompress a pdf, to set the language and to declare a few PDF standards % and to load some colorprofiles. % % \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}. % % Currently the following keys are implemented % % \begin{description} % \item[\texttt{backend}] Passes the backend name to expl3. This is % needed only if the needed backend can't be automatically % determined or if the workflow used requires a special backend. % %^^A This will probably be extended to pass the value also to %^^A packages. % % \item[\texttt{pdfversion}] Sets the PDF version explicitly, e.g., \texttt{pdfversion=1.7} % \item[\texttt{uncompress}] (no value) Forces an uncompressed pdf % --- mainly for debugging purposes. % % \item[\texttt{lang}] Explicitly sets the Lang entry in the Catalog, % e.g., \texttt{lang=de-DE}. If not given the default value used is |en-US|. % % \item[\texttt{pdfstandard}] Choice key to set the pdf standard. % Currently |A-1b|, |A-2a|, |A-2b|, |A-2u|, |A-3a|, |A-3b|, |A-3u| and |A-4| % are accepted as % values. The casing is irrelevant, |a-1b| works too. % The underlying code to ensure the requirements (as far as they % can be ensured) is still incomplete, but a color profile is included and the % \texttt{/OutputIntent} is set. The |u| variants for example do not force unicode, % but they will pass the information to hyperref and hyperxmp. The |a| variants % do \emph{not} enforce (or even test) a tagged pdf yet. % More information can be found in the documentation % of \pkg{l3pdfmeta}. % % \item[\texttt{colorprofiles}] This allows to load icc-colorprofiles. Details % are described in the documentation of \pkg{l3pdfmeta}. % % \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. % \begin{description} % \item[\texttt{phase-I}] % This value loads code implementing the first phase of the project~\cite{blueprint}, i.e., it % will load the tagpdf package. It will also activate tagging by issuing % |\tagpdfsetup{activate,interwordspace}|. This phase % is frozen. % \item[\texttt{phase-II}] % This is the current development phase. % Currently it differs from \texttt{phase-I} only in one point: It will % additionally activate tagging of paragraphs with % |\tagpdfsetup{paratagging}|. In the upcoming months it will % also enable automatic tagging of other basic document elements. % \end{description} % The |testphase| key can only be used in the first \cs{DocumentMetadata}. % % \item[\texttt{debug}] This key activates some debug options. It takes a list of key-values % as value. Currently the following keys are known: % \begin{description} % \item[\texttt{para}] with the default and only value |show|. It will activate the |paratagging-show| % option of \pkg{tagpdf}, % \item[\texttt{log}] with the values as described in the documentation \pkg{tagpdf}, % \item[\texttt{uncompress}] which does the same as |uncompress| as main key % \item[\texttt{pdfmanagement}] a boolean which allows to deactivate the pdfmanagement. % \item[\texttt{firstaidoff}] This accepts a comma lists of keywords and disables the patches % related to them. More information can be found in the documentation of % \pkg{pdfmanagement-firstaid}. % \end{description} % \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}{\GetDocumentProperties} % \begin{syntax} % \cs{GetDocumentProperties}\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}{\ShowDocumentProperties} % \begin{syntax} % \cs{ShowDocumentProperties} % \end{syntax} % This show 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}{2022-08-24}{0.95r} {Initialize document metadata} % % \end{macrocode} % \cs{DocumentMetadata} will be defined by the kernel in short time. % So we define it and the keys here only if it is not already defined. % \subsection{The keys for \cs{DocumentMetadata}} % We define the keys first so that we can test if \cs{DocumentMetadata} % exist (testing for the format date would be nice but would fail for the current % latex-dev). % \begin{variable}{\g_@@_firstaidoff_clist} % A list to store the firstaid code which should be disabled % \begin{macrocode} %<*package> \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_new:N \g_@@_testphase_tl % \end{macrocode} % \end{variable} % \begin{macrocode} \cs_if_free:NT \DocumentMetadata { \keys_define:nn { document / metadata } { backend .choices:nn = { dvipdfmx , dvips , dvisvgm , luatex , pdftex , pdfmode , xdvipdfmx , xetex } { \sys_load_backend:n {#1} }, backend .groups:n = { init } , } \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} } %,xmpmeta .bool_gset:N = \g_pdfmeta_xmp_bool %see pdfmeta unused and undefined for now! % this uses internal command from pdfmeta, it should probably move there ... ,pdfstandard .code:n = { \exp_args:Nnx \keys_set:nn {document / metadata} {_pdfstandard=\str_uppercase:n{#1}} } ,_pdfstandard .choices:nn = {A-1B,A-2A,A-2B,A-2U,A-3A,A-3B,A-3U,A-4} { \prop_if_exist:cT { g__pdfmeta_standard_pdf/#1_prop } { \prop_gset_eq:Nc \g__pdfmeta_standard_prop { g__pdfmeta_standard_pdf/#1 _prop } } \AddToDocumentProperties [document]{pdfstandard}{#1} } ,_pdfstandard / unknown .code:n = { \msg_warning:nnn{pdf}{unknown-standard}{#1} } ,testphase .multichoice: ,testphase / tagpdf .code:n = { \tl_gput_right:Nn\g_@@_testphase_tl { \file_if_exist_input:nF {tagpdf-latex-lab-testphase.ltx} { \RequirePackage{tagpdf} \AddToDocumentProperties [document]{testphase/tagpdf}{loaded} \tagpdfsetup{activate,paratagging,interwordspace} \AddToDocumentProperties [document]{tagging}{active} \AddToDocumentProperties [document]{tagging/para}{active} \AddToDocumentProperties [document]{tagging/interwordspace}{active} } } } ,testphase / unknown .code:n = { \tl_gput_right:Nn\g_@@_testphase_tl { \AddToDocumentProperties [document]{testphase/#1}{loaded} \file_if_exist_input:nF {#1-latex-lab-testphase.ltx} { \msg_warning:nnn{document}{latex-lab-pkg-missing}{#1} \AddToDocumentProperties [document]{testphase/#1}{missing} } } } ,activate .multichoice: ,activate / tagging .code:n = { \PackageWarning{pdfmanagement-testphase} {The~activate~key~is~deprecated.\MessageBreak Tagging~is~activated~with~'testphase=tagpdf'~directly}{} } ,debug .code:n = { \keys_set:nn { document / metadata / debug } {#1} } ,debug / para .code:n = { \AddToHook { package/tagpdf/after } { \tagpdfsetup{paratagging-show} } } ,debug / log .code:n = { \AddToHook { package/tagpdf/after } { \tagpdfsetup{log=#1} } } ,debug / uncompress .code:n = { \pdf_uncompress: } ,debug / pdfmanagement .bool_gset:N = \g_@@_active_bool ,debug / firstaidoff .clist_gset:N = \g_@@_firstaidoff_clist } } % \end{macrocode} % % \subsection{\cs{DocumentMetadata}/\cs{DeclareDocumentMetadata}} % At first we have to define the older alias \cs{DeclareDocumentMetadata} if % \cs{DocumentMetadata} is already defined in a newer LaTeX version. Here % we load the latex-lab support (if it hasn't been loaded % before) and redefine then \cs{DeclareDocumentMetadata} % to \cs{DocumentMetadata} % % \begin{macrocode} \cs_if_exist:NT \DocumentMetadata { \cs_new_protected:Npn \DeclareDocumentMetadata { \cs_if_free:NT \DocumentMetadata { \file_if_exist_input:nF {documentmetadata-support.ltx}% { \@latex@error {No~support~files~for~\noexpand\DeclareDocumentMetadata~found} { Is~the~'LaTeX-lab'~bundle~installed? \MessageBreak Without~it,~the~declaration~is~ignored. } \let\DeclareDocumentMetadata\@gobble } } \RenewDocumentCommand \DeclareDocumentMetadata {} { \DocumentMetadata } \DocumentMetadata } } % \end{macrocode} % Now we provide a definition for \cs{DocumentMetadata} if it doesn't exist yet. % \begin{macrocode} \cs_if_free:NT \DocumentMetadata { % \end{macrocode} % \cs{DocumentMetadata} should for now not be used after % \cs{documentclass} so we error in this case. It can be used more than once % but follow-up calls should not do the initialization code. % \begin{macrocode} \prop_gput:Nnn \g_msg_module_type_prop { document } { LaTeX } \prop_gput:Nnn \g_msg_module_name_prop { document } { DocumentMetadata } \msg_new:nnn { document } { setup-after-documentclass } { \token_to_str:N \DocumentMetadata \c_space_tl should~be~used~only~before~\token_to_str:N\documentclass } \msg_new:nnn { document } { latex-lab-pkg-missing } { LaTeX-lab~package~'#1'~not~found. } % \end{macrocode} % \begin{macro}{\DocumentMetadata} % \begin{macrocode} \NewDocumentCommand\DocumentMetadata { m } { \cs_if_eq:NNTF \documentclass \@twoclasseserror { \msg_error:nn { document }{ setup-after-documentclass } } { % \end{macrocode} % The wanted backend must be detected first, we read the init key and then % force the loading by loading expl3. % The backend can contains management commands, so the boolean should be set to true first. % \begin{macrocode} \bool_gset_true:N \g_@@_active_bool \keys_set_groups:nnn { document / metadata} {init}{ #1 } %if no backend has been loaded force it now: \str_if_exist:NF \c_sys_backend_str { \sys_load_backend:n {} } % \end{macrocode} % Now we load the extra backend code % \begin{macrocode} \ExplSyntaxOn\makeatletter \file_input:n {l3backend-testphase-\c_sys_backend_str.def} \ExplSyntaxOff\makeatother % \end{macrocode} % set the default language, process the rest of the keys, % and setup the generic driver % \begin{macrocode} \keys_set_filter:nnn { document / metadata } { init } { lang=en-US, #1 } \bool_if:NT \g_@@_active_bool { \PassOptionsToPackage{customdriver=hgeneric-testphase}{hyperref} } % \end{macrocode} % \cs{pdfmanagement_add:nnn} has collected values in this hook. % \begin{macrocode} \hook_use_once:n {pdfmanagement/add} % \end{macrocode} % Redefine \cs{DocumentMetadata} so that it only process the keys. % We need to update the hyperref option if the active status changes. % \begin{macrocode} \RenewDocumentCommand\DocumentMetadata { m } { \keys_set_filter:nnn { document / metadata } { init } { ##1 } \bool_if:NTF \g_@@_active_bool { \str_remove_all:cn {opt@hyperref.sty}{customdriver=hgeneric-testphase} \PassOptionsToPackage {customdriver=hgeneric-testphase}{hyperref} } { \str_remove_all:cn {opt@hyperref.sty}{customdriver=hgeneric-testphase} } } % \end{macrocode} % Load more modules, the testphase code and the firstaid code. % \begin{macrocode} \g_@@_testphase_tl \RequirePackage{pdfmanagement-firstaid} } } % \end{macrocode} % At last we need to provide the older alias here too % \begin{macrocode} \NewDocumentCommand\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:NNx \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} % \begin{macro}{\ShowDocumentProperties} % \begin{macrocode} \msg_new:nnn { pdfmanagement } { show-properties } { The~following~document~properties~have~been~stored: #1 } \NewDocumentCommand\ShowDocumentProperties {} { \msg_show:nnx {pdfmanagement}{show-properties} { \prop_map_function:NN \g_@@_documentproperties_prop \msg_show_item:nn } } % \end{macrocode} % \end{macro} % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % % \PrintIndex