3

I am trying to use the xmpincl package to include the Creative Commons licensing information of a paper into the pdf in a machine-readable way. In the past, this has worked just fine, but for the current document it is tripping up with a unicode character in one of the author names.

Specifically, the XMP file generated by the creativecommons website contains the attribution name

<cc:attributionName>Rodrigo Gutiérrez-Cuevas and Emilio Pisanty</cc:attributionName>

and xmpincl+pdflatex doesn't complain during compilation, but if I actually look at the metadata in the file (using exiftool, or just examining the pdf in a text editor), the accented é is completely garbled:

Attribution Name: Rodrigo Guti\unhbox \voidb@x \bgroup \let \unhbox \voidb@x \setbox 
                  \@tempboxa \hbox {e\global \mathchardef \accent@spacefactor 
                  \spacefactor }\let \begingroup \endgroup \relax \let \ignorespaces 
                  \relax \accent 19 e\egroup \spacefactor \accent@spacefactor rrez-Cuevas 
                  and Emilio Pisanty

Is there a way to include unicode characters in XMP metadata, either with xmpincl or otherwise?

(If not, then this is a massive problem. Systems that can only handle author names in ascii are, to put it bluntly, discriminatory.)


Edit: Here's a MWE:

\documentclass[pra]{revtex4-2}

\usepackage{xmpincl}
\includexmp{metadata}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}

