Phillip Briggs

Q: Using Ruby, Rename PDF with text from input PDF file

I have this script running pretty well thanks to the great support on this site. It currently opens a PDF, searches for a text string, and then saves the PDF with the string as the file name.

 

For a different project I need to check the string matches the original filename, so my thoughts are to read the string and then append it to the original filename like this: Originalname_Foundstring.pdf - then I can take over and compare the first and second parts of the filename.

 

This script searches for a string beginning "1000…." then saves the file with a new name based on the string.

 

How can I grab the input filename and then append the string like this: Originalname_Foundstring.pdf?


(I am only a beginner in Applescript and even more clueless in Ruby script).

 

 

_main()

on _main()

  script o

  property aa : choose file with prompt ("Choose PDF Files.") of type {"com.adobe.pdf"} ¬

  default location (path to desktop) with multiple selections allowed

 

  set my aa's beginning to choose folder with prompt ("Choose Destination Folder.") ¬

  default location (path to desktop)

 

  set args to ""

  repeat with a in my aa

  set args to args & a's POSIX path's quoted form & space

  end repeat

 

  considering numeric strings

  if (system info)'s system version < "10.9" then

  set ruby to "/usr/bin/ruby"

  else

  set ruby to "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby"

  end if

  end considering

 

  do shell script ruby & " <<'EOF' - " & args & "

require 'osx/cocoa'

include OSX

require_framework 'PDFKit'

 

 

outdir = ARGV.shift.chomp('/')

 

 

