Home Link

Hello, my name is Brett Terpstra, and it’s nice to meet you. Elegant solutions to complex problems. Curious?

Archive for the ‘Code’ Category

  • Jan
  • Feb
  • Mar
  • Apr
  • May
  • Jun
  • Jul
  • Aug
  • Sep
  • Oct
  • Nov
  • Dec

Mar 08
2010

I posted a way to save your Safari tabs to Ever­note, which I’ve found is gen­er­ally a great way to save book­marks. It syncs auto­mat­i­cally to your other com­put­ers and your iPhone, and it’s fast and easy. If you really want to high­light a few tabs to make sure you get back to them, you might con­sider this script, though. Once you’ve saved your entire Safari brows­ing ses­sion for later, close every­thing except for those spe­cial urls, run the code below as a script, and your open tabs will be saved as entries in your InstaPa­per account.

There are two “prop­erty” lines at the top of the script; edit them to set your Instapa­per user­name and pass­word (if you have one, oth­er­wise, set it to ""). The next sec­tion han­dles every­thing, iter­at­ing through each tab, grab­bing its title and url and build­ing a shell com­mand to do a sim­ple curl call to the InstaPa­per API.

After that, the rest of the script is a rou­tine for url encod­ing that I nicked here. It’s called when set­ting both the _title and _url vari­ables to make the curl call from the shell work. I haven’t tested this exten­sively yet, but it’s worked for every­thing I’ve tried. A title with odd char­ac­ters in it could poten­tially cause prob­lems. You can always add a shell-escaping routine…


property _user : "yourusername"
property _pass : "yourpassword"

tell application "Safari"
    repeat with _tab in tabs of front window
        set _title to my urlencode(name of _tab)
        set _url to my urlencode(URL of _tab)
        set _script to (¬
            "curl 'https://www.instapaper.com/api/add?username="¬
            & _user & "&password=" & _pass & "&url=" & _url & "&title=" & _title & "'")
        set output to do shell script _script
    end repeat
end tell

on urlencode(theText)
    set theTextEnc to ""
    repeat with eachChar in characters of theText
        set useChar to eachChar
        set eachCharNum to ASCII number of eachChar
        if eachCharNum = 32 then
            set useChar to "+"
        else if (eachCharNum ≠ 42) and (eachCharNum ≠ 95) and¬
            (eachCharNum < 45 or eachCharNum > 46) and (eachCharNum < 48 or eachCharNum > 57)¬
            and (eachCharNum < 65 or eachCharNum > 90) and (eachCharNum < 97 or eachCharNum > 122) then
            set firstDig to round (eachCharNum / 16) rounding down
            set secondDig to eachCharNum mod 16
            if firstDig > 9 then
                set aNum to firstDig + 55
                set firstDig to ASCII character aNum
            end if
            if secondDig > 9 then
                set aNum to secondDig + 55
                set secondDig to ASCII character aNum
            end if
            set numHex to ("%" & (firstDig as string) & (secondDig as string)) as string
            set useChar to numHex
        end if
        set theTextEnc to theTextEnc & useChar as string
    end repeat
    return theTextEnc
end urlencode

Open this script in your Script Editor.

Mar 06
2010

Another post, quickly and with less explanation…

The fact that Ever­note processes HTML so much bet­ter than it does plain or rich text got me think­ing and tin­ker­ing. I use Mark­down (actu­ally, Mul­ti­Mark­down) con­stantly, and it does a great job of turn­ing plain text into valid markup. With (Multi)Markdown, even plain text becomes HTML that–when imported into Evernote–retains most of its for­mat­ting. To answer your ques­tion, no, I’m not obsessed with Ever­note, I’m obsessed with prob­lems I think I could solve. It’s unhealthy.

Please note, this requires that you have Fletcher Penney’s Mul­ti­Mark­down installed in ~/Library/Application Support/MultiMarkdown, and that the Perl files (MultiMarkdown.pl and SmartyPants.pl) are located in a ‘bin’ sub­di­rec­tory (which is the default install). If you don’t have Mul­ti­Mark­down, you should get it any­way (all the cool kids have it), so head over to the down­load page and grab a copy. Now, on with the show.

I set this up orig­i­nally as a Text­Mate com­mand, intend­ing just to be able to clip code snip­pets and free-form text to Ever­note with­out think­ing too much about it. That worked well, so I mod­i­fied it to work as a Sys­tem Ser­vice. Specif­i­cally, a Snow Leop­ard ser­vice, but I’m pro­vid­ing the Ruby script here and it can be mod­i­fied for any Mac setup you want.

While it will work just fine on plain text with no markup, it does have a cou­ple of “spe­cial” fea­tures. If you start a line with a # and a space (e.g.: # This is my header), which is a Mark­down con­ven­tion for a first-level head­ing, it will use that as the title for the note and strip it out of the text in pro­cess­ing. It only uses the first one it finds, but it will strip out any first-level head­ers in the selec­tion. I’ll prob­a­bly mod­ify that later, or just have it leave them in. Also, a line that begins with “tags:” fol­lowed by a space and a comma-separated list of words will be split up and used to tag the new note. This is also stripped before pro­cess­ing. It han­dles spaces in multi-word tags, and odd marks at the begin­ning or end of a tag, but only one punc­tu­a­tion char­ac­ter, and only at the begin­ning or end of a tag. The code follows…

Con­tinue read­ing “A bet­ter Sys­tem Ser­vice for Ever­note clip­ping — with MultiMarkdown…”

Mar 06
2010

Just a quick change to my post on the bash func­tion fk that I’ve been using. A small mod­i­fi­ca­tion has greatly improved its usabil­ity: make the can­cel option always be first in the menu. Just move “Can­cel” before the $(fp $1) bit. It’s a lit­tle odd that I didn’t do that to begin with…


