Today’s MacOSXhint makes a handy one-liner AppleScript as well for getting shell script man pages as easily read PDF’s in Preview.
do shell script "man -t " & (text returned of (display dialog "Enter Name of Shell Function Man Page" default answer "grep" buttons {"Go Get It"} default button 1)) & " | open -f -a /Applications/Preview.app"
TIGER ONLY - For those running Panther, Bwana is recommended - it shows man pages in Safari.
See also: Help with User Input Text fields
property theCommand : ""
repeat while theCommand is ""
display dialog "View man page for this command:" default answer theCommand
set theCommand to text returned of result
end repeat
try
do shell script "/usr/bin/man -t " & quoted form of theCommand & " | open -f -a /Applications/Preview.app"
on error errorMsg number errorNum
display alert "Error " & errorNum message errorMsg buttons "Cancel" default button 1
end try
Good stuff, Bruce. How does the Postscript to PDF conversion happen - does Preview do it? Is there a way to get the man page to text?
I saw your post over at MacOSXHints.
To answer the question, Preview does the conversion. However, you could also do it this way:
property theCommand : ""
repeat while theCommand is ""
display dialog "View man page for this command:" default answer theCommand
set theCommand to text returned of result
end repeat
try
get quoted form of ("/tmp/" & theCommand & "-ManPage.pdf")
do shell script "/usr/bin/man -t " & quoted form of theCommand & " | /usr/bin/pstopdf -i -o " & result & "; open -a /Applications/Preview.app " & result
on error errorMsg number errorNum
display alert "Error " & errorNum message errorMsg buttons "Cancel" default button 1
end try
One nice thing about this script is that Preview.app won’t ask if you want to save the file.
Hmm. redirection would get you started:
Note that the double-lettered words are those that would appear bold when viewed in the terminal.
[Another edit] It seems there are extra characters betweens those letters (their not visible in BBEdit, or while editing this post).
[Yet another edit] It seems that character is ASCII character 8.
That’s excellent! Thanks, Adam and Bruce. It’s taken some of the slog out of trying to understand those appalling ‘man’ descriptions!
For my own use, I’ve adapted Bruce’s later script to save a permanent copy of the PDF in my Documents folder, for perusal at leisure. I’ve also made ‘theCommand’ (and all other variables) local, since as a property, it dooms the script to open the same manual page forever…
on main()
set theCommand to ""
repeat while theCommand is ""
display dialog "View man page for this command:" default answer theCommand
set theCommand to text returned of result
end repeat
try
set manFolderPath to (path to At Ease documents folder as Unicode text) & "Unix 'man' Pages (PDFs):"
do shell script ("mkdir -p " & quoted form of POSIX path of manFolderPath)
set manFilePath to quoted form of POSIX path of (manFolderPath & theCommand & "-ManPage.pdf")
do shell script "/usr/bin/man -t " & quoted form of theCommand & " | /usr/bin/pstopdf -i -o " & manFilePath & "; open -a /Applications/Preview.app " & manFilePath
on error errorMsg number errorNum
display alert "Error " & errorNum message errorMsg buttons "Cancel" default button 1
end try
end main
main()
Great stuff. I’ve given it a hot key. I’m going to play with it a bit too - shouldn’t it check whether the directory exists and whether a copy of that man page already exists in manFilePath and show me that rather than fetching and converting again?
But the inevitable question (from me): the script includes this part
set theCommand to ""
repeat while theCommand is ""
display dialog "View man page for this command:" default answer theCommand
set theCommand to text returned of result
end repeat
and while I understand what it does, it hasn’t occurred to me why it’s done.
I’ve never seen this before: “At Ease documents folder”. Since I get the same answer without “At Ease”, why is it there?
If theCommand is “”, then the script won’t do much. However, in some scripts, having no user input could result in some pointless errors.
Could do. I might do something like that myself. It’s just that my G5 is so fast that it doesn’t make much difference.
Sorry, Adam. I’m always worrying people by doing that. The reasons for the ‘At Ease’ part are lost in the history of AppleScript, before my time. I think there was once an Apple technology of that name. Until about Panther or Tiger, the offical ‘path to’ parameters for the Applications and Documents folders were respectively ‘At Ease applications folder’ and ‘At Ease documents folder’. This wasn’t widely known because there was some technical reason why these terms couldn’t be shown in the Standard Additions dictionary (!), and in any case, most people preferred the shorter string hacks ‘path to “apps”’ and ‘path to “docs”’.
Nowadays the ‘At Ease’ part isn’t necessary, but it still works. I use it partly out of habit and party because my other machine still runs Jaguar. And I like my scripts to work across as wide a range of systems as possible. This one doesn’t work in Jaguar, but the habit’s still there.
It’s 2006 here. Happy New Year to you when it arrives.
Thank you Nigel & Bruce.
Nigel: My dual-core G5 shipped yesterday (second time around). The first, ordered in late November, arrived with the side door bashed in (as if something sharp and heavy had penetrated the box). Apple snail mailed the required return shipping label from Cupertino, California during the Christmas rush so there was a long pause before I could return it and a pause before they sent a replacement; BUT: it’s on its way to replace a much goosed-up B&W G3/1100!
Bruce: having never seen such a “pointless error”, I’ll take your word for it.
/A
OK, I guess that’s not a great way to describe it.
To clarify, the repeat statement in question is used to validate user input.
A final form that checks to see if there is a saved copy of the man file before getting one and converting it.
on main()
set theCommand to ""
repeat while theCommand is ""
display dialog "View man page for this command:" default answer theCommand
set theCommand to text returned of result
end repeat
try
set manFolderPath to (path to documents folder as Unicode text) & "Unix 'man' Pages (PDFs):"
set manFile to manFolderPath & theCommand & "-ManPage.pdf"
tell application "Finder"
if exists manFile then
open manFile
return
end if
end tell
do shell script ("mkdir -p " & quoted form of POSIX path of manFolderPath)
set manFilePath to quoted form of POSIX path of manFile
do shell script "/usr/bin/man -t " & quoted form of theCommand & " | /usr/bin/pstopdf -i -o " & manFilePath & "; open -a /Applications/Preview.app " & manFilePath
on error errorMsg number errorNum
display alert "Error " & errorNum message errorMsg buttons "Cancel" default button 1
end try
end main
main()
tell application "Script Editor" to activate -- useful if running this as a script from FastScripts; not necessary if running this as an application.
Thanks, Adam. That’s a noticeable improvement.
I hope the frustration over getting your new G5 is soon over.
Preview is showing the man page in postscript – no conversion is taking place. Any ideas why that is?
Model: PowerBook G4
AppleScript: 1.9.3
Browser: Safari
Operating System: Mac OS X (10.3.9)
I’m afraid this is the problem, sd: Operating System: Mac OS X (10.3.9). It’s a Tiger only trick (as I indicated at the top of the thread).
Adam,
You’ve given me an idea. I liked your original idea, but hate viewing stuff in Preview. So before I knew it I was hip-deep in writing my first document-based AS Studio app that is a stand-alone man page viewer. I’ll be posting it to Scriptbuilders as soon as I get a creator code from Apple (probably tomorrow).
BTW: I found that piping the man page through “col -bx” and then displaying the result in a fixed-width font made for a nice read.
For those that haven’t tried it, AS Studio makes creating document-handling apps SINFULLY easy. I’m ashamed to admit that once you strip out empty lines and comments, the entire program is…23 lines. And with only that much code, you can write an app that can save the viewed man page and re-open the same document later. I spent more time doing the needed research into HOW to write the thing than I did in writing it.
Hey very nice.
I change the bit that does the display dialog
I used frontmost app to do this so it will bring the dialog to the front as I found the dialog pop up kept being hidden in the background.
on main()
set theCommand to ""
tell application "System Events"
set target_app to item 1 of (get name of processes whose frontmost is true)
end tell
tell application target_app
repeat while theCommand is ""
display dialog "View man page for this command:" default answer theCommand
set theCommand to text returned of result
end repeat
end tell
try
set manFolderPath to (path to documents folder as Unicode text) & "Unix 'man' Pages (PDFs):"
set manFile to manFolderPath & theCommand & "-ManPage.pdf"
tell application "Finder"
if exists manFile then
open manFile
return
end if
end tell
do shell script ("mkdir -p " & quoted form of POSIX path of manFolderPath)
set manFilePath to quoted form of POSIX path of manFile
do shell script "/usr/bin/man -t " & quoted form of theCommand & " | /usr/bin/pstopdf -i -o " & manFilePath & "; open -a /Applications/Preview.app " & manFilePath
on error errorMsg number errorNum
display alert "Error " & errorNum message errorMsg buttons "Cancel" default button 1
end try
end main
main()
--tell application "Script Editor" to activate -- useful if running this as a script from FastScripts; not necessary if running this as an application.
** Note for mod, Please move this to the help area if you feel it should be there. Thanks**
I wanted to have my PDFs In colour like Bwana Man http://www.bruji.com/bwana/index.html does.
So I edited the script to do it. There is most likely a better way but this is what I came up is in the short time I had.
It works but when I first run the script it fails.
Run it a second time looking for the same command it always works??
I have comment out the try statements to see where the bug is and it seems the convert fro rtf to pdf does not happen the first time round.
I ran some tests putting if exists on the html file in the temp folder before the convert to rtf and it finds it but still bugs out on the first run.
Any one got any ideas??
You will need Bwana Man for to use this.
I like Bwana Man and could quit easily a script to do the same thing. But I like the pdf’s
on main()
set theCommand to ""
set tmp to path to temporary items folder
set temp to POSIX path of tmp
tell application "System Events"
set target_app to item 1 of (get name of processes whose frontmost is true)
end tell
tell application target_app
repeat while theCommand is ""
display dialog "View man page for this command:" default answer theCommand
set theCommand to text returned of result
end repeat
end tell
--try
set manFolderPath to (path to documents folder as Unicode text) & "Unix 'man' Pages (PDFs):"
set manFile to manFolderPath & theCommand & "-ManPage.pdf"
tell application "Finder"
if exists manFile then
open manFile
return
end if
end tell
do shell script ("mkdir -p " & quoted form of POSIX path of manFolderPath)
set manFilePath to quoted form of POSIX path of manFile
do shell script "open man:" & theCommand & " |textutil -convert rtf " & temp & theCommand & ".html"
my processFile(theCommand, manFilePath, temp)
do shell script "open -a /Applications/Preview.app " & manFilePath
--on error errorMsg number errorNum
-- display alert "Error " & errorNum message errorMsg buttons "Cancel" default button 1
--end try
end main
main()
--tell application "Script Editor" to activate -- useful if running this as a script from FastScripts; not necessary if running this as an application.
-- This is from part of the Apple sample code "convert to pdf script"
on processFile(theCommand, manFilePath, temp)
--try
set terminalCommand to ""
set convertCommand to "/System/Library/Printers/Libraries/./convert "
set theCommandPath to temp & theCommand & ".rtf"
set newFileName to theCommand & ".pdf"
set terminalCommand to convertCommand & "-f " & theCommandPath & " -o " & manFilePath & " -j application/pdf"
do shell script terminalCommand
-- end try
end processFile
I came back to this today and Had a little debug session
found that the issue I had above was I needed to break up one line ( do shell script “open man:” & theCommand & " |textutil -convert rtf " & temp & theCommand & “.html” )
and put a 0.5 seconds delay in.
The change looks like this.
on _convert(theCommand, tempFolder)
do shell script “open man:” & theCommand & " |> " & tempFolder & theCommand & “.html”
do shell script “sleep 0.5”
do shell script "textutil -convert rtf " & tempFolder & theCommand & “.html”
end _convert
on main()
set theCommand to ""
tell application "System Events"
set target_app to item 1 of (get name of processes whose frontmost is true)
end tell
tell application target_app
repeat while theCommand is ""
display dialog "View man page for this command:" default answer theCommand
set theCommand to text returned of result
end repeat
end tell
try
set manFolderPath to (path to documents folder as Unicode text) & "Unix 'man' Pages (PDFs):"
set tempFolder to POSIX path of (path to temporary items folder) as string
set manFile to manFolderPath & theCommand & "-ManPage.pdf"
tell application "Finder"
if exists manFile then
open manFile
return
end if
end tell
do shell script ("mkdir -p " & quoted form of POSIX path of manFolderPath)
set manFilePath to quoted form of POSIX path of manFile
my _convert(theCommand, tempFolder)
my processFile(theCommand, manFilePath, tempFolder)
do shell script "open -a /Applications/Preview.app " & manFilePath
on error errorMsg number errorNum
display alert "Error " & errorNum message errorMsg buttons "Cancel" default button 1
end try
end main
main()
on _convert(theCommand, tempFolder)
do shell script "open man:" & theCommand & " |> " & tempFolder & theCommand & ".html"
do shell script "sleep 0.5"
do shell script "textutil -convert rtf " & tempFolder & theCommand & ".html"
end _convert
-- This is from part of the Apple sample code "convert to pdf script"
on processFile(theCommand, manFilePath, tempFolder)
--try
set terminalCommand to ""
set convertCommand to "/System/Library/Printers/Libraries/./convert "
set theCommandPath to tempFolder & theCommand & ".rtf"
set newFileName to theCommand & ".pdf"
set terminalCommand to convertCommand & "-f " & theCommandPath & " -o " & manFilePath & " -j application/pdf"
do shell script terminalCommand
--end try
end processFile
Hi guys, I know this is long after the initial thread, but this post sort of covers a problem of mine.
I want to use Preview to batch convert .eps files into .pdf files. Preview is fast, crops to the .eps bounding box and makes very tight pdf code (16k vs 1.1Mb from Illustrator CS2).
The only problem is I cann’t find a dictionary for Preview and the Preview conversion actions in Automator only convert to bitmap formats.
Could you please tell me how to create a workflow for Preview to convert my .eps to pdfs?
Thanks. s:-)
Model: iMac 17" PPC 2.0Ghz
AppleScript: 1.10.7
Browser: Safari 419.3
Operating System: Mac OS X (10.4)
Have a look at post #4. and see if that gives you the “tight” conversions you want.
I do not think you will have much luck trying to get preview to work for you, as you have discovered is not scriptable and does not have a library.
EDIT here is an example.
tell application "Finder"
set target_path to ((path to desktop folder as Unicode text) as alias)
set source_item to (choose file)
set source_itemP to POSIX path of source_item
set file_name to displayed name of source_item -- get displayed name
set oldDelims to AppleScript's text item delimiters -- get normal dilm
set AppleScript's text item delimiters to {"."} --sets new dilm
set file_name to text item 1 of file_name -- get thye name of file without extension
set AppleScript's text item delimiters to oldDelims -- resets dilm
set target_pathP to POSIX path of target_path & file_name & ".pdf" as string
end tell
do shell script (" /usr/bin/pstopdf " & quoted form of source_itemP & " -o " & quoted form of target_pathP)