ExtendScript to loop through directory and save fm files as pdf
I have 600+ fm files that I want to save as a pdf. They are all in the same directory. This is the script I started with (though I currently have Frankencode doing other stuff that was added between me and things suggested by Claudet/Gemini/etc).
#target framemaker
(function () {
// --- CONFIG ---
var PDF_SETTINGS_NAME = "";
// Leave empty "" to use the document's default PDF settings
// Or put the name of a PDF setup, e.g. "High Quality Print"
// ----------------
function log(msg) {
$.writeln(msg);
var oFile = new File ("C:/Catalog/output/run.log" );
oFile.open("a");
oFile.writeln(msg);
oFile.close();
}
function saveAsPdf(doc, savePath) {
// Get default save parameters
var params = GetSaveDefaultParams();
var i;
// Set the file type to PDF
i = GetPropIndex(params, Constants.FS_FileType);
params[i].propVal.ival = Constants.FV_SaveFmtPdf;
// Optional: Configure other PDF settings if needed
// Example: Set to not use Distiller (rely on modern internal PDF generation)
i = GetPropIndex(params, Constants.FS_PDFUseDistiller);
if (i > -1) {
params[i].propVal.ival = 0; // 0 for false, 1 for true
}
// Call the Save function
// FA_errno is a global variable that will contain the error code after the call
FA_errno = 0;
var returnParams = new PropVals();
// Check if the input is a book or a document to use the correct function
if (doc.Type === Constants.FA_Book) {
doc.Save(savePath, params, returnParams);
} else {
// For a single document, use F_ApiSave (often accessed via the document object in modern ExtendScript)
// Note: Direct doc.Save(path, params, returnParams) works for documents too in many cases.
// The Book object has a specific method signature in some versions.
doc.Save(savePath, params, returnParams);
}
if (FA_errno !== 0) {
log("Failed to save PDF. Error code: " + FA_errno);
} else {
log("PDF saved successfully to: " + savePath);
}
}
var runFile = new File("C:/Catalog/output/run.go");
if (!runFile.exists) {
$.writeln("run.go file does not exist. Exiting.");
return;
}
var folder = new Folder("C:/Catalog/output");
var files = folder.getFiles(function (f) {
return f instanceof File && /\.fm$/i.test(f.name);
});
if (files.length === 0) {
log("No .fm files found.");
app.Close(Constants.FF_CLOSE_MODIFIED);
}
log("Found " + files.length + " file(s).");
for (var i = 0; i < files.length; i++) {
var file = files[i];
log("Processing: " + file.name);
var doc = null;
try {
doc = SimpleOpen(file.fsName, false);
var pdfPath = file.fsName.replace(/\.fm$/i, ".pdf");
if (saveAsPdf(doc, pdfPath)) {
log(" PDF created: " + pdfPath);
}
} catch (e) {
log(" ERROR opening file: " + e);
} finally {
if (doc) {
try {
// Close without saving changes
doc.Close(Constants.FF_CLOSE_MODIFIED);
} catch (closeErr) {
log(" ERROR closing file: " + closeErr);
}
}
}
}
log("Batch PDF export complete.");
app.Close(Constants.FF_CLOSE_MODIFIED);
})();
I get timeout errors at random places. It will handle anywhere between 2-7 files, then give me a timeout error. I have the script in the startup folder so that I can place a file in the output folder, open FM, and then let it go to work. I'd also like to move the fm files to an archive folder once it's done.
Can someone give me a push in the right direction? I also don't really know if the SaveAsPdf function is what it should be, I'd be surprised if it was.