summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/hyperxmp
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-05-24 00:51:38 +0000
committerKarl Berry <karl@freefriends.org>2006-05-24 00:51:38 +0000
commitae0bea40b27f392a9597f584308def4060a4bd4d (patch)
tree52c8a1ff3ada3e56586b43c4aa69686bc2ea348e /Master/texmf-dist/source/latex/hyperxmp
parent42cb90508c7d60d9183533b23d65ac36e35ea4c0 (diff)
hyperxmp install
git-svn-id: svn://tug.org/texlive/trunk@1587 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/hyperxmp')
-rw-r--r--Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx1624
-rw-r--r--Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins55
2 files changed, 1679 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx
new file mode 100644
index 00000000000..264e78496f7
--- /dev/null
+++ b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx
@@ -0,0 +1,1624 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2006 by Scott Pakin <scott+hyxmp@pakin.org>
+% -------------------------------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3b
+% of this license or (at your option) any later version.
+% The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3b or later is part of all distributions of LaTeX
+% version 2006/01/07 or later.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{hyperxmp.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{hyperxmp}
+%<*package>
+ [2006/05/21 v1.1 Store hyperref metadata in XMP format]
+%</package>
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{tocbibind}
+\usepackage{hyperxmp}
+\usepackage[bookmarksopen]{hyperref}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+ \DocInput{hyperxmp.dtx}
+ \PrintChanges
+ \PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{756}
+%
+% \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
+% Lower-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
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{v1.0}{2006/05/14}{Initial version}
+%
+% \GetFileInfo{hyperxmp.dtx}
+%
+% \DoNotIndex{\#,\&,\<,\>,\\,\_,\|,\ }
+% \DoNotIndex{\@cons,\@elt,\@empty,\@ifpackageloaded,\@ifundefined}
+% \DoNotIndex{\@tempcnta,\@tempcntb}
+% \DoNotIndex{\advance,\afterassignment,\aftergroup}
+% \DoNotIndex{\begingroup,\bgroup}
+% \DoNotIndex{\catcode}
+% \DoNotIndex{\def,\divide}
+% \DoNotIndex{\edef,\egroup,\else,\endgroup,\expandafter}
+% \DoNotIndex{\fi,\futurelet}
+% \DoNotIndex{\gdef,\global}
+% \DoNotIndex{\if,\ifcase,\ifnum,\ifx,\immediate}
+% \DoNotIndex{\let,\loop}
+% \DoNotIndex{\MessageBreak,\multiply}
+% \DoNotIndex{\newcommand,\noexpand}
+% \DoNotIndex{\or}
+% \DoNotIndex{\relax,\repeat}
+% \DoNotIndex{\space,\string}
+% \DoNotIndex{\the,\toks}
+% \DoNotIndex{\xdef}
+%
+% ^^A Define a few logical styles.
+% \DeclareRobustCommand{\term}[1]{#1\SortIndex{#1}{#1}}
+% \DeclareRobustCommand{\pkgname}[1]{\textsf{#1}\SortIndex{#1}{\textsf{#1}}}
+% \DeclareRobustCommand{\xmpterm}[1]{\textsf{#1}\SortIndex{#1}{\textsf{#1}}}
+% \DeclareRobustCommand{\pdfterm}[1]{\textsf{#1}\SortIndex{#1}{\textsf{#1}}}
+% \DeclareRobustCommand{\acrostyle}[1]{\textsc{\MakeLowercase{#1}}}
+% \DeclareRobustCommand{\acro}[1]{^^A
+% \acrostyle{#1}^^A
+% \SortIndex{#1}{\acrostyle{#1}}^^A
+% }
+%
+% ^^A Specify this document's metadata.
+% \title{The \pkgname{hyperxmp} package\thanks{This document
+% corresponds to \pkgname{hyperxmp}~\fileversion, dated \filedate.}}
+% \author{Scott Pakin \\ \texttt{scott+hyxmp@pakin.org}}
+% \hypersetup{%
+% pdfauthor={Scott Pakin},
+% pdftitle={The hyperxmp package},
+% pdfsubject={LaTeX2e support for XMP metadata},
+% pdfkeywords={LaTeX, embedded metadata, XMP, PDF, copyright, license, comments},
+% pdfcopyright={Copyright (C) 2006, Scott Pakin},
+% pdflicenseurl={http://www.latex-project.org/lppl/}
+% }
+%
+% \maketitle
+% \sloppy
+%
+% \begin{abstract}
+% \pkgname{hyperxmp} makes it easy for an author to include \acro{XMP}
+% metadata in a \acro{PDF} document produced by \LaTeX\@. \pkgname{hyperxmp}
+% integrates seamlessly with \pkgname{hyperref} and requires virtually
+% no modifications to a document that already specifies document
+% metadata through \pkgname{hyperref}'s mechanisms.
+% \end{abstract}
+%
+%
+% \section{Introduction}
+%
+% Adobe Systems, Inc.\ has recently been promoting
+% \acro{XMP}~\cite{Adobe2005:XMP}---eXtensible Metadata Platform---as a
+% standard way to include metadata within a document. The idea behind
+% \acro{XMP} is that it is an \acro{XML}-based description of various
+% document attributes and is embedded as uncompressed, unencoded text
+% within the document it describes. By storing the metadata this way it
+% is independent of the document's file format. That is, regardless of
+% whether a document is of \acro{PDF}, \acrostyle{JPEG},
+% \acrostyle{HTML}, or any other type, it is trivial for a program (or
+% human) to locate, extract, and---using any standard \acro{XML}
+% parser---process the embedded \acro{XMP} metadata.
+%
+% As of this writing there are few tools that actually do process \acro{XMP}\@.
+% However, it is easy to imagine future support existing in file
+% browsers for displaying not only a document's filename but also its
+% title, list of authors, description, and other metadata.
+%
+% \paragraph{This is too abstract! Give me an example.}
+% Consider a \LaTeX\ document with three authors: Jack Napier, Edward
+% Nigma, and Harvey Dent. The generated \acro{PDF} file will contain, among
+% other information, the following stanza of \acro{XMP} code embedded within
+% it:
+%
+% \begin{verbatim}
+% <dc:creator>
+% <rdf:Seq>
+% <rdf:li>Jack Napier</rdf:li>
+% <rdf:li>Edward Nigma</rdf:li>
+% <rdf:li>Harvey Dent</rdf:li>
+% </rdf:Seq>
+% </dc:creator>
+% \end{verbatim}
+%
+% In the preceding code, the |dc| namespace refers to the
+% \href{http://purl.org/DC/}{Dublin Core schema}, a collection of
+% metadata properties. The |dc:creator| property surrounds the list of
+% authors. The |rdf| namespace is the
+% \href{http://www.w3.org/RDF/}{Resource Description Framework}, which
+% defines |rdf:Seq| as an ordered list of values. Each author is
+% represented by an individual list item (|rdf:li|), making it easy for
+% an \acro{XML} parser to separate the authors' names.
+%
+% Remember that \acro{XMP} code is stored as \emph{metadata}. It does not
+% appear when viewing or printing the \acro{PDF} file. Rather, it is intended
+% to make it easy for applications to identify and categorize the
+% document.
+%
+% \paragraph{What metadata does \textsf{hyperxmp} process?}
+% \pkgname{hyperxmp} knows how to embed each of the following types of
+% metadata within a document:
+%
+% \begin{itemize}
+% \item authors (|dc:creator|)
+% \item copyright (|dc:rights|)
+% \item date (|dc:date|)
+% \item document identifier (|xapMM:DocumentID|)
+% \item document instance identifier (|xapMM:InstanceID|)
+% \item format (|dc:format|)
+% \item keywords (|pdf:Keyword| and |dc:subject|)
+% \item license \acro{URL} (|xapRights:WebStatement|)
+% \item \acro{PDF}-generating tool (|pdf:Producer|)
+% \item summary (|dc:description|)
+% \item title (|dc:title|)
+% \end{itemize}
+%
+% \noindent
+% More types of metadata may be added in a future release.
+%
+% \paragraph{How does \textsf{hyperxmp} compare with the \textsf{xmpincl}
+% package?}
+% The short answer is that \pkgname{xmpincl} is more flexible but
+% \pkgname{hyperxmp} is easier to use. With \pkgname{xmpincl}, the
+% author manually constructs a file of arbitrary \acro{XMP} data and the
+% package merely embeds it within the generated \acro{PDF} file. With
+% \pkgname{hyperxmp}, the author specifies values for various predefined
+% metadata types and the package formats those values as \acro{XMP} and embeds
+% the result within the generated \acro{PDF} file.
+%
+% \pkgname{xmpincl} can embed \acro{XMP} only when running under pdf\LaTeX\ and
+% only when in \acro{PDF}-generating mode. \pkgname{hyperxmp} additionally
+% works with a few other \acro{PDF}-producing \LaTeX\ backends.
+%
+% \pkgname{hyperxmp} and \pkgname{xmpincl} can complement each other.
+% An author may want to use \pkgname{hyperxmp} to produce a basic set of
+% \acro{XMP} code, then extract the \acro{XMP} code from the \acro{PDF} file with a text
+% editor, augment the \acro{XMP} code with any metadata not supported by
+% \pkgname{hyperxmp}, and use \pkgname{xmpincl} to include the modified
+% \acro{XMP} code in the \acro{PDF} file.
+%
+% \section{Usage}
+%
+% \pkgname{hyperxmp} provides no commands of its own. Rather, it
+% processes some of the package options honored by \pkgname{hyperref}.
+% To use \pkgname{hyperxmp}, merely put a |\usepackage{hyperxmp}|
+% somewhere in your document's preamble. \pkgname{hyperxmp} will
+% construct its \acro{XMP} data using the following \pkgname{hyperref} options:
+%
+% \begin{itemize}
+% \item |pdfauthor|,
+% \item |pdfkeywords|,
+% \item |pdfproducer|,
+% \item |pdfsubject|, and
+% \item |pdftitle|.
+% \end{itemize}
+%
+% \noindent
+% \pkgname{hyperxmp} instructs \pkgname{hyperref} also to accept the
+% following options, which have meaning only to \pkgname{hyperxmp}:
+%
+% \begin{itemize}
+% \item |pdfcopyright| and
+% \item |pdflicenseurl|.
+% \end{itemize}
+%
+% \noindent
+% |\pdfcopyright| defines the copyright text. |pdflicenseurl| defines a
+% \acro{URL} that points to the document's license agreement.
+%
+% It's usually more convenient to provide values for those options using
+% \pkgname{hyperref}'s |\hypersetup| command than on the |\usepackage|
+% command line. See
+% \href{ftp://tug.ctan.org/pub/tex-archive/macros/latex/contrib/hyperref/doc/manual.pdf}{the
+% \pkgname{hyperref} manual} for more information. The following is a
+% sample \LaTeX\ document that provides values for most of the metadata
+% options that \pkgname{hyperxmp} recognizes:
+%
+% \begin{verbatim}
+% \documentclass{article}
+% \usepackage{hyperxmp}
+% \usepackage{hyperref}
+% \title{%
+% On a heuristic viewpoint concerning the production and
+% transformation of light}
+% \author{Albert Einstein}
+% \hypersetup{%
+% pdftitle={%
+% On a heuristic viewpoint concerning the production and
+% transformation of light},
+% pdfauthor={Albert Einstein},
+% pdfcopyright={Copyright (C) 1905, Albert Einstein},
+% pdfsubject={photoelectric effect},
+% pdfkeywords={energy quanta, Hertz effect, quantum physics}
+% }
+% \begin{document}
+% \maketitle
+% A profound formal difference exists between the theoretical
+% concepts that physicists have formed about gases and other
+% ponderable bodies, and Maxwell's theory of electromagnetic
+% processes in so-called empty space\dots
+% \end{document}
+% \end{verbatim}
+%
+% Compile the document to \acro{PDF} using any of the following approaches:
+%
+% \begin{itemize}
+% \item pdf\LaTeX
+% \item \LaTeX~$+$ Dvipdfm
+% \item \LaTeX~$+$ Dvips~$+$ Ghostscript
+% \end{itemize}
+%
+% The combination \LaTeX~$+$ Dvips~$+$ Adobe Acrobat Distiller
+% \emph{almost} works but is hampered by a Distiller bug (at least in
+% version~7.0.5) that incorrectly replaces the first author with the
+% complete list of authors in the generated \acro{PDF} file. That is,
+% if a document's authors are Jack Napier, Edward Nigma, and Harvey
+% Dent, Distiller replaces ``Jack Napier'' with a single author named
+% ``Jack Napier, Edward Nigma, Harvey Dent'' and leaves ``Edward Nigma''
+% and ``Harvey Dent'' as the second and third authors, respectively.
+% Until Adobe fixes this bug, Adobe Acrobat Distiller is not recommended
+% for use with \pkgname{hyperxmp}.
+%
+% Besides the approaches listed above, other approaches may work as well
+% but have not been tested. Note that in many \TeX\ distributions
+% |ps2pdf| is a convenience script that calls Ghostscript with the
+% appropriate options for converting PostScript to \acro{PDF} and
+% |dvipdf| is a convenience script that calls |dvips| and |ps2pdf|; both
+% |ps2pdf| and |dvipdf| should be compatible with \pkgname{hyperxmp}.
+%
+% \bigskip
+%
+% The resulting \acro{PDF} file will contain an \acro{XMP} packet that
+% looks something like this:
+%
+% \begin{verbatim}
+% <?xpacket begin="???" id="W5M0MpCehiHzreSzNTczkc9d"?>
+% <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1-702">
+% <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+% <rdf:Description rdf:about=""
+% xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+% <pdf:Keywords>energy quanta, Hertz effect,
+% quantum physics</pdf:Keywords>
+% <pdf:Producer>pdfeTeX-1.10b</pdf:Producer>
+% </rdf:Description>
+% <rdf:Description rdf:about=""
+% xmlns:dc="http://purl.org/dc/elements/1.1/">
+% <dc:format>application/pdf</dc:format>
+% <dc:title>
+% <rdf:Alt>
+% <rdf:li xml:lang="x-default">On a heuristic viewpoint
+% concerning the production and transformation of
+% light</rdf:li>
+% </rdf:Alt>
+% </dc:title>
+% <dc:description>
+% <rdf:Alt>
+% <rdf:li xml:lang="x-default">photoelectric effect</rdf:li>
+% </rdf:Alt>
+% </dc:description>
+% <dc:rights>
+% <rdf:Alt>
+% <rdf:li xml:lang="x-default">Copyright (C) 1905,
+% Albert Einstein</rdf:li>
+% </rdf:Alt>
+% </dc:rights>
+% <dc:creator>
+% <rdf:Seq>
+% <rdf:li>Albert Einstein</rdf:li>
+% </rdf:Seq>
+% </dc:creator>
+% <dc:subject>
+% <rdf:Bag>
+% <rdf:li>energy quanta</rdf:li>
+% <rdf:li>Hertz effect</rdf:li>
+% <rdf:li>quantum physics</rdf:li>
+% </rdf:Bag>
+% </dc:subject>
+% <dc:date>
+% <rdf:Seq>
+% <rdf:li>2006-04-19</rdf:li>
+% </rdf:Seq>
+% </dc:date>
+% </rdf:Description>
+% <rdf:Description rdf:about=""
+% xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/">
+% <xapMM:DocumentID>uuid:c4188820-aef2-0a82-626ce4182b62</xapMM:DocumentID>
+% <xapMM:InstanceID>uuid:9b62b67f-d754-626c-4c959595fd75</xapMM:InstanceID>
+% </rdf:Description>
+% </rdf:RDF>
+% </x:xmpmeta>
+% <?xpacket end="w"?>
+% \end{verbatim}
+%
+% \pkgname{hyperxmp} splits the |pdfauthor| and |pdfkeywords| lists at
+% commas. Therefore, when specifying |pdfauthor| and |pdfkeywords|, you
+% should separate items with commas. Also, omit ``|and|'' and other
+% text that does not belong to any list item. The following example
+% should serve as clarification:
+%
+% \begin{description}
+% \item[Wrong:] |pdfauthor={Jack Napier, Edward Nigma, and Harvey Dent}|
+% \item[Wrong:] |pdfauthor={Jack Napier; Edward Nigma; Harvey Dent}|
+% \item[Right:] |pdfauthor={Jack Napier, Edward Nigma, Harvey Dent}|
+% \end{description}
+%
+% If you desperately need to include a comma within an author or keyword
+% list you can define your own comma macro as follows:
+%
+% \begin{verbatim}
+% \bgroup
+% \catcode`,=11
+% \gdef\mycomma{,}
+% \egroup
+% \end{verbatim}
+%
+% \noindent
+% Thereafter, you can use |\mycomma| as a literal comma:
+%
+% \begin{verbatim}
+% pdfauthor={Napier\mycomma\ Jack,
+% Nigma\mycomma\ Edward,
+% Dent\mycomma\ Harvey}
+% \end{verbatim}
+%
+%
+% \StopEventually{^^A
+% \begin{thebibliography}{1}
+% \bibitem{Adobe2004:PDF}
+% Adobe Systems, Inc., San Jose, California.
+% \newblock {\em {PDF} Reference, Fifth Edition: {A}dobe Portable Document Format
+% Version~1.6}, November 2004.
+% \newblock Available from
+% \url{http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf}.
+%
+% \bibitem{Adobe2005:pdfmark}
+% Adobe Systems, Inc., San Jose, California.
+% \newblock {\em {A}dobe {A}crobat~7.0.5 pdfmark Reference Manual}, October~2,
+% 2005.
+% \newblock Available from
+% \url{http://partners.adobe.com/public/developer/en/acrobat/sdk/pdf/pdf_creation_apis_and_specs/pdfmarkReference.pdf}.
+%
+% \bibitem{Adobe2005:XMP}
+% Adobe Systems, Inc., San Jose, California.
+% \newblock {\em {XMP} Specification}, June 2005.
+% \newblock Available from
+% \url{http://partners.adobe.com/public/developer/en/xmp/sdk/xmpspecification.pdf}.
+%
+% \bibitem{Downes1994:ATB15}
+% Michael Downes.
+% \newblock Around the bend~\#15, answers, 4th (last) installment.
+% \newblock \href{news:comp.text.tex}{\texttt{comp.text.tex}} newsgroup posting,
+% January~3, 1994.
+% \newblock Archived by Google at
+% \url{http://groups.google.com/group/comp.text.tex/msg/7da7643b9e8f3b48}.
+% \end{thebibliography}
+% }
+%
+%
+% \section{Implementation}
+%
+% This section presents the commented \LaTeXe\ source code for
+% \pkgname{hyperxmp}. Read this section only if you want to learn how
+% \pkgname{hyperxmp} is implemented.
+%
+%
+% \subsection{Integration with \textsf{hyperref}}
+%
+% An important design decision underlying \pkgname{hyperxmp} is that the
+% package should integrate seamlessly with \pkgname{hyperref}. To that
+% end, \pkgname{hyperxmp} takes its \acro{XMP} metadata from the
+% \pkgname{hyperref} |pdftitle|, |pdfauthor|, |pdfsubject|, and
+% |pdfkeywords| options plus two new options, |pdfcopyright| and
+% |pdflicenseurl|, introduced by \pkgname{hyperxmp}.
+%
+% \begin{macrocode}
+\RequirePackage{keyval}
+% \end{macrocode}
+%
+% \begin{macro}{\@pdfcopyright}
+% Prepare to store the document's copyright statement. For consistency
+% with \pkgname{hyperref}'s document-metadata naming conventions (which
+% are in turn based on \LaTeXe's document-metadata naming conventions),
+% we do not prefix the macro name with our package-specific |\hyxmp@|
+% prefix.
+% \begin{macrocode}
+\def\@pdfcopyright{}
+\define@key{Hyp}{pdfcopyright}{\pdfstringdef\@pdfcopyright{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@pdflicenseurl}
+% Prepare to store the \acro{URL} containing the document's license
+% agreement. For consistency with \pkgname{hyperref}'s
+% document-metadata naming conventions (which are in turn based on
+% \LaTeXe's document-metadata naming conventions), we do not prefix the
+% macro name with our package-specific |\hyxmp@| prefix.
+% \begin{macrocode}
+\def\@pdflicenseurl{}
+\define@key{Hyp}{pdflicenseurl}{\pdfstringdef\@pdflicenseurl{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@find@metadata}
+% Issue a warning message if the author failed to include any metadata
+% at all.
+% \begin{macrocode}
+\newcommand*{\hyxmp@find@metadata}{%
+ \ifx\@pdfauthor\@empty
+ \ifx\@pdfcopyright\@empty
+ \ifx\@pdfkeywords\@empty
+ \ifx\@pdflicenseurl\@empty
+ \ifx\@pdfsubject\@empty
+ \ifx\@pdftitle\@empty
+ \PackageWarningNoLine{hyperxmp}{%
+\jobname.tex did not specify any metadata to\MessageBreak
+include in the XMP packet.\space\space Please see the hyperxmp\MessageBreak
+documentation for instructions on how to provide\MessageBreak
+metadata values to hyperxmp%
+ }%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \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}
+\AtBeginDocument{%
+ \@ifpackageloaded{hyperref}%
+ {%
+% \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}
+ \AtEndDocument{%
+ \hyxmp@find@metadata
+ \hyxmp@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}
+%
+%
+% \subsection{Manipulating author-supplied data}
+%
+% The author provides metadata information to \pkgname{hyperxmp} via
+% package options to \pkgname{hyperref} or via the \pkgname{hyperref}
+% |\hypersetup| command. The functions in this section convert
+% author-supplied lists (e.g.,~|pdfkeywords={foo, bar, baz}|) into
+% \LaTeXe\ lists (e.g.,~|\@elt {foo}| |\@elt {bar}| |\@elt {baz}|) that
+% can be more easily manipulated (Section~\ref{sec:list-manip}); define
+% macros for the \acro{XML} entites |&lt;|, |&gt;|, and |&amp;|
+% (Section~\ref{sec:xml-entities}); trim spaces off the ends of strings
+% (Section~\ref{sec:trim-spaces}); and, in Section~\ref{sec:text-xml},
+% convert text to \acro{XML} (e.g.,~from |<scott+hyxmp@pakin.org>| to
+% |&lt;scott+hyxmp@pakin.org&gt;|).
+%
+% \subsubsection{List manipulation}
+% \label{sec:list-manip}
+%
+% We define a macro for converting a list of comma-separated elements
+% (e.g.,~the list of \acro{PDF} keywords) to a list of \LaTeXe\
+% |\@elt|-separated elements.
+%
+% \begin{macro}{\hyxmp@commas@to@list}
+% Given a macro name~(|#1|) and a comma-separated list~(|#2|), define
+% the macro name as the elements of the list, each preceded by |\@elt|.
+% (Executing the macro therefore applies |\@elt| to each element in
+% turn.)
+% \begin{macrocode}
+\newcommand*{\hyxmp@commas@to@list}[2]{%
+ \gdef#1{}%
+ \expandafter\hyxmp@commas@to@list@i\expandafter#1#2,,%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@commas@to@list@i}
+% \begin{macro}{\next}
+% Recursively construct macro~|#1| from comma-separated list~|#2|. Stop
+% if |#2| is empty.
+% \begin{macrocode}
+\def\hyxmp@commas@to@list@i#1#2,{%
+ \gdef\hyxmp@sublist{#2}%
+ \ifx\hyxmp@sublist\@empty
+ \let\next=\relax
+ \else
+ \hyxmp@trimspaces\hyxmp@sublist
+ \@cons{#1}{{\hyxmp@sublist}}%
+ \def\next{\hyxmp@commas@to@list@i{#1}}%
+ \fi
+ \next
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Character-code and XML entity definitions}
+% \label{sec:xml-entities}
+%
+% The \pkgname{hyperref} package invokes |\pdfstringdef| on its metadata
+% parameters, setting every character to \TeX\ category code~11
+% (``other''). To match against these, we have to define a few category
+% code~11 characters of our own. Furthermore, because \acro{XMP} is an
+% \acro{XML} format, we have to replace the characters ``|&|'', ``|<|'',
+% and ``|>|'' with equivalent \acro{XML} entities.
+%
+% \begin{macro}{\hyxmp@xml@amp}
+% \begin{macro}{\hyxmp@other@amp}
+% \begin{macro}{\hyxmp@amp}
+% Define category code~11 (``other'') versions of the character~``|&|''
+% and map |\hyxmp@other@amp| to its \acro{XML} entity, |&amp;|.
+% \begin{macrocode}
+\bgroup
+\catcode`\&=11
+\gdef\hyxmp@xml@amp{&amp;}
+\global\let\hyxmp@other@amp=&
+\gdef\hyxmp@amp{&}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@xml@lt}
+% \begin{macro}{\hyxmp@other@lt}
+% Define a category code~11 (``other'') version of the character~``|<|''
+% and map |\hyxmp@other@lt| to its \acro{XML} entity, |&lt;|.
+% \begin{macrocode}
+\catcode`\<=11
+\gdef\hyxmp@xml@lt{&lt;}
+\global\let\hyxmp@other@lt=<
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@xml@gt}
+% \begin{macro}{\hyxmp@other@gt}
+% Define a category code~11 (``other'') version of the character~``|>|''
+% and map |\hyxmp@other@gt| to its \acro{XML} entity, |&gt;|.
+% \begin{macrocode}
+\catcode`\>=11
+\gdef\hyxmp@xml@gt{&gt;}
+\global\let\hyxmp@other@gt=>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@other@space}
+% \begin{macro}{\next}
+% Define a category code~11 (``other'') version of the space character.
+% \begin{macrocode}
+\def\next#1{#1}
+\next{\global\let\hyxmp@other@space= } %
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@other@bs}
+% Define a category code~11 (``other'') version of the character~``|\|''.
+% \begin{macrocode}
+\catcode`\|=0
+\catcode`\\=11
+|global|let|hyxmp@other@bs=\
+|egroup
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Trimming leading and trailing spaces}
+% \label{sec:trim-spaces}
+%
+% To make it easier for \acro{XMP} processors to manipulate our output we
+% define a |\hyxmp@trimspaces| macro to strip leading and trailing
+% spaces from various data fields.
+%
+% \begin{macro}{\hyxmp@trimspaces}
+% Redefine a macro as its previous value but without leading or trailing
+% spaces. This code---as well as that for its helper macros,
+% |\hyxmp@trimb| and |\hyxmp@trimc|---was taken almost verbatim from a
+% solution to an \emph{Around the Bend} puzzle~\cite{Downes1994:ATB15}.
+% Inline comments are also taken from the solution text.
+% \begin{macrocode}
+\catcode`\Q=3
+% \end{macrocode}
+% |\hyxmp@trimspaces\x| redefines |\x| to have the same replacement text
+% sans leading and trailing space tokens.
+% \begin{macrocode}
+\newcommand{\hyxmp@trimspaces}[1]{%
+% \end{macrocode}
+% Use grouping to emulate a multi-token |afterassignment| queue.
+% \begin{macrocode}
+ \begingroup
+% \end{macrocode}
+% Put |\toks 0 {| into the |afterassignment| queue.
+% \begin{macrocode}
+ \aftergroup\toks\aftergroup0\aftergroup{%
+% \end{macrocode}
+% Apply |\hyxmp@trimb| to the replacement text of |#1|, adding a leading
+% |\noexpand| to prevent brace stripping and to serve another purpose
+% later.
+% \begin{macrocode}
+ \expandafter\hyxmp@trimb\expandafter\noexpand#1Q Q}%
+% \end{macrocode}
+% Transfer the trimmed text back into |#1|.
+% \begin{macrocode}
+ \edef#1{\the\toks0}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@trimb}
+% |\hyxmp@trimb| removes a trailing space if present, then calls
+% |\hyxmp@trimc| to clean up any leftover bizarre |Q|s, and trim a
+% leading space. In order for |\hyxmp@trimc| to work properly we need to
+% put back a |Q| first.
+% \begin{macrocode}
+\def\hyxmp@trimb#1 Q{\hyxmp@trimc#1Q}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@trimc}
+% Execute |\vfuzz| assignment to remove leading space; the |\noexpand|
+% will now prevent unwanted expansion of a macro or other expandable
+% token at the beginning of the trimmed text. The |\endgroup| will feed
+% in the |\aftergroup| tokens after the |\vfuzz| assignment is
+% completed.
+% \begin{macrocode}
+\def\hyxmp@trimc#1Q#2{\afterassignment\endgroup \vfuzz\the\vfuzz#1}
+\catcode`\Q=11
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Converting text to XML}
+% \label{sec:text-xml}
+%
+% The ``|<|'', ``|>|'', and ``|&|'' characters are significant to \acro{XML}.
+% We therefore need to escape them in any author-supplied text.
+%
+% \begin{macro}{\hyxmp@xmlify}
+% \begin{macro}{\hyxmp@xmlified}
+% Given a piece of text defined using |\pdfstringdef| (i.e.,~with many
+% special characters redefined to have category code~11), set
+% |\hyxmp@xmlified| to the same text but with all occurrences of~``|<|''
+% replaced with~|&lt;|, all occurrences of~``|>|'' replaced with~|&gt;|,
+% and all occurrences of~``|&|'' replaced with~|&amp;|.
+%
+% If |\pdfmark| is defined then there's a chance the user will run
+% |dvips| on the resulting \acro{DVI} file and |dvips| may convert some
+% of the spaces to newlines, which is problematic for the proper display
+% of an \acro{XMP} packet. We therefore conditionally invoke
+% |\hyxmp@obscure@spaces| to replace all spaces with |&#32;|.
+% \begin{macrocode}
+\newcommand*{\hyxmp@xmlify}[1]{%
+ \gdef\hyxmp@xmlified{}%
+ \expandafter\hyxmp@xmlify@i#1\@empty
+ \@ifundefined{pdfmark}{}{%
+ \expandafter\hyxmp@obscure@spaces\expandafter{\hyxmp@xmlified}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@xmlify@i}
+% \begin{macro}{\hyxmp@one@token}
+% Bind the next token in the input stream to |\hyxmp@one@token| and
+% invoke |\hyxmp@xmlify@ii|. |\hyxmp@xmlify@i| (and therefore
+% |\hyxmp@xmlify@ii|) is invoked on each character in the text supplied
+% to |\hyxmp@xmlify|.
+% \begin{macrocode}
+\def\hyxmp@xmlify@i{\futurelet\hyxmp@one@token\hyxmp@xmlify@ii}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@xmlify@ii}
+% \begin{macro}{\next}
+% Given a token in |\hyxmp@one@token|, define |\next| to consume the
+% token, append the corresponding text to |\hyxmp@xmlified|, and
+% recursively invoke |\hyxmp@xmlify@i| to consume subsequent tokens.
+% \begin{macrocode}
+\def\hyxmp@xmlify@ii{%
+ \if\hyxmp@one@token\hyxmp@other@lt
+% \end{macrocode}
+% Replace ``|<|'' with |&lt;|.
+% \begin{macrocode}
+ \def\next##1{%
+ \xdef\hyxmp@xmlified{\hyxmp@xmlified\hyxmp@xml@lt}%
+ \hyxmp@xmlify@i
+ }%
+ \else
+ \if\hyxmp@one@token\hyxmp@other@gt
+% \end{macrocode}
+% Replace ``|>|'' with |&gt;|.
+% \begin{macrocode}
+ \def\next##1{%
+ \xdef\hyxmp@xmlified{\hyxmp@xmlified\hyxmp@xml@gt}%
+ \hyxmp@xmlify@i
+ }%
+ \else
+ \if\hyxmp@one@token\hyxmp@other@amp
+% \end{macrocode}
+% Replace ``|&|'' with |&amp;|.
+% \begin{macrocode}
+ \def\next##1{%
+ \xdef\hyxmp@xmlified{\hyxmp@xmlified\hyxmp@xml@amp}%
+ \hyxmp@xmlify@i
+ }%
+ \else
+ \ifx\hyxmp@one@token\hyxmp@other@space
+% \end{macrocode}
+% Store spaces. We need a special case for this to avoid inadvertently
+% discarding spaces.
+% \begin{macrocode}
+ \def\next##1{%
+ \g@addto@macro\hyxmp@xmlified{ }%
+ \hyxmp@xmlify@i##1%
+ }%
+ \else
+ \if\hyxmp@one@token\hyxmp@other@bs
+% \end{macrocode}
+% Replace |\|\meta{ooo} with |&#|\meta{ddd}|;|. For example, |\100|,
+% the octal code for ``|@|'', is represented in \acro{XML} as~|&#64;|.
+% \begin{macrocode}
+ \def\next##1{\futurelet\hyxmp@one@token\hyxmp@xmlify@iii}
+ \else
+ \ifx\hyxmp@one@token\@empty
+% \end{macrocode}
+% End the recursion upon encountering |\@empty|.
+% \begin{macrocode}
+ \def\next##1{}%
+ \else
+% \end{macrocode}
+% In most cases we merely append the next character in the input to
+% |\hyxmp@xmlified| without any special processing.
+% \begin{macrocode}
+ \def\next##1{%
+ \g@addto@macro\hyxmp@xmlified{##1}%
+ \hyxmp@xmlify@i
+ }%
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+% \end{macrocode}
+% Recursively process the next character in the input stream.
+% \begin{macrocode}
+ \next
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@xmlify@iii}
+% \begin{macro}{\next}
+% \pkgname{hyperref}'s |\pdfstringdef| macro converts certain special
+% characters to a backslash followed by a three-digit octal number.
+% However, it also replaces ``|(|'' and ``|)|'' with ``|\(|'' and
+% ``|\)|''. The |\hyxmp@xmlify@iii| macro is called after encountering
+% (and removing) a backslash. If the next character in the input stream
+% (|\hyxmp@one@token|) is a parenthesis, |\hyxmp@xmlify@iii| leaves it
+% alone. Otherwise, |\hyxmp@xmlify@iii| assumes it's an octal number
+% and replaces it with its \acro{XML} equivalent.
+% \begin{macrocode}
+\def\hyxmp@xmlify@iii{%
+ \def\next##1##2##3{%
+ \@tempcnta='##1##2##3
+ \xdef\hyxmp@xmlified{\hyxmp@xmlified
+ \hyxmp@amp\hyxmp@hash\the\@tempcnta;%
+ }%
+ \hyxmp@xmlify@i
+ }%
+ \if\hyxmp@one@token(
+ \let\next=\hyxmp@xmlify@i
+ \else
+ \if\hyxmp@one@token)
+ \let\next=\hyxmp@xmlify@i
+ \fi
+ \fi
+ \next
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@obscure@spaces}
+% The |dvips| backend rather obnoxiously word-wraps text. Doing so can
+% cause \acro{XMP} metadata to be displayed incorrectly. For example,
+% Adobe Acrobat displays the document's |dc:rights| (copyright notice)
+% within a single-line field. By introducing an extra line break in the
+% middle of the copyright notice, |dvips| implicitly causes it to be
+% truncated when displayed.
+%
+% To thwart |dvips|'s word-wrapping, we define |\hyxmp@obscure@spaces|
+% to replace each space in a given piece of text with an \acro{XML} |&#32;|
+% (space) entity.
+% \begin{macrocode}
+\newcommand*{\hyxmp@obscure@spaces}[1]{%
+ \gdef\hyxmp@xmlified{}%
+ \expandafter\hyxmp@obscure@spaces@i#1 {} %
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@obscure@spaces@i}
+% \begin{macro}{\hyxmp@one@token}
+% \begin{macro}{\next}
+% Do all of the work for |\hyxmp@obscure@spaces|.
+% \begin{macrocode}
+\def\hyxmp@obscure@spaces@i #1 #2 {%
+ \def\hyxmp@one@token{#2}%
+ \ifx\hyxmp@one@token\@empty
+ \xdef\hyxmp@xmlified{\hyxmp@xmlified#1}%
+ \let\next=\relax
+ \else
+ \xdef\hyxmp@xmlified{\hyxmp@xmlified#1\hyxmp@amp\hyxmp@hash32;}%
+ \def\next{\expandafter\hyxmp@obscure@spaces@i\expandafter#2 }%
+ \fi
+ \next
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{UUID generation}
+%
+% We use a linear congruential generator to produce pseudorandom
+% \acro{UUID}s. True, this method has its flaws but it's simple to
+% implement in \TeX\ and is good enough for producing the \acro{XMP}
+% \xmpterm{DocumentID} and \xmpterm{InstanceID} fields.
+%
+% \begin{macro}{\hyxmp@modulo@a}
+% Replace the contents of |\@tempcnta| with the contents modulo~|#1|.
+% Note that |\@tempcntb| is overwritten in the process.
+% \begin{macrocode}
+\def\hyxmp@modulo@a#1{%
+ \@tempcntb=\@tempcnta
+ \divide\@tempcntb by #1
+ \multiply\@tempcntb by #1
+ \advance\@tempcnta by -\@tempcntb
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@big@prime}
+% \begin{macro}{\hyxmp@big@prime@ii}
+% Define a couple of large prime numbers that can still be stored in a
+% \TeX\ counter.
+% \begin{macrocode}
+\def\hyxmp@big@prime{536870923}
+\def\hyxmp@big@prime@ii{536870027}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@seed@rng}
+% \begin{macro}{\hyxmp@one@token}
+% Seed \pkgname{hyperxmp}'s random-number generator from a given piece
+% of text.
+% \begin{macrocode}
+\def\hyxmp@seed@rng#1{%
+ \@tempcnta=\hyxmp@big@prime
+ \futurelet\hyxmp@one@token\hyxmp@seed@rng@i#1\@empty
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@seed@rng@i}
+% \begin{macro}{\hyxmp@one@token}
+% \begin{macro}{\next}
+% Do all of the work for |\hyxmp@seed@rng|. For each character code $c$
+% of the input text, assign $\mathtt{\string\@tempcnta} \leftarrow 3
+% \cdot \mathtt{\string\@tempcnta} + c
+% \pmod{\mathtt{\string\hyxmp@big@prime}}$.
+% \begin{macrocode}
+\def\hyxmp@seed@rng@i{%
+ \ifx\hyxmp@one@token\@empty
+ \let\next=\relax
+ \else
+ \def\next##1{%
+ \multiply\@tempcnta by 3
+ \advance\@tempcnta by `##1
+ \hyxmp@modulo@a{\hyxmp@big@prime}%
+ \futurelet\hyxmp@one@token\hyxmp@seed@rng@i
+ }%
+ \fi
+ \next
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@set@rand@num}
+% \begin{macro}{\hyxmp@rand@num}
+% Advance |\hyxmp@rand@num| to the next pseudorandom number in the
+% sequence. Specifically, we assign $\mathtt{\string\hyxmp@rand@num}
+% \leftarrow 3 \cdot \mathtt{\string\hyxmp@rand@num} +
+% \mathtt{\string\hyxmp@big@prime@ii}
+% \pmod{\mathtt{\string\hyxmp@big@prime}}$. Note that both |\@tempcnta|
+% and |\@tempcntb| are overwritten in the process.
+% \begin{macrocode}
+\def\hyxmp@set@rand@num{%
+ \@tempcnta=\hyxmp@rand@num
+ \multiply\@tempcnta by 3
+ \advance\@tempcnta by \hyxmp@big@prime@ii
+ \hyxmp@modulo@a{\hyxmp@big@prime}%
+ \xdef\hyxmp@rand@num{\the\@tempcnta}%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@append@hex}
+% Append a randomly selected hexadecimal digit to macro~|#1|. Note that
+% both |\@tempcnta| and |\@tempcntb| are overwritten in the process.
+% \begin{macrocode}
+\def\hyxmp@append@hex#1{%
+ \hyxmp@set@rand@num
+ \@tempcnta=\hyxmp@rand@num
+ \hyxmp@modulo@a{16}%
+ \ifnum\@tempcnta<10
+ \xdef#1{#1\the\@tempcnta}%
+ \else
+% \end{macrocode}
+% There \emph{must} be a better way to handle the numbers~10--15 than
+% with |\ifcase|.
+% \begin{macrocode}
+ \advance\@tempcnta by -10
+ \ifcase\@tempcnta
+ \xdef#1{#1a}%
+ \or\xdef#1{#1b}%
+ \or\xdef#1{#1c}%
+ \or\xdef#1{#1d}%
+ \or\xdef#1{#1e}%
+ \or\xdef#1{#1f}%
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@append@hex@iv}
+% Invoke |\hyxmp@append@hex| four times.
+% \begin{macrocode}
+\def\hyxmp@append@hex@iv#1{%
+ \hyxmp@append@hex#1%
+ \hyxmp@append@hex#1%
+ \hyxmp@append@hex#1%
+ \hyxmp@append@hex#1%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@create@uuid}
+% Define macro~|#1| as a \acro{UUID} of the form
+% ``|uuid:|\textit{xxxxxxxx}|-|\textit{xxxx}|-|\textit{xxxx}|-|\textit{xxxxxxxxxxxx}''
+% in which each ``\textit{x}'' is a lowercase hexadecimal digit. We
+% assume that the random-number generator is already seeded. Note that
+% |\hyxmp@create@uuid| overwrites both |\@tempcnta| and |\@tempcntb|.
+% \begin{macrocode}
+\def\hyxmp@create@uuid#1{%
+ \def#1{uuid:}%
+ \hyxmp@append@hex@iv#1%
+ \hyxmp@append@hex@iv#1%
+ \g@addto@macro#1{-}%
+ \hyxmp@append@hex@iv#1%
+ \g@addto@macro#1{-}%
+ \hyxmp@append@hex@iv#1%
+ \g@addto@macro#1{-}%
+ \hyxmp@append@hex@iv#1%
+ \hyxmp@append@hex@iv#1%
+ \hyxmp@append@hex@iv#1%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@def@DocumentID}
+% \begin{macro}{\hyxmp@DocumentID}
+% Seed the random-number generator with a function of the current
+% filename, \acro{PDF} document title, and \acro{PDF} author, then invoke
+% |\hyxmp@create@uuid| to define |\hyxmp@DocumentID| as a random \acro{UUID}.
+% \begin{macrocode}
+\newcommand*{\hyxmp@def@DocumentID}{%
+ \edef\hyxmp@seed@string{\jobname:\@pdftitle:\@pdfauthor}%
+ \expandafter\hyxmp@seed@rng\expandafter{\hyxmp@seed@string}%
+ \edef\hyxmp@rand@num{\the\@tempcnta}%
+ \hyxmp@create@uuid\hyxmp@DocumentID
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@def@InstanceID}
+% \begin{macro}{\hyxmp@InstanceID}
+% Seed the random-number generator with a function of the current
+% filename, \acro{PDF} document title, \acro{PDF} author, and the
+% current day, month, year, and minutes since midnight, then invoke
+% |\hyxmp@create@uuid| to define |\hyxmp@InstanceID| as a random
+% \acro{UUID}.
+% \begin{macrocode}
+\newcommand*{\hyxmp@def@InstanceID}{%
+ \edef\hyxmp@seed@string{%
+ \jobname:\@pdftitle:\@pdfauthor:%
+ \the\year/\the\month/\the\day:%
+ \the\time
+ }%
+ \expandafter\hyxmp@seed@rng\expandafter{\hyxmp@seed@string}%
+ \edef\hyxmp@rand@num{\the\@tempcnta}%
+ \hyxmp@create@uuid\hyxmp@InstanceID
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Constructing the XMP packet}
+%
+% An \acro{XMP} packet comprises a header, ``serialized \acro{XMP}'',
+% padding, and a trailer~\cite{Adobe2005:XMP}. The serialized
+% \acro{XMP} includes blocks of \acro{XML} for various \acro{XMP}
+% schemata: Adobe \acro{PDF} (Section~\ref{sec:adobe-pdf}), Dublin Core
+% (Section~\ref{sec:dublin-core}), \acro{XMP} Rights Management
+% (Section~\ref{sec:xmp-rights}), and \acro{XMP} Media Management
+% (Section~\ref{sec:xmp-media}). The |\hyxmp@construct@packet| macro
+% constructs the \acro{XMP} packet into |\hyxmp@xml|. It first writes
+% the appropriate \acro{XML} header, then calls the various
+% schema-writing macros, then injects |\hyxmp@padding| as padding, and
+% finally writes the appropriate \acro{XML} trailer.
+%
+% \subsubsection{XMP utility functions}
+%
+% \begin{macro}{\hyxmp@add@to@xml}
+% Given a piece of text, replace all underscores with category-code~11
+% (``other'') spaces and append the result to the |\hyxmp@xml| macro.
+% \begin{macrocode}
+\newcommand*{\hyxmp@add@to@xml}[1]{%
+ \bgroup
+ \@tempcnta=0
+ \loop
+ \lccode\@tempcnta=\@tempcnta
+ \advance\@tempcnta by 1
+ \ifnum\@tempcnta<256
+ \repeat
+ \lccode`\_=`\ \relax
+ \lowercase{\xdef\hyxmp@xml{\hyxmp@xml#1}}%
+ \egroup
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@hash}
+% Define a category-code~11 (``other'') version of the ``|#|'' character.
+% \begin{macrocode}
+\bgroup
+\catcode`\#=11
+\gdef\hyxmp@hash{#}
+\egroup
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@padding}
+% \begin{macro}{\hyxmp@xml}
+% The \acro{XMP} specification~\cite{Adobe2005:XMP} recommends leaving a
+% few kilobytes of whitespace at the end of each \acro{XMP} packet to
+% facilitate editing the packet in place. |\hyxmp@padding| is defined
+% to contain 32~lines of 50~spaces and a newline apiece for a total of
+% 1632 characters of whitespace.
+% \begin{macrocode}
+\bgroup
+ \xdef\hyxmp@xml{}%
+ \hyxmp@add@to@xml{%
+__________________________________________________^^J%
+ }
+ \xdef\hyxmp@padding{\hyxmp@xml}%
+\egroup
+\xdef\hyxmp@padding{\hyxmp@padding\hyxmp@padding}
+\xdef\hyxmp@padding{\hyxmp@padding\hyxmp@padding}
+\xdef\hyxmp@padding{\hyxmp@padding\hyxmp@padding}
+\xdef\hyxmp@padding{\hyxmp@padding\hyxmp@padding}
+\xdef\hyxmp@padding{\hyxmp@padding\hyxmp@padding}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\hyxmp@today}
+% Define today's date in \textit{YYYY}-\textit{MM}-\textit{DD} format.
+% \begin{macrocode}
+\xdef\hyxmp@today{\the\year}%
+\ifnum\month<10
+ \xdef\hyxmp@today{\hyxmp@today-0\the\month}%
+\else
+ \xdef\hyxmp@today{\hyxmp@today-\the\month}%
+\fi
+\ifnum\day<10
+ \xdef\hyxmp@today{\hyxmp@today-0\the\day}%
+\else
+ \xdef\hyxmp@today{\hyxmp@today-\the\day}%
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{The Adobe PDF schema}
+% \label{sec:adobe-pdf}
+%
+% \begin{macro}{\hyxmp@pdf@schema}
+% Add properties defined by the Adobe \acro{PDF} schema to the |\hyxmp@xml|
+% macro.
+% \begin{macrocode}
+\newcommand*{\hyxmp@pdf@schema}{%
+% \end{macrocode}
+% \begin{macro}{\hyxmp@have@any}
+% Include an Adobe \acro{PDF} schema block if at least one of
+% |\@pdfkeywords| and |\@pdfproducer| is defined.
+% \begin{macrocode}
+ \let\hyxmp@have@any=!%
+ \ifx\@pdfkeywords\@empty
+ \ifx\@pdfproducer\@empty
+ \let\hyxmp@have@any=\@empty
+ \fi
+ \fi
+ \ifx\hyxmp@have@any\@empty
+ \else
+% \end{macrocode}
+% Add a block of \acro{XML} to |\hyxmp@xml| that lists the document's keywords
+% (the \xmpterm{Keywords} property) and the tools used to produce the
+% \acro{PDF} file (the \xmpterm{Producer} property).
+% \begin{macrocode}
+ \hyxmp@add@to@xml{%
+______<rdf:Description rdf:about=""^^J%
+___________xmlns:pdf="http://ns.adobe.com/pdf/1.3/">^^J%
+ }%
+ \ifx\@pdfkeywords\@empty
+ \else
+ \hyxmp@xmlify{\@pdfkeywords}%
+ \hyxmp@add@to@xml{%
+___________<pdf:Keywords>\hyxmp@xmlified</pdf:Keywords>^^J%
+ }%
+ \fi
+ \ifx\@pdfproducer\@empty
+ \else
+ \hyxmp@xmlify{\@pdfproducer}%
+ \hyxmp@add@to@xml{%
+___________<pdf:Producer>\hyxmp@xmlified</pdf:Producer>^^J%
+ }%
+ \fi
+ \hyxmp@add@to@xml{%
+______</rdf:Description>^^J%
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{The Dublin Core schema}
+% \label{sec:dublin-core}
+%
+% \begin{macro}{\hyxmp@rdf@dc}
+% Given a Dublin Core property~(|#1|) and a macro containing some
+% |\pdfstringdef|-defined text~(|#2|), append the appropriate block of
+% \acro{XML} to the |\hyxmp@xml| macro but only if |#2| is non-empty.
+% \begin{macrocode}
+\newcommand*{\hyxmp@rdf@dc}[2]{%
+ \ifx#2\@empty
+ \else
+ \hyxmp@xmlify{#2}%
+ \hyxmp@add@to@xml{%
+_________<dc:#1>^^J%
+____________<rdf:Alt>^^J%
+_______________<rdf:li xml:lang="x-default">\hyxmp@xmlified</rdf:li>^^J%
+____________</rdf:Alt>^^J%
+_________</dc:#1>^^J%
+ }%
+ \fi%
+}%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@list@to@xml}
+% Given a Dublin Core property~(|#1|), an RDF array~(|#2|), and a macro
+% containing a comma-separated list~(|#3|), append the appropriate block
+% of \acro{XML} to the |\hyxmp@xml| macro but only if |#3| is non-empty.
+% \begin{macrocode}
+\newcommand*{\hyxmp@list@to@xml}[3]{%
+ \ifx#3\@empty
+ \else
+ \hyxmp@add@to@xml{%
+_________<dc:#1>^^J%
+____________<rdf:#2>^^J%
+ }%
+ \bgroup
+ \hyxmp@commas@to@list\hyxmp@list{#3}%
+ \def\@elt##1{%
+ \hyxmp@xmlify{##1}%
+ \hyxmp@add@to@xml{%
+_______________<rdf:li>\hyxmp@xmlified</rdf:li>^^J%
+ }%
+ }%
+ \hyxmp@list
+ \egroup
+ \hyxmp@add@to@xml{%
+____________</rdf:#2>^^J%
+_________</dc:#1>^^J%
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@dc@schema}
+% Add properties defined by the Dublin Core schema to the |\hyxmp@xml|
+% macro. Specifically, we add entries for the \xmpterm{title} property
+% if the author specified a |pdftitle|, the \xmpterm{description}
+% property if the author specified a |pdfsubject|, the \xmpterm{rights}
+% property if the author specified a |pdfcopyright|, the
+% \xmpterm{creator} property if the author specified a |pdfauthor|, and
+% the \xmpterm{subject} property if the author specified |pdfkeywords|.
+% We also specify the \xmpterm{date} property using the date the
+% document was run through \LaTeX.
+% \begin{macrocode}
+\newcommand*{\hyxmp@dc@schema}{%
+ \hyxmp@add@to@xml{%
+______<rdf:Description rdf:about=""^^J%
+____________xmlns:dc="http://purl.org/dc/elements/1.1/">^^J%
+_________<dc:format>application/pdf</dc:format>^^J%
+ }%
+ \hyxmp@rdf@dc{title}{\@pdftitle}%
+ \hyxmp@rdf@dc{description}{\@pdfsubject}%
+ \hyxmp@rdf@dc{rights}{\@pdfcopyright}%
+ \hyxmp@list@to@xml{creator}{Seq}{\@pdfauthor}%
+ \hyxmp@list@to@xml{subject}{Bag}{\@pdfkeywords}%
+ \hyxmp@list@to@xml{date}{Seq}{\hyxmp@today}%
+ \hyxmp@add@to@xml{%
+______</rdf:Description>^^J%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{The XMP Rights Management schema}
+% \label{sec:xmp-rights}
+%
+% \begin{macro}{\hyxmp@xapRights@schema}
+% Add properties defined by the XMP Rights Management schema to the
+% |\hyxmp@xml| macro. Currently, these are only the \xmpterm{Marked}
+% property and the \xmpterm{WebStatement} property and only if the
+% author defined a |pdflicenseurl|.
+% \begin{macrocode}
+\newcommand*{\hyxmp@xapRights@schema}{%
+ \ifx\@pdflicenseurl\@empty
+ \else
+ \hyxmp@xmlify{\@pdflicenseurl}%
+ \hyxmp@add@to@xml{%
+______<rdf:Description rdf:about=""^^J%
+___________xmlns:xapRights="http://ns.adobe.com/xap/1.0/rights/">^^J%
+_________<xapRights:Marked>True</xapRights:Marked>^^J%
+_________<xapRights:WebStatement>\hyxmp@xmlified</xapRights:WebStatement>^^J%
+______</rdf:Description>^^J%
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{The XMP Media Management schema}
+% \label{sec:xmp-media}
+%
+% \begin{macro}{\hyxmp@mm@schema}
+% Add properties defined by the XMP Media Management schema to the
+% |\hyxmp@xml| macro. Although the \xmpterm{DocumentID} property is
+% defined in the \acro{XMP} specification~\cite{Adobe2005:XMP}, the
+% \xmpterm{InstanceID} property is not. However, an
+% \xmpterm{InstanceID} field is produced by Adobe Acrobat~7.0 (the
+% latest version at the time of this writing) so it's probably worth
+% including here.
+% \begin{macrocode}
+\gdef\hyxmp@mm@schema{%
+ \hyxmp@def@DocumentID
+ \hyxmp@def@InstanceID
+ \hyxmp@add@to@xml{%
+______<rdf:Description rdf:about=""^^J%
+____________xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/">^^J%
+_________<xapMM:DocumentID>\hyxmp@DocumentID</xapMM:DocumentID>^^J%
+_________<xapMM:InstanceID>\hyxmp@InstanceID</xapMM:InstanceID>^^J%
+______</rdf:Description>^^J%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Constructing the XMP packet}
+%
+% \begin{macro}{\hyxmp@construct@packet}
+% \begin{macro}{\hyxmp@xml}
+% Successively add \acro{XML} data to |\hyxmp@xml| until we have something we
+% can insert into the document's \acro{PDF} catalog. The \acro{XMP}
+% specification~\cite{Adobe2005:XMP} states that the argument to the
+% \xmpterm{begin} attribute must be ``the Unicode `zero-width
+% non-breaking space character'~(U+FEFF)''. However, Adobe Acrobat~7.0
+% (the latest version at the time of this writing) inserts the sequence
+% \meta{EF}\meta{BB}\meta{BF} so that's what we use here.
+%
+% We explicitly mark characters \meta{EF}, \meta{BB}, \meta{BF} as
+% character code~12 (``letter'') because the \pkgname{inputenc} package
+% re-encodes them as character code~13 (``active''), which causes
+% \LaTeX\ to abort with an ``\texttt{Undefined control sequence}'' error
+% upon invoking |\hyxmp@construct@packet|.
+% \changes{v1.1}{2006/05/21}{Explicitly set the category codes of
+% characters \string\meta{EF}, \string\meta{BB}, and
+% \string\meta{BF} to ``letter''. Thanks to Daniel Sch\"omer for
+% the bug report}
+% \begin{macrocode}
+\bgroup
+\catcode`\^^ef=12
+\catcode`\^^bb=12
+\catcode`\^^bf=12
+\gdef\hyxmp@construct@packet{%
+ \gdef\hyxmp@xml{}%
+ \hyxmp@add@to@xml{%
+<?xpacket begin="^^ef^^bb^^bf" id="W5M0MpCehiHzreSzNTczkc9d"?>^^J%
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="3.1-702">^^J%
+___<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns\hyxmp@hash">^^J%
+ }%
+ \hyxmp@pdf@schema
+ \hyxmp@xapRights@schema
+ \hyxmp@dc@schema
+ \hyxmp@mm@schema
+ \hyxmp@add@to@xml{%
+___</rdf:RDF>^^J%
+</x:xmpmeta>^^J%
+\hyxmp@padding
+<?xpacket end="w"?>^^J%
+ }%
+}
+\egroup
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Embedding the XMP packet}
+%
+% The \acro{PDF} specification~\cite{Adobe2004:PDF} says that ``a
+% metadata stream can be attached to a document through the
+% \pdfterm{Metadata} entry in the document catalog'' so that's what we
+% do here. \pkgname{hyperxmp} does not currently support the embedding
+% of \acro{XMP} in any format other than \acro{PDF}.
+%
+% \begin{macro}{\hyxmp@embed@packet}
+% \begin{macro}{\hyxmp@driver}
+% Determine which \pkgname{hyperref} driver is in use and invoke the
+% appropriate embedding function.
+% \begin{macrocode}
+\newcommand*{\hyxmp@embed@packet}{%
+ \hyxmp@construct@packet
+ \def\hyxmp@driver{hpdftex}%
+ \ifx\hyxmp@driver\Hy@driver
+ \hyxmp@embed@packet@pdftex
+ \else
+ \def\hyxmp@driver{hdvipdfm}%
+ \ifx\hyxmp@driver\Hy@driver
+ \hyxmp@embed@packet@dvipdfm
+ \else
+ \@ifundefined{pdfmark}{%
+ \PackageWarningNoLine{hyperxmp}{%
+ Unrecognized hyperref driver `\Hy@driver'.\MessageBreak
+ \jobname.tex's XMP metadata will *not* be\MessageBreak
+ embedded in the resulting file}%
+ }{%
+ \hyxmp@embed@packet@pdfmark
+ }%
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Embedding using pdf\TeX}
+%
+% \begin{macro}{\hyxmp@embed@packet@pdftex}
+% Embed the \acro{XMP} packet using pdf\TeX\ primitives.
+% \begin{macrocode}
+\newcommand*{\hyxmp@embed@packet@pdftex}{%
+ \bgroup
+ \pdfcompresslevel=0
+ \immediate\pdfobj stream attr {%
+ /Type /Metadata
+ /Subtype /XML
+ }{\hyxmp@xml}%
+ \pdfcatalog {/Metadata \the\pdflastobj\space 0 R}%
+ \egroup
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Embedding using any \texttt{pdfmark}-based backend}
+%
+% \begin{macro}{\hyxmp@embed@packet@pdfmark}
+% Embed the \acro{XMP} packet using \pkgname{hyperref}'s |\pdfmark|
+% command. I believe |\pdfmark| is used by the |dvipdf|, |dvipsone|,
+% |dvips|, |dviwindo|, |nativepdf|, |pdfmark|, |ps2pdf| |textures|, and
+% |vtexpdfmark| options to \pkgname{hyperref} but I've tested only a few
+% of those.
+% \begin{macrocode}
+\newcommand*{\hyxmp@embed@packet@pdfmark}{%
+ \pdfmark{%
+ pdfmark=/OBJ,
+ Raw={/_objdef \string{hyxmp@Metadata\string} /type /stream}%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,
+ Raw={\string{hyxmp@Metadata\string}%
+ <<
+ /Type /Metadata
+ /Subtype /XML
+ >>
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,
+ Raw={\string{hyxmp@Metadata\string} (\hyxmp@xml)}%
+ }%
+ \pdfmark{%
+ pdfmark=/CLOSE,
+ Raw={\string{hyxmp@Metadata\string}}%
+ }%
+% \end{macrocode}
+% Adobe's |pdfmark| reference~\cite{Adobe2005:pdfmark} indicates that a
+% metadata stream can be added to the document catalog by specifying the
+% \pdfterm{Metadata} |pdfmark| instead of the \pdfterm{PUT} |pdfmark|.
+% I see no advantage to this alternative mechanism and, furthermore, it
+% works only with Adobe Acrobat Distiller and only with versions~6.0
+% onwards. Consequently, \pkgname{hyperxmp} uses the traditional
+% \pdfterm{PUT} mechanism to point the document catalog to our metadata
+% stream.
+% \begin{macrocode}
+ \pdfmark{%
+ pdfmark=/PUT,
+ Raw={\string{Catalog\string}%
+ <<
+ /Metadata \string{hyxmp@Metadata\string}%
+ >>
+ }%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Embedding using \texttt{dvipdfm}}
+%
+% \begin{macro}{\hyxmp@embed@packet@dvipdfm}
+% Embed the \acro{XMP} packet using a |dvipdfm|-specific |\special| command.
+% Note that |dvipdfm| rather irritatingly requires us to count the
+% number of characters in the |\hyxmp@xml| stream ourselves.
+% \begin{macrocode}
+\newcommand*{\hyxmp@embed@packet@dvipdfm}{%
+ \hyxmp@string@len{\hyxmp@xml}%
+ \special{pdf: object @hyxmp@Metadata
+ <<
+ /Type /Metadata
+ /Subtype /XML
+ /Length \the\@tempcnta
+ >>
+ stream^^J\hyxmp@xml endstream%
+ }%
+ \special{pdf: docview
+ <<
+ /Metadata @hyxmp@Metadata
+ >>
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@string@len}
+% Set |\@tempcnta| to the number of characters in a given string~(|#1|).
+% The approach is first to tally the number of space characters then to
+% tally the number of non-space characters. While this is rather
+% sloppy I haven't found a better way to achieve the same effect,
+% especially given that all of the characters in |#1| have already been
+% assigned their category codes.
+% \begin{macrocode}
+\newcommand*{\hyxmp@string@len}[1]{%
+ \@tempcnta=0
+ \expandafter\hyxmp@count@spaces#1 {} %
+ \expandafter\hyxmp@count@non@spaces#1{}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@count@spaces}
+% Count the number of spaces in a given string. We rely on the built-in
+% pattern matching of \TeX's |\def| primitive to pry one word at a time
+% off the head of the input string.
+% \begin{macrocode}
+\def\hyxmp@count@spaces#1 {%
+ \def\hyxmp@one@token{#1}%
+ \ifx\hyxmp@one@token\@empty
+ \advance\@tempcnta by -1
+ \else
+ \advance\@tempcnta by 1
+ \expandafter\hyxmp@count@spaces
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@count@non@spaces}
+% Count the number of non-spaces in a given string. Ideally, we'd count
+% both spaces and non-spaces but |\TeX| won't bind |#1| to a space
+% character (category code~10). Hence, in each iteration, |#1| is bound
+% to the next non-space character only.
+% \begin{macrocode}
+\newcommand*{\hyxmp@count@non@spaces}[1]{%
+ \def\hyxmp@one@token{#1}%
+ \ifx\hyxmp@one@token\@empty
+ \else
+ \advance\@tempcnta by 1
+ \expandafter\hyxmp@count@non@spaces
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \Finale
+\endinput
diff --git a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins
new file mode 100644
index 00000000000..82008a84a5f
--- /dev/null
+++ b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.ins
@@ -0,0 +1,55 @@
+%%
+%% Copyright (C) 2006 by Scott Pakin <scott+dtx@pakin.org>
+%%
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3b of this license
+%% or (at your option) any later version. The latest version of this
+%% license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3b or later is part of all distributions of LaTeX version
+%% 2006/01/07 or later.
+%%
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/latex/hyperxmp}
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2006 by Scott Pakin <scott+dtx@pakin.org>
+
+This file may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3b of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3b or later is part of all distributions of LaTeX
+version 2006/01/07 or later.
+
+\endpreamble
+
+\generate{\file{hyperxmp.sty}{\from{hyperxmp.dtx}{package}}}
+
+\obeyspaces
+\Msg{*************************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the following *}
+\Msg{* file into a directory searched by TeX: *}
+\Msg{* *}
+\Msg{* hyperxmp.sty *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file hyperxmp.dtx *}
+\Msg{* through LaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{*************************************************************}
+
+\endbatchfile