Skip to content

MathQuill Style Guide

Han edited this page May 22, 2013 · 29 revisions

We're pretty OCD about our code. Since you'll have to put up with our idiosyncrasies to contribute to MathQuill, we figured we should write them down.

Commits

  • Each commit should only have one logical change, like each function only perform one logical task.
    • When you're about to commit a big diff, think about how you'd describe the changes you made to a person, like in code review: "first I did A so C would be possible, then I did B so D would be possible, ignore this indentation change, then I did CD now that N and M are possible." Then you should commit the indentation change, A, B, and CD as 4 separate commits with git add -p or -e.
  • Commit messages are documentation, like comments but for diffs instead of functions.
    • They can't be inline like comments, but they often don't belong in one particular place in a diff anyway, they pertain to something being removed from one place and added to another. In a big diff you're about to commit, each non-contiguous sub-diff that you can describe in a self-contained way is exactly how you should break down the big diff into several logical commits, with that self-contained description as each commit message.
    • Link to external documentation whenever you rely on any API besides ECMAScript 3 and jQuery, in the commit message at least if not a comment. Read it, too, to check for edge cases. Well-engineered things work in practice and in theory. Recommended docs include SitePoint (in addition to high-quality summaries of the spec, they always have a compat table broken down by version number), QuirksMode, MDN, Can I use..., W3C and WHATWG specs. Bonus points for permalinks. (Dark, dusty corners of ES3 and jQuery should be linked to docs, too.)

We try to follow standard git commit message formatting guidelines:

  • first line summarizes "what changed" and as much "why" as fits
    • 50 character soft limit, 72 character hard limit. Specifically, the last word can stick out past the 50-character-line (but not too far)
    • "hashtags", a homegrown convention, ignore the 50 character line (but not the 72 character line), if you want. They're not that important, they just help scannability and searchability.
  • if there's a body, a blank line after the first line is mandatory
  • body obeys 72 character line length, except for stuff like URLs and pasted text like error messages that should be preserved verbatim
  • be imperative: "Fix bug" and not "Fixed bug" or "Fixes bug"
  • be specific and descriptive: "Fix spacing in Fragment.between", not "Cleanup"

JavaScript

Format and code samples graciously borrowed (and by borrowed I mean plagiarized) from: http://docs.jquery.com/JQuery_Core_Style_Guidelines

Semicolons

  • Semicolons terminate all statements, including inside one-liner functions, except statement blocks.
// Heresy:
f(function() { return blah() })
while (predicate()) {
  a = x.something()
  b += a
};

// Sacred:
f(function() { return blah(); });
while (predicate()) {
  a = x.something();
  b += a;
}

Spacing

  • Indent your code with soft tabs, 2 spaces. There should be no hard tab characters anywhere, ever.
  • Strip all trailing whitespace, including on empty lines.
  • Make sure your files end with newlines (looking at you, TextMate users)
  • A single space always follows keywords, colons, and commas, and always separates oppositely-directed delimiters (like ) {)
// Heresy:
if(blah==="foo"){
  foo("bar","baz",{zoo:1});
}

// Sacred:
if (blah === "foo") {
  foo("bar", "baz", { zoo: 1 });
}
  • The exception to this is the function keyword, which is always followed directly by (
// Heresy:
function (foo) { bar(); }

// Sacred:
function(foo) { bar(); }
  • No parentheses padding
// Heresy:
foo( "bar", "baz", { zoo: 1 } );

// Sacred:
foo("bar", "baz", { zoo: 1 });
  • Opening braces are always have a space on either side, except before a semicolon.
// Heresy:
return{a: 1, b: function() {return 2;}} ;

// Sacred:
return { a: 1, b: function() { return 2; } };

Equality

  • Always use ===. Seriously. If you use == we will flay you.

Blocks

  • Braces should always be used on if/else/for/while/try, unless they are a single line. If it won't fit on a single line, put it on its own line and use braces. One-liners should be short and sweet, like guards that just return early.
// Heresy:
if (cond)
  blah();

// Sacred:
if (cond) {
   blah();
}

// Heresy:
if (cond) { blah(); }

// Sacred:
if (cond) blah();
  • else/else if/catch go on the line after the close brace.
if (cond1) {
  f1();
}
else if (cond2) {
  f2();
}
else {
  f3();
}
  • Don't use && as a conditional statement.
// Heresy
variable && variable.method();
// Sacred
if (variable) variable.method();

Strings

  • Strings should always be "double-quoted" in HTML/CSS and 'single-quoted' in JavaScript.