sexy_slug 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d790a4c1a75bf89ae99be5f8199f8041f6e87e16a13a72c71581585bbd6e8bba
4
+ data.tar.gz: 296d25729f0fece000ba04ee621acff32d29dcbca922882f519ee421148be741
5
+ SHA512:
6
+ metadata.gz: 82ab515d4339eb3123b100732a257732748ba2a0844fda32be4fc5c3fc34f8f80ddadb77bcf69aabb200e36f1fff569e2a4cb44086b881d0cc214b3c23dc6ef5
7
+ data.tar.gz: c42da580bb64ba495a168145bb101a4fa03c06447f27322e93da942a225a17ac80421db1f3c3d7cc9e7355d133e92327276798dc1b7ffcd59ad90fe444c97c93
@@ -0,0 +1,7 @@
1
+ module SexySlug::AbbreviationDot
2
+ def self.call(string)
3
+ string.gsub(PATTERN) { |match| match.tr('.', '') }
4
+ end
5
+
6
+ PATTERN = /(?:\s|\(|^)(?:\p{alpha}(?:\.\p{alpha})+\.?\p{alpha}*(?:\s|\)|$))/
7
+ end
@@ -0,0 +1,5 @@
1
+ module SexySlug::ActiveSupportComposableChar
2
+ def self.call(string)
3
+ ActiveSupport::Multibyte::Chars.new(string).compose.to_s
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module SexySlug::ActiveSupportParameterize
2
+ def self.call(string)
3
+ ActiveSupport::Inflector.parameterize(string)
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ module SexySlug::Apostrophe
2
+ def self.call(string)
3
+ string.gsub(PATTERN, '')
4
+ end
5
+
6
+ PATTERN = /(?<=^|\p{alpha})['’`´](?=\p{alpha}|$)/
7
+ end
@@ -0,0 +1,7 @@
1
+ module SexySlug::DateTimeDelimiter
2
+ def self.call(string)
3
+ string.gsub(PATTERN, '-')
4
+ end
5
+
6
+ PATTERN = /(?<=\d)[:\/](?=\d)/
7
+ end
@@ -0,0 +1,162 @@
1
+ require 'yaml'
2
+
3
+ module SexySlug
4
+ TRANSLATIONS = YAML.load(File.read(__FILE__).split('__END__').last)
5
+ LOCALES = TRANSLATIONS.keys.map(&:to_sym)
6
+
7
+ def self.t(path)
8
+ path.split('.').inject(TRANSLATIONS[locale.to_s]) { |obj, key| obj[key] }
9
+ end
10
+
11
+ def self.locale
12
+ defined?(I18n) && LOCALES.include?(I18n.locale) ? I18n.locale : :en
13
+ end
14
+ end
15
+
16
+ __END__
17
+
18
+ de:
19
+ currency:
20
+ '$':
21
+ full:
22
+ one: Dollar
23
+ other: Dollar
24
+ part:
25
+ one: Cent
26
+ other: Cent
27
+ '€':
28
+ full:
29
+ one: Euro
30
+ other: Euro
31
+ part:
32
+ one: Cent
33
+ other: Cent
34
+ '£':
35
+ full:
36
+ one: Pfund
37
+ other: Pfund
38
+ part:
39
+ one: Pence
40
+ other: Pence
41
+
42
+ dot: Punkt
43
+
44
+ logogram:
45
+ '%': Prozent
46
+ '&': und
47
+ '+': plus
48
+ '/': oder
49
+ '=': gleich
50
+ '@': at
51
+ '°': Grad
52
+ '¼': ein Viertel
53
+ '½': halb
54
+ '¾': drei Viertel
55
+ '÷': geteilt durch
56
+ '⅓': ein Drittel
57
+ '⅔': zwei Drittel
58
+ '⅕': ein Fünftel
59
+ '⅖': zwei Fünftel
60
+ '⅗': drei Fünftel
61
+ '⅘': vier Fünftel
62
+ '⅙': ein Sechstel
63
+ '⅚': fünf Sechstel
64
+ '⅛': ein Achtel
65
+ '⅜': drei Achtel
66
+ '⅝': fünf Achtel
67
+ '⅞': sieben Achtel
68
+
69
+ number:
70
+ delimiter: '.'
71
+ separator: ','
72
+ sign:
73
+ hashtag: Hashtag
74
+ number: Nummer
75
+ word:
76
+ # only include numbers that are
77
+ # - conventionally spelled out in the locale
78
+ # - not subject to inflection
79
+ '0': null
80
+ '2': zwei
81
+ '3': drei
82
+ '4': vier
83
+ '5': fuenf
84
+ '6': sechs
85
+ '7': sieben
86
+ '8': acht
87
+ '9': neun
88
+ '10': zehn
89
+ '11': elf
90
+ '12': zwoelf
91
+
92
+ en:
93
+ currency:
94
+ '$':
95
+ full:
96
+ one: dollar
97
+ other: dollars
98
+ part:
99
+ one: cent
100
+ other: cents
101
+ '€':
102
+ full:
103
+ one: euro
104
+ other: euros
105
+ part:
106
+ one: cent
107
+ other: cents
108
+ '£':
109
+ full:
110
+ one: pound
111
+ other: pounds
112
+ part:
113
+ one: pence
114
+ other: pence
115
+
116
+ dot: dot
117
+
118
+ logogram:
119
+ '%': percent
120
+ '&': and
121
+ '+': plus
122
+ '/': or
123
+ '=': equals
124
+ '@': at
125
+ '°': degrees
126
+ '¼': one fourth
127
+ '½': half
128
+ '¾': three fourths
129
+ '÷': divided by
130
+ '⅓': one third
131
+ '⅔': two thirds
132
+ '⅕': one fifth
133
+ '⅖': two fifths
134
+ '⅗': three fifths
135
+ '⅘': four fifths
136
+ '⅙': one sixth
137
+ '⅚': five sixths
138
+ '⅛': one eighth
139
+ '⅜': three eighths
140
+ '⅝': five eighths
141
+ '⅞': seven eighths
142
+
143
+ number:
144
+ delimiter: ','
145
+ separator: '.'
146
+ sign:
147
+ hashtag: hashtag
148
+ number: number
149
+ word:
150
+ # only include numbers that are
151
+ # - conventionally spelled out in the locale
152
+ # - not subject to inflection
153
+ '0': zero
154
+ '1': one
155
+ '2': two
156
+ '3': three
157
+ '4': four
158
+ '5': five
159
+ '6': six
160
+ '7': seven
161
+ '8': eight
162
+ '9': nine
@@ -0,0 +1,7 @@
1
+ module SexySlug::Logogram
2
+ def self.call(string)
3
+ string.gsub(PATTERN) { ' ' + SexySlug.t("logogram.#{$1}") + ' ' }
4
+ end
5
+
6
+ PATTERN = /\s*(#{Regexp.union(SexySlug.t('logogram').keys)})\s*/
7
+ end
@@ -0,0 +1,30 @@
1
+ module SexySlug::MoneyAmount
2
+ def self.call(string)
3
+ result = string
4
+ separator = Regexp.escape(SexySlug.t('number.separator'))
5
+
6
+ SexySlug.t('currency').keys.each do |currency_symbol|
7
+ sym = Regexp.escape(currency_symbol)
8
+ next unless string.match?(/#{sym}/)
9
+
10
+ result = result.gsub(/
11
+ (?<=\s|^)
12
+ #{sym}\ *\d*(?:#{separator}\d+)? | \d*(?:#{separator}\d+)?\ *#{sym}
13
+ (?=\s|$)
14
+ /x) do |match|
15
+ translations = SexySlug.t("currency.#{currency_symbol}")
16
+
17
+ full, part = match.split(/#{separator}/).map { |el| el.to_s[/\d+/] }
18
+ part = nil if part.to_i == 0
19
+
20
+ [
21
+ full,
22
+ full && translations['full'][full.to_i == 1 ? 'one' : 'other'],
23
+ part,
24
+ part && translations['part'][part.to_i == 1 ? 'one' : 'other'],
25
+ ].compact.join(' ')
26
+ end
27
+ end
28
+ result
29
+ end
30
+ end
@@ -0,0 +1,6 @@
1
+ module SexySlug::NumberDelimiter
2
+ def self.call(string)
3
+ del = Regexp.escape(SexySlug.t('number.delimiter'))
4
+ string.gsub(/((?:^|[^\d#{del}])\d+)#{del}(\d+(?:[^\d#{del}]|$))/, '\1\2')
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module SexySlug::NumberSign
2
+ def self.call(string)
3
+ string.gsub(PATTERN) do
4
+ word = SexySlug.t("number.sign.#{$~[:number] ? :number : :hashtag}")
5
+ " #{word} #{$~[:target]}"
6
+ end
7
+ end
8
+
9
+ PATTERN = /\s*#\s*(?<target>(?<number>\d)|\w)/
10
+ end
@@ -0,0 +1,7 @@
1
+ module SexySlug::ShortNumber
2
+ def self.call(string)
3
+ words = SexySlug.t('number.word')
4
+ pattern = /(?<=\s|^)#{Regexp.union(words.keys)}(?=\s|$)/
5
+ string.gsub(pattern) { |match| words[match] }
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module SexySlug::SignificantDot
2
+ def self.call(string)
3
+ string.gsub(PATTERN, " #{SexySlug.t('dot')} ")
4
+ end
5
+
6
+ PATTERN = /(?<=[^\s\d.]|^)\.(?=[^\s\d.])/
7
+ end
@@ -0,0 +1,5 @@
1
+ module SexySlug::Underscore
2
+ def self.call(string)
3
+ string.tr('_', '-')
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ module SexySlug::UnreadableChar
2
+ def self.call(string)
3
+ string.gsub(PATTERN, '')
4
+ end
5
+
6
+ PATTERN = /\p{cntrl}/
7
+ end
@@ -0,0 +1,23 @@
1
+ module SexySlug::UsuallyTransliterableChar
2
+ def self.call(string)
3
+ string.gsub(PATTERN) { |match| TRANSLITERATIONS[match] }
4
+ end
5
+
6
+ TRANSLITERATIONS = {
7
+ 'Ä' => 'AE',
8
+ 'Å' => 'AA',
9
+ 'Æ' => 'AE',
10
+ 'Ö' => 'OE',
11
+ 'Ø' => 'OE',
12
+ 'Ü' => 'UE',
13
+ 'ß' => 'ss',
14
+ 'ä' => 'ae',
15
+ 'å' => 'aa',
16
+ 'æ' => 'ae',
17
+ 'ö' => 'oe',
18
+ 'ø' => 'oe',
19
+ 'ü' => 'ue',
20
+ }
21
+
22
+ PATTERN = Regexp.union(TRANSLITERATIONS.keys)
23
+ end
@@ -0,0 +1,3 @@
1
+ module SexySlug
2
+ VERSION = '1.0.1'
3
+ end
data/lib/sexy_slug.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'active_support/inflector/transliterate'
2
+ require 'active_support/multibyte'
3
+ require 'sexy_slug/i18n'
4
+ Dir[File.join(__dir__, 'sexy_slug', '*.rb')].each { |file| require file }
5
+
6
+ module SexySlug
7
+ def self.from(string)
8
+ PROCESSORS.inject(string.to_s) { |str, processor| processor.call(str) }
9
+ end
10
+
11
+ PROCESSORS = [
12
+ ActiveSupportComposableChar,
13
+ UnreadableChar,
14
+ Apostrophe,
15
+ NumberDelimiter,
16
+ DateTimeDelimiter,
17
+ MoneyAmount,
18
+ AbbreviationDot,
19
+ Logogram,
20
+ NumberSign,
21
+ ShortNumber,
22
+ SignificantDot,
23
+ Underscore,
24
+ UsuallyTransliterableChar,
25
+ ActiveSupportParameterize,
26
+ ]
27
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sexy_slug
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Janosch Müller
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '12.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '12.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: Build sexy slugs for your URL paths. A lightweight, opinionated alternative
70
+ to StringEx/ActAsUrl.
71
+ email:
72
+ - janosch84@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - lib/sexy_slug.rb
78
+ - lib/sexy_slug/abbreviation_dot.rb
79
+ - lib/sexy_slug/active_support_composable_char.rb
80
+ - lib/sexy_slug/active_support_parameterize.rb
81
+ - lib/sexy_slug/apostrophe.rb
82
+ - lib/sexy_slug/date_time_delimiter.rb
83
+ - lib/sexy_slug/i18n.rb
84
+ - lib/sexy_slug/logogram.rb
85
+ - lib/sexy_slug/money_amount.rb
86
+ - lib/sexy_slug/number_delimiter.rb
87
+ - lib/sexy_slug/number_sign.rb
88
+ - lib/sexy_slug/short_number.rb
89
+ - lib/sexy_slug/significant_dot.rb
90
+ - lib/sexy_slug/underscore.rb
91
+ - lib/sexy_slug/unreadable_char.rb
92
+ - lib/sexy_slug/usually_transliterable_char.rb
93
+ - lib/sexy_slug/version.rb
94
+ homepage: https://github.com/jaynetics/sexy_slug
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 2.3.0
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubygems_version: 3.0.3
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Builds slugs from Strings
117
+ test_files: []