ARGV.select {|f| f =~ /\\.pdf$/i }.each do |f|

    url = NSURL.fileURLWithPath(f)

    doc = PDFDocument.alloc.initWithURL(url)

    path = doc.documentURL.path

    pcnt = doc.pageCount

  

    (0 .. (pcnt - 1)).each do |i|

        page = doc.pageAtIndex(i)

       page.string.to_s =~ /1000\\S*/

        name = $&

        unless name

            puts \"no matching string in page #{i + 1} of #{path}\"

            next # ignore this page

 

        end

  newname = name[1..-1]

 

        doc1 = PDFDocument.alloc.initWithData(page.dataRepresentation) # doc for this page

        unless doc1.writeToFile(\"#{outdir}/#{newname}.pdf\")

            puts \"failed to save page #{i + 1} of #{path}\"

        end

    end

end

EOF"

  end script

  tell o to run

end _main

Posted on Apr 14, 2015 7:11 AM

Close

Q: Using Ruby, Rename PDF with text from input PDF file

  • All replies
  • Helpful answers

  • by Hiroto,Helpful

    Hiroto Hiroto Apr 14, 2015 8:51 AM in response to Phillip Briggs
    Level 5 (7,281 points)
    Apr 14, 2015 8:51 AM in response to Phillip Briggs

    Hello

     

    If I understand it correctly, you may try something like this.

     

    _main()
    on _main()
        script o
            property aa : choose file with prompt ("Choose PDF Files.") of type {"com.adobe.pdf"} ¬
                default location (path to desktop) with multiple selections allowed
            
            set my aa's beginning to choose folder with prompt ("Choose Destination Folder.") ¬
                default location (path to desktop)
            
            set args to ""
            repeat with a in my aa
                set args to args & a's POSIX path's quoted form & space
            end repeat
            
            considering numeric strings
                if (system info)'s system version < "10.9" then
                    set ruby to "/usr/bin/ruby"
                else
                    set ruby to "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby"
                end if
            end considering
            
            do shell script ruby & " <<'EOF' - " & args & "
    require 'osx/cocoa'
    include OSX
    require_framework 'PDFKit'
    
    outdir = ARGV.shift.chomp('/')
    
    ARGV.select {|f| f =~ /\\.pdf$/i }.each do |f|
        url = NSURL.fileURLWithPath(f)
        doc = PDFDocument.alloc.initWithURL(url)
        path = doc.documentURL.path
        pcnt = doc.pageCount
        bname = File.basename(f, File.extname(f))
        
        (0 .. (pcnt - 1)).each do |i|
            page = doc.pageAtIndex(i)
            page.string.to_s =~ /1000\\S*/
            name = $&
            unless name
                puts \"no matching string in page #{i + 1} of #{path}\"
                next # ignore this page
            end
            newname = name[1..-1]
    
            doc1 = PDFDocument.alloc.initWithData(page.dataRepresentation) # doc for this page
            unless doc1.writeToFile(\"#{outdir}/#{bname}_#{newname}.pdf\")
                puts \"failed to save page #{i + 1} of #{path}\"
            end
        end
    end
    EOF"
        end script
        tell o to run
    end _main
    

     

     

     

    Hope this helps,

    H

  • by Phillip Briggs,

    Phillip Briggs Phillip Briggs Apr 14, 2015 8:58 AM in response to Hiroto
    Level 1 (24 points)
    Mac OS X
    Apr 14, 2015 8:58 AM in response to Hiroto

    That is exactly what I needed - I searched for ages and could find no way of getting the File.basename !

     

    To take this one step further if you will:

     

    This is currently asking for user input in the applescript part, to select the files. Ideally, I would launch this script from another source (it's actually from Esko Automation Engine). So this would send PDFs to this script and then wait for output.

     

    Do you think it's possible to do this? For this to 'receive' files without user input, then process them?

  • by Phillip Briggs,

    Phillip Briggs Phillip Briggs Apr 15, 2015 2:34 AM in response to Phillip Briggs
    Level 1 (24 points)
    Mac OS X
    Apr 15, 2015 2:34 AM in response to Phillip Briggs

    Is it possible to run the Ruby Script part within Applescript, but without the manual user file selection?

     

    Ideally I'll be passing files to the script without user intervention

  • by Hiroto,Solvedanswer

    Hiroto Hiroto Apr 15, 2015 5:32 AM in response to Phillip Briggs
    Level 5 (7,281 points)
    Apr 15, 2015 5:32 AM in response to Phillip Briggs

    Hello

     

    I'm not sure but I guess you're trying to use the script via Esko Automation Engine Script Runner.

     

    The rest is based upon an official document I downloaded from the following link:

     

    http://help.esko.com/docs/en-us/automationengine/12/otherdocs/Scripting_in_Autom ation_Engine.pdf

     

     

    1) AppleScript for Esko Automation Engine Script Runner would be something like this. (You'd only need the main() handler definition. The rest is for testing purpose.)

     

     

    -- # start testing
    set inputs to choose file with prompt ("Choose PDF Files.") of type {"com.adobe.pdf"} ¬
        default location (path to desktop) with multiple selections allowed
    set outputFolder to choose folder with prompt ("Choose Destination Folder.") ¬
        default location (path to desktop)
    repeat with i in inputs
        set i's contents to i's POSIX path
    end repeat
    set outputFolder to outputFolder's POSIX path
    set params to {}
    main(inputs, outputFolder, params)
    -- # end testing
    
    (*
        for Esko Automation Engine Script Runner
    *)
    on main(inputs, outputFolder, params)
        (*
            list inputs : list of POSIX path of input files
            string outputFolder : POSIX path of output folder
            list params : list of additional parameters
            return string : "OK" or "Warning" or "Error"
        *)
        script o
            property aa : {outputFolder} & inputs
            set args to ""
            repeat with a in my aa
                set args to args & a's quoted form & space
            end repeat
            
            considering numeric strings
                if (system info)'s system version < "10.9" then
                    set ruby to "/usr/bin/ruby"
                else
                    set ruby to "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby"
                end if
            end considering
            
            try
                do shell script ruby & " <<'EOF' - " & args & "
    require 'osx/cocoa'
    include OSX
    require_framework 'PDFKit'
    
    ret = 0
    outdir = ARGV.shift.chomp('/')
    
    ARGV.select {|f| f =~ /\\.pdf$/i }.each do |f|
        url = NSURL.fileURLWithPath(f)
        doc = PDFDocument.alloc.initWithURL(url)
        path = doc.documentURL.path
        pcnt = doc.pageCount
        bname = File.basename(f, File.extname(f))
        
        (0 .. (pcnt - 1)).each do |i|
            page = doc.pageAtIndex(i)
            page.string.to_s =~ /1000\\S*/
            name = $&
            unless name
                ret = [ret, 1].max
                $stderr.puts \"No matching string in page #{i + 1} of #{path}.\"
                next # ignore this page
            end
            newname = name[1..-1]
    
            doc1 = PDFDocument.alloc.initWithData(page.dataRepresentation) # doc for this page
            unless doc1.writeToFile(\"#{outdir}/#{bname}_#{newname}.pdf\")
                ret = [ret, 2].max
                $stderr.puts \"Failed to save page #{i + 1} of #{path}.\"
            end
        end
    end
    exit ret
    EOF"
                set {r, err} to {result, 0}
            on error errs number errn
                set {r, err} to {errs, errn}
            end try
            
            if err = 0 then
                return "OK"
            else if err = 1 then
                log r
                return "Warning"
            else
                log r
                return "Error"
            end if
        end script
        tell o to run
    end main
    

     

     

     

     

    2) Shell Script for Esko Automation Engine Script Runner would be something like this.

     

     

    #!/bin/bash
    # 
    #   for Esko Automation Engine Script Runner
    # 
    #   $1   : input files separatated by :
    #   $2   : output directory
    #   $3.. : additional parameters
    #   exit : 0 = OK, 1 = Warning, 2 = Error
    #
    ruby1=/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
    ruby2=/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby
    [[ -e $ruby2 ]] && ruby=$ruby2 || ruby=$ruby1
    
    $ruby <<'EOF' - "$@"
    # 
    #   ARGV[0]   : input files separatated by :
    #   ARGV[1]   : output directory
    #   ARGV[2..] : additional parameters
    # 
    require 'osx/cocoa'
    include OSX
    require_framework 'PDFKit'
    
    ret = 0
    outdir = ARGV[1].chomp('/')
    
    ARGV[0].split(':').select {|f| f =~ /\.pdf$/i }.each do |f|
        url = NSURL.fileURLWithPath(f)
        doc = PDFDocument.alloc.initWithURL(url)
        path = doc.documentURL.path
        pcnt = doc.pageCount
        bname = File.basename(f, File.extname(f))
        
        (0 .. (pcnt - 1)).each do |i|
            page = doc.pageAtIndex(i)
            page.string.to_s =~ /1000\S*/
            name = $&
            unless name
                ret = [ret, 1].max
                $stderr.puts "No matching string in page #{i + 1} of #{path}."
                next # ignore this page
            end
            newname = name[1..-1]
    
            doc1 = PDFDocument.alloc.initWithData(page.dataRepresentation) # doc for this page
            unless doc1.writeToFile("#{outdir}/#{bname}_#{newname}.pdf")
                ret = [ret, 2].max
                $stderr.puts "Failed to save page #{i + 1} of #{path}."
            end
        end
    end
    exit ret
    EOF
    

     

     

     

    Hope this may help,

    H

  • by Phillip Briggs,

    Phillip Briggs Phillip Briggs Apr 15, 2015 6:01 AM in response to Hiroto
    Level 1 (24 points)
    Mac OS X
    Apr 15, 2015 6:01 AM in response to Hiroto

    Wow!

    Once again Hiroto you have come to my rescue

    I have just used your Shell script and it works perfectly via the Automation Engine Script Runner.

    Thanks to you I can build this into my workflow and save hours of work every week!

     

    Many, many thanks,

     

    you are so kind to give so much help!

  • by Hiroto,

    Hiroto Hiroto Apr 15, 2015 7:02 AM in response to Phillip Briggs
    Level 5 (7,281 points)
    Apr 15, 2015 7:02 AM in response to Phillip Briggs

    You're quite welcome! Glad to hear it serves you well.

     

    Best wishes,

    Hiroto