You might have heard of RubyMotion – it’s been kinda the buzz lately. If, like me, you find Objective C’s syntax daunting, Laurent Sansonetti’s project is probably most welcome. Wonderful (or, depending on your point of view, despicable – but what are you doing still reading this then?) (Mac)Ruby syntax sugar over the Cocoa APIs.
Until you look up the docs, that is. Apple’s code examples all being, to nobody’s surprise, pure Objective C. Translating in your head is error prone and annoying (never mind not copy-paste friendly), and where is the fun in using Ruby syntax if you have to understand every last nuance of the Objective C syntax anyway? The good news is Joakim Kolsjö agrees, and he has a solution: a user script that will deftly insert the MacRuby syntax version of example code in Apple’s API docs.
Nice start, but for the fact Safari does not support user scripts. No, I didn’t port the script to a Safari extension (still not a coder, my interest in changing this fact notwithstanding), but cooking up a little documentation viewer leveraging the script is no biggie even without coding chops (have I mentioned I still utterly lack these?).
You will need Andrew Peperell’s Alfred, Todd Ditchendorf’s Fluid and George Brocklehurst’s Choosy besides the script:
- create a Fluid SSB with the home page
https://developer.apple.com. Set it to whitelist*apple.com*. - Install Joakim’s user script into your SSB, set it to apply to
*apple.com*again. - Add a custom rule to Choosy to open links containing
developer.apple.comwith the newly created SSB. Now any call to such an URL (outside a browser that is) will open the SSB instead of [your default browser here, don’t start me on Chrome versus Safari]. - Add a custom search to Alfred called Apple Developer Library search with the query URL
https://developer.apple.com/search/index.php?q={query}. If you have the PowerPack (honestly, if you are using Alfred without it, you are missing out), you can add a hotkey to pass selected text in any window to that search directly . Mine isShift+Ctrl+D.
Select a Cocoa API keyword. Press your hotkey. Tada.

