function prepareExample(exampleDir, isLocal, done) {
  const baseDir = 'examples';
  const packageJson = require(
    resolveApp(path.join(baseDir, exampleDir, 'package.json')),
  );

  // Cancel early if the package.json says this is not a demo.
  const {blocklyDemoConfig: demoConfig} = packageJson;
  if (!demoConfig) {
    done();
    return;
  }
  console.log(`Preparing ${exampleDir} example for deployment.`);

  const fileList = demoConfig.files;

  // Create target folder, if it doesn't exist.
  fs.mkdirSync(path.join('gh-pages', baseDir, exampleDir), {recursive: true});

  // Special case: do a straight copy for the devsite demo, with no wrappers.
  if (packageJson.name == 'blockly-devsite-demo') {
    return gulp
      .src(
        fileList.map((f) => path.join(baseDir, exampleDir, f)),
        {base: baseDir, allowEmpty: true},
      )
      .pipe(gulp.dest('./gh-pages/examples/'));
  }

  // All other examples.
  const pageRegex = /.*\.(html|htm)$/i;
  const pages = fileList.filter((f) => pageRegex.test(f));
  // Add headers and footers to HTML pages.
  pages.forEach((page) =>
    createExamplePage(`${baseDir}/${exampleDir}`, page, demoConfig, isLocal),
  );

  // Copy over all other files mentioned in the demoConfig to the
  // correct directory.
  const assets = fileList.filter((f) => !pageRegex.test(f));
  let stream;
  if (assets.length) {
    stream = gulp.src(
      assets.map((f) => path.join(baseDir, exampleDir, f)),
      {base: baseDir, allowEmpty: true},
    );
  }
  return stream.pipe(gulp.dest('./gh-pages/examples/'));
}
Copy over files listed in the blocklyDemoConfig.files section of the
package.json and create the demo HTML pages.
The resulting code lives in gh-pages/examples/<exampleName>.
@param {string} exampleDir The subdirectory (inside examples/) for this
    example.
@param {boolean} isLocal True if building for a local test. False if
    building for gh-pages.
@param {Function} done Completed callback.
@returns {Function | undefined} Gulp task.