Hey, I’m Parker.

Creator of music, photography, and (mostly open) software.

Header Anchor Links in Vanilla JavaScript for GitHub Pages and Jekyll

The venerable Ben Balter, Esq. wrote earlier this year about how to add anchor links for headers in Jekyll.. I thought I'd follow up that post with one of my own, as I take a slightly different approach.

This solution is vanilla JavaScript with a little CSS and the Font Awesome web font.

Font Awesome

Font Awesome is, well, awesome. It's a font of icons that comes with a handy set of CSS classes.

Download the Font Awesome distribution and pull out just the font files. They're the files that end in .ttf, .woff, .svg, .otf, and .eot. Grab them all and put them in fonts/ in your Jekyll site.

The JavaScript

Add this JavaScript wherever is convenient:

var anchorForId = function (id) {
  var anchor = document.createElement("a");
  anchor.className = "header-link";
  anchor.href      = "#" + id;
  anchor.innerHTML = "<i class=\"fa fa-link\"></i>";
  return anchor;

var linkifyAnchors = function (level, containingElement) {
  var headers = containingElement.getElementsByTagName("h" + level);
  for (var h = 0; h < headers.length; h++) {
    var header = headers[h];

    if (typeof header.id !== "undefined" && header.id !== "") {

document.onreadystatechange = function () {
  if (this.readyState === "complete") {
    var contentBlock = document.getElementsByClassName("docs")[0] || document.getElementsByClassName("news")[0];
    if (!contentBlock) {
    for (var level = 1; level <= 6; level++) {
      linkifyAnchors(level, contentBlock);


Last, add this CSS to the css or _scss folder:

 *  Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
 *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
@font-face {
  font-family: 'FontAwesome';
  src: url('../fonts/fontawesome-webfont.eot?v=4.1.0');
  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
.fa {
  display: inline-block;
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
.fa-link:before {
  content: "\f0c1";
 * This code is courtesy Ben Balter, modified by Parker Moore for jekyllrb.com
 * http://ben.balter.com/2014/03/13/pages-anchor-links/
.header-link {
  position: relative;
  left: 0.5em;
  opacity: 0;
  font-size: 0.8em;

  -webkit-transition: opacity 0.2s ease-in-out 0.1s;
  -moz-transition: opacity 0.2s ease-in-out 0.1s;
  -ms-transition: opacity 0.2s ease-in-out 0.1s;
h2:hover .header-link,
h3:hover .header-link,
h4:hover .header-link,
h5:hover .header-link,
h6:hover .header-link {
  opacity: 1;

Enjoy the Magic

Now refresh your site and voilà! It's like magic. See it in action in the Jekyll docs.

A Hacker's Guide to Her Own GitHub Pages

GitHub Pages is a wonderful free platform GitHub has created to build and host your Jekyll sites for you. You push up any valid Jekyll site to a repo (on a special branch), and it's built and published to a predictable URL. The only downside? You can't use any custom Ruby code, which means no custom plugins. So what's the best way to host a Jekyll site that requires plugins?

Maybe you're writing a huge website for your employer, or just something small for yourself. Either way, you need a plugin or two to get it just right. You could build locally and push the compiled site up to GitHub Pages, but that requires that you install all the dependencies locally and write a script to compile and jostle things in just the right way to make it all work. What if you could have the same workflow – just git push – for sites with custom plugins?

You can. I do it every day. In fact, my personal site (https://parkermoo.re) is published with this method. Here's a step-by-step guide to making your own GitHub Pages.

1. Install and Configure Dependencies

You'll need the following:

  1. A server with root access. I use a Rackspace CentOS 1GB Performance VM, but you can use any Linux system from any provider.
  2. A web server if you don't have one already (Apache/Nginx).
  3. Ruby and RubyGems with the proper permissions to install new gems.
  4. Git
  5. Gitolite

First, sudo su - root. Then install Ruby. I suggest using rbenv to keep your Rubies organized. Then ensure RubyGems is installed, and install the github-pages gem.

Next, ensure you have a daemonized web server installed, like nginx or apache.

Then ensure git is installed and create a new git user. Run su - git and install gitolite.

Once you have gitolite installed, go back to your local machine and configure gitolite as described. You'll need to add a new user for your SSH key and create the repo for your site.

2. Add the post-receive hook

Run sudo su - git and find the post-receive file in your repository. It's usually at /home/git/repositories/MY_REPO.git/hooks/post-receive. Edit it so it looks like this:

set -e # fail on error

# ensure you have loaded git's environment with rbenv/ruby/jekyll in the path
source /home/git/.bash_profile

# this is only if you have rbenv installed
# remove if you're using a stock ruby
eval "$(rbenv init -)"

# this shows you where the Jekyll executable can be found
# it will also fail if jekyll can't be found, halting the build.
which jekyll

# this is the name of your repo, without the `.git`


# Change this to wherever your server (nginx/apache) will look
# for your compiled site. Usually called the document root.


# Run Jekyll!
cd $TMP_GIT_CLONE && jekyll build -d $PUBLIC_WWW --trace

This hook will clone your repo to /tmp and run jekyll build from your site source into the directory your server will serve from.

3. Add the git remote

Go back to your local site and add the remote:

$ git remote add publish [email protected]:MY_REPO.git

4. Test

Now, to test, just push!

$ git push publish master

You should see all the output of the Jekyll process in your terminal. Once you see ...done. and the process exits, you're done! Refresh your browser and admire your handiwork.

If you get a LoadError from Jekyll, then you don't have a gem installed or it can't access the _plugins directory. To install new gems, just run gem install GEM_NAME as root on your VM.

Don’t Like Being Tracked?

I don’t like being tracked by Web giants when I’m not on their websites. As more sites integrate Twitter, Facebook, and Google support, I can’t help but be tracked on almost every site I visit.

Luckily, the integrations for these three aforementioned companies is quite simple to subvert (at least partially). If you’re running a unix-based machine, you can add just a few lines to your /etc/hosts file (on Windows it’s C:\Windows\System32\drivers\etc\hosts) and you’re well on your way to Web privacy.

Open up a new tab, and open the Developer Console. Open the Network tab. Now navigate to your favourite blog, news site, etc. You’ll see each individual network request that is made from that page listed in the Network pane of the Developer Console. Scroll through requests and make note of the domain names you wish to block.

Once you have the list of domain names, simply use your hosts file to reroute those domains to your local server ( Here’s an example: connect.facebook.net google-analytics.com www.google-analytics.com platform.twitter.com adroll.com a.adroll.com d.adroll.com ib.adnxs.com googleadservices.com www.googleadservices.com

In this example, I’ve blocked Facebook, Google Analytics, Twitter, Ad Roll, Google Ad Services and the unknown "adnxs" service.

Preface each domain name with the address of your local server and group each line based on the second-level domain (e.g. adroll.com). Add each of these lines to your /etc/hosts file (note: this will require root privileges). Don’t forget to save it when you’re done.

Now navigate to that same site again, with the Network pane still open. You should now get 404’s or 500’s when you try to access those same domains you ‘blocked’.

For a solution that doesn’t require halting access to these hosts, check out the Tor project.

Clearing Up Confusion Around Baseurl

TL;DR: Don't use baseurl. It'll drive you crazy.

Hey, so there's been a bit of confusion about what the Jekyll configuration option called baseurl is. Part of the beauty of open-source and of Jekyll is that there's a lot of flexibility. Unfortunately, much of this flexibility doesn't apply to baseurl. Here's a quick distillation of its intentions, and how to use it.

Mimic GitHub Pages

baseurl was originally added back in 2010 to allow "the user to test the website with the internal webserver under the same base url it will be deployed to on a production server".1


So let's say I come up with a cool new project. I want to make documentation for a project I'm working on called "ubiqity", and I'll be deploying it to GitHub Pages as a repo under my username, "@parkr". Its documentation will be available at the URL http://parkr.github.io/ubiquity.

In this example, the term "base URL" refers to ubiquity. When I go to develop my website, I can set the baseurl key to equal ubiquity and navigate my website from http://localhost:4000/ubiquity/, as though it were hosted on GitHub Pages. Notice that the only difference here between development and production is the host: parkr.github.io vs. localhost:4000.2

Configuring Your Site Properly

  1. Set baseurl in your _config.yml to match the production URL without the host (e.g. ubiquity, not http://parkr.github.io/ubiquity).
  2. Run jekyll serve -w and go to http://localhost:4000/your_baseurl/, replacing your_baseurl with whatever you set baseurl to in your _config.yml, and not forgetting the trailing slash.
  3. Make sure everything works. Feel free to prepend your urls with site.baseurl.
  4. Push up to your host and see that everything works there, too!


You've done it! You've successfully used baseurl and the world is wonderful.

  1. https://github.com/jekyll/jekyll/pull/235 

  2. The port also differs, but that's not what's important here. The point is that everything after the / after the host is the same. 

Always Moving Forward

Emeryville California

Today, I'm proud to announce that I have accepted a job offer from Visual Supply Co, a small and happenin' start-up based in the Bay Area. Visual Supply Co, also known as VSCO, produces the well-loved VSCO Cam iPhone and Android apps, as well as VSCO Film, VSCO Grid, and VSCO Keys. I'll be working on all things web, including the Grid service and the API.

Super stoked to begin this next chapter in my journey through life working on a slick series of products with a stellar team. Follow my adventure on my grid!

Fixing Common Mistakes When Working With EC2

I'm lucky enough this semester to be taking CS 5300 at Cornell, a class entitled "The Architecture of Large-Scale Information Systems." For this class, we will need to know our way around Amazon's Web Services. I learned a lot about AWS when I worked at 6Wunderkinder last year, so I was feeling up to the challenge. Little did I know that the tooling 6W had created around its ops was far superior to anything else out there.

I already had an AWS account, so my first step was to find a good CLI. I did the logical thing, and asked Google. Turns out, Amazon ships its own aws client, written in Python and shipped via pip. Marvelous! I ran pip install aws, aws configure and presto, I was in business.

Our first question asked us to launch an instance of the AMI ami-bba18dd2, a simple Fedora distribution. After asking for the man pages for aws in 6 different ways, I got them. I discovered I would need to specify the instance type and security group as well. So I created a security group and went ahead:

$ aws ec2 run-instances \
--image-id ami-bba18dd2 \
--instance-type t1.micro \
--security-group-ids sg-sgsga888

Yay, it worked! Ok, now I need to ssh into this bad boy.

$ ssh ec2-la-la-la.amazonaws.com
Access denied (publickey).

Huh? What's that all about? I had created a key pair from previous messing around with EC2. Hm... After a few minutes of puzzlement, I realized I needed to pass another option to my aws ec2 command. Let's try this again:

# don't forget to terminate old instances!
$ aws ec2 terminate-instances --instance-ids i-1111111
# now, create the new one
$ aws ec2 run-instances \
--image-id ami-bba18dd2 \
--instance-type t1.micro \
--security-group-ids sg-sgsga888 \
--key-name parker

Booted! Now, let's try to ssh again:

$ ssh ec2-li-la-le.amazonaws.com
Access denied (publickey).

Bollocks! Looks like I am still missing something...

Ah! After taking a look at a tutorial, I realize I need to login as ec2-user. Let's give this one more try:

Last login: Tue Feb 4 05:13:24 2014 from cpe-88-88-88-88.twcny.res.rr.com
__| __|_ )
_| ( / Amazon Linux AMI
7 package(s) needed for security, out of 25 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-10-9-162-71 ~]$

YES! I did it. Ok, so lessons:

  1. Login as ec2-user, not as albie or any other name.
  2. Make sure you specify the key-name for the instance(s) you want to launch.
  3. Always err on the side of being more specific. Defaults can be bad.
  4. Always terminate once you're done using the box.

Simple fixes for problems that seem so intractible.

Installing Command-T With OS X Maverick's Built-In Vim

I was fortunate enough to, just today, pick up a new computer. My first hardware in over 4 years, I had been holding off. Once my trusty MacBook Pro bit the dust last night and I found out the repair cost was extraordinary, I bit the bullet.

So, you're probably in a similar place. You relatively recently got a shiny new Macintosh and you're so excited to start writing code and making a difference with those skillz of yours. Except one this is missing: Command-T.

Lucky for you, sir, I am here to help. OS X Maverick's built-in vim distribution comes with Ruby support already (which it needs for Command-T) so you're good there. Now you need to download and compile Command-T. Should be easy, right? Well, not quite.

Mavericks was notable for Ruby users because it ships with Ruby 2.0. All previous versions that I had ever used shipped with 1.8.7 so this was a huge bonus. Problem is, your pre-installed vim wasn't compiled with 2.0.0, it was compiled with 1.8.7.

To check this, run the following in vim in NORMAL mode:


For me, that output 1.8.7-p358. So that means the Ruby verison that vim is using is 1.8.7-p358, and we need to compile Command-T with that version. To do so, install it:

$ rbenv install 1.8.7-p358

Boom! Now download and install Command-T:

$ git clone https://github.com/wincent/Command-T.git ~/.vim/bundle/Command-T
$ cd ~/.vim/bundle/Command-T # for tpope's Pathogen
$ rbenv local 1.8.7-p358
$ rbenv rehash
$ gem install bundler
$ bundle install
$ bundle exec rake make

Aaaaand boom, you're done. Open up vim and type your leaderkey then t (for me, that's ,t) to launch the prompt.

If you get a weird SIGTERM error when you launch vim, then you installed Command-T with the wrong Ruby version. Remove ruby/command-t/ext.bundle and try again.

Fixing Memory Issues in Dokku Hosted on DigitalOcean 512MB Droplet

As many other Heroku customers, I rejoiced when Dokku was released. To have complete freedom to host as many apps with whatever databases or other plugins I wanted -- all for the cost of a small VM -- was wonderful news.

I decided, for cost's sake, to boot up one of those famed $5 DigitalOcean Droplets. I didn't see that DigitalOcean provides an "app" for Dokku, so I created a vanilla box of Ubuntu 13.04 and pressed on. I got everything up and running and went to go deploy my first app, only to see this when I ran git push:

runtime: panic before malloc heap initialized
fatal error: runtime: cannot allocate heap metadata

Well, golly, that sure is unhelpful. Looks like 512MB doesn't cut it. Luckily, we can avoid paying the extra $5/mo for the 1GB version by running the following as root:

dd if=/dev/zero of=/extraswap bs=1M count=512
mkswap /extraswap

Then adding the following to your /etc/fstab file so the swap persists between reboots:

/extraswap none swap sw 0 0

Then run this to enable /extraswap for swapping:

swapon -a

Boom. Now re-run git push and you're in business. Magic!

Credit goes to the brilliant @dhassler for the idea and the code. Just thought I'd share and preserve for my own benefit in the future.

Taking Over Someone Else's Open-Source Project

Last December (2012), Tom Preston-Werner granted me push & pull access to mojombo/jekyll. I had written a letter to Tom about the future of Jekyll and after a bit of persistence on my part, he relented:

mojombo added parkr to mojombo/jekyll

After a somewhat lengthy (and amusing) conversation via Skype, I knew what Tom's priorities were for the project and where I could help. I started off trimming down the number of open issues. At the time, they numbered just over 300. After a quick visit to Buffalo to tackle some issues with Nick Quaranto at a Buffalo OpenHack meetup at CoworkBuffalo, we were down to fewer than 200 open issues. I continued to work through them (much to my parents' dismay) all through Winter Break. I was making good progress in the triage process: I knew what many of the problems were with v0.12.1 and was formulating ideas about how we might go about fixing them.

jekyll shall inherit the earth

In January, I flew out to San Francisco to visit my sister for a week. I setup a meeting with Tom to talk more about Jekyll and a plan for moving forward to a v1.0.0 release. After about an hour or so at GitHub's office in SoMa, talking through various PR's, Tom said I could start merging pull requests.

Consultation with Tom was challenging (he runs a multi-million dollar company after all), as it was increasingly difficult for him to find time for Jekyll. Despite announcing that he was going to commit some of his "20% time" to Jekyll, he eventually abandoned that as impractical. As time went on, I received fewer replies to my emails and eventually stopped sending anything that didn't absolutely require Tom's input.

In March, I knew I needed more help. Tom wasn't able to give much time and I was trying to tackle this project alone. I had noticed that Matt Rogers shared my vision for Jekyll, so I asked Tom to add him on as a contributor to the repo. By v1.0.3, he had started merging pull requests like a BAW$ and was the sanity to my ridiculously-obsessed, inexperienced mind. Since Matt joined, I haven't really heard much from Tom. I write the occasional email and get the occasional reply but he's essentially phased out of the normal development of Jekyll. Matt & I have essentially taken over the project altogether.

By May, we were ready to ship v1.0.0. With the help of all the amazing contributors, Matt, and my many mentors along the way, I finally ran rake release for 1.0. The project was ours.

Since realizing that this product has few constraints outside of those I've constructed for it in my mind (no one is going to tell me, "No, you may not implement that feature or add that enhancement" without a valid argument as to my solution's invalidity), I've been thinking about what it means to take over someone else's project. Jekyll is 5 years old. I wasn't there in 2008 when it was first born as autoblog. Jekyll has changed a lot, as has its vision and purpose. It's used by lots of people now, whether via GitHub Pages or locally.

Taking over someone else's project takes a deep understanding of what the project is and what it should be. As much as I wish Jekyll could make me kräuterquark, that's outside the scope of the project. Developing that lens is crucial when taking over someone else's project.

Mentoring on the part of the original owner/previous maintainer(s) is exceedingly significant in the development of this critical lens. I am so grateful that I was able to meet up with Tom back in January and to have some amount of input from him as I understood what the project should be.

It would be ill-advised to take over someone else's project without a partner. Once Matt joined the team, Tom was able to step back into a much lesser role. If I had tried to do what I did without any guidance (or at least sanity checks), Jekyll v1.0.0 would have been a complete shit-show.

Trust in the community must also be earned. If people highly doubted my ability to handle Jekyll, Tom would have likely removed me and found a replacement. I argued a lot and got into some pretty heated debates at the beginning. There were a couple people who didn't share the vision that I had inherited from Tom and stopped contributing to the project altogether. I feel like we now have a pretty great community around Jekyll and are able to help each other out and share cool plugins and sites that we made for/with Jekyll.

Taking over someone else's open-source project was new terrain for me in December, and still is today. It can be successful with the right amount of mentoring and gradual removal of trusted feedback by the previous maintainer(s).

With some old projects that are brought back to life by the passing of the torch, the new maintainers are able to experience the added bonus of feeling like Frankenstein, which, I will say, is a pretty cool feeling.


Fix the Government: Open-Source Legislation

The following post was first written for a class at Cornell University taught by Phoebe Sengers called "Designing Technologies for Social Impact".

We have a rather significant problem in the U.S. Indeed, our government seems to be malfunctioning in a rather obvious and irresponsible way. The question of today is simply: can it be fixed? If so, how?

One must first examine the problem and its root cause. The problem of malfunction is most basically the conflict of multiple competing interests without proper ideological or procedural basis for dialogue. The root cause of this is that the existing platforms for dialogue (meetings, letters, rallies, news spots) are severely outdated. What worked pre-internet is not passing the test of time.

In particular, the legislative process is slow, dilapidated, and closed. This leads to laws with earmarks and loopholes, confusing language and unnecessary provisions. What if the law were made out in the open, for everyone to see, the way open-source software is made? Version control and online access to bills in-the-works as well as laws would certainly improve transparency. The Library of Congress runs a system called THOMAS which is updated about daily, but the bills aren't organized logically and the user interface is fair at best.

The open-source legislation system envisioned here is based on an open-source software system called GitHub. GitHub is setup like so: users and organizations own repositories of code, text or binary documents. Each repository contains the entire history of a particular set of documents as well as the "master" version, or the latest repository-owner(s)-approved version of the document(s). Each repository uses a version control system called git to keep track of the information about the documents it contains: current versions as well as previous versions. What is unique about this system, and the incredible strength it offers for open legislation, is the concept of a "diff". A "diff" is simply the difference between a document at one point in time (referred to as a "revision") and the same document at a different point in time. Each repository can be "forked" (cloned to a user's own profile for editing) by a user; this offers the most significant freedom of open-source, which is that anyone has the freedom to modify a copy of the source and suggest changes to the main project based on those derivative works. In GitHub parlance, the suggestion for a change is called a "pull request," but this term need not be adopted by this new system.

To illustrate the design of the ideal system:

  1. Use git derivative for prose editing, rather than (line-by-line) code editing
  2. Be online, accessible by anyone
  3. Offer input from anyone in any form (suggested changes or just comments)
  4. Do not make differentiation between users other than repository owner & non-owner (those with direct access to the repository and those who can fork and suggest changes, but can't incorporate those changes themselves)
  5. Each repository is a proposed bill owned by the deciding body at the given time during the legislative process as dictated by the U.S. Constitution. Each repository contains a text file for each sub-segment of the proposed bill as well as a rationale or goal, e.g. . (root) | |-- README.txt (rationale, goal(s) of bill, and other meta info) |-- section01.txt |-- section02.txt | ...

  6. The entire process of the creation and formulation of the law is public and open insofar as the culture can push for this

  7. Moderator of some sort to ensure comments are productive (usually repo owner). All of the comments that are hidden still exist inline and can be shown by any reader of the comment thread

  8. Membership of individual lawmakers in committees and other larger bodies reflected in membership of organization accounts on the platform, which gives them access to directly changing the legislation they have access to through their organizational memberships

  9. Offer "points of interest" as a means of discussion about a particular aspect of a bill without the need to suggest changes. Can ask anything from "why is this section worded this way?" to "what are the implications of this on agricultural development in Upstate New York?" No question is too dumb and all of them require an answer insofar as they are productive and relevant.

  10. Easy citation of preexisting laws and other bills to allow for discussion surrounding conflict or other interference

  11. Access to signing letters written by President (usually interpretations of pieces of the law for purposes of execution of the law)

  12. Easy viewing of votes on final versions of bills (who, when, did it pass?, etc)

  13. Means of mentioning lawmakers in a comment if comment is directed at them, or question is asked directly of them

  14. Links to more information about execution by Executive & other related policy/law

  15. Comments and changes can only be created from user accounts, e.g. David Skorton can suggest a change, but Cornell University cannot.

  16. Users can subscribe to updates from a bill repository and receive all information about changes that are made and discussions that occur.

One negative aspect of this approach is volume and the issues that come therefrom (see: student's answer on Piazza page linked to below). As the number of collaborators grows, the ability for those with direct access to the bills to handle suggestions for modification is greatly diminished. How are the interests of the few vs. those of the many weighed (e.g. individual comment vs comment from organization such as NAACP)? From the perspective of the way government works already, aides of the legislators who have access to the repositories will also have mirrored access to accept and discuss changes and questions from citizens. As each law is its own repository, the load is distributed over the many hundreds of bill repositories being considered. Additionally, Nissenbaum & Benkler discuss the idea of self-selection and volunteerism as an element of open-source. This applies very much so to the scalability of open-source legislation and responses to citizens. If a citizen is not interested in a particular bill, that citizen will not involve himself or herself with the creation of that bill. This self-selection will greatly reduce the number of individuals with whom the maintainers of the bills will have to contend with in discussion about a bill and suggestions for change.

Ultimately, this idea is predicated on the idea that citizens, when given the right tools, can reach compromise and have productive discussions to "get the job done" efficiently and accurately.