Loving Hipmunk
My new favorite flight reservation site is www.hipmunk.com.
Maybe it’s because I’m a visual person, but I find the flight display, all on one page, all on the same timeline way easier to use than the long lists that I get from other sites.
The prices look identical as well. Now, I haven’t actually used hipmunk to make any reservations — and Expedia has come through for me a couple of times when I had problems while on a trip — but I’m definitely going to give them a try and hope their UI skills carry over into their travel service skills.
I tried their hotel reservations as well. It has a great map-based interface, but the selection seems a little slim. I was looking for a place in Mexico City, so maybe they’ve yet to fully populate it. Once they do, it will be my first choice as well.
Semantic Things
I’m jumping back into semantics – the computer version that is. I’ll be using this blog to note tools, techniques and other things semantic that I find interesting.
I’ts been a while since I gave this any serious attention and my brief forays make me wonder if much progress has been made in the last 20+ years. I was encouraged somewhat when I attended the Semantic Web Summit East in November. I joined the Cambridge Semantic Web Monthly Meetup and attended the December meetup.
As I bring myself up to speed, I’ll post what I find here, under the category Semantic Things.
Emacs elisp regex preprocessor hack
I write a lot of elisp — that’s Emacs Lisp. I’m experimenting with Clojure, and may yet find a role for it, but for now, Emacs and elisp will remain our workhorses.
My brain has no trouble with lots of embedded parentheses, but escaped regular expressions drive me crazy. I just can’t read them. And Emacs Lisp requires they be doubly escaped. Trying to debug a simple doubly-escaped expression like this:
“\\([Aa][n]?[ ]*\\)?\\(\\(\\([Cc]ountry\\)\\|\\([Rr]epublic\\)\\|\\([Ii]ndependent [Ss]tate\\)\\|\\([Kk]ingdom\\)\\|\\([Mm]onarchy\\)\\|\\([Cc]onstitutional [Mm]onarchy\\)\\)\\|\\(\\(\\([Aa]utonomous\\)\\|\\([Ff]ederal\\)\\|\\([Ii]sland\\)\\|\\([Ii]slamic\\)\\|\\([Ii]ndependent\\)\\)[ ]*\\(\\([Cc]ountry\\)\\|\\([Rr]epublic\\)\\|\\([Ss]tate\\)\\)\\)\\)”
makes my head hurt — and it’s actually a single line. This one is used when we are trying to find all references to a country in one of our geographic dictionaries.
My hack is not perfect, but it allows me to write the above in a more readable form:
"([Aa][n]?[ ]*)? ( ( ([Cc]ountry) | ([Rr]epublic) | ([Ii]ndependent [Ss]tate) | ([Kk]ingdom) | ([Mm]onarchy) | ([Cc]onstitutional [Mm]onarchy) ) | ( ( ( [Aa]utonomous) | ([Ff]ederal) | ([Ii]sland) | ([Ii]slamic) | ([Ii]ndependent) ) [ ]* ( ([Cc]ountry) | ([Rr]epublic) | ([Ss]tate) ) ) )
The lisp code I use to do the pre-processing is simple — I include this in a “common” file which I load automatically whenever I start emacs.
(defun xr-escape-regex (regex-string &optional nparam) ;; Temporarily save character alternatives like: [a-zA-Z] (let ((ca-regex "\\[[^]]+\\]")) ;; increment n to mark the location of the replaced character alternatives ;; no character alt's left, escape the remaining string (cond ((not (string-match ca-regex regex-string)) (xr-escape-regex-basic regex-string)) ;; if we have a [ ] expression, replace it with an indexed placeholder (t (let* ((n (if nparam nparam 0)) (ca-place-marker (format "---------- %d ----------" n)) (saved-ca (match-string 0 regex-string)) ;; add the temporary replacement (regex-string-ca-removed (replace-match ca-place-marker t t regex-string))) ;; recurse on the modified string, ;; putting the ca's back as we come back up the stack. (xr-replace-string (xr-escape-regex regex-string-ca-removed (1+ n)) ca-place-marker saved-ca) ))))) (defun xr-escape-regex-basic (regex-string) "Helper function that escapes '(', ')' '|'. Will happily escape these chars even if inside of [], so should not be called directly. Allows white space around the (, ) and | characters. Uses xr-replace-string, because emacs replace-regex-in-string chokes if rep contains \\." (xr-replace-string (xr-replace-string (xr-replace-string (xr-replace-string (xr-replace-string regex-string "[ \t\n]*([ \t\n]*" "\\(") "[ \t\n]*)[ \t\n]*" "\\)") "[ \t\n]*{[ \t\n]*" "\\{") "[ \t\n]*}[ \t\n]*" "\\}") "[ \t\n]*|[ \t\n]*" "\\|")) (defun xr-replace-string (string regexp replacement) "Replace all occurrences in string matched by regexp with replacement." (save-match-data (mapconcat (function (lambda (x) x)) (split-string string regexp) replacement)))
To use it, I usually create a variable to hold the compiled regex and then use it where needed. If it’s a global, it will look like this:
(defvar xr-ont-regex-capital-to-trim nil) (setq xr-ont-regex-capital-to-trim (xr-escape-regex "and[ ]+((chief)|(only)|(largest))[ ]+(large[ ]+)?((city)|(town))[ ]+"))
After the setq, the global will hold the regex string:
“and[ ]+\\(\\(chief\\)\\|\\(only\\)\\|\\(largest\\)\\)[ ]+\\(large[ ]+\\)?\\(\\(city\\)\\|\\(town\\)\\)[ ]+
For complex regular expressions, especially ones where white space actually matters, this function can produce bad results. Most of my regular expressions are not that complex. I’ve so far been able to work around this by simply embedding the white space in character alternative tags.
It works fine in GNU Emacs. I’ve not tested it with any other flavor.
ALA Midwinter Tech Showcase Slides
In January, I gave a brief Technology Showcase presentation at the American Library Association’s Midwinter conference in Boston. The Technology Showcase is a forum for companies to “highlight the latest trends in library technology.” Our (Credo Reference Limited) slot was the last session of the last day, so attendance was a bit less than the numbers who showed up for Al Gore’s earlier keynote. It was still fun and some of those attending even took notes.
We announced “Topic Pages” at the conference — a new approach to presenting and organizing reference resources around a single topic — and the talk described how we select topics, select the content that goes with them and how we describe related topics.
Presentation slides are shared from my Google docs account here: Presentation Slides
Rackspace Cloud
I’ve been buried in a new project that requires moving our company servers onto a more flexible platform. After a little investigating, we decided to use the Rackspace Cloud.
So far, so good. In a couple of weeks we’ve created and configured 6 servers, running Java, Tomcat, Apache and Postgres all connected to Boston and our existing London site using OpenVPN. It’s been remarkably easy. We’re currently running a beta test, with selected customers on this configuration.
Now that things have settled down a bit, I’ll add some details over the coming days describing what we did, and how we did it.
Firefox new windows at random times
I was ready to trash Firefox after the last upgrade. Tabs kept turning into new windows in response to trivial mouse movements. It’s a bug — an extremely annoying one — clicking a tab once and then moving your mouse down causes a new window to open.
To fix, download this “Disable detach and tear off tab” addon:
https://addons.mozilla.org/en-US/firefox/addon/12276
- Install it.
- Click tools >> Add-ons (or type Alt-T, Alt-A).
- On the bug489729, click “Options”.
- Check “Disable detach tab”.
- Click “OK”.
Enabling “Drop URL” will restore an older Firefox feature that lets you drag a Tab to a folder to create a link.
My New Netbook — an Eee PC
For father’s day, I was given my choice of netbooks. With very little though, I chose an Eee Pc. It’s small, not too expensive ($299 at Best Buy) and cute. I opted for the dark blue one.
I’m setting it up, with the goal of have as few apps as possible running locally. Ideally, I’d like to have only a browser and, until single signon actually works, a password vault. So here goes. It came with Windows XP home — I made sure I wasn’t going to get stuck with Vista. ideally, I would like to try Ubuntu, but I’m sharing it at times with my spouse and she’s more comfortable with windows. Perhaps when Chrome really is an OS, I’ll replace Windows.
The setup wizard was only a few clicks. It found the LAN fine, then asked be if I wanted to connect to my wireless. That was easy too.
Skype was preinstalled, so I signed in. It was the older client, which I like a lot better than the new one.
IE was preinstalled, with Bing as the default search engine. I took a small amount of pleasure in making my first search “Firefox”. It was odd that the results page pointed my to an older version of Firefox. A search for Firefox 3.5 landed my on the right page. Firefox offerred to import the IE bookmarks — whatever they were — but I skipped that step.
The first Firefox extension I installed was Xmarks . I’ve been using it on my development laptop for a few months. It promises to synchronize all bookmarks across PC’s, so here’s my first test. After the install, the Xmarks wizard appeared and asked if I had an account. Once logged in, it offered several synch options. I chose ‘keep the data on the server, discard data on this computer’ since I wanted my netbook to mirror the bookmarks on my laptop. I was also given the option to save passwords. I declined. Still too paranoid. One warning and a click later, followed by a 10 second I had all of my laptop bookmarks on my netbook. Nice!
After getting nagged a few times, by different sites I visited, I installed Flash.
Next was Seesmic Desktop — there’s just no web client that I like as well for using Twitter. Seesmic Desktop is built on Adobe Air, so I had to install that as well. Added my bit.ly api key so I could post short urls and track them. And, right after doing this, I discovered that Seesmic has a web app. So far, not able to configure my own bit.ly api key, so for now I’ll stick with the desktop app.
Next step was to reset the windows start menu and controll panel to classic mode. Much nicer than the XP versions.
The Eee comes with a trial version of Microsoft Office preinstalled. Opening the control panel, selecting add/remove programs, scrolling down to MS office and selecting “remove” almost took care of that. After removing office, I was left with a vestigial Power Point viewer that I had to remove as well.
So after about 45 minutes, I’ve got Firefox 3.5, with all of my bookmarks, my password vault and Seesmic desktop.
It’s time to actually use it. I’ve got a presentation scheduled in a few days and have a dozen slides drafted in Powerpoint on my laptop. I’m hoping that I’ll be able to complete tham and do the presentation on my Netbook. I’ll describe how that works in my next post.
Daily Reads Moved to Twine
I’m now able to find my way around Twine, still stumbling, but oriented enough that I’m moving my daily reads. You can find them at:
www.twine.com/user/astevens
Twine makes it easy to save a bookmark, image or video. It organize these, along with comments around interests.
But it’s biggest feature is that it makes it easy to share them with other people who share similar interests. Nova Spivak, the founder calls it an “interest network”. It’s at an early stage, but I still find it an intellectually stimulating refuge from the over-hyped and attention-draining worlds of Twitter and Facebook.
Into the Cloud: PHP Anywhere
I’ve been distracted from my project to move my laptop apps onto web-based “cloud” services, but I’ve managed to progress on one front.
I discovered phpanywhere a web based IDE for the PHP language. It includes a real-time syntax-aware editor and FTP access to files.
One of the things I’ve been most concerned about is how to replace PHP Eclipse. This has the possibility of doing that.
Friday’s reads
Strong developer opinions, including “PHP is Crap“, and discussion about PHP, MySQL, PostgreSQL. [Julian Andres Klode on his blog]
Today, I’m trying to grok Twine
So, today’s reads include some old articles.
A high level overview of Twine, at the time it was announced, by an investor. [Peter Rip on EarlyStasgeVC October 19, 2007 ]
Twine first impressions summarized from various blog posts right after its public announcement. [Richard McMannus on Thinking Space October 21, 2007]