utils.rb 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. module Sprockets
  2. # `Utils`, we didn't know where else to put it!
  3. module Utils
  4. # If theres encoding support (aka Ruby 1.9)
  5. if "".respond_to?(:valid_encoding?)
  6. # Define UTF-8 BOM pattern matcher.
  7. # Avoid using a Regexp literal because it inheirts the files
  8. # encoding and we want to avoid syntax errors in other interpreters.
  9. UTF8_BOM_PATTERN = Regexp.new("\\A\uFEFF".encode('utf-8'))
  10. def self.read_unicode(pathname)
  11. pathname.read.tap do |data|
  12. # Eager validate the file's encoding. In most cases we
  13. # expect it to be UTF-8 unless `default_external` is set to
  14. # something else. An error is usually raised if the file is
  15. # saved as UTF-16 when we expected UTF-8.
  16. if !data.valid_encoding?
  17. raise EncodingError, "#{pathname} has a invalid " +
  18. "#{data.encoding} byte sequence"
  19. # If the file is UTF-8 and theres a BOM, strip it for safe concatenation.
  20. elsif data.encoding.name == "UTF-8" && data =~ UTF8_BOM_PATTERN
  21. data.sub!(UTF8_BOM_PATTERN, "")
  22. end
  23. end
  24. end
  25. else
  26. # Define UTF-8 and UTF-16 BOM pattern matchers.
  27. # Avoid using a Regexp literal to prevent syntax errors in other interpreters.
  28. UTF8_BOM_PATTERN = Regexp.new("\\A\\xEF\\xBB\\xBF")
  29. UTF16_BOM_PATTERN = Regexp.new("\\A(\\xFE\\xFF|\\xFF\\xFE)")
  30. def self.read_unicode(pathname)
  31. pathname.read.tap do |data|
  32. # If the file is UTF-8 and theres a BOM, strip it for safe concatenation.
  33. if data =~ UTF8_BOM_PATTERN
  34. data.sub!(UTF8_BOM_PATTERN, "")
  35. # If we find a UTF-16 BOM, theres nothing we can do on
  36. # 1.8. Only UTF-8 is supported.
  37. elsif data =~ UTF16_BOM_PATTERN
  38. raise EncodingError, "#{pathname} has a UTF-16 BOM. " +
  39. "Resave the file as UTF-8 or upgrade to Ruby 1.9."
  40. end
  41. end
  42. end
  43. end
  44. # Prepends a leading "." to an extension if its missing.
  45. #
  46. # normalize_extension("js")
  47. # # => ".js"
  48. #
  49. # normalize_extension(".css")
  50. # # => ".css"
  51. #
  52. def self.normalize_extension(extension)
  53. extension = extension.to_s
  54. if extension[/^\./]
  55. extension
  56. else
  57. ".#{extension}"
  58. end
  59. end
  60. end
  61. end