YAML Front Matter syntax highlighting in TextMate

Aside: Right now I’m a train with spotty Wifi. Hence, lots of time for noodling rather than actual productivity.

If you like that Jekyll as much as I do, chances are you’ve got lots and lots of wonderful Markdown files loaded with YAML Front Matter. I use Jekyll for everything, lo, even this very post! Let’s get TextMate’s Markdown Language Grammer to properly highlight the YAML up top.

Crack open the Bundle Editor (Cmd + Opt + Ctrl + B) and select the Markdown Language Grammer. In TextMate 2, this is in Markdown > Language Grammers > Markdown. You’ll need to add two bits.

In the block, er, block, add { include = '#yaml_front_matter'; }, to the patterns:

block = {
  patterns = (
    { include = '#yaml_front_matter'; },
    { include = '#separator'; },
    { include = '#heading'; },
    ...
  );

Then add the following pattern for yaml_front_matter under the block repository. I just added it after separator pattern.

separator = {
  match = '(^|\G)[ ]{,3}([-*_])([ ]{,2}\2){2,}[ \t]*$\n?';
  name = 'meta.separator.markdown';
};
# add this next bit
yaml_front_matter = {
  patterns = (
    { begin = '\G---';
      end = '^---';
      name = 'source.yaml.embedded.markdown';
      patterns = ( { include = 'source.yaml'; } );
    },
  );
};

Boom. Now my Jekyll Markdown files look niiiiiiiiiice.

YAML Front Matter

GitHub code blocks in TextMate

GitHub README’s feature nice syntax highlighted code blocks with the triple tick notation.

``` css
body { font-family: sans-serif; }
```

But as this syntax is a part of GitHub Flavored Markdown and not the vanilla Markdown variety, TextMate does not recognize triple ticked code blocks, which can lead to ugly sections of the document. Take this example from desandro/textmate-bundle/README.mdown

README with Redcarpet code block

I resolved this by modifying TextMate’s Markdown Language Grammer, adding in the triple tick pattern for raw_block.

raw_block = {
  patterns = (
    { begin = '(^|\G)([ ]{4}|\t)';
      name = 'markup.raw.block.markdown';
      while = '(^|\G)([ ]{4}|\t)';
    },
    { begin = '(^|\G)```';
      end = '(^|\G)```';
      name = 'markup.raw.block.markdown';
    },
  );
};

Bingo.

README with Redcarpet code block syntax highlighted

TextMate commands with node

TextMate commands are the scripts that run every time you do some special key command, for example, Ctrl + Shift + W to wrap text in an HTML tag. Commands aren’t just baked-in magic, each one is an editable script. This allows you to write your own. This is awesome.

Personally, I’m not familiar with bash or Ruby, which means the code behind any command is just as good as a magic spell. But through the wonder of node, I’m able to develop my own TextMate commands that I actually comprehend.

I had a project where I had to add links to any reference of a U.S. state, a perfect use-case for a custom command.

# before
Pennsylvania and Rhode Island
# after
[Pennsylvania](../pennsylvania/) and [Rhode Island](../rhode-island/)

First check that node is in your $PATH. On my machine, I have in ~/.bash_profile:

PATH=$PATH:~/bin:~/.gem/ruby/1.8/bin:/usr/local/bin/node
export PATH

To check it’s in there, from Terminal:

echo $PATH
# /usr/bin:/bin: ... /usr/local/bin/node
# /usr/local/bin/node or something similiar should appear in there

This will allow the script to be run in node. For this script, I am using process.stdin, which takes the selected in. Of course, node does this in chunks or something and there’s a good reason for it, that John could elaborate on. But what I do know is that this works.

#!/usr/bin/env node

process.stdin.resume();

var str = '';

process.stdin.on( 'data', function ( chunk ) {
  str += chunk;
});

process.stdin.on( 'end', function () {
  // convert selected text to lowercase, then convert spaces to dashes
  var link = str.toLowerCase().replace( ' ', '-' );
  // format link
  var output = '[' + str + '](../' + link +'/)';
  process.stdout.write( output );
});

My Bundle options for the command look something this:

TextMate bundle options

I hit Cmd + A around my selected text and it does the proper conversion. Nice! Now I can make TextMate commands at will.

NaN messes with sorting

I’m building some dynamic table sorting. Looks like NaN values are messing with the sorting. For the sake of the example, let’s use an array of number-like strings. Try pasting this in your console.

(function() {
  var numbers = '19 26 63 twelve 83 106 hundred zero 12'.split(' ');
  return numbers.sort();
})();
// ["106", "12", "19", "26", "63", "83", "hundred", "twelve", "zero"]

The resulting array is as expected, since the values are still strings.

Let’s parse those values as integers, using a compare function in sort.

(function() {
  var numbers = '19 26 63 twelve 83 106 hundred zero 12'.split(' ');
  function parse( value ) {
    return parseInt( value );
  }
  return numbers.sort( function( a, b ) {
    return parse( a ) < parse( b );
  });
})();
// ["63", "26", "19", "twelve", "106", "83", "hundred", "zero", "12"]

This looks just random. I believe what’s happening is how a NaN value from parseInt('foo') messes with the comparison. Comparing any number with NaN will return false.

14 > NaN
// false
NaN > 14
// false

Oh JavaScript, you so cray.

My solution is to account for NaN in the parser.

(function() {
  var numbers = '19 26 63 twelve 83 106 hundred zero 12'.split(' ');
  function parse( value ) {
    value = parseInt( value );
    value = isNaN( value ) ? Infinity : value;
    return value;
  }
  return numbers.sort( function( a, b ) {
    return parse( a ) > parse( b );
  });
})();
// ["12", "19", "26", "63", "83", "106", "twelve", "hundred", "zero"]

You don’t have to munge NaN as Infinity, but this at least treats the value as a number that can be properly compared.

Chrome Developer Tools settings

Via JFSIII, Chrome’s Developer Tools has some useful options hidden in its settings panel. All this time, it has been hiding as that little cog icon in the bottom right.

Chrome developer tools settings icon

Personal favorites include Disable cache, Text Editor indent, Dock to right which is ideal for mobile-sized media-query development.

Chrome developer tools settings

Git submodules

I think I’m ready to discuss Git submodules. My chronic problem with submodules is that I don’t use them often enough to understand how they work. From what I gather, you can do a lot more than what I’ll cover, but I’m only interested in just placing a repo in a repo.

The benefit of submodules is that you can reduce duplicate code. Instead of copying files from one repo into another, Git can manage this for you. nclud.com v3 currently has 6 submodules. These are helpful for pulling changes to external repos – in our case jquery-smartresize and jquery.form.js.

I’ve been breaking out re-useable bits of code into smaller repos and gists. So I’ve got this requestAnimationFrame polyfill, and I want to include it in another project, Inflickity. This can be done with two git submodule commands:

git submodule add git://gist.github.com/1866474.git request-animation-frame
git submodule update --init

This will add the submodule, then pull in the appropriate commit. I’ll be able to use request-animation-frame/requestanimationframe.js in the Inflickity demo.

Both those commands trigger a change in the repo, changing .gitmodules and reference to the submodule repository. This change will require a commit.

If anyone else clones the repo, they’ll have to update and init the submodules as well.

git clone https://github.com/nclud/inflickity.git
cd inflickity
git submodule update --init

EDIT Or better yet, clone the repo and pull in submodules with git clone --recursive (thx Mathias):

git clone --recursive https://github.com/nclud/inflickity.git

Now, the crazy-pants part. Per the Git reference, git submodule update

will make the submodules HEAD be detached

I think this is where I usually lose control of what was happening with my submodules. The submodule’s repository has checked out the specific commit, and is not on the master branch as I would have expected. For example, let’s try cloning the Inflickity repo and getting that submodule working.

~/projects $ git clone https://github.com/nclud/inflickity.git
Cloning into inflickity...
...
Unpacking objects: 100% (87/87), done.
~/projects $ cd inflickity
~/projects/inflickity $ git submodule update --init
Submodule 'request-animation-frame' (git://gist.github.com/1866474.git) registered for path 'request-animation-frame'
Cloning into request-animation-frame...
...
Submodule path 'request-animation-frame': checked out 'db50266cd98d2d46277fd54d24cfd37766476a00'
~/projects/inflickity $ ls request-animation-frame/
requestanimationframe.js

Great, so the contents of the submodule are there. But what happens if we check the status of that submodule repository:

~/projects/inflickity $ cd request-animation-frame/
~/projects/inflickity/request-animation-frame $ git status
# Not currently on any branch.
nothing to commit (working directory clean)

Not on any branch. Darnit. This will prevent the basic git pull from working, so you’ll have to specify remote and branch.

~/projects/inflickity/request-animation-frame $ git pull origin master
From git://gist.github.com/1866474
 * branch            master     -> FETCH_HEAD
Already up-to-date.

git submodule foreach allows you to run a shell command for each submodule, which is ideal for pulling all submodules.

~/projects/inflickity $ git submodule foreach 'git pull origin master'
Entering 'request-animation-frame'
From git://gist.github.com/1866474
 * branch            master     -> FETCH_HEAD
Already up-to-date.

Just like when adding submodules, if there are any new commits that were pulled for a submodule, you’ll need to track that change in a commit for the parent repository.

In review, my three go-to git submodule commands are:

# starts it off
git submodule update --init
# for anyone else cloning
git clone --recursive my-repo.git
# pull in any fresh commits
git submodule foreach 'git pull origin master'

This keeps me in the parent repo, and I don’t get confused popping in and out of submodules repo.

Function.prototype.bind

Modernizr 2.5 added lots of robust feature detects and tests, but perhaps its most convienent feature is the addition of a Function.prototype.bind polyfill. In short, .bind() allows you to set this within a function.

As I employ prototypal objects and class methods a lot, I’m using .bind() a bunch. It’s helpful within setTimeout:

function ClassAct() {
  this.generation = Math.floor( Math.random() * 10 + 4 );
  this.name = 'James J. Jones, the ' + this.generation + 'th.';
}

ClassAct.prototype.sayHello = function() {
  console.log('Gday! I am ' + this.name );
};

// old, ugly way
ClassAct.prototype.sayDelayedHello = function() {
  // can't use `this` in here, because it will be set to the `window` object
  // have to hack it with local `_this` var
  var _this = this;
  setTimeout( function() {
    _this.sayHello();
  }, 1000 );
};

// with Function.prototype.bind()
ClassAct.prototype.sayDelayedHello = function() {
  setTimeout( this.sayHello.bind( this ), 1000 );
};

Or, you could use it for quick and easy event handling:

function ClassAct() {
  // say hello on click
  // without .bind( this ), `this` in sayHello() will not be ClassAct instance
  document.addEventListener( 'mousedown', this.sayHello.bind( this ), false );
}

See it in action: here’s a fiddle to compare using .bind() within class methods: Without Function.prototype.bind and with Function.prototype.bind.

Slicing arguments

In the jQuery Plugins Authoring tutorial, Ralph Holzmann details an intriguing pattern for plugin methods:

var args = Array.prototype.slice.call( arguments, 1 );
return methods[ method ].apply( this, args );
// (edited for clarity)

As the tutorial explains, this pattern is what enabled jQuery UI plugins to have multiple methods. Indeed, If you look deep within the coils of jQuery UI widget factory, you’ll find it there as well:

var args = slice.call( arguments, 1 );
instance[ options ].apply( instance, args );
// (again, edited for clarity)

I had thought of this argument-slicing method pattern just as another bit of JavaScript witch-craft that seemed to work, but I had no comprehension of why.

Today, I’m working on a sort of particle/field class and this pattern finally clicked. Here’s what I’m working with

// field has multiple particles
function Field() {
  this.particles = [];
  for ( var i=0; i < max; i++ ) {
    this.particles.push( new Particle( i ) );
  }
}

// particles have methods
function Particle( index ) {
  this.index = index;
}

Particle.prototype.logIndex = function() {
  console.log( this.index );
}

If I want logIndex on each particle in a field, I would have to loop through each particle and call its method.

Field.prototype.logParticleIndexes = function() {
  for ( var i=0, len=this.particles.length; i < len; i++ ) {
    this.particles[i].logIndex();
  }
}

This is all fine and well when you only have a couple methods in a field that have to iterate over each particle. But you could create another method that was more flexible, and trigger a method passed in from an argument.

Field.prototype.eachParticleDo = function( methodName ) {
  for ( var i=0, len=this.particles.length; i < len; i++ ) {
    this.particles[i][ methodName ]();
  }
}

myField.eachParticleDo('logIndex');

But if the particle has method that require arguments, we’ll need a way to pass those arguments in.

Particle.prototype.setColor = function( color ) {
  this.elem.style.backgroundColor = color;
};

This is where argument-slicing comes in.

Field.prototype.eachParticleDo = function( methodName ) {
  // pass in any other arguments after `methodName`
  var args = Array.prototype.slice.call( arguments, 1 );
  var particle;
  for ( var i=0, len = this.particles.length; i < len; i++ ) {
    particle = this.particles[i];
    // first argument, particle, is what `this` will be inside function
    // second argument is the arguments for that function
    particle[ methodName ].apply( particle, args );
  }
};

myField.eachParticleDo( 'setColor', 'blue' );

Let’s break down what’s going on up there. In order to get any arguments after the first one, methodName, we need to remove methodName from arguments. With a normal array, we could use ary.slice( 1 ). But because arguments is a bizarre array-like object, we need to use an equally bizarre method to slice it. For more on this, See Sebastiano Armeli’s Understanding Array.prototype.slice.apply(arguments) in JavaScript.

Now that the arguments are in a proper array, they can be used as the arguments with .apply(). Per flatline on Stack Overflow What is the difference between call and apply?:

The main difference is that apply lets you invoke the function with arguments as an array; call requires the parameters be listed explicitly.

Nice. Here’s a quick particle demo with eachParticleDo in place.

See fiddle: Particle field with .eachParticleDo

Try opening up the raw fiddle with your console and enter.

myField.eachParticleDo( 'setColor', 'red' )

Varry var var

John Schulz turned me on to the code style of using var for every variable. This goes against most other code styles (see learn.jquery.com and Idiomatic JavaScript), which advise using one var, and listing following variables with commas.

// typically recommend
var firstName = 'Ryan',
    lastName = 'Gosling',
    age = 31,
    isAlive = true;

// multiple vars
var firstName = 'Ryan';
var lastName = 'Gosling';
var age = 31;
var isAlive = true;

At first I gawked at this style, but after using it for two months, I’m sticking with it. Using multiple vars have a couple benefits:

  • Easier to add more variables, no need to change any trailing comma or semi-colon.
  • Eliminates unnecessary git commit diffs, where a line has changed only because you changed a trailing semi-colon or comma.
  • Easier to read (IMO). var is a reserved keyword, so it jumps out when syntax highlighted.
  • Eliminates awkward tab spacing underneath the var. It only lines up if your tabs are 4 spaces wide.
  • (Per JFSIII) Helps collaboration, other devs might miss the change of semi-colon and accidentally add a global variable.

If you’re worried about bloating your code with all the superfluous vars, that should be taken care of when using a proper minifier.

Perspective values require px

Now that 3D transform support has landed in Firefox Aurora, it’s prime time to go back and revise any previous WebKit-only demos for other browsers.

Paul Rouget:

Please use “px” at the end of the perspective values. If you don’t, this will only works with Webkit (your examples don’t work correctly with Firefox because of that).

You got it, Paul.

#my-3d-environment {
  -webkit-perspective: 1000px;
     -moz-perspective: 1000px;
      -ms-perspective: 1000px;
       -o-perspective: 1000px;
          perspective: 1000px;
}