tsenart/sight — pull request #30 by 13k (2012-07-30 14:46:36+00:00)
Title: [feature proposal] Add ability to specify/force language via URL fragments

Hi,

Let me note first that this is just a proposal, a brainstorming, so many things I wrote are my very personal taste.

### Rationale

Recently I was using the extension and came across a .txt file that contained XML, so Sight didn't detect it and I didn't have the ability to specify/overwrite the language detection. Then I came up with this idea of doing this using URL fragments.

Since we are not interested in HTML content, which is exactly the only place fragments have any effect, using fragments here won't affect any previous behavior or conflict with any page that uses it.

Another approach to this would be to implement an overlay to change languages, like [syntaclet][syntacleturl] does, which is a big work and probably doesn't goes well with the idea of having an extension hidden under the covers detecting and doing syntax highlighting automatically for me (if that's the case for Sight, I'm just assuming this here).

### Usage

To specify language or overwrite the auto-detected one, just pass a fragment, like: `http://example.com/file.txt#syn=xml`, which is in the format:

`syn` is the fragment "argument" name (I quickly choose because I use vim and changing syntax is like `set syn=xml`), then `=`, then `xml`, the language name, not file extension.

Of course changing `syn` to anything is easy (and recommended I think...)

### Details

To make this work, I had to partially rewrite the language detection part, which now does this, in order:

1. use URL fragment, or
2. use content-type from headers, or
3. use file extension

Since the URL parsing thing was getting a little bit out of control (you have to account for N exception cases, like trailing slashes, which current code isn't; or URLs like http://jsonip.com which doesn't have a filename; etc) and then added the fragment parsing complexity, plus the fact that this matching is done for every request, I decided to add a external dependency on [URI.js][urijsurl], which is a well maintained, popular, URL parsing library from the NodeJS community (of course it can run on browsers too), so parsing became a matter of using one function and get a JS object with the URL parts, nice!

I also did a little performance improvement (not really benchmarked anything, just gut instincts) by reversing key/values from the `LANG_MAP` into `EXT_MAP` (one time only at startup) and performing direct key lookups in the map instead of the previous nested for-loops.

[syntacleturl]: http://www.syntaclet.com/
[urijsurl]: http://medialize.github.com/URI.js