Class: Zaru

Inherits:
Object
  • Object
show all
Defined in:
lib/zaru.rb

Overview

Zaru normalizes, sanitizes, and truncates filenames so they can be safely used across Linux, macOS, and Windows.

Constant Summary collapse

CHARACTER_FILTER =
%r{[\x00-\x1F/\\:*?"<>|]}u.freeze
UNICODE_WHITESPACE =
/[[:space:]]+/u.freeze
WINDOWS_RESERVED_NAMES =
%w[CON PRN AUX NUL COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9
COM COM² COM³ LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9 LPT¹
LPT² LPT³].freeze
FALLBACK_FILENAME =
'file'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename, options = {}) ⇒ Zaru

Returns a new instance of Zaru.



14
15
16
17
18
# File 'lib/zaru.rb', line 14

def initialize(filename, options = {})
  @fallback = options[:fallback] || FALLBACK_FILENAME
  @padding = options[:padding] || 0
  @raw = filename.to_s.freeze
end

Class Method Details

.sanitize!(filename, options = {}) ⇒ Object

convenience method



51
52
53
# File 'lib/zaru.rb', line 51

def self.sanitize!(filename, options = {})
  new(filename, options).to_s
end

Instance Method Details

#normalizeObject

strip whitespace on beginning and end collapse intra-string whitespace into single spaces



22
23
24
# File 'lib/zaru.rb', line 22

def normalize
  @normalize ||= @raw.strip.gsub(UNICODE_WHITESPACE, ' ')
end

#sanitizeObject

remove bad things!

  • remove characters that aren’t allowed cross-OS

  • don’t allow certain special filenames (issue on Windows)

  • don’t allow filenames to start with a dot

  • don’t allow empty filenames

this renormalizes after filtering in order to collapse whitespace



33
34
35
36
# File 'lib/zaru.rb', line 33

def sanitize
  @sanitize ||=
    filter(normalize.gsub(CHARACTER_FILTER, '')).gsub(UNICODE_WHITESPACE, ' ')
end

#to_sObject



46
47
48
# File 'lib/zaru.rb', line 46

def to_s
  truncate
end

#truncateObject

cut off at 255 characters optionally provide a padding, which is useful to make sure there is room to add a file extension later



41
42
43
44
# File 'lib/zaru.rb', line 41

def truncate
  max_length = [254 - @padding, 0].max + 1
  @truncate ||= sanitize.chars.to_a.slice(0...max_length).join
end