zaru 1.0.1 → 1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/zaru.rb +35 -24
  3. metadata +4 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3be0cb999f6287e9eb05028d4b1b67653d4b92ca4090e9ba02e0031e06150e3d
4
- data.tar.gz: 4aadd8f48d3ec42b0c596a119728ca6ad32daf80c024deb692f1077704ebd0e3
3
+ metadata.gz: 563b71271ed8169cd299499ef243e937f5fd3a04055377db87c0d821973a839e
4
+ data.tar.gz: a8f51824ca7a18598770f9a2a63c254565fe47ed4f616f87bcdd8c9e6d5f0201
5
5
  SHA512:
6
- metadata.gz: 3d6f69471eb7ce02f6e3e940784b7ccdaa479a3dd281e8259bf15a870a02c7473b77cbc24e0a1cba010ed1d0fe0b6b05c0d2d34761264a4ca55c944ce020f469
7
- data.tar.gz: 4085067f0407cad9cefde91add08d1973fbb3b393b8d57efaea1cb23ab4fb17fc34a851fae18c188d145511e34e54e5c80a08f6dbb1058a9a7a461c5f3a20c32
6
+ metadata.gz: f4b51ce4dc951a7ecbf2867b2554505ca0837392cee8e1f8b0bc26fcfebdffb6d787006c9764bd2b1d1e8ca9dd71a8ce9114459ba2ea783b6e0ecd0e16c0aeac
7
+ data.tar.gz: 9470144c2ca5b9a5eb79b030bad989ee0fa3d638a1572e38a1e69799a1da1dac1e8daaa65b2fe97aebadb126e50c528dfcc7890d243afd0a73e146c441f4f24e
data/lib/zaru.rb CHANGED
@@ -1,12 +1,14 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
+ # Zaru normalizes, sanitizes, and truncates filenames so they can be
4
+ # safely used across Linux, macOS, and Windows.
3
5
  class Zaru
4
- CHARACTER_FILTER = /[\x00-\x1F\/\\:\*\?\"<>\|]/u
5
- UNICODE_WHITESPACE = /[[:space:]]+/u
6
+ CHARACTER_FILTER = %r{[\x00-\x1F/\\:*?"<>|]}u.freeze
7
+ UNICODE_WHITESPACE = /[[:space:]]+/u.freeze
6
8
  WINDOWS_RESERVED_NAMES =
7
- %w{CON PRN AUX NUL COM1 COM2 COM3 COM4 COM5
8
- COM6 COM7 COM8 COM9 LPT1 LPT2 LPT3 LPT4
9
- LPT5 LPT6 LPT7 LPT8 LPT9}
9
+ %w[CON PRN AUX NUL COM1 COM2 COM3 COM4 COM5 COM6 COM7 COM8 COM9
10
+ COM COM² COM³ LPT1 LPT2 LPT3 LPT4 LPT5 LPT6 LPT7 LPT8 LPT9 LPT¹
11
+ LPT² LPT³].freeze
10
12
  FALLBACK_FILENAME = 'file'
11
13
 
12
14
  def initialize(filename, options = {})
@@ -18,7 +20,7 @@ class Zaru
18
20
  # strip whitespace on beginning and end
19
21
  # collapse intra-string whitespace into single spaces
20
22
  def normalize
21
- @normalized ||= @raw.strip.gsub(UNICODE_WHITESPACE,' ')
23
+ @normalize ||= @raw.strip.gsub(UNICODE_WHITESPACE, ' ')
22
24
  end
23
25
 
24
26
  # remove bad things!
@@ -29,15 +31,16 @@ class Zaru
29
31
  #
30
32
  # this renormalizes after filtering in order to collapse whitespace
31
33
  def sanitize
32
- @sanitized ||=
33
- filter(normalize.gsub(CHARACTER_FILTER,'')).gsub(UNICODE_WHITESPACE,' ')
34
+ @sanitize ||=
35
+ filter(normalize.gsub(CHARACTER_FILTER, '')).gsub(UNICODE_WHITESPACE, ' ')
34
36
  end
35
37
 
36
38
  # cut off at 255 characters
37
39
  # optionally provide a padding, which is useful to
38
40
  # make sure there is room to add a file extension later
39
41
  def truncate
40
- @truncated ||= sanitize.chars.to_a.slice(0..254-@padding).join
42
+ max_length = [254 - @padding, 0].max + 1
43
+ @truncate ||= sanitize.chars.to_a.slice(0...max_length).join
41
44
  end
42
45
 
43
46
  def to_s
@@ -51,24 +54,32 @@ class Zaru
51
54
 
52
55
  private
53
56
 
54
- attr_reader :fallback
57
+ attr_reader :fallback
55
58
 
56
- def filter(filename)
57
- filename = filter_windows_reserved_names(filename)
58
- filename = filter_blank(filename)
59
- filename = filter_dot(filename)
60
- end
59
+ def filter(filename)
60
+ filename = filter_windows_reserved_names(filename)
61
+ filename = filter_blank(filename)
62
+ filter_dot(filename)
63
+ end
61
64
 
62
- def filter_windows_reserved_names(filename)
63
- WINDOWS_RESERVED_NAMES.include?(filename.upcase) ? fallback : filename
64
- end
65
+ def filter_windows_reserved_names(filename)
66
+ return '' if filename.empty?
65
67
 
66
- def filter_blank(filename)
67
- filename.empty?? fallback : filename
68
- end
68
+ parts = filename.split('.').reject(&:empty?)
69
+ return '' if parts.empty?
69
70
 
70
- def filter_dot(filename)
71
- filename.start_with?('.')? "#{fallback}#{filename}" : filename
71
+ if WINDOWS_RESERVED_NAMES.include?(parts[0].upcase)
72
+ parts.fill(fallback, 0, 1).join('.')
73
+ else
74
+ filename
72
75
  end
76
+ end
77
+
78
+ def filter_blank(filename)
79
+ filename.empty? ? fallback : filename
80
+ end
73
81
 
82
+ def filter_dot(filename)
83
+ filename.start_with?('.') ? "#{fallback}#{filename}" : filename
84
+ end
74
85
  end
metadata CHANGED
@@ -1,56 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zaru
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: '1.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Fuchs
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-10-06 00:00:00.000000000 Z
11
- dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: bundler
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - ">="
17
- - !ruby/object:Gem::Version
18
- version: '0'
19
- type: :development
20
- prerelease: false
21
- version_requirements: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - ">="
24
- - !ruby/object:Gem::Version
25
- version: '0'
26
- - !ruby/object:Gem::Dependency
27
- name: rake
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :development
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '0'
40
- - !ruby/object:Gem::Dependency
41
- name: test-unit
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: '0'
47
- type: :development
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '0'
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
54
12
  description: Zaru takes a given filename (a string) and normalizes, filters and truncates
55
13
  it, so it can be safely used as a filename in modern operating systems. Zaru doesn't
56
14
  remove Unicode characters when not necessary.
@@ -71,7 +29,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
29
  requirements:
72
30
  - - ">="
73
31
  - !ruby/object:Gem::Version
74
- version: '1.9'
32
+ version: '2.0'
75
33
  required_rubygems_version: !ruby/object:Gem::Requirement
76
34
  requirements:
77
35
  - - ">="