From 66ebd4914b367eb00a52ce5d5bb51f695101931b Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sat, 26 Sep 2020 03:03:17 +0000 Subject: CTAN sync 202009260303 --- macros/latex/contrib/hyperxmp/README | 4 +- macros/latex/contrib/hyperxmp/einstein-xmp.tex | 149 ++- macros/latex/contrib/hyperxmp/hyperxmp.dtx | 1315 +++++++++++++++++------- macros/latex/contrib/hyperxmp/hyperxmp.ins | 4 +- macros/latex/contrib/hyperxmp/hyperxmp.pdf | Bin 1341156 -> 1520844 bytes 5 files changed, 1058 insertions(+), 414 deletions(-) (limited to 'macros/latex/contrib/hyperxmp') diff --git a/macros/latex/contrib/hyperxmp/README b/macros/latex/contrib/hyperxmp/README index c5365e41b0..4fb504485d 100644 --- a/macros/latex/contrib/hyperxmp/README +++ b/macros/latex/contrib/hyperxmp/README @@ -23,8 +23,8 @@ for specifying PDF metadata. hyperxmp can embed a wide variety of metadata as XMP, including the list of authors, document title, contact information (telephone number, postal address, email address, etc.), copyright statement, keywords, natural language, and much more. -hyperxmp is compatible with pdflatex, latex+dvips+ps2pdf, -latex+dvipdfm, xelatex, and lualatex. +hyperxmp is compatible with pdflatex, lualatex, xelatex, +latex+dvipdfm, and latex+dvips+Distiller. Installation ============ diff --git a/macros/latex/contrib/hyperxmp/einstein-xmp.tex b/macros/latex/contrib/hyperxmp/einstein-xmp.tex index f1b4d2ed06..7fad01f38a 100644 --- a/macros/latex/contrib/hyperxmp/einstein-xmp.tex +++ b/macros/latex/contrib/hyperxmp/einstein-xmp.tex @@ -6,45 +6,48 @@ \let\todayISO=\hyxmp@today \makeatother -\begin{alltt} +\begin{Verbatim}[fontsize=\small,commandchars=\\\{\}] + xmlns:pdf="http://ns.adobe.com/pdf/1.3/" + xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" + xmlns:xmp="http://ns.adobe.com/xap/1.0/" + xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" + xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" + xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/" + xmlns:pdfuaid="http://www.aiim.org/pdfua/ns/id/" + xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/" + xmlns:pdfxid="http://www.npes.org/pdfx/ns/id/" + xmlns:prism="http://prismstandard.org/namespaces/basic/3.0/" + xmlns:jav="http://www.niso.org/schemas/jav/1.0/" + xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" + xmlns:stFnt="http://ns.adobe.com/xap/1.0/sType/Font#" + xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/" + xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" + xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" + xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#" + xmlns:pdfaType="http://www.aiim.org/pdfa/ns/type#" + xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field#"> -\end{alltt} +\end{Verbatim} \begin{center} $\vdots$\par \emph{[over 200 lines of boilerplate definitions not shown]}\par $\vdots$\par \end{center} -\begin{alltt} +\begin{Verbatim}[fontsize=\small,commandchars=\\\{\}] \metavalue{energy quanta, Hertz effect, quantum physics} - \metavalue{pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019/Debian)} + \metavalue{LuaHBTeX, Version 1.12.0 (TeX Live 2020)} \metavalue{1.5} \metavalue{True} @@ -54,34 +57,28 @@ \metavalue{application/pdf} - - \metavalue{On a heuristic viewpoint concerning the production - and transformation of light} - - \metavalue{On a heuristic viewpoint concerning the production - and transformation of light} + \metavalue{On a heuristic viewpoint concerning the production} + \metavalue{and transformation of light} + + + \metavalue{On a heuristic viewpoint concerning the production} + \metavalue{and transformation of light} - \metavalue{\"Uber einen die Erzeugung und Verwandlung des Lichtes - betreffenden heuristischen Gesichtspunkt} + \metavalue{\"Uber einen die Erzeugung und Verwandlung des Lichtes} + \metavalue{betreffenden heuristischen Gesichtspunkt} \metavalue{photoelectric effect} - \metavalue{photoelectric effect} - - \metavalue{Copyright (C) 1905, Albert Einstein} - - - \metavalue{Copyright (C) 1905, Albert Einstein} - + \metavalue{Copyright (C) 1905, Albert Einstein} @@ -122,9 +119,9 @@ \metavalue{Technical Assistant, Level III} \metavalue{Scott Pakin} - \metavalue{2019-03-16T23:07:38-06:00} - \metavalue{2019-03-16T23:07:38-06:00} - \metavalue{2019-03-16T23:07:38-06:00} + \metavalue{2020-07-25T21:37:02-06:00} + \metavalue{2020-07-25T21:37:02-06:00} + \metavalue{2020-07-25T21:37:02-06:00} \metavalue{LaTeX with hyperref package} \metavalue{uuid:6d1ac9ec-4ff2-515a-954b-648eeb4853b0} @@ -163,10 +160,76 @@ \metavalue{http://www.physik.uni-augsburg.de/annalen/history/einstein-papers/190517132-148.pdf} - \metavalue{59846} - \metavalue{17} + \metavalue{41197} + \metavalue{1} + \metavalue{VoR} + + + + \metavalue{LMRoman10-Regular} + \metavalue{LM Roman 10} + \metavalue{LMRoman10-Regular} + + \metavalue{2.004;PS 2.004;hotconv 1.0.49;makeotf.lib2.0.14853} + + \metavalue{lmroman10-regular.otf} + \metavalue{opentype} + + + \metavalue{LMRoman17-Regular} + \metavalue{LM Roman 17} + \metavalue{LMRoman17-Regular} + + \metavalue{2.004;PS 2.004;hotconv 1.0.49;makeotf.lib2.0.14853} + + \metavalue{lmroman17-regular.otf} + \metavalue{opentype} + + + \metavalue{LMRoman12-Regular} + \metavalue{LM Roman 12} + \metavalue{LMRoman12-Regular} + + \metavalue{2.004;PS 2.004;hotconv 1.0.49;makeotf.lib2.0.14853} + + \metavalue{lmroman12-regular.otf} + \metavalue{opentype} + + + \metavalue{cmr12} + + + \metavalue{cmr8} + + + \metavalue{cmr6} + + + \metavalue{cmmi12} + + + \metavalue{cmmi8} + + + \metavalue{cmmi6} + + + \metavalue{cmsy10} + + + \metavalue{cmsy8} + + + \metavalue{cmsy6} + + + \metavalue{cmex10} + + + + \metavalue{1} -\end{alltt} +\end{Verbatim} diff --git a/macros/latex/contrib/hyperxmp/hyperxmp.dtx b/macros/latex/contrib/hyperxmp/hyperxmp.dtx index 9861784479..08e6d2fab8 100644 --- a/macros/latex/contrib/hyperxmp/hyperxmp.dtx +++ b/macros/latex/contrib/hyperxmp/hyperxmp.dtx @@ -22,7 +22,7 @@ %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{hyperxmp} %<*package> - [2020/06/19 v5.4 Store hyperref metadata in XMP format] + [2020/09/24 v5.5 Store hyperref metadata in XMP format] % % %<*driver> @@ -39,11 +39,15 @@ \usepackage{microtype} \usepackage{needspace} \usepackage{varioref} -\usepackage{alltt} +\usepackage{fancyvrb} \usepackage{multicol} \usepackage{makeidx} \usepackage{mmap} \usepackage{enumitem} +\usepackage{listings} +\usepackage[labelformat=simple]{subcaption} +\renewcommand\thesubfigure{(\alph{subfigure})} +\usepackage{array} \usepackage{booktabs} \usepackage{marginfix} \usepackage{ifmtarg} @@ -112,7 +116,7 @@ % % \fi % -% \CheckSum{2671} +% \CheckSum{2804} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z @@ -174,6 +178,19 @@ % \changes{v5.2}{2020/04/29}{Introduced the \protect\optname{pdfidentifier} % package option, which enables an author to specify a unique identifier % for the document} +% \changes{v5.5}{2020/07/23}{Introduced the \protect\optname{pdfpubstatus} +% package option, which enables an author to specify the document's +% publication status. Thanks to Robin Schwab for pointing me to the +% Journal Article Versions recommendation~\protect\cite{NISO2008:jav}} +% \changes{v5.5}{2020/07/25}{Automatically assign +% \protect\optname{pdfnumpages} and \protect\optname{pdfbytes} under +% \protect\pdfLaTeX\ and \protect\LuaLaTeX} +% \changes{v5.5}{2020/09/23}{Defer \protect\cs{AtEndPreamble} execution +% until the end of the document. This enables +% \protect\pkgname{hyperxmp} itself to be loaded from +% \protect\cs{AtEndPreamble}, as is done by +% \protect\pkgname{doclicense}~v2.2.0. Thanks to Tommaso Pecorella +% for the bug report and help testing} % % ^^A \GetFileInfo{hyperxmp.dtx} % @@ -325,6 +342,44 @@ % } % \makeatother % +% ^^A Index schemata. +% \DeleteShortVerb{\|} +% \makeatletter +% \newenvironment{schemadesc}[2][]{^^A +% \@ifmtarg{#1}{^^A +% \index{#2 schema|(}^^A +% \index{schemata|(}^^A +% \def\closeschemedesc{^^A +% \index{schemata|)}^^A +% \index{#2 schema|)}^^A +% }^^A +% }{^^A +% \index{#1 schema=#2 schema|(}^^A +% \index{schemata=#2|(}^^A +% \def\closeschemedesc{^^A +% \index{schemata=#2|)}^^A +% \index{#1 schema=#2 schema|)}^^A +% }^^A +% }^^A +% }{^^A +% \closeschemedesc +% } +% \newcommand{\schema}[2][]{^^A +% \@ifmtarg{#1}{^^A +% \kern0pt^^A +% \index{#2 schema}^^A +% \index{schemata}^^A +% #2^^A +% }{^^A +% \kern0pt^^A +% \index{#1 schema=#2 schema}^^A +% \index{schemata=#2}^^A +% #2^^A +% }^^A +% } +% \makeatother +% \MakeShortVerb{\|} +% % ^^A Pack figures a bit tighter onto the page. % \renewcommand{\floatpagefraction}{0.8} % @@ -380,9 +435,9 @@ % \end{verbatim} % % In the preceding code, the |dc| namespace refers to the -% \href{http://purl.org/DC/}{Dublin Core schema}, a collection of -% metadata properties. The \xmpprop{dc:creator} property surrounds the -% list of authors. The \textsf{rdf} namespace is the +% \href{http://purl.org/DC/}{\schema{Dublin Core} schema}, a collection +% of metadata properties. The \xmpprop{dc:creator} property surrounds +% the list of authors. The \textsf{rdf} namespace is the % \href{http://www.w3.org/RDF/}{Resource Description Framework}, which % defines \xmpterm{rdf:Seq} as an ordered list of values. Each author % is represented by an individual list item (\xmpterm{rdf:li}), making @@ -393,7 +448,8 @@ % is intended to make it easy for computer applications to identify and % categorize the document. % -% \paragraph{What metadata does \textsf{hyperxmp} process?} +% \subsection{Supported metadata} +% % \pkgname{hyperxmp} knows how to embed all of the following types of % metadata within a document: % @@ -419,6 +475,7 @@ % \item \acro{ISBN} (\xmpprop{prism:isbn}) % \item \acro{ISSN}---both print (\xmpprop{prism:issn}) and electronic (\xmpprop{prism:eIssn}) % \item issue number of parent publication (\xmpprop{prism:number}) +% \item journal article version (\xmpprop{jav:journal\_article\_version}) % \item keywords (\xmpprop{pdf:Keywords} and \xmpprop{dc:subject}) % \item language used (\xmpprop{dc:language}) % \item license \acro{URL} (\xmpprop{xmpRights:WebStatement}) @@ -454,15 +511,16 @@ % \noindent % More types of metadata may be added in a future release. % -% \paragraph{How does \textsf{hyperxmp} compare to the \textsf{xmpincl} -% package?} -% The short answer is that \pkgname{xmpincl} is more flexible but -% \pkgname{hyperxmp} is easier to use. With \pkgname{xmpincl}, the -% author manually constructs a file of arbitrary \acro{XMP} data and the -% package merely embeds it within the generated \acro{PDF} file. With -% \pkgname{hyperxmp}, the author specifies values for various predefined -% metadata types and the package formats those values as \acro{XMP} and embeds -% the result within the generated \acro{PDF} file. +% \subsection{Comparisons with similar packages} +% +% \paragraph{\textsf{xmpincl}} +% In short, \pkgname{xmpincl} is more flexible but \pkgname{hyperxmp} is +% easier to use. With \pkgname{xmpincl}, the author manually constructs +% a file of arbitrary \acro{XMP} data and the package merely embeds it +% within the generated \acro{PDF} file. With \pkgname{hyperxmp}, the +% author specifies values for various predefined metadata types and the +% package formats those values as \acro{XMP} and embeds the result +% within the generated \acro{PDF} file. % % \pkgname{xmpincl} can embed \acro{XMP} only when running under \pdfLaTeX\ and % only when in \acro{PDF}-generating mode. \pkgname{hyperxmp} additionally @@ -475,6 +533,96 @@ % \pkgname{hyperxmp}, and use \pkgname{xmpincl} to include the modified % \acro{XMP} code in the \acro{PDF} file. % +% \paragraph{\textsf{pdfx}} +% The main difference between \pkgname{hyperxmp} and \pkgname{pdfx} is +% that \pkgname{hyperxmp} tries to integrate as seamlessly as possible +% into an existing document. It leverages \pkgname{hyperref}'s +% \cs{hypersetup} command and many of \cs{hypersetup}'s options and +% defines its own options in a compatible manner. In contrast, +% \pkgname{pdfx} requires the user to create a separate +% |\jobname.xmpdata| file containing \pkgname{pdfx}-defined commands for +% each metadata element. +% +% \iffalse +%<*listings> +% \fi +\newsavebox{\pdfxbox} +\begin{lrbox}{\pdfxbox} + \begin{lstlisting}[ + language=tex, + columns=fullflexible, + linewidth=14pc, + frame=single, + basicstyle=\footnotesize, + showlines, + morekeywords={\Title,\Author,\Language,\Keywords,\Publisher,\sep} + ] + +\Title{Baking through the ages} +\Author{A. Baker\sep C. Kneader} +\Language{en-GB} +\Keywords{cookies\sep muffins\sep cakes} +\Publisher{Baking International} + + \end{lstlisting} +\end{lrbox} + +\newsavebox{\hyxmpbox} +\begin{lrbox}{\hyxmpbox} + \begin{lstlisting}[ + language=tex, + columns=fullflexible, + linewidth=13pc, + frame=single, + basicstyle=\footnotesize, + morekeywords={\hypersetup} + ] +\hypersetup{% + pdftitle={Baking through the ages}, + pdfauthor={A. Baker, C. Kneader}, + pdflang={en-GB}, + pdfkeywords={cookies, muffins, cakes}, + pdfpublisher={Baking International} +} + \end{lstlisting} +\end{lrbox} +% \iffalse +% +% \fi +% +% Figure~\ref{fig:pdfx-hyxmp} adapts an example appearing in the +% \pkgname{pdfx} manual to \pkgname{hyperxmp}. +% \begin{figure} +% \centering +% \subcaptionbox{\pkgname{pdfx} (separate \texttt{.xmpdata} file) +% \label{fig:ph-pdfx}}{% +% \usebox{\pdfxbox}% +% } +% \hfil +% \subcaptionbox{\pkgname{hyperxmp} (main document) +% \label{fig:ph-hyxmp}}{% +% \usebox{\hyxmpbox}} +% \caption{Comparison of \pkgname{pdfx} and \pkgname{hyperxmp}} +% \label{fig:pdfx-hyxmp} +% \end{figure} +% The two are comparable line-by-line in terms of how one specifies the +% title, author, document language, keywords, and publisher. However, +% \pkgname{hyperxmp} implicitly writes a wealth of additional metadata +% into the \acro{XMP} packet such as the document date, creation date, +% creator tool, file format, \acro{PDF} version, and unique document and +% instance IDs. In fact, if a document omits all of the code shown in +% Figure~\ref{fig:ph-hyxmp}, it will still store the \cs{title} and +% \cs{author} data in the \acro{XMP} packet. +% +% One can therefore summarize the difference between \pkgname{hyperxmp} +% and \pkgname{pdfx} as follows: \pkgname{pdfx} requires the author to +% be fully explicit about the document's metadata while +% \pkgname{hyperxmp} allows some metadata to be specified implicitly, +% automatically inferring it when possible. In general, +% \pkgname{hyperxmp} tries to simplify the author's task as much as +% possible. +% +% % \section{Usage} % % \pkgname{hyperxmp} works by postprocessing some of the package options @@ -540,6 +688,7 @@ % \item \optname{pdfpagerange} % \item \optname{pdfpublication} % \item \optname{pdfpublisher} +% \item \optname{pdfpubstatus} % \item \optname{pdfpubtype} % \item \optname{pdfrendition} % \item \optname{pdfsource} @@ -615,10 +764,7 @@ % the same as the document language (\pkgname{hyperref}'s % \moptname{pdflang} option). If neither \optname{pdfmetalang} nor % \optname{pdflang} is specified, \pkgname{hyperxmp} uses only -% ``|x-default|'' as the metadata language. Note that ``|x-default|'' -% metadata are always included in addition to the specified metadata -% language, as the user reading the document may not have specified a -% language preference. +% ``\xmpterm{x-default}'' as the metadata language. % % \acro{XMP} can include a universally unique identifier (\acro{UUID}) % for each document and for each instance of a given document. By @@ -700,25 +846,47 @@ % \moptname{pdfpubtype} indicates the type of publication in which the % document was published. This should be one of the \acro{PRISM} % aggregation types~\cite{PRISM2012:cont-voc} such as |book|, |journal|, -% |magazine|, |manual|, |report|, or |whitepaper|. For publications in -% journals, magazines, and similar periodicals, a document can specify -% the volume number with \moptname{pdfvolumenum} and the issue number -% within the volume with \moptname{pdfissuenum}. +% |magazine|, |manual|, |report|, or |whitepaper|. +% +% For publications in journals, magazines, and similar periodicals, a +% document can specify the volume number with \moptname{pdfvolumenum} +% and the issue number within the volume with \moptname{pdfissuenum}. % \moptname{pdfpagerange} indicates the page numbers at which the % document appears within the publication. The intention is that this % be a comma-separated list of dash-separated ranges, as in % |pdfpagerange={1,4-5}|. See Note~\ref{note:page-counting} on % page~\pageref{note:page-counting} for advice on how to assign -% \optname{pdfpagerange} semi-automatically. For books, -% \moptname{pdfbookedition} names the edition of the book. This is -% specified as text, not a number. As with \optname{pdfpublication} -% (above), \optname{pdfbookedition} accepts a bracketed language code, -% as in |pdfbookedition={[en]Second| |edition}|. -% -% The number of pages in the published, print version of the document -% can be expressed with \moptname{pdfnumpages}. -% Note~\ref{note:page-counting} on page~\pageref{note:page-counting} -% explains how to automatically assign a value to \optname{pdfnumpages}. +% \optname{pdfpagerange} semi-automatically. A journal article's +% publication status can be indicated with \moptname{pdfpubstatus}. +% This option expects to take one of the values listed in +% Table~\ref{tbl:jav}. See the \acro{NISO}/\acro{ALPSP} Journal Article +% Versions recommendation~\cite{NISO2008:jav} for an explanation of each +% of those values and when to use them. +% +% \begin{table} +% \centering +% \caption{Valid arguments for \optname{pdfpubstatus}} +% \label{tbl:jav} +% \begin{tabular}{@{}>{\ttfamily}ll@{}} +% \toprule +% \multicolumn{1}{@{}l}{Value} & Meaning \\ +% \midrule +% AO & Author's Original \\ +% SMUR & Submitted Manuscript Under Review \\ +% AM & Accepted Manuscript \\ +% P & Proof \\ +% VoR & Version of Record \\ +% CVoR & Corrected Version of Record \\ +% EVoR & Enhanced Version of Record \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% For books, \moptname{pdfbookedition} names the edition of the book. +% This is specified as text, not a number. As with +% \optname{pdfpublication} (above), \optname{pdfbookedition} accepts a +% bracketed language code, as in |pdfbookedition={[en]Second| +% |edition}|. % % \acro{XMP} metadata can include a number of dates (in fact, % timestamps, as they include both date and time components). @@ -780,43 +948,29 @@ % |\documentclass|, in which case \pkgname{hyperxmp} defaults to % |draft|. % -% The \moptname{pdfbytes} option expresses the document's file size in -% bytes. The intention is for this to be used to display an estimate of -% download time to a user or to serve as a quick check on whether a file -% was transmitted correctly between systems. This feature is easiest to -% use in conjunction with \pdfTeX's |\pdffilesize| primitive: -% ``|pdfbytes={\pdffilesize{\jobname.pdf}}|''. Note that this requires -% a second run of |pdftex| because it queries the size of the \acro{PDF} -% file from the \emph{previous} run. -% % \pkgname{hyperxmp} honors \pkgname{hyperref}'s \moptname{pdftrapped} % option. A document can indicate whether it employs % \href{https://en.wikipedia.org/wiki/Trap_(printing)}{color trapping} % by specifying \optname{pdftrapped}=|True| or % \optname{pdftrapped}=|False|. (\optname{pdftrapped}=|Unknown| is also -% allowed.) A current limitation of \pkgname{hyperxmp} is that if a -% value other than |False| is provided, a document will additionally -% need to specify \optname{keeppdfinfo} -% (page~\pageref{page:keeppdfinfo}) to ensure that the \acro{PDF} -% \pdfterm{Info} dictionary specifies the correct trapping value. +% allowed.) % % \moptname{pdfapart} and \moptname{pdfaconformance}, are used in % conjunction with \pkgname{hyperref}'s \optname{pdfa} option to claim a % particular \acro{PDF/A} standard by which the document abides. They % default to \optname{pdfapart}=|1| and \optname{pdfaconformance}=|B|, -% indicating the \PDFstd{A}{1}{b}{} standard. These can be -% changed (with caution) to assert that the document abides by a -% different standard (e.g.,~\PDFstd{A}{2}{u}{}). A document that -% conforms to the \acro{PDF/UA} standard can use \moptname{pdfuapart} to -% indicate the \acro{PDF/UA} conformance level. For example, -% \optname{pdfuapart}=|1| asserts that the document respects -% \PDFstd{UA}{1}{}{}. \moptname{pdfxstandard} indicates -% the particular \acro{PDF/X} standard by which the document abides. -% Unlike \optname{pdfapart} and \optname{pdfaconformance}, which accept a -% number and a letter, respectively, \optname{pdfxstandard} expects a -% textual identification of a standard name. The following are the -% \acro{PDF/X} standard names that are considered acceptable at the time -% of this writing. +% indicating the \PDFstd{A}{1}{b}{} standard. These can be changed +% (with caution) to assert that the document abides by a different +% standard (e.g.,~\PDFstd{A}{2}{u}{}). A document that conforms to the +% \acro{PDF/UA} standard can use \moptname{pdfuapart} to indicate the +% \acro{PDF/UA} conformance level. For example, \optname{pdfuapart}=|1| +% asserts that the document respects \PDFstd{UA}{1}{}{}. +% \moptname{pdfxstandard} indicates the particular \acro{PDF/X} standard +% by which the document abides. Unlike \optname{pdfapart} and +% \optname{pdfaconformance}, which accept a number and a letter, +% respectively, \optname{pdfxstandard} expects a textual identification +% of a standard name. The following are the acceptable \acro{PDF/X} +% standard names as of at the time of this writing. % % ^^A This list needs to be kept up-to-date with the standards checked % ^^A by \@pdfxstandard. @@ -842,16 +996,30 @@ % \PDFstd{X}{4}{p}{}, \PDFstd{X}{5}{n}{}, and \PDFstd{X}{5}{pg}{} % standards has not been tested. % -% A rarely needed option, \moptname{pdfsource}, overrides the name of -% the \LaTeX\ source file. It defaults to |\jobname.tex| but can be -% replaced by any other string. If \optname{pdfsource} is given an -% empty argument, no document source will be specified at all. +% \subsubsection*{Rarely needed options} +% +% \moptname{pdfsource} overrides the name of the \LaTeX\ source file. +% It defaults to |\jobname.tex| but can be replaced by any other string. +% If \optname{pdfsource} is given an empty argument, no document source +% will be specified at all. +% +% The number of pages in the published, print version of the document +% can be expressed with \moptname{pdfnumpages}. This is computed +% automatically when the document is built using either \pdfLaTeX\ or +% \LuaLaTeX\@. +% +% The \moptname{pdfbytes} option expresses the document's file size in +% bytes. The intention is for this to be used to display an estimate of +% download time to a user or to serve as a quick check on whether a file +% was transmitted correctly between systems. \optname{pdfbytes} is +% computed automatically by both \pdfLaTeX\ and \LuaLaTeX, using the +% file size from the previous build of the document. % % \bigskip % -% It is usually more convenient to provide values for the preceding -% options using \pkgname{hyperref}'s |\hypersetup| command than on the -% |\usepackage| command line. See +% It is usually more convenient to provide values for all of the options +% presented in this section using \pkgname{hyperref}'s |\hypersetup| +% command than on the |\usepackage| command line. See % \href{http://mirrors.ctan.org/macros/latex/contrib/hyperref/hyperref.pdf}{the % \pkgname{hyperref} manual} for more information. % @@ -907,15 +1075,14 @@ % pdfvolumenum={322}, % pdfissuenum={6}, % pdfpagerange={132-148}, -% pdfnumpages={17}, % pdfissn={0003-3804}, % pdfeissn={1521-3889}, +% pdfpubstatus={VoR}, % pdflang={en}, % pdfmetalang={en}, % pdfurl={http://www.physik.uni-augsburg.de/annalen/history/einstein-papers/1905_17_132-148.pdf}, % pdfdoi={10.1002/andp.19053220607}, -% pdfidentifier={info:lccn/50013519}, -% pdfbytes={\pdffilesize{\jobname.pdf}} % Requires pdflatex +% pdfidentifier={info:lccn/50013519} % } % \XMPLangAlt{de}{pdftitle={Über einen die Erzeugung und Verwandlung des % Lichtes betreffenden heuristischen Gesichtspunkt}} @@ -937,9 +1104,9 @@ % \begin{itemize} % \item \pdfLaTeX % \item \LuaLaTeX +% \item \XeLaTeX % \item \LaTeX~$+$ Dvipdfm % \item \LaTeX~$+$ \Dvips~$+$ Adobe Acrobat Distiller -% \item \XeLaTeX % \end{itemize} % % \noindent @@ -1162,7 +1329,7 @@ % document's author(s) as specified by |\author{|\dots|}|. % \optname{pdfdate} defaults to the current date and time. % \optname{pdfmetalang} defaults to the same value as \optname{pdflang} -% if non-empty, ``|x-default|'' otherwise. \pkgname{hyperxmp} +% if non-empty, ``\xmpterm{x-default}'' otherwise. \pkgname{hyperxmp} % recognizes some class-specific metadata as well, such as that provided % via the \Koma\ letter classes (e.g.,~\clsname{scrlttr2}) and the % \ACMclass\ article class (\clsname{acmart}). @@ -1248,25 +1415,16 @@ % package in the output file to ensure that any macros used in arguments % to \pkgname{hyperxmp} options produced the expected output. % -% \usagenote{Automatic page counting} +% \usagenote{Semi-automatic page ranges} % \label{note:page-counting} -% Although \optname{pdfnumpages} and \optname{pdfpagerange} are intended -% to refer to pages in the final, published version of a document, it -% would be convenient for them to be generated automatically when -% producing a standalone \acro{PDF} file that is not intended to be -% incorporated into a book, journal, or other publication (or if it is -% known that the pages will not be renumbered for publication). One -% approach is to use the \pkgname{totpages} package to keep track of the -% number of pages. -% -% \begin{verbatim} -% \hypersetup{% -% pdfnumpages={\ref*{TotPages}} -% } -% \end{verbatim} -% -% \pkgname{totpages} can likewise help generate \optname{pdfpagerange}. -% For documents numbered from~1 to~$n$, a simple +% Although \optname{pdfpagerange} is intended to refer to pages in the +% final, published version of a document, it would be convenient for +% them to be generated automatically when producing a standalone +% \acro{PDF} file that is not intended to be incorporated into a book, +% journal, or other publication (or if it is known that the pages will +% not be renumbered for publication). One approach is to use the +% \pkgname{totpages} package help generate \optname{pdfpagerange}. For +% documents numbered from~1 to~$n$, a simple % % \begin{verbatim} % \hypersetup{% @@ -1294,21 +1452,20 @@ % % I don't know how unnumbered pages (e.g.,~blank pages and the title % page) are supposed to be handled. I suppose blank pages can be -% omitted from \optname{pdfpagerange}, and title page can be either -% omitted or listed as |title|, for example. +% omitted from \optname{pdfpagerange}, and the title page can be either +% omitted or listed as \texttt{title}, for example. % % It appears that at least with version~2.00 of \pkgname{totpages}, the % |TotPages| label is not defined until after the |\begin{document}|. % Consequently, using |TotPages| within a \cs{hypersetup} invocation in % the document's preamble will produce ``|??|'' as the page count in the % \acro{XMP} packet. The solution is either to assign -% \optname{pdfnumpages} and \optname{pdfpagerange} after the -% |\begin{document}| or to ask \LaTeX\ to do that on your behalf: +% \optname{pdfpagerange} after the |\begin{document}| or to ask +% \LaTeX\ to do that on your behalf: % % \begin{verbatim} % \AtBeginDocument{% % \hypersetup{% -% pdfnumpages={\ref*{TotPages}}, % pdfpagerange={1-\ref*{TotPages}} % }% % } @@ -1342,6 +1499,17 @@ % \input{einstein-xmp} % % \begin{thebibliography}{99} +% \bibitem{NISO2008:jav} +% Beverley Acreman, Claire Bird, Catherine Jones, Peter McCracken, Cliff Morgan, +% John Ober, Evan Owens, T.~Scott Plutchak, Bernie Rous, and Andrew Wray. +% \newblock {J}ournal {A}rticle {V}ersions ({JAV}): Recommendations of the +% {NISO}/{ALPSP} {JAV} {T}echnical {W}orking {G}roup. +% \newblock Recommended practice, National Information Standards Organization, +% Baltimore, Maryland, USA, April 2008. +% \newblock ISBN~\mbox{978-1-880124-79-6}. +% \newblock Available from +% \url{https://www.niso.org/sites/default/files/2017-08/RP-8-2008.pdf}. +% % \bibitem{Adobe2010:pdfmark} % Adobe Systems, Inc., San Jose, California. % \newblock \emph{{A}dobe {A}crobat~{X} {SDK} Help, pdfmark Reference}. @@ -1491,6 +1659,70 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\hyxmp@set@jobname} +% Given an expanded \cs{jobname} followed by \cs{relax}, invoke the +% \cs{hyxmp@set@jobname@dbl} macro if the job name is surrounded by +% double quotes and the \cs{hyxmp@set@jobname@plain} macro otherwise. +% \begin{macrocode} +\def\hyxmp@set@jobname#1\relax{% + \@ifnextchar"{\hyxmp@set@jobname@dbl}{\hyxmp@set@jobname@plain}#1\relax +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@set@jobname@dbl} +% \begin{macro}{\hyxmp@jobname} +% Set \cs{hyxmp@jobname} to to |#1|, discarding the surrounding double +% quotes. +% \begin{macrocode} +\def\hyxmp@set@jobname@dbl"#1"\relax{\xdef\hyxmp@jobname{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\hyxmp@set@jobname@plain} +% \begin{macro}{\hyxmp@jobname} +% Set \cs{hyxmp@jobname} to to |#1|. +% \begin{macrocode} +\def\hyxmp@set@jobname@plain#1\relax{\xdef\hyxmp@jobname{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% Define \cs{hyxmp@jobname} as a sanitized version of \cs{jobname}. The +% problem with using \cs{jobname} directly is that it surrounds the +% filename with double quotes if it contains a space character. For +% example, a source file named \texttt{my-file.tex} results in a +% \cs{jobname} of ``\texttt{my-file}'', but a source file named +% \texttt{my file.tex} results in a \cs{jobname} of ``|"my file"|''. +% Trying to access |"my file".log| (as is done on +% page~\pageref{page:jobname-log}) will fail because the filename does +% not in fact contain literal double quotes. +% \changes{v5.5}{2020/07/28}{Correctly handle source files with spaces +% in their name. Thanks to Peter Dyballa for the bug report} +% \begin{macrocode} +\expandafter\hyxmp@set@jobname\jobname\relax +% \end{macrocode} +% +% \begin{macro}{\hyxmp@aep@toks} +% In order for \pkgname{hyperxmp} to be loaded safely during +% \cs{AtEndPreamble} we need to ensure that we perform no +% \cs{AtEndPreamble} actions until all top-level macro definitions have +% been made. The most straightforward approach would be to move all of +% \pkgname{hyperxmp}'s \cs{AtEndPreamble} stanzas to the end of the +% package. However, this degrades readability of the source code. For +% instance, an \cs{AtEndPreamble} stanza related to integration with +% \pkgname{hyperref} could no longer appear in the ``Integration with +% \pkgname{hyperref}'' section (Section~\ref{sec:hyperref-int}). Hence, +% we instead store in a token list, \cs{hyxmp@aep@toks}, each +% \cs{AtEndPreamble} stanza as we encounter it. This token list is +% evaluated as one of the package's final actions +% (Section~\ref{sec:clean-up}). +% \begin{macrocode} +\newtoks{\hyxmp@aep@toks} +% \end{macrocode} +% \end{macro} +% % % \subsection{Integration with \textsf{hyperref}} % \label{sec:hyperref-int} @@ -1531,6 +1763,15 @@ \RequirePackage{ifthen} % \end{macrocode} % +% There are a few places where \pkgname{hyperxmp} can take advantage of +% \LuaTeX\ features. To simplify the use of \LuaTeX\ we load the +% \pkgname{luacode} package. +% \begin{macrocode} +\ifLuaTeX + \RequirePackage{luacode} +\fi +% \end{macrocode} +% % \begin{macro}{\@ifmtargexp} % \begin{macro}{\@ifnotmtargexp} % |\@ifmtarg| and |\@ifnotmtarg| do not expand their first argument. @@ -1824,7 +2065,7 @@ % \changes{v3.3}{2017/07/16}{Added this macro and the corresponding % \protect\optname{pdfsource} option, at Niklas Beisert's request} % \begin{macrocode} -\edef\@pdfsource{\jobname.tex} +\edef\@pdfsource{\hyxmp@jobname.tex} \define@key{Hyp}{pdfsource}{\hyxmp@pdfstringdef\@pdfsource{#1}} % \end{macrocode} % \end{macro} @@ -2030,6 +2271,14 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@pdfpubstatus} +% Prepare to store the document's journal article version. +% \begin{macrocode} +\def\@pdfpubstatus{} +\define@key{Hyp}{pdfpubstatus}{\hyxmp@pdfstringdef\@pdfpubstatus{#1}} +% \end{macrocode} +% \end{macro} +% % The following eight macros---|\@pdfcontactaddress|, % |\@pdfcontactcity|, |\@pdfcontactregion|, |\@pdfcontactpostcode|, % |\@pdfcontactcountry|, |\@pdfcontactphone|, |\@pdfcontactemail|, and @@ -2364,23 +2613,27 @@ % Assume that if the document loaded either \pkgname{babel} or % \pkgname{polyglossia} it will eventually define one or more languages % that \pkgname{hyperxmp} can list within a \xmpprop{dc:language} -% element. +% element. As explained in Section~\ref{sec:initial-prep}, we defer the +% invocation of \cs{AtEndPreamble} to the end of the file. % \begin{macrocode} \edef\hyxmp@concated@metadata{} -\AtEndPreamble{% - \@ifpackageloaded{babel}{% - \edef\hyxmp@concated@metadata{babel}% - }{% - \@ifpackageloaded{polyglossia}{% - \edef\hyxmp@concated@metadata{polyglossia}% +\expandafter\hyxmp@aep@toks\expandafter=\expandafter{% + \the\hyxmp@aep@toks + \AtEndPreamble{% + \@ifpackageloaded{babel}{% + \edef\hyxmp@concated@metadata{babel}% }{% + \@ifpackageloaded{polyglossia}{% + \edef\hyxmp@concated@metadata{polyglossia}% + }{% + }% }% }% } % \end{macrocode} % \end{macro} % -% \begin{macro}{\hyxmp@find@metadata} +% \begin{macro}{\hyxmp@warn@if@no@metadata} % \begin{macro}{\hyxmp@concated@metadata} % Issue a warning message if the author failed to specify any metadata % at all. This excludes metadata that is included automatically such as @@ -2389,7 +2642,7 @@ % with other information. We also don't examine |\@pdfapart| or % |\@pdfaconformance| because those have nonempty default values. % \begin{macrocode} -\newcommand*{\hyxmp@find@metadata}{% +\newcommand*{\hyxmp@warn@if@no@metadata}{% \edef\hyxmp@concated@metadata{% \hyxmp@concated@metadata \@baseurl @@ -2434,7 +2687,7 @@ }% \ifx\hyxmp@concated@metadata\@empty \PackageWarningNoLine{hyperxmp}{% - \jobname.tex did not specify any metadata to\MessageBreak + \hyxmp@jobname.tex did not specify any metadata to\MessageBreak include in the XMP packet.\space\space Please see the\MessageBreak hyperxmp documentation for instructions on how to\MessageBreak provide metadata values to hyperxmp}% @@ -2496,54 +2749,25 @@ % \end{macro} % \end{macro} % -% Rather than load \pkgname{hyperref} ourself we let the author do it -% then verify he actually did. This approach gives the author the -% flexibility to load \pkgname{hyperxmp} and \pkgname{hyperref} in -% either order and to call |\hypersetup| anywhere in the document's -% preamble, not just before \pkgname{hyperxmp} is loaded. -% \begin{macrocode} -\AtEndPreamble{% - \@ifpackageloaded{hyperref}{% -% \end{macrocode} -% If \cs{@pdflang} is not set, see if we can detect the document -% language via either the \pkgname{babel} or \pkgname{polyglossia} -% packages. +% Right before we reach the |\begin{document}| we check if +% \pkgname{hyperref} was loaded. In normal usage, the document will +% already have done a |\usepackage{hyperref}| because otherwise, +% \cs{hypersetup} will not have been defined, and only a limited amount +% of metadata will be included. However, in case the author is relying +% exclusively on \pkgname{hyperxmp}'s automatically detected metadata, +% we'll need to load \pkgname{hyperref} now. As explained in +% Section~\ref{sec:initial-prep}, we defer the invocation of +% \cs{AtEndPreamble} to the end of the file. +% \changes{v5.5}{2020/06/24}{Load \protect\pkgname{hyperref} automatically +% if the document does not do so explicitly, as requested by Robin Schwab} % \begin{macrocode} - \@if@def@and@nonempty{@pdflang}{% - }{% - \hyxmp@detect@langs - }% -% \end{macrocode} -% Fill in any missing metadata we can using values provided by the author -% via mechanisms other than the \cs{hypersetup} command. -% \begin{macrocode} - \hyxmp@auto@assign@data -% \end{macrocode} -% Most \acro{PDF} standards dictate that if the same metadata appear in -% both the \acro{XMP} packet and the \acro{PDF} \pdfterm{Info} -% dictionary, the metadata must match. This requirement poses a problem -% for a user-unspecified \optname{pdfcreationdate} in the context of -% \XeLaTeX\@. In this case we explicitly define |\@pdfcreationdate| as -% |\hyxmp@today@pdf| to prevent the \cmdname{xdvipdfmx} back-end -% processor from detecting a missing \pdfterm{CreationDate} in the -% \pdfterm{Info} dictionary and adding its own---typically a few seconds -% after \pkgname{hyperxmp} has constructed an \xmpprop{xmp:CreateDate} -% for the \acro{XMP} metadata and leading to a metadata mismatch. -% \begin{macrocode} - \@ifundefined{XeTeXversion}{}{% - \@ifmtargexp{\@pdfcreationdate}{% - \let\@pdfcreationdate=\hyxmp@today@pdf - }% - {}% - }% -% \end{macrocode} -% If the document claims to comply with one or more \acro{PDF} -% standards, check that all of the requisite metadata are present. -% \begin{macrocode} - \hyxmp@check@standards +\expandafter\hyxmp@aep@toks\expandafter=\expandafter{% + \the\hyxmp@aep@toks + \AtEndPreamble{% + \RequirePackage{hyperref}% % \end{macrocode} % Older versions of \pkgname{hyperref} write the \pdfterm{Info} -% dictionary to the \acro{PDF} file at the end of the document. New +% dictionary to the \acro{PDF} file at the end of the document. Newer % versions of \pkgname{hyperref} write the \pdfterm{Info} dictionary to % the \acro{PDF} file at the \emph{beginning} of the document. For % compatibility with both old and new \pkgname{hyperref} implementations @@ -2556,39 +2780,44 @@ % \begin{macrocode} \hyxmp@no@info@lists % \end{macrocode} -% We wait until the end of the document to construct the \acro{XMP} -% packet and write it to the \acro{PDF} document catalog. This gives -% the author ample opportunity to provide metadata to \pkgname{hyperref} -% and thereby \pkgname{hyperxmp}. -% \begin{macrocode} - \hyxmp@at@end{% - \hyxmp@find@metadata - \hyxmp@embed@packet - }% - }{% - \PackageWarningNoLine{hyperxmp}{% - \jobname.tex failed to include a\MessageBreak - \string\usepackage\string{hyperref\string} - in the preamble.\MessageBreak - Consequently, all hyperxmp functionality will be\MessageBreak - disabled}% +% If \optname{pdftitle} is undefined but the author invoked \cs{title}, +% we copy the latter to the former. This addresses two problems: +% (1)~handling \LaTeX\ classes in which \cs{maketitle} clears \cs{title} +% and (2)~ensuring that \pkgname{hyperref} writes the same title to the +% \acro{PDF} \pdfterm{Info} dictionary that \pkgname{hyperxmp} writes to +% the \acro{XMP} packet. We do likewise for \cs{author}~$\rightarrow$ +% \optname{pdfauthor}. +% +% One tricky bit is that the standard \LaTeX\ classes do not define +% \cs{@title} and \cs{@author} as empty strings but rather as calls to +% \cs{@latex@warning@no@line} that complain about a missing +% title/author. Hence, we can't simply test if the title and author are +% empty because they're not. Instead, we first locally redefine +% \cs{@latex@warning@no@line} to discard its argument then test if any +% text remains. +% \changes{v5.5}{2020/07/24}{Copy \protect\cs{title} to +% \protect\optname{pdftitle} and \protect\cs{author} to +% \protect\optname{pdfauthor} at the start of the document to improve +% consistency between \protect\acro{XMP} and \protect\acro{PDF} metadata} +% \begin{macrocode} + \begingroup + \let\@latex@warning@no@line=\@gobble + \hyxmp@use@first@valid{pdftitle}{\@pdftitle}{% + \scr@subject@var,% + \@title + }% + \hyxmp@use@first@valid{pdfauthor}{\@pdfauthor}{% + \scr@fromname@var,% + \@author + }% + \endgroup }% } % \end{macrocode} % -% A number of classes either require or recommend that authors declare -% various class-specific metadata \emph{after} the |\begin{document}|. -% So where do we invoke \cs{hyxmp@auto@assign@data}? On one hand, we -% want to invoke it before the |\begin{document}| because this may -% obviate \pkgname{hyperxmp}'s ``\meta{job name} did not specify any -% metadata'' warning message. On the other hand, we want to invoke it -% after the |\begin{document}| so it picks up metadata not specified in -% the preamble. Our solution is to invoke \cs{hyxmp@auto@assign@data} -% twice: both before the |\begin{document}| and at the |\end{document}|. -% We additionally identify here the natural language(s) in use because -% these aren't known until the end of the document when provided by -% \pkgname{babel} or \pkgname{polyglossia}. Also, \pkgname{hyperref} -% forbids changes to \optname{pdflang} past the |\begin{document}|. +% When we reach the |\end{document}| we need to gather up the metadata +% specified explicitly by the user, infer additional metadata where +% possible, and write the \acro{XMP} packet to the \acro{PDF} file. % \changes{v1.3}{2011/04/25}{Introduced the \protect\optname{pdfmetalang} % package option, which enables an author to specify the language in which he % wrote the document's metadata} @@ -2596,24 +2825,32 @@ % Oberdiek to properly encode \cs{@pdfmetalang}} % \changes{v3.3}{2017/07/21}{Don't overwrite an existing % \protect\optname{pdfmetalang} with \protect\optname{pdflang} or -% \protect\texttt{x-default}. This addresses a bug report by Niklas +% \protect\xmpterm{x-default}. This addresses a bug report by Niklas % Beisert} % \changes{v5.4}{2020/06/18}{Moved the automatic assignment of % \protect\cs{@pdflang} and \protect\cs{@pdfmetalang} from % \protect\cs{hyxmp@auto@assign@data} to within a call to % \protect\cs{hyxmp@at@end}} +% \changes{v5.5}{2020/07/21}{Move most of the \protect\cs{AtEndPreamble} +% code to \protect\cs{hyxmp@at@end}} % \begin{macrocode} \hyxmp@at@end{% - \hyxmp@set@dc@lang - \ifx\@pdfmetalang\@empty - \ifx\@pdflang\@empty - \let\@pdfmetalang=\hyxmp@x@default - \else - \edef\@pdfmetalang{\@pdflang}% - \fi - \fi - \hyxmp@xmlify\@pdfmetalang +% \end{macrocode} +% Fill in any missing metadata we can using values provided by the author +% via mechanisms other than the \cs{hypersetup} command. +% \begin{macrocode} \hyxmp@auto@assign@data +% \end{macrocode} +% If the document claims to comply with one or more \acro{PDF} +% standards, check that all of the requisite metadata are present. +% \begin{macrocode} + \hyxmp@check@standards +% \end{macrocode} +% We can finally construct the \acro{XMP} packet and write it to the +% \acro{PDF} document catalog. +% \begin{macrocode} + \hyxmp@warn@if@no@metadata + \hyxmp@embed@packet } % \end{macrocode} % @@ -2638,23 +2875,29 @@ % % \begin{macro}{\hyxmp@set@koma@phones} % \changes{v5.3}{2020/06/07}{Added this macro} +% \changes{v5.5}{2020/07/08}{Support hyperlinks and other markup in +% \protect\texttt{frommobilephone} and \protect\texttt{fromphone}, +% as requested by Robin Schwab} % \begin{macro}{\hyxmp@koma@phones} % Define \cs{hyxmp@koma@phones} as a comma-separated list of the phone % numbers provided to a \Koma\ letter class (mobile and landline). % \begin{macrocode} \newcommand*{\hyxmp@set@koma@phones}{% - \@if@def@and@nonempty{scr@frommobilephone@var}{% - \@if@def@and@nonempty{scr@fromphone@var}{% - \edef\hyxmp@koma@phones{\scr@frommobilephone@var,\scr@fromphone@var}% - }{% - \edef\hyxmp@koma@phones{\scr@frommobilephone@var}% - }% - }{% - \@if@def@and@nonempty{scr@fromphone@var}{% - \edef\hyxmp@koma@phones{\scr@fromphone@var}% + \begingroup + \Hy@unicodefalse + \@if@def@and@nonempty{scr@frommobilephone@var}{% + \@if@def@and@nonempty{scr@fromphone@var}{% + \hyxmp@pdfstringdef\hyxmp@koma@phones{\scr@frommobilephone@var,\scr@fromphone@var}% + }{% + \hyxmp@pdfstringdef\hyxmp@koma@phones{\scr@frommobilephone@var}% + }% }{% + \@if@def@and@nonempty{scr@fromphone@var}{% + \hyxmp@pdfstringdef\hyxmp@koma@phones{\scr@fromphone@var}% + }{% + }% }% - }% + \endgroup } % \end{macrocode} % \end{macro} @@ -2709,9 +2952,28 @@ % \begin{macrocode} \newcommand*{\hyxmp@auto@assign@data}{% % \end{macrocode} -% If the author left \optname{pdftitle} blank but specified |\title|, -% use the title for \optname{pdftitle}. Do likewise for various other -% metadata: identify author-provided information that can be co-opted +% If \cs{@pdflang} is not set, see if we can detect the document +% language via either the \pkgname{babel} or \pkgname{polyglossia} +% packages. +% \begin{macrocode} + \@if@def@and@nonempty{@pdflang}{% + \let\hyxmp@dc@lang=\@pdflang + }{% + \hyxmp@detect@langs + }% +% \end{macrocode} +% Replace an empty \cs{@pdfmetalang}. If \cs{@pdflang} is defined, use +% that as the metadata language. Otherwise, use \xmpterm{x-default}. +% \begin{macrocode} + \ifx\@pdfmetalang\@empty + \ifx\@pdflang\@empty + \let\@pdfmetalang=\hyxmp@x@default + \else + \edef\@pdfmetalang{\@pdflang}% + \fi + \fi +% \end{macrocode} +% Identify various author-provided information that can be co-opted % for use as \acro{XMP} metadata. % \changes{v2.7}{2016/02/01}{Automatically use \cs{title} and \cs{author} % if \protect\optname{pdftitle} and \protect\optname{pdfauthor} are left @@ -2719,15 +2981,14 @@ % \changes{v5.3}{2020/05/29}{Consider other author-provided sources of % metadata. Thanks to Robin Schwab for proposing that % \protect\pkgname{hyperxmp} use the \Koma\ letter classes's metadata} +% \changes{v5.5}{2020/07/24}{Moved the language-detection and +% \protect\XeTeX\ date-detection code here from the +% \protect\cs{hyxmp@at@end} block} +% \changes{v5.5}{2020/07/24}{Use \protect\LuaTeX\ mechanisms, when available, +% to automatically compute the page count} +% \changes{v5.5}{2020/07/24}{Moved title and author autodetection to the +% \protect\cs{AtEndPreamble}} % \begin{macrocode} - \hyxmp@use@first@valid{pdftitle}{\@pdftitle}{% - \scr@subject@var,% - \@title - }% - \hyxmp@use@first@valid{pdfauthor}{\@pdfauthor}{% - \scr@fromname@var,% - \@author - }% \hyxmp@use@first@valid{pdfcontactemail}{\@pdfcontactemail}{% \scr@fromemail@var }% @@ -2752,6 +3013,98 @@ % redefined to do nothing. % \begin{macrocode} \hyxmp@parse@acmart +% \end{macrocode} +% Most \acro{PDF} standards dictate that if the same metadata appear in +% both the \acro{XMP} packet and the \acro{PDF} \pdfterm{Info} +% dictionary, the metadata must match. This requirement poses a problem +% for a user-unspecified \optname{pdfcreationdate} in the context of +% \XeLaTeX\@. In this case we explicitly define |\@pdfcreationdate| as +% |\hyxmp@today@pdf| to prevent the \cmdname{xdvipdfmx} back-end +% processor from detecting a missing \pdfterm{CreationDate} in the +% \pdfterm{Info} dictionary and adding its own---typically a few seconds +% after \pkgname{hyperxmp} has constructed an \xmpprop{xmp:CreateDate} +% for the \acro{XMP} metadata and leading to a metadata mismatch. +% \begin{macrocode} + \@ifundefined{XeTeXversion}{}{% + \@ifmtargexp{\@pdfcreationdate}{% + \let\@pdfcreationdate=\hyxmp@today@pdf + }% + {}% + }% +% \end{macrocode} +% Query the document currently being built for page and byte counts. +% \begin{macrocode} + \hyxmp@query@self +} +% \end{macrocode} +% \end{macro} +% +% \pkgname{hyperxmp} can directly query the page count using +% \LuaTeX\ features. When any other \TeX\ engine is used, +% \pkgname{hyperxmp} employs the \pkgname{totpages} package to help +% tally the total number of pages. +% \begin{macrocode} +\ifLuaTeX +\else + \RequirePackage{totpages} +\fi +% \end{macrocode} +% +% Determine the size of the output file from the \emph{previous} run of +% \LuaLaTeX\ or \pdfLaTeX\@. This action has to be performed before the +% |\begin{document}| because at that point the size of the output file +% is reset to zero. We use |\jobname.pdf| as the name of the output +% file even in the \LuaLaTeX\ case because |status.output_file_name| is +% not defined at this point. +% \begin{macrocode} +\ifLuaTeX + \edef\hyxmp@prev@pdf@size{% + \luadirect{% +local nbytes = lfs.attributes("\hyxmp@jobname.pdf", "size") +if nbytes then + tex.write(nbytes) +end + }% + }% +\else + \ifPDFTeX + \edef\hyxmp@prev@pdf@size{\pdffilesize{\hyxmp@jobname.pdf}}% + \fi +\fi +% \end{macrocode} +% +% \begin{macro}{\hyxmp@query@self} +% Query the document currently being built to acquire page and byte counts. +% \changes{v5.5}{2020/07/25}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@query@self}{% +% \end{macrocode} +% \LuaTeX\ exposes via \texttt{status.total\_pages} the number of pages +% written. We use this mechanism when available to assign +% \cs{@pdfnumpages}. To finalize the page count we first issue a +% \cs{clearpage}. +% \begin{macrocode} + \ifLuaTeX + \@if@def@and@nonempty{@pdfnumpages}{% + }{% + \clearpage + \xdef\@pdfnumpages{\luadirect{tex.print(status.total_pages)}}% + }% + \else +% \end{macrocode} +% Without \LuaTeX\ we rely on the \pkgname{totpages} package to help +% count the number of pages. This may require an additional run of +% \LaTeX, but the user will be notified in that case. +% \begin{macrocode} + \pdfstringdef\@pdfnumpages{\ref*{TotPages}}% + \fi +% \end{macrocode} +% If \optname{pdfbytes} hasn't been set, set it to the output file's size +% from the previous run. +% \begin{macrocode} + \hyxmp@use@first@valid{pdfbytes}{\@pdfbytes}{% + \hyxmp@prev@pdf@size + }% } % \end{macrocode} % \end{macro} @@ -2979,39 +3332,25 @@ \@ifclassloaded{acmart}{}{\let\hyxmp@parse@acmart=\relax} % \end{macrocode} % -% \begin{macro}{\hyxmp@set@dc@lang} % \begin{macro}{\hyxmp@dc@lang} -% \cs{@pdflang} is used in both the \acro{PDF} document catalog (the -% \pdfterm{Lang} key, written to the \acro{PDF} file by -% \pkgname{hyperref}) and in the Dublin Core \xmpprop{dc:language} tag -% (Section~\ref{sec:dublin-core}). Normally, these are the same. -% However, \pdfterm{Lang} accepts only a single language while -% \xmpprop{dc:language} accepts multiple languages. If the document -% loads either \pkgname{babel} or \pkgname{polyglossia} and does not -% specify \optname{pdflang} in \cs{hypersetup}, \cs{hyxmp@set@dc@lang} -% is redefined below (in \cs{hyxmp@detect@langs}) to set -% \cs{hyxmp@dc@lang} to \pkgname{babel}\slash\pkgname{polyglossia}'s -% list of used languages (once this is known). Otherwise, -% \cs{hyxmp@set@dc@lang} assigns the language specified by -% \optname{pdflang} (if any) to \cs{hyxmp@dc@lang}. +% \cs{hyxmp@dc@lang} is a comma-separated list of all languages used in +% the document. % \begin{macrocode} -\newcommand*{\hyxmp@set@dc@lang}{% - \let\hyxmp@dc@lang=\@pdflang -} +\let\hyxmp@dc@lang=\@empty % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}{\hyxmp@detect@langs} % If \optname{pdflang} was not specified, try to determine the document % language(s) using either \pkgname{babel}'s or \pkgname{polyglossia}'s -% definitions. If so, we redefine \cs{hyxmp@set@dc@lang} as a -% comma-separate list of languages used in the document. +% definitions. % \changes{v5.3}{2020/06/08}{Acquire the default language from the % \protect\pkgname{polyglossia} package, if loaded. Thanks to % Robin Schwab for bringing that package to my attention} % \changes{v5.4}{2020/06/16}{Refactored language detection into a -% separate command} +% separate command} +% \changes{v5.5}{2020/07/21}{Set the language(s) immediately instead of +% deferring them to \protect\cs{hyxmp@set@dc@lang}} % \begin{macrocode} \newcommand*{\hyxmp@detect@langs}{% \@ifundefined{mainbcp47id}{% @@ -3034,103 +3373,45 @@ \let\@pdflang=\@empty }{% % \end{macrocode} -% Use \pkgname{babel}'s \cs{LocaleForEach} and \cs{getlocaleproperty} to -% construct a comma-separate list of all document languages. We also -% set \cs{@pdflang} within \cs{hyxmp@set@dc@lang}. -% (\cs{hyxmp@detect@langs} should only be called if \cs{@pdflang} is -% empty.) Unlike \pkgname{polyglossia}, \pkgname{babel} does not -% provide information about the main language until after the -% |\begin{document}| so we have to wait until \cs{hyxmp@set@dc@lang} is -% called to set it. % \changes{v5.4}{2020/06/17}{Added support for \protect\pkgname{babel}} +% \changes{v5.5}{2020/07/16}{Store the main language in \protect\cs{@pdflang}. +% Thanks to Javier Bezos for his help with the \protect\pkgname{hyperxmp} +% code and for modifying \protect\pkgname{babel} for +% \protect\pkgname{hyperxmp}'s benefit} +% \begin{macro}{\hyxmp@dc@lang} +% \begin{macro}{\hyxmp@lang@tag} +% \begin{macro}{\hyxmp@lang@name} +% \begin{macro}{\@pdflang} +% Use \pkgname{babel}'s \cs{LocaleForEach} and \cs{getlocaleproperty} to +% set \cs{@pdflang} to the document's main language and +% \cs{hyxmp@dc@lang} to a comma-separated list of all languages used. % \begin{macrocode} \BabelEnsureInfo - \renewcommand*{\hyxmp@set@dc@lang}{% - \getlocaleproperty\@pdflang{\bbl@main@language}{identification/tag.bcp47}% - \hyxmp@write@pdflang - \let\hyxmp@dc@lang=\relax - \LocaleForEach{% - \getlocaleproperty\hyxmp@lang@tag{####1}{identification/tag.bcp47}% - \ifx\hyxmp@dc@lang\relax - \edef\hyxmp@dc@lang{\hyxmp@lang@tag}% - \else - \edef\hyxmp@dc@lang{\hyxmp@dc@lang,\hyxmp@lang@tag}% - \fi - }% + \LocaleForEach{% + \getlocaleproperty\hyxmp@lang@tag{##1}{identification/tag.bcp47}% + \ifx\hyxmp@dc@lang\@empty + \xdef\hyxmp@dc@lang{\hyxmp@lang@tag}% + \else + \xdef\hyxmp@dc@lang{\hyxmp@dc@lang,\hyxmp@lang@tag}% + \fi + \def\hyxmp@lang@name{##1}% + \ifx\hyxmp@lang@name\bbl@main@language + \edef\@pdflang{\hyxmp@lang@tag}% + \fi }% }% }{% % \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % Use \pkgname{polyglossia}'s \cs{mainbcp47id} as the document's main % language and its \cs{xpg@bcp@loaded} as a comma-separated list of all % document languages. % \begin{macrocode} \xdef\@pdflang{\csname mainbcp47id\endcsname}% - \renewcommand*{\hyxmp@set@dc@lang}{% - \edef\hyxmp@dc@lang{\xpg@bcp@loaded}% - }% - }% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@write@pdflang} -% Here's a conundrum: \pkgname{babel} doesn't provide access to -% information on the document's main language until after the -% |\begin{document}|. However, \pkgname{hyperref} allows -% \optname{pdflang} to be set only \emph{before} the |\begin{document}|. -% So what do we do? -% -% Note that the underlying \cs{@pdflang} macro serves two purposes: -% \pkgname{hyperref} uses it to set the \pdfterm{Lang} entry in the -% \acro{PDF} document catalog, and \pkgname{hyperxmp} uses it as the -% default metadata language. The latter is used in \xmpprop{dc:title} -% and other \acro{XMP} properties that can include per-language -% variants. We set \cs{@pdflang} once we have the main-language -% information from \pkgname{babel}. As this is too late for -% \pkgname{hyperref}, we bypass \pkgname{hyperref} and manually write -% the \pdfterm{Lang} key into the document catalog. This is a bit -% kludgy, but we do leverage as much of \pkgname{hyperref}'s -% infrastructure as possible to increase \cs{hyxmp@write@pdflang}'s -% robustness. -% \changes{v5.4}{2020/06/19}{Added this macro} -% \begin{macrocode} -\newcommand*{\hyxmp@write@pdflang}{% - \@ifundefined{pdfmark}{% - \@ifundefined{@pdfm@mark}{% - \@ifundefined{pdfcatalog}{% -% \end{macrocode} -% We don't recognize the \tex\ engine or \acro{PDF} generator. (This is -% unexpected.) We therefore issue a warning message and take no further -% action. -% \begin{macrocode} - \PackageWarning{hyperxmp}{Unknown PDF generator; not setting the language (\@pdflang) in the PDF catalog}% - }{% -% \end{macrocode} -% We're running either \pdfTeX\ or \LuaTeX\@. (\pkgname{hyperref} -% defines \cs{pdfcatalog} in the latter case.) -% \begin{macrocode} - \pdfcatalog{/Lang (\@pdflang)}% - }% - }{% -% \end{macrocode} -% We're running either \XeTeX\ or \tex~+ -% \texttt{dvipdfm}.\SortIndex{dvipdfm}{\texttt{dvipdfm}}. -% \begin{macrocode} - \@pdfm@mark{docview << /Lang (\@pdflang) >>}% - }% -}{% -% \end{macrocode} -% We're running either \tex~+ \Dvips~+ Adobe Acrobat Distiller (or other -% converter from PostScript to \acro{PDF}). -% \begin{macrocode} - \pdfmark{% - pdfmark=/PUT,Raw={% - \string{Catalog\string} << - /Lang (\@pdflang) - >> - }% - }% + \edef\hyxmp@dc@lang{\xpg@bcp@loaded}% }% } % \end{macrocode} @@ -3659,6 +3940,7 @@ % Case 3: |\filemoddate| is defined (\XeLaTeX). % In this case, we treat the timestamp of the job's |.log| file as the % current date/time. +% \label{page:jobname-log} % \changes{v5.1}{2020/04/08}{Don't rely on % \string\cs{jobname}\string\texttt{.aux} existing to query the % current time under \string\XeLaTeX\string\@. Instead, use @@ -3666,7 +3948,7 @@ % for the bug report and for her suggestion to use the log file.} % \begin{macrocode} \hyxmp@try@today{filemoddate}{% - \edef\hyxmp@today@xmp{\filemoddate{\jobname.log}}% + \edef\hyxmp@today@xmp{\filemoddate{\hyxmp@jobname.log}}% \edef\next{% \edef\noexpand\hyxmp@today@xmp{\noexpand\hyxmp@as@xmp@date{\hyxmp@today@xmp}}% }% @@ -4244,7 +4526,7 @@ % and typesets the text within the \acro{XML} tag. % \begin{macrocode} \newcommand*{\hyxmp@add@simple@lang@i}{% - \@ifnextchar[\hyxmp@add@simple@lang@ii{\hyxmp@add@simple@lang@ii[]}% + \@ifnextchar[\hyxmp@add@simple@lang@ii{\hyxmp@add@simple@lang@ii[\@pdfmetalang]}% } % \end{macrocode} % \end{macro} @@ -4302,9 +4584,10 @@ ______<#3 xml:lang="#1">\hyxmp@xmlified^^J% % \xmpprop{dc:description}, and \xmpprop{dc:rights} (and others? Let me % know.)---can be expressed in multiple languages. The same text is % used for both language \optname{pdfmetalang} (default: -% \optname{pdflang}) and language ``|x-default|''. To express the same -% metadata in multiple languages, we provide an |\XMPLangAlt| macro to -% construct a list of alternative forms for a piece of metadata. +% \optname{pdflang}) and language ``\xmpterm{x-default}''. To express +% the same metadata in multiple languages, we provide an |\XMPLangAlt| +% macro to construct a list of alternative forms for a piece of +% metadata. % % \begin{macro}{\hyxmp@alt@title} % \begin{macro}{\hyxmp@alt@description} @@ -4572,7 +4855,7 @@ ______<#3 xml:lang="#1">\hyxmp@xmlified^^J% % Bug reported by Ga\"etan Leurent} % \begin{macrocode} \newcommand*{\hyxmp@def@DocumentID}{% - \edef\hyxmp@seed@string{\jobname:\@pdftitle:\@pdfauthor:}% + \edef\hyxmp@seed@string{\hyxmp@jobname:\@pdftitle:\@pdfauthor:}% \expandafter\hyxmp@seed@rng\expandafter{\hyxmp@seed@string}% \edef\hyxmp@rand@num{\the\@tempcnta}% \hyxmp@create@uuid\hyxmp@DocumentID @@ -4600,7 +4883,7 @@ ______<#3 xml:lang="#1">\hyxmp@xmlified^^J% \newcommand*{\hyxmp@def@InstanceID}{% \hyxmp@today@xmp@define{\hyxmp@seed@string}% \edef\hyxmp@seed@string{% - \jobname:\@pdftitle:\@pdfauthor:\hyxmp@today@xmp:\hyxmp@seed@string + \hyxmp@jobname:\@pdftitle:\@pdfauthor:\hyxmp@today@xmp:\hyxmp@seed@string }% \expandafter\hyxmp@seed@rng\expandafter{\hyxmp@seed@string}% \edef\hyxmp@rand@num{\the\@tempcnta}% @@ -4617,20 +4900,32 @@ ______<#3 xml:lang="#1">\hyxmp@xmlified^^J% % An \acro{XMP} packet ``shall consist of the following, in order: a % header \acro{PI}, the serialized \acro{XMP} data model (the \acro{XMP} % packet) with optional white-space padding, and a trailer -% \acro{PI}''~\cite{Adobe2012:XMP}. (``\acro{PI}'' is an abbreviation -% for ``processing instructions''). The serialized \acro{XMP} includes -% blocks of \acro{XML} for various \acro{XMP} schemata: Adobe \acro{PDF} -% (Section~\ref{sec:adobe-pdf}), Dublin Core -% (Section~\ref{sec:dublin-core}), \acro{XMP} Rights Management -% (Section~\ref{sec:xmp-rights}), \acro{XMP} Media Management -% (Section~\ref{sec:xmp-media}), \acro{XMP} Basic -% (Section~\ref{sec:xmp-basic}), Photoshop -% (Section~\ref{sec:photoshop}), \acro{IPTC} Photo Metadata -% (Section~\ref{sec:photo-meta}), and \acro{PDF}\textsc{/*} Identification -% (Section~\ref{sec:pdfX-id}). The |\hyxmp@construct@packet| macro -% (Section~\ref{sec:combining-schemata}) constructs the \acro{XMP} -% packet into |\hyxmp@xml|. It first writes the appropriate \acro{XML} -% header, then calls the various schema-writing macros, then injects +% \acro{PI}''~\cite{Adobe2012:XMP}. (``\acro{PI}'' is an abbreviation for +% ``processing instructions''). The serialized \acro{XMP} includes blocks +% of \acro{XML} for various \acro{XMP} schemata: +% ^^A +% \schema[Adobe PDF]{Adobe \protect\acro{PDF}} (Section~\ref{sec:adobe-pdf}), +% \schema{Dublin Core} (Section~\ref{sec:dublin-core}), +% \schema[XMP Rights Management]{\protect\acro{XMP} Rights Management} (Section~\ref{sec:xmp-rights}), +% \schema[XMP Media Management]{\protect\acro{XMP} Media Management} (Section~\ref{sec:xmp-media}), +% \schema[XMP Basic]{\protect\acro{XMP} Basic} (Section~\ref{sec:xmp-basic}), +% \schema{Photoshop} (Section~\ref{sec:photoshop}), +% \index{PDF/A Identification schema=\acro {PDF/A} Identification schema} +% \index{PDF/X Identification schema=\acro {PDF/X} Identification schema} +% \index{PDF/UA Identification schema=\acro {PDF/UA} Identification schema} +% \index{schemata&PDF/A Identification=\acro {PDF/A} Identification} +% \index{schemata&PDF/X Identification=\acro {PDF/X} Identification} +% \index{schemata&PDF/UA Identification=\acro {PDF/UA} Identification} +% \acro{PDF}\textsc{/*} Identification (Section~\ref{sec:pdfX-id}), +% \schema[IPTC Photo Metadata]{\protect\acro{IPTC} Photo Metadata} (Section~\ref{sec:photo-meta}), +% \schema[PRISM Basic Metadata]{\protect\acro{PRISM} Basic Metadata} (Section~\ref{sec:prism-meta}), +% \schema{Journal Article Versions} (Section~\ref{sec:niso-jav-meta}), and +% \schema[XMP Paged-Text]{\protect\acro{XMP} Paged-Text} (Section~\ref{sec:xmp-paged-text}). +% ^^A +% The |\hyxmp@construct@packet| macro +% (Section~\ref{sec:combining-schemata}) constructs the \acro{XMP} packet +% into |\hyxmp@xml|. It first writes the appropriate \acro{XML} header, +% then calls the various schema-writing macros, then injects % |\hyxmp@padding| as padding, and finally writes the appropriate % \acro{XML} trailer. % @@ -4705,8 +5000,8 @@ _______________________________________________________________^^J% % \end{macro} % % \begin{macro}{\hyxmp@x@default} -% Define an |x-default| string that we can use in comparisons with -% |\@pdfmetalang|. +% Define an \xmpterm{x-default} string that we can use in comparisons +% with |\@pdfmetalang|. % \begin{macrocode} \newcommand*{\hyxmp@x@default}{x-default} % \end{macrocode} @@ -4716,6 +5011,8 @@ _______________________________________________________________^^J% % \subsubsection{The Adobe PDF schema} % \label{sec:adobe-pdf} % +% \begin{schemadesc}[Adobe PDF]{Adobe \protect\acro{PDF}} +% % Older versions of \pkgname{hyperref} defined a default producer; newer % versions do not. Instead, they let the \tex\ engine define the % producer itself. This poses a problem for \acro{PDF/A} compliance @@ -4891,20 +5188,44 @@ _______________________________________________________________^^J% % \end{macrocode} % \end{macro} % +% \end{schemadesc} +% % % \subsubsection{The Dublin Core schema} % \label{sec:dublin-core} % +% \begin{schemadesc}{Dublin Core} +% +% \begin{macro}{\ifhyxmp@multi@langs} +% \begin{macro}{\hyxmp@multi@langstrue} +% \begin{macro}{\hyxmp@multi@langsfalse} +% These macros are used locally to \cs{hyxmp@rdf@dc}. If the property +% being processed has values in different languages, +% \cs{ifhyxmp@multi@langs} evaluates to \textsc{true}. If it has a +% value in only a single language, \cs{ifhyxmp@multi@langs} evaluates to +% \textsc{false}. +% \begin{macrocode} +\newif\ifhyxmp@multi@langs +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macro}{\hyxmp@rdf@dc} % Given an optional |\if|\meta{something} statement (|#1|), a Dublin Core % property~(|#2|) and a macro containing some |\pdfstringdef|-defined % text~(|#3|), append the appropriate block of \acro{XML} to the |\hyxmp@xml| % macro. -% \changes{v1.4}{2011/06/12}{Included metadata in the \texttt{x-default} +% \changes{v1.4}{2011/06/12}{Included metadata in the \xmpterm{x-default} % language regardless of the specified metadata language} % \changes{v3.3}{2017/07/22}{Bug fix: Output the metadata language as % correct \noexpand\acro{XML} even when \noexpand\pkgname{hyperref} is % loaded with the \noexpand\optname{unicode} option} +% \changes{v5.5}{2020/07/17}{List \protect\xmpterm{x-default} alternatives +% before language-specific alternatives, as dictated by the +% \protect\acro{XMP} specification~\protect\cite{Adobe2012:XMP}} +% \changes{v5.5}{2020/07/21}{Rewrite the core part of this macro to +% divide it into four, cleanly defined cases} % \begin{macrocode} \newcommand*{\hyxmp@rdf@dc}[3][\iffalse]{% % \end{macrocode} @@ -4930,27 +5251,90 @@ _______________________________________________________________^^J% ______^^J% ________^^J% }% +% \end{macrocode} +% Record whether property~|#2| has definitions in multiple languages. +% \begin{macrocode} + \@if@def@and@nonempty{hyxmp@alt@#2}{% + \hyxmp@multi@langstrue + }{% + \hyxmp@multi@langsfalse + }% +% \end{macrocode} +% There are now four cases to consider: the cross product of +% \{\optname{pdfmetalang}~$=$ ``\xmpterm{x-default}'', +% \optname{pdfmetalang}~$\neq$ ``\xmpterm{x-default}''\} and +% \{\cs{XMPLangAlt} was specified, \cs{XMPLangAlt} was not specified\}. +% We handle each of these in turn. +% \begin{macrocode} \ifx\@pdfmetalang\hyxmp@x@default + \ifhyxmp@multi@langs +% \end{macrocode} +% \textbf{Case~1}: No \optname{pdfmetalang} but \cs{XMPLangAlt}. +% We consider this an error because the \xmpterm{x-default} language will +% not have a matching non-default language, in violation of the +% \acro{XMP} specification's guidance~\cite[p.~23]{Adobe2012:XMP}: +% +% \begin{quote} +% \sffamily +% +% An \textbf{xml:lang} value of ``x-default'' may be used to +% explicitly denote a default item. If used, the ``x-default'' item +% shall be first in the array and its simple text value should be +% repeated in another item in which \textbf{xml:lang} specifies its +% actual language. However, an ``x-default'' item may be the only +% item, in which case there is only a default value in no defined +% language. +% \end{quote} +% \begin{macrocode} + \PackageError{hyperxmp}% + {\string\XMPLangAlt\space was used without specifying + pdfmetalang\MessageBreak + or pdflang}% + {Be sure to assign a language code to the pdfmetalang key and/or a + document\MessageBreak + language to the pdflang key (e.g., \string\hypersetup{pdfmetalang={en}}).}% + \else +% \end{macrocode} +% \textbf{Case~2}: No \optname{pdfmetalang} and no \cs{XMPLangAlt}. +% Here we specify only \xmpterm{x-default} as the language, as per the +% guidance quoted above. +% \begin{macrocode} + \hyxmp@add@to@xml{% +__________\hyxmp@value^^J% + }% + \fi \else - \hyxmp@xmlify{\@pdfmetalang}% - \hyxmp@add@to@xml{% -__________\hyxmp@value^^J% - }% - \fi - \hyxmp@add@to@xml{% + \ifhyxmp@multi@langs +% \end{macrocode} +% \textbf{Case~3}: Both \optname{pdfmetalang} and \cs{XMPLangAlt}. In +% this case, we include an \xmpterm{x-default} followed by the +% \optname{pdfmetalang} language, followed by all of the language +% alternatives. +% \begin{macrocode} + \hyxmp@xmlify{\@pdfmetalang}% + \hyxmp@add@to@xml{% __________\hyxmp@value^^J% - }% +__________\hyxmp@value^^J% + }% + \def\do##1##2{ + \hyxmp@xmlify{##2}% + \hyxmp@add@to@xml{% + __________\hyxmp@xmlified^^J% + }% + }% + \csname hyxmp@alt@#2\endcsname + \else % \end{macrocode} -% Include variants of the text expressed in other languages, as specified by -% the author using |\XMPLangAlt| (Section~\ref{sec:lang-alt}). +% \textbf{Case~4}: \optname{pdfmetalang} but no \cs{XMPLangAlt}. To +% reduce redundancy we omit the \xmpterm{x-default} and include the +% single language in which the text appears. % \begin{macrocode} - \def\do##1##2{ - \hyxmp@xmlify{##2}% - \hyxmp@add@to@xml{% -__________\hyxmp@xmlified^^J% - }% - }% - \csname hyxmp@alt@#2\endcsname + \hyxmp@xmlify{\@pdfmetalang}% + \hyxmp@add@to@xml{% +__________\hyxmp@value^^J% + }% + \fi + \fi % \end{macrocode} % Complete this \acro{XMP} element. % \begin{macrocode} @@ -5118,9 +5502,14 @@ ______^^J% % \end{macrocode} % \end{macro} % +% \end{schemadesc} +% +% % \subsubsection{The XMP Rights Management schema} % \label{sec:xmp-rights} % +% \begin{schemadesc}[XMP Rights Management]{\protect\acro{XMP} Rights Management} +% % \begin{macro}{\hyxmp@xmpRights@schema} % Add properties defined by the \acro{XMP} Rights Management schema to the % |\hyxmp@xml| macro. Currently, these are only the @@ -5169,10 +5558,14 @@ ______^^J% % \end{macro} % \end{macro} % +% \end{schemadesc} +% % % \subsubsection{The XMP Media Management schema} % \label{sec:xmp-media} % +% \begin{schemadesc}[XMP Media Management]{\protect\acro{XMP} Media Management} +% % \begin{macro}{\hyxmp@mm@schema} % Add properties defined by the \acro{XMP} Media Management schema to % the |\hyxmp@xml| macro. According to the \acro{XMP} specification, @@ -5203,10 +5596,14 @@ ______^^J% % \end{macrocode} % \end{macro} % +% \end{schemadesc} +% % % \subsubsection{The XMP Basic schema} % \label{sec:xmp-basic} % +% \begin{schemadesc}[XMP Basic]{\protect\acro{XMP} Basic} + % \begin{macro}{\hyxmp@xmp@basic@schema} % Add properties defined by the \acro{XMP} Basic schema to the % |\hyxmp@xml| macro. These include a bunch of dates (all set to the @@ -5265,10 +5662,14 @@ ______^^J% % \end{macrocode} % \end{macro} % +% \end{schemadesc} +% % % \subsubsection{The Photoshop schema} % \label{sec:photoshop} % +% \begin{schemadesc}{Photoshop} +% % \begin{macro}{\hyxmp@photoshop@schema} % \changes{v2.0}{2012/08/26}{Simplified using % \texttt{\string\string\string\hyxmp@add@simple}} @@ -5287,10 +5688,16 @@ ______^^J% % \end{macro} % \end{macro} % +% \end{schemadesc} +% % % \subsubsection{PDF/* Identification schemata} % \label{sec:pdfX-id} % +% \begin{schemadesc}[PDF/A Identification]{\protect\acro{PDF/A} Identification} +% \begin{schemadesc}[PDF/X Identification]{\protect\acro{PDF/X} Identification} +% \begin{schemadesc}[PDF/UA Identification]{\protect\acro{PDF/UA} Identification} +% % \begin{macro}{\hyxmp@pdfa@id@schema} % Add properties defined by the \acro{PDF/A} Identification % schema~\cite{PDFA2008:xmp-props} to the |\hyxmp@xml| macro. These @@ -5350,10 +5757,16 @@ ______^^J% % \end{macrocode} % \end{macro} % +% \end{schemadesc} +% \end{schemadesc} +% \end{schemadesc} +% % % \subsubsection{The IPTC Photo Metadata schema} % \label{sec:photo-meta} % +% \begin{schemadesc}[IPTC Photo Metadata]{\protect\acro{IPTC} Photo Metadata} +% % \begin{macro}{\xmplinesep} % Lines in multiline fields are separated by |\xmplinesep| in the % generated \acro{XML}. This defaults to an \acro{LF} (|^^J|) character @@ -5486,9 +5899,14 @@ ______^^J% % \end{macro} % \end{macro} % +% \end{schemadesc} +% +% % \subsubsection{The PRISM Basic Metadata schema} % \label{sec:prism-meta} % +% \begin{schemadesc}[PRISM Basic Metadata]{\protect\acro{PRISM} Basic Metadata} +% % \begin{macro}{\hyxmp@prism@schema} % \changes{v4.0}{2019/03/10}{Added this macro} % Add properties defined by the \acro{PRISM} Basic Metadata @@ -5517,6 +5935,110 @@ ______^^J% % \end{macrocode} % \end{macro} % +% \end{schemadesc} +% +% +% \subsubsection{The Journal Article Versions (JAV) schema} +% \label{sec:niso-jav-meta} +% +% \begin{schemadesc}{Journal Article Versions} +% +% \begin{macro}{\hyxmp@jav@schema} +% \changes{v5.5}{2020/07/23}{Added this macro} +% Add properties defined by the \acro{NISO}/\acro{ALPSP} Journal Article +% Versions schema~\cite{NISO2008:jav}. +% \begin{macrocode} +\newcommand*{\hyxmp@jav@schema}{% + \hyxmp@add@simple{jav:journal_article_version}{\@pdfpubstatus}% +} +% \end{macrocode} +% \end{macro} +% +% \end{schemadesc} +% +% \subsubsection{The XMP Paged-Text schema} +% \label{sec:xmp-paged-text} +% +% \begin{schemadesc}[XMP Paged-Text]{\protect\acro{XMP} Paged-Text} +% +% \begin{macro}{\hyxmp@xmptpg@schema} +% The \acro{XMP} Paged-Text schema~\cite{Adobe2012:XMP} includes +% properties related to the construction of the \acro{PDF} file itself. +% We acquire most of this information through \LuaTeX\ mechanisms and +% therefore include much less information when run from other \TeX\ engines. +% \changes{v5.5}{2020/07/25}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@xmptpg@schema}{% + \ifLuaTeX + \luadirect{write_xmp_font_list(\the\hyxmp@cct)}% + \fi + \hyxmp@add@simple{xmpTPg:NPages}{\@pdfnumpages}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@cct} +% We store the current category-code table to ensure that +% |write_xmp_font_list|'s output uses our redefined category codes. +% \begin{macrocode} +\ifLuaTeX + \newcatcodetable\hyxmp@cct + \savecatcodetable\hyxmp@cct +\fi +% \end{macrocode} +% \end{macro} +% +% Here we define a Lua\index{Lua} function, |write_xmp_font_list|, that +% writes font information to the \acro{XMP} packet. +% \begin{macrocode} +\ifLuaTeX + \begin{luacode*} +function write_xmp_font_list (cct) + local function show_field(name, ...) + for i = 1, select("#", ...) do + local val = select(i, ...) + if val then + local xml = string.gsub(val, "&", "&") + xml = string.gsub(xml, "<", "<") + xml = string.gsub(xml, ">", ">") + tex.print(cct, "____________" .. + val .. "^^J%") + return + end + end + end + tex.print(cct, "\\hyxmp@add@to@xml{%") + tex.print(cct, "______^^J%") + tex.print(cct, "________^^J%") + for i, f in font.each() do + tex.print(cct, "__________^^J%") + if f.filename then + local info = fontloader.info(f.filename) + show_field("fontFace", info.fullname) + show_field("fontFamily", info.familyname) + show_field("fontName", info.fontname) + show_field("versionString", info.version) + local baseName = string.gsub(f.filename, ".*[/\\](.*)", "%1") + show_field("fontFileName", baseName) + else + show_field("fontName", f.psname, f.fullname, f.name) + end + if f.format and f.format ~= "unknown" then + show_field("fontType", f.format) + end + tex.print(cct, "__________^^J%") + end + tex.print(cct, "________^^J%") + tex.print(cct, "______^^J%") + tex.print(cct, "}") +end + \end{luacode*} +\fi +% \end{macrocode} +% +% \end{schemadesc} +% +% % \subsubsection{XMP extension schemata} % \label{sec:extension-schemata} % @@ -5529,13 +6051,11 @@ ______^^J% % declare only those schemata we actually use. % % \begin{macro}{\hyxmp@check@iptc@data} +% \begin{macro}{\hyxmp@iptc@data} % Define |\hyxmp@iptc@data| as the concatenation of all \acro{IPTC} % photo metadata supplied by the document. % \begin{macrocode} \newcommand*{\hyxmp@check@iptc@data}{% -% \end{macrocode} -% \begin{macro}{\hyxmp@iptc@data} -% \begin{macrocode} \edef\hyxmp@iptc@data{% \@pdfcontactaddress \@pdfcontactcity @@ -5552,13 +6072,11 @@ ______^^J% % \end{macro} % % \begin{macro}{\hyxmp@check@prism@data} +% \begin{macro}{\hyxmp@prism@data} % Define |\hyxmp@prism@data| as the concatenation of all \acro{PRISM} % metadata supplied by the document. % \begin{macrocode} \newcommand*{\hyxmp@check@prism@data}{% -% \end{macrocode} -% \begin{macro}{\hyxmp@prism@data} -% \begin{macrocode} \edef\hyxmp@prism@data{% \@pdfbookedition \@pdfbytes @@ -5580,6 +6098,20 @@ ______^^J% % \end{macro} % \end{macro} % +% \begin{macro}{\hyxmp@check@jav@data} +% \begin{macro}{\hyxmp@jav@data} +% Define |\hyxmp@jav@data| as the concatenation of all \acro{JAV} +% metadata supplied by the document. +% \begin{macrocode} +\newcommand*{\hyxmp@check@jav@data}{% + \edef\hyxmp@jav@data{% + \@pdfpubstatus + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}{\hyxmp@begin@extension@decls} % Begin a block of \acro{XML} tags that indicates we're declaring one or % more extension schemata. @@ -5701,6 +6233,9 @@ ______________________^^J% % \begin{macro}{\hyxmp@mm@extensions} % Declare the \acro{XMP} Media Management schema. % \changes{v4.0}{2019/03/15}{Added this macro} +% \changes{v5.5}{2020/07/23}{Corrected the type of +% \protect\xmpprop{xmpMM:RenditionClass}. Thanks to Thorsten Wi{\ss}mann +% for the bug report and patch} % \begin{macrocode} \newcommand*{\hyxmp@mm@extensions}{% \hyxmp@begin@ext@decl @@ -5722,6 +6257,7 @@ ______________________^^J% {internal}% {Document version identifier}% \hyxmp@declare@property + [RenditionClass]% {RenditionClass}% {internal}% {The manner in which a document is rendered}% @@ -5909,7 +6445,7 @@ __________^^J% \hyxmp@begin@ext@decl {PRISM Basic Metadata}% {prism}% - {http://prismstandard.org/namespaces/basic/2.1/}% + {http://prismstandard.org/namespaces/basic/3.0/}% \hyxmp@declare@property {complianceProfile}% {internal}% @@ -5978,6 +6514,29 @@ __________^^J% % \end{macrocode} % \end{macro} % +% \begin{macro}{\hyxmp@jav@extensions} +% \changes{v5.5}{2020/07/23}{Added this macro} +% Because \acro{JAV} metadata are not recognized by the \acro{PDF/A} +% standard, \acro{PDF/A} conversion would normally fail for documents +% that utilize \acro{JAV} metadata. Declaring the \acro{JAV} metadata +% we support enables the document to be converted to \acro{PDF/A} +% format. +% \begin{macrocode} +\newcommand*{\hyxmp@jav@extensions}{% + \hyxmp@begin@ext@decl + {NISO/ALPSP Journal Article Versions}% + {jav}% + {http://www.niso.org/schemas/jav/1.0/}% + \hyxmp@declare@property + [Closed Choice of Text]% + {journal_article_version}% + {external}% + {Article status, one of "AO", "SMUR", "AM", "P", "VoR", "CVoR", or "EVoR"}% + \hyxmp@end@ext@decl +}% +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\hyxmp@declare@extensions} % Declare all \acro{XMP} extension schemata. We'll always have at least % one, the \acro{XMP} Media Management extensions, because we @@ -6034,6 +6593,13 @@ __________^^J% \hyxmp@prism@extensions \fi % \end{macrocode} +% Conditionally declare \acro{JAV} metadata. +% \begin{macrocode} + \ifx\hyxmp@jav@data\@empty + \else + \hyxmp@jav@extensions + \fi +% \end{macrocode} % \begin{macrocode} \hyxmp@end@extension@decls } @@ -6098,7 +6664,10 @@ _____________________xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/"^^J% _____________________xmlns:pdfuaid="http://www.aiim.org/pdfua/ns/id/"^^J% _____________________xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/"^^J% _____________________xmlns:pdfxid="http://www.npes.org/pdfx/ns/id/"^^J% -_____________________xmlns:prism="http://prismstandard.org/namespaces/basic/2.1/"^^J% +_____________________xmlns:prism="http://prismstandard.org/namespaces/basic/3.0/"^^J% +_____________________xmlns:jav="http://www.niso.org/schemas/jav/1.0/"^^J% +_____________________xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"^^J% +_____________________xmlns:stFnt="http://ns.adobe.com/xap/1.0/sType/Font\hyxmp@hash"^^J% _____________________xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"^^J% _____________________xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"^^J% _____________________xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema\hyxmp@hash"^^J% @@ -6111,6 +6680,7 @@ _____________________xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field\hyxmp@ha % \begin{macrocode} \hyxmp@check@iptc@data \hyxmp@check@prism@data + \hyxmp@check@jav@data \hyxmp@declare@extensions % \end{macrocode} % Insert all the metadata we know how to insert. @@ -6126,6 +6696,8 @@ _____________________xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field\hyxmp@ha \hyxmp@mm@schema \hyxmp@iptc@schema \hyxmp@prism@schema + \hyxmp@jav@schema + \hyxmp@xmptpg@schema \hyxmp@add@to@xml{% ____^^J% __^^J% @@ -6171,7 +6743,7 @@ __^^J% \@ifundefined{pdfmark}{% \PackageWarningNoLine{hyperxmp}{% Unrecognized hyperref driver `\Hy@driver'.\MessageBreak - \jobname.tex's XMP metadata will *not* be\MessageBreak + \hyxmp@jobname.tex's XMP metadata will *not* be\MessageBreak embedded in the resulting file}% }{% \hyxmp@embed@packet@pdfmark @@ -6402,6 +6974,15 @@ __^^J% % \subsection{Final clean-up} % \label{sec:clean-up} % +% As explained in Section~\ref{sec:initial-prep}, all invocations of +% \cs{AtEndPreamble} have been stored in \cs{hyxmp@aep@toks} rather than +% executed. Now that \pkgname{hyperxmp} has been initialized +% completely, it is finally safe to execute the accumulated +% \cs{AtEndPreamble} stanzas. +% \begin{macrocode} +\the\hyxmp@aep@toks +% \end{macrocode} +% % Having saved the category code of % ``\,{\fontencoding{T1}\selectfont\textquotedbl}\,'' at the start of % the package code (Section~\ref{sec:initial-prep}), we now restore that diff --git a/macros/latex/contrib/hyperxmp/hyperxmp.ins b/macros/latex/contrib/hyperxmp/hyperxmp.ins index 7a81974604..81db9d155a 100644 --- a/macros/latex/contrib/hyperxmp/hyperxmp.ins +++ b/macros/latex/contrib/hyperxmp/hyperxmp.ins @@ -5,9 +5,9 @@ %% the LaTeX Project Public License, either version 1.3c of this license %% or (at your option) any later version. The latest version of this %% license is in: -%% +%% %% http://www.latex-project.org/lppl.txt -%% +%% %% and version 1.3c or later is part of all distributions of LaTeX version %% 2008/05/04 or later. %% diff --git a/macros/latex/contrib/hyperxmp/hyperxmp.pdf b/macros/latex/contrib/hyperxmp/hyperxmp.pdf index 998059c14e..713d57a2b6 100644 Binary files a/macros/latex/contrib/hyperxmp/hyperxmp.pdf and b/macros/latex/contrib/hyperxmp/hyperxmp.pdf differ -- cgit v1.2.3