* Yeah, I know, bis repetitas placent not so much and all … but I just couldn’t resist
Pinboard’s founder, lead and operator Maciej Ceglowski has published what he, very modestly, calls “a rant on the ‘Social Graph’”. Don’t be fooled. This might very well be the smartest thing you will read this year. Not just about the social web.
There is a lot in Maciej’s brilliant essay that has helped clear up thoughts I was tossing around in my head: how Twitter’s (conscious?) restraint from modeling a “social graph” is its strength, and how its one-dimensional network model (“follow what / who interests you”) makes it the only network that can usefully be leveraged as a foundation for other networks – if they fit its mold. Or how I am on the fence as to Facebook: as awkwardly clumsy as its network representation may be, as creepy as its business model is, I am all too aware how well it works for your run-of-the-mill, non techy user, a demographic Facebook has opened a world of sharing to the net for (just to catch that sharing in the confines of its walled garden, of course – but there is the rub: knowing your audience is lowering the entry barrier. Which is why I cherish my Tumblr readers. All 11 of you). Or why alternative networks modeled on Facebook are doomed to be niche (AnyBeat), or even simply doomed, period (Google+ – Google so obviously doesn’t get the first word of what Maciej writes) – there are only so much catch-all social buckets people need. But this is not about me.
If you ever wondered why Facebook wants to know about your pastor’s dominatrix, or why there is a Mormon bartender in Uncanny Valley, you need to read Maciej‘s essay. And if you never did, you need to read it all the more.
Now.
I’ve been spending entirely too much time on Stack Exchange lately. This has triggered two things: complaints from the wife (but that is off topic to this post) and the creation of a dedicated browser for Stack Exchange courtesy of the fantastic Fluid. I’ve thrown a load of user scripts at this SSB, and now I am very nearly happy but for a few things.
One of the itches I decided to scratch today: the lack of a Dock badge and Growl notifications for new messages in the Stack Exchange MultiCollider (aka global inbox). The result is my very first userscript (and my first foray into JavaScript beyond bookmarklets, ever, too). Grab it and enjoy.
Here’s to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They’re not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can’t do is ignore them. Because they change things. They push the human race forward. And while some may see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do.
I have been wanting to write some stuff down about how that whole Markdown to Evernote thing came to pass for a while. See, that wasn’t actually meant to be an end on itself; it happened because I wanted to compile some documentation strewn around the web (which I wrote in Markdown, of course) and coerce it into my note repository of choice, which happens to be Evernote. Brett Terpstra’s conversion service failed me, and one thing kind of lead to another.
What I was actually trying to do was find out how OS X handles the $PATH environment variable, and that was because I wanted my homebrew installs path searched first, before system defaults. Better not ask why (OK, if you insist: I wanted to run Ruby 1.9 by default. Yes, I know, I really should use RVM for that. Told you not to ask). Now, if you google around, you’ll mostly get directed to reference material for *nix shells telling you to add an export PATH=/my/path/:$PATH directive to this or that profile file (Apple’s Shell Scripting Primer has an excellent overview of those). I didn’t want to do that.
One, it’s double the work if you switch between Bourne and C shells – which is academic in my case, but you know, I might want to one day. Two, it saddles you with a bunch of directives strewn around obscure dot files which tend to stick around long after the corresponding software is gone, which is untidy. Three, doing one, and four, alleviating two, both sound like “I really should be automating this” kind of work. Short version: yuck. Maximum yuck, even.
Now it turned out Apple seems to share these thoughts as they have implemented a better (as in far tidier) mechanism for adding $PATH directives as of Leopard: path.d files and the path_helper tool (thanks to this Ars Technica forum thread for pointing me the right way). path_helper’s man page explains it better than I could:
The path_helper utility reads the contents of the files in the directories
/etc/paths.dand/etc/manpaths.dand appends their contents to thePATHandMANPATHenvironment variables respectively. (TheMANPATHenvironment variable will not be modified unless it is already set in the environment.)Files in these directories should contain one path element per line.
Prior to reading these directories, default
PATHandMANPATHvalues are obtained from the files/etc/pathsand/etc/manpathsrespectively.
Disregarding the whole MANPATH part (that variable is not set by default, at least on Snow Leopard), that leaves us with a pretty neat $PATH management system: put a file into /etc/paths.d, one path per line, and presto, you have those appended to $PATH. Remove the file, poof, paths gone (technically, you have to start a new shell instance, but that is the basic idea). No dicking around with dotties; I just had to add /etc/paths.d/homebrew with /usr/bin/local/ in it. Great.
The problem with this neat solution was the “appended” part: Apple obviously do not believe in user defined paths overriding the system defaults. Maybe wisely so (see the above mentioned forum thread), path_helper will always keep the system default paths at the start of $PATH. Still: I wanted /usr/bin/local/ up front. And not by hacking the root access only /etc/paths (which stores the system defaults) either.
What I ended up with was editing a profile file. But not to add path export directives to it. Instead, I added a simple loop to .bash_profile that will read in the files in /etc/paths.d, and put those with a numerical dot suffix before the given path, in order of that suffix. So all I had to do was rename my /etc/paths.d/homebrew to /etc/paths.d/homebrew.1 and its contents started leading the way — uh, path (sorry). If I decide I need to use MacPorts alongside homebrew, but want to give homebrew installs precedence, all I need is a /etc/paths.d/ports.2 file containing whatever paths MacPorts needs to keep its array of libraries and duplicate X installs working. You get the idea.
Here is the loop:
if [ -d "/etc/paths.d/" -a -x "/etc/paths.d/" ]; then
path_temp="$PATH"
for index in {9..1}; do
path_clean="$path_temp"
for file in /etc/paths.d/*.${index}; do
if [ -f "$file" -a -r "$file" ]; then
while read line; do
path_front="${path_front}${line}:"
path_clean=$(printf "$path_clean" | sed s:$line::g)
done < "$file"
fi
done
path_temp=$(printf "${path_front}${path_clean}" | tr -s ':')
done
export PATH="$path_temp"
fi
You will notice that this does a real reshuffling, not just prefixing: paths prepended will be removed from their original position in the path_helper generated version, leaving no duplicates. This is probably totally unnecessary, but duplicates annoy me.
The beauty of the whole thing is it reduces tampering with $PATH elements and precedence to basic file operations (with a dash of sudo): echo to add paths, mv to change their priority, rm to remove them – no more scouring dot files to find that one export directive you know must be there, somewhere. It keeps the main advantage of Apple’s system, easy install and uninstall of system wide paths, while extending it to allow the user to set the order of precedence. Yes, it means editing profile files, but only once (twice if you need it to work in a C shell). After that, it just works.
As it should be.
Smart stuff for shell users. The trick to sync dot files needed by shells via Dropbox is one I have adapted to my needs right away, and using a .source file is pretty certain to follow suit, in Alfred shell scripts if nowhere else.
/via Brett Terpstra
(Source: luoma)
Possibly most importantly, though, the FBI is now presumably in possession of a complete copy of the Instapaper database as it stood on Tuesday morning, including the complete list of users and any non-deleted bookmarks. […]
Linked Facebook, Twitter, or Tumblr accounts only store their respective OAuth keys. Linked Evernote accounts only store the Evernote email-in address. Linked Pinboard accounts, however, store plaintext usernames and encrypted passwords, and the encryption keys are present in the website source code on the server.
So the FBI now has illegal possession of nearly all of Instapaper’s data and a moderate portion of its codebase, and as far as I know, this is completely out of my control.
Yikes. Not only did the FBI disrupt Pinboard’s operations by taking one of their servers, too – they have now full access to the accounts whose credentials were stored in Instapaper.
I’ll have that round of fresh passwords, please.
I know there is a ton more I could post about Apple’s announcements coming out of WWDC. But I think while all of the details and features of iCloud, iOS 5, and Mac OS X Lion are interesting, there is an idea that these technologies surround and support that is far more so.
Patrick Rhone is always a great read, and this post even more so than usual. Still, with only a Stevenote to go on, I find it a bit early to speculate on a paradigm shift in computing.
Apple have always sold more than computers; they have sold a digital ecosystem. They simply had to realize that to save their ecosystem approach, they have to cut the cord. It was that or fade into history, and Jobs is not going to let that happen.
Now, there remains only the wee matter of their track record in cloud services …
I’m not going to tell you I love Markdown. If you strolled in here (hi, by the way), chances are good you do too, so there would be no point.
The only thing holding me back from going Markdown crazy until now has been the fact I didn’t have a Markdown editor I really liked. This has changed with Byword, specifically version 1.2, which has both support for MultiMarkdown (or MMD for short) and for the ODB editing protocol. Using it for Tumblr via QuickCursor (as I did for this post) was a given, but Byword’s editing niceness ignited a loftier ambition: using it to write free style Evernote notes.
Now I’m hearing you say “WTF, Evernote doesn’t support Markdown!”. True. To which I answer with a name: Brett Terpstra.
If you haven’t heard of Brett, it’s time to have a look at his blog. Seriously, it’s awe-inspiring (take your time and check out the Markdown tag; appreciate if you’d come back, though). Brett keeps churning out productivity hacks at a pace that makes me dizzy, and that is besides being an editor at TUAW and having successfully forked Notational Velocity to create his ideal Markdown enabled notes editor. One of his minor projects is a convenient OS X system service converting any selected MultiMarkdown text into an Evernote note. With this and Byword, I was all set. Or so I thought.
The truth is, despite my unadulterated admiration for Brett (as behooves somebody whose whole contribution to the Markdown ecosystem is one very very minor commit to the current developer branch of MMD), his service has a few shortcomings. Rather major ones, in fact.
Issue one, it turns each line of Markdown you pass it into a single new note:

Issue two, it sometimes fails to do anything at all. Brett glossed over this when he mentioned “It does choke once in a while, apparently on Markdown-generated code snippets, but I haven’t quite narrowed down why, yet”.
So I decided to have a look at the code at the core of the service. After all, it’s Ruby, and Ruby is nothing if not readable. Even to total coding oiks like me.
Figuring out the cause for issue one wasn’t too hard (a doubly nested loop, making the script create one note for each line f in its ARG.each block). And once I was there, I couldn’t help myself but pull at the threads. Some stuff came apart easily and some stuff … less so. Mainly because, as I said, I suck at coding (I stared for so long at tag.strip.gsub(/^(.)?\b|\b(.)?$/,"\\2\"\\1") my eyes watered, before finally figuring out what the regex does. Yeah, laugh all you can). Along the way, the script slowly changed, notably in metadata handling:
- you can now specify the notebook the note goes into in your Markdown text’s metadata block, using either
= <name>or in MMD metadata notation, using the custom keyword Notebook; - you can also to specify the title and tags of the note in MMD metadata syntax, using the standard keywords Title and Keywords respectively;
- for consistency with the short title and short notebook syntax, the non-MMD syntax for tags now is
@ <comma separated tag list>; - you can mix short syntax (i.e. “@” for tags, “=” for the notebook and “#” for the title ) and MMD syntax metadata lines freely, but both will only be parsed inside the MMD metadata block, so you don’t have to worry about random paragraphs starting with metadata keywords being stripped out of your text (note that if you provide multiple metadata lines in the block, only the last one will be kept). The one exception to this being atx style 1st level headings (i.e.
# My heading), which are intrinsically outside the metadata block anyway and will be parsed anywhere; the first one becomes the title, the others are stripped from the Markdown.
While I was at it, I also fixed some other stuff, so that the script now:
- uses a localized date time stamp (courtesy of AppleScript) instead of a US formatted one as a fallback note title.
- uses the default notebook set in Evernote if you omit to name one (instead of defaulting to a notebook called “Untitled”);
- correctly parses tag names with any amount of punctuation (except commas, obviously, as they separate tags from each other) and other “special” characters;
- correctly assigns multiple tags (instead of quietly failing);
- correctly parses all flavors of 1st level atx headings (not just those following the hash with a space; granted, that is the most common way of writing them, but Markdown will parse anything as a heading as long as the line starts with “#”);
- will quietly exit if the Markdown and smart typography executables indicated are not available to you (which, alongside the fact PEG Markdown and its derivatives integrate smart typography via a command line switch instead of an external script [with PEG MultiMarkdown, aka MMD 3, having it on by default, with an “off” switch upcoming], is the reason for the breakdown of what was one simple command line string into no less than five distinct constants);
- will run on both Ruby 1.8 (which is used by Automator on Leopard and Snow Leopard) and Ruby 1.9 (which will hopefully make the cut into Lion);
- oh, and it defaults to MMD 3 (instead of the MMD 2 Perl script).
And what about issue two? That one took me a while to pinpoint (and it’s at the root of my somewhat unexpected contribution to the MMD 3 code base). Actually, what the original script would choke on are straight single quotes, that’s “'” to you. The reason for this is it pipes the AppleScript command that talks to Evernote proper into osascript -e, and bash’s command line parsing will not handle nested single quotes (tip of the hat to Stuart Colville for the details). I sidestepped this by writing the whole AppleScript command to a Ruby Tempfile and passing that to osascript instead. The fact Brett only noticed the issue on code blocks is due to him having smart typography on, which will turn straight single quotes into proper single quotes – except in code blocks. As a side effect, it’s also safe to use straight single quotes in the notebook title now. In tag names too, for that matter.
What is left? Well, I could try to make the thing understand Setext headings, but as I never use these and it’s not quite as straightforward as the rest of the parsing (the heading proper being the line that precedes the heading markers, and input is parsed line by line), I won’t bother for now. Oh, and you could make a case that if a Title metadata line is provided, 1st level Markdown headings should be left alone. Jury’s still out on that one, but, for the time being, you can use a Setext style heading instead if the stripping of 1st level atx style headings bothers you.
Find the zipped service over here. The code is also up as a GitHub gist over here.
And to Brett Terpstra, all I can say is:
I luv your code so much
I has fixed it