texlive[55608] Master/texmf-dist: hyperxmp (20jun20)

commits+karl at tug.org commits+karl at tug.org
Sat Jun 20 22:41:10 CEST 2020


Revision: 55608
          http://tug.org/svn/texlive?view=revision&revision=55608
Author:   karl
Date:     2020-06-20 22:41:10 +0200 (Sat, 20 Jun 2020)
Log Message:
-----------
hyperxmp (20jun20)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf
    trunk/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx
    trunk/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty

Modified: trunk/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx	2020-06-20 20:40:51 UTC (rev 55607)
+++ trunk/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx	2020-06-20 20:41:10 UTC (rev 55608)
@@ -22,7 +22,7 @@
 %<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
 %<package>\ProvidesPackage{hyperxmp}
 %<*package>
-    [2020/06/13 v5.3 Store hyperref metadata in XMP format]
+    [2020/06/19 v5.4 Store hyperref metadata in XMP format]
 %</package>
 %
 %<*driver>
@@ -112,7 +112,7 @@
 %</driver>
 % \fi
 %
-% \CheckSum{2610}
+% \CheckSum{2671}
 %
 % \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
@@ -190,8 +190,16 @@
 %
 % ^^A  Define a few logical styles.
 % \DeclareRobustCommand{\term}[1]{#1\SortIndex{#1}{#1}}
-% \DeclareRobustCommand{\pkgname}[1]{\mbox{\textsf{#1}}\SortIndex{#1}{\textsf{#1}}}
-% \DeclareRobustCommand{\clsname}[1]{\mbox{\textsf{#1}}\SortIndex{#1}{\textsf{#1}}}
+% \DeclareRobustCommand{\pkgname}[1]{^^A
+%   \mbox{\textsf{#1}}^^A
+%   \SortIndex{#1}{\textsf{#1} (package)}^^A
+%   \index{packages&#1=\textsf{#1}}^^A
+% }
+% \DeclareRobustCommand{\clsname}[1]{^^A
+%   \mbox{\textsf{#1}}^^A
+%   \SortIndex{#1}{\textsf{#1} (class)}^^A
+%   \index{classes&#1=\textsf{#1}}^^A
+% }
 % \makeatletter
 % \DeclareRobustCommand{\xmpprop}[2][]{^^A   XMP property
 %   \def\xmppropopt{#1}^^A
@@ -210,7 +218,11 @@
 % }
 % \makeatother
 % \index{XMP=\acrostyle  {XMP}&properties|see{properties, \acrostyle{XMP}}}
-% \DeclareRobustCommand{\pdfterm}[1]{\mbox{\textsf{#1}}\SortIndex{#1}{\textsf{#1}}}
+% \DeclareRobustCommand{\pdfterm}[1]{^^A
+%   \mbox{\textsf{#1}}^^A
+%   \SortIndex{#1}{\textsf{#1}}^^A
+%   \index{PDF=\acrostyle{PDF}&#1=\textsf{#1}}^^A
+% }
 % \DeclareRobustCommand{\cmdname}[1]{\mbox{\texttt{#1}}\SortIndex{#1}{\texttt{#1}}}
 % \DeclareRobustCommand{\optname}[1]{^^A
 %   \mbox{\textsf{#1}}^^A
@@ -272,6 +284,15 @@
 % \DeclareRobustCommand{\Lua}{^^A
 %   Lua\index{Lua}^^A
 % }
+% \DeclareRobustCommand{\Koma}{^^A
+%   Koma^^A
+%   \SortIndex{Koma}{Koma (class)}^^A
+%   \index{classes&Koma}^^A
+% }
+% \DeclareRobustCommand{\ACMclass}{^^A
+%   \acro{ACM}^^A
+%   \index{classes&ACM=\acrostyle{ACM}}^^A
+% }
 %
 % ^^A  Define an environment just like macro but for Lua functions.
 % \makeatletter
@@ -1143,15 +1164,16 @@
 % \optname{pdfmetalang} defaults to the same value as \optname{pdflang}
 % if non-empty, ``|x-default|'' otherwise.  \pkgname{hyperxmp}
 % recognizes some class-specific metadata as well, such as that provided
-% via the Koma letter classes (e.g.,~\clsname{scrlttr2}) and the
-% \acro{ACM} article class (\clsname{acmart}).
+% via the \Koma\ letter classes (e.g.,~\clsname{scrlttr2}) and the
+% \ACMclass\ article class (\clsname{acmart}).
 %
-% If a document uses the \pkgname{polyglossia} package, it is
-% recommended that it \emph{not} explicitly set \optname{pdflang}.
-% \optname{pdflang} accepts only a single language name while
-% \pkgname{hyperxmp} can automatically query \pkgname{polyglossia} for a
-% list of all languages used in the document and include this list in an
-% \acro{XMP} \xmpterm{dc:language} element.
+% If a document uses either or \pkgname{babel} or \pkgname{polyglossia}
+% package, it is recommended that it \emph{not} explicitly set
+% \optname{pdflang}.  \optname{pdflang} accepts only a single language
+% name while \pkgname{hyperxmp} can automatically query \pkgname{babel}
+% and \pkgname{polyglossia} for a list of all languages used in the
+% document and include this list in an \acro{XMP} \xmpprop{dc:language}
+% element.
 %
 % \usagenote{Multilingual metadata}
 % \label{note:multilingual}
@@ -2212,6 +2234,7 @@
     }{}%
   }%
 %    \end{macrocode}
+% \Needspace{6\baselineskip}
 % \begin{macro}{\KV at Hyp@pdfauthor}
 % \begin{macro}{\xmpcomma}
 % \begin{macro}{\xmpquote}
@@ -2337,6 +2360,26 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\hyxmp at concated@metadata}
+% Assume that if the document loaded either \pkgname{babel} or
+% \pkgname{polyglossia} it will eventually define one or more languages
+% that \pkgname{hyperxmp} can list within a \xmpprop{dc:language}
+% element.
+%    \begin{macrocode}
+\edef\hyxmp at concated@metadata{}
+\AtEndPreamble{%
+  \@ifpackageloaded{babel}{%
+    \edef\hyxmp at concated@metadata{babel}%
+  }{%
+    \@ifpackageloaded{polyglossia}{%
+      \edef\hyxmp at concated@metadata{polyglossia}%
+    }{%
+    }%
+  }%
+}
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\hyxmp at find@metadata}
 % \begin{macro}{\hyxmp at concated@metadata}
 % Issue a warning message if the author failed to specify any metadata
@@ -2348,6 +2391,7 @@
 %    \begin{macrocode}
 \newcommand*{\hyxmp at find@metadata}{%
   \edef\hyxmp at concated@metadata{%
+    \hyxmp at concated@metadata
     \@baseurl
     \@pdfauthor
     \@pdfauthortitle
@@ -2452,11 +2496,151 @@
 % \end{macro}
 % \end{macro}
 %
+% Rather than load \pkgname{hyperref} ourself we let the author do it
+% then verify he actually did.  This approach gives the author the
+% flexibility to load \pkgname{hyperxmp} and \pkgname{hyperref} in
+% either order and to call |\hypersetup| anywhere in the document's
+% preamble, not just before \pkgname{hyperxmp} is loaded.
+%    \begin{macrocode}
+\AtEndPreamble{%
+  \@ifpackageloaded{hyperref}{%
+%    \end{macrocode}
+% If \cs{@pdflang} is not set, see if we can detect the document
+% language via either the \pkgname{babel} or \pkgname{polyglossia}
+% packages.
+%    \begin{macrocode}
+    \@if at def@and at nonempty{@pdflang}{%
+    }{%
+      \hyxmp at detect@langs
+    }%
+%    \end{macrocode}
+% Fill in any missing metadata we can using values provided by the author
+% via mechanisms other than the \cs{hypersetup} command.
+%    \begin{macrocode}
+    \hyxmp at auto@assign at data
+%    \end{macrocode}
+% Most \acro{PDF} standards dictate that if the same metadata appear in
+% both the \acro{XMP} packet and the \acro{PDF} \pdfterm{Info}
+% dictionary, the metadata must match.  This requirement poses a problem
+% for a user-unspecified \optname{pdfcreationdate} in the context of
+% \XeLaTeX\@.  In this case we explicitly define |\@pdfcreationdate| as
+% |\hyxmp at 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 at 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 at 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
+% the \acro{PDF} file at the \emph{beginning} of the document.  For
+% compatibility with both old and new \pkgname{hyperref} implementations
+% we suppress writing the \pdfterm{Info} dictionary here, at the
+% beginning of the document.
+% \changes{v4.1}{2019/04/02}{Invoke
+%   \protect\cs{hyxmp at no@info at lists} at the beginning of the
+%   document, for compatibility with both newer and older versions of
+%   \protect\pkgname{hyperref}}
+%    \begin{macrocode}
+    \hyxmp at no@info at lists
+%    \end{macrocode}
+% We wait until the end of the document to construct the \acro{XMP}
+% packet and write it to the \acro{PDF} document catalog.  This gives
+% the author ample opportunity to provide metadata to \pkgname{hyperref}
+% and thereby \pkgname{hyperxmp}.
+%    \begin{macrocode}
+    \hyxmp at at@end{%
+      \hyxmp at find@metadata
+      \hyxmp at embed@packet
+    }%
+  }{%
+    \PackageWarningNoLine{hyperxmp}{%
+      \jobname.tex failed to include a\MessageBreak
+      \string\usepackage\string{hyperref\string}
+      in the preamble.\MessageBreak
+      Consequently, all hyperxmp functionality will be\MessageBreak
+      disabled}%
+  }%
+}
+%    \end{macrocode}
+%
+% A number of classes either require or recommend that authors declare
+% various class-specific metadata \emph{after} the |\begin{document}|.
+% So where do we invoke \cs{hyxmp at auto@assign at data}?  On one hand, we
+% want to invoke it before the |\begin{document}| because this may
+% obviate \pkgname{hyperxmp}'s ``\meta{job name} did not specify any
+% metadata'' warning message.  On the other hand, we want to invoke it
+% after the |\begin{document}| so it picks up metadata not specified in
+% the preamble.  Our solution is to invoke \cs{hyxmp at auto@assign at data}
+% twice: both before the |\begin{document}| and at the |\end{document}|.
+% We additionally identify here the natural language(s) in use because
+% these aren't known until the end of the document when provided by
+% \pkgname{babel} or \pkgname{polyglossia}.  Also, \pkgname{hyperref}
+% forbids changes to \optname{pdflang} past the |\begin{document}|.
+% \changes{v1.3}{2011/04/25}{Introduced the \protect\optname{pdfmetalang}
+%   package option, which enables an author to specify the language in which he
+%   wrote the document's metadata}
+% \changes{v2.0}{2012/08/02}{New \cs{AtBeginDocument} code from Heiko
+%   Oberdiek to properly encode \cs{@pdfmetalang}}
+% \changes{v3.3}{2017/07/21}{Don't overwrite an existing
+%   \protect\optname{pdfmetalang} with \protect\optname{pdflang} or
+%   \protect\texttt{x-default}.  This addresses a bug report by Niklas
+%   Beisert}
+% \changes{v5.4}{2020/06/18}{Moved the automatic assignment of
+%   \protect\cs{@pdflang} and \protect\cs{@pdfmetalang} from
+%   \protect\cs{hyxmp at auto@assign at data} to within a call to
+%   \protect\cs{hyxmp at at@end}}
+%    \begin{macrocode}
+\hyxmp at at@end{%
+  \hyxmp at set@dc at lang
+  \ifx\@pdfmetalang\@empty
+    \ifx\@pdflang\@empty
+      \let\@pdfmetalang=\hyxmp at x@default
+    \else
+      \edef\@pdfmetalang{\@pdflang}%
+    \fi
+  \fi
+  \hyxmp at xmlify\@pdfmetalang
+  \hyxmp at auto@assign at data
+}
+%    \end{macrocode}
+%
+%
+% \subsection{Advanced metadata detection}
+%
+% \pkgname{hyperxmp} strives to be as convenient and user-friendly as
+% possible.  To that end, we try to automatically detect as much
+% metadata as possible.  The author can of course augment or override
+% autodetected metadata by explicitly providing values to
+% \cs{hypersetup}, but the hope is that we can save the author some
+% effort in many cases.
+%
+% In this section, we identify additional metadata we can use.  Most of
+% the functionality is class- or package-specific.  For example, we
+% check for phone numbers provided to the \Koma\ letter classes via
+% |\setkomavar{fromphone}{|\dots|}| and/or
+% |\setkomavar{frommobilephone}{|\dots|}|, street addresses provided to
+% the \ACMclass\ article class via \cs{affiliation}, and languages
+% the \pkgname{polyglossia} package is instructed to load via
+% \cs{setdefaultlanguage} and \cs{setotherlanguage}.
+%
 % \begin{macro}{\hyxmp at set@koma at phones}
 % \changes{v5.3}{2020/06/07}{Added this macro}
 % \begin{macro}{\hyxmp at koma@phones}
 % Define \cs{hyxmp at koma@phones} as a comma-separated list of the phone
-% numbers provided to a Koma letter class (mobile and landline).
+% numbers provided to a \Koma\ letter class (mobile and landline).
 %    \begin{macrocode}
 \newcommand*{\hyxmp at set@koma at phones}{%
   \@if at def@and at nonempty{scr at frommobilephone@var}{%
@@ -2525,30 +2709,6 @@
 %    \begin{macrocode}
 \newcommand*{\hyxmp at auto@assign at data}{%
 %    \end{macrocode}
-% If the author explicitly specified the language to use for the
-% document's metadata, we use that.  If not, we use the document
-% language, specified to \pkgname{hyperref} with the \protect\optname{pdflang}
-% option.  If the author did not specify a language, we use |x-default|
-% as the metadata language.
-% \changes{v1.3}{2011/04/25}{Introduced the \protect\optname{pdfmetalang}
-%   package option, which enables an author to specify the language in which he
-%   wrote the document's metadata}
-% \changes{v2.0}{2012/08/02}{New \cs{AtBeginDocument} code from Heiko
-%   Oberdiek to properly encode \cs{@pdfmetalang}}
-% \changes{v3.3}{2017/07/21}{Don't overwrite an existing
-%   \protect\optname{pdfmetalang} with \protect\optname{pdflang} or
-%   \protect\texttt{x-default}.  This addresses a bug report by Niklas
-%   Beisert}
-%    \begin{macrocode}
-  \ifx\@pdfmetalang\@empty
-    \ifx\@pdflang\@empty
-      \let\@pdfmetalang=\hyxmp at x@default
-    \else
-      \edef\@pdfmetalang{\@pdflang}%
-    \fi
-  \fi
-  \hyxmp at xmlify\@pdfmetalang
-%    \end{macrocode}
 % If the author left \optname{pdftitle} blank but specified |\title|,
 % use the title for \optname{pdftitle}.  Do likewise for various other
 % metadata: identify author-provided information that can be co-opted
@@ -2558,7 +2718,7 @@
 %   unspecified.   Thanks to Maciej Radziejewski for the suggestion}
 % \changes{v5.3}{2020/05/29}{Consider other author-provided sources of
 %   metadata.  Thanks to Robin Schwab for proposing that
-%  \protect\pkgname{hyperxmp} use the Koma letter classes's metadata}
+%  \protect\pkgname{hyperxmp} use the \Koma\ letter classes's metadata}
 %    \begin{macrocode}
   \hyxmp at use@first at valid{pdftitle}{\@pdftitle}{%
     \scr at subject@var,%
@@ -2728,6 +2888,8 @@
 % ``10.1145/nnnnnnn.nnnnnnn'', or the example \acro{DOI} specified in
 % the \clsname{acmart} example document, ``10.1145/1122445.1122456''.
 % We ignore both of those \acro{DOI}s.
+% \changes{v5.4}{2020/06/16}{Bug fix: Correct a missing ``else'' argument
+%   in two invocations of \protect\cs{@if at def@and at nonempty}}
 %    \begin{macrocode}
   \@if at def@and at nonempty{@acmDOI}{%
     \IfSubStr{\@acmDOI}{10.1145/1122445.1122456}{}{%
@@ -2738,6 +2900,7 @@
       }%
     }%
   }%
+  {}%
 %    \end{macrocode}
 % \begin{macro}{\hyxmp at strip@isbn at date}
 % \begin{macro}{\hyxmp at acm@isbn}
@@ -2761,6 +2924,7 @@
       }%
     }%
   }%
+  {}%
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -2819,16 +2983,17 @@
 % \begin{macro}{\hyxmp at dc@lang}
 % \cs{@pdflang} is used in both the \acro{PDF} document catalog (the
 % \pdfterm{Lang} key, written to the \acro{PDF} file by
-% \pkgname{hyperref}) and in the Dublin Core \xmpterm{dc:language} tag
+% \pkgname{hyperref}) and in the Dublin Core \xmpprop{dc:language} tag
 % (Section~\ref{sec:dublin-core}).  Normally, these are the same.
 % However, \pdfterm{Lang} accepts only a single language while
-% \xmpterm{dc:language} accepts multiple languages.  If the document
-% loads \pkgname{polyglossia} and does not specify \optname{pdflang} in
-% \cs{hypersetup}, \cs{hyxmp at set@dc at lang} is redefined below to set
-% \cs{hyxmp at dc@lang} to \pkgname{polyglossia}'s list of used languages
-% (once this is known).  Otherwise, \cs{hyxmp at set@dc at lang} assigns the
-% language specified by \optname{pdflang} (if any) to
-% \cs{hyxmp at dc@lang}.
+% \xmpprop{dc:language} accepts multiple languages.  If the document
+% loads either \pkgname{babel} or \pkgname{polyglossia} and does not
+% specify \optname{pdflang} in \cs{hypersetup}, \cs{hyxmp at set@dc at lang}
+% is redefined below (in \cs{hyxmp at detect@langs}) to set
+% \cs{hyxmp at dc@lang} to \pkgname{babel}\slash\pkgname{polyglossia}'s
+% list of used languages (once this is known).  Otherwise,
+% \cs{hyxmp at set@dc at lang} assigns the language specified by
+% \optname{pdflang} (if any) to \cs{hyxmp at dc@lang}.
 %    \begin{macrocode}
 \newcommand*{\hyxmp at set@dc at lang}{%
   \let\hyxmp at dc@lang=\@pdflang
@@ -2837,121 +3002,141 @@
 % \end{macro}
 % \end{macro}
 %
-% Rather than load \pkgname{hyperref} ourself we let the author do it
-% then verify he actually did.  This approach gives the author the
-% flexibility to load \pkgname{hyperxmp} and \pkgname{hyperref} in
-% either order and to call |\hypersetup| anywhere in the document's
-% preamble, not just before \pkgname{hyperxmp} is loaded.
+% \begin{macro}{\hyxmp at detect@langs}
+% If \optname{pdflang} was not specified, try to determine the document
+% language(s) using either \pkgname{babel}'s or \pkgname{polyglossia}'s
+% definitions.  If so, we redefine \cs{hyxmp at set@dc at lang} as a
+% comma-separate list of languages used in the document.
+% \changes{v5.3}{2020/06/08}{Acquire the default language from the
+%   \protect\pkgname{polyglossia} package, if loaded.  Thanks to
+%   Robin Schwab for bringing that package to my attention}
+% \changes{v5.4}{2020/06/16}{Refactored language detection into a
+% separate command}
 %    \begin{macrocode}
-\AtEndPreamble{%
-  \@ifpackageloaded{hyperref}{%
+\newcommand*{\hyxmp at detect@langs}{%
+  \@ifundefined{mainbcp47id}{%
+    \@ifundefined{LocaleForEach}{%
 %    \end{macrocode}
-% In older versions of \pkgname{hyperref}, \cs{@pdflang} is set to
+% The document doesn't appear to have loaded either \pkgname{babel} or
+% \pkgname{polyglossia}.  In this case we have one small task to do.  In
+% older versions of \pkgname{hyperref}, \cs{@pdflang} is set to
 % \cs{@empty} if \optname{pdflang} is not specified.  In newer versions
 % of \pkgname{hyperref}, \cs{@pdflang} is set to \cs{relax} if
 % \optname{pdflang} is not specified.  The latter is a bit problematic
 % for \pkgname{hyperxmp} because it makes \cs{@pdflang} non-expandable,
 % which causes a literal ``\cs{@pdflang}'' to be written as \acro{XMP}
-% metadata.  To avoid that situation we redefine \cs{@pdflang} as
-% \cs{@empty} if we see it set to \cs{relax}.  Actually, we first check
-% if the \pkgname{polyglossia} package has specified the document's main
-% language in \cs{mainbcp47id}.  If so, we use that instead of
-% \cs{@empty} and redefine \cs{hyxmp at set@dc at lang} to consider
-% \pkgname{polyglossia}'s list of used languages.
+% metadata.  To avoid that situation we explicitly set \cs{@pdflang} to
+% \cs{@empty} to avoid problems with non-expandable symbols.
 % \changes{v2.3a}{2013/04/16}{Bug fix: Redefine \cs{@pdflang} as
 %   \cs{@empty} when \protect\pkgname{hyperref} has set
 %   it to \cs{relax}}
-% \changes{v5.3}{2020/06/08}{Acquire the default language from the
-%   \protect\pkgname{polyglossia} package, if loaded.  Thanks to
-%   Robin Schwab for bringing that package to my attention}
 %    \begin{macrocode}
-    \ifx\@pdflang\relax
-      \@ifundefined{mainbcp47id}{%
-        \let\@pdflang=\@empty
-      }{%
-        \xdef\@pdflang{\csname mainbcp47id\endcsname}%
-        \renewcommand*{\hyxmp at set@dc at lang}{%
-          \edef\hyxmp at dc@lang{\xpg at bcp@loaded}%
+      \let\@pdflang=\@empty
+    }{%
+%    \end{macrocode}
+% Use \pkgname{babel}'s \cs{LocaleForEach} and \cs{getlocaleproperty} to
+% construct a comma-separate list of all document languages.  We also
+% set \cs{@pdflang} within \cs{hyxmp at set@dc at lang}.
+% (\cs{hyxmp at detect@langs} should only be called if \cs{@pdflang} is
+% empty.)  Unlike \pkgname{polyglossia}, \pkgname{babel} does not
+% provide information about the main language until after the
+% |\begin{document}| so we have to wait until \cs{hyxmp at set@dc at lang} is
+% called to set it.
+% \changes{v5.4}{2020/06/17}{Added support for \protect\pkgname{babel}}
+%    \begin{macrocode}
+      \BabelEnsureInfo
+      \renewcommand*{\hyxmp at set@dc at lang}{%
+        \getlocaleproperty\@pdflang{\bbl at main@language}{identification/tag.bcp47}%
+        \hyxmp at write@pdflang
+        \let\hyxmp at dc@lang=\relax
+        \LocaleForEach{%
+          \getlocaleproperty\hyxmp at lang@tag{####1}{identification/tag.bcp47}%
+          \ifx\hyxmp at dc@lang\relax
+            \edef\hyxmp at dc@lang{\hyxmp at lang@tag}%
+          \else
+            \edef\hyxmp at dc@lang{\hyxmp at dc@lang,\hyxmp at lang@tag}%
+          \fi
         }%
       }%
-    \fi
+    }%
+  }{%
 %    \end{macrocode}
-% Fill in any missing metadata we can using values provided by the author
-% via mechanisms other than the \cs{hypersetup} command.
+% Use \pkgname{polyglossia}'s \cs{mainbcp47id} as the document's main
+% language and its \cs{xpg at bcp@loaded} as a comma-separated list of all
+% document languages.
 %    \begin{macrocode}
-    \hyxmp at auto@assign at data
+    \xdef\@pdflang{\csname mainbcp47id\endcsname}%
+    \renewcommand*{\hyxmp at set@dc at lang}{%
+      \edef\hyxmp at dc@lang{\xpg at bcp@loaded}%
+    }%
+  }%
+}
 %    \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 at 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.
+% \end{macro}
+%
+% \begin{macro}{\hyxmp at write@pdflang}
+% Here's a conundrum: \pkgname{babel} doesn't provide access to
+% information on the document's main language until after the
+% |\begin{document}|.  However, \pkgname{hyperref} allows
+% \optname{pdflang} to be set only \emph{before} the |\begin{document}|.
+% So what do we do?
+%
+% Note that the underlying \cs{@pdflang} macro serves two purposes:
+% \pkgname{hyperref} uses it to set the \pdfterm{Lang} entry in the
+% \acro{PDF} document catalog, and \pkgname{hyperxmp} uses it as the
+% default metadata language.  The latter is used in \xmpprop{dc:title}
+% and other \acro{XMP} properties that can include per-language
+% variants.  We set \cs{@pdflang} once we have the main-language
+% information from \pkgname{babel}.  As this is too late for
+% \pkgname{hyperref}, we bypass \pkgname{hyperref} and manually write
+% the \pdfterm{Lang} key into the document catalog.  This is a bit
+% kludgy, but we do leverage as much of \pkgname{hyperref}'s
+% infrastructure as possible to increase \cs{hyxmp at write@pdflang}'s
+% robustness.
+% \changes{v5.4}{2020/06/19}{Added this macro}
 %    \begin{macrocode}
-    \@ifundefined{XeTeXversion}{}{%
-      \@ifmtargexp{\@pdfcreationdate}{%
-        \let\@pdfcreationdate=\hyxmp at today@pdf
-      }%
-      {}%
-    }%
+\newcommand*{\hyxmp at write@pdflang}{%
+  \@ifundefined{pdfmark}{%
+    \@ifundefined{@pdfm at mark}{%
+      \@ifundefined{pdfcatalog}{%
 %    \end{macrocode}
-% If the document claims to comply with one or more \acro{PDF}
-% standards, check that all of the requisite metadata are present.
+% We don't recognize the \tex\ engine or \acro{PDF} generator.  (This is
+% unexpected.)  We therefore issue a warning message and take no further
+% action.
 %    \begin{macrocode}
-    \hyxmp at check@standards
+        \PackageWarning{hyperxmp}{Unknown PDF generator; not setting the language (\@pdflang) in the PDF catalog}%
+      }{%
 %    \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
-% the \acro{PDF} file at the \emph{beginning} of the document.  For
-% compatibility with both old and new \pkgname{hyperref} implementations
-% we suppress writing the \pdfterm{Info} dictionary here, at the
-% beginning of the document.
-% \changes{v4.1}{2019/04/02}{Invoke
-%   \protect\cs{hyxmp at no@info at lists} at the beginning of the
-%   document, for compatibility with both newer and older versions of
-%   \protect\pkgname{hyperref}}
+% We're running either \pdfTeX\ or \LuaTeX\@.  (\pkgname{hyperref}
+% defines \cs{pdfcatalog} in the latter case.)
 %    \begin{macrocode}
-    \hyxmp at no@info at lists
+        \pdfcatalog{/Lang (\@pdflang)}%
+      }%
+    }{%
 %    \end{macrocode}
-% We wait until the end of the document to construct the \acro{XMP}
-% packet and write it to the \acro{PDF} document catalog.  This gives
-% the author ample opportunity to provide metadata to \pkgname{hyperref}
-% and thereby \pkgname{hyperxmp}.
+% We're running either \XeTeX\ or \tex~+
+% \texttt{dvipdfm}.\SortIndex{dvipdfm}{\texttt{dvipdfm}}.
 %    \begin{macrocode}
-    \hyxmp at at@end{%
-      \hyxmp at find@metadata
-      \hyxmp at embed@packet
+      \@pdfm at mark{docview << /Lang (\@pdflang) >>}%
     }%
-  }{%
-    \PackageWarningNoLine{hyperxmp}{%
-      \jobname.tex failed to include a\MessageBreak
-      \string\usepackage\string{hyperref\string}
-      in the preamble.\MessageBreak
-      Consequently, all hyperxmp functionality will be\MessageBreak
-      disabled}%
+}{%
+%    \end{macrocode}
+% We're running either \tex~+ \Dvips~+ Adobe Acrobat Distiller (or other
+% converter from PostScript to \acro{PDF}).
+%    \begin{macrocode}
+    \pdfmark{%
+      pdfmark=/PUT,Raw={%
+        \string{Catalog\string} <<
+        /Lang (\@pdflang)
+        >>
+      }%
+    }%
   }%
 }
 %    \end{macrocode}
+% \end{macro}
 %
-% A number of classes either require or recommend that authors declare
-% various class-specific metadata \emph{after} the |\begin{document}|.
-% So where do we invoke \cs{hyxmp at auto@assign at data}?  On one hand, we
-% want to invoke it before the |\begin{document}| because this may
-% obviate \pkgname{hyperxmp}'s ``\meta{job name} did not specify any
-% metadata'' warning message.  On the other hand, we want to invoke it
-% after the |\begin{document}| so it picks up metadata not specified in
-% the preamble.  Our solution is to invoke \cs{hyxmp at auto@assign at data}
-% twice: both before the |\begin{document}| at at the |\end{document}|.
-%    \begin{macrocode}
-\hyxmp at at@end{\hyxmp at auto@assign at data}
-%    \end{macrocode}
 %
-%
 % \subsection{Manipulating author-supplied data}
 %
 % The author provides metadata information to \pkgname{hyperxmp} via
@@ -4628,7 +4813,7 @@
 % Assign |\hyxmp at major@minor| to be the \acro{PDF} version targeted by
 % the running \TeX\ engine.
 % \changes{v5.2}{2020/05/10}{Added this macro.  \string\pkgname{hyperxmp}
-%   now correctly specifies \string\xmpterm{pdf:PDFVersion} when
+%   now correctly specifies \string\xmpprop{pdf:PDFVersion} when
 %   generating \string\acro{PDF}~2.0+.  Thanks to Ulrike Fischer for
 %   alerting me to \string\acro{PDF}~2.0's availability in the
 %   \string\TeX\ ecosystem and informing me how to activate it}
@@ -4852,11 +5037,11 @@
 % \end{macro}
 %
 % \begin{macro}{\hyxmp at cond@dc at identifier}
-% Conditionally add a \xmpterm{dc:identifier} tag.  Given a prefix
+% Conditionally add a \xmpprop{dc:identifier} tag.  Given a prefix
 % string~(|#1|) and a main string~(|#2|), wrap these in a
-% \xmpterm{dc:identifier} if the main string is nonempty and
+% \xmpprop{dc:identifier} if the main string is nonempty and
 % |\hyxmp at xmlified| \emph{is} empty (implying the
-% \xmpterm{dc:identifier} has not yet been written).
+% \xmpprop{dc:identifier} has not yet been written).
 % \changes{v5.2}{2020/04/29}{Added this macro}
 %    \begin{macrocode}
 \newcommand*{\hyxmp at cond@dc at identifier}[2]{%
@@ -4883,14 +5068,19 @@
 % the author specified \optname{pdftype}, and the
 % \xmpprop{dc:identifier} if the author specified
 % \optname{pdfidentifier} or if we can derive it from other options.  We
-% also specify the \xmpprop{dc:date} property using the date the
-% document was run through \LaTeX\ and the \xmpprop{dc:source} property
-% using the base name of the source file with |.tex| appended.
+% also specify the \xmpprop{dc:source} property using the base name of
+% the source file with |.tex| appended and the \xmpprop{dc:date}
+% property using the date the document was run through \LaTeX---unless
+% the author specified \optname{pdfdate}, in which case we use that.
 % \changes{v2.0}{2012/08/26}{Added support for \xmpprop{dc:language}
 %   and \xmpprop{dc:source}}
 % \changes{v2.4}{2013/12/21}{Made \xmpprop{dc:language} a \xmpterm{Bag}
 %   instead of an individual item so as to conform to the latest
 %   \acro{XMP} specifications, a detail identified by Florian Breitwieser}
+% \changes{v5.3}{2020/06/13}{Include all languages used in the document
+%   in \protect\xmpprop{dc:language}}
+% \changes{v5.4}{2020/06/18}{Bug fix: Use \protect\cs{hyxmp at today@xmp}
+%   as the date only if \protect\cs{@pdfdatetime} is undefined}
 %    \begin{macrocode}
 \newcommand*{\hyxmp at dc@schema}{%
   \hyxmp at add@simple{dc:format}{application/pdf}%
@@ -4898,7 +5088,11 @@
   \hyxmp at rdf@dc[\ifHy at pdfa]{description}{\@pdfsubject}%
   \hyxmp at rdf@dc{rights}{\@pdfcopyright}%
   \hyxmp at singleton@dc{publisher}{\@pdfpublisher}%
-  \hyxmp at singleton@dc[Seq]{date}{\hyxmp at today@xmp}%
+  \@ifmtargexp{\@pdfdatetime}{%
+    \hyxmp at singleton@dc[Seq]{date}{\hyxmp at today@xmp}%
+  }{%
+    \hyxmp at singleton@dc[Seq]{date}{\@pdfdatetime}%
+  }%
   \hyxmp at singleton@dc{type}{\@pdftype}%
   \hyxmp at list@to at xml[\ifHy at pdfa]{creator}{Seq}{\hyxmp at pdfauthor}%
   \hyxmp at list@to at xml{subject}{Bag}{\hyxmp at pdfkeywords}%
@@ -4906,18 +5100,7 @@
   \else
     \hyxmp at add@simple{dc:source}{\@pdfsource}%
   \fi
-%    \end{macrocode}
-% Set \cs{hyxmp at dc@lang} to either the single language \cs{@pdflang}
-% (which may be unspecified) or to a list of languages used in the
-% document via \pkgname{polyglossia}.  See
-% Section~\ref{sec:hyperref-int} for the definition of
-% \cs{hyxmp at set@dc at lang}.
-% \changes{v5.3}{2020/06/13}{Include all languages used in the document
-%   in \protect\xmpterm{dc:language}}
-%    \begin{macrocode}
-  \hyxmp at set@dc at lang
   \hyxmp at list@to at xml{language}{Bag}{\hyxmp at dc@lang}%
-%    \end{macrocode}
 % If |\@pdfidentifier| is empty, try setting it to each of |\@pdfdoi|,
 % |\@pdfeissn|, |\@pdfissn|, and |\@pdfisbn|, in turn, with proper
 % syntactic adjustments.
@@ -6254,6 +6437,7 @@
 % file, which offers the benefit of live hyperlinks in almost all
 % \acro{PDF} readers.
 %
+%
 % \subsection{Ensuring proper support}
 %
 % \begin{macro}{\next}
@@ -6298,6 +6482,7 @@
 \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

Modified: trunk/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty	2020-06-20 20:40:51 UTC (rev 55607)
+++ trunk/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty	2020-06-20 20:41:10 UTC (rev 55608)
@@ -22,7 +22,7 @@
 %% 
 \NeedsTeXFormat{LaTeX2e}[1999/12/01]
 \ProvidesPackage{hyperxmp}
-    [2020/06/13 v5.3 Store hyperref metadata in XMP format]
+    [2020/06/19 v5.4 Store hyperref metadata in XMP format]
 \edef\hyxmp at dq@code{\the\catcode`\"}
 \catcode`\"=12
 \@ifundefined{AtEndDocument}{%
@@ -287,8 +287,20 @@
   \hyxmp at redefine@Hyp
   \hyxmp at hypersetup
 }
+\edef\hyxmp at concated@metadata{}
+\AtEndPreamble{%
+  \@ifpackageloaded{babel}{%
+    \edef\hyxmp at concated@metadata{babel}%
+  }{%
+    \@ifpackageloaded{polyglossia}{%
+      \edef\hyxmp at concated@metadata{polyglossia}%
+    }{%
+    }%
+  }%
+}
 \newcommand*{\hyxmp at find@metadata}{%
   \edef\hyxmp at concated@metadata{%
+    \hyxmp at concated@metadata
     \@baseurl
     \@pdfauthor
     \@pdfauthortitle
@@ -365,6 +377,46 @@
     {}%
   }%
 }
+\AtEndPreamble{%
+  \@ifpackageloaded{hyperref}{%
+    \@if at def@and at nonempty{@pdflang}{%
+    }{%
+      \hyxmp at detect@langs
+    }%
+    \hyxmp at auto@assign at data
+    \@ifundefined{XeTeXversion}{}{%
+      \@ifmtargexp{\@pdfcreationdate}{%
+        \let\@pdfcreationdate=\hyxmp at today@pdf
+      }%
+      {}%
+    }%
+    \hyxmp at check@standards
+    \hyxmp at no@info at lists
+    \hyxmp at at@end{%
+      \hyxmp at find@metadata
+      \hyxmp at embed@packet
+    }%
+  }{%
+    \PackageWarningNoLine{hyperxmp}{%
+      \jobname.tex failed to include a\MessageBreak
+      \string\usepackage\string{hyperref\string}
+      in the preamble.\MessageBreak
+      Consequently, all hyperxmp functionality will be\MessageBreak
+      disabled}%
+  }%
+}
+\hyxmp at at@end{%
+  \hyxmp at set@dc at lang
+  \ifx\@pdfmetalang\@empty
+    \ifx\@pdflang\@empty
+      \let\@pdfmetalang=\hyxmp at x@default
+    \else
+      \edef\@pdfmetalang{\@pdflang}%
+    \fi
+  \fi
+  \hyxmp at xmlify\@pdfmetalang
+  \hyxmp at auto@assign at data
+}
 \newcommand*{\hyxmp at set@koma at phones}{%
   \@if at def@and at nonempty{scr at frommobilephone@var}{%
     \@if at def@and at nonempty{scr at fromphone@var}{%
@@ -401,14 +453,6 @@
   \next
 }
 \newcommand*{\hyxmp at auto@assign at data}{%
-  \ifx\@pdfmetalang\@empty
-    \ifx\@pdflang\@empty
-      \let\@pdfmetalang=\hyxmp at x@default
-    \else
-      \edef\@pdfmetalang{\@pdflang}%
-    \fi
-  \fi
-  \hyxmp at xmlify\@pdfmetalang
   \hyxmp at use@first at valid{pdftitle}{\@pdftitle}{%
     \scr at subject@var,%
     \@title
@@ -489,6 +533,7 @@
       }%
     }%
   }%
+  {}%
   \@if at def@and at nonempty{@acmISBN}{%
     \IfSubStr{\@acmISBN}{XXXX}{}{%
       \IfSubStr{\@acmISBN}{xxxx}{}{%
@@ -502,6 +547,7 @@
       }%
     }%
   }%
+  {}%
   \def\hyxmp at acm@publisher{Association for Computing Machinery}%
   \hyxmp at use@first at valid{pdfpublisher}{\@pdfpublisher}{%
     \hyxmp at acm@publisher
@@ -530,41 +576,54 @@
 \newcommand*{\hyxmp at set@dc at lang}{%
   \let\hyxmp at dc@lang=\@pdflang
 }
-\AtEndPreamble{%
-  \@ifpackageloaded{hyperref}{%
-    \ifx\@pdflang\relax
-      \@ifundefined{mainbcp47id}{%
-        \let\@pdflang=\@empty
-      }{%
-        \xdef\@pdflang{\csname mainbcp47id\endcsname}%
-        \renewcommand*{\hyxmp at set@dc at lang}{%
-          \edef\hyxmp at dc@lang{\xpg at bcp@loaded}%
+\newcommand*{\hyxmp at detect@langs}{%
+  \@ifundefined{mainbcp47id}{%
+    \@ifundefined{LocaleForEach}{%
+      \let\@pdflang=\@empty
+    }{%
+      \BabelEnsureInfo
+      \renewcommand*{\hyxmp at set@dc at lang}{%
+        \getlocaleproperty\@pdflang{\bbl at main@language}{identification/tag.bcp47}%
+        \hyxmp at write@pdflang
+        \let\hyxmp at dc@lang=\relax
+        \LocaleForEach{%
+          \getlocaleproperty\hyxmp at lang@tag{####1}{identification/tag.bcp47}%
+          \ifx\hyxmp at dc@lang\relax
+            \edef\hyxmp at dc@lang{\hyxmp at lang@tag}%
+          \else
+            \edef\hyxmp at dc@lang{\hyxmp at dc@lang,\hyxmp at lang@tag}%
+          \fi
         }%
       }%
-    \fi
-    \hyxmp at auto@assign at data
-    \@ifundefined{XeTeXversion}{}{%
-      \@ifmtargexp{\@pdfcreationdate}{%
-        \let\@pdfcreationdate=\hyxmp at today@pdf
+    }%
+  }{%
+    \xdef\@pdflang{\csname mainbcp47id\endcsname}%
+    \renewcommand*{\hyxmp at set@dc at lang}{%
+      \edef\hyxmp at dc@lang{\xpg at bcp@loaded}%
+    }%
+  }%
+}
+\newcommand*{\hyxmp at write@pdflang}{%
+  \@ifundefined{pdfmark}{%
+    \@ifundefined{@pdfm at mark}{%
+      \@ifundefined{pdfcatalog}{%
+        \PackageWarning{hyperxmp}{Unknown PDF generator; not setting the language (\@pdflang) in the PDF catalog}%
+      }{%
+        \pdfcatalog{/Lang (\@pdflang)}%
       }%
-      {}%
+    }{%
+      \@pdfm at mark{docview << /Lang (\@pdflang) >>}%
     }%
-    \hyxmp at check@standards
-    \hyxmp at no@info at lists
-    \hyxmp at at@end{%
-      \hyxmp at find@metadata
-      \hyxmp at embed@packet
+}{%
+    \pdfmark{%
+      pdfmark=/PUT,Raw={%
+        \string{Catalog\string} <<
+        /Lang (\@pdflang)
+        >>
+      }%
     }%
-  }{%
-    \PackageWarningNoLine{hyperxmp}{%
-      \jobname.tex failed to include a\MessageBreak
-      \string\usepackage\string{hyperref\string}
-      in the preamble.\MessageBreak
-      Consequently, all hyperxmp functionality will be\MessageBreak
-      disabled}%
   }%
 }
-\hyxmp at at@end{\hyxmp at auto@assign at data}
 \newcommand*{\hyxmp at commas@to at list}[2]{%
   \gdef#1{}%
   \expandafter\hyxmp at commas@to at list@i\expandafter#1#2,,%
@@ -1307,7 +1366,11 @@
   \hyxmp at rdf@dc[\ifHy at pdfa]{description}{\@pdfsubject}%
   \hyxmp at rdf@dc{rights}{\@pdfcopyright}%
   \hyxmp at singleton@dc{publisher}{\@pdfpublisher}%
-  \hyxmp at singleton@dc[Seq]{date}{\hyxmp at today@xmp}%
+  \@ifmtargexp{\@pdfdatetime}{%
+    \hyxmp at singleton@dc[Seq]{date}{\hyxmp at today@xmp}%
+  }{%
+    \hyxmp at singleton@dc[Seq]{date}{\@pdfdatetime}%
+  }%
   \hyxmp at singleton@dc{type}{\@pdftype}%
   \hyxmp at list@to at xml[\ifHy at pdfa]{creator}{Seq}{\hyxmp at pdfauthor}%
   \hyxmp at list@to at xml{subject}{Bag}{\hyxmp at pdfkeywords}%
@@ -1315,7 +1378,6 @@
   \else
     \hyxmp at add@simple{dc:source}{\@pdfsource}%
   \fi
-  \hyxmp at set@dc at lang
   \hyxmp at list@to at xml{language}{Bag}{\hyxmp at dc@lang}%
   \@ifmtargexp{\@pdfidentifier}{%
     \let\hyxmp at xmlified=\@empty



More information about the tex-live-commits mailing list.