Copy link to clipboard
Copied
I'm trying to included a pdf's keywords in a dynamic stamp, and it just won't work.
Here is my code for that form field:
event.value=event.source.source.info.keywords;
I'm using the following to insert the file name into the stamp, and it works fine:
event.value = event.source.source.documentFileName;
Anyone have any insight?
Thanks, N
Copy link to clipboard
Copied
In the doc it is Keywords, not keywords.
Copy link to clipboard
Copied
Unfortunately I tried "Keywords" as well. No luck.
Really, how freakin hard does it have to be to get keywords to display on a pdf?!
Copy link to clipboard
Copied
Just tried it with the code above (using Keywords) and it works just fine.
Copy link to clipboard
Copied
Are these keywords accessible from doc.info.Keywords in other places (such as the JavaScript console)?
Copy link to clipboard
Copied
app.doc.info.Author returns the correct object.
app.doc.info.Keywords no go.
Copy link to clipboard
Copied
Can you share the file in question with us?
Also, what version of Acrobat are you using, and on what OS?
Copy link to clipboard
Copied
Win 10.
Acrobat Pro DC 2021.001.20145
I'll post the stamp file and one of the (50) pdf's with keywords I'm trying to stamp.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
JSON.stringify(app.doc.info.Title);
...returns [document title]
JSON.stringify(app.doc.info.Keywords);
... returns ""
Copy link to clipboard
Copied
Ok, so you have shown this is not a problem with stamps, but with document.info.Keywords for this file. Thank you for sharing the file. I have now examined the file. The result is by design, but not necessarily as anyone would expect.
1. A PDF can contain document level metadata in two places
- the Info dictionary (old fashioned; banned in PDF 2.0)
- the embedded XMP packet (modern)
An app can set either or both; unless it is PDF 2.0 compatbible it should probably set both, and Acrobat does this. Your keyword-adding app only sets keywords in the XML packet, while it sets Title in both places.
2. The Properties dialog looks in both places for its general values. It can also be used to view the XMP directly.
3. The document.info method shows ONLY what is in the Info dictionary (and is documented to do this).
4. To fully emulate the Properties dialog you need to use both document.info and document.metadata.
5. Getting info from the XMP is not nearly so simple as the Info dictionary!
Copy link to clipboard
Copied
Originally, there was no XML metadata in a PDF, the keywords were just a list of words. I've noticed that access and synchronization between the info and metadata for the keywords has changed over time. It's kinda confusing. But the metadata is the real location and it looks like Adobe has decided to just break the connect to the info object.
There is an example of manipulating the metadata in the Acrobat JS reference.
The metadata is complex and uses a lot of namespaces, but getting to the info data isn't so bad. Here's some code that will return the keywords:
// Parse the XML metadata
xx = new XML(this.metadata)
// We only need two namespaces to get to the info data.
var myrdf = new Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
var mydc = new Namespace("http://purl.org/dc/elements/1.1/");
var oXMLKeywords = xx.myrdf::RDF.myrdf::Description.mydc::subject.myrdf::Bag.myrdf::li
// Convert XML list of keywords into JS array
var aKeyWords = [];
for(y in oXMLKeywords)
aKeyWords.push(oXMLKeywords[y]);
var strKeywords = aKeyWords.join(",")
Copy link to clipboard
Copied
Yep, not very happy about having to parse XML for this.
Copy link to clipboard
Copied
Thanks so much, Thom!
Here is my (your!) final stamp code:
//keyword stamp script (thanks to Thom Parker- PDFScripting)
xx = new XML(event.source.source.metadata);
// We only need two namespaces to get to the info data.
var myrdf = new Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
var mydc = new Namespace("http://purl.org/dc/elements/1.1/");
var oXMLKeywords = xx.myrdf::RDF.myrdf::Description.mydc::subject.myrdf::Bag.myrdf::li;
var aKeyWords = [];
for(y in oXMLKeywords)
aKeyWords.push(oXMLKeywords[y]);
var strKeywords = aKeyWords.join("\n");
event.value = strKeywords;