A Small Snippet for Rails To Generate Filenames

Sometimes you need to generate a safe continuous ASCII string from a given text. You cannot trust the content of your input, as it is provided by some user and there are so many different edge cases. It would be nice if the original text is still readable, especially if it is written in a foreign language and contains names. Take the turkish name Özgür, if you strip the Ö and the ü you get zgr.

The following method tries to solve this problem. You can paste the snippet in any Rails application there are no other dependencies.

If you don’t use Rails you have to require “i18n” and replace the blank? and truncate calls.

SEPARATOR = "_"
DEFAULT_FILENAME = "asset"
MAX_FILENAME_SIZE = 64

# Creates a clean filename from a given text. This filename only
# includes 0-9a-zA-Z and SEPARATOR. Strange characters are
# substituted by their ASCII counterparts.
#
#   "Özgür das Flußpferd hat ein Déjà Vu!" # =>
#     "Ozgur_das_Flusspferd_hat_ein_Deja_Vu"
def filename_from(text)
  filename = I18n.transliterate(text, SEPARATOR ).
    gsub(/[^0-9a-zA-Z-]+/, '_')
  # remove trailing SEPARATOR
  filename = filename[1..-1] if filename[0] == SEPARATOR
  filename = filename[0..-2] if filename[-1] == SEPARATOR
  # remove ugly repititions of _ and -
  filename.gsub!(/[-#{SEPARATOR}][-#{SEPARATOR}][-#{SEPARATOR}]+/,
    "#{SEPARATOR}-#{SEPARATOR}")
  # blank? only works in rails
  filename = DEFAULT_FILENAME if filename.blank? || filename.match(/^[_-]+$/)
  # truncate only works in rails
  filename.truncate(MAX_FILENAME_SIZE, :omission => '')
end