texlive[55549] Master/texmf-dist: hyperxmp (15jun20)
commits+karl at tug.org
commits+karl at tug.org
Mon Jun 15 00:18:02 CEST 2020
Revision: 55549
http://tug.org/svn/texlive?view=revision&revision=55549
Author: karl
Date: 2020-06-15 00:18:02 +0200 (Mon, 15 Jun 2020)
Log Message:
-----------
hyperxmp (15jun20)
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-14 22:17:46 UTC (rev 55548)
+++ trunk/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx 2020-06-14 22:18:02 UTC (rev 55549)
@@ -22,7 +22,7 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{hyperxmp}
%<*package>
- [2020/05/12 v5.2 Store hyperref metadata in XMP format]
+ [2020/06/13 v5.3 Store hyperref metadata in XMP format]
%</package>
%
%<*driver>
@@ -112,7 +112,7 @@
%</driver>
% \fi
%
-% \CheckSum{2425}
+% \CheckSum{2610}
%
% \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
@@ -169,6 +169,8 @@
% 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}
+% \changes{v5.0}{2020/03/17}{Don't set any document dates (creation,
+% modification, or metadata) from \string\optname{pdfdate}}
% \changes{v5.2}{2020/04/29}{Introduced the \protect\optname{pdfidentifier}
% package option, which enables an author to specify a unique identifier
% for the document}
@@ -189,6 +191,7 @@
% ^^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}}}
% \makeatletter
% \DeclareRobustCommand{\xmpprop}[2][]{^^A XMP property
% \def\xmppropopt{#1}^^A
@@ -1128,16 +1131,28 @@
% can include \term{Unicode} characters in its \acro{XMP} fields.
%
% \usagenote{Automatically specified metadata}
-% \optname{pdftitle} defaults to the document's title as specified by
-% |\title{|\dots|}|. \optname{pdfauthor} defaults to the document's
-% author(s) as specified by |\author{|\dots|}|. \optname{pdfdate}
-% defaults to the current date and time. \optname{pdfmetalang}
-% defaults to the same value as \optname{pdflang} if non-empty,
-% ``|x-default|'' otherwise. An implication of automatic
-% metadata specification is that an author can simply include
-% |\usepackage{hyperxmp}| in a document's preamble and benefit from
-% a modicum of \acro{XMP} metadata with no additional effort.
+% \pkgname{hyperxmp} attempts to identify certain metadata
+% automatically. The hope is that in many cases, an author can simply
+% include |\usepackage{hyperxmp}| in a document's preamble and benefit
+% from a modicum of \acro{XMP} metadata with no additional effort.
%
+% Currently, \optname{pdftitle} defaults to the document's title as
+% specified by |\title{|\dots|}|. \optname{pdfauthor} defaults to the
+% document's author(s) as specified by |\author{|\dots|}|.
+% \optname{pdfdate} defaults to the current date and time.
+% \optname{pdfmetalang} defaults to the same value as \optname{pdflang}
+% if non-empty, ``|x-default|'' otherwise. \pkgname{hyperxmp}
+% 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}).
+%
+% 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.
+%
% \usagenote{Multilingual metadata}
% \label{note:multilingual}
% The \optname{pdfmetalang} option specifies the language in which the
@@ -1435,22 +1450,24 @@
% Thanks to Heiko Oberdiek for the bug report and suggested modifications.}
%
% \begin{macro}{\hyxmp at at@end}
-% \begin{macro}{\hyxmp at driver}
% The |\hyxmp at at@end| macro includes code at the end of the document.
-% For \pdfTeX, the standard |\AtEndDocument| works well enough. For all
-% the other backends we use |\AtEndDvi| from the \pkgname{atenddvi}
-% package, which is more robust but requires an addition \LaTeX\ run.
+% When available (as is the case in most modern \tex\ backends),
+% \cs{AtEndDocument} works well enough. Otherwise, we invoke
+% \cs{AtEndDvi} from the \pkgname{atenddvi} package, which is robust but
+% requires an addition \LaTeX\ run.
+% \changes{v5.3}{2020/05/29}{Use \protect\cs{AtEndDocument} in all
+% \protect\tex\ back ends that provide it. Thanks to Nelson Posse
+% Lago for pointing out why \protect\pkgname{atenddvi} is best avoided
+% if possible}
% \begin{macrocode}
-\def\hyxmp at driver{hpdftex}
-\ifx\hyxmp at driver\Hy at driver
- \let\hyxmp at at@end=\AtEndDocument
-\else
+\@ifundefined{AtEndDocument}{%
\RequirePackage{atenddvi}
\let\hyxmp at at@end=\AtEndDvi
-\fi
+}{%
+ \let\hyxmp at at@end=\AtEndDocument
+}
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
%
% \subsection{Integration with \textsf{hyperref}}
@@ -1504,6 +1521,20 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\@if at def@and at nonempty}
+% This macro combines \cs{@ifundefined} and \cs{@ifmtargexp}. If the
+% macro named |#1| is both defined and non-empty, evaluate~|#2|.
+% Otherwise, evaluate~|#3|.
+% \changes{v5.3}{2020/06/07}{Added this macro}
+% \begin{macrocode}
+\newcommand*{\@if at def@and at nonempty}[3]{%
+ \@ifundefined{#1}{#3}{%
+ \expandafter\@ifmtargexp\expandafter{\csname#1\endcsname}{#3}{#2}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\hyxmp at pdfstringdef}
% \begin{macro}{\hyxmp at textunderscore}
% Because \pkgname{hyperxmp} uses underscores to represent hard spaces,
@@ -2421,31 +2452,79 @@
% \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 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).
% \begin{macrocode}
-\AtBeginDocument{%
- \@ifpackageloaded{hyperref}{%
+\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}{%
+ \edef\hyxmp at koma@phones{\scr at frommobilephone@var,\scr at fromphone@var}%
+ }{%
+ \edef\hyxmp at koma@phones{\scr at frommobilephone@var}%
+ }%
+ }{%
+ \@if at def@and at nonempty{scr at fromphone@var}{%
+ \edef\hyxmp at koma@phones{\scr at fromphone@var}%
+ }{%
+ }%
+ }%
+}
% \end{macrocode}
-% In older versions of \pkgname{hyperref}, |\@pdflang| is set to
-% |\@empty| if \optname{pdflang} is not specified. In newer versions of
-% \pkgname{hyperref}, |\@pdflang| is set to |\relax| if
-% \optname{pdflang} is not specified. The latter is a bit problematic
-% for \pkgname{hyperxmp} because it makes |\@pdflang| non-expandable,
-% which causes a literal ``|\@pdflang|'' to be written as \acro{XMP}
-% metadata. To avoid that situation we redefine |\@pdflang| as
-% |\@empty| if we see it set to |\relax|.
-% \changes{v2.3a}{2013/04/16}{Bug fix: Redefine \cs{@pdflang} as
-% \cs{@empty} when \protect\pkgname{hyperref} has set
-% it to \cs{relax}}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp at use@first at valid}
+% Given a \pkgname{hyperxmp} option~(|#1|), its current value~(|#2|),
+% and a comma-separated list of option names~(|#3|), if the current
+% value is empy, invoke \cs{hypersetup} to set the option to the first
+% non-empty item in the list. If all items in the list are empty, do
+% nothing.
+% \changes{v5.3}{2020/05/29}{Added this macro}
% \begin{macrocode}
- \ifx\@pdflang\relax
- \let\@pdflang=\@empty
+\newcommand*{\hyxmp at use@first at valid}[3]{%
+ \@ifmtargexp{#2}{%
+ \hyxmp at use@first at valid@i{#1}#3,!,%
+ }%
+ {}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp at use@first at valid@i}
+% This macro performs all the work for \cs{hyxmp at use@first at valid}. It
+% loops over a comma-separated list of macros~(|#2|), stopping when it
+% encounters an end-of-list marker~(``|!|''). The first list element
+% that is neither undefined nor empty is assigned to a given option
+% name~(|#1|) using \cs{hypersetup}.
+% \begin{macrocode}
+\def\hyxmp at use@first at valid@i#1#2,{%
+ \def\next{\hyxmp at use@first at valid@i{#1}}%
+ \ifx#2!%
+ \let\next=\relax
+ \else
+ \ifx#2\undefined
+ \else
+ \@ifnotmtargexp{#2}{%
+ \hypersetup{#1={#2}}%
+ \def\next##1!,{}%
+ }%
\fi
+ \fi
+ \next
+}
% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp at auto@assign at data}
+% If certain metadata are unspecified, try to specify meaningful values
+% using data provided by author via other means (e.g.,~\cs{title} for
+% the document's title).
+% \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}
@@ -2461,38 +2540,347 @@
% \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
+ \ifx\@pdfmetalang\@empty
+ \ifx\@pdflang\@empty
+ \let\@pdfmetalang=\hyxmp at x@default
+ \else
+ \edef\@pdfmetalang{\@pdflang}%
\fi
- \hyxmp at xmlify\@pdfmetalang
+ \fi
+ \hyxmp at xmlify\@pdfmetalang
% \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
-% \optname{pdfauthor}.
+% use the title for \optname{pdftitle}. Do likewise for various other
+% metadata: identify author-provided information that can be co-opted
+% for use as \acro{XMP} metadata.
% \changes{v2.7}{2016/02/01}{Automatically use \cs{title} and \cs{author}
% if \protect\optname{pdftitle} and \protect\optname{pdfauthor} are left
% 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}
% \begin{macrocode}
- \@ifmtargexp{\@pdftitle}{%
- \@ifnotmtargexp{\@title}{%
- \hypersetup{pdftitle={\@title}}%
+ \hyxmp at use@first at valid{pdftitle}{\@pdftitle}{%
+ \scr at subject@var,%
+ \@title
+ }%
+ \hyxmp at use@first at valid{pdfauthor}{\@pdfauthor}{%
+ \scr at fromname@var,%
+ \@author
+ }%
+ \hyxmp at use@first at valid{pdfcontactemail}{\@pdfcontactemail}{%
+ \scr at fromemail@var
+ }%
+ \hyxmp at set@koma at phones
+ \hyxmp at use@first at valid{pdfcontactphone}{\@pdfcontactphone}{%
+ \hyxmp at koma@phones
+ }%
+ \hyxmp at use@first at valid{pdfcontacturl}{\@pdfcontacturl}{%
+ \scr at fromurl@var
+ }%
+ \hyxmp at use@first at valid{pdfsubtitle}{\@pdfsubtitle}{%
+ \@subtitle
+ }%
+ \hyxmp at use@first at valid{pdfpublisher}{\@pdfpublisher}{%
+ \@publishers
+ }%
+% \end{macrocode}
+% We handle the \clsname{acmart} class specially. \clsname{acmart}
+% stores author-provided contact information in a structured format that
+% we can process fairly easily. Note that if the author is not using
+% the \clsname{acmart} class, \cs{hyxmp at parse@acmart} will have been
+% redefined to do nothing.
+% \begin{macrocode}
+ \hyxmp at parse@acmart
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp at parse@acmart}
+% The \clsname{acmart} class stores a rich set of author metadata in its
+% \cs{addresses} macro. \cs{hyxmp at parse@acmart} extracts the contact
+% information for the first author and converts that to \acro{XMP}
+% metadata.
+% \changes{v5.3}{2020/05/30}{Added this macro}
+% \begin{macrocode}
+\newcommand*{\hyxmp at parse@acmart}{%
+ \begingroup
+% \end{macrocode}
+% \begin{macro}{\@author}
+% \clsname{acmart} has already invoked
+% |\hypersetup{pdfauthor=|\dots|}| to specify the complete list of
+% authors. At this point, |\@author| is defined to produce a warning
+% message. We locally redefine it to do nothing.
+% \begin{macrocode}
+ \let\@author=\@gobble
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\email}
+% \begin{macro}{\hyxmp at address@val}
+% Within \cs{addresses}, \cs{email} is defined to accept two arguments,
+% the second of which is the author's email address.
+% \begin{macrocode}
+ \def\email##1##2{%
+ \def\hyxmp at address@val{##2}%
+ \hyxmp at use@first at valid{pdfcontactemail}{\@pdfcontactemail}{%
+ \hyxmp at address@val
}%
}%
- {}%
- \@ifmtargexp{\@pdfauthor}{%
- \@ifnotmtargexp{\@author}{%
- \hypersetup{pdfauthor={\@author}}%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\streetaddress}
+% \begin{macro}{\hyxmp at address@val}
+% \cs{streetaddress} wraps the author's street address.
+% \begin{macrocode}
+ \def\streetaddress##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactaddress}{\@pdfcontactaddress}{%
+ \hyxmp at address@val
}%
}%
- {}%
% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\city}
+% \begin{macro}{\hyxmp at address@val}
+% \cs{city} wraps the author's city name.
+% \begin{macrocode}
+ \def\city##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactcity}{\@pdfcontactcity}{%
+ \hyxmp at address@val
+ }%
+ }%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\state}
+% \begin{macro}{\hyxmp at address@val}
+% \cs{state} wraps the author's state or region name.
+% \begin{macrocode}
+ \def\state##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactregion}{\@pdfcontactregion}{%
+ \hyxmp at address@val
+ }%
+ }%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\country}
+% \begin{macro}{\hyxmp at address@val}
+% \cs{country} wraps the author's country name.
+% \begin{macrocode}
+ \def\country##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactcountry}{\@pdfcontactcountry}{%
+ \hyxmp at address@val
+ }%
+ }%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\postcode}
+% \begin{macro}{\hyxmp at address@val}
+% \cs{postcode} wraps the author's postal code.
+% \begin{macrocode}
+ \def\postcode##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactpostcode}{\@pdfcontactpostcode}{%
+ \hyxmp at address@val
+ }%
+ }%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\affiliation}
+% We want to produce \acro{XMP} metadata for only a single affiliation.
+% Although \cs{hyxmp at use@first at valid} will ensure that only the first
+% email, city, country, etc.\ encountered is considered, we run the
+% first of one affiliation defining, say, a city and state but no
+% country and a subsequent affiliation defining a country. In that
+% case, the \acro{XMP} would include the first author's city and state
+% and the subsequent author's country. Hence, we define
+% \cs{affiliation} to ``self destruct'' after its first use, discarding
+% all further affiliations.
+% \begin{macrocode}
+ \def\affiliation##1##2{%
+ ##2%
+ \let\affiliation=\@gobbletwo
+ }%
+% \end{macrocode}
+% \end{macro}
+%
+% We want to evaluate \cs{addresses} with the preceding local
+% definitions in effect, but we don't want to typeset any text appearing
+% in the string. Hence, we ``typeset'' \cs{addresses} within a box that
+% is subsequently discarded.
+% \begin{macrocode}
+ \setbox0=\hbox{\addresses}%
+ \endgroup
+% \end{macrocode}
+%
+% \clsname{acmart} supports other relevant metadata in addition to the
+% authors' mailing addresses. For instance, papers accepted for
+% publication indicate their \acro{DOI} number. However, papers under
+% review will contain either a placeholder \acro{DOI},
+% ``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.
+% \begin{macrocode}
+ \@if at def@and at nonempty{@acmDOI}{%
+ \IfSubStr{\@acmDOI}{10.1145/1122445.1122456}{}{%
+ \IfSubStr{\@acmDOI}{10.1145/nnnnnnn.nnnnnnn}{}{%
+ \hyxmp at use@first at valid{pdfdoi}{\@pdfdoi}{%
+ \@acmDOI
+ }%
+ }%
+ }%
+ }%
+% \end{macrocode}
+% \begin{macro}{\hyxmp at strip@isbn at date}
+% \begin{macro}{\hyxmp at acm@isbn}
+% Papers appearing in conference proceedings specify the proceedings'
+% \acro{ISBN}. As with \cs{@acmDOI} above, we ignore both the
+% placeholder \acro{ISBN}, ``978-x-xxxx-xxxx-x/YY/MM'', and the example
+% \acro{ISBN}, ``978-1-4503-XXXX-X/18/06''. We also strip off the
+% ``\texttt{/}\meta{year}\texttt{/}\meta{month}'' suffix so as to
+% include a true \acro{ISBN} in the \acro{XMP} metadata.
+% \begin{macrocode}
+ \@if at def@and at nonempty{@acmISBN}{%
+ \IfSubStr{\@acmISBN}{XXXX}{}{%
+ \IfSubStr{\@acmISBN}{xxxx}{}{%
+ \def\hyxmp at strip@isbn at date##1/##2!{##1}%
+ \edef\hyxmp at acm@isbn{%
+ \expandafter\hyxmp at strip@isbn at date\@acmISBN/!%
+ }%
+ \hyxmp at use@first at valid{pdfisbn}{\@pdfisbn}{%
+ \hyxmp at acm@isbn
+ }%
+ }%
+ }%
+ }%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\hyxmp at acm@publisher}
+% The publisher is of course \acro{ACM}.
+% \begin{macrocode}
+ \def\hyxmp at acm@publisher{Association for Computing Machinery}%
+ \hyxmp at use@first at valid{pdfpublisher}{\@pdfpublisher}{%
+ \hyxmp at acm@publisher
+ }%
+% \end{macrocode}
+% Use the journal name if defined, otherwise the book name (for
+% conference proceedings).
+% \begin{macrocode}
+ \hyxmp at use@first at valid{pdfpublication}{\@pdfpublication}{%
+ \@journalName,%
+ \@acmBooktitle,%
+ \@acmConference
+ }%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\hyxmp at acm@pubtype}
+% \clsname{acmart} makes clear whether it's typesetting a journal
+% article. If it's not a journal, we assume it's a book (conference
+% proceedings).
+% \begin{macrocode}
+ \if at ACM@journal
+ \def\hyxmp at acm@pubtype{journal}%
+ \else
+ \def\hyxmp at acm@pubtype{book}%
+ \fi
+ \hyxmp at use@first at valid{pdfpubtype}{\@pdfpubtype}{%
+ \hyxmp at acm@pubtype
+ }%
+% \end{macrocode}
+% \end{macro}
+% Journal articles have a volume and issue number.
+% \begin{macrocode}
+ \hyxmp at use@first at valid{pdfvolumenum}{\@pdfvolumenum}{%
+ \@acmVolume
+ }%
+ \hyxmp at use@first at valid{pdfissuenum}{\@pdfissuenum}{%
+ \@acmNumber
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Nullify \cs{hyxmp at parse@acmart} if the author is not using the
+% \clsname{acmart} class.
+% \begin{macrocode}
+\@ifclassloaded{acmart}{}{\let\hyxmp at parse@acmart=\relax}
+% \end{macrocode}
+%
+% \begin{macro}{\hyxmp at set@dc at lang}
+% \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
+% (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}.
+% \begin{macrocode}
+\newcommand*{\hyxmp at set@dc at lang}{%
+ \let\hyxmp at dc@lang=\@pdflang
+}
+% \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
+% 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}
+% 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.
+% \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}%
+ }%
+ }%
+ \fi
+% \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
@@ -2550,7 +2938,20 @@
}
% \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}| 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
@@ -4436,7 +4837,7 @@
% \changes{v4.1}{2019/04/05}{Added this macro}
% \begin{macrocode}
\newcommand{\hyxmp at singleton@dc}[3][Bag]{%
- \@ifnotmtarg{#3}{%
+ \@ifnotmtargexp{#3}{%
\hyxmp at xmlify{#3}%
\hyxmp at add@to at xml{%
______<dc:#2>^^J%
@@ -4498,7 +4899,6 @@
\hyxmp at rdf@dc{rights}{\@pdfcopyright}%
\hyxmp at singleton@dc{publisher}{\@pdfpublisher}%
\hyxmp at singleton@dc[Seq]{date}{\hyxmp at today@xmp}%
- \hyxmp at singleton@dc{language}{\@pdflang}%
\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}%
@@ -4507,6 +4907,17 @@
\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.
@@ -4777,7 +5188,7 @@
%
% \begin{macro}{\hyxmp at list@to at lines}
% Given a property~(|#1|) and a macro containing a comma-separated
-% list~(|#2|), replace commas with |\xmplinesep|. Do nothing it the
+% list~(|#2|), replace commas with |\xmplinesep|. Do nothing if the
% list is empty.
% \changes{v2.2}{2012/12/07}{Added this macro}
% \begin{macrocode}
Modified: trunk/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty 2020-06-14 22:17:46 UTC (rev 55548)
+++ trunk/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty 2020-06-14 22:18:02 UTC (rev 55549)
@@ -22,16 +22,15 @@
%%
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{hyperxmp}
- [2020/05/12 v5.2 Store hyperref metadata in XMP format]
+ [2020/06/13 v5.3 Store hyperref metadata in XMP format]
\edef\hyxmp at dq@code{\the\catcode`\"}
\catcode`\"=12
-\def\hyxmp at driver{hpdftex}
-\ifx\hyxmp at driver\Hy at driver
- \let\hyxmp at at@end=\AtEndDocument
-\else
+\@ifundefined{AtEndDocument}{%
\RequirePackage{atenddvi}
\let\hyxmp at at@end=\AtEndDvi
-\fi
+}{%
+ \let\hyxmp at at@end=\AtEndDocument
+}
\RequirePackage{kvoptions}
\RequirePackage{pdfescape}
\RequirePackage{stringenc}
@@ -42,6 +41,11 @@
\RequirePackage{ifthen}
\def\@ifmtargexp#1{\expandafter\@ifmtarg\expandafter{#1}}
\def\@ifnotmtargexp#1{\expandafter\@ifnotmtarg\expandafter{#1}}
+\newcommand*{\@if at def@and at nonempty}[3]{%
+ \@ifundefined{#1}{#3}{%
+ \expandafter\@ifmtargexp\expandafter{\csname#1\endcsname}{#3}{#2}%
+ }%
+}
\newcommand{\hyxmp at pdfstringdef}[2]{%
\let\hyxmp at textunderscore=\textunderscore
\let\textunderscore=\hyxmp at uscore
@@ -361,31 +365,184 @@
{}%
}%
}
-\AtBeginDocument{%
- \@ifpackageloaded{hyperref}{%
- \ifx\@pdflang\relax
- \let\@pdflang=\@empty
+\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}{%
+ \edef\hyxmp at koma@phones{\scr at frommobilephone@var,\scr at fromphone@var}%
+ }{%
+ \edef\hyxmp at koma@phones{\scr at frommobilephone@var}%
+ }%
+ }{%
+ \@if at def@and at nonempty{scr at fromphone@var}{%
+ \edef\hyxmp at koma@phones{\scr at fromphone@var}%
+ }{%
+ }%
+ }%
+}
+\newcommand*{\hyxmp at use@first at valid}[3]{%
+ \@ifmtargexp{#2}{%
+ \hyxmp at use@first at valid@i{#1}#3,!,%
+ }%
+ {}%
+}
+\def\hyxmp at use@first at valid@i#1#2,{%
+ \def\next{\hyxmp at use@first at valid@i{#1}}%
+ \ifx#2!%
+ \let\next=\relax
+ \else
+ \ifx#2\undefined
+ \else
+ \@ifnotmtargexp{#2}{%
+ \hypersetup{#1={#2}}%
+ \def\next##1!,{}%
+ }%
\fi
- \ifx\@pdfmetalang\@empty
- \ifx\@pdflang\@empty
- \let\@pdfmetalang=\hyxmp at x@default
- \else
- \edef\@pdfmetalang{\@pdflang}%
- \fi
+ \fi
+ \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
- \hyxmp at xmlify\@pdfmetalang
- \@ifmtargexp{\@pdftitle}{%
- \@ifnotmtargexp{\@title}{%
- \hypersetup{pdftitle={\@title}}%
+ \fi
+ \hyxmp at xmlify\@pdfmetalang
+ \hyxmp at use@first at valid{pdftitle}{\@pdftitle}{%
+ \scr at subject@var,%
+ \@title
+ }%
+ \hyxmp at use@first at valid{pdfauthor}{\@pdfauthor}{%
+ \scr at fromname@var,%
+ \@author
+ }%
+ \hyxmp at use@first at valid{pdfcontactemail}{\@pdfcontactemail}{%
+ \scr at fromemail@var
+ }%
+ \hyxmp at set@koma at phones
+ \hyxmp at use@first at valid{pdfcontactphone}{\@pdfcontactphone}{%
+ \hyxmp at koma@phones
+ }%
+ \hyxmp at use@first at valid{pdfcontacturl}{\@pdfcontacturl}{%
+ \scr at fromurl@var
+ }%
+ \hyxmp at use@first at valid{pdfsubtitle}{\@pdfsubtitle}{%
+ \@subtitle
+ }%
+ \hyxmp at use@first at valid{pdfpublisher}{\@pdfpublisher}{%
+ \@publishers
+ }%
+ \hyxmp at parse@acmart
+}
+\newcommand*{\hyxmp at parse@acmart}{%
+ \begingroup
+ \let\@author=\@gobble
+ \def\email##1##2{%
+ \def\hyxmp at address@val{##2}%
+ \hyxmp at use@first at valid{pdfcontactemail}{\@pdfcontactemail}{%
+ \hyxmp at address@val
}%
}%
- {}%
- \@ifmtargexp{\@pdfauthor}{%
- \@ifnotmtargexp{\@author}{%
- \hypersetup{pdfauthor={\@author}}%
+ \def\streetaddress##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactaddress}{\@pdfcontactaddress}{%
+ \hyxmp at address@val
}%
}%
- {}%
+ \def\city##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactcity}{\@pdfcontactcity}{%
+ \hyxmp at address@val
+ }%
+ }%
+ \def\state##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactregion}{\@pdfcontactregion}{%
+ \hyxmp at address@val
+ }%
+ }%
+ \def\country##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactcountry}{\@pdfcontactcountry}{%
+ \hyxmp at address@val
+ }%
+ }%
+ \def\postcode##1{%
+ \def\hyxmp at address@val{##1}%
+ \hyxmp at use@first at valid{pdfcontactpostcode}{\@pdfcontactpostcode}{%
+ \hyxmp at address@val
+ }%
+ }%
+ \def\affiliation##1##2{%
+ ##2%
+ \let\affiliation=\@gobbletwo
+ }%
+ \setbox0=\hbox{\addresses}%
+ \endgroup
+ \@if at def@and at nonempty{@acmDOI}{%
+ \IfSubStr{\@acmDOI}{10.1145/1122445.1122456}{}{%
+ \IfSubStr{\@acmDOI}{10.1145/nnnnnnn.nnnnnnn}{}{%
+ \hyxmp at use@first at valid{pdfdoi}{\@pdfdoi}{%
+ \@acmDOI
+ }%
+ }%
+ }%
+ }%
+ \@if at def@and at nonempty{@acmISBN}{%
+ \IfSubStr{\@acmISBN}{XXXX}{}{%
+ \IfSubStr{\@acmISBN}{xxxx}{}{%
+ \def\hyxmp at strip@isbn at date##1/##2!{##1}%
+ \edef\hyxmp at acm@isbn{%
+ \expandafter\hyxmp at strip@isbn at date\@acmISBN/!%
+ }%
+ \hyxmp at use@first at valid{pdfisbn}{\@pdfisbn}{%
+ \hyxmp at acm@isbn
+ }%
+ }%
+ }%
+ }%
+ \def\hyxmp at acm@publisher{Association for Computing Machinery}%
+ \hyxmp at use@first at valid{pdfpublisher}{\@pdfpublisher}{%
+ \hyxmp at acm@publisher
+ }%
+ \hyxmp at use@first at valid{pdfpublication}{\@pdfpublication}{%
+ \@journalName,%
+ \@acmBooktitle,%
+ \@acmConference
+ }%
+ \if at ACM@journal
+ \def\hyxmp at acm@pubtype{journal}%
+ \else
+ \def\hyxmp at acm@pubtype{book}%
+ \fi
+ \hyxmp at use@first at valid{pdfpubtype}{\@pdfpubtype}{%
+ \hyxmp at acm@pubtype
+ }%
+ \hyxmp at use@first at valid{pdfvolumenum}{\@pdfvolumenum}{%
+ \@acmVolume
+ }%
+ \hyxmp at use@first at valid{pdfissuenum}{\@pdfissuenum}{%
+ \@acmNumber
+ }%
+}
+\@ifclassloaded{acmart}{}{\let\hyxmp at parse@acmart=\relax}
+\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}%
+ }%
+ }%
+ \fi
+ \hyxmp at auto@assign at data
\@ifundefined{XeTeXversion}{}{%
\@ifmtargexp{\@pdfcreationdate}{%
\let\@pdfcreationdate=\hyxmp at today@pdf
@@ -407,6 +564,7 @@
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,,%
@@ -1125,7 +1283,7 @@
\fi
}
\newcommand{\hyxmp at singleton@dc}[3][Bag]{%
- \@ifnotmtarg{#3}{%
+ \@ifnotmtargexp{#3}{%
\hyxmp at xmlify{#3}%
\hyxmp at add@to at xml{%
______<dc:#2>^^J%
@@ -1150,7 +1308,6 @@
\hyxmp at rdf@dc{rights}{\@pdfcopyright}%
\hyxmp at singleton@dc{publisher}{\@pdfpublisher}%
\hyxmp at singleton@dc[Seq]{date}{\hyxmp at today@xmp}%
- \hyxmp at singleton@dc{language}{\@pdflang}%
\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}%
@@ -1158,6 +1315,8 @@
\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
\hyxmp at cond@dc at identifier{info:doi/}{\@pdfdoi}%
More information about the tex-live-commits
mailing list.