\begin{document}
\title{MWE}
\author{Rodrigo Guti\'{e}rrez-Cuevas}
\author{Emilio Pisanty}
\begin{abstract}
Test.
\end{abstract}
\maketitle
Test.
\end{document}

with the file metadata.xmp reading

<?xpacket begin='' id=''?>
<x:xmpmeta xmlns:x='adobe:ns:meta/'>
  <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
    <rdf:Description rdf:about=''
      xmlns:cc='http://creativecommons.org/ns#'>
      <cc:attributionName>Rodrigo Gutiérrez-Cuevas and Emilio Pisanty</cc:attributionName>
    </rdf:Description>
  </rdf:RDF>
</x:xmpmeta>
<?xpacket end='r'?>

I left the hyperref and inputenc/fontenc packages just because they are in my original document, but they don't affect the output.

3
  • Try with \usepackage[T1]{fontenc}, and if this doesn't help make a complete example. Mar 18, 2021 at 17:55
  • @UlrikeFischer it's already loaded, but I'll make a MWE shortly.
    – E.P.
    Mar 18, 2021 at 18:12
  • did you try the hyperxmp package? Mar 18, 2021 at 18:53

1 Answer 1

3

The xmpincl package does \immediate\write\xmpinclWrite{\mcs@xmpinclStart} and similar errors.

Why is this wrong? Because the macro \mcs@xmpinclStart is expanded all the way.

If I change the code to add

\newcommand\xmpincl@write[2]{\immediate\write#1{\unexpanded\expandafter{#2}}}

and then replace all occurrences of \immediate\write with \xmpincl@write, the .xmpi file that results is

<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> 
<x:xmpmeta xmlns:x='adobe:ns:meta/'> 
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'> 
<rdf:Description rdf:about='' 
xmlns:cc='http://creativecommons.org/ns#'> 
<cc:attributionName>Rodrigo Gutiérrez-Cuevas and Emilio Pisanty</cc:attributionName> 
</rdf:Description> 
</rdf:RDF> 
</x:xmpmeta> 
<?xpacket end='r'?> 

This is the modified copy of xmpincl.sty. I also removed a few \immediate that do nothing at all. There are several unprotected endlines, but they should not be a problem.

%%
%% This is file `xmpincl.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% xmpincl.dtx  (with options: `package')
%% 
%% This is a generated file.
%% 
%% Copyright (C) 2005 by Maarten Sneep <[email protected]>
%% 
%% This work is licensed under the CC-GNU GPL, the human readable license
%% can be found here, with a link to the full text on this page.
%% http://creativecommons.org/licenses/GPL/2.0/
%% 
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{xmpincl}
    [2008/05/10 v2.2 Include XMP data in pdflatex -- modified by egreg]
\RequirePackage{ifpdf}
\ifpdf\else
\PackageWarningNoLine{xmpincl}%
  {Only pdflatex is supported by the xmpincl package}
\newcommand{\includexmp}[1]{%
  \PackageError{xmpincl}%
  {latex is not supported by the \protect\includexmp\space package}%
  {You tried to include XMP metadata in DVI production.\MessageBreak
   That doesn't work, and I friendly tried to warn you.\MessageBreak
   Just continue and pretend nothing is wrong,\MessageBreak
   but please remove the package or switch to pdflatex.}
}
\relax\expandafter\endinput
\fi
\RequirePackage{ifthen}
\newcommand\xmpincl@write[2]{\immediate\write#1{\unexpanded\expandafter{#2}}}%<-- added
\newcommand*{\mcs@xmpincl@patchFile}[1]{
\begingroup
\newwrite\xmpinclWrite
\newread\xmpinclRead
\openin\xmpinclRead #1.xmp
\immediate\openout\xmpinclWrite #1.xmpi
\newcommand{\mcs@xmpinclStart}%
  {<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> }
\newcommand{\mcs@xmpinclStartAlt}%
  {<?xpacket begin='' id=''?> }
\newcommand{\mcs@xmpinclEnd}%
  {<?xpacket end='r'?> }
\catcode`\#=12
\catcode`\~=12
\catcode`\&=12
\read\xmpinclRead to\xmpinclReadln%
\ifthenelse{%
  \equal{\mcs@xmpinclStart}{\xmpinclReadln}%
  \or%
  \equal{\mcs@xmpinclStartAlt}{\xmpinclReadln}%
}%
{%
  \xmpincl@write\xmpinclWrite{\mcs@xmpinclStart}%<--- modified
}%
{%
  \xmpincl@write\xmpinclWrite{\mcs@xmpinclStart}%<--- modified
  \xmpincl@write\xmpinclWrite{\xmpinclReadln}%<--- modified
}%
\loop%
  \read\xmpinclRead to\xmpinclReadln%
  \ifthenelse{%
    \equal{\mcs@xmpinclEnd}{\xmpinclReadln}%
    }{% Note: no if.
    }{%
    \if\par\xmpinclReadln\else%
      \xmpincl@write\xmpinclWrite{\xmpinclReadln}%<--- modified
    \fi%
  }%
  \ifeof\xmpinclRead\else%
\repeat
\xmpincl@write\xmpinclWrite{\mcs@xmpinclEnd}%<--- modified
\closein\xmpinclRead
\immediate\closeout\xmpinclWrite
\endgroup
}
\newcommand{\includexmp}[1]{%
  \IfFileExists{#1.xmp}{
    \mcs@xmpincl@patchFile{#1}
    \begingroup
      \pdfcompresslevel=0
      \immediate\pdfobj stream attr {/Type /Metadata /Subtype /XML}
      file{#1.xmpi}
      \pdfcatalog{/Metadata \the\pdflastobj\space 0 R}
    \endgroup
  }
  {\newcommand{\mcs@xmpincl@filename}{#1.xmp}
    \PackageError{xmpincl}%
    {The file \mcs@xmpincl@filename\space was not found}
    {The file \mcs@xmpincl@filename\space The metadata file
     wasn't found.\MessageBreak Oops.}
  }
}
\endinput
%%
%% End of file `xmpincl.sty'.

An expl3 version of xmpincl follows. Beware that PDF internal experts warn that this is incompatible with hyperxmp and pdfx. The problem is how the catalog entry is added, because other package might try to add /Metadata and the combination would fail miserably.

\NeedsTeXFormat{LaTeX2e}[2020/10/01]
\ProvidesPackage{xmpincl3}
    [2021/03/19 v0.1 Include XMP data in pdflatex]

\RequirePackage{expl3}

\ExplSyntaxOn

\msg_new:nnn { xmpincl3 } { not-pdf } {Only~pdf~mode~is~supported~by~the~xmpincl3~package}

\msg_new:nnnn { xmpincl3 } { not-pdf-error }
 { DVI~mode~is~not~supported~by~the~xmpincl3~package }
 {
   You~tried~to~include~XMP~metadata~in~DVI~production.^^J
   That~doesn't~work,~and~I~friendly~tried~to~warn~you.^^J
   Just~continue~and~pretend~nothing~is~wrong,^^J
   but~please~remove~the~package~or~switch~to~pdflatex.
 }

\msg_new:nnnn { xmpincl3 } { file-not-found }
 { The~file~#1~was~not~found }
 { The~metadata~file~#1~wasn't~found.^^J Oops. }

\sys_if_output_pdf:F
 {
  \msg_warning:nn { xmpincl3 } { not-pdf }
  \NewDocumentCommand{\includexmp}{m}{ \msg_error:nn { xmpincl3 } { not-pdf-error } }
 }
\sys_if_output_pdf:F { \endinput }

\ior_new:N \g__xmpincl_input_ior
\iow_new:N \g__xmpincl_output_iow
\str_const:Nn \c__xmpincl_start_str { <?xpacket~begin=''~id='W5M0MpCehiHzreSzNTczkc9d'?> }
\str_const:Nn \c__xmpincl_alt_str { <?xpacket~begin=''~id=''?> }
\str_const:Nn \c__xmpincl_end_str  { <?xpacket~end='r'?> }
\str_new:N \l__xmpincl_first_str

\cs_new_protected:Nn \__xmpincl_writeline:n
 {
  \iow_now:Nn \g__xmpincl_output_iow { #1 }
 }
\cs_generate_variant:Nn \__xmpincl_writeline:n { V }

\cs_new_protected:Nn \__xmpincl_patch:n
 {
  \ior_open:Nn \g__xmpincl_input_ior { #1.xmp }
  \iow_open:Nn \g__xmpincl_output_iow { #1.xmpi }
  \ior_str_get:NN \g__xmpincl_input_ior \l__xmpincl_first_str
  \bool_lazy_or:nnTF
   { \str_if_eq_p:NN \c__xmpincl_start_str \l__xmpincl_first_str }
   { \str_if_eq_p:NN \c__xmpincl_alt_str \l__xmpincl_first_str }
   { \__xmpincl_writeline:V \c__xmpincl_start_str }
   {
    \__xmpincl_writeline:V \l__xmpincl_first_str
   }
  \ior_str_map_inline:Nn \g__xmpincl_input_ior
   {
    \str_if_eq:VnTF \c__xmpincl_end_str { ##1 }
     {
      \ior_map_break:
     }
     {
      \str_if_eq:nnF { ##1 } { } { \__xmpincl_writeline:n { ##1 } }
     }
   }
  \__xmpincl_writeline:V \c__xmpincl_end_str
  \iow_close:N \g__xmpincl_output_iow
  \ior_close:N \g__xmpincl_input_ior
 }

\NewDocumentCommand{\includexmp}{m}
 {
  \file_if_exist:nTF {#1.xmp}
   {
    \__xmpincl_patch:n { #1 }
    \pdf_object_unnamed_write:nx{fstream}{{/Type~/Metadata~/Subtype~/XML}{#1.xmpi}}
    \pdfcatalog{/Metadata~\the\pdflastobj\space 0~R}
  }
  {
   \msg_error:nnn { xmpincl } { file-not-found } { #1 }
  }
 }
\endinput

It's essentially a straight copy of xmpincl.sty, with no issues about special characters, because the file lines are examined as “strings”.

5
  • I can't get this to compile correctly. Would you be able to share the modified copy of the package file?
    – E.P.
    Mar 18, 2021 at 21:10
  • @E.P. I included the modified .sty file.
    – egreg
    Mar 18, 2021 at 21:53
  • Many thanks. This fully solves the problem on my document.
    – E.P.
    Mar 19, 2021 at 14:16
  • Presumably this should be incorporated into the package as an update? I have contacted the listed maintainer, though given the age of the package he might not be that interested / able to update it.
    – E.P.
    Mar 19, 2021 at 14:16
  • @E.P. I'm not really sure what the package really does. It simply changes <?xpacket begin='' id=''?> into <?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> and removes leading white space and empty lines. Then it adds the xmp file so modified to the PDF file as a PDF object. As far as I can see, the id string is as arbitrary as any you can think to.
    – egreg
    Mar 19, 2021 at 14:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .