uweschmidt.org

42 / π ≈ 13.37 

A different kind of print server

I’m using an old Mac Mini running regular OS X 10.4 “Tiger” to share an attached laser printer with the local network. For some reason, the two Windows laptops here (Windows Vista & Windows 7) can’t print PDFs with Adobe Reader. Printing from any other application works however.

I’m sick of debugging problems like this and instead shared a folder on the Mac Mini that is “watched” by a shell script that immediately prints every PDF that gets thrown in there, and deletes it afterwards. We share this folder with Dropbox, so this could also be used to print from about anywhere to your home printer.

The actual printing is done with an AppleScript that uses GUI scripting to send the keystrokes ⌘P, , and ⌘W to Preview.app after the PDF has been opened. While this isn’t very flexible (it always uses the default print options), it’s simple and probably covers 95% of the printing needs here.

Note that this doesn’t work well if someone is actually using the Mac where this is running on. You also need to “Enable access for assistive devices” in the Universal Access System Preference pane for the AppleScript to work (more details here).

Bash script watch_and_print.command

I used the extension .command for the shell script to allow it to be opened directly with the Finder, then dragged it to the Dock and enabled “Open at Login” from the contextual menu. Okay, cron would probably work too.

#!/bin/bash

script_dir=`dirname "$0"`
print_dir=/path/to/shared/print/folder
cd $print_dir

while [ 1 ]
do
  # http://bit.ly/bmvIih
  find . -type f|grep -i .pdf$ |while read file; do
    echo Printing "$file"
    /usr/bin/open -a Preview.app "$file"
    /usr/bin/osascript $script_dir/print_pdf.applescript
    rm "$file"
  done
  sleep 10
done

AppleScript print_pdf.applescript

Put it in the same folder as watch_and_print.command. The delays in the script are pretty arbitrary, your milage may vary.

tell application "Preview"
  activate
  tell application "System Events"
    tell process "Preview"
      keystroke "p" using command down
      delay 5
      keystroke return
      delay 10
      keystroke "w" using command down
    end tell
  end tell
end tell

3 Responses

  1. Marc Werner says:

    Hi Uwe,

    how about just using

    lp

    to print instead of some GUI scripting?
    You could also try using folder actions to initiate the printing although I’m not sure if they are invoked when the folder is accessed over the network.

    Greetings,

    Marc

  2. Uwe says: in reply to Marc Werner

    Hi Marc,

    how about just using lp to print instead of some GUI scripting?

    why didn’t I think of that obvious solution first? D’oh!
    However, I just wanted to print a PDF in landscape and lp didn’t automatically do “the right thing” — one has to use the option -o landscape as the man page reveals.
    In conclusion, I’ll continue using GUI scripting with Preview.app because it just does “the right thing” by default.
    Alternatively, another possibility would be several print folders, each using a different combination of parameters for lp (e.g., “normal”, “landscape”, “2 pages per sheet”, etc.).

    You could also try using folder actions to initiate the printing although I’m not sure if they are invoked when the folder is accessed over the network.

    I actually looked into this, but found it too complicated. As a programmer, I find AppleScript to be a strange language in general. How about you?

    Uwe

  3. Marc Werner says: in reply to Uwe

    You are definitely right that Apple Script is strange. But on the other hand it was not created for “real programmers” :-)

Leave a Reply