Mac 最佳应用软件

Quicker Markdown linking with TextExpander

I listened to the Mac Power Users TextExpander episode today and noticed that I come off as a bit of a dick, always correcting others. This was surprising only inasmuch as I wasn’t on the show. Normally, I have to be present to demonstrate my dickishness, but David and Katie have dealt with me enough to limn my essence without me. Still, as Marvin and Tammi say, ain’t nothing like the real thing, baby. Let me demonstrate by explaining why I think David’s Markdown link snippet could use some improvement.

He describes it starting at about 38:30. The snippet uses the Mac clipboard to paste a URL into the proper spot in a Markdown link structure. To use it, David

  1. Switches to Safari, presumably through ⌘-Tab.
  2. Selects the URL of the current page with ⌘L.
  3. Copies it to the clipboard with ⌘C.
  4. Switches to his text editor with ⌘-Tab again.
  5. Invokes his snippet by typing its abbreviation.

He saves a little time by keeping the ⌘ key pressed through some of the steps, but there’s still too much context shifting and too many repeated keystrokes. With a little AppleScript, all he’d need is Step 5.

Here’s my first attempt,

Markdown link TE snippet

and here’s the AppleScript it uses:

 1  tell application "System Events"
 2    set numSafari to count (every process whose name is "Safari")
 3    set numChrome to count (every process whose name is "Google Chrome")
 4  end tell
 5  
 6  if numSafari > 0 then
 7    tell application "Safari" to set fURL to URL of front document
 8  else
 9    if numChrome > 0 then
10      tell application "Google Chrome"
11        set frontIndex to active tab index of front window
12        set fURL to URL of tab frontIndex of front window
13      end tell
14      
15    end if
16  end if
17  
18  get "[%|](" & fURL & ")"

Without line numbers

Lines 1-16 get the URL of the current page in either Safari or Chrome. These lines were stolen directly from my trusty ;furl snippet, whose history can be traced back to this old AppleScript I used to invoke through Quicksilver.

Line 18 does something pretty cool. It returns a string that looks something like this

[%|](http://macsparky.com/tesnippets/)

where what’s inside the parentheses is the URL of the current page. The cool part, though, is the %| inside the brackets. This is the TextExpander code for “put the cursor here after the expansion,” which is exactly what happens when this snippet is run. So this snippet gets the URL, creates the Markdown inline link and positions the cursor right where you want it to type the link text. No context shifting, no fiddling with the clipboard.

This, by the way, is why TextExpander is such a great tool. Not only can you use it to run scripts, but the output of those scripts will then be interpreted as TextExpander variables.

In fact, that last line could be written this way,

18: get "[%filltext:name=link text:default=link text:width=32%](" & fURL & ")"

which would use a single-line TextExpander fill-in to get the link text. Unfortunately, TextExpander shows you the whole script while you’re doing the fill-in:

Fill-in in AppleScript

This works, but… blech. There’s a better way.

If you look through the popup menu that shows the TextExpander variables you can embed in a snippet, you’ll notice that all of your previously defined snippets are available, which means you can nest one snippet inside another. The best way to use a fill-in for the link text is this way:

Nested snippet for Markdown link

The content of this snippet is

[%filltext:name=link text:default=link text:width=32%](%snippet:;furl%)

where the thing in the parentheses is a call to my ;furl snippet.

When this is invoked, you see a much cleaner interface with the desired URL already in place:

Fill-in and nested snippet

Now we’re talkin’. No context shifting, no fiddling with the clipboard, and a clean fill-in interface. All you need to type is the abbreviation and the link text.

Maybe you don’t want to link to the current tab. No problem. Similar snippets can use the URLs of other tabs. I have snippets that will get the URLs of the first through the sixth tabs (counting left to right) of the frontmost Safari or Chrome window. Those could be nested just like ;furl:

[%filltext:name=link text:default=link text:width=32%](%snippet:;1url%)

What would be really nice is if these could be put into a popup menu, but TextExpander doesn’t allow that much magic yet.

I should mention that despite my love of script-driven snippets, David and Katie are exactly right when they say that TextExpander’s greatest value comes from simple, text-only snippets. There is so much repetition in business writing, especially correspondence, you’ll get your money’s worth fromTextExpander even if you never exercise the AppleScript parts. (But you’ll have more fun if you do.)