There is a nice Ruby gem that allows for automatic CSS Sprite generation: Sprite Factory. It has lots of ways to configure it, and allows for output that works with the Rails asset pipeline, which is nice.

Unfortunately out of the box it doesn't help with generating retina ready sprite files (i.e. with 2x size files where you then scale the image back - such as described here).

Here is the script I ended up with, using the Sprite Factory gem:

require 'sprite_factory'

SOURCE_PATH = "../Downloads/icon-assets-2x/"
SELECTOR_PREFIX = ".icon"
OUTPUT_IMAGE = "icons_sprite.png"

SpriteFactory.run!(SOURCE_PATH, {
  library: "chunkypng",
  # go all lower case and convert spaces to underscores
  sanitizer: -> (name) { name.strip.downcase.gsub(/\s+/, '_').gsub(/[^A-z]/, '') },
  style: "scss",
  output_image: "app/assets/images/#{OUTPUT_IMAGE}",
  output_style: "app/assets/stylesheets/sprites/_icons.scss"
}) do |images|

  # Find the max right-most point of any sprite in the list.
  # This must therefore be the image width.
  image_width  = images.values.map { |data| data[:x] + data[:width] }.max

  output = <<-SCSS
    #{SELECTOR_PREFIX} {
      display: block;
      background-size: #{image_width / 2}px auto;
      background-image: image-url('#{OUTPUT_IMAGE}');
      background-repeat: no-repeat;
    }

  SCSS

  # The rest is standard, divide everything in half
  output << images.map do |name, data|
    <<-SCSS
#{SELECTOR_PREFIX}.#{name} {
  width: #{data[:width] / 2}px;
  height: #{data[:height] / 2}px;
  background-position: #{data[:x] / -2}px #{data[:y] / -2}px;
}
    SCSS
  end.join("\n")
end

Original script that provided some guidance.

The output is really clean:

.icon {
  display: block;
  background-size: 1204px auto;
  background-image: image-url('icons/sprite.png');
  background-repeat: no-repeat;
}


.icon.calendar {
  width: 68px;
  height: 65px;
  background-position: 0px -27px;
}

.icon.trash {
  width: 68px;
  height: 63px;
  background-position: -68px -28px;
}

...