Loads a theme from either a path, github path (username/repo), or URL

A theme consists of the following (optional) files:
- style.css
- template.mustache
- layout.mustache
- script.js

If the source matches a URL, the function will assume the URL points to a
directory, in which it will look for the above files.

Otherwise, if the source matches a path that exists, the function will look
in that path for the files. If the source matches the form username/repo,
it will assume the source to be a GitHub repository.

@param {string} source The source to look for the theme
@param {Object} ctx The context to access fields such as templates and
and layouts
@return {Promise}
function loadTheme(source, ctx) {
  var promises = [];

  if (!fs.existsSync(source) && source.match(/^[\w-]+\/[\w-]+$/)) {
    source = 'https://raw.githubusercontent.com/' + source + '/master/';
  }

  if (!source.match(/\/$/)) {
    source += '/';
  }

  promises = [
    loadSettings(source + 'settings.json', ctx),
    populateSingle(source + 'style.css', ctx.external, 'style'),
    populateSingle(source + 'template.mustache', ctx.templates, 'slides'),
    populateSingle(source + 'layout.mustache', ctx.templates, 'layout'),
    populateSingle(source + 'script.js', ctx.external, 'script')
  ];

  return Q.all(promises);
}