diff options
author | Karl Berry <karl@freefriends.org> | 2020-03-26 21:27:46 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-03-26 21:27:46 +0000 |
commit | e5b867c8ebe58caa2dae444265723e8a88603b1f (patch) | |
tree | 38f31c315e0a0b8e45bf120bf54d502b4c7b0476 /Master | |
parent | 0b6fc17678db57f37210b8ced66a414f3fc6a4e6 (diff) |
hyperxmp (26mar20)
git-svn-id: svn://tug.org/texlive/trunk@54559 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/latex/hyperxmp/README | 2 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf | bin | 655188 -> 1234122 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/hyperxmp/einstein-xmp.tex | 14 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/hyperxmp/einstein1.pdf | bin | 0 -> 70830 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/hyperxmp/einstein1.png | bin | 35909 -> 0 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/hyperxmp/einstein2.pdf | bin | 0 -> 77679 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/hyperxmp/einstein2.png | bin | 40735 -> 0 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx | 1361 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins | 9 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty | 432 |
10 files changed, 1412 insertions, 406 deletions
diff --git a/Master/texmf-dist/doc/latex/hyperxmp/README b/Master/texmf-dist/doc/latex/hyperxmp/README index c65c6452239..c5365e41b00 100644 --- a/Master/texmf-dist/doc/latex/hyperxmp/README +++ b/Master/texmf-dist/doc/latex/hyperxmp/README @@ -47,7 +47,7 @@ Building hyperxmp.pdf is a little more involved: Copyright and license ===================== -Copyright (C) 2019 Scott Pakin +Copyright (C) 2011-2020 Scott Pakin This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license diff --git a/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf b/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf Binary files differindex 559569698f8..66c531f3306 100644 --- a/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf +++ b/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf diff --git a/Master/texmf-dist/source/latex/hyperxmp/einstein-xmp.tex b/Master/texmf-dist/source/latex/hyperxmp/einstein-xmp.tex index f876012212a..2526cf0ff7c 100644 --- a/Master/texmf-dist/source/latex/hyperxmp/einstein-xmp.tex +++ b/Master/texmf-dist/source/latex/hyperxmp/einstein-xmp.tex @@ -19,7 +19,10 @@ 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:prism="http://prismstandard.org/namespaces/basic/3.0/" + 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/2.1/" 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#" @@ -31,7 +34,7 @@ \end{alltt} \begin{center} $\vdots$\par - \emph{[over 100 lines of boilerplate definitions not shown]}\par + \emph{[over 200 lines of boilerplate definitions not shown]}\par $\vdots$\par \end{center} \begin{alltt} @@ -40,7 +43,9 @@ <pdf:Keywords> \metavalue{energy quanta, Hertz effect, quantum physics} </pdf:Keywords> - <pdf:Producer>\metavalue{pdfTeX-1.40.19}</pdf:Producer> + <pdf:Producer> + \metavalue{pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019/Debian)} + </pdf:Producer> <pdf:PDFVersion>\metavalue{1.5}</pdf:PDFVersion> <xmpRights:Marked>\metavalue{True}</xmpRights:Marked> <xmpRights:WebStatement> @@ -127,6 +132,7 @@ \metavalue{uuid:3e4c4182-b182-46c9-995f-754c41d13390} </xmpMM:InstanceID> <xmpMM:VersionID>\metavalue{2.998e8}</xmpMM:VersionID> + <xmpMM:RenditionClass>\metavalue{default}</xmpMM:RenditionClass> <Iptc4xmpCore:CreatorContactInfo rdf:parseType="Resource"> <Iptc4xmpCore:CiAdrExtadr>\metavalue{Kramgasse 49}</Iptc4xmpCore:CiAdrExtadr> <Iptc4xmpCore:CiAdrCity>\metavalue{Bern}</Iptc4xmpCore:CiAdrCity> @@ -156,7 +162,7 @@ <prism:url> \metavalue{http://www.physik.uni-augsburg.de/annalen/history/einstein-papers/190517132-148.pdf} </prism:url> - <prism:byteCount>\metavalue{56884}</prism:byteCount> + <prism:byteCount>\metavalue{59846}</prism:byteCount> <prism:pageCount>\metavalue{17}</prism:pageCount> </rdf:Description> </rdf:RDF> diff --git a/Master/texmf-dist/source/latex/hyperxmp/einstein1.pdf b/Master/texmf-dist/source/latex/hyperxmp/einstein1.pdf Binary files differnew file mode 100644 index 00000000000..3a283dfca70 --- /dev/null +++ b/Master/texmf-dist/source/latex/hyperxmp/einstein1.pdf diff --git a/Master/texmf-dist/source/latex/hyperxmp/einstein1.png b/Master/texmf-dist/source/latex/hyperxmp/einstein1.png Binary files differdeleted file mode 100644 index 8cee49db9d1..00000000000 --- a/Master/texmf-dist/source/latex/hyperxmp/einstein1.png +++ /dev/null diff --git a/Master/texmf-dist/source/latex/hyperxmp/einstein2.pdf b/Master/texmf-dist/source/latex/hyperxmp/einstein2.pdf Binary files differnew file mode 100644 index 00000000000..3a3144d096a --- /dev/null +++ b/Master/texmf-dist/source/latex/hyperxmp/einstein2.pdf diff --git a/Master/texmf-dist/source/latex/hyperxmp/einstein2.png b/Master/texmf-dist/source/latex/hyperxmp/einstein2.png Binary files differdeleted file mode 100644 index abe66a246de..00000000000 --- a/Master/texmf-dist/source/latex/hyperxmp/einstein2.png +++ /dev/null diff --git a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx index a5aa24a146b..bad62e4b981 100644 --- a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx +++ b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 2019 by Scott Pakin <scott+hyxmp@pakin.org> -% ------------------------------------------------------- +% Copyright (C) 2011--2020 by Scott Pakin <scott+hyxmp@pakin.org> +% --------------------------------------------------------------- % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c @@ -22,7 +22,7 @@ %<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] %<package>\ProvidesPackage{hyperxmp} %<*package> - [2019/04/05 v4.1 Store hyperref metadata in XMP format] + [2020/03/20 v5.0 Store hyperref metadata in XMP format] %</package> % %<*driver> @@ -31,8 +31,10 @@ \gdef\levelchar{&} \egroup \documentclass{ltxdoc} +\usepackage[T1]{fontenc} +\usepackage[english]{babel} \usepackage{graphicx} -\usepackage{color} +\usepackage[cmyk]{xcolor} \usepackage{tocbibind} \usepackage{microtype} \usepackage{needspace} @@ -40,9 +42,19 @@ \usepackage{alltt} \usepackage{multicol} \usepackage{makeidx} -\usepackage[utf8]{inputenc} +\usepackage{mmap} +\usepackage{enumitem} +\usepackage{booktabs} +\usepackage{marginfix} +\usepackage{ifmtarg} +\usepackage{iftex} +\input{hyperxmp-stds} +\expandafter\ifx\csname wantpdfstandards\endcsname\relax + \usepackage{hyperref} +\else + \usepackage[pdfa]{hyperref} +\fi \usepackage{hyperxmp} -\usepackage[unicode,bookmarksopen,bookmarksopenlevel=2,bookmarksnumbered]{hyperref} \EnableCrossrefs \CodelineIndex \RecordChanges @@ -60,17 +72,27 @@ pdftitle={The hyperxmp package}, pdfsubject={LaTeX2e support for XMP metadata}, pdfkeywords={LaTeX, embedded metadata, XMP, PDF, copyright, license, comments}, - pdfcopyright={Copyright (C) 2019, Scott Pakin}, + pdfcopyright={Copyright (C) 2011-2020, Scott Pakin}, pdflicenseurl={http://www.latex-project.org/lppl/}, pdfcaptionwriter={Scott Pakin}, pdfcontactemail={scott+hyxmp@pakin.org}, pdfcontacturl={http://www.pakin.org/\xmptilde scott/}, pdfversionid={\versionnumber}, pdflang={en-US}, + pdftrapped={False}, + pdfstartpage={}, pdfurl={http://mirror.ctan.org/macros/latex/contrib/hyperxmp/hyperxmp.pdf}, baseurl={http://mirror.ctan.org/macros/latex/contrib/hyperxmp/} } +% Specify some additional hyperref configuration. +\hypersetup{% + unicode, + bookmarksopen, + bookmarksopenlevel=2, + bookmarksnumbered +} + \begin{document} \DocInput{hyperxmp.dtx} \Needspace{10\baselineskip} @@ -89,7 +111,7 @@ %</driver> % \fi % -% \CheckSum{2095} +% \CheckSum{2342} % % \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 @@ -142,6 +164,10 @@ % \changes{v4.1}{2019/04/05}{Updated the documentation to refer to % \protect\cs{pdfnumpages} by its correct name. Thanks to Volker RW Schaa % for catching the discrepancy} +% \changes{v5.0}{2020/02/15}{Added support for \protect\acro{PDF/UA} +% standards, as requested by Robin Schwab} +% \changes{v5.0}{2020/02/26}{Added support for \protect\acro{PDF/X} +% standards, as requested by Robin Schwab} % % ^^A \GetFileInfo{hyperxmp.dtx} % @@ -259,6 +285,18 @@ % } % \makeatother % +% ^^A Typeset a PDF standard name, indexing only the standard type but +% ^^A not the subtype or year. +% \makeatletter +% \newcommand*{\PDFstd}[4]{^^A +% \mbox{^^A +% \acro{PDF/#1}-\oldstylenums{#2}^^A +% #3^^A +% \@ifnotmtarg{#4}{:\oldstylenums{#4}}^^A +% }^^A +% } +% \makeatother +% % ^^A Pack figures a bit tighter onto the page. % \renewcommand{\floatpagefraction}{0.8} % @@ -276,7 +314,6 @@ % metadata through \pkgname{hyperref}'s mechanisms. % \end{abstract} % -% % \section{Introduction} % % Adobe Systems, Inc.\ has been promoting @@ -297,10 +334,12 @@ % also its title, list of authors, description, and other metadata. % % \paragraph{This is too abstract! Give me an example.} -% Consider a \LaTeX\ document with three authors: Jack Napier, Edward -% Nigma, and Harvey Dent. The generated \acro{PDF} file will contain, -% among other information, the following stanza of \acro{XMP} code -% embedded within it: +% Consider a \LaTeX\ document with three authors---Jack Napier, Edward +% Nigma, and Harvey Dent---named in the \LaTeX\ source in the usual way: +% ``\verb|\author{|\texttt{Jack Napier \cs{and} Edward Nigma \cs{and} +% Harvey Dent}\verb|}|''. With \pkgname{hyperxmp}, the generated +% \acro{PDF} file will contain, among other information, the following +% stanza of \acro{XMP} code embedded within it: % % \begin{verbatim} % <dc:creator> @@ -323,7 +362,7 @@ % % Remember that \acro{XMP} code is stored as \emph{metadata}. It does % not appear when viewing or printing the \acro{PDF} file. Rather, it -% is intended to make it easy for applications to identify and +% is intended to make it easy for computer applications to identify and % categorize the document. % % \paragraph{What metadata does \textsf{hyperxmp} process?} @@ -360,14 +399,18 @@ % \item page range(s) (\xmpprop{prism:pageRange}) % \item \acro{PDF} version (\xmpprop{pdf:PDFVersion}) % \item \acro{PDF}-generating tool (\xmpprop{pdf:Producer} and \xmpprop{xmp:CreatorTool}) -% \item \acro{PDF/A} compliance level and version (\xmpprop{pdfaid:part} and \xmpprop{pdfaid:conformance}) +% \item \acro{PDF/A} version and conformance level (\xmpprop{pdfaid:part} and \xmpprop{pdfaid:conformance}) +% \item \acro{PDF/UA} version (\xmpprop{pdfuaid:part}) +% \item \acro{PDF/X} standard compliance (\xmpprop{pdfxid:GTS\_PDFXVersion}) % \item position/title of primary author (\xmpprop{photoshop:AuthorsPosition}) % \item publication name of parent publication (\xmpprop{prism:publicationName}) % \item publisher of the document (\xmpprop{dc:publisher}) +% \item rendition variation of the document (\xmpprop{xmpMM:RenditionClass}) % \item summary (\xmpprop{dc:description}) % \item subtitle (\xmpprop{prism:subtitle}) % \item telephone number(s) of primary author (\xmpprop[CiTelWork]{Iptc4xmpCore:CreatorContactInfo}) % \item title (\xmpprop{dc:title}) +% \item trapping of colors (\xmpprop{pdf:trapped}) % \item type of document (\xmpprop{dc:type}) % \item type of parent publication (\xmpprop{prism:aggregationType}) % \item \acro{URL} of the document (\xmpprop{prism:url}) @@ -425,6 +468,7 @@ % \item \optname{pdfproducer} % \item \optname{pdfsubject} % \item \optname{pdftitle} +% \item \optname{pdftrapped} % \end{itemize} % \end{multicols} % @@ -467,12 +511,15 @@ % \item \optname{pdfpublication} % \item \optname{pdfpublisher} % \item \optname{pdfpubtype} +% \item \optname{pdfrendition} % \item \optname{pdfsource} % \item \optname{pdfsubtitle} % \item \optname{pdftype} +% \item \optname{pdfuapart} % \item \optname{pdfurl} % \item \optname{pdfversionid} % \item \optname{pdfvolumenum} +% \item \optname{pdfxstandard} % \end{itemize} % \end{multicols} % \label{page:end-new-options} @@ -483,8 +530,10 @@ % The document title is specified as normal for \pkgname{hyperref} with % \moptname{pdftitle}, but see Note~\ref{note:multilingual} on % page~\pageref{note:multilingual} for instructions on how to specify a -% title in multiple languages. \pkgname{hyperxmp} introduces a -% complementary \moptname{pdfsubtitle} option: +% title in multiple languages. If \optname{pdftitle} is not specified +% it will inherit its value from the document's \cs{title}. +% \pkgname{hyperxmp} introduces a complementary \moptname{pdfsubtitle} +% option: % % \begin{verbatim} % pdftitle={Frankenstein}, @@ -498,14 +547,20 @@ % optional \acro{ISO} \mbox{3166-1} two-letter region code. See the % example below for \optname{pdfpublication}. % -% \Needspace{6\baselineskip} -% \moptname{pdfauthortitle} indicates the primary author's position or -% title. \moptname{pdfcaptionwriter} specifies the name of the person -% who added the metadata to the document. The next eight items describe -% how to contact the person or institution responsible for the document -% (the ``contact''). \moptname{pdfcontactaddress} is the contact's -% street address and can include the institution name if the contact is -% an institution; \moptname{pdfcontactcity} is the contact's city; +% \pkgname{hyperref}'s \moptname{pdfauthor} option specifies the +% document's author(s). See Note~\ref{note:literal-commas} on +% page~\pageref{note:literal-commas} for a discussion of the correct +% syntax. If \optname{pdfauthor} is not specified it will inherit its +% value from the document's \cs{author}. \moptname{pdfauthortitle} +% indicates the primary author's position or title. +% \moptname{pdfcaptionwriter} specifies the name of the person who added +% the metadata to the document. +% +% The next eight items describe how to contact the person or institution +% responsible for the document (the ``contact''). +% \moptname{pdfcontactaddress} is the contact's street address and can +% include the institution name if the contact is an institution; +% \moptname{pdfcontactcity} is the contact's city; % \moptname{pdfcontactcountry} is the contact's country; % \moptname{pdfcontactemail} is the contact's email address (or % multiple, comma-separated email addresses); \moptname{pdfcontactphone} @@ -561,7 +616,8 @@ % \pkgname{gitver} package is an expandable (see % Note~\ref{note:expandable} on page~\pageref{note:expandable}) version % of the current \href{https://git-scm.com/}{Git} hash that can suitably -% be passed to \optname{pdfversionid}. +% be passed to \optname{pdfversionid}. If not specified, +% \optname{pdfversionid} defaults to~|1|. % % Already-published documents can be identified in a number of ways. % \moptname{pdfisbn} specifies the \acro{ISBN}. \moptname{pdfissn} @@ -663,6 +719,16 @@ % of mailing lists,''~\cite{DCMI2012:meta-terms} and other forms of % text---all things \LaTeX\ is commonly used to typeset. % +% Sometimes a base document is rendered in different forms. +% \moptname{pdfrendition} indicates the particular rendition the current +% document instance represents. The value should come from the +% following controlled vocabulary~\cite{Adobe2012:XMP}: |default|, +% |draft|, |low-res|, |proof|, |screen|, and |thumbnail|. +% \pkgname{hyperxmp}'s default value is |default|, which indicates the +% master document, unless the \optname{draft} option is passed to +% |\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 @@ -672,27 +738,71 @@ % 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. +% +% \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{pdfpart} 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. +% +% ^^A This list needs to be kept up-to-date with the standards checked +% ^^A by \@pdfxstandard. +% \begin{multicols}{3} +% \raggedcolumns +% \begin{itemize}[noitemsep] +% \item \PDFstd{X}{1}{a}{2001} +% \item \PDFstd{X}{1}{a}{2003} +% \item \PDFstd{X}{3}{}{2002} +% \item \PDFstd{X}{3}{}{2003} +% \item \PDFstd{X}{4}{}{} +% \item \PDFstd{X}{4}{p}{} +% \item \PDFstd{X}{5}{g}{} +% \item \PDFstd{X}{5}{n}{} +% \item \PDFstd{X}{5}{pg}{} +% \end{itemize} +% \end{multicols} +% +% For example, one can specify \optname{pdfxstandard}=|{PDF/X-4}| or +% \optname{pdfxstandard}=|{PDF/X-3:2003}|, but specifying +% \optname{pdfxstandard}=|{PDF/X-3}| will not pass \acro{PDF/X} +% validation. Note that at the time of this writing the use of the +% \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. % -% Two other rarely needed options, \moptname{pdfaconformance} and -% \moptname{pdfapart}, 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 \acro{PDF/A}-\textsc{1b} -% standard. These can be changed (with caution) to assert that the -% document abides by a different standard -% (e.g.,~\acro{PDF/A}-\textsc{2u}). -% % \bigskip % -% It is usually more convenient to provide values for those options using -% \pkgname{hyperref}'s |\hypersetup| command than on the |\usepackage| -% command line. See +% 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 % \href{http://mirrors.ctan.org/macros/latex/contrib/hyperref/hyperref.pdf}{the -% \pkgname{hyperref} manual} for more information. +% \pkgname{hyperref} manual} for more information. % % % \subsection{A complete example} @@ -819,6 +929,7 @@ % \subsection{Usage notes} % % \usagenote{Conflicting metadata in PDF/A documents} +% \label{note:meta-conflicts} % A \acro{PDF} file includes an \pdfterm{Info} dictionary containing % \pdfterm{Author}, \pdfterm{Title}, \pdfterm{Subject}, and % \pdfterm{Keywords} keys. The \pkgname{hyperref} package's @@ -857,10 +968,12 @@ % % Starting with version~4.0, \pkgname{hyperxmp}'s solution is to % suppress writing metadata to the \acro{PDF} \pdfterm{Info} dictionary -% and write it only to the \acro{XMP} packet. This appears to pacify -% \acro{PDF/A} validators yet retains the author and keyword lists in -% their non-truncated form. If desired, the \pdfterm{Info} dictionary -% can be retained by passing the \optname{keeppdfinfo} option to +% and write it only to the \acro{XMP} packet. (\pkgname{hyperxmp}~v5.0+ +% is more sophisticated. It suppresses only the author and keyword +% lists.) This appears to pacify \acro{PDF/A} validators yet retains +% the author and keyword lists in their non-truncated form. If desired, +% the \pdfterm{Info} dictionary can be retained by passing the +% \moptname{keeppdfinfo}\label{page:keeppdfinfo} option to % \cs{hypersetup}. % % \usagenote{Acrobat multiline-field bug} @@ -916,6 +1029,7 @@ % \end{enumerate} % % \usagenote{Literal commas} +% \label{note:literal-commas} % \pkgname{hyperxmp} splits the \optname{pdfauthor} and % \optname{pdfkeywords} lists at commas. Therefore, when specifying % \optname{pdfauthor} and \optname{pdfkeywords}, you should separate @@ -1162,7 +1276,7 @@ % % \input{einstein-xmp} % -% \begin{thebibliography}{1} +% \begin{thebibliography}{99} % \bibitem{Adobe2010:pdfmark} % Adobe Systems, Inc., San Jose, California. % \newblock \emph{{A}dobe {A}crobat~{X} {SDK} Help, pdfmark Reference}. @@ -1265,6 +1379,9 @@ % \pkgname{hyperxmp}. Read this section only if you want to learn how % \pkgname{hyperxmp} is implemented. % +% \iffalse +%<*package> +% \fi % % \subsection{Initial preparation} % \label{sec:initial-prep} @@ -1309,14 +1426,15 @@ % % % \subsection{Integration with \textsf{hyperref}} +% \label{sec:hyperref-int} % % An important design decision underlying \pkgname{hyperxmp} is that the % package should integrate seamlessly with \pkgname{hyperref}. To that -% end, \pkgname{hyperxmp} takes its \acro{XMP} metadata from +% end, \pkgname{hyperxmp} takes \acro{XMP} metadata from % \pkgname{hyperref}'s \optname{baseurl}, \optname{pdfauthor}, % \optname{pdfkeywords}, \optname{pdflang}, \optname{pdfproducer}, -% \optname{pdfsubject}, and \optname{pdftitle} options. It also -% introduces a number of new options, which are listed +% \optname{pdfsubject}, \optname{pdftrapped}, and \optname{pdftitle} +% options. It also introduces a number of new options, which are listed % \vpagerefrange[above]{page:begin-new-options}{page:end-new-options}. % For consistency with \pkgname{hyperref}'s document-metadata naming % conventions (which are in turn based on \LaTeX's document-metadata @@ -1329,16 +1447,21 @@ % We load a bunch of helper packages: \pkgname{kvoptions} for % package-option processing, \pkgname{pdfescape} and \pkgname{stringenc} % for re-encoding \term{Unicode} strings, \pkgname{intcalc} for -% performing integer calculations (division and modulo), -% \pkgname{ifxetex} for detecting \XeTeX, and \pkgname{ifmtarg} for -% testing if a macro argument is empty or all spaces. +% performing integer calculations (division and modulo), \pkgname{iftex} +% for determining which \tex\ engine is being used, \pkgname{ifmtarg} +% for testing if a macro argument is empty or all spaces, +% \pkgname{etoolbox} for dynamically patching existing commands +% (specifically, \pkgname{hyperref}'s |\PDF@FinishDoc|), and +% \pkgname{ifthen} for convenient string comparisons. % \begin{macrocode} \RequirePackage{kvoptions} \RequirePackage{pdfescape} \RequirePackage{stringenc} \RequirePackage{intcalc} -\RequirePackage{ifxetex} +\RequirePackage{iftex} \RequirePackage{ifmtarg} +\RequirePackage{etoolbox} +\RequirePackage{ifthen} % \end{macrocode} % % \begin{macro}{\@ifmtargexp} @@ -1476,11 +1599,26 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\hyxmp@no@bad@parts} +% Complain about a bad \optname{pdfapart} or \optname{pdfuapart} if given +% trailing non-digits after a part number. +% \begin{macrocode} +\def\hyxmp@no@bad@parts#1\relax{% + \@ifnotmtarg{#1}{% + \PackageWarning{hyperxmp}{pdfapart and pdfuapart must be numeric}% + }% +} +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@pdfapart} % Prepare to store the \acro{PDF/A} part ID, which defaults to~``1''. % \begin{macrocode} \def\@pdfapart{1} -\define@key{Hyp}{pdfapart}{\hyxmp@pdfstringdef\@pdfapart{#1}} +\define@key{Hyp}{pdfapart}{% + \afterassignment\hyxmp@no@bad@parts\@tempcnta=0#1\relax + \hyxmp@pdfstringdef\@pdfapart{\the\@tempcnta}% +} % \end{macrocode} % \end{macro} % @@ -1488,8 +1626,112 @@ % Prepare to store the \acro{PDF/A} conformance ID, which defaults to~``B''. % \begin{macrocode} \def\@pdfaconformance{B} -\define@key{Hyp}{pdfaconformance}{\hyxmp@pdfstringdef\@pdfaconformance{#1}} +\define@key{Hyp}{pdfaconformance}{% + \uppercase{\hyxmp@pdfstringdef\@pdfaconformance{#1}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@pdfuapart} +% Prepare to store the \acro{PDF/UA} part ID. +% \begin{macrocode} +\def\@pdfuapart{} +\define@key{Hyp}{pdfuapart}{% + \afterassignment\hyxmp@no@bad@parts\@tempcnta=0#1\relax + \hyxmp@pdfstringdef\@pdfuapart{\the\@tempcnta}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@set@pdfx@major} +% Parse \optname{pdfxstandard} as ``|PDF/X-|\meta{major}\meta{other}'', +% setting |\hyxmp@pdfx@major| to \meta{major}. +% \begin{macrocode} +\newcommand*{\hyxmp@set@pdfx@major}[1]{\hyxmp@set@pdfx@major@i#1!} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@set@pdfx@major@i} +% This is the first helper macro for |\hyxmp@set@pdfx@major|. It stores +% the \acro{PDF/X} major version in |\@tempcnta|. +% \begin{macrocode} +\def\hyxmp@set@pdfx@major@i PDF/X-{% + \afterassignment\hyxmp@set@pdfx@major@ii + \@tempcnta=% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@set@pdfx@major@ii} +% \begin{macro}{\hyxmp@pdfx@major} +% This is the second helper macro for |\hyxmp@set@pdfx@major|. It +% copies the \acro{PDF/X} major version from |\@tempcnta| to +% |\@hyxmp@pdfx@major| and discards the rest of the \acro{PDF/X} +% standard string. +% \begin{macrocode} +\def\hyxmp@set@pdfx@major@ii#1!{% + \edef\hyxmp@pdfx@major{\the\@tempcnta}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\hyxmp@check@std} +% \changes{v5.0}{2020/03/10}{Added this macro} +% Compare a user-provided string to a fixed string. (Assumption: Both +% are names of \acro{PDF/X} standard versions.) If they match, undefine +% |\next|, which we assume was previously defined to issue an +% ``unrecognized standard'' warning message. +% \begin{macrocode} +\newcommand*\hyxmp@check@std[2]{% + \ifthenelse{\equal{#1}{#2}}% + {\global\let\next=\relax}% + {}% +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@pdfxstandard} +% Prepare to store the \acro{PDF/X} standard. +% \changes{v5.0}{2020/03/10}{Added this macro} +% \begin{macrocode} +\def\@pdfxstandard{} +\def\hyxmp@pdfx@major{} +\define@key{Hyp}{pdfxstandard}{% + \hyxmp@pdfstringdef\@pdfxstandard{#1}% % \end{macrocode} +% \begin{macro}{\next} +% Issue a warning message if the \acro{PDF/X} standard named by the user +% does not appear in a list of known \acro{PDF/X} standards. This is to +% caution the user that \pkgname{hyperxmp} generates standard-specific +% \acro{XMP} metadata and it can only guess at the correct format for +% new standard versions. (See the comments on +% page~\pageref{page:pdfx-id-schema} above the definition of +% |\hyxmp@pdfx@id@schema|, for example.) +% \begin{macrocode} + \gdef\next{% + \PackageWarning{hyperxmp}{Unrecognized PDF/X standard `#1'}% + }% + \hyxmp@check@std{#1}{PDF/X-1a:2001}% + \hyxmp@check@std{#1}{PDF/X-1a:2003}% + \hyxmp@check@std{#1}{PDF/X-3:2002}% + \hyxmp@check@std{#1}{PDF/X-3:2003}% + \hyxmp@check@std{#1}{PDF/X-4}% + \hyxmp@check@std{#1}{PDF/X-4p}% + \hyxmp@check@std{#1}{PDF/X-5g}% + \hyxmp@check@std{#1}{PDF/X-5n}% + \hyxmp@check@std{#1}{PDF/X-5pg}% + \next +% \end{macrocode} +% \begin{macro}{\hyxmp@pdfx@major} +% Parse the \acro{PDF/X} major version number from +% \optname{pdfxstandard} and assign it to |\hyxmp@pdfx@major|. +% \begin{macrocode} + \hyxmp@set@pdfx@major{#1}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} % \end{macro} % % \begin{macro}{\@pdfsource} @@ -1525,14 +1767,36 @@ % \end{macro} % % \begin{macro}{\@pdfversionid} -% Prepare to store a \acro{UUID} that represents the current version of -% the document. +% Prepare to store a string that represents the current version of +% the document. It defaults to ``|1|''. % \begin{macrocode} -\def\@pdfversionid{} +\def\@pdfversionid{1} \define@key{Hyp}{pdfversionid}{\hyxmp@pdfstringdef\@pdfversionid{#1}} % \end{macrocode} % \end{macro} % +% \begin{macrocode} +\RequirePackage{ifdraft} +% \end{macrocode} +% +% \begin{macro}{\@pdfrendition} +% \changes{v5.0}{2020/02/27}{Added the \protect\optname{pdfrendition} +% option} +% Prepare to store a tag describing how this rendition of the document +% differs from the master. The default value is |default|, which +% indicates the master document, except in the case of +% |\documentclass[draft]|, for which |\@pdfrendition| defaults to +% |draft|. +% \begin{macrocode} +\ifdraft{% + \def\@pdfrendition{draft}% +}{% + \def\@pdfrendition{default}% +} +\define@key{Hyp}{pdfrendition}{\hyxmp@pdfstringdef\@pdfrendition{#1}} +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@pdfpublication} % Prepare to store the name of the publication in which the % document was published. @@ -1761,24 +2025,58 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\hyxmp@suppress@pdf@metadata} -% Suppress \pkgname{hyperref} from writing \pdfterm{Author}, -% \pdfterm{Title}, \pdfterm{Subject}, and other \acro{PDF} metadata into -% the \pdfterm{Info} dictionary. This prevents conflicts between the -% \acro{PDF} metadata and the \acro{XMP} metadata, which cause -% \acro{PDF/A} validation to fail. The \acro{PDF} metadata can be -% restored by passing the \optname{keeppdfinfo} option to +% \begin{macro}{\hyxmp@no@info@lists} +% Suppress \pkgname{hyperref} from writing \pdfterm{Author} and +% \pdfterm{Keywords} into the \pdfterm{Info} dictionary. This prevents +% conflicts between the \acro{PDF} metadata and the \acro{XMP} metadata +% that cause \acro{PDF/A} validation to fail. The \acro{PDF} metadata +% can be restored by passing the \optname{keeppdfinfo} option to % |\hypersetup|. % \changes{v4.0}{2019/03/31}{Added this macro} +% \changes{v5.0}{2020/03/10}{Renamed this macros from +% \protect\cs{hyxmp@suppress@pdf@metadata} and rewrote it to replace, +% if possible, only \protect\pdfterm{Author} and \protect\pdfterm{Keywords}} +% \begin{macrocode} +\def\hyxmp@no@info@lists{% +% \end{macrocode} +% \begin{macro}{\hyxmp@suppress@pdf@info} +% \begin{macro}{\next} +% If |\patchcmd| fails for any reason---most likely, a modification to +% the \pkgname{hyperref} package---our fallback is to prevent +% \pkgname{hyperref} from writing \emph{any} data to the \acro{PDF} +% \pdfterm{Info} dictionary. % \begin{macrocode} -\def\hyxmp@suppress@pdf@metadata{% - \global\let\PDF@FinishDoc=\@empty + \def\hyxmp@suppress@pdf@info{% + \global\let\PDF@FinishDoc=\@empty + \PackageWarningNoLine{hyperxmp}{% + Suppressing the _entire_ PDF Info dictionary.\MessageBreak + Please notify the hyperxmp maintainer% + }% + }% + \let\next=\relax + \patchcmd + {\PDF@FinishDoc}% + {/Author(\@pdfauthor)}% + {}% + {}% + {\let\next=\hyxmp@suppress@pdf@info}% + \patchcmd + {\PDF@FinishDoc}% + {/Keywords(\@pdfkeywords)}% + {}% + {}% + {\let\next=\hyxmp@suppress@pdf@info}% + \next } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macrocode} \define@key{Hyp}{keeppdfinfo}[true]{% - \gdef\hyxmp@suppress@pdf@metadata{}% + \gdef\hyxmp@no@info@lists{}% } % \end{macrocode} -% \end{macro} % % \changes{v2.1}{2012/09/16}{Enabled \protect\pkgname{hyperxmp} and % \protect\pkgname{hyperref} to be loaded in either order. This addresses @@ -2005,10 +2303,10 @@ \@pdfsubject \@pdfsubtitle \@pdftitle - \@pdftype + \@pdfuapart \@pdfurl - \@pdfversionid \@pdfvolumenum + \@pdfxstandard }% \ifx\hyxmp@concated@metadata\@empty \PackageWarningNoLine{hyperxmp}{% @@ -2022,6 +2320,40 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\hyxmp@check@standards} +% Most \acro{PDF} standards require that certain metadata be present. +% If compliance with a \acro{PDF} standard is claimed but any of the +% metadata it requires are absent, issue a warning message. +% \changes{v5.0}{2020/03/11}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@check@standards}{% +% \end{macrocode} +% \begin{macro}{\hyxmp@standards} +% We define |\hyxmp@standards| to be non-empty if \emph{any} \acro{PDF} +% standard is claimed (currently, \acro{PDF/A}, \acro{PDF/X}, or +% \acro{PDF/UA}. +% \begin{macrocode} + \def\hyxmp@standards{% + \@pdfapart + \@pdfxstandard + \@pdfuapart + }% +% \end{macrocode} +% Check that a document title was provided and is non-empty. +% \begin{macrocode} + \@ifnotmtargexp{\hyxmp@standards}{% + \@ifmtargexp{\@pdftitle}{% + \PackageWarning{hyperxmp}{% + Missing pdftitle (required for PDF standards\MessageBreak + compliance)% + }% + }% + }% +} +% \end{macrocode} +% \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 @@ -2071,14 +2403,8 @@ \fi \hyxmp@xmlify\@pdfmetalang % \end{macrocode} -% If the author explicitly specified the document date, override the -% compilation timestamp with the specified date. -% \begin{macrocode} - \ifx\@pdfdatetime\@empty - \else - \edef\hyxmp@today{\@pdfdatetime}% - \fi -% \end{macrocode} +% \changes{v5.0}{2020/03/17}{Don't set any document dates (creation, +% modification, or metadata) from \string\optname{pdfdate}} % If the author left \optname{pdftitle} blank but specified |\title|, % use the title for \optname{pdftitle}. Likewise, if the author left % \optname{pdfauthor} blank but specified |\author|, use the author for @@ -2100,6 +2426,29 @@ }% {}% % \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 +% \end{macrocode} % Older versions of \pkgname{hyperref} write the \pdfterm{Info} % dictionary to the \acro{PDF} file at the end of the document. New % versions of \pkgname{hyperref} write the \pdfterm{Info} dictionary to @@ -2108,11 +2457,11 @@ % we suppress writing the \pdfterm{Info} dictionary here, at the % beginning of the document. % \changes{v4.1}{2019/04/02}{Invoke -% \protect\cs{hyxmp@suppress@pdf@metadata} at the beginning of the +% \protect\cs{hyxmp@no@info@lists} at the beginning of the % document, for compatibility with both newer and older versions of % \protect\pkgname{hyperref}} % \begin{macrocode} - \hyxmp@suppress@pdf@metadata + \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 @@ -2142,10 +2491,15 @@ % |\hypersetup| command. The functions in this section convert % author-supplied lists (e.g.,~|pdfkeywords={foo, bar, baz}|) into % \LaTeX\ lists (e.g.,~|\@elt {foo}| |\@elt {bar}| |\@elt {baz}|) that -% can be more easily manipulated (Section~\ref{sec:list-manip}); trim -% spaces off the ends of strings (Section~\ref{sec:trim-spaces}); and, -% in Section~\ref{sec:text-xml}, convert text to \acro{XML} (e.g.,~from -% |<scott+hyxmp@pakin.org>| to |<scott+hyxmp@pakin.org>|). +% can be more easily manipulated (Section~\ref{sec:list-manip}); parse +% dates in both \acro{PDF} and \acro{XMP} formats +% (Section~\ref{sec:date-manip}; trim spaces off the ends of strings +% (Section~\ref{sec:trim-spaces}); convert text to \acro{XML} +% (e.g.,~from |<scott+hyxmp@pakin.org>| to +% |<scott+hyxmp@pakin.org>|) (Section~\ref{sec:text-xml}); +% simplify the pretty-printing of a begin tag, \acro{XML} text, and end +% tag (Section~\ref{sec:output-xml}; and provide metadata in multiple +% languages (Section~\ref{sec:lang-alt}). % % \subsubsection{List manipulation} % \label{sec:list-manip} @@ -2345,7 +2699,7 @@ % \changes{v3.2}{2017/02/20}{Added this macro} % \begin{macrocode} \def\hyxmp@as@xmp@date#1{% - \expandafter\ifx\hyxmp@first@char@i#1\relax D% + \expandafter\ifnum\expandafter`\hyxmp@first@char@i#1\relax=`D \hyxmp@pdf@to@xmp@date{#1}% \else #1% @@ -2561,15 +2915,16 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\hyxmp@today@define} +% \begin{macro}{\hyxmp@today@xmp@define} % Use \tex\ primitives to define a given macro as today's date in -% \textsc{yyyy}-\textsc{mm}-\textsc{dd}|T|hh|:|mm format. +% \textsc{yyyy}-\textsc{mm}-\textsc{dd}|T|hh|:|mm|Z| format. % \changes{v2.4}{2013/12/21}{Added this macro} % \changes{v3.0}{2016/07/03}{Modified to accept the name of a macro % to define} % \changes{v3.2}{2017/02/21}{Modified to include hours and minutes} +% \changes{v5.0}{2020/03/16}{Modified to specify UTC} % \begin{macrocode} -\def\hyxmp@today@define#1{% +\def\hyxmp@today@xmp@define#1{% % \end{macrocode} % The date is a straightforward representation of \tex's |\year|, % |\month|, and |\day| primitives, with the latter two zero-padded to @@ -2594,48 +2949,89 @@ % macro~|#1|. % \begin{macrocode} \@tempcnta=\time - \divide\@tempcnta by 60% - \ifnum\@tempcnta<10% + \divide\@tempcnta by 60 + \ifnum\@tempcnta<10 \xdef#1{#1T0\the\@tempcnta}% \else \xdef#1{#1T\the\@tempcnta}% \fi - \multiply\@tempcnta by -60% + \multiply\@tempcnta by -60 \advance\@tempcnta by \time - \ifnum\@tempcnta<10% + \ifnum\@tempcnta<10 \xdef#1{#1:0\the\@tempcnta}% \else \xdef#1{#1:\the\@tempcnta}% \fi + \xdef#1{#1Z}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@try@today} +% If |\hyxmp@today@xmp| is still empty and |#1| is defined, evaluate |#2|. +% Otherwise, do nothing. +% \begin{macrocode} +\def\hyxmp@try@today#1#2{% + \@ifmtargexp{\hyxmp@today@xmp}{% + \@ifundefined{#1}{}{#2}% + }{}% } % \end{macrocode} % \end{macro} % -% \begin{macro}{\hyxmp@today} -% Define |\hyxmp@today| as the current date and (if available) time and +% \begin{macro}{\hyxmp@today@xmp} +% Define |\hyxmp@today@xmp| as the current date and (if available) time and % timezone in \acro{XMP} \xmpterm{Date} format~\cite{Adobe2012:XMP}. % \changes{v2.4}{2013/12/24}{Modified the code to parse the time and % timezone from \texttt{\string\string\string\pdfcreationdate}, as % proposed by Florian Breitwieser} +% \changes{v5.0}{2020/03/15}{Support \string\XeTeX's \string\cs{filemoddate}} % \begin{macrocode} -\@ifundefined{pdffeedback}{% - \@ifundefined{pdfcreationdate}{% +\def\hyxmp@today@xmp{} % \end{macrocode} -% Case 1: Neither |\pdffeedback| nor |\pdfcreationdate| is defined -% (\XeLaTeX\ and regular \LaTeX). +% Case 1: |\pdfcreationdate| is defined (\pdfLaTeX\ and pre-0.85 \LuaLaTeX). % \begin{macrocode} - \hyxmp@today@define\hyxmp@today - }{% +\hyxmp@try@today{pdfcreationdate}{% + \edef\hyxmp@today@xmp{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate}% +} +% \end{macrocode} +% Case 2: |\pdffeedback| is defined (\LuaLaTeX~0.85+). +% \begin{macrocode} +\hyxmp@try@today{pdffeedback}{% + \edef\hyxmp@today@xmp{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate}% +} % \end{macrocode} -% Case 2: |\pdfcreationdate| is defined (\pdfLaTeX\ and pre-0.85 \LuaLaTeX). +% Case 3: |\filemoddate| is defined (\XeLaTeX). +% In this case, we treat the timestamp of the job's |.aux| file as the +% current date/time. % \begin{macrocode} - \edef\hyxmp@today{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate}% +\hyxmp@try@today{filemoddate}{% + \edef\hyxmp@today@xmp{\filemoddate{\jobname.aux}}% + \edef\next{% + \edef\noexpand\hyxmp@today@xmp{\noexpand\hyxmp@as@xmp@date{\hyxmp@today@xmp}}% }% -}{% + \next +}% % \end{macrocode} -% Case 3: |\pdffeedback| is defined (\LuaLaTeX~0.85+). +% Case 4: None of the above. +% Do the best we can using the available \tex\ primitives (|\year|, +% |\month|, |\day|, and |\time|. % \begin{macrocode} - \edef\hyxmp@today{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate}% +\hyxmp@try@today{year}{% + \hyxmp@today@xmp@define\hyxmp@today@xmp +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@today@pdf} +% Define |\hyxmp@today@pdf| as the current date and (if available) time +% and timezone in \acro{PDF} date format~\cite{Adobe2008:PDF}. To do so +% we simply convert |\hyxmp@today@xmp|, defined above, from \acro{XMP} +% to \acro{PDF} using |\hyxmp@xmp@to@pdf@date|. +% \changes{v5.0}{2020/03/16}{Added this macro} +% \begin{macrocode} +\expandafter\edef\expandafter\hyxmp@today@pdf\expandafter{% + \expandafter\hyxmp@xmp@to@pdf@date\expandafter{\hyxmp@today@xmp}% } % \end{macrocode} % \end{macro} @@ -2737,18 +3133,6 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\hyxmp@reencode} -% This is now a placeholder macro needed only for |\@pdfmetalang| in -% the |\begin{document}|. -% \changes{v1.3}{2011/04/25}{Introduced this macro to re-encode Unicode -% strings as 8-bit strings before manipulating them into \acro{XMP} -% schema. This change addresses a bug reported by Martin M\"unch} -% \changes{v2.0}{2012/08/02}{Replaced with an empty macro by Heiko Oberdiek} -% \begin{macrocode} -\newcommand*{\hyxmp@reencode}[1]{} -% \end{macrocode} -% \end{macro} -% % \begin{macro}{\SE->pdfdoc@03} % Preserve \acro{ETX} (|^^C|), which is normally an invalid character in % \term{PDFDocEncoding}. We use it in \pkgname{hyperxmp} (and @@ -2793,7 +3177,7 @@ \StringEncodingConvert \hyxmp@text\hyxmp@text{utf16be}{utf32be}% }{% - \ifxetex + \ifXeTeX \hyxmp@xetex@crap \else \StringEncodingConvert @@ -3115,6 +3499,118 @@ % \end{macro} % % +% \subsubsection{Outputting structured XML} +% \label{sec:output-xml} +% +% An \acro{XMP} packet consists of structured \acro{XML} data. We +% define some helper routines to handle the repetitive tasks of +% indenting a consistent number of spaces, inserting begin and end tags, +% and escaping arbitrary text as necessary for \acro{XML} compatibility. +% +% \begin{macro}{\hyxmp@extra@indent} +% This macro is used internally to increase the amount of indentation +% when writing certain \acro{XML} data. It is normally defined as empty +% but can temporarily be redefined to a sequence of |\space| characters. +% \begin{macrocode} +\newcommand*{\hyxmp@extra@indent}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@add@simple} +% Given an \acro{XMP} tag~(|#1|) and a string~(|#2|), if the string is +% nonempty, add a begin tag, the string, and an end tag to the packet. +% The ``|simple|'' in the macro name indicates that the string is output +% without variations for different languages. +% \changes{v2.0}{2012/08/25}{Added this macro} +% \changes{v5.0}{2020/02/21}{Insert the tag name (\string\texttt{\#1}) +% verbatim} +% \begin{macrocode} +\newcommand*{\hyxmp@add@simple}[2]{% + \@ifnotmtargexp{#2}{% + \hyxmp@xmlify{#2}% + \hyxmp@add@to@xml{\hyxmp@extra@indent______<}% + \xdef\hyxmp@xml{\hyxmp@xml#1}% + \hyxmp@add@to@xml{>\hyxmp@xmlified</}% + \xdef\hyxmp@xml{\hyxmp@xml#1>^^J}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@add@simple@var} +% Given an \acro{XMP} tag~(|#1|) and a variable name~(|#2|), if the +% string is defined, add a begin tag, the string, and an end tag to the +% packet. The ``|simple|'' in the macro name indicates that the string +% is output without variations for different languages. +% |\hyxmp@add@simple@var| differs from |\hyxmp@add@simple| in that the +% former includes defined but empty values in the \acro{XMP} packet +% while the latter excludes both undefined and defined but empty values. +% \changes{v2.4}{2013/12/21}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@add@simple@var}[2]{% + \expandafter\ifx\csname#2\endcsname\relax + \else + \hyxmp@xmlify{\csname#2\endcsname}% + \hyxmp@add@to@xml{% + \hyxmp@extra@indent______<#1>\hyxmp@xmlified</#1>^^J% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@add@simple@lang} +% Given an \acro{XMP} tag~(|#1|) and a string~(|#2|), if the string is +% nonempty, add a begin tag, the string, and an end tag to the packet. +% The ``|simple|'' in the macro name indicates that the string is output +% without variations for different languages. However, if the string +% begins with a language code in square brackets, specify that as the +% (sole) language for the tag. +% \changes{v4.0}{2019/03/12}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@add@simple@lang}[2]{% + \@ifnotmtarg{#2}{% + \hyxmp@xmlify{#2}% + \expandafter\hyxmp@add@simple@lang@i\hyxmp@xmlified\relax{#1}% + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@add@simple@lang@i} +% This is a helper macro for |\hyxmp@add@simple@lang|. It takes an +% optional language code (in brackets), text up to |\relax|, and a tag, +% 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[]}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@add@simple@lang@ii} +% This is another helper macro for |\hyxmp@add@simple@lang|. It takes +% an mandatory language code (in brackets; can be empty), text up to +% |\relax|, and a tag, and typesets the text within the \acro{XML} tag. +% \begin{macrocode} +\def\hyxmp@add@simple@lang@ii[#1]#2\relax#3{% + \@ifnotmtarg{#2}{% + \hyxmp@xmlify{#2}% + \@ifmtarg{#1}{% + \hyxmp@add@to@xml{% +______<#3>\hyxmp@xmlified</#3>^^J% + }% + }{% + \hyxmp@add@to@xml{% +______<#3 xml:lang="#1">\hyxmp@xmlified</#3>^^J% + }% + }% + }% +} +% \end{macrocode} +% \end{macro} +% +% % \subsubsection{Providing metadata in multiple languages} % \label{sec:lang-alt} % @@ -3418,9 +3914,9 @@ % addition to the document-specified timestamp} % \begin{macrocode} \newcommand*{\hyxmp@def@InstanceID}{% - \hyxmp@today@define{\hyxmp@seed@string}% + \hyxmp@today@xmp@define{\hyxmp@seed@string}% \edef\hyxmp@seed@string{% - \jobname:\@pdftitle:\@pdfauthor:\hyxmp@today:\hyxmp@seed@string + \jobname:\@pdftitle:\@pdfauthor:\hyxmp@today@xmp:\hyxmp@seed@string }% \expandafter\hyxmp@seed@rng\expandafter{\hyxmp@seed@string}% \edef\hyxmp@rand@num{\the\@tempcnta}% @@ -3446,8 +3942,8 @@ % (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/A} Identification -% (Section~\ref{sec:pdfa-id}). The |\hyxmp@construct@packet| macro +% (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 @@ -3536,6 +4032,91 @@ _______________________________________________________________^^J% % \subsubsection{The Adobe PDF schema} % \label{sec:adobe-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 +% because \pkgname{hyperxmp} sees an empty producer and therefore omits +% writing a \xmpprop{pdf:Producer} to the \acro{XMP} packet, causing a +% mismatch between the data in the \acro{XMP} packet and the data in the +% \acro{PDF} \pdfterm{Info} dictionary. To ensure consistency between +% \acro{XMP} and \pdfterm{Info}, we explicitly define our own default +% |\@pdfproducer| here. +% +% \begin{macro}{\@pdfproducer} +% \begin{macro}{\hyxmp@define@pdfproducer} +% Define |\@pdfproducer| using the banner string if available or the +% \tex\ engine's version number if not. +% \changes{v5.0}{2020/03/01}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@define@pdfproducer}{% + \gdef\@pdfproducer{TeX} + \ifPDFTeX + \expandafter\hyxmp@banner@to@producer\expandafter{\pdftexbanner} + \else + \ifLuaTeX + \expandafter\hyxmp@banner@to@producer\expandafter{\luatexbanner} + \else + \ifXeTeX + \edef\@pdfproducer{XeTeX version \the\XeTeXversion\XeTeXrevision} + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@pdfproducer} +% \begin{macro}{\hyxmp@banner@to@producer} +% Define |\@pdfproducer| as the \tex\ engine's banner string +% \ifPDFTeX +% (e.g.,~``\texttt{\pdftexbanner}''), +% \else +% \ifLuaTeX +% (e.g.,~``\texttt{\luatexbanner}''), +% \else +% (e.g.,~``\texttt{This is pdfTeX, Version 3.14159265-2.6-1.40.20 +% (TeX Live 2019/Debian) kpathsea version 6.3.1}''), +% \fi +% \fi +% removing the initial ``\texttt{This is}'' if possible (specifically, +% when $\varepsilon$-\TeX's\index{e-TeX=$\varepsilon$-\TeX} +% |\scantokens| primitive is available). +% \begin{macrocode} +\def\hyxmp@banner@to@producer#1{% + \ifx\scantokens\relax + \gdef\@pdfproducer{#1}% + \else + \scantokens{\makeatletter\hyxmp@remove@this#1\relax\makeatother}% + \fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@pdfproducer} +% \begin{macro}{\hyxmp@remove@this} +% Define |\@pdfproducer| as a given banner string with the initial +% ``\texttt{This is}'' stripped off the beginning. +% \begin{macrocode} +\def\hyxmp@remove@this This is #1\relax{\gdef\@pdfproducer{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% If \optname{pdfproducer} wasn't specified and \pkgname{hyperref} +% didn't already define |\@pdfproducer|---old versions of +% \pkgname{hyperref} did; newer ones don't---try to assign a meaningful +% producer string and use that. +% \changes{v5.0}{2020/03/02}{Define a default producer} +% \begin{macrocode} +\AtBeginDocument{% + \ifx\@pdfproducer\relax + \hyxmp@define@pdfproducer + \fi +} +% \end{macrocode} +% % \begin{macro}{\hyxmp@pdf@schema} % Add properties defined by the Adobe \acro{PDF} schema to the |\hyxmp@xml| % macro. @@ -3549,7 +4130,7 @@ _______________________________________________________________^^J% % \xmpprop{pdf:PDFVersion} property). Unlike most of the other schemata % that \pkgname{hyperxmp} supports, the Adobe \acro{PDF} schema is % \emph{always} included in the document, even if all of its keys are -% empty. This is because \acro{PDF/A}-1b requires the keywords and +% empty. This is because \PDFstd{A}{1}{b}{} requires the keywords and % producer to be the same in the \acro{XMP} metadata and the \acro{PDF} % metadata. Because \pkgname{hyperref} always specifies the % \pdfterm{Keywords} and \pdfterm{Producer} fields, even when they're @@ -3560,10 +4141,15 @@ _______________________________________________________________^^J% % \texttt{\string\string\string\hyxmp@pdf@schema} % \protect\emph{always} include the Adobe \protect\acro{PDF} schema, % even when empty. Florian Breitwieser noted that this is necessary -% for \protect\acro{PDF/A}-1b compliance} +% for \protect\PDFstd{A}{1}{b}{} compliance} +% \changes{v5.0}{2020/02/28}{Honor \protect\optname{pdftrapped}} % \begin{macrocode} - \hyxmp@add@simple@var{pdf:Keywords}{@pdfkeywords}% \hyxmp@add@simple@var{pdf:Producer}{@pdfproducer}% + \hyxmp@add@simple@var{pdf:Keywords}{@pdfkeywords}% + \hyxmp@add@simple{pdf:Trapped}{\@pdftrapped}% +% \end{macrocode} +% Specify the \acro{PDF} version. +% \begin{macrocode} \@ifundefined{pdfvariable}{% \@ifundefined{pdfminorversion}{% % \end{macrocode} @@ -3586,106 +4172,6 @@ _______________________________________________________________^^J% % \end{macrocode} % \end{macro} % -% \begin{macro}{\hyxmp@extra@indent} -% This macro is used internally to increase the amount of indentation -% when writing certain \acro{XML} data. It is normally defined as empty -% but can temporarily be redefined to a sequence of |\space| characters. -% \begin{macrocode} -\newcommand*{\hyxmp@extra@indent}{} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@add@simple} -% Given an \acro{XMP} tag~(|#1|) and a string~(|#2|), if the string is -% nonempty, add a begin tag, the string, and an end tag to the packet. -% The ``|simple|'' in the macro name indicates that the string is output -% without variations for different languages. -% \changes{v2.0}{2012/08/25}{Added this macro} -% \begin{macrocode} -\newcommand*{\hyxmp@add@simple}[2]{% - \@ifnotmtargexp{#2}{% - \hyxmp@xmlify{#2}% - \hyxmp@add@to@xml{% - \hyxmp@extra@indent______<#1>\hyxmp@xmlified</#1>^^J% - }% - }% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@add@simple@var} -% Given an \acro{XMP} tag~(|#1|) and a variable name~(|#2|), if the -% string is defined, add a begin tag, the string, and an end tag to the -% packet. The ``|simple|'' in the macro name indicates that the string -% is output without variations for different languages. -% |\hyxmp@add@simple@var| differs from |\hyxmp@add@simple| in that the -% former includes defined but empty values in the \acro{XMP} packet -% while the latter excludes both undefined and defined but empty values. -% \changes{v2.4}{2013/12/21}{Added this macro} -% \begin{macrocode} -\newcommand*{\hyxmp@add@simple@var}[2]{% - \expandafter\ifx\csname#2\endcsname\relax - \else - \hyxmp@xmlify{\csname#2\endcsname}% - \hyxmp@add@to@xml{% - \hyxmp@extra@indent______<#1>\hyxmp@xmlified</#1>^^J% - }% - \fi -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@add@simple@lang} -% Given an \acro{XMP} tag~(|#1|) and a string~(|#2|), if the string is -% nonempty, add a begin tag, the string, and an end tag to the packet. -% The ``|simple|'' in the macro name indicates that the string is output -% without variations for different languages. However, if the string -% begins with a language code in square brackets, specify that as the -% (sole) language for the tag. -% \changes{v4.0}{2019/03/12}{Added this macro} -% \begin{macrocode} -\newcommand*{\hyxmp@add@simple@lang}[2]{% - \@ifnotmtarg{#2}{% - \hyxmp@xmlify{#2}% - \expandafter\hyxmp@add@simple@lang@i\hyxmp@xmlified\relax{#1}% - }% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@add@simple@lang@i} -% This is a helper macro for |\hyxmp@add@simple@lang|. It takes an -% optional language code (in brackets), text up to |\relax|, and a tag, -% 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[]}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@add@simple@lang@ii} -% This is another helper macro for |\hyxmp@add@simple@lang|. It takes -% an mandatory language code (in brackets; can be empty), text up to -% |\relax|, and a tag, and typesets the text within the \acro{XML} tag. -% \begin{macrocode} -\def\hyxmp@add@simple@lang@ii[#1]#2\relax#3{% - \@ifnotmtarg{#2}{% - \hyxmp@xmlify{#2}% - \@ifmtarg{#1}{% - \hyxmp@add@to@xml{% -______<#3>\hyxmp@xmlified</#3>^^J% - }% - }{% - \hyxmp@add@to@xml{% -______<#3 xml:lang="#1">\hyxmp@xmlified</#3>^^J% - }% - }% - }% -} -% \end{macrocode} -% \end{macro} -% % % \subsubsection{The Dublin Core schema} % \label{sec:dublin-core} @@ -3857,7 +4343,7 @@ ______</dc:#2>^^J% \hyxmp@rdf@dc[\ifHy@pdfa]{description}{\@pdfsubject}% \hyxmp@rdf@dc{rights}{\@pdfcopyright}% \hyxmp@singleton@dc{publisher}{\@pdfpublisher}% - \hyxmp@singleton@dc[Seq]{date}{\hyxmp@today}% + \hyxmp@singleton@dc[Seq]{date}{\hyxmp@today@xmp}% \hyxmp@singleton@dc{language}{\@pdflang}% \hyxmp@singleton@dc{type}{\@pdftype}% \hyxmp@list@to@xml[\ifHy@pdfa]{creator}{Seq}{\hyxmp@pdfauthor}% @@ -3950,6 +4436,7 @@ ______</dc:#2>^^J% \hyxmp@add@simple{xmpMM:DocumentID}{\hyxmp@DocumentID}% \hyxmp@add@simple{xmpMM:InstanceID}{\hyxmp@InstanceID}% \hyxmp@add@simple{xmpMM:VersionID}{\@pdfversionid}% + \hyxmp@add@simple{xmpMM:RenditionClass}{\@pdfrendition}% } % \end{macrocode} % \end{macro} @@ -3958,38 +4445,6 @@ ______</dc:#2>^^J% % \subsubsection{The XMP Basic schema} % \label{sec:xmp-basic} % -% \begin{macro}{\hyxmp@define@createdate} -% \begin{macro}{\hyxmp@createdate} -% Define |\hyxmp@createdate| as the document's creation date but in -% \acro{XMP} date format, not \acro{PDF} date format. We use -% |\hyxmp@createdate| for the \xmpprop{xmp:CreateDate}, -% \xmpprop{xmp:ModifyDate}, and \xmpprop{xmp:MetadataDate} fields. -% \begin{macrocode} -\newcommand*{\hyxmp@define@createdate}{% - \@ifundefined{pdffeedback}{% - \@ifundefined{pdfcreationdate}{% -% \end{macrocode} -% Case 1: Neither |\pdffeedback| nor |\pdfcreationdate| is defined -% (\XeLaTeX\ and regular \LaTeX). -% \begin{macrocode} - \hyxmp@today@define\hyxmp@createdate - }{% -% \end{macrocode} -% Case 2: |\pdfcreationdate| is defined (\pdfLaTeX\ and pre-0.85 \LuaLaTeX). -% \begin{macrocode} - \edef\hyxmp@createdate{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate}% - }% - }{% -% \end{macrocode} -% Case 3: |\pdffeedback| is defined (\LuaLaTeX~0.85+). -% \begin{macrocode} - \edef\hyxmp@createdate{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate}% - }% -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \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 @@ -4007,47 +4462,38 @@ ______</dc:#2>^^J% % \protect\pkgname{hyperxmp} code} % \begin{macrocode} \newcommand*{\hyxmp@xmp@basic@schema}{% - \hyxmp@define@createdate % \end{macrocode} % For the document's creation date, use the user-specified % |\@pdfcreationdate| if defined and non-empty. Otherwise use our -% fabricated |\hyxmp@createdate|. +% fabricated |\hyxmp@today@xmp|. % \begin{macrocode} - \@ifundefined{@pdfcreationdate}{% - \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@createdate}% + \@ifmtargexp{\@pdfcreationdate}{% + \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@today@xmp}% }{% - \ifx\@pdfcreationdate\@empty - \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@createdate}% - \else - \hyxmp@add@simple{xmp:CreateDate}{% - \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfcreationdate}}% - \fi + \hyxmp@add@simple{xmp:CreateDate}{% + \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfcreationdate}}% }% % \end{macrocode} % For the document's modification date, use the user-specified % |\@pdfmoddate| if defined and non-empty. Otherwise use our -% fabricated |\hyxmp@createdate|. +% fabricated |\hyxmp@today@xmp|. % \begin{macrocode} - \@ifundefined{@pdfmoddate}{% - \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@createdate}% + \@ifmtargexp{\@pdfmoddate}{% + \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@today@xmp}% }{% - \ifx\@pdfmoddate\@empty - \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@createdate}% - \else - \hyxmp@add@simple{xmp:ModifyDate}{% - \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfmoddate}}% - \fi + \hyxmp@add@simple{xmp:ModifyDate}{% + \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfmoddate}}% }% % \end{macrocode} % For the document's metadata date, use the user-specified % |\@pdfmetadatetime| if defined and non-empty. Otherwise use our -% fabricated |\hyxmp@createdate|. +% fabricated |\hyxmp@today@xmp|. % \begin{macrocode} - \ifx\@pdfmetadatetime\@empty - \hyxmp@add@simple{xmp:MetadataDate}{\hyxmp@createdate}% - \else + \@ifmtargexp{\@pdfmetadatetime}{% + \hyxmp@add@simple{xmp:MetadataDate}{\hyxmp@today@xmp}% + }{% \hyxmp@add@simple{xmp:MetadataDate}{\@pdfmetadatetime}% - \fi + }% % \end{macrocode} % Define the creation tool and the base \acro{URL}. % \begin{macrocode} @@ -4080,16 +4526,17 @@ ______</dc:#2>^^J% % \end{macro} % % -% \subsubsection{The PDF/A Identification schema} -% \label{sec:pdfa-id} +% \subsubsection{PDF/* Identification schemata} +% \label{sec:pdfX-id} % % \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 % properties identify a document as conforming to a particular -% \acro{PDF/A} standard. We default to \acro{PDF/A}-1b if any \acro{PDF/A} -% compliance is detected but let the author override the ``1'' with -% \optname{pdfapart} and the ``B'' with \optname{pdfaconformance}. +% \acro{PDF/A} standard. We default to \PDFstd{A}{1}{b}{} if any +% \acro{PDF/A} compliance is detected but let the author override the +% ``1'' with \optname{pdfapart} and the ``B'' with +% \optname{pdfaconformance}. % \changes{v2.4}{2013/12/21}{Added this macro} % \changes{v2.9}{2016/04/12}{Let the author specify the \protect\acro{PDF/A} % part and conformance IDs, as requested by Leonid Sinev} @@ -4103,6 +4550,44 @@ ______</dc:#2>^^J% % \end{macrocode} % \end{macro} % +% \begin{macro}{\hyxmp@pdfua@id@schema} +% If the document conforms to a \acro{PDF/UA} standard, the author can +% indicate the standard version with \optname{pdfuapart}. +% \changes{v5.0}{2020/02/16}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@pdfua@id@schema}{% + \hyxmp@add@simple{pdfuaid:part}{\@pdfuapart}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@pdfx@id@schema} +% \label{page:pdfx-id-schema} +% If the document conforms to a \acro{PDF/X} standard, the author can +% indicate the standard version with \optname{pdfxstandard}. We +% separately handle \PDFstd{X}{1}{}{}, \PDFstd{X}{2}{}{} and +% \PDFstd{X}{3}{}{}, and \PDFstd{X}{4}{}{} onwards. +% \changes{v5.0}{2020/02/26}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@pdfx@id@schema}{% + \@tempcnta=0\hyxmp@pdfx@major\relax + \ifnum\@tempcnta=0 + \else + \ifnum\@tempcnta=1 + \hyxmp@add@simple{pdfx:GTS_PDFXVersion}{PDF/X-1:2001}% + \hyxmp@add@simple{pdfx:GTS_PDFXConformance}{\@pdfxstandard}% + \else + \ifnum\@tempcnta<4 + \hyxmp@add@simple{pdfx:GTS_PDFXVersion}{\@pdfxstandard}% + \else + \hyxmp@add@simple{pdfxid:GTS_PDFXVersion}{\@pdfxstandard}% + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% % % \subsubsection{The IPTC Photo Metadata schema} % \label{sec:photo-meta} @@ -4396,11 +4881,15 @@ __________</rdf:li>^^J% % takes as input an optional type (defaults to \xmpterm{Text}) and a % mandatory name, category, and description. % \changes{v4.0}{2019/03/15}{Added this macro} +% \changes{v5.0}{2020/02/21}{Insert the property name (\string\texttt{\#2}) +% verbatim} % \begin{macrocode} \newcommand{\hyxmp@declare@property}[4][Text]{% \hyxmp@add@to@xml{% ________________<rdf:li rdf:parseType="Resource">^^J% -__________________<pdfaProperty:name>#2</pdfaProperty:name>^^J% +__________________<pdfaProperty:name>}% + \xdef\hyxmp@xml{\hyxmp@xml#2}% + \hyxmp@add@to@xml{</pdfaProperty:name>^^J% __________________<pdfaProperty:valueType>#1</pdfaProperty:valueType>^^J% __________________<pdfaProperty:category>#3</pdfaProperty:category>^^J% __________________<pdfaProperty:description>#4</pdfaProperty:description>^^J% @@ -4429,6 +4918,24 @@ ______________________</rdf:li>^^J% % \end{macrocode} % \end{macro} % +% \begin{macro}{\hyxmp@pdf@extensions} +% Declare the Adobe \acro{PDF} schema. +% \changes{v5.0}{2020/02/27}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@pdf@extensions}{% + \hyxmp@begin@ext@decl + {Adobe PDF Schema}% + {pdf}% + {http://ns.adobe.com/pdf/1.3/}% + \hyxmp@declare@property + {Trapped}% + {internal}% + {Indication if the document has been modified to include trapping information}% + \hyxmp@end@ext@decl +}% +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\hyxmp@mm@extensions} % Declare the \acro{XMP} Media Management schema. % \changes{v4.0}{2019/03/15}{Added this macro} @@ -4452,6 +4959,10 @@ ______________________</rdf:li>^^J% {VersionID}% {internal}% {Document version identifier}% + \hyxmp@declare@property + {RenditionClass}% + {internal}% + {The manner in which a document is rendered}% \hyxmp@end@ext@decl }% % \end{macrocode} @@ -4480,6 +4991,67 @@ ______________________</rdf:li>^^J% % \end{macrocode} % \end{macro} % +% \begin{macro}{\hyxmp@pdfua@id@extensions} +% Declare the \acro{PDF/UA} Universal Accessibility schema. +% \changes{v5.0}{2020/02/15}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@pdfua@id@extensions}{% + \hyxmp@begin@ext@decl + {PDF/UA Universal Accessibility Schema}% + {pdfuaid}% + {http://www.aiim.org/pdfua/ns/id/}% + \hyxmp@declare@property + [Integer]% + {part}% + {internal}% + {Part of ISO 14289 standard}% + \hyxmp@end@ext@decl +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@pdfx@id@extensions} +% Declare the schema used pre-\PDFstd{X}{4}{}{}. Because Adobe Acrobat DC +% (at least) defines this even for \PDFstd{X}{4}{}{} and later, we follow +% suit. +% \changes{v5.0}{2020/02/26}{Added this macro} +% \begin{macrocode} +\newcommand*{\hyxmp@pdfx@id@extensions}{% + \ifx\hyxmp@pdfx@major\empty + \else + \hyxmp@begin@ext@decl + {Adobe Document Info PDF/X eXtension Schema}% + {pdfx}% + {http://ns.adobe.com/pdfx/1.3/}% + \hyxmp@declare@property + {GTS_PDFXVersion}% + {internal}% + {ID of PDF/X standard}% + \hyxmp@declare@property + {GTS_PDFXConformance}% + {internal}% + {Conformance level of PDF/X standard}% + \hyxmp@end@ext@decl + \fi +% \end{macrocode} +% Declare the schema used in \PDFstd{X}{4}{}{} and later versions. +% \begin{macrocode} + \@tempcnta=0\hyxmp@pdfx@major\relax + \ifnum\@tempcnta>3 + \hyxmp@begin@ext@decl + {PDF/X ID Schema}% + {pdfxid}% + {http://www.npes.org/pdfx/ns/id/}% + \hyxmp@declare@property + {GTS_PDFXVersion}% + {internal}% + {ID of PDF/X standard}% + \hyxmp@end@ext@decl + \fi +}% +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\hyxmp@iptc@extensions} % \changes{v2.2}{2012/12/13}{Added this macro to support % \acro{PDF/A} generation} @@ -4654,6 +5226,10 @@ __________</rdf:li>^^J% \newcommand*{\hyxmp@declare@extensions}{% \hyxmp@begin@extension@decls % \end{macrocode} +% Declare the Adobe \acro{PDF} schema (always present). +% \begin{macrocode} + \hyxmp@pdf@extensions +% \end{macrocode} % Declare the \acro{XMP} Media Management extensions (always present). % \begin{macrocode} \hyxmp@mm@extensions @@ -4662,9 +5238,26 @@ __________</rdf:li>^^J% % generating a \acro{PDF/A} document. % \begin{macrocode} \ifHy@pdfa - \hyxmp@mm@extensions + \hyxmp@pdfa@id@extensions + \fi +% \end{macrocode} +% Conditionally declare the \acro{PDF/UA} Universal Accessibility +% extensions. +% \begin{macrocode} + \ifx\@pdfuapart\@empty + \else + \hyxmp@pdfua@id@extensions \fi % \end{macrocode} +% \begin{macro}{\next} +% Conditionally declare the \acro{PDF/X} extensions. +% \begin{macrocode} + \ifx\@pdfxversion\@empty + \else + \hyxmp@pdfx@id@extensions + \fi +% \end{macrocode} +% \end{macro} % Conditionally declare \acro{IPTC} photo metadata extensions. % \begin{macrocode} \ifx\hyxmp@iptc@data\@empty @@ -4740,6 +5333,9 @@ _____________________xmlns:xmp="http://ns.adobe.com/xap/1.0/"^^J% _____________________xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"^^J% _____________________xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent\hyxmp@hash"^^J% _____________________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:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"^^J% _____________________xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"^^J% @@ -4763,6 +5359,8 @@ _____________________xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field\hyxmp@ha \hyxmp@photoshop@schema \hyxmp@xmp@basic@schema \hyxmp@pdfa@id@schema + \hyxmp@pdfua@id@schema + \hyxmp@pdfx@id@schema \hyxmp@mm@schema \hyxmp@iptc@schema \hyxmp@prism@schema @@ -5051,5 +5649,192 @@ __</rdf:RDF>^^J% \catcode`\"=\hyxmp@dq@code % \end{macrocode} % +% \iffalse +%</package> +% \fi +% +% \iffalse +%<*doc-helper> +% \fi +% +% ^^A There's not much point including the documentation helper code +% ^^A in the documentation itself, but feel free to remove the +% ^^A following |\iffalse| and matching |\fi| if you'd like to include +% ^^A it. +% \iffalse +% +% \section{Documentation helper code} +% +% The following code is used to make |hyperxmp.pdf| compliant with the +% \PDFstd{A}{1}{b}{} standard, at least when built from \pdfLaTeX\ or +% \LuaLaTeX, but not currently \XeLaTeX\@. We include this code in a +% separate file because (a)~it is less distracting squirreled away here +% than placed at the top of the |.dtx| file, and (b)~putting it in a +% separate file makes it easy to disable. One simply needs to comment +% out the |\input{hyperxmp-stds}| line to produce an ordinary \acro{PDF} +% file, which offers the benefit of live hyperlinks in almost all +% \acro{PDF} readers. +% +% \subsection{Ensuring proper support} +% +% \begin{macro}{\next} +% We can't proceed without a color profile. For this document we use a +% \acro{CMYK} profile, specifically uncoated FOGRA29L, as a small and +% thus safe color space. As long as |FOGRA29L_uncoated.icc| lies in the +% \tex\ search path (which normally includes the current directory), +% we'll be able to find it. +% \begin{macrocode} +\let\next=\endinput +\IfFileExists{FOGRA29L_uncoated.icc} + {\let\next=\relax} + {} +\next +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\next} +% We can't proceed unless we're running either \pdfLaTeX\ or +% \LuaLaTeX\@. \XeLaTeX\ doesn't appear to support all of the +% mechanisms required below to support \PDFstd{A}{1}{b}{} compliance. +% If you know how to adapt the following code to \XeLaTeX, please +% contact the \pkgname{hyperxmp} maintainer. +% \begin{macrocode} +\let\next=\endinput +\ifPDFTeX + \let\next=\relax +\else + \ifLuaTeX + \usepackage{luatex85} + \let\next=\relax + \fi +\fi +\next +% \end{macrocode} +% \end{macro} +% +% If we're here, we should be able to make |hyperxmp.pdf| +% \PDFstd{A}{1}{b}{}-compliant. +% \begin{macrocode} +\def\wantpdfstandards{} +\typeout{Generating PDF/A-1b compliant hyperxmp documentation.} +% \end{macrocode} +% +% \subsection{Complying with the PDF/A-1b standard} +% +% We can't specify \PDFstd{A}{1}{b}{} compliance until after both +% \pkgname{hyperref} and \pkgname{hyperxmp} are loaded so we do so at +% the beginning of the document. +% \begin{macrocode} +\AtBeginDocument{% + \hypersetup{% + pdfapart=1, + pdfaconformance=b + }% +} +% \end{macrocode} +% +% \PDFstd{A}{1}{b}{} forbids object compression. This is normally the +% default for \pdfLaTeX, but the \TeX\ Live distribution changes the +% default to compression level~2. Here we explicitly change it back +% to~0. +% \begin{macrocode} +\pdfobjcompresslevel=0 +% \end{macrocode} +% +% We specify an uncoated FOGRA29 output intent for both +% \PDFstd{A}{1}{b}{} and \acro{PDF/X} (all versions). +% \begin{macrocode} +\immediate\pdfobj stream attr {/N 4} file {FOGRA29L_uncoated.icc} +\edef\iccobj{\the\pdflastobj} +\pdfcatalog{% + /OutputIntents [ + << + /Type /OutputIntent + /S /GTS_PDFA1 + /DestOutputProfile \iccobj\space 0 R + /OutputConditionIdentifier (Uncoated FOGRA29) + /Info (FOGRA29L) + >> + << + /Type /OutputIntent + /S /GTS_PDFX + /DestOutputProfile \iccobj\space 0 R + /OutputConditionIdentifier (Uncoated FOGRA29) + /Info (FOGRA29L) + >> + ] +} +% \end{macrocode} +% +% \begin{macro}{\HyColor@HyperrefBorderColor} +% We just specified a \acro{CMYK} color profile, but \pkgname{hyperref} +% normally produces \acro{RGB} link borders. The following code +% instructs \pkgname{hyperref} to accept \acro{CMYK} colors. +% \begin{macrocode} +\makeatletter +\AtBeginDocument{% + \let\HyColor@HyperrefBorderColor\HyColor@XZeroOneThreeFour +} +\makeatother +% \end{macrocode} +% \end{macro} +% +% \pkgname{hyperref}'s default colors are specified as \acro{RGB}\@. We +% need to reassign them so they take on \acro{CMYK} values. (Note that +% the main document already loaded the \pkgname{xcolor} package with the +% \optname{cmyk} option.) Annoyingly, very few \acro{PDF} readers +% correctly color hyperlinks defined with \acro{CMYK} link borders. At +% the time of this writing (March 2020), Adobe Acrobat DC displays the +% \emph{reverse} of the specified color, presumably because it always +% interprets the first three color channels as red, green, and blue. +% Other browsers display no border or a black border. This is not a +% huge problem in practice because (a)~it's more important to be able to +% distinguish hyperlinks from regular text than to render with correct +% border colors and (b)~\acro{PDF} readers may suppress hyperlink +% borders anyway for \PDFstd{A}{1}{b}{} documents. +% \begin{macrocode} +\AtBeginDocument{% + \hypersetup{% + citebordercolor=green, + linkbordercolor=red, + urlbordercolor=cyan + }% +} +% \end{macrocode} +% +% \begin{macro}{\@tempdima} +% \begin{macro}{\boxwd} +% \begin{macro}{\boxht} +% \begin{macro}{\next} +% Explicitly specify the \pdfterm{BleedBox} and \pdfterm{TrimBox} to use +% for every page of the documentation. +% \begin{macrocode} +\makeatletter +\@tempdima=0.996264\paperwidth +\edef\boxwd{\strip@pt\@tempdima} +\@tempdima=0.996264\paperheight +\edef\boxht{\strip@pt\@tempdima} +\makeatother +\edef\next{% + \protect\pdfpageattr{ + /BleedBox [0.0 0.0 \boxwd\space \boxht] + /TrimBox [0.0 0.0 \boxwd\space \boxht] + /StructParents 0 + /Tabs /S + }% +} +\next +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \fi +% +% \iffalse +%</doc-helper> +% \fi +% % \Finale \endinput diff --git a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins index 1b82c2a2020..7a819746049 100644 --- a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins +++ b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins @@ -1,5 +1,5 @@ %% -%% Copyright (C) 2019 by Scott Pakin <scott+hyxmp@pakin.org> +%% Copyright (C) 2011-2020 by Scott Pakin <scott+hyxmp@pakin.org> %% %% This file may be distributed and/or modified under the conditions of %% the LaTeX Project Public License, either version 1.3c of this license @@ -21,7 +21,7 @@ This is a generated file. -Copyright (C) 2019 by Scott Pakin <scott+hyxmp@pakin.org> +Copyright (C) 2011-2020 by Scott Pakin <scott+hyxmp@pakin.org> This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license @@ -35,7 +35,10 @@ version 2008/05/04 or later. \endpreamble -\generate{\file{hyperxmp.sty}{\from{hyperxmp.dtx}{package}}} +\generate{% + \file{hyperxmp.sty}{\from{hyperxmp.dtx}{package}}% + \file{hyperxmp-stds.tex}{\from{hyperxmp.dtx}{doc-helper}}% +} \obeyspaces \Msg{*************************************************************} diff --git a/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty b/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty index 5933861a84d..bcd36e7d64c 100644 --- a/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty +++ b/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty @@ -8,7 +8,7 @@ %% %% This is a generated file. %% -%% Copyright (C) 2019 by Scott Pakin <scott+hyxmp@pakin.org> +%% Copyright (C) 2011-2020 by Scott Pakin <scott+hyxmp@pakin.org> %% %% This file may be distributed and/or modified under the conditions of %% the LaTeX Project Public License, either version 1.3c of this license @@ -22,7 +22,7 @@ %% \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{hyperxmp} - [2019/04/05 v4.1 Store hyperref metadata in XMP format] + [2020/03/20 v5.0 Store hyperref metadata in XMP format] \edef\hyxmp@dq@code{\the\catcode`\"} \catcode`\"=12 \def\hyxmp@driver{hpdftex} @@ -36,8 +36,10 @@ \RequirePackage{pdfescape} \RequirePackage{stringenc} \RequirePackage{intcalc} -\RequirePackage{ifxetex} +\RequirePackage{iftex} \RequirePackage{ifmtarg} +\RequirePackage{etoolbox} +\RequirePackage{ifthen} \def\@ifmtargexp#1{\expandafter\@ifmtarg\expandafter{#1}} \def\@ifnotmtargexp#1{\expandafter\@ifnotmtarg\expandafter{#1}} \newcommand{\hyxmp@pdfstringdef}[2]{% @@ -80,18 +82,72 @@ \define@key{Hyp}{pdfcaptionwriter}{\hyxmp@pdfstringdef\@pdfcaptionwriter{#1}} \def\@pdfmetalang{} \define@key{Hyp}{pdfmetalang}{\hyxmp@pdfstringdef\@pdfmetalang{#1}} +\def\hyxmp@no@bad@parts#1\relax{% + \@ifnotmtarg{#1}{% + \PackageWarning{hyperxmp}{pdfapart and pdfuapart must be numeric}% + }% +} \def\@pdfapart{1} -\define@key{Hyp}{pdfapart}{\hyxmp@pdfstringdef\@pdfapart{#1}} +\define@key{Hyp}{pdfapart}{% + \afterassignment\hyxmp@no@bad@parts\@tempcnta=0#1\relax + \hyxmp@pdfstringdef\@pdfapart{\the\@tempcnta}% +} \def\@pdfaconformance{B} -\define@key{Hyp}{pdfaconformance}{\hyxmp@pdfstringdef\@pdfaconformance{#1}} +\define@key{Hyp}{pdfaconformance}{% + \uppercase{\hyxmp@pdfstringdef\@pdfaconformance{#1}}% +} +\def\@pdfuapart{} +\define@key{Hyp}{pdfuapart}{% + \afterassignment\hyxmp@no@bad@parts\@tempcnta=0#1\relax + \hyxmp@pdfstringdef\@pdfuapart{\the\@tempcnta}% +} +\newcommand*{\hyxmp@set@pdfx@major}[1]{\hyxmp@set@pdfx@major@i#1!} +\def\hyxmp@set@pdfx@major@i PDF/X-{% + \afterassignment\hyxmp@set@pdfx@major@ii + \@tempcnta=% +} +\def\hyxmp@set@pdfx@major@ii#1!{% + \edef\hyxmp@pdfx@major{\the\@tempcnta}% +} +\newcommand*\hyxmp@check@std[2]{% + \ifthenelse{\equal{#1}{#2}}% + {\global\let\next=\relax}% + {}% +}% +\def\@pdfxstandard{} +\def\hyxmp@pdfx@major{} +\define@key{Hyp}{pdfxstandard}{% + \hyxmp@pdfstringdef\@pdfxstandard{#1}% + \gdef\next{% + \PackageWarning{hyperxmp}{Unrecognized PDF/X standard `#1'}% + }% + \hyxmp@check@std{#1}{PDF/X-1a:2001}% + \hyxmp@check@std{#1}{PDF/X-1a:2003}% + \hyxmp@check@std{#1}{PDF/X-3:2002}% + \hyxmp@check@std{#1}{PDF/X-3:2003}% + \hyxmp@check@std{#1}{PDF/X-4}% + \hyxmp@check@std{#1}{PDF/X-4p}% + \hyxmp@check@std{#1}{PDF/X-5g}% + \hyxmp@check@std{#1}{PDF/X-5n}% + \hyxmp@check@std{#1}{PDF/X-5pg}% + \next + \hyxmp@set@pdfx@major{#1}% +} \edef\@pdfsource{\jobname.tex} \define@key{Hyp}{pdfsource}{\hyxmp@pdfstringdef\@pdfsource{#1}} \def\hyxmp@DocumentID{} \define@key{Hyp}{pdfdocumentid}{\hyxmp@pdfstringdef\hyxmp@DocumentID{#1}} \def\hyxmp@InstanceID{} \define@key{Hyp}{pdfinstanceid}{\hyxmp@pdfstringdef\hyxmp@InstanceID{#1}} -\def\@pdfversionid{} +\def\@pdfversionid{1} \define@key{Hyp}{pdfversionid}{\hyxmp@pdfstringdef\@pdfversionid{#1}} +\RequirePackage{ifdraft} +\ifdraft{% + \def\@pdfrendition{draft}% +}{% + \def\@pdfrendition{default}% +} +\define@key{Hyp}{pdfrendition}{\hyxmp@pdfstringdef\@pdfrendition{#1}} \def\@pdfpublication{} \define@key{Hyp}{pdfpublication}{\hyxmp@pdfstringdef\@pdfpublication{#1}} \def\@pdfpubtype{} @@ -144,11 +200,31 @@ \define@key{Hyp}{pdfcontactemail}{\hyxmp@pdfstringdef\@pdfcontactemail{#1}} \def\@pdfcontacturl{} \define@key{Hyp}{pdfcontacturl}{\hyxmp@pdfstringdef\@pdfcontacturl{#1}} -\def\hyxmp@suppress@pdf@metadata{% - \global\let\PDF@FinishDoc=\@empty +\def\hyxmp@no@info@lists{% + \def\hyxmp@suppress@pdf@info{% + \global\let\PDF@FinishDoc=\@empty + \PackageWarningNoLine{hyperxmp}{% + Suppressing the _entire_ PDF Info dictionary.\MessageBreak + Please notify the hyperxmp maintainer% + }% + }% + \let\next=\relax + \patchcmd + {\PDF@FinishDoc}% + {/Author(\@pdfauthor)}% + {}% + {}% + {\let\next=\hyxmp@suppress@pdf@info}% + \patchcmd + {\PDF@FinishDoc}% + {/Keywords(\@pdfkeywords)}% + {}% + {}% + {\let\next=\hyxmp@suppress@pdf@info}% + \next } \define@key{Hyp}{keeppdfinfo}[true]{% - \gdef\hyxmp@suppress@pdf@metadata{}% + \gdef\hyxmp@no@info@lists{}% } \def\hyxmp@pdfauthor{} \def\hyxmp@pdfkeywords{} @@ -238,10 +314,10 @@ \@pdfsubject \@pdfsubtitle \@pdftitle - \@pdftype + \@pdfuapart \@pdfurl - \@pdfversionid \@pdfvolumenum + \@pdfxstandard }% \ifx\hyxmp@concated@metadata\@empty \PackageWarningNoLine{hyperxmp}{% @@ -251,6 +327,21 @@ provide metadata values to hyperxmp}% \fi } +\newcommand*{\hyxmp@check@standards}{% + \def\hyxmp@standards{% + \@pdfapart + \@pdfxstandard + \@pdfuapart + }% + \@ifnotmtargexp{\hyxmp@standards}{% + \@ifmtargexp{\@pdftitle}{% + \PackageWarning{hyperxmp}{% + Missing pdftitle (required for PDF standards\MessageBreak + compliance)% + }% + }% + }% +} \AtBeginDocument{% \@ifpackageloaded{hyperref}{% \ifx\@pdflang\relax @@ -264,10 +355,6 @@ \fi \fi \hyxmp@xmlify\@pdfmetalang - \ifx\@pdfdatetime\@empty - \else - \edef\hyxmp@today{\@pdfdatetime}% - \fi \@ifmtargexp{\@pdftitle}{% \@ifnotmtargexp{\@title}{% \hypersetup{pdftitle={\@title}}% @@ -280,7 +367,14 @@ }% }% {}% - \hyxmp@suppress@pdf@metadata + \@ifundefined{XeTeXversion}{}{% + \@ifmtargexp{\@pdfcreationdate}{% + \let\@pdfcreationdate=\hyxmp@today@pdf + }% + {}% + }% + \hyxmp@check@standards + \hyxmp@no@info@lists \hyxmp@at@end{% \hyxmp@find@metadata \hyxmp@embed@packet @@ -340,7 +434,7 @@ \def\hyxmp@first@char#1{\hyxmp@first@char@i#1\relax} \def\hyxmp@first@char@i#1#2\relax{#1} \def\hyxmp@as@xmp@date#1{% - \expandafter\ifx\hyxmp@first@char@i#1\relax D% + \expandafter\ifnum\expandafter`\hyxmp@first@char@i#1\relax=`D \hyxmp@pdf@to@xmp@date{#1}% \else #1% @@ -433,7 +527,7 @@ \def\hyxmp@xmp@to@pdf@date@viii#1#2#3#4{% '#1#2'% } -\def\hyxmp@today@define#1{% +\def\hyxmp@today@xmp@define#1{% \xdef#1{\the\year}% \ifnum\month<10 \xdef#1{#1-0\the\month}% @@ -446,28 +540,45 @@ \xdef#1{#1-\the\day}% \fi \@tempcnta=\time - \divide\@tempcnta by 60% - \ifnum\@tempcnta<10% + \divide\@tempcnta by 60 + \ifnum\@tempcnta<10 \xdef#1{#1T0\the\@tempcnta}% \else \xdef#1{#1T\the\@tempcnta}% \fi - \multiply\@tempcnta by -60% + \multiply\@tempcnta by -60 \advance\@tempcnta by \time - \ifnum\@tempcnta<10% + \ifnum\@tempcnta<10 \xdef#1{#1:0\the\@tempcnta}% \else \xdef#1{#1:\the\@tempcnta}% \fi + \xdef#1{#1Z}% } -\@ifundefined{pdffeedback}{% - \@ifundefined{pdfcreationdate}{% - \hyxmp@today@define\hyxmp@today - }{% - \edef\hyxmp@today{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate}% +\def\hyxmp@try@today#1#2{% + \@ifmtargexp{\hyxmp@today@xmp}{% + \@ifundefined{#1}{}{#2}% + }{}% +} +\def\hyxmp@today@xmp{} +\hyxmp@try@today{pdfcreationdate}{% + \edef\hyxmp@today@xmp{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate}% +} +\hyxmp@try@today{pdffeedback}{% + \edef\hyxmp@today@xmp{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate}% +} +\hyxmp@try@today{filemoddate}{% + \edef\hyxmp@today@xmp{\filemoddate{\jobname.aux}}% + \edef\next{% + \edef\noexpand\hyxmp@today@xmp{\noexpand\hyxmp@as@xmp@date{\hyxmp@today@xmp}}% }% -}{% - \edef\hyxmp@today{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate}% + \next +}% +\hyxmp@try@today{year}{% + \hyxmp@today@xmp@define\hyxmp@today@xmp +} +\expandafter\edef\expandafter\hyxmp@today@pdf\expandafter{% + \expandafter\hyxmp@xmp@to@pdf@date\expandafter{\hyxmp@today@xmp}% } \catcode`\Q=3 \newcommand{\hyxmp@trimspaces}[1]{% @@ -485,7 +596,6 @@ \else \hyxmp@unicodetexfalse \fi -\newcommand*{\hyxmp@reencode}[1]{} \expandafter\def\csname SE->pdfdoc@03\endcsname{0003} \expandafter\def\csname SE->pdfdoc@15\endcsname{0015} \newcommand*{\hyxmp@xmlify}[1]{% @@ -496,7 +606,7 @@ \StringEncodingConvert \hyxmp@text\hyxmp@text{utf16be}{utf32be}% }{% - \ifxetex + \ifXeTeX \hyxmp@xetex@crap \else \StringEncodingConvert @@ -678,6 +788,48 @@ \catcode0=12 % \gdef\hyxmp@zero{^^00}% \endgroup +\newcommand*{\hyxmp@extra@indent}{} +\newcommand*{\hyxmp@add@simple}[2]{% + \@ifnotmtargexp{#2}{% + \hyxmp@xmlify{#2}% + \hyxmp@add@to@xml{\hyxmp@extra@indent______<}% + \xdef\hyxmp@xml{\hyxmp@xml#1}% + \hyxmp@add@to@xml{>\hyxmp@xmlified</}% + \xdef\hyxmp@xml{\hyxmp@xml#1>^^J}% + }% +} +\newcommand*{\hyxmp@add@simple@var}[2]{% + \expandafter\ifx\csname#2\endcsname\relax + \else + \hyxmp@xmlify{\csname#2\endcsname}% + \hyxmp@add@to@xml{% + \hyxmp@extra@indent______<#1>\hyxmp@xmlified</#1>^^J% + }% + \fi +} +\newcommand*{\hyxmp@add@simple@lang}[2]{% + \@ifnotmtarg{#2}{% + \hyxmp@xmlify{#2}% + \expandafter\hyxmp@add@simple@lang@i\hyxmp@xmlified\relax{#1}% + }% +} +\newcommand*{\hyxmp@add@simple@lang@i}{% + \@ifnextchar[\hyxmp@add@simple@lang@ii{\hyxmp@add@simple@lang@ii[]}% +} +\def\hyxmp@add@simple@lang@ii[#1]#2\relax#3{% + \@ifnotmtarg{#2}{% + \hyxmp@xmlify{#2}% + \@ifmtarg{#1}{% + \hyxmp@add@to@xml{% +______<#3>\hyxmp@xmlified</#3>^^J% + }% + }{% + \hyxmp@add@to@xml{% +______<#3 xml:lang="#1">\hyxmp@xmlified</#3>^^J% + }% + }% + }% +} \def\hyxmp@alt@title{} \def\hyxmp@alt@description{} \def\hyxmp@alt@rights{} @@ -785,9 +937,9 @@ \hyxmp@create@uuid\hyxmp@DocumentID } \newcommand*{\hyxmp@def@InstanceID}{% - \hyxmp@today@define{\hyxmp@seed@string}% + \hyxmp@today@xmp@define{\hyxmp@seed@string}% \edef\hyxmp@seed@string{% - \jobname:\@pdftitle:\@pdfauthor:\hyxmp@today:\hyxmp@seed@string + \jobname:\@pdftitle:\@pdfauthor:\hyxmp@today@xmp:\hyxmp@seed@string }% \expandafter\hyxmp@seed@rng\expandafter{\hyxmp@seed@string}% \edef\hyxmp@rand@num{\the\@tempcnta}% @@ -830,9 +982,37 @@ _______________________________________________________________^^J% \xdef\hyxmp@padding{\hyxmp@padding\hyxmp@padding} \xdef\hyxmp@padding{\hyxmp@padding\hyxmp@padding} \newcommand*{\hyxmp@x@default}{x-default} +\newcommand*{\hyxmp@define@pdfproducer}{% + \gdef\@pdfproducer{TeX} + \ifPDFTeX + \expandafter\hyxmp@banner@to@producer\expandafter{\pdftexbanner} + \else + \ifLuaTeX + \expandafter\hyxmp@banner@to@producer\expandafter{\luatexbanner} + \else + \ifXeTeX + \edef\@pdfproducer{XeTeX version \the\XeTeXversion\XeTeXrevision} + \fi + \fi + \fi +} +\def\hyxmp@banner@to@producer#1{% + \ifx\scantokens\relax + \gdef\@pdfproducer{#1}% + \else + \scantokens{\makeatletter\hyxmp@remove@this#1\relax\makeatother}% + \fi +} +\def\hyxmp@remove@this This is #1\relax{\gdef\@pdfproducer{#1}} +\AtBeginDocument{% + \ifx\@pdfproducer\relax + \hyxmp@define@pdfproducer + \fi +} \newcommand*{\hyxmp@pdf@schema}{% - \hyxmp@add@simple@var{pdf:Keywords}{@pdfkeywords}% \hyxmp@add@simple@var{pdf:Producer}{@pdfproducer}% + \hyxmp@add@simple@var{pdf:Keywords}{@pdfkeywords}% + \hyxmp@add@simple{pdf:Trapped}{\@pdftrapped}% \@ifundefined{pdfvariable}{% \@ifundefined{pdfminorversion}{% }{% @@ -842,47 +1022,6 @@ _______________________________________________________________^^J% \hyxmp@add@simple{pdf:PDFVersion}{1.\the\pdfvariable minorversion}% }% } -\newcommand*{\hyxmp@extra@indent}{} -\newcommand*{\hyxmp@add@simple}[2]{% - \@ifnotmtargexp{#2}{% - \hyxmp@xmlify{#2}% - \hyxmp@add@to@xml{% - \hyxmp@extra@indent______<#1>\hyxmp@xmlified</#1>^^J% - }% - }% -} -\newcommand*{\hyxmp@add@simple@var}[2]{% - \expandafter\ifx\csname#2\endcsname\relax - \else - \hyxmp@xmlify{\csname#2\endcsname}% - \hyxmp@add@to@xml{% - \hyxmp@extra@indent______<#1>\hyxmp@xmlified</#1>^^J% - }% - \fi -} -\newcommand*{\hyxmp@add@simple@lang}[2]{% - \@ifnotmtarg{#2}{% - \hyxmp@xmlify{#2}% - \expandafter\hyxmp@add@simple@lang@i\hyxmp@xmlified\relax{#1}% - }% -} -\newcommand*{\hyxmp@add@simple@lang@i}{% - \@ifnextchar[\hyxmp@add@simple@lang@ii{\hyxmp@add@simple@lang@ii[]}% -} -\def\hyxmp@add@simple@lang@ii[#1]#2\relax#3{% - \@ifnotmtarg{#2}{% - \hyxmp@xmlify{#2}% - \@ifmtarg{#1}{% - \hyxmp@add@to@xml{% -______<#3>\hyxmp@xmlified</#3>^^J% - }% - }{% - \hyxmp@add@to@xml{% -______<#3 xml:lang="#1">\hyxmp@xmlified</#3>^^J% - }% - }% - }% -} \newcommand*{\hyxmp@rdf@dc}[3][\iffalse]{% \@ifmtargexp{#3}{\@tempswafalse}{\@tempswatrue}% #1 @@ -962,7 +1101,7 @@ ______</dc:#2>^^J% \hyxmp@rdf@dc[\ifHy@pdfa]{description}{\@pdfsubject}% \hyxmp@rdf@dc{rights}{\@pdfcopyright}% \hyxmp@singleton@dc{publisher}{\@pdfpublisher}% - \hyxmp@singleton@dc[Seq]{date}{\hyxmp@today}% + \hyxmp@singleton@dc[Seq]{date}{\hyxmp@today@xmp}% \hyxmp@singleton@dc{language}{\@pdflang}% \hyxmp@singleton@dc{type}{\@pdftype}% \hyxmp@list@to@xml[\ifHy@pdfa]{creator}{Seq}{\hyxmp@pdfauthor}% @@ -997,45 +1136,26 @@ ______</dc:#2>^^J% \hyxmp@add@simple{xmpMM:DocumentID}{\hyxmp@DocumentID}% \hyxmp@add@simple{xmpMM:InstanceID}{\hyxmp@InstanceID}% \hyxmp@add@simple{xmpMM:VersionID}{\@pdfversionid}% -} -\newcommand*{\hyxmp@define@createdate}{% - \@ifundefined{pdffeedback}{% - \@ifundefined{pdfcreationdate}{% - \hyxmp@today@define\hyxmp@createdate - }{% - \edef\hyxmp@createdate{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate}% - }% - }{% - \edef\hyxmp@createdate{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate}% - }% + \hyxmp@add@simple{xmpMM:RenditionClass}{\@pdfrendition}% } \newcommand*{\hyxmp@xmp@basic@schema}{% - \hyxmp@define@createdate - \@ifundefined{@pdfcreationdate}{% - \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@createdate}% + \@ifmtargexp{\@pdfcreationdate}{% + \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@today@xmp}% }{% - \ifx\@pdfcreationdate\@empty - \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@createdate}% - \else - \hyxmp@add@simple{xmp:CreateDate}{% - \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfcreationdate}}% - \fi + \hyxmp@add@simple{xmp:CreateDate}{% + \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfcreationdate}}% }% - \@ifundefined{@pdfmoddate}{% - \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@createdate}% + \@ifmtargexp{\@pdfmoddate}{% + \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@today@xmp}% }{% - \ifx\@pdfmoddate\@empty - \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@createdate}% - \else - \hyxmp@add@simple{xmp:ModifyDate}{% - \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfmoddate}}% - \fi + \hyxmp@add@simple{xmp:ModifyDate}{% + \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfmoddate}}% }% - \ifx\@pdfmetadatetime\@empty - \hyxmp@add@simple{xmp:MetadataDate}{\hyxmp@createdate}% - \else + \@ifmtargexp{\@pdfmetadatetime}{% + \hyxmp@add@simple{xmp:MetadataDate}{\hyxmp@today@xmp}% + }{% \hyxmp@add@simple{xmp:MetadataDate}{\@pdfmetadatetime}% - \fi + }% \hyxmp@add@simple{xmp:CreatorTool}{\@pdfcreator}% \hyxmp@add@simple{xmp:BaseURL}{\@baseurl}% } @@ -1050,6 +1170,25 @@ ______</dc:#2>^^J% \hyxmp@add@simple{pdfaid:conformance}{\@pdfaconformance}% \fi } +\newcommand*{\hyxmp@pdfua@id@schema}{% + \hyxmp@add@simple{pdfuaid:part}{\@pdfuapart}% +} +\newcommand*{\hyxmp@pdfx@id@schema}{% + \@tempcnta=0\hyxmp@pdfx@major\relax + \ifnum\@tempcnta=0 + \else + \ifnum\@tempcnta=1 + \hyxmp@add@simple{pdfx:GTS_PDFXVersion}{PDF/X-1:2001}% + \hyxmp@add@simple{pdfx:GTS_PDFXConformance}{\@pdfxstandard}% + \else + \ifnum\@tempcnta<4 + \hyxmp@add@simple{pdfx:GTS_PDFXVersion}{\@pdfxstandard}% + \else + \hyxmp@add@simple{pdfxid:GTS_PDFXVersion}{\@pdfxstandard}% + \fi + \fi + \fi +} \begingroup \catcode`\&=12 \catcode`\#=12 @@ -1181,7 +1320,9 @@ __________</rdf:li>^^J% \newcommand{\hyxmp@declare@property}[4][Text]{% \hyxmp@add@to@xml{% ________________<rdf:li rdf:parseType="Resource">^^J% -__________________<pdfaProperty:name>#2</pdfaProperty:name>^^J% +__________________<pdfaProperty:name>}% + \xdef\hyxmp@xml{\hyxmp@xml#2}% + \hyxmp@add@to@xml{</pdfaProperty:name>^^J% __________________<pdfaProperty:valueType>#1</pdfaProperty:valueType>^^J% __________________<pdfaProperty:category>#3</pdfaProperty:category>^^J% __________________<pdfaProperty:description>#4</pdfaProperty:description>^^J% @@ -1197,6 +1338,17 @@ ________________________<pdfaField:description>#3</pdfaField:description>^^J% ______________________</rdf:li>^^J% }% } +\newcommand*{\hyxmp@pdf@extensions}{% + \hyxmp@begin@ext@decl + {Adobe PDF Schema}% + {pdf}% + {http://ns.adobe.com/pdf/1.3/}% + \hyxmp@declare@property + {Trapped}% + {internal}% + {Indication if the document has been modified to include trapping information}% + \hyxmp@end@ext@decl +}% \newcommand*{\hyxmp@mm@extensions}{% \hyxmp@begin@ext@decl {XMP Media Management Schema}% @@ -1216,6 +1368,10 @@ ______________________</rdf:li>^^J% {VersionID}% {internal}% {Document version identifier}% + \hyxmp@declare@property + {RenditionClass}% + {internal}% + {The manner in which a document is rendered}% \hyxmp@end@ext@decl }% \newcommand*{\hyxmp@pdfa@id@extensions}{% @@ -1234,6 +1390,48 @@ ______________________</rdf:li>^^J% {Conformance level of PDF/A standard}% \hyxmp@end@ext@decl }% +\newcommand*{\hyxmp@pdfua@id@extensions}{% + \hyxmp@begin@ext@decl + {PDF/UA Universal Accessibility Schema}% + {pdfuaid}% + {http://www.aiim.org/pdfua/ns/id/}% + \hyxmp@declare@property + [Integer]% + {part}% + {internal}% + {Part of ISO 14289 standard}% + \hyxmp@end@ext@decl +}% +\newcommand*{\hyxmp@pdfx@id@extensions}{% + \ifx\hyxmp@pdfx@major\empty + \else + \hyxmp@begin@ext@decl + {Adobe Document Info PDF/X eXtension Schema}% + {pdfx}% + {http://ns.adobe.com/pdfx/1.3/}% + \hyxmp@declare@property + {GTS_PDFXVersion}% + {internal}% + {ID of PDF/X standard}% + \hyxmp@declare@property + {GTS_PDFXConformance}% + {internal}% + {Conformance level of PDF/X standard}% + \hyxmp@end@ext@decl + \fi + \@tempcnta=0\hyxmp@pdfx@major\relax + \ifnum\@tempcnta>3 + \hyxmp@begin@ext@decl + {PDF/X ID Schema}% + {pdfxid}% + {http://www.npes.org/pdfx/ns/id/}% + \hyxmp@declare@property + {GTS_PDFXVersion}% + {internal}% + {ID of PDF/X standard}% + \hyxmp@end@ext@decl + \fi +}% \newcommand*{\hyxmp@iptc@extensions}{% \hyxmp@begin@ext@decl {IPTC Core Schema}% @@ -1364,9 +1562,18 @@ __________</rdf:li>^^J% }% \newcommand*{\hyxmp@declare@extensions}{% \hyxmp@begin@extension@decls + \hyxmp@pdf@extensions \hyxmp@mm@extensions \ifHy@pdfa - \hyxmp@mm@extensions + \hyxmp@pdfa@id@extensions + \fi + \ifx\@pdfuapart\@empty + \else + \hyxmp@pdfua@id@extensions + \fi + \ifx\@pdfxversion\@empty + \else + \hyxmp@pdfx@id@extensions \fi \ifx\hyxmp@iptc@data\@empty \else @@ -1407,6 +1614,9 @@ _____________________xmlns:xmp="http://ns.adobe.com/xap/1.0/"^^J% _____________________xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"^^J% _____________________xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent\hyxmp@hash"^^J% _____________________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:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"^^J% _____________________xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"^^J% @@ -1424,6 +1634,8 @@ _____________________xmlns:pdfaField="http://www.aiim.org/pdfa/ns/field\hyxmp@ha \hyxmp@photoshop@schema \hyxmp@xmp@basic@schema \hyxmp@pdfa@id@schema + \hyxmp@pdfua@id@schema + \hyxmp@pdfx@id@schema \hyxmp@mm@schema \hyxmp@iptc@schema \hyxmp@prism@schema |