diff options
author | Karl Berry <karl@freefriends.org> | 2020-06-14 22:18:02 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-06-14 22:18:02 +0000 |
commit | 3cc75a75fe8966b95123fd66dbd8db584ad74151 (patch) | |
tree | ae09ac42f93c9cd4741f3de985bd0628fa96138e /Master/texmf-dist | |
parent | 3e1ebf9c03aadcdc3750b4ca47b0e30758ead926 (diff) |
hyperxmp (15jun20)
git-svn-id: svn://tug.org/texlive/trunk@55549 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf | bin | 1303174 -> 1326332 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx | 541 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty | 213 |
3 files changed, 662 insertions, 92 deletions
diff --git a/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf b/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf Binary files differindex 01425c6e03f..28b08b07879 100644 --- a/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf +++ b/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf diff --git a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx index 1d2c3320185..e4e4f528374 100644 --- a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx +++ b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx @@ -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,15 +1131,27 @@ % 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} @@ -1435,22 +1450,24 @@ % Thanks to Heiko Oberdiek for the bug report and suggested modifications.} % % \begin{macro}{\hyxmp@at@end} -% \begin{macro}{\hyxmp@driver} % The |\hyxmp@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. -% \begin{macrocode} -\def\hyxmp@driver{hpdftex} -\ifx\hyxmp@driver\Hy@driver - \let\hyxmp@at@end=\AtEndDocument -\else +% 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} +\@ifundefined{AtEndDocument}{% \RequirePackage{atenddvi} \let\hyxmp@at@end=\AtEndDvi -\fi +}{% + \let\hyxmp@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@def@and@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@def@and@nonempty}[3]{% + \@ifundefined{#1}{#3}{% + \expandafter\@ifmtargexp\expandafter{\csname#1\endcsname}{#3}{#2}% + }% +} +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\hyxmp@pdfstringdef} % \begin{macro}{\hyxmp@textunderscore} % Because \pkgname{hyperxmp} uses underscores to represent hard spaces, @@ -2421,30 +2452,78 @@ % \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@set@koma@phones} +% \changes{v5.3}{2020/06/07}{Added this macro} +% \begin{macro}{\hyxmp@koma@phones} +% Define \cs{hyxmp@koma@phones} as a comma-separated list of the phone +% numbers provided to a Koma letter class (mobile and landline). % \begin{macrocode} -\AtBeginDocument{% - \@ifpackageloaded{hyperref}{% +\newcommand*{\hyxmp@set@koma@phones}{% + \@if@def@and@nonempty{scr@frommobilephone@var}{% + \@if@def@and@nonempty{scr@fromphone@var}{% + \edef\hyxmp@koma@phones{\scr@frommobilephone@var,\scr@fromphone@var}% + }{% + \edef\hyxmp@koma@phones{\scr@frommobilephone@var}% + }% + }{% + \@if@def@and@nonempty{scr@fromphone@var}{% + \edef\hyxmp@koma@phones{\scr@fromphone@var}% + }{% + }% + }% +} % \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@use@first@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@use@first@valid}[3]{% + \@ifmtargexp{#2}{% + \hyxmp@use@first@valid@i{#1}#3,!,% + }% + {}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@use@first@valid@i} +% This macro performs all the work for \cs{hyxmp@use@first@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@use@first@valid@i#1#2,{% + \def\next{\hyxmp@use@first@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@auto@assign@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@auto@assign@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 @@ -2461,37 +2540,346 @@ % \protect\texttt{x-default}. This addresses a bug report by Niklas % Beisert} % \begin{macrocode} - \ifx\@pdfmetalang\@empty - \ifx\@pdflang\@empty - \let\@pdfmetalang=\hyxmp@x@default - \else - \edef\@pdfmetalang{\@pdflang}% - \fi + \ifx\@pdfmetalang\@empty + \ifx\@pdflang\@empty + \let\@pdfmetalang=\hyxmp@x@default + \else + \edef\@pdfmetalang{\@pdflang}% \fi - \hyxmp@xmlify\@pdfmetalang + \fi + \hyxmp@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@use@first@valid{pdftitle}{\@pdftitle}{% + \scr@subject@var,% + \@title + }% + \hyxmp@use@first@valid{pdfauthor}{\@pdfauthor}{% + \scr@fromname@var,% + \@author + }% + \hyxmp@use@first@valid{pdfcontactemail}{\@pdfcontactemail}{% + \scr@fromemail@var + }% + \hyxmp@set@koma@phones + \hyxmp@use@first@valid{pdfcontactphone}{\@pdfcontactphone}{% + \hyxmp@koma@phones + }% + \hyxmp@use@first@valid{pdfcontacturl}{\@pdfcontacturl}{% + \scr@fromurl@var + }% + \hyxmp@use@first@valid{pdfsubtitle}{\@pdfsubtitle}{% + \@subtitle + }% + \hyxmp@use@first@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@parse@acmart} will have been +% redefined to do nothing. +% \begin{macrocode} + \hyxmp@parse@acmart +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hyxmp@parse@acmart} +% The \clsname{acmart} class stores a rich set of author metadata in its +% \cs{addresses} macro. \cs{hyxmp@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@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@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@address@val{##2}% + \hyxmp@use@first@valid{pdfcontactemail}{\@pdfcontactemail}{% + \hyxmp@address@val }% }% - {}% - \@ifmtargexp{\@pdfauthor}{% - \@ifnotmtargexp{\@author}{% - \hypersetup{pdfauthor={\@author}}% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\streetaddress} +% \begin{macro}{\hyxmp@address@val} +% \cs{streetaddress} wraps the author's street address. +% \begin{macrocode} + \def\streetaddress##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactaddress}{\@pdfcontactaddress}{% + \hyxmp@address@val }% }% - {}% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\city} +% \begin{macro}{\hyxmp@address@val} +% \cs{city} wraps the author's city name. +% \begin{macrocode} + \def\city##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactcity}{\@pdfcontactcity}{% + \hyxmp@address@val + }% + }% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\state} +% \begin{macro}{\hyxmp@address@val} +% \cs{state} wraps the author's state or region name. +% \begin{macrocode} + \def\state##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactregion}{\@pdfcontactregion}{% + \hyxmp@address@val + }% + }% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\country} +% \begin{macro}{\hyxmp@address@val} +% \cs{country} wraps the author's country name. +% \begin{macrocode} + \def\country##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactcountry}{\@pdfcontactcountry}{% + \hyxmp@address@val + }% + }% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\postcode} +% \begin{macro}{\hyxmp@address@val} +% \cs{postcode} wraps the author's postal code. +% \begin{macrocode} + \def\postcode##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactpostcode}{\@pdfcontactpostcode}{% + \hyxmp@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@use@first@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@def@and@nonempty{@acmDOI}{% + \IfSubStr{\@acmDOI}{10.1145/1122445.1122456}{}{% + \IfSubStr{\@acmDOI}{10.1145/nnnnnnn.nnnnnnn}{}{% + \hyxmp@use@first@valid{pdfdoi}{\@pdfdoi}{% + \@acmDOI + }% + }% + }% + }% +% \end{macrocode} +% \begin{macro}{\hyxmp@strip@isbn@date} +% \begin{macro}{\hyxmp@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@def@and@nonempty{@acmISBN}{% + \IfSubStr{\@acmISBN}{XXXX}{}{% + \IfSubStr{\@acmISBN}{xxxx}{}{% + \def\hyxmp@strip@isbn@date##1/##2!{##1}% + \edef\hyxmp@acm@isbn{% + \expandafter\hyxmp@strip@isbn@date\@acmISBN/!% + }% + \hyxmp@use@first@valid{pdfisbn}{\@pdfisbn}{% + \hyxmp@acm@isbn + }% + }% + }% + }% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\hyxmp@acm@publisher} +% The publisher is of course \acro{ACM}. +% \begin{macrocode} + \def\hyxmp@acm@publisher{Association for Computing Machinery}% + \hyxmp@use@first@valid{pdfpublisher}{\@pdfpublisher}{% + \hyxmp@acm@publisher + }% +% \end{macrocode} +% Use the journal name if defined, otherwise the book name (for +% conference proceedings). +% \begin{macrocode} + \hyxmp@use@first@valid{pdfpublication}{\@pdfpublication}{% + \@journalName,% + \@acmBooktitle,% + \@acmConference + }% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\hyxmp@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@ACM@journal + \def\hyxmp@acm@pubtype{journal}% + \else + \def\hyxmp@acm@pubtype{book}% + \fi + \hyxmp@use@first@valid{pdfpubtype}{\@pdfpubtype}{% + \hyxmp@acm@pubtype + }% +% \end{macrocode} +% \end{macro} +% Journal articles have a volume and issue number. +% \begin{macrocode} + \hyxmp@use@first@valid{pdfvolumenum}{\@pdfvolumenum}{% + \@acmVolume + }% + \hyxmp@use@first@valid{pdfissuenum}{\@pdfissuenum}{% + \@acmNumber + }% +} +% \end{macrocode} +% \end{macro} +% +% Nullify \cs{hyxmp@parse@acmart} if the author is not using the +% \clsname{acmart} class. +% \begin{macrocode} +\@ifclassloaded{acmart}{}{\let\hyxmp@parse@acmart=\relax} +% \end{macrocode} +% +% \begin{macro}{\hyxmp@set@dc@lang} +% \begin{macro}{\hyxmp@dc@lang} +% \cs{@pdflang} is used in both the \acro{PDF} document catalog (the +% \pdfterm{Lang} key, written to the \acro{PDF} file by +% \pkgname{hyperref}) and in the Dublin Core \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@set@dc@lang} is redefined below to set +% \cs{hyxmp@dc@lang} to \pkgname{polyglossia}'s list of used languages +% (once this is known). Otherwise, \cs{hyxmp@set@dc@lang} assigns the +% language specified by \optname{pdflang} (if any) to +% \cs{hyxmp@dc@lang}. +% \begin{macrocode} +\newcommand*{\hyxmp@set@dc@lang}{% + \let\hyxmp@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@set@dc@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@set@dc@lang}{% + \edef\hyxmp@dc@lang{\xpg@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@auto@assign@data % \end{macrocode} % Most \acro{PDF} standards dictate that if the same metadata appear in % both the \acro{XMP} packet and the \acro{PDF} \pdfterm{Info} @@ -2550,6 +2938,19 @@ } % \end{macrocode} % +% A number of classes either require or recommend that authors declare +% various class-specific metadata \emph{after} the |\begin{document}|. +% So where do we invoke \cs{hyxmp@auto@assign@data}? On one hand, we +% want to invoke it before the |\begin{document}| because this may +% obviate \pkgname{hyperxmp}'s ``\meta{job name} did not specify any +% metadata'' warning message. On the other hand, we want to invoke it +% after the |\begin{document}| so it picks up metadata not specified in +% the preamble. Our solution is to invoke \cs{hyxmp@auto@assign@data} +% twice: both before the |\begin{document}| at at the |\end{document}|. +% \begin{macrocode} +\hyxmp@at@end{\hyxmp@auto@assign@data} +% \end{macrocode} +% % % \subsection{Manipulating author-supplied data} % @@ -4436,7 +4837,7 @@ ______</dc:#2>^^J% % \changes{v4.1}{2019/04/05}{Added this macro} % \begin{macrocode} \newcommand{\hyxmp@singleton@dc}[3][Bag]{% - \@ifnotmtarg{#3}{% + \@ifnotmtargexp{#3}{% \hyxmp@xmlify{#3}% \hyxmp@add@to@xml{% ______<dc:#2>^^J% @@ -4498,7 +4899,6 @@ ______</dc:#2>^^J% \hyxmp@rdf@dc{rights}{\@pdfcopyright}% \hyxmp@singleton@dc{publisher}{\@pdfpublisher}% \hyxmp@singleton@dc[Seq]{date}{\hyxmp@today@xmp}% - \hyxmp@singleton@dc{language}{\@pdflang}% \hyxmp@singleton@dc{type}{\@pdftype}% \hyxmp@list@to@xml[\ifHy@pdfa]{creator}{Seq}{\hyxmp@pdfauthor}% \hyxmp@list@to@xml{subject}{Bag}{\hyxmp@pdfkeywords}% @@ -4507,6 +4907,17 @@ ______</dc:#2>^^J% \hyxmp@add@simple{dc:source}{\@pdfsource}% \fi % \end{macrocode} +% Set \cs{hyxmp@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@set@dc@lang}. +% \changes{v5.3}{2020/06/13}{Include all languages used in the document +% in \protect\xmpterm{dc:language}} +% \begin{macrocode} + \hyxmp@set@dc@lang + \hyxmp@list@to@xml{language}{Bag}{\hyxmp@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 @@ ______</dc:#2>^^J% % % \begin{macro}{\hyxmp@list@to@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} diff --git a/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty b/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty index 9aaa6b6e101..2293be810c9 100644 --- a/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty +++ b/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty @@ -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@dq@code{\the\catcode`\"} \catcode`\"=12 -\def\hyxmp@driver{hpdftex} -\ifx\hyxmp@driver\Hy@driver - \let\hyxmp@at@end=\AtEndDocument -\else +\@ifundefined{AtEndDocument}{% \RequirePackage{atenddvi} \let\hyxmp@at@end=\AtEndDvi -\fi +}{% + \let\hyxmp@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@def@and@nonempty}[3]{% + \@ifundefined{#1}{#3}{% + \expandafter\@ifmtargexp\expandafter{\csname#1\endcsname}{#3}{#2}% + }% +} \newcommand{\hyxmp@pdfstringdef}[2]{% \let\hyxmp@textunderscore=\textunderscore \let\textunderscore=\hyxmp@uscore @@ -361,31 +365,184 @@ {}% }% } -\AtBeginDocument{% - \@ifpackageloaded{hyperref}{% - \ifx\@pdflang\relax - \let\@pdflang=\@empty +\newcommand*{\hyxmp@set@koma@phones}{% + \@if@def@and@nonempty{scr@frommobilephone@var}{% + \@if@def@and@nonempty{scr@fromphone@var}{% + \edef\hyxmp@koma@phones{\scr@frommobilephone@var,\scr@fromphone@var}% + }{% + \edef\hyxmp@koma@phones{\scr@frommobilephone@var}% + }% + }{% + \@if@def@and@nonempty{scr@fromphone@var}{% + \edef\hyxmp@koma@phones{\scr@fromphone@var}% + }{% + }% + }% +} +\newcommand*{\hyxmp@use@first@valid}[3]{% + \@ifmtargexp{#2}{% + \hyxmp@use@first@valid@i{#1}#3,!,% + }% + {}% +} +\def\hyxmp@use@first@valid@i#1#2,{% + \def\next{\hyxmp@use@first@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@x@default - \else - \edef\@pdfmetalang{\@pdflang}% - \fi + \fi + \next +} +\newcommand*{\hyxmp@auto@assign@data}{% + \ifx\@pdfmetalang\@empty + \ifx\@pdflang\@empty + \let\@pdfmetalang=\hyxmp@x@default + \else + \edef\@pdfmetalang{\@pdflang}% \fi - \hyxmp@xmlify\@pdfmetalang - \@ifmtargexp{\@pdftitle}{% - \@ifnotmtargexp{\@title}{% - \hypersetup{pdftitle={\@title}}% + \fi + \hyxmp@xmlify\@pdfmetalang + \hyxmp@use@first@valid{pdftitle}{\@pdftitle}{% + \scr@subject@var,% + \@title + }% + \hyxmp@use@first@valid{pdfauthor}{\@pdfauthor}{% + \scr@fromname@var,% + \@author + }% + \hyxmp@use@first@valid{pdfcontactemail}{\@pdfcontactemail}{% + \scr@fromemail@var + }% + \hyxmp@set@koma@phones + \hyxmp@use@first@valid{pdfcontactphone}{\@pdfcontactphone}{% + \hyxmp@koma@phones + }% + \hyxmp@use@first@valid{pdfcontacturl}{\@pdfcontacturl}{% + \scr@fromurl@var + }% + \hyxmp@use@first@valid{pdfsubtitle}{\@pdfsubtitle}{% + \@subtitle + }% + \hyxmp@use@first@valid{pdfpublisher}{\@pdfpublisher}{% + \@publishers + }% + \hyxmp@parse@acmart +} +\newcommand*{\hyxmp@parse@acmart}{% + \begingroup + \let\@author=\@gobble + \def\email##1##2{% + \def\hyxmp@address@val{##2}% + \hyxmp@use@first@valid{pdfcontactemail}{\@pdfcontactemail}{% + \hyxmp@address@val }% }% - {}% - \@ifmtargexp{\@pdfauthor}{% - \@ifnotmtargexp{\@author}{% - \hypersetup{pdfauthor={\@author}}% + \def\streetaddress##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactaddress}{\@pdfcontactaddress}{% + \hyxmp@address@val }% }% - {}% + \def\city##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactcity}{\@pdfcontactcity}{% + \hyxmp@address@val + }% + }% + \def\state##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactregion}{\@pdfcontactregion}{% + \hyxmp@address@val + }% + }% + \def\country##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactcountry}{\@pdfcontactcountry}{% + \hyxmp@address@val + }% + }% + \def\postcode##1{% + \def\hyxmp@address@val{##1}% + \hyxmp@use@first@valid{pdfcontactpostcode}{\@pdfcontactpostcode}{% + \hyxmp@address@val + }% + }% + \def\affiliation##1##2{% + ##2% + \let\affiliation=\@gobbletwo + }% + \setbox0=\hbox{\addresses}% + \endgroup + \@if@def@and@nonempty{@acmDOI}{% + \IfSubStr{\@acmDOI}{10.1145/1122445.1122456}{}{% + \IfSubStr{\@acmDOI}{10.1145/nnnnnnn.nnnnnnn}{}{% + \hyxmp@use@first@valid{pdfdoi}{\@pdfdoi}{% + \@acmDOI + }% + }% + }% + }% + \@if@def@and@nonempty{@acmISBN}{% + \IfSubStr{\@acmISBN}{XXXX}{}{% + \IfSubStr{\@acmISBN}{xxxx}{}{% + \def\hyxmp@strip@isbn@date##1/##2!{##1}% + \edef\hyxmp@acm@isbn{% + \expandafter\hyxmp@strip@isbn@date\@acmISBN/!% + }% + \hyxmp@use@first@valid{pdfisbn}{\@pdfisbn}{% + \hyxmp@acm@isbn + }% + }% + }% + }% + \def\hyxmp@acm@publisher{Association for Computing Machinery}% + \hyxmp@use@first@valid{pdfpublisher}{\@pdfpublisher}{% + \hyxmp@acm@publisher + }% + \hyxmp@use@first@valid{pdfpublication}{\@pdfpublication}{% + \@journalName,% + \@acmBooktitle,% + \@acmConference + }% + \if@ACM@journal + \def\hyxmp@acm@pubtype{journal}% + \else + \def\hyxmp@acm@pubtype{book}% + \fi + \hyxmp@use@first@valid{pdfpubtype}{\@pdfpubtype}{% + \hyxmp@acm@pubtype + }% + \hyxmp@use@first@valid{pdfvolumenum}{\@pdfvolumenum}{% + \@acmVolume + }% + \hyxmp@use@first@valid{pdfissuenum}{\@pdfissuenum}{% + \@acmNumber + }% +} +\@ifclassloaded{acmart}{}{\let\hyxmp@parse@acmart=\relax} +\newcommand*{\hyxmp@set@dc@lang}{% + \let\hyxmp@dc@lang=\@pdflang +} +\AtEndPreamble{% + \@ifpackageloaded{hyperref}{% + \ifx\@pdflang\relax + \@ifundefined{mainbcp47id}{% + \let\@pdflang=\@empty + }{% + \xdef\@pdflang{\csname mainbcp47id\endcsname}% + \renewcommand*{\hyxmp@set@dc@lang}{% + \edef\hyxmp@dc@lang{\xpg@bcp@loaded}% + }% + }% + \fi + \hyxmp@auto@assign@data \@ifundefined{XeTeXversion}{}{% \@ifmtargexp{\@pdfcreationdate}{% \let\@pdfcreationdate=\hyxmp@today@pdf @@ -407,6 +564,7 @@ disabled}% }% } +\hyxmp@at@end{\hyxmp@auto@assign@data} \newcommand*{\hyxmp@commas@to@list}[2]{% \gdef#1{}% \expandafter\hyxmp@commas@to@list@i\expandafter#1#2,,% @@ -1125,7 +1283,7 @@ ______</dc:#2>^^J% \fi } \newcommand{\hyxmp@singleton@dc}[3][Bag]{% - \@ifnotmtarg{#3}{% + \@ifnotmtargexp{#3}{% \hyxmp@xmlify{#3}% \hyxmp@add@to@xml{% ______<dc:#2>^^J% @@ -1150,7 +1308,6 @@ ______</dc:#2>^^J% \hyxmp@rdf@dc{rights}{\@pdfcopyright}% \hyxmp@singleton@dc{publisher}{\@pdfpublisher}% \hyxmp@singleton@dc[Seq]{date}{\hyxmp@today@xmp}% - \hyxmp@singleton@dc{language}{\@pdflang}% \hyxmp@singleton@dc{type}{\@pdftype}% \hyxmp@list@to@xml[\ifHy@pdfa]{creator}{Seq}{\hyxmp@pdfauthor}% \hyxmp@list@to@xml{subject}{Bag}{\hyxmp@pdfkeywords}% @@ -1158,6 +1315,8 @@ ______</dc:#2>^^J% \else \hyxmp@add@simple{dc:source}{\@pdfsource}% \fi + \hyxmp@set@dc@lang + \hyxmp@list@to@xml{language}{Bag}{\hyxmp@dc@lang}% \@ifmtargexp{\@pdfidentifier}{% \let\hyxmp@xmlified=\@empty \hyxmp@cond@dc@identifier{info:doi/}{\@pdfdoi}% |