fp () { #find and list processes matching a case-insensitive partial-match string
        ps Ao pid,comm|awk '{match($0,/[^\/]+$/); print substr($0,RSTART,RLENGTH)": "$1}'|grep -i $1|grep -v grep
}

fk () { 
    IFS=$'\n'
    PS3='Kill which process? (1 to cancel): '
    select OPT in "Cancel" $(fp $1); do
        if [ $OPT != "Cancel" ]; then
            kill $(echo $OPT|awk '{print $NF}')
        fi
        break
    done
    unset IFS
}

Mar 06
2010

I pri­mar­ily use Safari for web brows­ing, mostly because it’s smoother and faster than Fire­fox, and the Web Inspec­tor is just as use­ful as Fire­bug. As time passes, I end up with a lot of web pages open, and I like to clear out my browser tabs on a reg­u­lar basis. Safari doesn’t really have a long-term session-saving option, so I save lists of open tabs to var­i­ous appli­ca­tions. I used to use Safari­S­tand to do this, but it got too buggy and slow for me. I use VoodooPad for it, but I like the sort­ing and search­ing option in Ever­note, both on my desk­top, and synced online and to my iPhone.

As much as I love Ever­note, its edi­tor is, well, a has­sle. Import­ing text clip­pings can strip line breaks and leave you with quite a mess, and clean­ing it up is less than pleas­ant. I’ve found that using Apple­Script, HTML and Ever­note together allows me to cre­ate pretty well-formatted notes from web and text clip­pings, aside from using Evernote’s PDF fea­tures. In most cases—like web­site clippings—I don’t need or want a full PDF, replete with ads and com­ments (Clip­pable was designed with that in mind). The trick when cre­at­ing a note in Ever­note via Apple­Script is to use a lit­tle HTML to get the basic for­mat­ting. Evernote’s Apple­Script library pro­vides a com­mand tai­lored to this purpose.

To demon­strate, I’ll show you how to save your brows­ing ses­sion in Safari as a nicely for­mat­ted list in Ever­note. For this I set up a new Note­book called “Book­marks,” and am keep­ing the markup very sim­ple. Ever­note strips most styling from imported HTML, but accepts struc­tural items like head­lines, lists, tables, etc., apply­ing its own default for­mat­ting to the elements.

Con­tinue read­ing “Sav­ing Safari brows­ing ses­sions to Evernote…”

Dec 31
2009

Down­load the Eval­u­ate Expres­sion Snow Leop­ard ser­vice: EvaluateExpressionService.zip

This is a stripped down ver­sion of a com­mand I have in the Text­Mate bun­dle we use at TUAW. It allows you to select any basic numeric equa­tion and eval­u­ate it, replac­ing the selected text with the results. It will ignore your text if it con­tains any­thing but num­bers and basic math­e­mat­i­cal sym­bols. Sure, there are plenty of ways to do cal­cu­la­tions in OS X (Spot­light, Launch­bar, Quick­sil­ver), but I’ve had more and more inci­dents lately where I just wanted to do quick cal­cu­la­tions inline, so I whipped this up. A lit­tle explanation…

Con­tinue read­ing “A (fairly) sim­ple equa­tion eval­u­a­tion ser­vice for Snow Leopard…”

Dec 31
2009

I made a cou­ple of minor changes to the Clip­pable book­marklet, mostly in the way it han­dles Syn­tax­High­lighter code blocks. The Syn­tax­High­lighter plu­gin is used (too) often to for­mat and color code source snip­pets in web­sites. The result when clip­ping a page is that the code you get still has line num­bers, but no option to view the raw source with­out going back to the web page. Then you end up man­u­ally edit­ing out the line num­bers if you want to copy and paste the code, which can be a pain in most cases.

Since the point of Clip­pable was to deal bet­ter with things like code blocks (espe­cially for sav­ing snip­pets to Ever­note), it now removes the tool­bar and line num­bers from Syn­tax­High­lighter blocks. It also looks for another com­mon tech­nique: con­vert­ing lines in code to an ordered list inside of a pre block. This is just blot­ted out with CSS now. Those are the only two high­light­ing meth­ods it tar­gets at the moment, but I’ll tackle more as I run into them.

If you already have the book­marklet installed, you’re already ben­e­fit­ting from these changes (the book­marklet calls the source scripts on my server, so it is, in essence, auto­mat­i­cally updated). If not, just cruise over to the Clip­pable page and grab it!

Nov 17
2009

I do a lot in Ter­mi­nal. Some­times, it’s eas­ier. Some­times it’s faster. Some­times I’d just rather type it out. What­ever the rea­son, I’ve never been able to stand look­ing at a bor­ing shell prompt. Bash is my pri­mary shell, mostly because I’ve never taken the time to learn much else. I’ll get there some­day. For now, here’s my cur­rent Bash shell prompt…

I’m using the PROMPT_COMMAND vari­able to run a few quick func­tions to gen­er­ate the prompt. It doesn’t do any­thing processor-intensive, so I haven’t seen any lag caused by this one (unlike some of my pre­vi­ous exper­i­ments). PROMPT_COMMAND is set to call a func­tion called, appro­pri­ately, prompt_command(). This, in turn, calls a few exter­nal func­tions defined in my .bash_profile. To use it, just stick all of the code below into your .bash_profile, and mod­ify it as you see fit. Be sure to replace any def­i­n­i­tions of PROMPT_COMMAND or PS1.

Con­tinue read­ing “My new favorite Bash prompt…”

Entries (RSS) and Comments (RSS).

Switch to Mobile version