perkee's code

Easy Table of Contents

To make the table of contents on this page, I really wanted to do everything server side. That way, I would offer a consistent experience for users with and without Javascript. But I didn't want to have to maintain an actual table of contents section of this page by hand, as I'm just not into that. The solution then was to use a snippet of PHP to scan this page for sections and generate the ToC for me.

Each project on this page is in a div of class "project." The id of the div is how we will navigate to each, either with or without Javascript. Each div has a child h2 with the title of the project inside. We, then, want to make a list of links with targets taken from the div elements and their text taken from the h2 elements. Because the page is structured logically, I didn't bother parsing out the DOM structure; rather, I just used grep and new that every time I find a div I'm going to find a corresponding h2. I modified these regexes to make sure that they don't detect themselves in the page. Using the various utilities for stripping out all PHP and HTML tags would have been cool too, but I wanted to avoid unnecessary processing.

$lines = file(__FILE__);
$ids = preg_grep('/^[ \t]+<div.*class="project"/', $lines);
$projects = preg_grep("/^[ \t]+<h2>/", $lines);
$ids = array_values($ids);            //normalize the arrays to be 0 based
$projects = array_values($projects);
$patterns = array("/<h2/","/\/h2/");
foreach($projects as $key => $value)
{
  $id = trim(preg_replace(array("/<.*id=\"/","/\">/"),array('',''),$ids[$key]));
  $replacements = array('  <li><a href="'."#$id".'"',"/a></li"); //replace with list items holding links to hashed IDs
  echo(preg_replace($patterns,$replacements,$value));
}

Whom to Follow

Update Twitter has once again rejiggered everything and I've gotten a little better with jQuery.

$('.flex-module-header h3:contains("Who to follow")').text("Whom to follow")

Whom to follow is a user script that changes the "Who to Follow" link on Twitter's top bar to "Whom to Follow." I wrote it because that thing was driving me up a wall.

I've only tested it in Chrome, but it's so simple that it's almost not worth testing in Greasemonkey. Kidding. I'll test it. Install it here. If you'd prefer a bookmarklet (tested in IE8, Firefox, Safari, and Chrome) then run the following in the URL bar of your browser tab that's open to Twitter:

javascript:(function(){document.getElementById("global-nav-whotofollow").firstChild.innerHTML="Whom to Follow";}())

You can also get the script from its Userscripts page.

3 Month Calendar

I like seeing a calendar for the previous, current, and next month. I also like seeing the current day highlighted. This (admittedly insane) one liner does all of those. I'll post the whole thing then break it down.

cal $(date '+"BEGIN{if(%m==1){print 12;print %Y-1}else{print %m-1;print %Y;}}"'|xargs awk);cal|sed "s/ $(date "+%d"|sed 's/^0/ /')/$(echo -e "\033[1;31m")&$(echo -e "\033[0m")/";date '+"BEGIN{if(%m==12){print 1;print %Y+1}else{print %m+1;print %Y;}}"'|xargs awk|xargs cal

The first part of this is the previous month's date. That's easy enough, we just get the date from date and subtract 1. But we have to handle the case of January, where we get 12 for the month and the previous year. So our date string becomes an awk command which handles that. We pass it using xargs to turn the whole output into one string of arguments, rather than passing them one at a time like backticks or $(). We then pass the output of awk to cal which just prints the previous month. Easy peasy.

The current month is fun. We first get the current day and, if it has a leading zero, replace that with a space. that then becomes the target of a regex in sed, which wraps the day in ANSI escape codes for, respectively, turning the text red and then clearing any effect. That regex is then applied to the output of the current month's calendar. We have to echo -e the color escape codes because just printing them is not enough, apparently.

Finally we just do basically the same thing as the first command to print out the next month. I used xargs to pass to cal because I actually like that better. So do that.

Addendum: I use this in my Geektool to display it on the desktop. In that case you have to leave off the -e option on each echo inside the regex, but otherwise leave it the same.

Post addendum: I realize that the GNU date makes this easier than the BSD date—all you have to do is specify -d "next month" and you can skip the whole awk malarky. But BSD just doesn't have that.

cal $(date -d "last month" '+%m %y'); cal; cal $(date -d "next month" '+%m %y')

Heatmap

I like heatmaps. They're a pretty cool way of expressing 3D data in two dimensions. I've been working on a web tool to make quick little ones. Check it out. I've got a ton of features I want to add in the coming days and weeks and such, but I couldn't not give you a taste. Right now the only way to export the data is to hide the numbers and take a screenshot. It's what I've got right now. And obviously if you don't have Javascript please stay home.