63 lines
1.6 KiB
JavaScript
63 lines
1.6 KiB
JavaScript
|
// List and extract embedded files in a PDF document.
|
||
|
|
||
|
if (scriptArgs.length != 1 && scriptArgs.length != 3) {
|
||
|
print("usage: mutool run pdf-portfolio.js input.pdf [index filename]");
|
||
|
print(" List embedded files, or extract an embedded file from a PDF document.")
|
||
|
quit();
|
||
|
}
|
||
|
|
||
|
var doc = new PDFDocument(scriptArgs[0]);
|
||
|
var Root = doc.getTrailer().Root
|
||
|
if (!("EmbeddedFiles" in Root.Names)) {
|
||
|
print("Document has no embedded files!");
|
||
|
quit();
|
||
|
}
|
||
|
|
||
|
function mapNameTree(N, fn) {
|
||
|
function mapNameTreeNames(NN) {
|
||
|
var i, n = NN.length;
|
||
|
for (i = 0; i < n; i += 2)
|
||
|
fn(NN[i], NN[i+1]);
|
||
|
}
|
||
|
function mapNameTreeKids(NK) {
|
||
|
var i, n = NK.length;
|
||
|
for (i = 0; i < n; ++i)
|
||
|
mapNameTree(NK[i], fn)
|
||
|
}
|
||
|
if ("Names" in N)
|
||
|
mapNameTreeNames(N.Names);
|
||
|
if ("Kids" in N)
|
||
|
mapNameTreeKids(N.Kids);
|
||
|
}
|
||
|
|
||
|
function fileNameFromFS(fs) {
|
||
|
if ("UF" in fs) return fs.UF.asString();
|
||
|
if ("F" in fs) return fs.F.asString();
|
||
|
if ("Unix" in fs) return fs.Unix.asString();
|
||
|
if ("DOS" in fs) return fs.DOS.asString();
|
||
|
if ("Mac" in fs) return fs.Mac.asString();
|
||
|
return "Untitled";
|
||
|
}
|
||
|
|
||
|
if (scriptArgs.length == 1) {
|
||
|
var idx = 1;
|
||
|
mapNameTree(Root.Names.EmbeddedFiles, function (name,fs) {
|
||
|
print(idx, name.asString());
|
||
|
print("\tFilename:", fileNameFromFS(fs));
|
||
|
if ("Desc" in fs)
|
||
|
print("\tDescription:", fs.Desc.asString());
|
||
|
++idx;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (scriptArgs.length == 3) {
|
||
|
var idx = 1;
|
||
|
mapNameTree(Root.Names.EmbeddedFiles, function (name,fs) {
|
||
|
if (idx == scriptArgs[1]) {
|
||
|
print("Saving embedded file", idx, "as:", scriptArgs[2]);
|
||
|
fs.EF.F.readStream().save(scriptArgs[2]);
|
||
|
}
|
||
|
++idx;
|
||
|
});
|
||
|
}
|