This command offers @tbone 's great PDFToolkit Menu functionality as an internal command so it is easily accessible from everywhere (eg a context menu for a pdf file type group).
As the original menu it expects the /pdftoolkit
folder alias pointing to the PDF toolkit root path (the one containing the /bin
folder).
Parameters
The following commands are available (but just one at a time). For the sake of simplicity I did not (yet?) add further parameters thus the values for filenames, page ragens... are entered via dialogs (just like in the original menu buttons code).
- PDFTK APPENDFROMDEST/S
- PDFTK EXTRACT/K[all,even,odd,range]
- PDFTK MERGE/S
- PDFTK MERGEODDEVEN/S
- PDFTK ROTATE/K[left,right,reverse,llrr,rrll]
- PDFTK SPLIT/S
- PDFTK PROTECT/S
- PDFTK UNPROTECT/S
- PDFTK COMPRESS/S
Installation / Downloads
How to install https://resource.dopus.com/t/how-to-use-buttons-and-scripts-from-this-forum/3546/3.
- v1.0 (2022.03.11) Inital version
Command.File.PDFtk.js.txt (11.1 KB)
// Command.File.PDFtk
// (c) 2022 Felix
// Based on tbone's great PDF Toolkit Menu
// https://resource.dopus.com/t/pdf-toolkit-menu-pdf-merge-extract-protect-unprotect-organize/22348
// This is a script for Directory Opus.
// See https://www.gpsoft.com.au/DScripts/redirect.asp?page=scripts for development information.
// Called by Directory Opus to initialize the script
function OnInit(initData)
{
initData.name = "Command.File.PDFtk";
initData.version = "1.0 (2022.03.11)";
initData.copyright = "(c) 2022 Felix";
initData.url = "https://resource.dopus.com/t/command-file-pdftk-a-wrapper-for-pdftk-as-an-internal-command/40771";
initData.desc = "Wrapper for PDF Toolkit as internal command";
initData.default_enable = true;
initData.min_version = "12.0";
initData.group = "Column";
var cmd = initData.AddCommand();
cmd.name = "PDFTK";
cmd.method = "OnPDFTK";
cmd.desc = "Wrapper for PDF Toolkit as internal command";
cmd.label = "PDFTK";
cmd.template = "APPENDFROMDEST/S,EXTRACT/K[all,even,odd,range],MERGE/S,MERGEODDEVEN/S,ROTATE/K[left,right,reverse,llrr,rrll],SPLIT/S,PROTECT/S,UNPROTECT/S,COMPRESS/S";
cmd.hide = false;
cmd.icon = "rename2";
}
var PDFtkBinaryPath = null;
// Implement the PDFTK command
function OnPDFTK(scriptCmdData)
{
PDFtkBinaryPath = "\"" + DOpus.FSUtil.Resolve('/pdftoolkit\\bin\\pdftk.exe') + "\"";
if(!PDFtkBinaryPath)
{
Log("Pdftk binary path not found", true);
return;
}
var args = scriptCmdData.func.args;
if(args.got_arg.MERGE)
Merge(scriptCmdData);
else if(args.got_arg.SPLIT)
Split(scriptCmdData);
else if(args.got_arg.ROTATE)
Rotate(scriptCmdData, args.ROTATE.toLowerCase());
else if(args.got_arg.EXTRACT)
Extract(scriptCmdData, args.EXTRACT.toLowerCase());
else if(args.got_arg.PROTECT)
Protect(scriptCmdData);
else if(args.got_arg.UNPROTECT)
Unprotect(scriptCmdData);
else if(args.got_arg.COMPRESS)
Compress(scriptCmdData);
else if(args.got_arg.APPENDFROMDEST)
AppendFromDest(scriptCmdData);
}
function Merge(data)
{
var dlg = DOpus.Dlg;
var tab = data.func.sourcetab;
var selFiles = tab.selected_files;
var cmd = data.func.command;
cmd.deselect = false; cmd.SetModifier('runmode', 'hide');
var shell = new ActiveXObject("WScript.Shell");
if (selFiles.count<2)
return;
var input = dlg.GetString("Enter new *basename* for merged PDF file (will be overwritten if exists):", selFiles(0).name_stem+"_merged", 255,
"Ok|Cancel", "Merge PDF", data.func.sourcetab.lister);
if (!input)
return;
var path = (selFiles(0).path+"").replace('(\/|\\\\)$', "");
//var pdftkPath = DOpus.FSUtil.Resolve('/pdftoolkit\\bin\\pdftk.exe');
var pdfFilePaths = PrepItems(selFiles, "realpath").join(" ");
cmd.RunCommand('"'+PDFtkBinaryPath+'" '+pdfFilePaths+' cat output "'+path+'\\'+input+'.pdf"');
var mergeTextFiles = true;
var textFilePaths = PrepItems(selFiles, "realpath", "", "", false);
for(var i=0;i<textFilePaths.length;i++)
{
textFilePaths[i] = textFilePaths[i].replace(new RegExp("\.pdf$","i"),".txt");
if (!DOpus.FSUtil.Exists(textFilePaths[i]))
{
mergeTextFiles = false;
break;
}
textFilePaths[i] = "'"+textFilePaths[i]+"'";
Log(textFilePaths[i]);
}
var cmdLine = "powershell.exe -noexit -executionpolicy bypass -command \"&{$f = @("+textFilePaths.join(",")+"); $dest='"+path+"\\"+input+".txt'; $v='';"+
"for($i=0;$i -lt $f.count;$i++) {$v+=gc -lit $f[$i] -en utf8 -raw;$v+=[char]13+[char]10;} sc -lit $dest -val $v -enc utf8;}\"";
if (mergeTextFiles) shell.Run(cmdLine, 0, true);
else DOpus.Output("Skipping merge of txt sidecar files (no full set found).");
}
function MergeOddEven(data)
{
var cmd = data.func.command, dlg = DOpus.Dlg, tab = data.func.sourcetab, selFiles = tab.selected_files;
cmd.SetModifier('runmode','hide');
cmd.deselect = false;
var input = dlg.GetString( "Enter name of new odd/even merged file:", selFiles(0).name_stem+'_oddeven.pdf', 255,
"Ok|Cancel", "Merge odd/even", data.func.sourcetab.lister);
var filePath1 = selFiles(0).realpath;
var baseName1 = selFiles(0).name_stem;
var filePath2 = selFiles(1).realpath;
var baseName2 = selFiles(1).name_stem;
var path = (selFiles(0).path+"").replace('(\/|\\\\)$', '');
//var pdftkPath = DOpus.FSUtil.Resolve('/pdftoolkit\\bin\\pdftk.exe');
cmd.RunCommand('"'+PDFtkBinaryPath+'" A="'+filePath1+'" B="'+filePath2+'" shuffle A B output "'+path+'\\'+input+'"');
}
function Split(data){
var cmd = data.func.command, dlg = DOpus.Dlg, tab = data.func.sourcetab, selFiles = tab.selected_files;
cmd.SetModifier('runmode','hide');
cmd.deselect = false;
var input = dlg.GetString( "Enter number of first page to be separated:", "2", 3,
"Ok|Cancel", "Split PDF", data.func.sourcetab.lister);
if (!input || input*1<2) return;
var filePath = selFiles(0).realpath;
var baseName = selFiles(0).name_stem;
var path = (selFiles(0).path+"").replace('(\/|\\\\)$', '');
//var pdftkPath = DOpus.FSUtil.Resolve('/pdftoolkit\\bin\\pdftk.exe');
cmd.RunCommand('"'+PDFtkBinaryPath+'" "'+filePath+'" cat 1-'+(input-1)+' output "'+path+'\\'+baseName+'_1-'+(input-1)+'.pdf"');
cmd.RunCommand('"'+PDFtkBinaryPath+'" "'+filePath+'" cat '+(input)+'-end output "'+path+'\\'+baseName+'_'+(input)+'-end.pdf"');
}
function Rotate(data, param)
{
var cmd = data.func.command;
cmd.SetModifier('runmode','hide');
cmd.deselect = false;
cmd.SetType("msdos");
if(param == "left")
cmd.RunCommand(PDFtkBinaryPath + " {file$} rotate 1-endleft output {file|noext}_(-90°).pdf");
else if(param == "right")
cmd.RunCommand(PDFtkBinaryPath + " {file$} rotate 1-endright output {file|noext}_(+90°).pdf");
else if(param == "reverse")
cmd.RunCommand(PDFtkBinaryPath + " {filepath$} cat 1-enddown output {filepath|noext}_(+180°).pdf");
else if(param == "llrr")
RotateScanned(data, "left");
else if(param == "rrll")
RotateScanned(data, "right");
}
function RotateScanned(data, rotDirection)
{
var cmd = data.func.command, dlg = DOpus.Dlg, tab = data.func.sourcetab, selFiles = tab.selected_files;
cmd.deselect = false; cmd.SetModifier('runmode', 'hide'); var shell = new ActiveXObject("WScript.Shell");
if (selFiles.count<2 || selFiles.count%2 != 0){
Log("Bad number of selected files, need even number and more than 1.", true);
return;
}
var input = dlg.GetString("Enter new *basename* for renamed PDF files (will be overwritten if exists):", "book_pages", 255,
"Ok|Cancel", "Rename PDFs", data.func.sourcetab.lister);
if (!input) return;
var path = (selFiles(0).path+"").replace('(\/|\\\\)$', "");
//var pdftkPath = DOpus.FSUtil.Resolve('/pdftoolkit\\bin\\pdftk.exe');
var pageCount = selFiles.count;
var indexOdd = pageCount;
var indexEven = 1;
//var rotDirection = "left";
for(var i=0;i<pageCount;i+=2)
{
RunWS('"'+PDFtkBinaryPath+'" "'+selFiles(i).realpath+'" rotate 1-end'+rotDirection+' output "'+selFiles(i).realpath+'.tmp.pdf"');
RunDO('Rename "'+selFiles(i).name+'.tmp.pdf" TO="'+input+Pad(indexOdd,"0")+'.pdf"'); indexOdd--;
RunWS('"'+PDFtkBinaryPath+'" "'+selFiles(i+1).realpath+'" rotate 1-end'+rotDirection+' output "'+selFiles(i+1).realpath+'.tmp.pdf"');
RunDO('Rename "'+selFiles(i+1).name+'.tmp.pdf" TO="'+input+Pad(indexEven,"0")+'.pdf"'); indexEven++;
rotDirection = rotDirection == "right" ? "left" : "right";
}
}
function Extract(data, param)
{
var cmd = data.func.command;
cmd.SetModifier('runmode','hide');
cmd.deselect = false;
cmd.SetType("msdos");
cmd.AddLine("@firstfileonly");
if(param == "all")
{
cmd.AddLine(PDFtkBinaryPath + " {file} burst output {file|noext}_%%03d.pdf");
cmd.Run();
}
else if(param == "even")
{
cmd.AddLine("@set fileMod={dlgstringS|Enter name for PDF containing even pages only:\n(will be overwritten if exists)|{file$|noext}_even.pdf}");
cmd.AddLine(PDFtkBinaryPath + " {file$} cat 1-endeven output \"{$fileMod}\" dont_ask");
cmd.Run();
}
else if(param == "odd")
{
cmd.AddLine("@set fileMod={dlgstringS|Enter name for PDF containing odd pages only:\n(will be overwritten if exists)|{file$|noext}_odd.pdf}");
cmd.AddLine(PDFtkBinaryPath + " {file$} cat 1-endodd output \"{$fileMod}\" dont_ask");
cmd.Run();
}
else if(param == "range")
{
cmd.AddLine("@set fileMod={dlgstringS|Enter name for new modified PDF file:\n(will be overwritten if exists)|{file$|noext}_modified.pdf}");
cmd.AddLine("@set pages={dlgstringS|Enter pages to keep (example: 1 6-8 2-3 10-end):}");
cmd.AddLine(PDFtkBinaryPath + " {file$} cat {$pages} output \"{$fileMod}\" dont_ask");
cmd.Run();
}
}
function Protect(data)
{
var cmd = data.func.command;
cmd.SetModifier('runmode','hide');
cmd.deselect = false;
cmd.SetType("msdos");
cmd.AddLine("@set pass={dlgstring|Enter new password to protect PDF file:\n(will create \"{file$|noext}_protected.pdf\")}");
cmd.AddLine(PDFtkBinaryPath + " {file} output {file|noext}_protected.pdf user_pw \"{$pass}\" dont_ask");
cmd.Run();
}
function Unprotect(data)
{
var cmd = data.func.command;
cmd.SetModifier('runmode','hide');
cmd.deselect = false;
cmd.SetType("msdos");
cmd.AddLine("@set pass={dlgstring|Enter password to unprotect PDF file:\n(will create \"{file$|noext}_unprotected.pdf\")}");
cmd.AddLine(PDFtkBinaryPath + " {file} input_pw \"{$pass}\" output {file|noext}_unprotected.pdf dont_ask");
cmd.Run();
}
function Compress(data)
{
var cmd = data.func.command;
cmd.SetModifier('runmode','hide');
cmd.deselect = false;
cmd.SetType("msdos");
cmd.AddLine("@set fileComp={dlgstringS|Enter *basename* for compressed PDF file (will be overwritten if exists)|{file$|noext}_compressed}");
cmd.AddLine(PDFtkBinaryPath + " {filepath$} output \"{$fileComp}.pdf\" compress");
cmd.Run();
}
function AppendFromDest(data)
{
var cmd = data.func.command;
cmd.SetModifier('runmode','hide');
cmd.deselect = false;
cmd.SetType("msdos");
cmd.AddLine("@set fileAppended={dlgstringS|Enter name for appended PDF file (will be overwritten if exists)|{file$|noext}_appended.pdf}");
cmd.AddLine(PDFtkBinaryPath + " {filepath$} {allfilepathdest$} cat output \"{$fileAppended}\" dont_ask ");
cmd.Run();
}
function PrepItems(items, property, prefix, suffix, addQuotes)
{
function PrepParam(p, defValue){ return typeof p==='undefined'?defValue:p;}
property = PrepParam(property,"name"); prefix = PrepParam(prefix,"");
suffix = PrepParam(suffix,""); addQuotes = PrepParam(addQuotes,true);
for(var i=0,names=[];i<items.count;i++)
names[names.length] = (addQuotes?'"':'')+prefix+items(i)[property]+suffix+(addQuotes?'"':'');
return names;
}
function Pad(str, character, digits)
{
character = character || ' ';
digits = digits || 4;
str = str+'';
while(str.length<digits) str=character+str;
return str;
}
function RunDO(cmdLine)
{
Log(cmdLine);
cmd.RunCommand(cmdLine);
}
function RunWS(cmdLine,wait)
{
wait = typeof wait == "undefined" ? true : wait;
Log(cmdLine);
var shell = new ActiveXObject("WScript.Shell");
shell.Run(cmdLine,0,wait);
}
function Log(msg, e)
{
DOpus.Output(String(msg), e || false);
}