I've made another extension for IE8, Outline View, which gives you a side bar in IE that displays an outline of the current page and lets you make intrapage bookmarks.
The outline is generated based on the heading tags in the document (e.g. h1, h2, etc), kind of like what W3C's Semantic data extractor tool displays for an outline. So if the page doesn't use heading tags the way the HTML spec intended or just sticks img tags in them, then the outline doesn't look so hot. On a page that does use headings as intended though it looks really good. For instance a section from the HTML 4 spec shows up quite nicely and I find its actually useful to be able to jump around to the different sections. Actually, I've been surprised going to various blogs how well the outline view is actually working -- I thought a lot more webdevs would be abusing their heading tags.
I've also added intrapage bookmarks. When you make a text selection and clear it, that selected text is added as a temporary intrapage bookmark which shows up in the correct place in the outline. You can navigate to the bookmark or right click to make it permanent. Right now I'm storing the permanent intrapage bookmarks in IE8's new per-domain DOM storage because I wanted to avoid writing code to synchronize a cross process store of bookmarks, it allowed me to play with the DOM storage a bit, and the bookmarks will get cleared appropriately when the user clears their history via the control panel.
Sarah and I are back from Munich, Germany as of Thursday and I've just about recovered. The trip there via Air France we watched many movies and it was much better than the trip back in which the entertainment system failed and I had a cold. When we arrived, Jon met us at the airport, helped us with the subway system, we played Guitar Hero, ate at a Bavarian pub, and then later at an Australian bar.
The following day we met up with Jon and three of his friends, one of whom was visiting from England and we all took a train to Neuschwanstein Castle. Apparently its the 'Disney' castle in that Disney's castle's are based upon it. The castle is filled with images and statues of swans in homage to the Swan Knight. We ate in the town at a cafe with traditional Bavarian food before taking the train back and getting all you can eat fajitas for dinner.
PowerShell gives us a real CLI for Windows based around .Net stuff. I don't like the creation of a new shell language but I suppose it makes sense given that they want something C# like but not C# exactly since that's much to verbose and strict for a CLI. One of the functions you can override is the TabExpansion function which is used when you tab complete commands. I really like this and so I've added on to the standard implementation to support replacing a variable name with its value, tab completion of available commands, previous command history, and drive names (there not restricted to just one letter in PS).
Learning the new language was a bit of a chore but MSDN helped. A couple of things to note, a statement that has a return value that you don't do anything with is implicitly the return value for the current function. That's why there's no explicit return's in my TabExpansion function. Also, if you're TabExpansion function fails or returns nothing then the builtin TabExpansion function runs which does just filenames. This is why you can see that the standard TabExpansion function doesn't handle normal filenames: it does extra stuff (like method and property completion on variables that represent .Net objects) but if there's no fancy extra stuff to be done it lets the builtin one take a crack.
Here's my TabExpansion function. Probably has bugs, so watch out!
function EscapePath([string] $path, [string] $original)
{
if ($path.Contains(' ') -and !$original.Contains(' '))
{
'"' $path '"';
}
else
{
$path;
}
}
function PathRelativeTo($pathDest, $pathCurrent)
{
if ($pathDest.PSParentPath.ToString().EndsWith($pathCurrent.Path))
{
'.\' $pathDest.name;
}
else
{
$pathDest.FullName;
}
}
# This is the default function to use for tab expansion. It handles simple
# member expansion on variables, variable name expansion and parameter completion
# on commands. It doesn't understand strings so strings containing ; | ( or { may
# cause expansion to fail.
function TabExpansion($line, $lastWord)
{
switch -regex ($lastWord)
{
# Handle property and method expansion...
'(^.*)(\$(\w|\.) )\.(\w*)$' {
$method = [Management.Automation.PSMemberTypes] `
'Method,CodeMethod,ScriptMethod,ParameterizedProperty'
$base = $matches[1]
$expression = $matches[2]
Invoke-Expression ('$val=' $expression)
$pat = $matches[4] '*'
Get-Member -inputobject $val $pat | sort membertype,name |
where { $_.name -notmatch '^[gs]et_'} |
foreach {
if ($_.MemberType -band $method)
{
# Return a method...
$base $expression '.' $_.name '('
}
else {
# Return a property...
$base $expression '.' $_.name
}
}
break;
}
# Handle variable name expansion...
'(^.*\$)([\w\:]*)$' {
$prefix = $matches[1]
$varName = $matches[2]
foreach ($v in Get-Childitem ('variable:' $varName '*'))
{
if ($v.name -eq $varName)
{
$v.value
}
else
{
$prefix $v.name
}
}
break;
}
# Do completion on parameters...
'^-([\w0-9]*)' {
$pat = $matches[1] '*'
# extract the command name from the string
# first split the string into statements and pipeline elements
# This doesn't handle strings however.
$cmdlet = [regex]::Split($line, '[|;]')[-1]
# Extract the trailing unclosed block e.g. ls | foreach { cp
if ($cmdlet -match '\{([^\{\}]*)$')
{
$cmdlet = $matches[1]
}
# Extract the longest unclosed parenthetical expression...
if ($cmdlet -match '\(([^()]*)$')
{
$cmdlet = $matches[1]
}
# take the first space separated token of the remaining string
# as the command to look up. Trim any leading or trailing spaces
# so you don't get leading empty elements.
$cmdlet = $cmdlet.Trim().Split()[0]
# now get the info object for it...
$cmdlet = @(Get-Command -type 'cmdlet,alias' $cmdlet)[0]
# loop resolving aliases...
while ($cmdlet.CommandType -eq 'alias') {
$cmdlet = @(Get-Command -type 'cmdlet,alias' $cmdlet.Definition)[0]
}
# expand the parameter sets and emit the matching elements
foreach ($n in $cmdlet.ParameterSets | Select-Object -expand parameters)
{
$n = $n.name
if ($n -like $pat) { '-' $n }
}
break;
}
default {
$varNameStar = $lastWord '*';
foreach ($n in @(Get-Childitem $varNameStar))
{
$name = PathRelativeTo ($n) ($PWD);
if ($n.PSIsContainer)
{
EscapePath ($name '\') ($lastWord);
}
else
{
EscapePath ($name) ($lastWord);
}
}
if (!$varNameStar.Contains('\'))
{
foreach ($n in @(Get-Command $varNameStar))
{
if ($n.CommandType.ToString().Equals('Application'))
{
foreach ($ext in @((cat Env:PathExt).Split(';')))
{
if ($n.Path.ToString().ToLower().EndsWith(($ext).ToString().ToLower()))
{
EscapePath($n.Path) ($lastWord);
}
}
}
else
{
EscapePath($n.Name) ($lastWord);
}
}
foreach ($n in @(Get-psdrive $varNameStar))
{
EscapePath($n.name ":") ($lastWord);
}
}
foreach ($n in @(Get-History))
{
if ($n.CommandLine.StartsWith($line) -and $n.CommandLine -ne $line)
{
$lastWord $n.CommandLine.Substring($line.Length);
}
}
# Add the original string to the end of the expansion list.
$lastWord;
break;
}
}
}
Sarah asked me if I knew of a syntax highlighter for the QuickBase formula language which she uses at work. I couldn't find one but thought it might be fun to make a QuickBase Formula syntax highlighter based on the QuickBase help's description of the formula syntax. Thankfully the language is relatively simple since my skills with ANTLR, the parser generator, are rusty now and I've only used it previously for personal projects (like Javaish, the ridiculous Java based shell idea I had).
With the help of some great ANTLR examples and an ANTLR cheat sheet I was able to come up with the grammar that parses the QuickBase Formula syntax and prints out the same formula marked up with HTML SPAN tags and various CSS classes. ANTLR produces the parser in Java which I wrapped up in an applet, put in a jar, and embedded in an HTML page. The script in that page runs user input through the applet's parser and sticks the output at the bottom of the page with appropriate CSS rules to highlight and print the formula in a pretty fashion.
What I learned:
Netflix has recommended three party movies over my time with Netflix and if you're OK with movies featuring sex, drugs, rock&roll (or techno) as almost the main character then I can recommend at least The Boys and Girls Guide to Getting Down.
24 Hour Party People is based on the true story of Tony Wilson, journalist, band manager, and club owner (not all at once) around the rise of punk and new wave in England. Like many true-story based movies it starts off strong and very interesting but gets very slow at the end like the writers got bored and just started copying the actual events. Unless you have some interest in the history of music in the 80s in Manchester I don't recommend this movie.
Human Traffic is fun and funny following a group of friends going out for a night of clubbing and partying. I had to get over seeing John Simm as not The Master from Doctor Who but rather as a partying youth. It felt like it was geared towards viewers who were on something like the totally odd techno musical interludes with the characters dancing for no apparent reason. Otherwise the movie was good.
The Boys and Girls Guide to Getting Down is done in the style of an old educational movie on the topic of clubbing and partying. It sounds like a premise that would get old but they do a good job. While demonstrating drinking and driving they have scientists push a mouse around in a toy convertible. Enough said. It was funny and I recommend it.
I just upgraded to the Zune 3.0 software which includes games and purchasing music on the Zune via WiFi and once again I'm thrilled that the new firmware is available for old Zunes like mine. Rooting around looking at the new features I noticed Zune Badges for the first time. They're like Xbox Achievements, for example I have a Pixies Silver Artist Power Listener award for listening to the Pixies over 1000 times. I know its ridiculous but I like it, and now I want achievements for everything.
Achievements everywhere would require more developments in self-tracking. Self-trackers, folks who keep statistics on exactly when and what they eat, when and how much they exercise, anything one may track about one's self, were the topic of a Kevin Kelly Quantified Self blog post (also check out Cory Doctorow's SF short story The Things that Make Me Weak and Strange Get Engineered Away featuring a colony of self-trackers). For someone like me with a medium length attention span the data collection needs to be completely automatic or I will lose interest and stop collecting within a week. For instance, Nike iPod shoes that keep track of how many steps the wearer takes. I'll also need software to analyze, display, and share this data on a website like Mycrocosm. I don't want to have to spend extreme amounts of time to create something as wonderful as the Feltron Report (check out his statistic on how many daily measurements he takes for the report). Once we have the data we can give out achievements for everything!
Carnivore Eat at least ten different kinds of animals. |
|
Make Friends Meet at least 10% of the residents in your home town. |
|
Globetrotter Visit a city in every country. |
|
You're Old Survive at least 80 years of life. |
Of course none of the above is practical yet, but how about Delicious achievements based on the public Delicious feeds? That should be doable...
As noted previously, my page consists of the aggregation of my various feeds and in working on that code recently it was again brought to my attention that everyone has different ways of representing tag metadata in feeds. I made up a list of how my various feed sources represent tags and list that data here so that it might help others in the future.
Source | Feed Type | Tag Markup Scheme | One Tag Per Element | Tag Scheme URI | Human / Machine Names | Example Markup |
---|---|---|---|---|---|---|
LiveJournal | Atom | atom:category | yes | no | no | , (source) |
LiveJournal | RSS 2.0 | rss2:category | yes | no | no |
technical (soure) |
WordPress | RSS 2.0 | rss2:category | yes | no | no |
, (source)
|
Delicious | RSS 1.0 | dc:subject | no | no | no |
photosynth photos 3d tool (source) |
Delicious | RSS 2.0 | rss2:category | yes | yes | no |
domain="http://delicious.com/SequelGuy/"> (source) |
Flickr | Atom | atom:category | yes | yes | no |
term="seattle" (source) |
Flickr | RSS 2.0 | media:category | no | yes | no |
scheme="urn:flickr:tags"> (source) |
YouTube | RSS 2.0 | media:category | no | no | no |
label="Tags"> (source) |
LibraryThing | RSS 2.0 | No explicit tag metadata. | no | no | no | n/a, (source) |
Tag Markup Scheme | Notes | Example |
---|---|---|
Atom Category atom:category xmlns:atom="http://www.w3.org/2005/Atom"
|
|
term="catName"
|
RSS 2.0 category rss2:category empty namespace |
|
domain="tag:deletethis.net,2008:tagscheme">
|
Yahoo Media RSS Module category media:category xmlns:media="http://search.yahoo.com/mrss/"
|
|
scheme="http://dmoz.org"
|
Dublin Core subject dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
humor
|
Update 2009-9-14: Added WordPress to the Tag Markup table and namespaces to the Tag Markup Scheme table.
The weekend before last I saw Dark Knight with some friends from work and then we all ate at Z'Tejas after. Like everyone has said and as the name implies Dark Knight is... dark. Dark Knight was a little over the top at times as compared to Batman Begins but I really enjoyed it. Two times during the movie I thought it had ended but I was wrong. The Joker is both frightening (Cringe inducing line "Wanna know how I got these scars?") and humorous ("Where is Harvey Dent? ... You know where Harvey is? You know who he is?", as well as the pencil magic trick). I can certainly recommend it to anyone who enjoyed Batman Begins. The previews included Burn After Reading a new Coen Brother's comedy that I look forward to, and Quantum of Solace which hopefully does the same thing Dark Knight has, keep up the new direction on the refreshed franchise.
This past weekend Sarah and I went to a Mariners baseball game. I think this is the first MLB baseball game I've seen in person. Sarah's company gave out tickets for the game and the use of a suite. Its a room half way up the stadium with comfortable chairs, a mini-fridge built-in to the marble counter-topped center table, and a big flat screen television with the game on it. I suppose that's in case you don't want to turn to the right and sit at the window, or walk out onto the balcony which features three rows of comfy chairs overlooking the field. Anyway there was free food and drinks and I met some of the people Sarah works with.