Speak Instapaper Posts — Part 1

I saw this in my Twitter stream the other day:

You know what I want? A text-to-speech plugin for @instapaper so, while commuting to/from work, I can listen to the stuff I find at work.

— @seankaiser

That shouldn’t be too hard, shouldn’t it?

First we have to get the unread articles from Instapaper. If you go instapaper, log in, and go to your unread articles, you can see the RSS button in the URL field in Safari. To get to the RSS feed in Automator, do the following:

  • Open Automator, create a new Workflow
  • Open www.instapaper.com/u in Safari and drag the link from the URL bar to the empty Automator Workflow window. Automator will create an new “Get Specified URLs” action with the Instapaper URL unread in it
  • Add a “Get Feeds from URLs” action next
  • Add a “Get Link URLs from Articles” action. Unselect the “only in the same domain” option
  • Finally add the “New Safari Documents” action.
  • The workflow already does something useful. Save as “Open unread Instapaper articles”

If you ares anything like me this workflow will open quite a large number of pages. I think Instapaper limits the RSS feed to 25. That’s still a lot of new Safari tabs/windows you are opening there. We want to add an action that restricts the number of items passed through it. Surprisingly there is none in the default actions, but this is fairly easy to add. Insert a new “Run AppleScript” action before the “New Safari Documents” action and replace the default code with the following:

on run {input, parameters}
	
	set maxNum to 3
	-- filters all but the first maxNum items from the articles, change as appropriate
	-- enter '-1' or remove this action entirely to get all urls
	if (count of input) > maxNum then
		set output to items 1 through maxNum of input
	else
		set output to input
	end if
	
	return output
end run

This will only pass through the first maxNum of items passed into it, regardless of type. You can change maxNum to fit your taste and/or needs. You can also set maxNum to -1 if you want to pass all items without removing the AppleScript action.

Save again and try running it. The next step will be to filter the actual text out of the web page which will be a little tougher and the main topic of Part 2.

Some ssh Tricks

I found this website with a bunch of ssh tricks. Some highlights:

Compare a Remote File with a Local File

ssh user@host cat /path/to/remotefile | diff /path/to/localfile -

Useful for checking if there are differences between local and remote files.

opendiff ((Part of the Developer Tools installed with Xcode)) and bbdiff ((One of the tools installed by BBEdit)) do not use stdin for their input, but you can work around that by copying the file to /tmp first:

scp user@host:/path/to/remotefile /tmp/remotefile && opendiff /path/to/localfile /tmp/remotefile

SSH Connection through host in the middle

ssh -t reachable_host ssh unreachable_host

Unreachable_host is unavailable from local network, but it’s available from reachable_host’s network. This command creates a connection to unreachable_host through “hidden” connection to reachable_host.

Using the -t option uses less overhead on the intermediate host. Same trick is used later in the article where you directly attach to a remote screen session:

ssh -t remote_host screen -r

Though I prefer using screen -DR. Read the man page for details.

The next one however didn’t do anything for me, I suspect there is a piece missing in the command somewhere:

Remove a line in a text File

sed -i 8d ~/.ssh/known_hosts

However there is a dedicated tool for this: use

ssh-keygen -R host

instead. I re-image some machines over and over again and then run into the ssh host key errors. This is very useful.

Enable Some Extra Services

It’s Thanksgiving here in the US. To keep you happy with minimal effort on my side I’ll give you a whole bunch of services to explore, without me (or you) having to write any of them.

Open System Preferences, select the Keyboard preference pane, select the Keyboard Shortcuts Pane and then from the list on the left select “Services.”

There you will find a long list of pre-installed services many of which are disabled by default. Go through the list and enable those that sound promising. “Get Result of AppleScript” and “Add to iTunes as Spoken Track” are two of my favorites.

Any services you have built yourself will also appear in this list. You can disable or re-enable them to keep your context menu trim.

This pane is also where you assign or change keyboard shortcuts. So if there is a service that you use frequently you can further optimize your workflow with a keystroke.

On man Pages

Note: update for macOS Ventura

So you’re writing this email explaining to a customer or colleague on how to do some really cool thing (say hide a file in the Finder) in Terminal. The command for that is chflags, but of course you can’t remember the exact syntax. So you open Terminal and write man chflags and find the correct options.1

However reading longer man pages (try ssh or bash) in the Terminal can be kind of painful. I’m sure some of you have encountered this command before:

man -t chflags | open -f -a "Preview"

which uses the -t flag to pass the output to groff and generate a postscript file which we then pipe into the Preview app, using open‘s -f option to pipe the stdin into a file to open in a GUI app. Preview will then convert the postscript to PDF and display the result.

I think this started to work in Tiger and you should immediately go and add this command to your shell’s profile.2 Which is nice but you still have to make the roundtrip to the Terminal.3

Enter Snow Leopard Automator Services. Open Automator. Create a new service. Leave the settings to work on ‘text’ in ‘any application’. Search for the ‘Run Shell Script’ action and double click to add to the workflow. Leave the Shell at ‘/bin/bash’ but set the ‘Pass Input’ option to ‘as arguments.’

Replace the default code with

man -t "$1" | open -f -a /Applications/Preview.app
Screenshot of the workflow in Automator

Save the Service and give it a nice name, such as “Open Man Page.”

Then in any application4 you can ctrl/right/double-finger click on a word and “Open Man Page” will be an option in the menu.5 You can even go to System Preferences -> Keyboard -> and add a keyboard shortcut to the command.6 If any other command in the man page strikes your curiosity, just ctrl/right/double-finger click the word in Preview and select “Open Man Page” again.

Another rarely known but quite useful trick is that you can create hyperlinks to man pages with the x-man-page://command URL.7 This will open the man page in man in a new Terminal window. This is especially useful in IM sessions.


  1. chflags [no]hidden /path/to/file
  2. for me the relevant line looks like: function preman() { man -t "$@" | open -f -a "Preview" ;}
  3. though you could save the resulting PDF and attach it to the email, especially if you have a customer who can’t find his or her way around the command line.
  4. well… most…
  5. it may be under a under an extra level “Services” Menu. Some applications do not show Services in the context menu, but all will show the “Services” Menu under the Application Menu
  6. I usually don’t bother since I immediately forget any new keystrokes I assign. Your memory may work better.
  7. I once had somebody freak out on me because I made him open Terminal on his Mac with this…