4

I found out how to implement the Lua code for setting PDF metadata. I have failed.

My code:

\directlua0{
  pdf.setinfo ("Title", "Naked Cheerleaders on Crack")
  pdf.setinfo ("Creator", "LuaTeX")
  pdf.setinfo ("Subject", "Twentieth-Century European
    philosophy")
  pdf.setinfo ("Description", "myDescription")
  pdf.setinfo ("Publisher", "myPublisher")
  pdf.setinfo ("Contributor", "myContributor")
  pdf.setinfo ("Date", "2020-01-17")
  pdf.setinfo ("Type", "myType")
  pdf.setinfo ("Format", "myFormat")
  pdf.setinfo ("Identifier", "myIdentifier")
  pdf.setinfo ("Source", "mypdfsetinfo.tex")
  pdf.setinfo ("Language", "myLanguage")
  pdf.setinfo ("Rights", "myRights")
  pdf.setinfo ("Author", "Craig Parker-Feldmann")
  pdf.setinfo ("Keywords", "nudity, cheerleading, drugs,
    philosophy, seaweed")
}
The typeset output of this document is only
interesting because I have defined several metadata
fields in the PDF file.

Please note that I do not wish to use LuaLaTeX, but Plain TeX compiled with LuaTeX.


It seems to me that addressing the problem at the “\directlua” level offers me no advantages. I have changed my code to the following:

\pdfinfo {
  /Title (Naked Cheerleaders on Crack)
  %% /Title (Äther Ölpest Übelkeit bloß schräg blöd Tür)
  /Author (Craig Parker-Feldmann)
  /Subject (Twentieth-Century European philosophy)
  /Keywords (nudity cheerleading drugs philosophy seaweed)
  /JavaScript (no)
}
To profit from viewing this PDF document, you should view the “Properties” of the newly-created PDF file.

Revised Code

\directlua0{
  pdf.setinfo (
     table.concat (
        {
           "/Title (Naked Cheerleaders on Crack)",
           "/Author (William Faulkner)",
           "/Subject (Twentieth-Century European philosophy)",
           "/Keywords (nudity cheerleading drugs philosophy seaweed)"
        }, " "
     )
  )
}% End of \directlua
To profit from viewing this PDF document, you should view the “Properties” of the newly-created PDF file.

This code now functions the way I want it to function.

1
  • I have revised my code after investigating the suggestion made by @hmenke. It functions the way I want it to function. Dec 4, 2020 at 23:49

2 Answers 2

8

LuaTeX operated on a much lower level: pdf.setinfo does not take care of proper formatting, it is only a way to dump raw information into the PDF info dictionary. Also every use of setinfo overwrites all previous ones, so in you code all lines except for

pdf.setinfo ("Keywords", "nudity, cheerleading, drugs,
philosophy, seaweed")

are ignored. Here setinfo only takes a single argument and LuaTeX for some weird reason often uses the last arguments if you pass too many, so this is basically the same as

\directlua0{
  pdf.setinfo ("nudity, cheerleading, drugs,
    philosophy, seaweed")
}
The typeset output of this document is only
interesting because I have defined several metadata
fields in the PDF file.
\bye

This gets written into the PDF Info dictionary as-is:

<< nudity, cheerleading, drugs, philosophy, seaweed /Producer (LuaTeX-1.10.0) /Creator (TeX) /CreationDate (D:20200117203308+01'00') /ModDate (D:20200117203308+01'00') /Trapped /False /PTEX.FullBanner (This is LuaTeX, Version 1.10.0 (TeX Live 2019)) >>

Of course, this isn't valid PDF syntax.

Instead, you have to properly escape your values and get them into PDF dictionary syntax. E.g.

\directlua0{
  pdf.setinfo ("/Title (Some nice title) "
            .. "/Author (The fantastic author)")
}
Some text
\bye

Here, you might need additional code to escape special characters in PDF names (The words starting with /) and in PDF strings. After that, you additionally need to take care to use the right names. E.g. Date is not a standard field, you would probably want CreationDate and/or ModDate (Modification date) instead. Also e.g. the Language has to be set in the document catalog, not in the Info dictionary.

You can find all the details in the PDF specification, either the current one from ISO (for PDF 2.0) or you can find a "copy" of the old PDF 1.7 specs from Adobe (of course, the old spec is also still available from ISO).

3
  • Thank you for the information. It seems to me that addressing the problem at the “\directlua” level offers me no advantages. I have changed my code to the following: Jan 18, 2020 at 13:17
  • ``` tex \pdfinfo { /Title (Naked Cheerleaders on Crack) %% /Title (Äther Ölpest Übelkeit bloß schräg blöd Tür) /Author (Craig Parker-Feldmann) /Subject (Twentieth-Century European philosophy) /Keywords (nudity cheerleading drugs philosophy seaweed) /JavaScript (no) } To profit from viewing this PDF document, you should view the “Properties” of the newly-created PDF file. ``` Jan 18, 2020 at 13:18
  • 3
    I think it's more idiomatic to use a construction like pdf.setinfo (table.concat({"/Title (Some nice title)", "/Author (The fantastic author)"}, " ")) Jan 20, 2020 at 9:14
0

An alternative strategy is to use XMP to inject this information into the document. If you were using pdf(La)TeX, then you could do that using the package xmpincl, but since you're using Lua(La)TeX you can use the magic mentioned in the documentation of the minim-xmp package.

This, of course, requires that you generate the XMP file beforehand. That may be easy or it may be hard, depending on your context (the xmpincl package gives some boilerplate). The resulting metadata, in the PDF, does show up in Acrobat but not in other PDF readers such as macOS Preview.


For completeness, the magic minim-xmp mentions is:

\immediate\pdfextension obj uncompressed
    stream attr {/Type/Metadata /Subtype/XML}
    file {your-file.xmp}
\pdfextension catalog
    {/Metadata \pdffeedback lastobj 0 R}

You must log in to answer this question.

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