summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-09-14 00:35:00 +0000
committerKarl Berry <karl@freefriends.org>2012-09-14 00:35:00 +0000
commita1f11c0b253215e29345a70060ea16c46dd8536e (patch)
treecaa8921a5fcc6a72a9a207603e5e9c92e24e6b0a /Master
parentc10f0604c0627b56b4126da3a23d4088647d8f13 (diff)
hyperxmp (13sep12)
git-svn-id: svn://tug.org/texlive/trunk@27663 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdfbin446991 -> 548015 bytes
-rw-r--r--Master/texmf-dist/source/latex/hyperxmp/einstein.pngbin0 -> 36422 bytes
-rw-r--r--Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx1461
-rw-r--r--Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty500
4 files changed, 1308 insertions, 653 deletions
diff --git a/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf b/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf
index 2e3aa7c848e..47a254ae78b 100644
--- a/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf
+++ b/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/hyperxmp/einstein.png b/Master/texmf-dist/source/latex/hyperxmp/einstein.png
new file mode 100644
index 00000000000..661c3c6dfa0
--- /dev/null
+++ b/Master/texmf-dist/source/latex/hyperxmp/einstein.png
Binary files differ
diff --git a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx
index 78dedace992..f1aa01b724e 100644
--- a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx
+++ b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx
@@ -22,13 +22,19 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{hyperxmp}
%<*package>
- [2012/03/10 v1.5 Store hyperref metadata in XMP format]
+ [2012/09/10 v2.0 Store hyperref metadata in XMP format]
%</package>
%
%<*driver>
+\bgroup
+ \catcode`\&=11
+ \gdef\levelchar{&}
+\egroup
\documentclass{ltxdoc}
\usepackage{graphicx}
+\usepackage{color}
\usepackage{tocbibind}
+\usepackage{microtype}
\usepackage{hyperxmp}
\usepackage[bookmarksopen,bookmarksopenlevel=2,pdflang=en]{hyperref}
\EnableCrossrefs
@@ -36,13 +42,21 @@
\RecordChanges
\begin{document}
\DocInput{hyperxmp.dtx}
+ \phantomsection\addcontentsline{toc}{section}{Change History}
\PrintChanges
+ \makeatletter
+ \let\orig@index@prologue=\index@prologue
+ \def\index@prologue{%
+ \phantomsection\addcontentsline{toc}{section}{Index}
+ \orig@index@prologue
+ }%
+ \makeatother
\PrintIndex
\end{document}
%</driver>
% \fi
%
-% \CheckSum{898}
+% \CheckSum{1200}
%
% \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
@@ -62,6 +76,11 @@
%
%
% \changes{v1.0}{2006/05/14}{Initial version}
+% \changes{v2.0}{2012/08/02}{Heiko Oberdiek's major rewrite of the code
+% to better support native-Unicode \string\TeX\ implementations
+% (\string\XeTeX\ and \string\LuaTeX)}
+% \changes{v2.0}{2012/08/26}{Added support for the \protect\acro{XMP} Basic
+% schema and miscellaneous other bits of metadata}
%
% \GetFileInfo{hyperxmp.dtx}
%
@@ -91,6 +110,7 @@
% \DeclareRobustCommand{\xmpterm}[1]{\mbox{\textsf{#1}}\SortIndex{#1}{\textsf{#1}}}
% \DeclareRobustCommand{\pdfterm}[1]{\mbox{\textsf{#1}}\SortIndex{#1}{\textsf{#1}}}
% \DeclareRobustCommand{\cmdname}[1]{\mbox{\texttt{#1}}\SortIndex{#1}{\texttt{#1}}}
+% \DeclareRobustCommand{\optname}[1]{\mbox{\texttt{#1}}\SortIndex{#1}{\textsf{#1} (option)}}
% \DeclareRobustCommand{\acrostyle}[1]{\textsc{\MakeLowercase{#1}}}
% \DeclareRobustCommand{\acro}[1]{^^A
% \mbox{\acrostyle{#1}}^^A
@@ -98,6 +118,9 @@
% }
%
% ^^A Define some other shortcut macros.
+% \DeclareRobustCommand{\tex}{^^A
+% \texorpdfstring{\TeX\SortIndex{TeX}{\TeX}}{TeX}^^A
+% }
% \DeclareRobustCommand{\XeTeXlogo}{^^A
% X\lower0.5ex\hbox{\kern-.15em\reflectbox{E}}\kern-0.1667em\TeX
% }
@@ -110,6 +133,28 @@
% \DeclareRobustCommand{\XeLaTeX}{^^A
% \texorpdfstring{\XeLaTeXlogo\SortIndex{XeLaTeX}{\XeLaTeXlogo}}{XeLaTeX}^^A
% }
+% \DeclareRobustCommand{\LuaTeXlogo}{Lua\TeX}
+% \DeclareRobustCommand{\LuaTeX}{^^A
+% \texorpdfstring{\LuaTeXlogo\SortIndex{LuaTeX}{\LuaTeXlogo}}{LuaTeX}^^A
+% }
+% \DeclareRobustCommand{\LuaLaTeXlogo}{Lua\LaTeX}
+% \DeclareRobustCommand{\LuaLaTeX}{^^A
+% \texorpdfstring{\LuaLaTeXlogo\SortIndex{LuaLaTeX}{\LuaLaTeXlogo}}{LuaLaTeX}^^A
+% }
+% \DeclareRobustCommand{\pdfTeXlogo}{pdf\TeX}
+% \DeclareRobustCommand{\pdfTeX}{^^A
+% \texorpdfstring{\pdfTeXlogo\SortIndex{pdfTeX}{\pdfTeXlogo}}{pdfTeX}^^A
+% }
+% \DeclareRobustCommand{\pdfLaTeXlogo}{pdf\LaTeX}
+% \DeclareRobustCommand{\pdfLaTeX}{^^A
+% \texorpdfstring{\pdfLaTeXlogo\SortIndex{pdfLaTeX}{\pdfLaTeXlogo}}{pdfLaTeX}^^A
+% }
+% \DeclareRobustCommand{\Dvips}{^^A
+% \texorpdfstring{Dvips\SortIndex{dvips}{\texttt{dvips}}}{Dvips}^^A
+% }
+%
+% ^^A Pack figures a bit tighter onto the page.
+% \renewcommand{\floatpagefraction}{0.8}
%
% ^^A Specify this document's metadata.
% \title{The \pkgname{hyperxmp} package\thanks{This document
@@ -151,16 +196,16 @@
% 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.
+% 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:
+% 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>
@@ -181,10 +226,10 @@
% is represented by an individual list item (\xmpterm{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.
+% 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 all of the following types of
@@ -192,15 +237,21 @@
%
% \begin{itemize}
% \item authors (\xmpterm{dc:creator})
-% \item copyright (\xmpterm{dc:rights})
-% \item date (\xmpterm{dc:date})
+% \item base \acro{URL} (\xmpterm{xmp:BaseURL})
+% \item copyright (\xmpterm{dc:rights} and \xmpterm{xmpRights:Marked})
+% \item date (\xmpterm{dc:date}, \xmpterm{xmp:CreateDate},
+% \xmpterm{xmp:ModifyDate}, and \xmpterm{xmp:MetadataDate})
% \item document identifier (\xmpterm{xmpMM:DocumentID})
% \item document instance identifier (\xmpterm{xmpMM:InstanceID})
-% \item format (\xmpterm{dc:format})
-% \item keywords (\xmpterm{pdf:Keyword} and \xmpterm{dc:subject})
+% \item file format (\xmpterm{dc:format})
+% \item keywords (\xmpterm{pdf:Keywords} and \xmpterm{dc:subject})
+% \item language (\xmpterm{dc:language})
+% \item \LaTeX\ file name (\xmpterm{dc:source})
% \item license \acro{URL} (\xmpterm{xmpRights:WebStatement})
% \item metadata writer (\xmpterm{photoshop:CaptionWriter})
-% \item \acro{PDF}-generating tool (\xmpterm{pdf:Producer})
+% \item \acro{PDF}-generating tool (\xmpterm{pdf:Producer} and
+% \xmpterm{xmp:CreatorTool})
+% \item \acro{PDF} version (\xmpterm{pdf:PDFVersion})
% \item primary author's position/title (\xmpterm{photoshop:AuthorsPosition})
% \item summary (\xmpterm{dc:description})
% \item title (\xmpterm{dc:title})
@@ -219,7 +270,7 @@
% 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
+% \pkgname{xmpincl} can embed \acro{XMP} only when running under \pdfLaTeX\ and
% only when in \acro{PDF}-generating mode. \pkgname{hyperxmp} additionally
% works with a few other \acro{PDF}-producing \LaTeX\ backends.
%
@@ -232,19 +283,20 @@
%
% \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:
+% \pkgname{hyperxmp} works by postprocessing 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 |pdflang|
-% \item |pdfproducer|
-% \item |pdfsubject|
-% \item |pdftitle|
+% \item \optname{baseurl}
+% \item \optname{pdfauthor}
+% \item \optname{pdfkeywords}
+% \item \optname{pdflang}
+% \item \optname{pdfproducer}
+% \item \optname{pdfsubject}
+% \item \optname{pdftitle}
% \end{itemize}
%
% \noindent
@@ -252,30 +304,31 @@
% following options, which have meaning only to \pkgname{hyperxmp}:
%
% \begin{itemize}
-% \item |pdfauthortitle|
-% \item |pdfcaptionwriter|
-% \item |pdfcopyright|
-% \item |pdflicenseurl|
-% \item |pdfmetalang|
+% \item \optname{pdfauthortitle}
+% \item \optname{pdfcaptionwriter}
+% \item \optname{pdfcopyright}
+% \item \optname{pdflicenseurl}
+% \item \optname{pdfmetalang}
% \end{itemize}
%
% \noindent
-% |pdfauthortitle| indicates the primary author's position or title.
-% |pdfcaptionwriter| specifies the name of the person who added
-% the metadata to the document. |pdfcopyright| defines the copyright
-% text. |pdflicenseurl| identifies a \acro{URL} that points to the
-% document's license agreement. |pdfmetalang| indicates the natural
-% language in which the metadata is written, typically as an \acro{IETF}
-% language tag~\cite{IANA2011:lang-tags}, for example, ``|en|'' for
-% English, ``|en-US|'' for specifically United States English, ``|de|''
-% for German, and so forth. If |pdfmetalang| is not specified,
+% \optname{pdfauthortitle} indicates the primary author's position or
+% title. \optname{pdfcaptionwriter} specifies the name of the person
+% who added the metadata to the document. \optname{pdfcopyright}
+% defines the copyright text. \optname{pdflicenseurl} identifies a
+% \acro{URL} that points to the document's license agreement.
+% \optname{pdfmetalang} indicates the natural language in which the
+% metadata is written, typically as an \acro{IETF} language
+% tag~\cite{IANA2011:lang-tags}, for example, ``|en|'' for English,
+% ``|en-US|'' for specifically United States English, ``|de|'' for
+% German, and so forth. If \optname{pdfmetalang} is not specified,
% \pkgname{hyperxmp} assumes the metadata language is the same as the
-% document language (\pkgname{hyperref}'s |pdflang| option). If neither
-% |pdfmetalang| nor |pdflang| is specified, \pkgname{hyperxmp} uses only
-% ``|x-default|'' as the metadata language. Note that ``|x-default|''
-% metadata is always included in addition to the specified metadata
-% language, as the user reading the document may not have specified a
-% language preference.
+% document language (\pkgname{hyperref}'s \optname{pdflang} option). If
+% neither \optname{pdfmetalang} nor \optname{pdflang} is specified,
+% \pkgname{hyperxmp} uses only ``|x-default|'' as the metadata language.
+% Note that ``|x-default|'' metadata is always included in addition to
+% the specified metadata language, as the user reading the document may
+% not have specified a language preference.
%
% It is usually more convenient to provide values for those options using
% \pkgname{hyperref}'s |\hypersetup| command than on the |\usepackage|
@@ -298,10 +351,14 @@
% On a heuristic viewpoint concerning the production and
% transformation of light},
% pdfauthor={Albert Einstein},
+% pdfauthortitle={Technical Assistant, Level III},
% pdfcopyright={Copyright (C) 1905, Albert Einstein},
% pdfsubject={photoelectric effect},
% pdfkeywords={energy quanta, Hertz effect, quantum physics},
-% pdflang={en}
+% pdflicenseurl={http://creativecommons.org/licenses/by-nc-nd/3.0/},
+% pdfcaptionwriter={Scott Pakin},
+% pdflang={en},
+% baseurl={http://www.ctan.org/tex-archive/macros/latex/contrib/hyperxmp/}
% }
% \begin{document}
% \maketitle
@@ -312,51 +369,65 @@
% \end{document}
% \end{verbatim}
%
-% Compile the document to \acro{PDF} using any of the following approaches:
+% Compile the document to \acro{PDF} using any of the following
+% approaches:
%
% \begin{itemize}
-% \item pdf\LaTeX
-% \item Lua\LaTeX
+% \item \pdfLaTeX
+% \item \LuaLaTeX
% \item \LaTeX~$+$ Dvipdfm
-% \item \LaTeX~$+$ Dvips~$+$ Ghostscript
-% \item \LaTeX~$+$ Dvips~$+$ Adobe Acrobat Distiller
+% \item \LaTeX~$+$ \Dvips~$+$ Adobe Acrobat Distiller
% \item \XeLaTeX
% \end{itemize}
%
-% Besides the approaches listed above, other approaches may work as well
-% but have not been tested. Note that in many \TeX\ distributions
-% \cmdname{ps2pdf} is a convenience script that calls Ghostscript with
-% the appropriate options for converting PostScript to \acro{PDF} and
-% \cmdname{dvipdf} is a convenience script that calls \cmdname{dvips}
-% and \cmdname{ps2pdf}; both \cmdname{ps2pdf} and \cmdname{dvipdf}
-% should be compatible with \pkgname{hyperxmp}.
+% \noindent
+% Unfortunately, the \LaTeX~$+$ \Dvips~$+$ \term{Ghostscript} path
+% doesn't work.
+% \href{http://bugs.ghostscript.com/show_bug.cgi?id=690066}{Ghostscript
+% bug report~\#690066}, closed with ``\textsc{wontfix}'' status on
+% 2012-05-28, explains that \term{Ghostscript} doesn't honor the
+% \pdfterm{Metadata} tag needed to inject a custom \acro{XMP} packet.
+% Instead, \term{Ghostscript} fabricates an \acro{XMP} packet of its own
+% based on the metadata it finds in the \acro{PDF} file's \pdfterm{Info}
+% dictionary (\pdfterm{Author}, \pdfterm{Title}, \pdfterm{Subject}, and
+% \pdfterm{Keywords}).
%
% \bigskip
%
-% The resulting \acro{PDF} file will contain an \acro{XMP} packet that
-% looks something like this:
+% Once the document is compiled, the resulting \acro{PDF} file
+% will contain an \acro{XMP} packet that looks something like this:
%
% \begin{verbatim}
-% <?xpacket begin="???" id="W5M0MpCehiHzreSzNTczkc9d"?>
+% <?xpacket begin="\357\273\277" 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>
+% <pdf:Keywords>
+% energy quanta, Hertz effect, quantum physics
+% </pdf:Keywords>
+% <pdf:Producer>pdfTeX-1.40.10</pdf:Producer>
+% </rdf:Description>
+% <rdf:Description rdf:about=""
+% xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/">
+% <xmpRights:Marked>True</xmpRights:Marked>
+% <xmpRights:WebStatement>
+% http://creativecommons.org/licenses/by-nc-nd/3.0/
+% </xmpRights:WebStatement>
% </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="en">On a heuristic viewpoint
-% concerning the production and transformation of
-% light</rdf:li>
-% <rdf:li xml:lang="x-default">On a heuristic viewpoint
-% concerning the production and transformation of
-% light</rdf:li>
+% <rdf:li xml:lang="en">
+% On a heuristic viewpoint concerning the production and
+% transformation of light
+% </rdf:li>
+% <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>
@@ -367,10 +438,12 @@
% </dc:description>
% <dc:rights>
% <rdf:Alt>
-% <rdf:li xml:lang="en">Copyright (C) 1905,
-% Albert Einstein</rdf:li>
-% <rdf:li xml:lang="x-default">Copyright (C) 1905,
-% Albert Einstein</rdf:li>
+% <rdf:li xml:lang="en">
+% Copyright (C) 1905, Albert Einstein
+% </rdf:li>
+% <rdf:li xml:lang="x-default">
+% Copyright (C) 1905, Albert Einstein
+% </rdf:li>
% </rdf:Alt>
% </dc:rights>
% <dc:creator>
@@ -387,21 +460,51 @@
% </dc:subject>
% <dc:date>
% <rdf:Seq>
-% <rdf:li>2006-04-19</rdf:li>
+% <rdf:li>2012-08-26</rdf:li>
% </rdf:Seq>
% </dc:date>
+% <dc:language>en</dc:language>
+% <dc:source>einstein.tex</dc:source>
+% </rdf:Description>
+% <rdf:Description rdf:about=""
+% xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
+% <photoshop:AuthorsPosition>
+% Technical Assistant, Level III
+% </photoshop:AuthorsPosition>
+% <photoshop:CaptionWriter>Scott Pakin</photoshop:CaptionWriter>
+% </rdf:Description>
+% <rdf:Description rdf:about=""
+% xmlns:xmp="http://ns.adobe.com/xap/1.0/">
+% <xmp:CreateDate>2012-08-26</xmp:CreateDate>
+% <xmp:ModifyDate>2012-08-26</xmp:ModifyDate>
+% <xmp:MetadataDate>2012-08-26</xmp:MetadataDate>
+% <xmp:CreatorTool>LaTeX with hyperref package</xmp:CreatorTool>
+% <xmp:BaseURL>
+% http://www.ctan.org/tex-archive/macros/latex/contrib/hyperxmp/
+% </xmp:BaseURL>
% </rdf:Description>
% <rdf:Description rdf:about=""
% xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/">
-% <xmpMM:DocumentID>uuid:c4188820-aef2-0a82-626ce4182b62</xmpMM:DocumentID>
-% <xmpMM:InstanceID>uuid:9b62b67f-d754-626c-4c959595fd75</xmpMM:InstanceID>
+% <xmpMM:DocumentID>uuid:0595fdce-41dc-e4c4-6c418dc4ce46</xmpMM:DocumentID>
+% <xmpMM:InstanceID>uuid:efd754c4-1d7f-200a-ef754ce413ea</xmpMM:InstanceID>
% </rdf:Description>
% </rdf:RDF>
% </x:xmpmeta>
% <?xpacket end="w"?>
% \end{verbatim}
%
+% \noindent
+% Figure~\ref{fig:xmp-metadata} is a screenshot of the preceding packet
+% as it appears in Adobe Acrobat's ``Advanced'' metadata dialog box.
+%
+% \begin{figure}[htbp]
+% \includegraphics[width=\linewidth]{einstein}
+% \caption{\acro{XMP} metadata as it appears in Adobe Acrobat}
+% \label{fig:xmp-metadata}
+% \end{figure}
+%
% \paragraph{Note~1: Acrobat \pdfterm{Author} bug}
+% \label{page:author-bug}
% A bug in Adobe Acrobat---at least in versions~10.0.1 and
% earlier---causes that \acro{PDF} reader to confuse the \acro{XMP} and
% non-\acro{XMP} author lists when displaying the document's metadata.
@@ -415,22 +518,21 @@
% leaves ``Edward Nigma'' and ``Harvey Dent'' as the second and third
% authors, respectively.
%
-% A workaround, independent of \TeX, is to modify the \acro{PDF} file to
-% remove all but the first author from the non-\acro{XMP} author list
-% while retaining all of the authors in the \acro{XMP} author list.
-% Doing so will cause Adobe Acrobat to properly display all of the
-% authors but at the cost of other \acro{PDF} readers likely displaying
-% only the first author. The following Perl command (which should be
-% entered as a single line) automates this modification:
+% \DescribeMacro{\XMPTruncateList}
+% The \pkgname{hyperxmp} package provides a workaround for this bug in
+% the form of the |\XMPTruncateList| macro. |\XMPTruncateList| takes
+% the name of a list (a \pkgname{hyperref} option name) and replaces the
+% list with the value of its first element. Currently, the only
+% meaningful usage is to put
%
% \begin{verbatim}
-% perl -i -ne 's,(/Author\s*\([^\,\)]+)(.*?)\),"$1)" . " " x length($2),ge;
-% print' myfile.pdf
+% \XMPTruncateList{pdfauthor}
% \end{verbatim}
%
% \noindent
-% (Systems with different quoting conventions from Linux/Unix may need
-% to adapt the preceding commands as appropriate.)
+% in your document's preamble. This will cause Adobe Acrobat to
+% properly display all of the authors but at the cost of other
+% \acro{PDF} readers likely displaying only the first author.
%
%
% \paragraph{Note~2: \XeLaTeX\ object compression}
@@ -438,47 +540,58 @@
% compresses \emph{all} \acro{PDF} objects, including the ones
% containing \acro{XMP} metadata. While Adobe Acrobat can still detect
% and utilize the \acro{XMP} metadata, non-\acro{PDF}-aware applications
-% are unlikely to see the metadata. Either use a different program
-% (e.g.,~Lua\LaTeX) or use \XeLaTeX\ to produce a \acro{DVI} or
-% \acro{XDV} file and run \cmdname{xdvipdfmx} manually on that file
-% using the |-z0| option to turn off all compression (which will of
-% course make the \acro{PDF} file substantially larger).
+% are unlikely to see the metadata. Three options to consider are to
+% (1)~use a different program (e.g.,~\LuaLaTeX), (2)~pass the
+% |--output-driver="xdvipdfmx -z0"| option to \XeLaTeX\ to instruct
+% \cmdname{xdvipdfmx} to turn off all compression (which will of course
+% make the \acro{PDF} file substantially larger), or (3)~postprocess the
+% generated \acro{PDF} file by loading it into the commercial version of
+% Adobe Acrobat and re-saving it with the Save As\dots\ menu option.
%
%
% \paragraph{Note~3: Literal commas}
-% \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:
+% \pkgname{hyperxmp} splits the \optname{pdfauthor} and
+% \optname{pdfkeywords} lists at commas. Therefore, when specifying
+% \optname{pdfauthor} and \optname{pdfkeywords}, you should separate
+% items with commas. Also, omit ``|and|'' and other text that does not
+% belong to any list item. The following examples 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[Wrong:] |pdfauthor={Jack Napier, Edward Nigma,|
+% \textcolor{red}{\texttt{and}} |Harvey Dent}|
+% \item[Wrong:] |pdfauthor={Jack Napier|\textcolor{red}{\texttt{;}}
+% |Edward Nigma|\textcolor{red}{\texttt{;}}
+% |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:
+% \DescribeMacro{\xmpcomma}
+% If you need to include a comma within an author or keyword list, use
+% the |\xmpcomma| macro to represent it, and wrap the entire entry
+% containing the comma within |\xmpquote{|\dots|}| as shown below:
%
% \begin{verbatim}
-% pdfauthor={Napier\mycomma\ Jack,
-% Nigma\mycomma\ Edward,
-% Dent\mycomma\ Harvey}
+% pdfauthor={\xmpquote{Jack Napier\xmpcomma\ Jr.},
+% \xmpquote{Edward Nigma\xmpcomma\ PhD},
+% \xmpquote{Harvey Dent\xmpcomma\ Esq.}}
% \end{verbatim}
%
%
% \StopEventually{^^A
+% \section{Future Work}
+% \label{sec:future-work}
+%
+% \paragraph{Help wanted}
+% Ideally, \texttt{\string\xmpquote} should automatically replace all
+% commas with \texttt{\string\xmpcomma}. Unfortunately, my \tex\ skills
+% are insufficient to pull that off. If you know a way to make
+% \texttt{\string\xmpquote\string{Hello, world\string}} work with both
+% \term{Unicode} and non-\term{Unicode} encodings and with all
+% \tex\ engines (\pdfTeX, \LuaTeX, \XeTeX, etc.), please send me a code
+% patch.
+%
% \begin{thebibliography}{1}
% \bibitem{Adobe2010:pdfmark}
% Adobe Systems, Inc., San Jose, California.
@@ -486,6 +599,11 @@
% \newblock Available from
% \url{http://www.adobe.com/devnet/acrobat/documentation.html}.
%
+% \bibitem{Adobe1996:postscript}
+% {Adobe Systems, Inc.}
+% \newblock {\em {P}ost{S}cript Language Reference Manual}.
+% \newblock Addison-Wesley, 2nd edition, January 1996, ISBN: \mbox{0-201-18127-4}.
+%
% \bibitem{Adobe2008:PDF}
% Adobe Systems, Inc., San Jose, California.
% \newblock {\em Document Management---Portable Document Format---Part 1:
@@ -550,7 +668,7 @@
% \begin{macro}{\hyxmp@at@end}
% \begin{macro}{\hyxmp@driver}
% The |\hyxmp@at@end| macro includes code at the end of the document.
-% For pdf\TeX, the standard |\AtEndDocument| works well enough. For all
+% 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}
@@ -571,26 +689,31 @@
% 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
-% \pkgname{hyperref}'s |pdftitle|, |pdfauthor|, |pdfsubject|,
-% |pdfkeywords|, and |pdflang| options. It also introduces five new
-% options: |pdfcopyright|, |pdflicenseurl|, |pdfauthortitle|,
-% |pdfcaptionwriter|, and |pdfmetalang|. For consistency with
-% \pkgname{hyperref}'s document-metadata naming conventions (which are
-% in turn based on \LaTeX's document-metadata naming conventions), we do
-% not prefix metadata-related macro names with our package-specific
-% |\hyxmp@| prefix. That is, we use names like |\@pdfcopyright| instead
-% of |\hyxmp@pdfcopyright|.
+% \pkgname{hyperref}'s \optname{pdftitle}, \optname{pdfauthor},
+% \optname{pdfsubject}, \optname{pdfkeywords}, and \optname{pdflang}
+% options. It also introduces five new options: \optname{pdfcopyright},
+% \optname{pdflicenseurl}, \optname{pdfauthortitle},
+% \optname{pdfcaptionwriter}, and \optname{pdfmetalang}. For
+% consistency with \pkgname{hyperref}'s document-metadata naming
+% conventions (which are in turn based on \LaTeX's document-metadata
+% naming conventions), we do not prefix metadata-related macro names
+% with our package-specific |\hyxmp@| prefix. That is, we use names
+% like |\@pdfcopyright| instead of |\hyxmp@pdfcopyright|.
%
% \bigskip
%
-% We load three helper packages: \pkgname{keyval} for package-option
-% processing and \pkgname{pdfescape} and \pkgname{stringenc} for
-% re-encoding Unicode strings.
+% We load a bunch of helper packages: \pkgname{kvoptions} for
+% package-option processing, \pkgname{pdfescape} and \pkgname{stringenc}
+% for re-encoding \term{Unicode} strings, \pkgname{intcalc} for
+% performing integer calculations (division and modulo), and
+% \pkgname{ifxetex} for detecting \XeTeX.
%
% \begin{macrocode}
-\RequirePackage{keyval}
+\RequirePackage{kvoptions}
\RequirePackage{pdfescape}
\RequirePackage{stringenc}
+\RequirePackage{intcalc}
+\RequirePackage{ifxetex}
% \end{macrocode}
%
% \begin{macro}{\@pdfcopyright}
@@ -636,20 +759,147 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\hyxmp@ProcessKeyvalOptions}
+% \changes{v2.0}{2012/09/05}{Added this macro}
+% \begin{macro}{\ProcessKeyvalOptions}
+% \changes{v2.0}{2012/09/05}{Added this macro}
+% We need to capture list arguments (viz.~\optname{pdfauthor} and
+% \optname{pdfkeywords}) before \pkgname{hyperref} converts them to
+% \term{PDFDocEncoding}. Otherwise, |\xmpcomma| is permanently replaced
+% with a comma, and we lose our ability to change it to a
+% |\hyxmp@comma|. We therefore need to augment \pkgname{hyperref}'s
+% option processing with our own. Because \pkgname{hyperref} has not
+% yet been loaded we need to ensure that our augmentation gets loaded in
+% the future: after the |\usepackage{hyperref}| but before options are
+% passed to that package.
+%
+% For lack of a better approach, \pkgname{hyperxmp} redefines
+% |\ProcessKeyvalOptions| to alter the way \pkgname{hyperref} processes
+% \optname{pdfauthor} and \optname{pdfkeywords}. This is somewhat
+% heavy-handed as it gets executed for \emph{every} subsequently loaded
+% package that uses |\ProcessKeyvalOptions|, but at least it does what
+% we need.
+% \begin{macrocode}
+\let\hyxmp@ProcessKeyvalOptions=\ProcessKeyvalOptions
+\renewcommand*{\ProcessKeyvalOptions}{%
+% \end{macrocode}
+% \begin{macro}{\hyxmp@Hyp@pdfauthor}
+% Store the old definition of |\KV@Hyp@pdfauthor| in
+% |\hyxmp@Hyp@pdfauthor|, but only if we see that |\KV@Hyp@pdfauthor| is
+% defined and |\hyxmp@Hyp@pdfauthor| isn't. Otherwise, we'd be defining
+% |\hyxmp@Hyp@pdfauthor| in terms of itself and creating an infinite
+% loop.
+% \begin{macrocode}
+ \@ifundefined{KV@Hyp@pdfauthor}{}{%
+ \@ifundefined{hyxmp@Hyp@pdfauthor}{%
+ \expandafter\let\expandafter\hyxmp@Hyp@pdfauthor
+ \csname KV@Hyp@pdfauthor\endcsname
+ }{}%
+ }%
+% \end{macrocode}
+% \begin{macro}{\KV@Hyp@pdfauthor}
+% \begin{macro}{\xmpcomma}
+% \begin{macro}{\xmpquote}
+% \begin{macro}{\hyxmp@pdfauthor}
+% \begin{macro}{\@pdfauthor}
+% Redefine |\KV@Hyp@pdfauthor| to process its argument twice. The first
+% time, |\xmpcomma| is defined as a placeholder character
+% (|\hyxmp@comma|) and |\xmpquote| as the identity function. The
+% result is stored in |\hyxmp@pdfauthor| for use in structured lists
+% (those surrounding each entry with |<rdf:li>|). The second time,
+% |\xmpcomma| is defined as an ordinary comma, and |\xmpquote| is
+% defined as a macro that puts its argument within double quotes. The
+% result is stored in |\@pdfauthor| for use in unstructured lists (those
+% in which the entire list appears within a single pair of tags).
+% \begin{macrocode}
+ \define@key{Hyp}{pdfauthor}{%
+ \let\xmpcomma=\hyxmp@comma
+ \def\xmpquote####1{####1}%
+ \hyxmp@Hyp@pdfauthor{##1}%
+ \global\let\hyxmp@pdfauthor=\@pdfauthor
+ \def\xmpcomma{,}%
+ \def\xmpquote####1{"####1"}%
+ \hyxmp@Hyp@pdfauthor{##1}%
+ \let\xmpcomma=\relax
+ \let\xmpquote=\relax
+ }%
+% \end{macrocode}
+% \begin{macro}{\hyxmp@Hyp@pdfkeywords}
+% The previous block of code now repeats for the keyword list, starting
+% by storing the old definition of |\KV@Hyp@pdfkeywords| in
+% |\hyxmp@Hyp@pdfkeywords|.
+% \begin{macrocode}
+ \@ifundefined{KV@Hyp@pdfkeywords}{}{%
+ \@ifundefined{hyxmp@Hyp@pdfkeywords}{%
+ \expandafter\let\expandafter\hyxmp@Hyp@pdfkeywords
+ \csname KV@Hyp@pdfkeywords\endcsname
+ }{}%
+ }%
+% \end{macrocode}
+% \begin{macro}{\KV@Hyp@pdfkeywords}
+% \begin{macro}{\xmpcomma}
+% \begin{macro}{\xmpquote}
+% \begin{macro}{\hyxmp@pdfkeywords}
+% \begin{macro}{\@pdfkeywords}
+% Redefine |\KV@Hyp@pdfkeywords| to process its argument twice. The
+% first time, |\xmpcomma| is defined as a placeholder character
+% (|\hyxmp@comma|) and |\xmpquote| as the identity function. The
+% result is stored in |\hyxmp@pdfkeywords| for use in structured lists
+% (those surrounding each entry with |<rdf:li>|). The second time,
+% |\xmpcomma| is defined as an ordinary comma, and |\xmpquote| is
+% defined as a macro that puts its argument within double quotes. The
+% result is stored in |\@pdfkeywords| for use in unstructured lists
+% (those in which the entire list appears within a single pair of tags).
+% \begin{macrocode}
+ \define@key{Hyp}{pdfkeywords}{%
+ \let\xmpcomma=\hyxmp@comma
+ \def\xmpquote####1{####1}%
+ \hyxmp@Hyp@pdfkeywords{##1}%
+ \global\let\hyxmp@pdfkeywords=\@pdfkeywords
+ \def\xmpcomma{,}%
+ \def\xmpquote####1{"####1"}%
+ \hyxmp@Hyp@pdfkeywords{##1}%
+ \let\xmpcomma=\relax
+ \let\xmpquote=\relax
+ }%
+% \end{macrocode}
+% Process the calling package's options as normal but with the preceding
+% substitutions.
+% \begin{macrocode}
+ \hyxmp@ProcessKeyvalOptions
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\hyxmp@find@metadata}
% \begin{macro}{\hyxmp@concated@metadata}
% Issue a warning message if the author failed to include any metadata
-% at all. Note that we don't consider |\@pdflang| or |\@pdfmetalang| as
-% metadata, as they're meaningful only when used in conjunction with
-% other information.
+% at all. Note that we don't consider |\@pdfmetalang| as metadata as
+% that value is meaningful only when used in conjunction with other
+% information.
% \begin{macrocode}
\newcommand*{\hyxmp@find@metadata}{%
\edef\hyxmp@concated@metadata{%
+ \@baseurl
\@pdfauthor
\@pdfauthortitle
\@pdfcaptionwriter
\@pdfcopyright
\@pdfkeywords
+ \@pdflang
\@pdflicenseurl
\@pdfsubject
\@pdftitle
@@ -673,28 +923,26 @@ metadata values to hyperxmp}%
% preamble, not just before \pkgname{hyperxmp} is loaded.
% \begin{macrocode}
\AtBeginDocument{%
- \@ifpackageloaded{hyperref}%
- {%
+ \@ifpackageloaded{hyperref}{%
% \end{macrocode}
% If the user 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 |pdflang| option.
-% If the author did not specify a language, we use |x-default| as the
-% metadata language.
+% language, specified to \pkgname{hyperref} with the \optname{pdflang}
+% option. If the author did not specify a language, we use |x-default|
+% as the metadata language.
% \changes{v1.3}{2011/04/25}{Introduced the \texttt{pdfmetalang} package
% option, which enables an author to specify the language in which he
% wrote the document's metadata}
+% \changes{v2.0}{2012/08/02}{New
+% \texttt{\string\string\string\AtBeginDocument} code from Heiko
+% Oberdiek to properly encode \texttt{\string\string\string\@pdfmetalang}}
% \begin{macrocode}
- \ifx\@pdfmetalang\@empty
- \ifx\@pdflang\@empty
- \let\@pdfmetalang=\hyxmp@x@default
- \else
- \edef\@pdfmetalang{\@pdflang}%
- \fi
- \fi
- \ifHy@unicode
- \hyxmp@reencode\@pdfmetalang
- \fi
+ \ifx\@pdflang\@empty
+ \let\@pdfmetalang=\hyxmp@x@default
+ \else
+ \edef\@pdfmetalang{\@pdflang}%
+ \fi
+ \hyxmp@xmlify\@pdfmetalang
% \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
@@ -724,12 +972,10 @@ disabled}%
% |\hypersetup| command. The functions in this section convert
% author-supplied lists (e.g.,~|pdfkeywords={foo, bar, baz}|) into
% \LaTeX\ 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;|).
+% can be more easily manipulated (Section~\ref{sec:list-manip}); 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}
@@ -771,75 +1017,73 @@ disabled}%
% \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{macro}{\xmpcomma}
+% Because \pkgname{hyperxmp} splits lists at commas, a comma cannot
+% normally be used within a list. We there provide an |\xmpcomma| macro
+% that can expand to either a true comma or a placeholder character
+% depending on the situation. Here, we bind it to |\relax| to prevent
+% it from expanding to either prematurely.
+% \changes{v2.0}{2012/08/25}{Added this macro}
% \begin{macrocode}
-\bgroup
-\catcode`\&=11
-\gdef\hyxmp@xml@amp{&amp;}
-\global\let\hyxmp@other@amp=&
-\gdef\hyxmp@amp{&}
+\let\xmpcomma=\relax
% \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{macro}{\hyxmp@comma}
+% This is what |\xmpcomma| maps to during list construction. We assume
+% that documents will never otherwise use an \acro{ETX} (|^^C|)
+% character in their \acro{XMP} metadata.
+% \changes{v2.0}{2012/08/25}{Added this macro}
% \begin{macrocode}
-\catcode`\<=11
-\gdef\hyxmp@xml@lt{&lt;}
-\global\let\hyxmp@other@lt=<
+\bgroup
+\catcode`\^^C=11
+\gdef\hyxmp@comma{^^C}
+\egroup
% \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{macro}{\xmpquote}
+% Adobe Acrobat likes to see double quotes around list elements that
+% contain commas when the entire list appears within a single \acro{XMP}
+% tag (e.g.,~|<pdf:Keywords>|). However, it doesn't like to see double
+% quotes around list elements that contain commas when the list is
+% broken up into individual components (i.e.,~using |<rdf:li>| tags).
+% We therefore introduce an |\xmpquote| macro that quotes or doesn't
+% quote its argument based on context. Here, we bind |\xmpquote| to
+% |\relax| to prevent it from prematurely quoting or not quoting.
+% \changes{v2.0}{2012/09/10}{Added this macro}
% \begin{macrocode}
-\catcode`\>=11
-\gdef\hyxmp@xml@gt{&gt;}
-\global\let\hyxmp@other@gt=>
+\let\xmpquote=\relax
% \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= } %
+% \begin{macro}{\XMPTruncateList}
+% \changes{v2.0}{2012/09/07}{Added this macro}
+% \begin{macro}{\hyxmp@temp@str}
+% \begin{macro}{\hyxmp@temp@list}
+% \begin{macro}{\@elt}
+% As a workaround for Adobe Acrobat's inability to display author lists
+% correctly (cf.~``Acrobat \pdfterm{Author} bug'' on
+% page~\pageref{page:author-bug}) we introduce a hack that replaces a
+% list with its first element. One can then write
+% ``|\XMPTruncateList{pdfauthor}|'' and have Adobe Acrobat display the
+% author list correctly. It's sad that this is necessary, though.
+% \begin{macrocode}
+\newcommand{\XMPTruncateList}[1]{%
+ \edef\hyxmp@temp@str{\csname hyxmp@#1\endcsname}%
+ \hyxmp@commas@to@list{\hyxmp@temp@list}{\hyxmp@temp@str}%
+ \def\@elt##1{%
+ \expandafter\gdef\csname @#1\endcsname{##1}%
+ \let\@elt=\@gobble
+ }
+ \hyxmp@temp@list
+}
% \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}
+% \end{macro}
+%
%
% \subsubsection{Trimming leading and trailing spaces}
% \label{sec:trim-spaces}
@@ -912,33 +1156,55 @@ disabled}%
% The ``|<|'', ``|>|'', and ``|&|'' characters are significant to \acro{XML}.
% We therefore need to escape them in any author-supplied text.
%
+% \begin{macro}{\ifhyxmp@unicodetex}
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% \begin{macro}{\hyxmp@unicodetextrue}
+% \begin{macro}{\hyxmp@unicodetexfalse}
+% \XeTeX\ and \LuaTeX\ natively support \term{Unicode}. We define the
+% conditional |\ifhyxmp@unicodetex| to check for these so we can
+% properly handle encoding conversions. The trick here is that
+% \term{Unicode} \tex\ implementations compare decimal~64 to
+% hexadecimal~40 (decimal~64), specified with four carets, and take the
+% \textsc{true} branch; non-\term{Unicode} \tex\ implementations compare
+% decimal~64 to character~``|^|'' (decimal~94), ignore the ``|^^0040|''
+% and the rest of the \textsc{true} branch, and take the \textsc{false}
+% branch.
+% \begin{macrocode}
+\newif\ifhyxmp@unicodetex
+\ifnum64=`\^^^^0040\relax
+ \hyxmp@unicodetextrue
+\else
+ \hyxmp@unicodetexfalse
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\hyxmp@reencode}
+% This is now a placeholder macro needed only for |\@pdfmetalang| in
+% the |\begin{document}|.
% \changes{v1.3}{2011/04/25}{Introduced this macro to re-encode Unicode
% strings as 8-bit strings before manipulating them into \acro{XMP}
% schema. This change addresses a bug reported by Martin M\"unch}
-% \begin{macro}{\hyxmp@reencoded}
-% Given a control word that expands to a Unicode (|utf16be|) string,
-% re-encode it in a more basic (|pdfdoc|) 8-bit encoding so we don't
-% wind up escaping each octet of what should be a single 16-bit
-% character. The bulk of the work is left to |\EdefUnescapeString| from
-% the \pkgname{pdfescape} package and |\StringEncodingConvert| and to
-% |\StringEncodingSuccessFailure| from the \pkgname{stringenc} package.
-% \begin{macrocode}
-\newcommand*{\hyxmp@reencode}[1]{%
- \EdefUnescapeString\hyxmp@reencoded{#1}%
- \StringEncodingConvert\hyxmp@reencoded\hyxmp@reencoded{utf16be}{pdfdoc}%
- \StringEncodingSuccessFailure{%
- \global\let\hyxmp@reencoded=\hyxmp@reencoded
- }{%
- \gdef\hyxmp@reencoded{#1}%
- }%
- \edef#1{\hyxmp@reencoded}%
-}
+% \changes{v2.0}{2012/08/02}{Replaced with an empty macro by Heiko Oberdiek}
+% \begin{macrocode}
+\newcommand*{\hyxmp@reencode}[1]{}
% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}{\SE->pdfdoc@03}
+% Preserve \acro{ETX} (|^^C|), which is normally an invalid character in
+% \term{PDFDocEncoding}. We use it in \pkgname{hyperxmp} (and
+% specifically in |\hyxmp@xmlify| below) as a list-element separator.
+% \begin{macrocode}
+\expandafter\def\csname SE->pdfdoc@03\endcsname{0003}
+% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\hyxmp@xmlify}
+% \changes{v2.0}{2012/08/02}{Completely rewritten by Heiko Oberdiek to
+% better support Unicode-enabled \tex\ programs}
% \begin{macro}{\hyxmp@xmlified}
% \begin{macro}{\hyxmp@text}
% Given a piece of text defined using |\pdfstringdef| (i.e.,~with many
@@ -946,201 +1212,349 @@ disabled}%
% |\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
-% \cmdname{dvips} on the resulting \acro{DVI} file and \cmdname{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{}%
- \edef\hyxmp@text{#1}%
- \ifHy@unicode
- \hyxmp@reencode\hyxmp@text
- \fi
- \expandafter\hyxmp@xmlify@i\hyxmp@text\@empty
- \@ifundefined{pdfmark}{}{%
- \expandafter\hyxmp@obscure@spaces\expandafter{\hyxmp@xmlified}%
- }%
-}
% \end{macrocode}
-% \end{macro}
-% \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|.
+% Escaped PDF string~$\rightarrow$ \term{PDFDocEncoding}/\term{Unicode}
% \begin{macrocode}
-\def\hyxmp@xmlify@i{\futurelet\hyxmp@one@token\hyxmp@xmlify@ii}
+ \EdefUnescapeString\hyxmp@text{#1}%
+ \ifhyxmp@unicodetex
% \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.
+% \term{PDFDocEncoding}/\term{Unicode}~$\rightarrow$ \acro{UTF-32BE}
% \begin{macrocode}
-\def\hyxmp@xmlify@ii{%
- \if\hyxmp@one@token\hyxmp@other@lt
+ \hyxmp@is@unicode\hyxmp@text{%
+ \StringEncodingConvert
+ \hyxmp@text\hyxmp@text{utf16be}{utf32be}%
+ }{%
+ \ifxetex
+ \hyxmp@xetex@crap
+ \else
+ \StringEncodingConvert
+ \hyxmp@text\hyxmp@text{pdfdoc}{utf32be}%
+ \fi
+ }%
% \end{macrocode}
-% Replace ``|<|'' with |&lt;|.
+% \acro{UTF-32BE}~$\rightarrow$ \acro{UTF-32BE} as hex string
% \begin{macrocode}
- \def\next##1{%
- \xdef\hyxmp@xmlified{\hyxmp@xmlified\hyxmp@xml@lt}%
- \hyxmp@xmlify@i
- }%
- \else
- \if\hyxmp@one@token\hyxmp@other@gt
+ \EdefEscapeHex\hyxmp@text{\hyxmp@text}%
% \end{macrocode}
-% Replace ``|>|'' with |&gt;|.
+% \acro{UTF-32BE}~$\rightarrow$ \acro{XML} in \acro{ASCII}
% \begin{macrocode}
- \def\next##1{%
- \xdef\hyxmp@xmlified{\hyxmp@xmlified\hyxmp@xml@gt}%
- \hyxmp@xmlify@i
- }%
- \else
- \if\hyxmp@one@token\hyxmp@other@amp
+ \edef\hyxmp@text{%
+ \expandafter
+ }\expandafter\hyxmp@toxml@unicodetex\hyxmp@text
+ \relax\relax\relax\relax\relax\relax\relax\relax
+ \else
% \end{macrocode}
-% Replace ``|&|'' with |&amp;|.
+% \term{PDFDocEncoding}/\term{Unicode}~$\rightarrow$ \acro{UTF-8}
% \begin{macrocode}
- \def\next##1{%
- \xdef\hyxmp@xmlified{\hyxmp@xmlified\hyxmp@xml@amp}%
- \hyxmp@xmlify@i
- }%
- \else
- \ifx\hyxmp@one@token\hyxmp@other@space
+ \hyxmp@is@unicode\hyxmp@text{%
+ \StringEncodingConvert
+ \hyxmp@text\hyxmp@text{utf16be}{utf8}%
+ }{%
+ \StringEncodingConvert
+ \hyxmp@text\hyxmp@text{pdfdoc}{utf8}%
+ }%
% \end{macrocode}
-% Store spaces. We need a special case for this to avoid inadvertently
-% discarding spaces.
+% \acro{UTF-8}~$\rightarrow$ \acro{UTF-8} as hex string
% \begin{macrocode}
- \def\next##1{%
- \g@addto@macro\hyxmp@xmlified{ }%
- \hyxmp@xmlify@i##1%
- }%
- \else
- \if\hyxmp@one@token\hyxmp@other@bs
+ \EdefEscapeHex\hyxmp@text{\hyxmp@text}%
% \end{macrocode}
-% Replace |\|\meta{ooo} with |&#|\meta{ddd}|;|. For example, |\100|,
-% the octal code for ``|@|'', is represented in \acro{XML} as~|&#64;|.
+% \acro{UTF-8} as hex string~$\rightarrow$ \acro{XML} in \acro{UTF-8}
+% as hex string
% \begin{macrocode}
- \def\next##1{\futurelet\hyxmp@one@token\hyxmp@xmlify@iii}
- \else
- \ifx\hyxmp@one@token\@empty
+ \edef\hyxmp@text{%
+ \expandafter\hyxmp@toxml\hyxmp@text\@empty\@empty
+ }%
% \end{macrocode}
-% End the recursion upon encountering |\@empty|.
+% \acro{XML} in \acro{UTF-8} as hex string~$\rightarrow$ \acro{XML}
+% in \acro{UTF-8}
% \begin{macrocode}
- \def\next##1{}%
- \else
+ \EdefUnescapeHex\hyxmp@text{\hyxmp@text}%
+ \fi
+ \global\let\hyxmp@xmlified\hyxmp@text
+}
% \end{macrocode}
-% In most cases we merely append the next character in the input to
-% |\hyxmp@xmlified| without any special processing.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@is@unicode}
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% \begin{macro}{\hyxmp@@is@unicode}
+% Given a string and two expressions, evaluate the first expression if
+% the string is \acro{UTF-16BE}-encoded and the second expression if not.
% \begin{macrocode}
- \def\next##1{%
- \g@addto@macro\hyxmp@xmlified{##1}%
- \hyxmp@xmlify@i
- }%
- \fi
- \fi
- \fi
- \fi
+\begingroup
+ \lccode`\<=254 %
+ \lccode`\>=255 %
+ \catcode254=12 %
+ \catcode255=12 %
+\lowercase{\endgroup
+ \def\hyxmp@is@unicode#1{%
+ \expandafter\hyxmp@@is@unicode#1<>\@nil
+ }%
+ \def\hyxmp@@is@unicode#1<>#2\@nil{%
+ \ifx\\#1\\%
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
\fi
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@toxml}
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% Replace the characters ``\textless, ``\&'', and ``\textgreater'' with
+% \acro{XML} entities when using a non-native-\term{Unicode}
+% \tex\ (\tex\ or \pdfTeX).
+% \begin{macrocode}
+\def\hyxmp@toxml#1#2{%
+ \ifx#1\@empty
+ \else
+ \ifnum"#1#2=`\& %
+ 26616D703B% &amp;
+ \else\ifnum"#1#2=`\< %
+ 266C743B% &lt;
+ \else\ifnum"#1#2=`\> %
+ 2667743B% &gt;
+ \else
+% \end{macrocode}
+% \cmdname{dvips} wraps text when generating most PostScript code but
+% preserves line breaks within strings. Unfortunately, \cmdname{dvips}
+% fails to observe the special case in the PostScript specification that
+% ``[b]alanced pairs of parentheses in the string require no special
+% treatment''~\cite{Adobe1996:postscript}. Consequently, \acro{XMP}
+% data containing parentheses (e.g.,~``\texttt{Copyright (C) 1605 Miguel
+% de Cervantes}'') confuse \cmdname{dvips} into thinking that the
+% string has ended after the closing parenthesis and that line breaks
+% can subsequently be injected safely into the document at arbitrary
+% points for formatting purposes. This leads to erroneous display by
+% \acro{PDF} viewers, which honor line breaks within \acro{XMP} tags.
+% The solution is to insert a backslash before all parentheses when in
+% \texttt{pdfmark}-generating mode to convince \cmdname{dvips} that the
+% entire \acro{XMP} packet must be treated as a single,
+% not-to-be-modified string.
+% \changes{v2.0}{2012/08/22}{Escaped parentheses written with
+% \texttt{pdfmark}s to prevent \cmdname{dvips} from line-wrapping the
+% \acro{xmp} packet}
+% \begin{macrocode}
+ \@ifundefined{pdfmark}{%
+ #1#2%
+ }{%
+ \ifnum"#1#2=`\( %
+ 5C28% \(
+ \else\ifnum"#1#2=`\) %
+ 5C29% \)
+ \else
+ #1#2%
+ \fi\fi
+ }%
+ \fi\fi\fi
+ \expandafter\hyxmp@toxml
\fi
+}
% \end{macrocode}
-% Recursively process the next character in the input stream.
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@toxml@unicodetex}
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% \begin{macro}{\hyxmp@text}
+% Replace the characters ``\textless, ``\&'', and ``\textgreater'' with
+% \acro{XML} entities when using a native-\term{Unicode}
+% \tex\ (\XeTeX\ or \LuaTeX).
% \begin{macrocode}
- \next
+\def\hyxmp@toxml@unicodetex#1#2#3#4#5#6#7#8{%
+ \ifx#1\relax
+ \else
+ \ifnum"#1#2#3#4#5#6#7#8>127 %
+ \uccode`\*="#1#2#3#4#5#6#7#8\relax
+ \uppercase{%
+ \edef\hyxmp@text{\hyxmp@text *}%
+ }%
+ \else\ifnum"#7#8=`\< %
+ \edef\hyxmp@text{\hyxmp@text &lt;}%
+ \else\ifnum"#7#8=`\& %
+ \edef\hyxmp@text{\hyxmp@text &amp;}%
+ \else\ifnum"#7#8=`\> %
+ \edef\hyxmp@text{\hyxmp@text &gt;}%
+ \else\ifnum"#7#8=`\ %
+ \edef\hyxmp@text{\hyxmp@text\space}%
+ \else
+ \uccode`\*="#7#8\relax
+ \uppercase{%
+ \edef\hyxmp@text{\hyxmp@text *}%
+ }%
+ \fi\fi\fi\fi\fi
+ \expandafter\hyxmp@toxml@unicodetex
+ \fi
}
% \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;%
+% \begin{macro}{\hyxmp@skipzeros}
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% Skip over leading zeroes in the input argument.
+% \begin{macrocode}
+\def\hyxmp@skipzeros#1{%
+ \ifx#10%
+ \expandafter\hyxmp@skipzeros
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\x}
+% \begin{macro}{\hyxmp@xetex@crap}
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% \begin{macro}{\hyxmp@try}
+% \begin{macro}{\hyxmp@crap@result}
+% \begin{macro}{\hyxmp@text}
+% In the case of \XeTeX, the strings defined by |\pdfstringdef| can
+% contain big characters. In this case, the string is treated as
+% \term{Unicode}.
+% \begin{macrocode}
+\begingroup
+\def\x#1{\endgroup
+ \def\hyxmp@xetex@crap{%
+ \edef\hyxmp@try{%
+ \expandafter\hyxmp@SpaceOther\hyxmp@text#1\@nil
}%
- \hyxmp@xmlify@i
- }%
- \if\hyxmp@one@token(
- \let\next=\hyxmp@xmlify@i
- \else
- \if\hyxmp@one@token)
- \let\next=\hyxmp@xmlify@i
+ \let\hyxmp@crap@result=N%
+ \expandafter\hyxmp@crap@test\hyxmp@try\relax
+ \ifx\hyxmp@crap@result Y%
+ \let\hyxmp@text\@empty
+ \expandafter\hyxmp@crap@convert\hyxmp@try\relax
+ \else
+ \StringEncodingConvert\hyxmp@text\hyxmp@text{pdfdoc}{utf32be}%
\fi
- \fi
- \next
+ }%
}
+\x{ }
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\hyxmp@obscure@spaces}
-% The \cmdname{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 \xmpterm{dc:rights}
-% (copyright notice) within a single-line field. By introducing an
-% extra line break in the middle of the copyright notice,
-% \cmdname{dvips} implicitly causes it to be truncated when displayed.
+% \begin{macro}{\hyxmp@SpaceOther}
+% Re-encode all spaces in a string with category code~12 (``other'').
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% \begin{macrocode}
+\begingroup
+ \catcode`\~=12 %
+ \lccode`\~=`\ %
+\lowercase{\endgroup
+ \def\hyxmp@SpaceOther#1 #2\@nil{%
+ #1%
+ \ifx\relax#2\relax
+ \expandafter\@gobble
+ \else
+ ~%
+ \expandafter\@firstofone
+ \fi
+ {\hyxmp@SpaceOther#2\@nil}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
%
-% To thwart \cmdname{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{macro}{\hyxmp@crap@test}
+% Determine if we need to treat a string as \term{Unicode}.
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
% \begin{macrocode}
-\newcommand*{\hyxmp@obscure@spaces}[1]{%
- \gdef\hyxmp@xmlified{}%
- \expandafter\hyxmp@obscure@spaces@i#1 {} %
+\def\hyxmp@crap@test#1{%
+ \ifx#1\relax
+ \else
+ \ifnum`#1>127 %
+ \let\hyxmp@crap@result=Y%
+ \expandafter\expandafter\expandafter\hyxmp@skiptorelax
+ \else
+ \expandafter\expandafter\expandafter\hyxmp@crap@test
+ \fi
+ \fi
}
% \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{macro}{\hyxmp@skiptorelax}
+% Discard all tokens up to and including the first |\relax|.
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
% \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
+\def\hyxmp@skiptorelax#1\relax{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hyxmp@crap@convert}
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% \begin{macro}{\hyxmp@num}
+% \begin{macro}{\hyxmp@text}
+% Convert a hexadecimal string to a number.
+% \begin{macrocode}
+\def\hyxmp@crap@convert#1{%
+ \ifx#1\relax
\else
- \xdef\hyxmp@xmlified{\hyxmp@xmlified#1\hyxmp@amp\hyxmp@hash32;}%
- \def\next{\expandafter\hyxmp@obscure@spaces@i\expandafter#2 }%
+ \edef\hyxmp@num{\number`#1}%
+ \ifnum\hyxmp@num>"FFFFFF %
+ \lccode`\!=\intcalcDiv{\hyxmp@num}{\number"1000000}\relax
+ \lowercase{\edef\hyxmp@text{\hyxmp@text!}}%
+ \edef\hyxmp@num{\intcalcMod{\hyxmp@num}{\number"1000000}}%
+ \else
+ \edef\hyxmp@text{\hyxmp@text\hyxmp@zero}%
+ \fi
+ \ifnum\hyxmp@num>"FFFF %
+ \lccode`\!=\intcalcDiv{\hyxmp@num}{\number"10000}\relax
+ \lowercase{\edef\hyxmp@text{\hyxmp@text!}}%
+ \edef\hyxmp@num{\intcalcMod{\hyxmp@num}{\number"10000}}%
+ \else
+ \edef\hyxmp@text{\hyxmp@text\hyxmp@zero}%
+ \fi
+ \ifnum\hyxmp@num>"FF %
+ \lccode`\!=\intcalcDiv{\hyxmp@num}{\number"100}\relax
+ \lowercase{\edef\hyxmp@text{\hyxmp@text!}}%
+ \edef\hyxmp@num{\intcalcMod{\hyxmp@num}{\number"100}}%
+ \else
+ \edef\hyxmp@text{\hyxmp@text\hyxmp@zero}%
+ \fi
+ \ifnum\hyxmp@num>0 %
+ \lccode`\!=\hyxmp@num\relax
+ \lowercase{\edef\hyxmp@text{\hyxmp@text!}}%
+ \else
+ \edef\hyxmp@text{\hyxmp@text\hyxmp@zero}%
+ \fi
+ \expandafter\hyxmp@crap@convert
\fi
- \next
}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\hyxmp@zero}
+% Define a null character with category code~12 (``other'').
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% \begin{macrocode}
+\begingroup
+ \catcode0=12 %
+ \gdef\hyxmp@zero{^^00}%
+\endgroup
+% \end{macrocode}
+% \end{macro}
+%
%
% \subsection{UUID generation}
% \label{sec:uuid-gen}
%
% 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}
+% implement in \tex\ and is good enough for producing the \acro{XMP}
% \xmpterm{xmpMM:DocumentID} and \xmpterm{xmpMM:InstanceID} fields.
%
% \begin{macro}{\hyxmp@modulo@a}
@@ -1159,7 +1573,7 @@ disabled}%
% \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.
+% \tex\ counter.
% \begin{macrocode}
\def\hyxmp@big@prime{536870923}
\def\hyxmp@big@prime@ii{536870027}
@@ -1350,7 +1764,9 @@ disabled}%
%
% \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.
+% (``other'') spaces and all |^C| characters with commas, then append
+% the result to the |\hyxmp@xml| macro.
+% \changes{v2.0}{2012/08/24}{Updated also to replace commas}
% \begin{macrocode}
\newcommand*{\hyxmp@add@to@xml}[1]{%
\bgroup
@@ -1361,6 +1777,7 @@ disabled}%
\ifnum\@tempcnta<256
\repeat
\lccode`\_=`\ \relax
+ \lccode`\^^C=`\,\relax
\lowercase{\xdef\hyxmp@xml{\hyxmp@xml#1}}%
\egroup
}
@@ -1457,20 +1874,11 @@ __________________________________________________^^J%
______<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@simple{pdf:Keywords}{\@pdfkeywords}%
+ \hyxmp@add@simple{pdf:Producer}{\@pdfproducer}%
+ \@ifundefined{pdfminorversion}{}{%
+ \hyxmp@add@simple{pdf:PDFVersion}{1.\the\pdfminorversion}%
+ }%
\hyxmp@add@to@xml{%
______</rdf:Description>^^J%
}%
@@ -1480,6 +1888,29 @@ ______</rdf:Description>^^J%
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\hyxmp@add@simple}
+% \begin{macro}{\hyxmp@string}
+% Given an \acro{XMP} tag~(|#1|) and a string~(|#2|), if the string is
+% nonempty, add a begin tag, the string, and an end tag to the packet.
+% The ``|simple|'' in the macro name indicates that the string is output
+% without variations for different languages.
+% \changes{v2.0}{2012/08/25}{Added this macro}
+% \begin{macrocode}
+\newcommand*{\hyxmp@add@simple}[2]{%
+ \edef\hyxmp@string{#2}%
+ \ifx\hyxmp@string\@empty
+ \else
+ \hyxmp@xmlify{\hyxmp@string}%
+ \hyxmp@add@to@xml{%
+_________<#1>\hyxmp@xmlified</#1>^^J%
+ }%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
% \subsubsection{The Dublin Core schema}
% \label{sec:dublin-core}
%
@@ -1518,6 +1949,8 @@ _________</dc:#1>^^J%
% 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.
+% \changes{v2.0}{2012/08/02}{Modified by Heiko Oberdiek to use the new
+% \term{Unicode}-processing macros}
% \begin{macrocode}
\newcommand*{\hyxmp@list@to@xml}[3]{%
\ifx#3\@empty
@@ -1528,22 +1961,16 @@ ____________<rdf:#2>^^J%
}%
\bgroup
% \end{macrocode}
-% \begin{macro}{\hyxmp@text}
% \begin{macro}{\@elt}
-% We store the comma-separated list in |\hyxmp@text| so we can re-encode
-% it from Unicode if necessary. We then redefine |\@elt| to
-% \acro{XML}-ify each element of the list and append it to
+% Re-encode the text from \term{Unicode} if necessary. Then redefine
+% |\@elt| to \acro{XML}-ify each element of the list and append it to
% |\hyxmp@xmlified|.
% \begin{macrocode}
- \edef\hyxmp@text{#3}%
- \ifHy@unicode
- \hyxmp@reencode\hyxmp@text
- \fi
- \hyxmp@commas@to@list\hyxmp@list{\hyxmp@text}%
+ \hyxmp@xmlify{#3}%
+ \hyxmp@commas@to@list\hyxmp@list{\hyxmp@xmlified}%
\def\@elt##1{%
- \hyxmp@xmlify{##1}%
\hyxmp@add@to@xml{%
-_______________<rdf:li>\hyxmp@xmlified</rdf:li>^^J%
+_______________<rdf:li>##1</rdf:li>^^J%
}%
}%
\hyxmp@list
@@ -1557,18 +1984,23 @@ _________</dc:#1>^^J%
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \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{dc:title} property
-% if the author specified a |pdftitle|, the \xmpterm{dc:description}
-% property if the author specified a |pdfsubject|, the \xmpterm{dc:rights}
-% property if the author specified a |pdfcopyright|, the
-% \xmpterm{dc:creator} property if the author specified a |pdfauthor|, and
-% the \xmpterm{dc:subject} property if the author specified |pdfkeywords|.
-% We also specify the \xmpterm{dc:date} property using the date the
-% document was run through \LaTeX.
+% macro. Specifically, we add entries for the \xmpterm{dc:title}
+% property if the author specified a \optname{pdftitle}, the
+% \xmpterm{dc:description} property if the author specified a
+% \optname{pdfsubject}, the \xmpterm{dc:rights} property if the author
+% specified a \optname{pdfcopyright}, the \xmpterm{dc:creator} property
+% if the author specified a \optname{pdfauthor}, the
+% \xmpterm{dc:subject} property if the author specified
+% \optname{pdfkeywords}, and the \xmpterm{dc:language} property if the
+% author specified \optname{pdflang}. We also specify the
+% \xmpterm{dc:date} property using the date the document was run through
+% \LaTeX\ and the \xmpterm{dc:source} property using the base name of
+% the source file with |.tex| appended.
+% \changes{v2.0}{2012/08/26}{Added support for \xmpterm{dc:language}
+% and \xmpterm{dc:source}}
% \begin{macrocode}
\newcommand*{\hyxmp@dc@schema}{%
\hyxmp@add@to@xml{%
@@ -1579,9 +2011,11 @@ _________<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{creator}{Seq}{\hyxmp@pdfauthor}%
+ \hyxmp@list@to@xml{subject}{Bag}{\hyxmp@pdfkeywords}%
\hyxmp@list@to@xml{date}{Seq}{\hyxmp@today}%
+ \hyxmp@add@simple{dc:language}{\@pdflang}%
+ \hyxmp@add@simple{dc:source}{\jobname.tex}%
\hyxmp@add@to@xml{%
______</rdf:Description>^^J%
}%
@@ -1596,26 +2030,71 @@ ______</rdf:Description>^^J%
% Add properties defined by the XMP Rights Management schema to the
% |\hyxmp@xml| macro. Currently, these are only the
% \xmpterm{xmpRights:Marked} property and the
-% \xmpterm{xmpRights:WebStatement} property and only if the author
-% defined a |pdflicenseurl|.
+% \xmpterm{xmpRights:WebStatement} property. If the author specified a
+% copyright statement we mark the document as copyrighted. If the
+% author specified a license statement we include the \acro{URL} in the
+% metadata.
% \changes{v1.4}{2011/05/29}{Renamed the \texttt{xapRights} namespace
% prefix to \texttt{xmpRights}}
+% \changes{v2.0}{2012/08/25}{Modified to include
+% \xmpterm{xmpRights:Marked} only when \optname{pdfcopyright} is
+% specified and \xmpterm{xmpRights:WebStatement} only when
+% \optname{pdflicenseurl} is specified}
% \begin{macrocode}
\newcommand*{\hyxmp@xmpRights@schema}{%
+% \end{macrocode}
+% \begin{macro}{\hyxmp@legal}
+% Set |\hyxmp@rights| to |YES| if either \optname{pdfcopyright} or
+% \optname{pdflicenseurl} was specified.
+% \begin{macrocode}
+ \let\hyxmp@rights=\@empty
\ifx\@pdflicenseurl\@empty
\else
- \hyxmp@xmlify{\@pdflicenseurl}%
+ \def\hyxmp@rights{YES}%
+ \fi
+ \ifx\@pdfcopyright\@empty
+ \else
+ \def\hyxmp@rights{YES}%
+ \fi
+% \end{macrocode}
+% Include the license-statement \acro{URL} and/or the copyright
+% indication. The copyright statement itself is included by
+% |\hyxmp@dc@schema| in Section~\ref{sec:dublin-core}.
+% \begin{macrocode}
+ \ifx\hyxmp@rights\@empty
+ \else
+% \end{macrocode}
+% Header
+% \begin{macrocode}
\hyxmp@add@to@xml{%
______<rdf:Description rdf:about=""^^J%
___________xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/">^^J%
+ }%
+% \end{macrocode}
+% Copyright indication
+% \begin{macrocode}
+ \ifx\@pdfcopyright\@empty
+ \else
+ \hyxmp@add@to@xml{%
_________<xmpRights:Marked>True</xmpRights:Marked>^^J%
-_________<xmpRights:WebStatement>\hyxmp@xmlified</xmpRights:WebStatement>^^J%
+ }%
+ \fi
+% \end{macrocode}
+% License \acro{URL}
+% \begin{macrocode}
+ \hyxmp@add@simple{xmpRights:WebStatement}{\@pdflicenseurl}%
+% \end{macrocode}
+% Trailer
+% \begin{macrocode}
+ \hyxmp@add@to@xml{%
______</rdf:Description>^^J%
}%
\fi
}
% \end{macrocode}
% \end{macro}
+% \end{macro}
+%
%
% \subsubsection{The XMP Media Management schema}
% \label{sec:xmp-media}
@@ -1627,7 +2106,7 @@ ______</rdf:Description>^^J%
% document, and the \xmpterm{xmpMM:InstanceID} property is supposed to
% change with each save operation~\cite{Adobe2010:XMP}. As seen in
% Section~\ref{sec:uuid-gen}, we do what we can to honor this intention
-% from within a \TeX-based workflow.
+% from within a \tex-based workflow.
% \changes{v1.4}{2011/05/29}{Renamed the \texttt{xapMM} namespace
% prefix to \texttt{xmpMM}}
% \begin{macrocode}
@@ -1645,16 +2124,47 @@ ______</rdf:Description>^^J%
% \end{macrocode}
% \end{macro}
%
+%
+% \subsubsection{The XMP Basic schema}
+% \label{sec:xmp-basic}
+%
+% \begin{macro}{\hyxmp@xmp@basic@schema}
+% Add properties defined by the \acro{XMP} Basic schema to the
+% |\hyxmp@xml| macro. These include a bunch of dates (all set to the
+% same value) and the base \acro{URL} for the document if specified with
+% \optname{baseurl}.
+% \changes{v2.0}{2012/08/26}{Added this macro}
+% \begin{macrocode}
+\newcommand*{\hyxmp@xmp@basic@schema}{%
+ \hyxmp@add@to@xml{%
+______<rdf:Description rdf:about=""^^J%
+____________xmlns:xmp="http://ns.adobe.com/xap/1.0/">^^J%
+ }%
+ \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@today}%
+ \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@today}%
+ \hyxmp@add@simple{xmp:MetadataDate}{\hyxmp@today}%
+ \hyxmp@add@simple{xmp:CreatorTool}{\@pdfcreator}%
+ \hyxmp@add@simple{xmp:BaseURL}{\@baseurl}%
+ \hyxmp@add@to@xml{%
+______</rdf:Description>^^J%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
% \subsubsection{The Photoshop schema}
% \label{sec:photoshop}
%
% \begin{macro}{\hyxmp@photoshop@schema}
% \begin{macro}{\hyxmp@photoshop@data}
% Add properties defined by the Photoshop schema to the |\hyxmp@xml|
-% macro. We support only the \xmpterm{photoshop:AuthorsPosition} and
-% \xmpterm{photoshop:CaptionWriter} properties, as that's all that Adobe
-% Acrobat currently displays.
+% macro. We currently support only the
+% \xmpterm{photoshop:AuthorsPosition} and
+% \xmpterm{photoshop:CaptionWriter} properties.
% \changes{v1.2}{2010/06/07}{Added support for the Photoshop schema}
+% \changes{v2.0}{2012/08/26}{Simplified using
+% \texttt{\string\string\string\hyxmp@add@simple}}
% \begin{macrocode}
\gdef\hyxmp@photoshop@schema{%
\edef\hyxmp@photoshop@data{\@pdfauthortitle\@pdfcaptionwriter}%
@@ -1665,26 +2175,8 @@ ______<rdf:Description rdf:about=""^^J%
____________xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">^^J%
}%
\fi
-% \end{macrocode}
-% \begin{macrocode}
- \ifx\@pdfauthortitle\@empty
- \else
- \hyxmp@xmlify{\@pdfauthortitle}%
- \hyxmp@add@to@xml{%
-_________<photoshop:AuthorsPosition>\hyxmp@xmlified</photoshop:AuthorsPosition>^^J%
- }%
- \fi
-% \end{macrocode}
-% \begin{macrocode}
- \ifx\@pdfcaptionwriter\@empty
- \else
- \hyxmp@xmlify{\@pdfcaptionwriter}%
- \hyxmp@add@to@xml{%
-_________<photoshop:CaptionWriter>\hyxmp@xmlified</photoshop:CaptionWriter>^^J%
- }%
- \fi
-% \end{macrocode}
-% \begin{macrocode}
+ \hyxmp@add@simple{photoshop:AuthorsPosition}{\@pdfauthortitle}%
+ \hyxmp@add@simple{photoshop:CaptionWriter}{\@pdfcaptionwriter}%
\ifx\hyxmp@photoshop@data\@empty
\else
\hyxmp@add@to@xml{%
@@ -1696,41 +2188,54 @@ ______</rdf:Description>^^J%
% \end{macro}
% \end{macro}
%
+%
% \subsubsection{Constructing the XMP packet}
%
+% \begin{macro}{\hyxmp@bom}
+% Define a macro for the \term{Unicode} byte-order marker (\acro{BOM}).
+% \changes{v2.0}{2012/08/02}{Added by Heiko Oberdiek}
+% \begin{macrocode}
+\begingroup
+ \ifhyxmp@unicodetex
+ \lccode`\!="FEFF %
+ \lowercase{%
+ \gdef\hyxmp@bom{!}
+ }%
+ \else
+ \catcode`\^^ef=12
+ \catcode`\^^bb=12
+ \catcode`\^^bf=12
+ \gdef\hyxmp@bom{^^ef^^bb^^bf}%
+ \fi
+\endgroup
+% \end{macrocode}
+% \end{macro}
+%
% \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 states that the argument to the
-% \xmpterm{begin} attribute is supposed to be ``the Unicode character
-% U+FEFF used as a byte-order marker''~\cite{Adobe2010:XMP}, so that's
-% what we use, although inserted as the 8-bit character sequence
-% \meta{EF}\meta{BB}\meta{BF}. We explicitly mark those characters 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}
+% \changes{v2.0}{2012/08/02}{Modified by Heiko Oberdiek to use an
+% appropriate \acro{BOM} representation via
+% \texttt{\string\string\string\hyxmp@bom}}
+% \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.
% \begin{macrocode}
-\bgroup
-\catcode`\^^ef=12
-\catcode`\^^bb=12
-\catcode`\^^bf=12
-\gdef\hyxmp@construct@packet{%
+\def\hyxmp@construct@packet{%
\gdef\hyxmp@xml{}%
- \hyxmp@add@to@xml{%
-<?xpacket begin="^^ef^^bb^^bf" id="W5M0MpCehiHzreSzNTczkc9d"?>^^J%
+ \hyxmp@add@to@xml{<?xpacket begin="\hyxmp@bom" %
+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%
+___<rdf:RDF
+xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns\hyxmp@hash">^^J%
}%
\hyxmp@pdf@schema
\hyxmp@xmpRights@schema
\hyxmp@dc@schema
\hyxmp@photoshop@schema
+ \hyxmp@xmp@basic@schema
\hyxmp@mm@schema
\hyxmp@add@to@xml{%
___</rdf:RDF>^^J%
@@ -1739,7 +2244,6 @@ ___</rdf:RDF>^^J%
<?xpacket end="w"?>^^J%
}%
}
-\egroup
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1786,10 +2290,10 @@ ___</rdf:RDF>^^J%
% \end{macro}
% \end{macro}
%
-% \subsubsection{Embedding using pdf\TeX}
+% \subsubsection{Embedding using \pdfTeX}
%
% \begin{macro}{\hyxmp@embed@packet@pdftex}
-% Embed the \acro{XMP} packet using pdf\TeX\ primitives.
+% Embed the \acro{XMP} packet using \pdfTeX\ primitives.
% \begin{macrocode}
\newcommand*{\hyxmp@embed@packet@pdftex}{%
\bgroup
@@ -1808,23 +2312,28 @@ ___</rdf:RDF>^^J%
%
% \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.
+% command. I believe |\pdfmark| is used by the \optname{dvipdf},
+% \optname{dvipsone}, \optname{dvips}, \optname{dviwindo},
+% \optname{nativepdf}, \optname{pdfmark}, \optname{ps2pdf},
+% \optname{textures}, and \optname{vtexpdfmark} options to
+% \pkgname{hyperref} but I've tested only a few of those.
% \begin{macrocode}
\newcommand*{\hyxmp@embed@packet@pdfmark}{%
\pdfmark{%
+ pdfmark=/NamespacePush
+ }%
+ \pdfmark{%
pdfmark=/OBJ,
Raw={/_objdef \string{hyxmp@Metadata\string} /type /stream}%
}%
\pdfmark{%
pdfmark=/PUT,
- Raw={\string{hyxmp@Metadata\string}%
- <<
- /Type /Metadata
- /Subtype /XML
- >>
+ Raw={\string{hyxmp@Metadata\string}
+ 2 dict begin
+ /Type /Metadata def
+ /Subtype /XML def
+ currentdict
+ end
}%
}%
\pdfmark{%
@@ -1832,27 +2341,11 @@ ___</rdf:RDF>^^J%
Raw={\string{hyxmp@Metadata\string} (\hyxmp@xml)}%
}%
\pdfmark{%
- pdfmark=/CLOSE,
- Raw={\string{hyxmp@Metadata\string}}%
+ pdfmark=/Metadata,
+ Raw={\string{Catalog\string} \string{hyxmp@Metadata\string}}%
}%
-% \end{macrocode}
-% Adobe's |pdfmark| reference indicates that a metadata stream should be
-% added to the document catalog by specifying the \pdfterm{Metadata}
-% |pdfmark|~\cite{Adobe2010:pdfmark}. However, earlier versions of
-% Adobe Acrobat Distiller (pre-6.0) and Ghostscript ignored
-% \pdfterm{Metadata} but honored \pdfterm{PUT} so that's what versions
-% of \pkgname{hyperxmp} prior to~1.3 used. As all current
-% PostScript-to-\acro{PDF} generators seem to honor the
-% \pdfterm{Metadata} |pdfmark|, \pkgname{hyperxmp} now uses that
-% mechanism to point the document catalog to our metadata stream.
-% \begin{macrocode}
\pdfmark{%
- pdfmark=/Metadata,
- Raw={\string{Catalog\string}%
- <<
- /Metadata \string{hyxmp@Metadata\string}%
- >>
- }%
+ pdfmark=/NamespacePop
}%
}
% \end{macrocode}
@@ -1903,7 +2396,7 @@ ___</rdf:RDF>^^J%
%
% \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
+% 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 {%
@@ -1920,7 +2413,7 @@ ___</rdf:RDF>^^J%
%
% \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
+% 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}
diff --git a/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty b/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty
index a7dec0caeeb..bf84fefeed5 100644
--- a/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty
+++ b/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty
@@ -22,7 +22,7 @@
%%
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{hyperxmp}
- [2012/03/10 v1.5 Store hyperref metadata in XMP format]
+ [2012/09/10 v2.0 Store hyperref metadata in XMP format]
\edef\hyxmp@dq@code{\the\catcode`\"}
\catcode`\"=12
\def\hyxmp@driver{hpdftex}
@@ -32,9 +32,11 @@
\RequirePackage{atenddvi}
\let\hyxmp@at@end=\AtEndDvi
\fi
-\RequirePackage{keyval}
+\RequirePackage{kvoptions}
\RequirePackage{pdfescape}
\RequirePackage{stringenc}
+\RequirePackage{intcalc}
+\RequirePackage{ifxetex}
\def\@pdfcopyright{}
\define@key{Hyp}{pdfcopyright}{\pdfstringdef\@pdfcopyright{#1}}
\def\@pdflicenseurl{}
@@ -45,13 +47,53 @@
\define@key{Hyp}{pdfcaptionwriter}{\pdfstringdef\@pdfcaptionwriter{#1}}
\def\@pdfmetalang{}
\define@key{Hyp}{pdfmetalang}{\pdfstringdef\@pdfmetalang{#1}}
+\let\hyxmp@ProcessKeyvalOptions=\ProcessKeyvalOptions
+\renewcommand*{\ProcessKeyvalOptions}{%
+ \@ifundefined{KV@Hyp@pdfauthor}{}{%
+ \@ifundefined{hyxmp@Hyp@pdfauthor}{%
+ \expandafter\let\expandafter\hyxmp@Hyp@pdfauthor
+ \csname KV@Hyp@pdfauthor\endcsname
+ }{}%
+ }%
+ \define@key{Hyp}{pdfauthor}{%
+ \let\xmpcomma=\hyxmp@comma
+ \def\xmpquote####1{####1}%
+ \hyxmp@Hyp@pdfauthor{##1}%
+ \global\let\hyxmp@pdfauthor=\@pdfauthor
+ \def\xmpcomma{,}%
+ \def\xmpquote####1{"####1"}%
+ \hyxmp@Hyp@pdfauthor{##1}%
+ \let\xmpcomma=\relax
+ \let\xmpquote=\relax
+ }%
+ \@ifundefined{KV@Hyp@pdfkeywords}{}{%
+ \@ifundefined{hyxmp@Hyp@pdfkeywords}{%
+ \expandafter\let\expandafter\hyxmp@Hyp@pdfkeywords
+ \csname KV@Hyp@pdfkeywords\endcsname
+ }{}%
+ }%
+ \define@key{Hyp}{pdfkeywords}{%
+ \let\xmpcomma=\hyxmp@comma
+ \def\xmpquote####1{####1}%
+ \hyxmp@Hyp@pdfkeywords{##1}%
+ \global\let\hyxmp@pdfkeywords=\@pdfkeywords
+ \def\xmpcomma{,}%
+ \def\xmpquote####1{"####1"}%
+ \hyxmp@Hyp@pdfkeywords{##1}%
+ \let\xmpcomma=\relax
+ \let\xmpquote=\relax
+ }%
+ \hyxmp@ProcessKeyvalOptions
+}
\newcommand*{\hyxmp@find@metadata}{%
\edef\hyxmp@concated@metadata{%
+ \@baseurl
\@pdfauthor
\@pdfauthortitle
\@pdfcaptionwriter
\@pdfcopyright
\@pdfkeywords
+ \@pdflang
\@pdflicenseurl
\@pdfsubject
\@pdftitle
@@ -65,18 +107,13 @@ metadata values to hyperxmp}%
\fi
}
\AtBeginDocument{%
- \@ifpackageloaded{hyperref}%
- {%
- \ifx\@pdfmetalang\@empty
- \ifx\@pdflang\@empty
- \let\@pdfmetalang=\hyxmp@x@default
- \else
- \edef\@pdfmetalang{\@pdflang}%
- \fi
- \fi
- \ifHy@unicode
- \hyxmp@reencode\@pdfmetalang
- \fi
+ \@ifpackageloaded{hyperref}{%
+ \ifx\@pdflang\@empty
+ \let\@pdfmetalang=\hyxmp@x@default
+ \else
+ \edef\@pdfmetalang{\@pdflang}%
+ \fi
+ \hyxmp@xmlify\@pdfmetalang
\hyxmp@at@end{%
\hyxmp@find@metadata
\hyxmp@embed@packet
@@ -105,23 +142,21 @@ disabled}%
\fi
\next
}
+\let\xmpcomma=\relax
\bgroup
-\catcode`\&=11
-\gdef\hyxmp@xml@amp{&amp;}
-\global\let\hyxmp@other@amp=&
-\gdef\hyxmp@amp{&}
-\catcode`\<=11
-\gdef\hyxmp@xml@lt{&lt;}
-\global\let\hyxmp@other@lt=<
-\catcode`\>=11
-\gdef\hyxmp@xml@gt{&gt;}
-\global\let\hyxmp@other@gt=>
-\def\next#1{#1}
-\next{\global\let\hyxmp@other@space= } %
-\catcode`\|=0
-\catcode`\\=11
-|global|let|hyxmp@other@bs=\
-|egroup
+\catcode`\^^C=11
+\gdef\hyxmp@comma{^^C}
+\egroup
+\let\xmpquote=\relax
+\newcommand{\XMPTruncateList}[1]{%
+ \edef\hyxmp@temp@str{\csname hyxmp@#1\endcsname}%
+ \hyxmp@commas@to@list{\hyxmp@temp@list}{\hyxmp@temp@str}%
+ \def\@elt##1{%
+ \expandafter\gdef\csname @#1\endcsname{##1}%
+ \let\@elt=\@gobble
+ }
+ \hyxmp@temp@list
+}
\catcode`\Q=3
\newcommand{\hyxmp@trimspaces}[1]{%
\begingroup
@@ -132,103 +167,204 @@ disabled}%
\def\hyxmp@trimb#1 Q{\hyxmp@trimc#1Q}
\def\hyxmp@trimc#1Q#2{\afterassignment\endgroup \vfuzz\the\vfuzz#1}
\catcode`\Q=11
-\newcommand*{\hyxmp@reencode}[1]{%
- \EdefUnescapeString\hyxmp@reencoded{#1}%
- \StringEncodingConvert\hyxmp@reencoded\hyxmp@reencoded{utf16be}{pdfdoc}%
- \StringEncodingSuccessFailure{%
- \global\let\hyxmp@reencoded=\hyxmp@reencoded
- }{%
- \gdef\hyxmp@reencoded{#1}%
- }%
- \edef#1{\hyxmp@reencoded}%
-}
+\newif\ifhyxmp@unicodetex
+\ifnum64=`\^^^^0040\relax
+ \hyxmp@unicodetextrue
+\else
+ \hyxmp@unicodetexfalse
+\fi
+\newcommand*{\hyxmp@reencode}[1]{}
+\expandafter\def\csname SE->pdfdoc@03\endcsname{0003}
\newcommand*{\hyxmp@xmlify}[1]{%
\gdef\hyxmp@xmlified{}%
- \edef\hyxmp@text{#1}%
- \ifHy@unicode
- \hyxmp@reencode\hyxmp@text
+ \EdefUnescapeString\hyxmp@text{#1}%
+ \ifhyxmp@unicodetex
+ \hyxmp@is@unicode\hyxmp@text{%
+ \StringEncodingConvert
+ \hyxmp@text\hyxmp@text{utf16be}{utf32be}%
+ }{%
+ \ifxetex
+ \hyxmp@xetex@crap
+ \else
+ \StringEncodingConvert
+ \hyxmp@text\hyxmp@text{pdfdoc}{utf32be}%
+ \fi
+ }%
+ \EdefEscapeHex\hyxmp@text{\hyxmp@text}%
+ \edef\hyxmp@text{%
+ \expandafter
+ }\expandafter\hyxmp@toxml@unicodetex\hyxmp@text
+ \relax\relax\relax\relax\relax\relax\relax\relax
+ \else
+ \hyxmp@is@unicode\hyxmp@text{%
+ \StringEncodingConvert
+ \hyxmp@text\hyxmp@text{utf16be}{utf8}%
+ }{%
+ \StringEncodingConvert
+ \hyxmp@text\hyxmp@text{pdfdoc}{utf8}%
+ }%
+ \EdefEscapeHex\hyxmp@text{\hyxmp@text}%
+ \edef\hyxmp@text{%
+ \expandafter\hyxmp@toxml\hyxmp@text\@empty\@empty
+ }%
+ \EdefUnescapeHex\hyxmp@text{\hyxmp@text}%
\fi
- \expandafter\hyxmp@xmlify@i\hyxmp@text\@empty
- \@ifundefined{pdfmark}{}{%
- \expandafter\hyxmp@obscure@spaces\expandafter{\hyxmp@xmlified}%
+ \global\let\hyxmp@xmlified\hyxmp@text
+}
+\begingroup
+ \lccode`\<=254 %
+ \lccode`\>=255 %
+ \catcode254=12 %
+ \catcode255=12 %
+\lowercase{\endgroup
+ \def\hyxmp@is@unicode#1{%
+ \expandafter\hyxmp@@is@unicode#1<>\@nil
+ }%
+ \def\hyxmp@@is@unicode#1<>#2\@nil{%
+ \ifx\\#1\\%
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
}%
}
-\def\hyxmp@xmlify@i{\futurelet\hyxmp@one@token\hyxmp@xmlify@ii}
-\def\hyxmp@xmlify@ii{%
- \if\hyxmp@one@token\hyxmp@other@lt
- \def\next##1{%
- \xdef\hyxmp@xmlified{\hyxmp@xmlified\hyxmp@xml@lt}%
- \hyxmp@xmlify@i
- }%
+\def\hyxmp@toxml#1#2{%
+ \ifx#1\@empty
\else
- \if\hyxmp@one@token\hyxmp@other@gt
- \def\next##1{%
- \xdef\hyxmp@xmlified{\hyxmp@xmlified\hyxmp@xml@gt}%
- \hyxmp@xmlify@i
- }%
+ \ifnum"#1#2=`\& %
+ 26616D703B% &amp;
+ \else\ifnum"#1#2=`\< %
+ 266C743B% &lt;
+ \else\ifnum"#1#2=`\> %
+ 2667743B% &gt;
\else
- \if\hyxmp@one@token\hyxmp@other@amp
- \def\next##1{%
- \xdef\hyxmp@xmlified{\hyxmp@xmlified\hyxmp@xml@amp}%
- \hyxmp@xmlify@i
- }%
+ \@ifundefined{pdfmark}{%
+ #1#2%
+ }{%
+ \ifnum"#1#2=`\( %
+ 5C28% \(
+ \else\ifnum"#1#2=`\) %
+ 5C29% \)
\else
- \ifx\hyxmp@one@token\hyxmp@other@space
- \def\next##1{%
- \g@addto@macro\hyxmp@xmlified{ }%
- \hyxmp@xmlify@i##1%
- }%
- \else
- \if\hyxmp@one@token\hyxmp@other@bs
- \def\next##1{\futurelet\hyxmp@one@token\hyxmp@xmlify@iii}
- \else
- \ifx\hyxmp@one@token\@empty
- \def\next##1{}%
- \else
- \def\next##1{%
- \g@addto@macro\hyxmp@xmlified{##1}%
- \hyxmp@xmlify@i
- }%
- \fi
- \fi
- \fi
- \fi
- \fi
+ #1#2%
+ \fi\fi
+ }%
+ \fi\fi\fi
+ \expandafter\hyxmp@toxml
\fi
- \next
}
-\def\hyxmp@xmlify@iii{%
- \def\next##1##2##3{%
- \@tempcnta='##1##2##3
- \xdef\hyxmp@xmlified{\hyxmp@xmlified
- \hyxmp@amp\hyxmp@hash\the\@tempcnta;%
+\def\hyxmp@toxml@unicodetex#1#2#3#4#5#6#7#8{%
+ \ifx#1\relax
+ \else
+ \ifnum"#1#2#3#4#5#6#7#8>127 %
+ \uccode`\*="#1#2#3#4#5#6#7#8\relax
+ \uppercase{%
+ \edef\hyxmp@text{\hyxmp@text *}%
+ }%
+ \else\ifnum"#7#8=`\< %
+ \edef\hyxmp@text{\hyxmp@text &lt;}%
+ \else\ifnum"#7#8=`\& %
+ \edef\hyxmp@text{\hyxmp@text &amp;}%
+ \else\ifnum"#7#8=`\> %
+ \edef\hyxmp@text{\hyxmp@text &gt;}%
+ \else\ifnum"#7#8=`\ %
+ \edef\hyxmp@text{\hyxmp@text\space}%
+ \else
+ \uccode`\*="#7#8\relax
+ \uppercase{%
+ \edef\hyxmp@text{\hyxmp@text *}%
+ }%
+ \fi\fi\fi\fi\fi
+ \expandafter\hyxmp@toxml@unicodetex
+ \fi
+}
+\def\hyxmp@skipzeros#1{%
+ \ifx#10%
+ \expandafter\hyxmp@skipzeros
+ \fi
+}
+\begingroup
+\def\x#1{\endgroup
+ \def\hyxmp@xetex@crap{%
+ \edef\hyxmp@try{%
+ \expandafter\hyxmp@SpaceOther\hyxmp@text#1\@nil
}%
- \hyxmp@xmlify@i
+ \let\hyxmp@crap@result=N%
+ \expandafter\hyxmp@crap@test\hyxmp@try\relax
+ \ifx\hyxmp@crap@result Y%
+ \let\hyxmp@text\@empty
+ \expandafter\hyxmp@crap@convert\hyxmp@try\relax
+ \else
+ \StringEncodingConvert\hyxmp@text\hyxmp@text{pdfdoc}{utf32be}%
+ \fi
}%
- \if\hyxmp@one@token(
- \let\next=\hyxmp@xmlify@i
+}
+\x{ }
+\begingroup
+ \catcode`\~=12 %
+ \lccode`\~=`\ %
+\lowercase{\endgroup
+ \def\hyxmp@SpaceOther#1 #2\@nil{%
+ #1%
+ \ifx\relax#2\relax
+ \expandafter\@gobble
+ \else
+ ~%
+ \expandafter\@firstofone
+ \fi
+ {\hyxmp@SpaceOther#2\@nil}%
+ }%
+}
+\def\hyxmp@crap@test#1{%
+ \ifx#1\relax
\else
- \if\hyxmp@one@token)
- \let\next=\hyxmp@xmlify@i
+ \ifnum`#1>127 %
+ \let\hyxmp@crap@result=Y%
+ \expandafter\expandafter\expandafter\hyxmp@skiptorelax
+ \else
+ \expandafter\expandafter\expandafter\hyxmp@crap@test
\fi
\fi
- \next
-}
-\newcommand*{\hyxmp@obscure@spaces}[1]{%
- \gdef\hyxmp@xmlified{}%
- \expandafter\hyxmp@obscure@spaces@i#1 {} %
}
-\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
+\def\hyxmp@skiptorelax#1\relax{}
+\def\hyxmp@crap@convert#1{%
+ \ifx#1\relax
\else
- \xdef\hyxmp@xmlified{\hyxmp@xmlified#1\hyxmp@amp\hyxmp@hash32;}%
- \def\next{\expandafter\hyxmp@obscure@spaces@i\expandafter#2 }%
+ \edef\hyxmp@num{\number`#1}%
+ \ifnum\hyxmp@num>"FFFFFF %
+ \lccode`\!=\intcalcDiv{\hyxmp@num}{\number"1000000}\relax
+ \lowercase{\edef\hyxmp@text{\hyxmp@text!}}%
+ \edef\hyxmp@num{\intcalcMod{\hyxmp@num}{\number"1000000}}%
+ \else
+ \edef\hyxmp@text{\hyxmp@text\hyxmp@zero}%
+ \fi
+ \ifnum\hyxmp@num>"FFFF %
+ \lccode`\!=\intcalcDiv{\hyxmp@num}{\number"10000}\relax
+ \lowercase{\edef\hyxmp@text{\hyxmp@text!}}%
+ \edef\hyxmp@num{\intcalcMod{\hyxmp@num}{\number"10000}}%
+ \else
+ \edef\hyxmp@text{\hyxmp@text\hyxmp@zero}%
+ \fi
+ \ifnum\hyxmp@num>"FF %
+ \lccode`\!=\intcalcDiv{\hyxmp@num}{\number"100}\relax
+ \lowercase{\edef\hyxmp@text{\hyxmp@text!}}%
+ \edef\hyxmp@num{\intcalcMod{\hyxmp@num}{\number"100}}%
+ \else
+ \edef\hyxmp@text{\hyxmp@text\hyxmp@zero}%
+ \fi
+ \ifnum\hyxmp@num>0 %
+ \lccode`\!=\hyxmp@num\relax
+ \lowercase{\edef\hyxmp@text{\hyxmp@text!}}%
+ \else
+ \edef\hyxmp@text{\hyxmp@text\hyxmp@zero}%
+ \fi
+ \expandafter\hyxmp@crap@convert
\fi
- \next
}
+\begingroup
+ \catcode0=12 %
+ \gdef\hyxmp@zero{^^00}%
+\endgroup
\def\hyxmp@modulo@a#1{%
\@tempcntb=\@tempcnta
\divide\@tempcntb by #1
@@ -323,6 +459,7 @@ disabled}%
\ifnum\@tempcnta<256
\repeat
\lccode`\_=`\ \relax
+ \lccode`\^^C=`\,\relax
\lowercase{\xdef\hyxmp@xml{\hyxmp@xml#1}}%
\egroup
}
@@ -367,25 +504,26 @@ __________________________________________________^^J%
______<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@simple{pdf:Keywords}{\@pdfkeywords}%
+ \hyxmp@add@simple{pdf:Producer}{\@pdfproducer}%
+ \@ifundefined{pdfminorversion}{}{%
+ \hyxmp@add@simple{pdf:PDFVersion}{1.\the\pdfminorversion}%
+ }%
\hyxmp@add@to@xml{%
______</rdf:Description>^^J%
}%
\fi
}
+\newcommand*{\hyxmp@add@simple}[2]{%
+ \edef\hyxmp@string{#2}%
+ \ifx\hyxmp@string\@empty
+ \else
+ \hyxmp@xmlify{\hyxmp@string}%
+ \hyxmp@add@to@xml{%
+_________<#1>\hyxmp@xmlified</#1>^^J%
+ }%
+ \fi
+}
\newcommand*{\hyxmp@rdf@dc}[2]{%
\ifx#2\@empty
\else
@@ -415,15 +553,11 @@ _________<dc:#1>^^J%
____________<rdf:#2>^^J%
}%
\bgroup
- \edef\hyxmp@text{#3}%
- \ifHy@unicode
- \hyxmp@reencode\hyxmp@text
- \fi
- \hyxmp@commas@to@list\hyxmp@list{\hyxmp@text}%
+ \hyxmp@xmlify{#3}%
+ \hyxmp@commas@to@list\hyxmp@list{\hyxmp@xmlified}%
\def\@elt##1{%
- \hyxmp@xmlify{##1}%
\hyxmp@add@to@xml{%
-_______________<rdf:li>\hyxmp@xmlified</rdf:li>^^J%
+_______________<rdf:li>##1</rdf:li>^^J%
}%
}%
\hyxmp@list
@@ -443,22 +577,39 @@ _________<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{creator}{Seq}{\hyxmp@pdfauthor}%
+ \hyxmp@list@to@xml{subject}{Bag}{\hyxmp@pdfkeywords}%
\hyxmp@list@to@xml{date}{Seq}{\hyxmp@today}%
+ \hyxmp@add@simple{dc:language}{\@pdflang}%
+ \hyxmp@add@simple{dc:source}{\jobname.tex}%
\hyxmp@add@to@xml{%
______</rdf:Description>^^J%
}%
}
\newcommand*{\hyxmp@xmpRights@schema}{%
+ \let\hyxmp@rights=\@empty
\ifx\@pdflicenseurl\@empty
\else
- \hyxmp@xmlify{\@pdflicenseurl}%
+ \def\hyxmp@rights{YES}%
+ \fi
+ \ifx\@pdfcopyright\@empty
+ \else
+ \def\hyxmp@rights{YES}%
+ \fi
+ \ifx\hyxmp@rights\@empty
+ \else
\hyxmp@add@to@xml{%
______<rdf:Description rdf:about=""^^J%
___________xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/">^^J%
+ }%
+ \ifx\@pdfcopyright\@empty
+ \else
+ \hyxmp@add@to@xml{%
_________<xmpRights:Marked>True</xmpRights:Marked>^^J%
-_________<xmpRights:WebStatement>\hyxmp@xmlified</xmpRights:WebStatement>^^J%
+ }%
+ \fi
+ \hyxmp@add@simple{xmpRights:WebStatement}{\@pdflicenseurl}%
+ \hyxmp@add@to@xml{%
______</rdf:Description>^^J%
}%
\fi
@@ -474,6 +625,20 @@ _________<xmpMM:InstanceID>\hyxmp@InstanceID</xmpMM:InstanceID>^^J%
______</rdf:Description>^^J%
}%
}
+\newcommand*{\hyxmp@xmp@basic@schema}{%
+ \hyxmp@add@to@xml{%
+______<rdf:Description rdf:about=""^^J%
+____________xmlns:xmp="http://ns.adobe.com/xap/1.0/">^^J%
+ }%
+ \hyxmp@add@simple{xmp:CreateDate}{\hyxmp@today}%
+ \hyxmp@add@simple{xmp:ModifyDate}{\hyxmp@today}%
+ \hyxmp@add@simple{xmp:MetadataDate}{\hyxmp@today}%
+ \hyxmp@add@simple{xmp:CreatorTool}{\@pdfcreator}%
+ \hyxmp@add@simple{xmp:BaseURL}{\@baseurl}%
+ \hyxmp@add@to@xml{%
+______</rdf:Description>^^J%
+ }%
+}
\gdef\hyxmp@photoshop@schema{%
\edef\hyxmp@photoshop@data{\@pdfauthortitle\@pdfcaptionwriter}%
\ifx\hyxmp@photoshop@data\@empty
@@ -483,20 +648,8 @@ ______<rdf:Description rdf:about=""^^J%
____________xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">^^J%
}%
\fi
- \ifx\@pdfauthortitle\@empty
- \else
- \hyxmp@xmlify{\@pdfauthortitle}%
- \hyxmp@add@to@xml{%
-_________<photoshop:AuthorsPosition>\hyxmp@xmlified</photoshop:AuthorsPosition>^^J%
- }%
- \fi
- \ifx\@pdfcaptionwriter\@empty
- \else
- \hyxmp@xmlify{\@pdfcaptionwriter}%
- \hyxmp@add@to@xml{%
-_________<photoshop:CaptionWriter>\hyxmp@xmlified</photoshop:CaptionWriter>^^J%
- }%
- \fi
+ \hyxmp@add@simple{photoshop:AuthorsPosition}{\@pdfauthortitle}%
+ \hyxmp@add@simple{photoshop:CaptionWriter}{\@pdfcaptionwriter}%
\ifx\hyxmp@photoshop@data\@empty
\else
\hyxmp@add@to@xml{%
@@ -504,21 +657,32 @@ ______</rdf:Description>^^J%
}%
\fi
}
-\bgroup
-\catcode`\^^ef=12
-\catcode`\^^bb=12
-\catcode`\^^bf=12
-\gdef\hyxmp@construct@packet{%
+\begingroup
+ \ifhyxmp@unicodetex
+ \lccode`\!="FEFF %
+ \lowercase{%
+ \gdef\hyxmp@bom{!}
+ }%
+ \else
+ \catcode`\^^ef=12
+ \catcode`\^^bb=12
+ \catcode`\^^bf=12
+ \gdef\hyxmp@bom{^^ef^^bb^^bf}%
+ \fi
+\endgroup
+\def\hyxmp@construct@packet{%
\gdef\hyxmp@xml{}%
- \hyxmp@add@to@xml{%
-<?xpacket begin="^^ef^^bb^^bf" id="W5M0MpCehiHzreSzNTczkc9d"?>^^J%
+ \hyxmp@add@to@xml{<?xpacket begin="\hyxmp@bom" %
+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%
+___<rdf:RDF
+xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns\hyxmp@hash">^^J%
}%
\hyxmp@pdf@schema
\hyxmp@xmpRights@schema
\hyxmp@dc@schema
\hyxmp@photoshop@schema
+ \hyxmp@xmp@basic@schema
\hyxmp@mm@schema
\hyxmp@add@to@xml{%
___</rdf:RDF>^^J%
@@ -527,7 +691,6 @@ ___</rdf:RDF>^^J%
<?xpacket end="w"?>^^J%
}%
}
-\egroup
\newcommand*{\hyxmp@embed@packet}{%
\hyxmp@construct@packet
\def\hyxmp@driver{hpdftex}%
@@ -566,16 +729,20 @@ ___</rdf:RDF>^^J%
}
\newcommand*{\hyxmp@embed@packet@pdfmark}{%
\pdfmark{%
+ pdfmark=/NamespacePush
+ }%
+ \pdfmark{%
pdfmark=/OBJ,
Raw={/_objdef \string{hyxmp@Metadata\string} /type /stream}%
}%
\pdfmark{%
pdfmark=/PUT,
- Raw={\string{hyxmp@Metadata\string}%
- <<
- /Type /Metadata
- /Subtype /XML
- >>
+ Raw={\string{hyxmp@Metadata\string}
+ 2 dict begin
+ /Type /Metadata def
+ /Subtype /XML def
+ currentdict
+ end
}%
}%
\pdfmark{%
@@ -583,16 +750,11 @@ ___</rdf:RDF>^^J%
Raw={\string{hyxmp@Metadata\string} (\hyxmp@xml)}%
}%
\pdfmark{%
- pdfmark=/CLOSE,
- Raw={\string{hyxmp@Metadata\string}}%
+ pdfmark=/Metadata,
+ Raw={\string{Catalog\string} \string{hyxmp@Metadata\string}}%
}%
\pdfmark{%
- pdfmark=/Metadata,
- Raw={\string{Catalog\string}%
- <<
- /Metadata \string{hyxmp@Metadata\string}%
- >>
- }%
+ pdfmark=/NamespacePop
}%
}
\newcommand*{\hyxmp@embed@packet@dvipdfm}{%