From 69138b92d7784154c2db4471d176e3027815336a Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 23 Feb 2017 22:00:11 +0000 Subject: hyperxmp (22feb17) git-svn-id: svn://tug.org/texlive/trunk@43316 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/source/latex/hyperxmp/hyperxmp.dtx | 763 +++++++++++++++------ .../texmf-dist/source/latex/hyperxmp/hyperxmp.ins | 4 +- 2 files changed, 546 insertions(+), 221 deletions(-) (limited to 'Master/texmf-dist/source/latex/hyperxmp') diff --git a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx index dad0acc32a9..7d95a994ae7 100644 --- a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx +++ b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2016 by Scott Pakin +% Copyright (C) 2017 by Scott Pakin % ------------------------------------------------------- % % This file may be distributed and/or modified under the @@ -22,7 +22,7 @@ %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{hyperxmp} %<*package> - [2016/07/04 v3.0 Store hyperref metadata in XMP format] + [2017/02/23 v3.2 Store hyperref metadata in XMP format] % % %<*driver> @@ -54,7 +54,7 @@ pdftitle={The hyperxmp package}, pdfsubject={LaTeX2e support for XMP metadata}, pdfkeywords={LaTeX, embedded metadata, XMP, PDF, copyright, license, comments}, - pdfcopyright={Copyright (C) 2016, Scott Pakin}, + pdfcopyright={Copyright (C) 2017, Scott Pakin}, pdflicenseurl={http://www.latex-project.org/lppl/}, pdfcaptionwriter={Scott Pakin}, pdfcontactemail={scott+hyxmp@pakin.org}, @@ -81,7 +81,7 @@ % % \fi % -% \CheckSum{1593} +% \CheckSum{1775} % % \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 @@ -366,8 +366,10 @@ % \begin{itemize} % \item \optname{baseurl} % \item \optname{pdfauthor} +% \item \optname{pdfcreationdate} % \item \optname{pdfkeywords} % \item \optname{pdflang} +% \item \optname{pdfmoddate} % \item \optname{pdfproducer} % \item \optname{pdfsubject} % \item \optname{pdftitle} @@ -394,6 +396,7 @@ % \item \optname{pdfcopyright} % \item \optname{pdfdate} % \item \optname{pdflicenseurl} +% \item \optname{pdfmetadate} % \item \optname{pdfmetalang} % \item \optname{pdftype} % \end{itemize} @@ -404,10 +407,10 @@ % 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}-1B standard. These can be changed (with -% caution) to assert that the document abides by a different standard -% (e.g.,~\acro{PDF/A}-2U). - +% 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}). +% % \optname{pdfauthortitle} indicates the primary author's position or % title. \optname{pdfcaptionwriter} specifies the name of the person % who added the metadata to the document. The next eight items describe @@ -424,36 +427,56 @@ % \optname{pdfcontacturl} is the contact's \acro{URL} (or multiple, % comma-separated \acro{URL}s). % -% \optname{pdfcopyright} defines the copyright text. \optname{pdfdate} -% specifies the document date. It is analogous to the \LaTeX\ |\date| -% command, and, like |\date|, defaults to the date the document was -% built. However, \optname{pdfdate} must be specified in -% \textsc{yyyy}|-|\textsc{mm}|-|\textsc{dd}|T|hh|:|mm|:|ss|.|ff|+|\textsc{tt}|:|tt -% format as per the W3C's recommendation~\cite{Wolf1997:date-time}. For -% example, 14~hours, 15~minutes, 9.26~seconds past midnight -% U.S. Mountain Daylight Time (UTC-6) on the 23rd day of September in the -% year~2014 should be written as \texttt{2014-09-23T14:15:09.26-06:00}. -% This can be truncated to \texttt{2014-09-23T14:15:09-06:00} or -% \texttt{2014-09-23T14:15-06:00} or \texttt{2014-09-23} or -% \texttt{2014-09} or \texttt{2014} but no other subsets. -% \pkgname{hyperxmp} does not validate \optname{pdfdate}'s argument, but -% an invalid format may confuse a \acro{PDF} reader. -% +% \acro{XMP} metadata can include a number of dates (in fact, +% timestamps, as they include both date and time components). +% \optname{pdfdate} specifies the document date. It is analogous to the +% \LaTeX\ |\date| command, and, like |\date|, defaults to the date the +% document was built. It must be specified in either \acro{XMP} +% format~\cite{Adobe2012:XMP} or \acro{PDF} format~\cite{Adobe2008:PDF}. +% \acro{XMP} dates are written in the form +% \textsc{yyyy}|-|\textsc{mm}|-|\textsc{dd}|T|hh|:|mm|:|ss|+|\textsc{tt}|:|tt.\footnote{Although +% allowed by \acro{XMP}, \pkgname{hyperxmp} does not currently accept +% fractions of a second in timestamps.} A W3C +% recommendation~\cite{Wolf1997:date-time} discusses this format in more +% detail, but as an example, 14~hours, 15~minutes, 9~seconds past +% midnight U.S. Mountain Daylight Time (UTC-6) on the 23rd day of +% September in the year~2014 should be written as +% \texttt{2014-09-23T14:15:09-06:00}. This can be truncated (with loss +% of information) to \texttt{2014-09-23T14:15:09} or +% \texttt{2014-09-23T14:15} or \texttt{2014-09-23} or \texttt{2014-09} +% or \texttt{2014} but no other subsets. \acro{PDF} dates are written +% in the form |D:|\textsc{yyyymmdd}hhmmss|+|\textsc{tt}|'|tt|'|. The +% same date in the preceding example would be written as +% \texttt{D:20140923141509-06'00'} in \acro{PDF} format. +% +% The document's creation date, modification date, and metadata date are +% normally set automatically, but \optname{pdfcreationdate}, +% \optname{pdfmoddate}, and \optname{pdfmetadate} can be used to +% override the defaults. Like \optname{pdfdate}, \optname{pdfmetadate} +% can be specified in either \acro{XMP} or \acro{PDF} format. However, +% because \pkgname{hyperref} defines \optname{pdfcreationdate} and +% \optname{pdfmoddate} and expects these to be written as \acro{PDF} +% dates, \pkgname{hyperxmp} concomitantly accepts these two dates only +% in \acro{PDF} format as well. Note that it's rare that a document +% would need to specify any of \optname{pdfcreationdate}, +% \optname{pdfmoddate}, or \optname{pdfmetadate}. +% +% \optname{pdfcopyright} defines the copyright text, and % \optname{pdflicenseurl} identifies a \acro{URL} that points to the % document's license agreement. -% \optname{pdfmetalang} indicates the -% natural language in which the metadata is written, typically as an -% \acro{IETF} language tag~\cite{IANA2011:lang-tags}, for example, -% ``|en|'' for English, ``|en-US|'' for specifically United States -% English, ``|de|'' for German, and so forth. If \optname{pdfmetalang} -% is not specified, \pkgname{hyperxmp} assumes the metadata language is -% the same as the document language (\pkgname{hyperref}'s -% \optname{pdflang} option). If neither \optname{pdfmetalang} nor -% \optname{pdflang} is specified, \pkgname{hyperxmp} uses only -% ``|x-default|'' as the metadata language. Note that ``|x-default|'' -% metadata is always included in addition to the specified metadata -% language, as the user reading the document may not have specified a -% language preference. +% +% \optname{pdfmetalang} indicates the natural language in which the +% metadata is written, typically as an \acro{IETF} language +% tag~\cite{IANA2011:lang-tags}, for example, ``|en|'' for English, +% ``|en-US|'' for specifically United States English, ``|de|'' for +% German, and so forth. If \optname{pdfmetalang} is not specified, +% \pkgname{hyperxmp} assumes the metadata language is the same as the +% document language (\pkgname{hyperref}'s \optname{pdflang} option). If +% neither \optname{pdfmetalang} nor \optname{pdflang} is specified, +% \pkgname{hyperxmp} uses only ``|x-default|'' as the metadata language. +% Note that ``|x-default|'' metadata is always included in addition to +% the specified metadata language, as the user reading the document may +% not have specified a language preference. % % \optname{pdftype} describes the type of document being produced. This % refers to ``the nature or genre of the resource''~\cite{Adobe2012:XMP} @@ -956,11 +979,53 @@ % \end{macro} % % \begin{macro}{\@pdfdatetime} -% Prepare to store the document's date and (optionally) time. +% Prepare to store the document's date and (optionally) time. Whether +% specified by the author in \acro{XMP} format or \acro{PDF} format +% (cf.~Section~\ref{sec:date-manip}) we always store |\@pdfdatetime| as +% an \acro{XMP}-format string. % \begin{macrocode} \def\@pdfdatetime{} -\define@key{Hyp}{pdfdate}{\hyxmp@pdfstringdef\@pdfdatetime{#1}} +\define@key{Hyp}{pdfdate}{% + \begingroup + \Hy@unicodefalse +% \end{macrocode} +% \begin{macro}{\next} +% Expand \optname{pdfdate}'s argument and convert it to \acro{XMP} format. +% \begin{macrocode} + \edef\next{% + \noexpand\hyxmp@pdfstringdef\noexpand\@pdfdatetime{% + \noexpand\hyxmp@as@xmp@date{#1}}% + }% + \next + \endgroup +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@pdfmetadatetime} +% Prepare to store the document's metadata date and (optionally) time. +% Whether specified by the author in \acro{XMP} format or \acro{PDF} +% format (cf.~Section~\ref{sec:date-manip}) we always store +% |\@pdfmetadatetime| as an \acro{XMP}-format string. +% \begin{macrocode} +\def\@pdfmetadatetime{} +\define@key{Hyp}{pdfmetadate}{% + \begingroup + \Hy@unicodefalse % \end{macrocode} +% \begin{macro}{\next} +% Expand \optname{pdfmetadate}'s argument and convert it to \acro{XMP} format. +% \begin{macrocode} + \edef\next{% + \noexpand\hyxmp@pdfstringdef\noexpand\@pdfmetadatetime{% + \noexpand\hyxmp@as@xmp@date{#1}}% + }% + \next + \endgroup +} +% \end{macrocode} +% \end{macro} % \end{macro} % % \begin{macro}{\@pdfcopyright} @@ -1330,13 +1395,16 @@ \@pdfcontactregion \@pdfcontacturl \@pdfcopyright - \@pdftype + \@pdfcreationdate \@pdfdatetime \@pdfkeywords \@pdflang \@pdflicenseurl + \@pdfmetadatetime + \@pdfmoddate \@pdfsubject \@pdftitle + \@pdftype }% \ifx\hyxmp@concated@metadata\@empty \PackageWarningNoLine{hyperxmp}{% @@ -1596,6 +1664,354 @@ disabled}% % \end{macro} % % +% \subsubsection{Date manipulation} +% \label{sec:date-manip} +% +% \pkgname{hyperxmp} needs to manipulate two types of date (really, +% timestamp) formats: \acro{PDF} format and \acro{XMP} format. +% \acro{PDF} timestamps are of the form +% ``|D:|\textsc{yyyymmdd}hhmmss|+|\textsc{tt}|'|tt|'|'' +% \makeatletter +% \@ifundefined{pdffeedback}{^^A +% \@ifundefined{pdfcreationdate}{^^A +% }{^^A +% (e.g.,~\texttt{\pdfcreationdate})^^A +% }^^A +% }{^^A +% (e.g.,~\texttt{\pdffeedback creationdate})^^A +% } +% \makeatother +% ~\cite{Adobe2008:PDF}, while \acro{XMP} timestamps are of the form +% ``\textsc{yyyy}|-|\textsc{mm}|-|\textsc{dd}|T|hh|:|mm|:|ss|+|\textsc{tt}|:|tt'' +% \makeatletter +% \@ifundefined{pdffeedback}{^^A +% \@ifundefined{pdfcreationdate}{^^A +% \unskip +% }{^^A +% (e.g.,~\texttt{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate})^^A +% }^^A +% }{^^A +% (e.g.,~\texttt{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate})^^A +% }^^A +% \makeatother +% ~\cite{Adobe2012:XMP}. The |\hyxmp@as@pdf@date| and +% |\hyxmp@as@xmp@date| macros defined in this section facilitate +% timestamp conversions to \acro{PDF} and \acro{XMP} formats, +% respectively. +% +% \begin{macro}{\hyxmp@first@char} +% \begin{macro}{\hyxmp@first@char@i} +% Return the first character of a string. This macro is fully expandable. +% \begin{macrocode} +\def\hyxmp@first@char#1{\hyxmp@first@char@i#1\relax} +\def\hyxmp@first@char@i#1#2\relax{#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\hyxmp@as@xmp@date} +% If necessary, convert a timestamp to \acro{XMP} format. That is, if +% the timestamp is in \acro{PDF} format, convert it; otherwise, leave it +% unmodified. This macro is fully expandable. +% \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% + \hyxmp@pdf@to@xmp@date{#1}% + \else + #1% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@pdf@to@xmp@date} +% Convert a timestamp from \acro{PDF} format to \acro{XMP} format. This +% macro is fully expandable. +% \changes{v2.4}{2013/12/24}{Added this macro} +% \begin{macrocode} +\def\hyxmp@pdf@to@xmp@date#1:#2#3#4#5#6#7#8#9{% + #2#3#4#5-#6#7-#8#9% + \hyxmp@parse@time +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@parse@time} +% This is a helper function for |\hyxmp@pdf@to@xmp@date|. +% |\hyxmp@pdf@to@xmp@date| proper parses only the year, month, and day +% then calls |\hyxmp@parse@time|. |\hyxmp@parse@time| parses the +% hours, minutes, and seconds then calls |\hyxmp@parse@tz@char|. +% \changes{v2.4}{2013/12/24}{Added this macro} +% \begin{macrocode} +\def\hyxmp@parse@time#1#2#3#4#5#6{% + T#1#2:#3#4:#5#6% + \hyxmp@parse@tz@char +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@parse@tz@char} +% This is another helper function for |\hyxmp@pdf@to@xmp@date|. So far, +% the date and time have been parsed. |\hyxmp@parse@tz@char| parses the +% first character of the timezone descriptor. This can be one of +% ``|+|'' for eastern timezones (\mbox{UTC$+x$}, including Asia, +% Oceania, and most of Europe), ``|-|'' for western timezones +% (\mbox{UTC$-x$}, primarily the Americas), or ``|Z|'' for Zulu time +% (\mbox{UTC$+0$}). Timezones beginning with ``|+|'' or ``|-|'' are +% followed by an offset in hours and minutes (parsed by +% |\hyxmp@parse@tz|; timezones beginning with ``|Z|'' are not. +% \changes{v2.4}{2013/12/24}{Added this macro} +% \begin{macrocode} +\def\hyxmp@parse@tz@char#1{% + #1% + \ifx#1-% + \expandafter\hyxmp@parse@tz + \else + \ifx#1+% + \expandafter\hyxmp@parse@tz + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@parse@tz} +% This is the final helper function for |\hyxmp@pdf@to@xmp@date|. It +% parses the piece of the timezone comprising the offset from +% Coordinated Universal Time, measured in hours and minutes. +% \changes{v2.4}{2013/12/24}{Added this macro} +% \begin{macrocode} +\def\hyxmp@parse@tz#1'#2'{% + #1:#2% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@as@pdf@date} +% If necessary, convert a timestamp to \acro{PDF} format. That is, if +% the timestamp is in \acro{XMP} format, convert it; otherwise, leave it +% unmodified. This macro is fully expandable. +% \changes{v3.2}{2017/02/20}{Added this macro} +% \begin{macrocode} +\def\hyxmp@as@pdf@date#1{% + \expandafter\ifx\hyxmp@first@char@i#1\relax D% + #1% + \else + \hyxmp@xmp@to@pdf@date{#1}% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@xmp@to@pdf@date} +% Convert a timestamp from \acro{XMP} format to \acro{PDF} format. This +% macro is fully expandable. +% \changes{v2.4}{2013/12/24}{Added this macro} +% \begin{macrocode} +\def\hyxmp@xmp@to@pdf@date#1{% + D:\hyxmp@xmp@to@pdf@date@i#1\relax\relax +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@xmp@to@pdf@date@i} +% Parse the year for |\hyxmp@xmp@to@pdf@date|. +% \begin{macrocode} +\def\hyxmp@xmp@to@pdf@date@i#1#2#3#4#5#6{% + #1#2#3#4% + \ifx#5-% + \expandafter\hyxmp@xmp@to@pdf@date@ii\expandafter#6% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@xmp@to@pdf@date@ii} +% Parse the month for |\hyxmp@xmp@to@pdf@date|. +% \begin{macrocode} +\def\hyxmp@xmp@to@pdf@date@ii#1#2#3#4{% + #1#2% + \ifx#3-% + \expandafter\hyxmp@xmp@to@pdf@date@iii\expandafter#4% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@xmp@to@pdf@date@iii} +% Parse the day for |\hyxmp@xmp@to@pdf@date|. +% \begin{macrocode} +\def\hyxmp@xmp@to@pdf@date@iii#1#2#3#4{% + #1#2% + \ifx#3T% + \expandafter\hyxmp@xmp@to@pdf@date@iv\expandafter#4% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@xmp@to@pdf@date@iv} +% Parse the hour for |\hyxmp@xmp@to@pdf@date|. +% \begin{macrocode} +\def\hyxmp@xmp@to@pdf@date@iv#1#2#3#4{% + #1#2% + \ifx#3:% + \expandafter\hyxmp@xmp@to@pdf@date@v\expandafter#4% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@xmp@to@pdf@date@v} +% Parse the minute for |\hyxmp@xmp@to@pdf@date|. +% \begin{macrocode} +\def\hyxmp@xmp@to@pdf@date@v#1#2#3#4{% + #1#2% + \ifx#3:% + \expandafter\hyxmp@xmp@to@pdf@date@vi\expandafter#4% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@gobbletwo} +% This is exactly the same as \LaTeXe's |\@gobbletwo| but needs to be a +% different literal for |\hyxmp@xmp@to@pdf@date@vii|'s pattern-matching +% to work. +% \begin{macrocode} +\let\@hyxmp@gobbletwo=\@gobbletwo +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@xmp@to@pdf@date@vi} +% Parse the second for |\hyxmp@xmp@to@pdf@date|. The challenge here is +% that we need to handle four cases for the character following the +% seconds---``|+|'', ``|-|'', ``|Z|'', and no character---without sacrificing +% expandability. Our tricky solution is to insert a |\@gobbletwo| as a +% sentinel and let |\hyxmp@xmp@to@pdf@date@vi| discard everything up to +% that sentinel (i.e.,~all the other conditionals). +% \begin{macrocode} +\def\hyxmp@xmp@to@pdf@date@vi#1#2#3#4{% + #1#2% + \ifx#3+% + +\expandafter\hyxmp@xmp@to@pdf@date@vii + \fi + \ifx#3-% + -\expandafter\hyxmp@xmp@to@pdf@date@vii + \fi + \ifx#3Z% + Z% + \fi + \ifx#3\relax + \expandafter\@hyxmp@gobbletwo + \fi + \@gobbletwo #4% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@xmp@to@pdf@date@vii} +% Parse the time-zone hours for |\hyxmp@xmp@to@pdf@date|. +% \begin{macrocode} +\def\hyxmp@xmp@to@pdf@date@vii#1\@gobbletwo#2#3#4#5{% + #2#3% + \ifx#4:% + \expandafter\hyxmp@xmp@to@pdf@date@viii\expandafter#5% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@xmp@to@pdf@date@viii} +% Parse the time-zone minutes for |\hyxmp@xmp@to@pdf@date|. +% \begin{macrocode} +\def\hyxmp@xmp@to@pdf@date@viii#1#2#3#4{% + '#1#2'% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@today@define} +% Use \TeX\ primitives to define a given macro as today's date in +% \textsc{yyyy}-\textsc{mm}-\textsc{dd}|T|hh|:|mm 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} +% \begin{macrocode} +\def\hyxmp@today@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 +% two digits apiece. +% \begin{macrocode} + \xdef#1{\the\year}% + \ifnum\month<10 + \xdef#1{#1-0\the\month}% + \else + \xdef#1{#1-\the\month}% + \fi + \ifnum\day<10 + \xdef#1{#1-0\the\day}% + \else + \xdef#1{#1-\the\day}% + \fi +% \end{macrocode} +% \TeX\ does not provide the time in terms of separate hours and minutes +% but rather as the total number of minutes since midnight (|\time|). +% There's no mechanism in \TeX\ to query the number of seconds since +% midnight or the timezone so we omit those fields when defining +% macro~|#1|. +% \begin{macrocode} + \@tempcnta=\time + \divide\@tempcnta by 60% + \ifnum\@tempcnta<10% + \xdef#1{#1T0\the\@tempcnta}% + \else + \xdef#1{#1T\the\@tempcnta}% + \fi + \multiply\@tempcnta by -60% + \advance\@tempcnta by \time + \ifnum\@tempcnta<10% + \xdef#1{#1:0\the\@tempcnta}% + \else + \xdef#1{#1:\the\@tempcnta}% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@today} +% Define |\hyxmp@today| 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} +% \begin{macrocode} +\@ifundefined{pdffeedback}{% + \@ifundefined{pdfcreationdate}{% +% \end{macrocode} +% Case 1: Neither |\pdffeedback| nor |\pdfcreationdate| is defined +% (\XeLaTeX\ and regular \LaTeX). +% \begin{macrocode} + \hyxmp@today@define\hyxmp@today + }{% +% \end{macrocode} +% Case 2: |\pdfcreationdate| is defined (\pdfLaTeX\ and pre-0.85 \LuaLaTeX). +% \begin{macrocode} + \edef\hyxmp@today{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate}% + }% +}{% +% \end{macrocode} +% Case 3: |\pdffeedback| is defined (\LuaLaTeX~0.85+). +% \begin{macrocode} + \edef\hyxmp@today{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate}% +} +% \end{macrocode} +% \end{macro} +% +% % \subsubsection{Trimming leading and trailing spaces} % \label{sec:trim-spaces} % @@ -2380,145 +2796,6 @@ _______________________________________________________________^^J% % \end{macro} % \end{macro} % -% \begin{macro}{\hyxmp@pdf@to@xmp@date} -% Convert a timestamp from \acro{PDF}'s -% |D:|\textsc{yyyymmdd}hhmmss|-|\textsc{tt}|'|tt|'| format -% \makeatletter -% \@ifundefined{pdffeedback}{^^A -% \@ifundefined{pdfcreationdate}{^^A -% }{^^A -% (e.g.,~\texttt{\pdfcreationdate}) -% }^^A -% }{^^A -% (e.g.,~\texttt{\pdffeedback creationdate}) -% } -% \makeatother -% to \acro{XMP}'s -% \textsc{yyyy}|-|\textsc{mm}|-|\textsc{dd}|T|hh|:|mm|:|ss|+|\textsc{tt}|:|tt format -% \makeatletter -% \@ifundefined{pdffeedback}{^^A -% \@ifundefined{pdfcreationdate}{^^A -% \unskip -% }{^^A -% (e.g.,~\texttt{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate})^^A -% }^^A -% }{^^A -% (e.g.,~\texttt{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate})^^A -% }^^A -% \makeatother -% ~\cite{Adobe2012:XMP}. This macro is fully expandable.^^A -% \changes{v2.4}{2013/12/24}{Added this macro} -% \begin{macrocode} -\def\hyxmp@pdf@to@xmp@date#1:#2#3#4#5#6#7#8#9{% - #2#3#4#5-#6#7-#8#9% - \hyxmp@parse@time -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@parse@time} -% This is a helper function for |\hyxmp@pdf@to@xmp@date|. -% |\hyxmp@pdf@to@xmp@date| proper parses only the year, month, and day -% then calls |\hyxmp@parse@time|. |\hyxmp@parse@time| parses the -% hours, minutes, and seconds then calls |\hyxmp@parse@tz@char|. -% \changes{v2.4}{2013/12/24}{Added this macro} -% \begin{macrocode} -\def\hyxmp@parse@time#1#2#3#4#5#6{% - T#1#2:#3#4:#5#6% - \hyxmp@parse@tz@char -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@parse@tz@char} -% This is another helper function for |\hyxmp@pdf@to@xmp@date|. So far, -% the date and time have been parsed. |\hyxmp@parse@tz@char| parses the -% first character of the timezone descriptor. This can be one of -% ``|+|'' for eastern timezones (\mbox{UTC$+x$}, including Asia, -% Oceania, and most of Europe), ``|-|'' for western timezones -% (\mbox{UTC$-x$}, primarily the Americas), or ``|Z|'' for Zulu time -% (\mbox{UTC$+0$}). Timezones beginning with ``|+|'' or ``|-|'' are -% followed by an offset in hours and minutes (parsed by -% |\hyxmp@parse@tz|; timezones beginning with ``|Z|'' are not. -% \changes{v2.4}{2013/12/24}{Added this macro} -% \begin{macrocode} -\def\hyxmp@parse@tz@char#1{% - #1% - \ifx#1-% - \expandafter\hyxmp@parse@tz - \else - \ifx#1+% - \expandafter\hyxmp@parse@tz - \fi - \fi -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@parse@tz} -% This is the final helper function for |\hyxmp@pdf@to@xmp@date|. It -% parses the piece of the timezone comprising the offset from -% Coordinated Universal Time, measured in hours and minutes. -% \changes{v2.4}{2013/12/24}{Added this macro} -% \begin{macrocode} -\def\hyxmp@parse@tz#1'#2'{% - #1:#2% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@today@define} -% Use \TeX's |\year|, |\month|, and |\day| primitives to define a given -% macro as today's date in \textsc{yyyy}-\textsc{mm}-\textsc{dd} 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} -% \begin{macrocode} -\def\hyxmp@today@define#1{% - \xdef#1{\the\year}% - \ifnum\month<10 - \xdef#1{#1-0\the\month}% - \else - \xdef#1{#1-\the\month}% - \fi - \ifnum\day<10 - \xdef#1{#1-0\the\day}% - \else - \xdef#1{#1-\the\day}% - \fi -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\hyxmp@today} -% Define |\hyxmp@today| 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} -% \begin{macrocode} -\@ifundefined{pdffeedback}{% - \@ifundefined{pdfcreationdate}{% -% \end{macrocode} -% Case 1: Neither |\pdffeedback| nor |\pdfcreationdate| is defined -% (\XeLaTeX\ and regular \LaTeX). -% \begin{macrocode} - \hyxmp@today@define\hyxmp@today - }{% -% \end{macrocode} -% Case 2: |\pdfcreationdate| is defined (\pdfLaTeX\ and pre-0.85 \LuaLaTeX). -% \begin{macrocode} - \edef\hyxmp@today{\expandafter\hyxmp@pdf@to@xmp@date\pdfcreationdate}% - }% -}{% -% \end{macrocode} -% Case 3: |\pdffeedback| is defined (\LuaLaTeX~0.85+). -% \begin{macrocode} - \edef\hyxmp@today{\expandafter\hyxmp@pdf@to@xmp@date\pdffeedback creationdate}% -} -% \end{macrocode} -% \end{macro} -% % \begin{macro}{\hyxmp@x@default} % Define an |x-default| string that we can use in comparisons with % |\@pdfmetalang|. @@ -2926,6 +3203,11 @@ ______^^J% % \protect\xmpterm{CreateDate}, \protect\xmpterm{ModifyDate}, and % \protect\xmpterm{MetadataDate} match the \protect\acro{PDF} % \protect\pdfterm{CreationDate}} +% \changes{v3.2}{2017/01/22}{Honor \string\pkgname{hyperref}'s +% \string\optname{pdfcreationdate} and \string\optname{pdfmoddate} +% options plus a new \string\optname{pdfmetadate} option. Leonid +% Sinev requested this additional control and helped test the resulting +% \protect\pkgname{hyperxmp} code} % \begin{macrocode} \newcommand*{\hyxmp@xmp@basic@schema}{% \hyxmp@add@to@xml{% @@ -2933,9 +3215,49 @@ ______^^J% }% \hyxmp@define@createdate - \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@createdate}% - \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@createdate}% - \hyxmp@add@simple{xmp:MetadataDate}{\hyxmp@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|. +% \begin{macrocode} + \@ifundefined{@pdfcreationdate}{% + \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@createdate}% + }{% + \ifx\@pdfcreationdate\@empty + \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@createdate}% + \else + \hyxmp@add@simple{xmp:CreateDate}{% + \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfcreationdate}}% + \fi + }% +% \end{macrocode} +% For the document's modification date, use the user-specified +% |\@pdfmoddate| if defined and non-empty. Otherwise use our +% fabricated |\hyxmp@createdate|. +% \begin{macrocode} + \@ifundefined{@pdfmoddate}{% + \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@createdate}% + }{% + \ifx\@pdfmoddate\@empty + \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@createdate}% + \else + \hyxmp@add@simple{xmp:ModifyDate}{% + \expandafter\hyxmp@as@xmp@date\expandafter{\@pdfmoddate}}% + \fi + }% +% \end{macrocode} +% For the document's metadata date, use the user-specified +% |\@pdfmetadatetime| if defined and non-empty. Otherwise use our +% fabricated |\hyxmp@createdate|. +% \begin{macrocode} + \ifx\@pdfmetadatetime\@empty + \hyxmp@add@simple{xmp:MetadataDate}{\hyxmp@createdate}% + \else + \hyxmp@add@simple{xmp:MetadataDate}{\@pdfmetadatetime}% + \fi +% \end{macrocode} +% Define the creation tool and the base \acro{URL}. +% \begin{macrocode} \hyxmp@add@simple{xmp:CreatorTool}{\@pdfcreator}% \hyxmp@add@simple{xmp:BaseURL}{\@baseurl}% \hyxmp@add@to@xml{% @@ -3358,14 +3680,44 @@ ___^^J% % % \subsubsection{Embedding using \pdfTeX} % +% Up to version~0.85, \LuaTeX\ supported the \pdfTeX\ primitives, and +% \pkgname{hyperref} didn't distinguish the two backends. However, from +% \pkgname{hyperxmp}'s perspective there is one key difference: the +% effect of |\pdfcompresslevel| is local to a group in \pdfTeX\ but is +% global in \LuaTeX\@. +% +% The \acro{PDF} object representing the \acro{XMP} packet is supposed +% to include an uncompressed stream so it can be read by +% non-\acro{PDF}-aware tools. However, we don't want to unnecessarily +% uncompress \emph{every} \acro{PDF} stream. The solution, provided by +% Hans Hagen on the |luatex| mailing list (thread: +% \href{http://tug.org/pipermail/luatex/2016-July/006077.html}{``Leaving +% a single PDF object uncompressed''}, 6\,\textsc{Jul}\,2016), is to +% provide the |uncompressed| flag to |\pdfobj|. Our definition of +% |\hyxmp@embed@packet@pdftex| uses the \pkgname{ifluatex} package to +% distinguish the \pdfTeX\ case from the pre-0.85 \LuaTeX\ case. +% +% \begin{macrocode} +\RequirePackage{ifluatex} +% \end{macrocode} +% % \begin{macro}{\hyxmp@embed@packet@pdftex} % Embed the \acro{XMP} packet using \pdfTeX\ primitives, which are -% supported by both \pdfTeX\ and pre-0.85 \LuaTeX. +% supported by both \pdfTeX\ and pre-0.85 \LuaTeX. The only difference +% is that in the former case we locally specify |\pdfcompresslevel=0| to +% leave the \acro{PDF} object uncompressed while in the latter case we +% pass the |uncompressed| flag to |\pdfobj| to achieve the same effect. +% \changes{v3.1}{2016/07/06}{Leave the \protect\acro{XMP} packet---and +% only the \protect\acro{XMP} packet---uncompressed in both +% \protect\pdfTeX\ and pre-0.85 \protect\LuaTeX} % \begin{macrocode} \newcommand*{\hyxmp@embed@packet@pdftex}{% \bgroup - \pdfcompresslevel=0 - \immediate\pdfobj stream attr {% + \ifluatex + \else + \pdfcompresslevel=0 + \fi + \immediate\pdfobj \ifluatex uncompressed\fi stream attr {% /Type /Metadata /Subtype /XML }{\hyxmp@xml}% @@ -3377,45 +3729,18 @@ ___^^J% % % \subsubsection{Embedding using \LuaTeX~0.85+} % -% If we're running \LuaLaTeX~0.85+ we apparently need to use \Lua\ -% directly to leave uncompressed the \acro{PDF} object holding the -% \acro{XMP} packet. The \pkgname{luacode} package facilitates the -% inclusion of Lua code in a \LaTeX\ document. -% \begin{macrocode} -\expandafter\ifx\csname pdffeedback\endcsname\relax -\else - \RequirePackage{luacode}% -% \end{macrocode} -% -% \begin{luafunc}{hyxmp_embed_packet} -% We define a \Lua\ function, |hyxmp_embed_packet|, that embeds a string -% as an uncompressed \acro{PDF} object of tyoe \xmpterm{Metadata}. -% \changes{v3.0}{2016/07/02}{Added this \protect\Lua\ function} -% \begin{macrocode} - \begin{luacode*} - function hyxmp_embed_packet (contents) - local n = pdf.obj { - type = "stream", - attr = [[ -/Type /Metadata -/Subtype /XML - ]], - compresslevel = 0, - string = contents - } - pdf.refobj(n) - end - \end{luacode*} -\fi -% \end{macrocode} -% \end{luafunc} -% % \begin{macro}{\hyxmp@embed@packet@luatex} % Embed the \acro{XMP} packet using \LuaTeX~0.85+ primitives. % \changes{v3.0}{2016/07/02}{Added this macro} +% \changes{v3.1}{2016/07/06}{Updated to use +% \protect\texttt{\string\string\string\pdfextension\ obj uncompressed} +% as suggested by Hans Hagen} % \begin{macrocode} \newcommand*{\hyxmp@embed@packet@luatex}{% - \luadirect{hyxmp_embed_packet(\luastring{\hyxmp@xml})}% + \immediate\pdfextension obj uncompressed stream attr {% + /Type /Metadata + /Subtype /XML + }{\hyxmp@xml}% \pdfextension catalog {/Metadata \the\numexpr\pdffeedback lastobj\relax\space 0 R}% } % \end{macrocode} @@ -3429,7 +3754,7 @@ ___^^J% % \optname{dvipsone}, \optname{dvips}, \optname{dviwindo}, % \optname{nativepdf}, \optname{pdfmark}, \optname{ps2pdf}, % \optname{textures}, and \optname{vtexpdfmark} options to -% \pkgname{hyperref} but I've tested only a few of those. +% \pkgname{hyperref}, but I've tested only a few of those. % \begin{macrocode} \newcommand*{\hyxmp@embed@packet@pdfmark}{% \pdfmark{% diff --git a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins index 1717e20b8d5..8f22906434d 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) 2016 by Scott Pakin +%% Copyright (C) 2017 by 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 @@ -21,7 +21,7 @@ This is a generated file. -Copyright (C) 2016 by Scott Pakin +Copyright (C) 2017 by 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 -- cgit v1.2.3