pdf-portfolio.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // List and extract embedded files in a PDF document.
  2. if (scriptArgs.length != 1 && scriptArgs.length != 3) {
  3. print("usage: mutool run pdf-portfolio.js input.pdf [index filename]");
  4. print(" List embedded files, or extract an embedded file from a PDF document.")
  5. quit();
  6. }
  7. var doc = Document.openDocument(scriptArgs[0]);
  8. var Root = doc.getTrailer().Root;
  9. if (Root.Names == undefined || !("EmbeddedFiles" in Root.Names)) {
  10. print("Document has no embedded files!");
  11. quit();
  12. }
  13. function mapNameTree(N, fn) {
  14. function mapNameTreeNames(NN) {
  15. var i, n = NN.length;
  16. for (i = 0; i < n; i += 2)
  17. fn(NN[i], NN[i+1]);
  18. }
  19. function mapNameTreeKids(NK) {
  20. var i, n = NK.length;
  21. for (i = 0; i < n; ++i)
  22. mapNameTree(NK[i], fn)
  23. }
  24. if ("Names" in N)
  25. mapNameTreeNames(N.Names);
  26. if ("Kids" in N)
  27. mapNameTreeKids(N.Kids);
  28. }
  29. function fileNameFromFS(fs) {
  30. if ("UF" in fs) return fs.UF.asString();
  31. if ("F" in fs) return fs.F.asString();
  32. if ("Unix" in fs) return fs.Unix.asString();
  33. if ("DOS" in fs) return fs.DOS.asString();
  34. if ("Mac" in fs) return fs.Mac.asString();
  35. return "Untitled";
  36. }
  37. if (scriptArgs.length == 1) {
  38. var idx = 1;
  39. mapNameTree(Root.Names.EmbeddedFiles, function (name,fs) {
  40. print(idx, name.asString());
  41. print("\tFilename:", fileNameFromFS(fs));
  42. if ("Desc" in fs)
  43. print("\tDescription:", fs.Desc.asString());
  44. ++idx;
  45. });
  46. }
  47. if (scriptArgs.length == 3) {
  48. var idx = 1;
  49. mapNameTree(Root.Names.EmbeddedFiles, function (name,fs) {
  50. if (idx == scriptArgs[1]) {
  51. print("Saving embedded file", idx, "as:", scriptArgs[2]);
  52. fs.EF.F.readStream().save(scriptArgs[2]);
  53. }
  54. ++idx;
  55. });
  56. }