Handy Hint for Man Pages

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! :slight_smile:

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… :slight_smile:

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. :smiley:

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. :slight_smile:

It’s 2006 here. Happy New Year to you when it arrives. :slight_smile:

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. :slight_smile:

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 :confused:

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)