I am a fresh DTP user, new to AS and trying to create an automated solution to re-sort pdf documents which are scanned with a simplex scanner in a fast and comfortable manner.
The work process looks like this:
Scanning all the odd pages [1,3,5,…]
Flipping the document an scanning the even pages backwards […6,4,2]
Saving the scanned pdf file which looks like this [1,3,5,…,6,4,2]
Now I created a loop which declutters that scanned pages and sorts everything to [1,2,3,4,5,6,…]
I found it difficult to modify a pdf within applescript or without using automator, but I found a nice script by S. Stanley which helped a lot (https://macscripter.net/viewtopic.php?pid=192080#p192080)
use scripting additions
use framework "Foundation"
use framework "Quartz" -- required for PDF stuff
global inPath
tell application id "DNtp"
try
set this_selection to the selection
if this_selection is {} then error "Please select some PDF Files"
set folderPath to path of inbox
set this_item to first item of this_selection
if the type of this_item is equal to PDF document then
set inPath to path of this_item
end if
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning
end try
end tell
set folderPath to POSIX path of "/Users/Username/Library/Application Support/DEVONthink 3/Inbox/"
its splitPagesInPath:inPath savingInFolder:folderPath
on splitPagesInPath:inPath savingInFolder:folderPath
try
-- make URL of the PDF
set inNSURL to current application's |NSURL|'s fileURLWithPath:inPath
-- get name of PDF
set docName to inNSURL's lastPathComponent()
-- make URL of output folder
set outFolderNSURL to current application's |NSURL|'s fileURLWithPath:folderPath
-- make PDF document from the file
set theDoc to current application's PDFDocument's alloc()'s initWithURL:inNSURL
-- store media bounds of page 1; unnecessary in most cases
set theBounds to (theDoc's pageAtIndex:0)'s boundsForBox:(current application's kPDFDisplayBoxMediaBox)
-- count the pages
set theCount to theDoc's pageCount() as integer
set midpoint to round (theCount / 2) rounding up
-- build new document's name
set newDocName to (its addString:("-NEU") beforeExtensionIn:docName)
-- make URL for new PDF
set outNSURL to (outFolderNSURL's URLByAppendingPathComponent:newDocName)
-- get page of old PDF
set theNewPDFDocument to current application's PDFDocument's new()
set k to 0
repeat with i from 1 to midpoint
set n to i - 1
set m to theCount - i
set thePDFPage to (theDoc's pageAtIndex:(n)) -- zero-based indexes
(thePDFPage's setBounds:theBounds forBox:(current application's kPDFDisplayBoxMediaBox))
(theNewPDFDocument's insertPage:thePDFPage atIndex:(k))
set k to k + 1
set thePDFPage to (theDoc's pageAtIndex:(m)) -- zero-based indexes
(thePDFPage's setBounds:theBounds forBox:(current application's kPDFDisplayBoxMediaBox))
(theNewPDFDocument's insertPage:thePDFPage atIndex:(k))
set k to k + 1
end repeat
(theNewPDFDocument's writeToURL:outNSURL)
on error error_message number error_number
if the error_number is not -128 then display alert "Sub" message error_message as warning
end try
end splitPagesInPath:savingInFolder:
on addString:extraString beforeExtensionIn:aPath
set aString to current application's NSString's stringWithString:aPath
set newString to current application's NSString's stringWithFormat_("%@%@.%@", aString's stringByDeletingPathExtension(), extraString, aString's pathExtension())
return newString as text
end addString:beforeExtensionIn:
Since I am fairly new a few problems occur:
how can I catch the POSIX path of the global inbox?
the inbox does not recognize the document added in that matter until I restart Devonthink
– can I update the inbox somehow?
I am not happy the script isn’t running completely inside the tell command for DNtp
It is still a bit clunky but it does the job pretty decent for everybody with a simplex scanner and right now I can avoid to buy a scansnap setup that way.
how can I catch the POSIX path of the global inbox?
For what purpose? This feels like you’re heading down a path you shouldn’t be going down.
Note: A third-party script like this, especially one from someone with DEEP knowledge like Shane Stanley is not one to be dissected and supported easily by other people.
Since this script is used when new documents are added to a databes I thought it’s viable to add it to the inbox. But please, if you have better solutions, give me a hint or advice.
Thank you.
You can add things to the Global Inbox, but you getting the path to the Inbox is leading you down a path you shouldn’t be going.
Read the section on Orphaned Files in the built-in Help > Documentation > Troubleshooting > Repairing a defective database(and it’s not just related to scripting) to see why it’s a very bad idea.
You would use the import command as shown in DEVONthink’s AppleScript dictionary. As a simple example…
tell application id "DNtp"
import "~/desktop/book.bib" to incoming group
end tell
Thanks for the advice. I changed the script to temporarily save the file and then use the import command. This works quite decent and solves the problems.
This was quite an intrusion into the database idea and architecture by my side…
This would be very useful. I currently use PDFpen for this, since it comes with a couple of built-in scripts: “reverse pages” and “merge every other”. I see that DTP3 now has Tools > PDF Document > Reverse Page Order, which is great, but it would be good to have DTP3 replicate the “merge every other” – or do the equivalent page re-ordering on an already-merged file.
@Osai, can you post the latest version of your script? @BLUEFROG, can we do this more elegantly keeping everything within DTP3’s “tell…” loop?
use scripting additions
use framework "Foundation"
use framework "Quartz" -- required for PDF stuff
global inPath
set tmpFolderPath to POSIX path of (path to home folder)
tell application id "DNtp"
try
set this_selection to the selection
if this_selection is {} then error "Please select some PDF Files"
set this_item to first item of this_selection
if the type of this_item is equal to PDF document then
set inPath to path of this_item
end if
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning
end try
end tell
its splitPagesInPath:inPath savingInFolder:tmpFolderPath
on splitPagesInPath:inPath savingInFolder:tmpFolderPath
try
-- make URL of the PDF
set inNSURL to current application's |NSURL|'s fileURLWithPath:inPath
-- get name of PDF
set docName to inNSURL's lastPathComponent()
-- make URL of output folder
set outFolderNSURL to current application's |NSURL|'s fileURLWithPath:tmpFolderPath
-- make PDF document from the file
set theDoc to current application's PDFDocument's alloc()'s initWithURL:inNSURL
-- store media bounds of page 1; unnecessary in most cases
set theBounds to (theDoc's pageAtIndex:0)'s boundsForBox:(current application's kPDFDisplayBoxMediaBox)
-- count the pages
set theCount to theDoc's pageCount() as integer
set midpoint to round (theCount / 2) rounding up
-- build new document's name
set newDocName to (its addString:("-sorted") beforeExtensionIn:docName)
-- make URL for new PDF
set outNSURL to (outFolderNSURL's URLByAppendingPathComponent:newDocName)
-- get page of old PDF
set theNewPDFDocument to current application's PDFDocument's new()
set k to 0
repeat with i from 1 to midpoint
set n to i - 1
set m to theCount - i
set thePDFPage to (theDoc's pageAtIndex:(n)) -- zero-based indexes
(thePDFPage's setBounds:theBounds forBox:(current application's kPDFDisplayBoxMediaBox))
(theNewPDFDocument's insertPage:thePDFPage atIndex:(k))
set k to k + 1
set thePDFPage to (theDoc's pageAtIndex:(m)) -- zero-based indexes
(thePDFPage's setBounds:theBounds forBox:(current application's kPDFDisplayBoxMediaBox))
(theNewPDFDocument's insertPage:thePDFPage atIndex:(k))
set k to k + 1
end repeat
-- create a temporary file
(theNewPDFDocument's writeToURL:outNSURL)
set newPDFPosixPath to POSIX path of (tmpFolderPath & newDocName)
-- import to DevonThink
tell application id "DNtp" to import newPDFPosixPath to incoming group
-- Delete temporary file
tell application "System Events" to delete alias newPDFPosixPath
on error error_message number error_number
if the error_number is not -128 then display alert "Sub" message error_message as warning
end try
end splitPagesInPath:savingInFolder:
on addString:extraString beforeExtensionIn:aPath
set aString to current application's NSString's stringWithString:aPath
set newString to current application's NSString's stringWithFormat_("%@%@.%@", aString's stringByDeletingPathExtension(), extraString, aString's pathExtension())
return newString as text
end addString:beforeExtensionIn:
Just to recap for anyone new to this thread: Osai’s script operates on a single PDF with pages in the order: [1, 3, 5, 7, … 8, 6, 4, 2]. In my case that results from merging two files created by successive passes through my Brother DCP-7045N, whose flips the pages during the scan. In other words I don’t have to reverse the page order of the “evens” file before running the script.