strings-case 0.1.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +317 -0
- data/Rakefile +8 -0
- data/lib/strings-case.rb +1 -0
- data/lib/strings/case.rb +304 -0
- data/lib/strings/case/extensions.rb +50 -0
- data/lib/strings/case/version.rb +7 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/unit/camelcase_spec.rb +51 -0
- data/spec/unit/constcase_spec.rb +44 -0
- data/spec/unit/extensions_spec.rb +75 -0
- data/spec/unit/headercase_spec.rb +50 -0
- data/spec/unit/kebabcase_spec.rb +48 -0
- data/spec/unit/pascalcase_spec.rb +51 -0
- data/spec/unit/pathcase_spec.rb +51 -0
- data/spec/unit/sentencecase_spec.rb +51 -0
- data/spec/unit/snakecase_spec.rb +51 -0
- data/spec/unit/titlecase_spec.rb +51 -0
- data/strings-case.gemspec +32 -0
- data/tasks/console.rake +11 -0
- data/tasks/coverage.rake +11 -0
- data/tasks/spec.rake +29 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5985a29d7cd211560f31949ea90cacd559ec100cc993c12cd2d5c2a6c0fdb683
|
4
|
+
data.tar.gz: 9e542cd6473627f1f5bad0b05ec47a0e8b667bcbf00377cac5a918da13524fad
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9e73e4189c6af4a9458022af07b20a8863e9fb344dadd223a1e86ba16c44a2a798c7d8fd5f663b556e89f7c8577d060791eb05c59bc967c9d9e07faa39d07ac6
|
7
|
+
data.tar.gz: 7052e5e1fffd616a6c00fb92cb2869586a21232d062f1625c09503c79b396a21e645e432d63a648f479465ac99b25f25dfc83b1284009bff79a230d662ee7711
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Piotr Murach
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,317 @@
|
|
1
|
+
<div align="center">
|
2
|
+
<img width="225" src="https://github.com/piotrmurach/strings/blob/master/assets/strings_logo.png" alt="strings logo" />
|
3
|
+
</div>
|
4
|
+
|
5
|
+
# Strings::Case
|
6
|
+
|
7
|
+
[][gem]
|
8
|
+
[][travis]
|
9
|
+
[][appveyor]
|
10
|
+
[][codeclimate]
|
11
|
+
[][coverage]
|
12
|
+
[][inchpages]
|
13
|
+
|
14
|
+
[gem]: http://badge.fury.io/rb/strings-case
|
15
|
+
[travis]: http://travis-ci.org/piotrmurach/strings-case
|
16
|
+
[appveyor]: https://ci.appveyor.com/project/piotrmurach/strings-case
|
17
|
+
[codeclimate]: https://codeclimate.com/github/piotrmurach/strings-case/maintainability
|
18
|
+
[coverage]: https://coveralls.io/github/piotrmurach/strings-case?branch=master
|
19
|
+
[inchpages]: http://inch-ci.org/github/piotrmurach/strings-case
|
20
|
+
|
21
|
+
> Convert strings to different cases.
|
22
|
+
|
23
|
+
**Strings::Case** provides string case conversions for [Strings](https://github.com/piotrmurach/strings) utilities.
|
24
|
+
|
25
|
+
## Motivation
|
26
|
+
|
27
|
+
Popular solutions that deal with transforming string cases work well in simple cases.(Sorry ;-) With more complex strings you may get unexpected results:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
ActiveSupport::Inflector.underscore("supports IPv6 on iOS?")
|
31
|
+
# => "supports i_pv6 on i_os?"
|
32
|
+
```
|
33
|
+
|
34
|
+
In contrast, `Strings::Case` aims to be able to transform any string to expected case:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
Strings::Case.underscore("supports IPv6 on iOS?")
|
38
|
+
# => "supports_ipv6_on_ios"
|
39
|
+
```
|
40
|
+
|
41
|
+
## Installation
|
42
|
+
|
43
|
+
Add this line to your application's Gemfile:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
gem 'strings-case'
|
47
|
+
```
|
48
|
+
|
49
|
+
And then execute:
|
50
|
+
|
51
|
+
$ bundle
|
52
|
+
|
53
|
+
Or install it yourself as:
|
54
|
+
|
55
|
+
$ gem install strings-case
|
56
|
+
|
57
|
+
|
58
|
+
## Features
|
59
|
+
|
60
|
+
* No monkey-patching String class
|
61
|
+
* Converts any string to specified case
|
62
|
+
* Supports Unicode characters
|
63
|
+
* Provides many common case transformations
|
64
|
+
* Allows to preserve casing of acronyms
|
65
|
+
|
66
|
+
## Contents
|
67
|
+
|
68
|
+
* [1. Usage](#1-usage)
|
69
|
+
* [2. API](#2-api)
|
70
|
+
* [2.1 camelcase](#21-camelcase)
|
71
|
+
* [2.2 constcase](#22-constcase)
|
72
|
+
* [2.3 headercase](#23-headercase)
|
73
|
+
* [2.4 kebabcase | dashcase](#24-kebabcase--dashcase)
|
74
|
+
* [2.5 pascalcase](#25-pascalcase)
|
75
|
+
* [2.6 pathcase](#26-pathcase)
|
76
|
+
* [2.7 sentencecase](#27-sentencecase)
|
77
|
+
* [2.8 snakecase | underscore](#28-snakecase--underscore)
|
78
|
+
* [2.9 titlecase](#29-titlecase)
|
79
|
+
* [3. Extending String class](#3-extending-string-class)
|
80
|
+
|
81
|
+
## 1. Usage
|
82
|
+
|
83
|
+
The `Strings::Case` is a module with functions for transforming between string cases:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
Strings::Case.snakecase("foo bar baz")
|
87
|
+
# => "foo_bar_baz"
|
88
|
+
````
|
89
|
+
|
90
|
+
It will transform any string into expected case:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
Strings::Case.snake_case("supports IPv6 on iOS?")
|
94
|
+
# => "supports_ipv6_on_ios"
|
95
|
+
```
|
96
|
+
|
97
|
+
You can apply case transformations to Unicode characters:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
Strings::Case.snake_case("ЗдравствуйтеПривет")
|
101
|
+
# => "здравствуйте_привет"
|
102
|
+
```
|
103
|
+
|
104
|
+
Here is a quick summary of available transformations:
|
105
|
+
|
106
|
+
| Case Type | Result |
|
107
|
+
| --------- | ------- |
|
108
|
+
| ```Strings::Case.camelcase("foo bar baz")``` | `"fooBarBaz"` |
|
109
|
+
| ```Strings::Case.constcase("foo bar baz")``` | `"FOO_BAR_BAZ"` |
|
110
|
+
| ```Strings::Case.headercase("foo bar baz")``` | `"Foo-Bar-Baz"` |
|
111
|
+
| ```Strings::Case.kebabcase("foo bar baz")``` | `"foo-bar-baz"` |
|
112
|
+
| ```Strings::Case.pascalcase("foo bar baz")``` | `"FooBarBaz"` |
|
113
|
+
| ```Strings::Case.pathcase("foo bar baz")``` | `"foo/bar/baz"` |
|
114
|
+
| ```Strings::Case.sentencecase("foo bar baz")``` | `"Foo bar baz"` |
|
115
|
+
| ```Strings::Case.snakecase("foo bar baz")``` | `"foo_bar_baz"` |
|
116
|
+
| ```Strings::Case.titlecase("foo bar baz")``` | `"Foo Bar Baz"` |
|
117
|
+
|
118
|
+
## 2. API
|
119
|
+
|
120
|
+
### 2.1 camelcase
|
121
|
+
|
122
|
+
To convert a string into a camel case, that is, a case with all the words capitilized apart from the first one and compouned together without any space use `camelase` method. For example:
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
Strings::Case.camelcase("HTTP Response Code")
|
126
|
+
# => "httpResponseCode"
|
127
|
+
```
|
128
|
+
|
129
|
+
To preserve the acronyms use the `:acronyms` option:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
Strings::Case.camelcase("HTTP Response Code", acronyms: ["HTTP"])
|
133
|
+
# => "HTTPResponseCode"
|
134
|
+
```
|
135
|
+
|
136
|
+
### 2.2 constcase
|
137
|
+
|
138
|
+
To convert a string into a constant case, that is, a case with all the words uppercased and separated by underscore character use `constcase`. For example:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
Strings::Case.constcase("HTTP Response Code")
|
142
|
+
# => "HTTP_RESPONSE_CODE"
|
143
|
+
```
|
144
|
+
|
145
|
+
### 2.3 headercase
|
146
|
+
|
147
|
+
To covert a string into a header case, that is, a case with all the words capitalized and separated by a hypen use `headercase`. For example:
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
Strings::Case.headercase("HTTP Response Code")
|
151
|
+
# => "Http-Response-Code"
|
152
|
+
```
|
153
|
+
|
154
|
+
To preserve the acronyms use the `:acronyms` option:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
Strings::Case.headercase("HTTP Response Code", acronyms: ["HTTP"])
|
158
|
+
# => "HTTP-Response-Code"
|
159
|
+
```
|
160
|
+
### 2.4 kebabcase | dashcase
|
161
|
+
|
162
|
+
To convert a string into a kebab case, that is, a case with all the words lowercased and separted by a dash, like a words kebabab on a skewer, use `kebabcase` or `dashcase` methods. For example:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
Strings::Case.kebabcase("HTTP Response Code")
|
166
|
+
# => "http-response-code"
|
167
|
+
```
|
168
|
+
|
169
|
+
To preserve the acronyms use the `:acronyms` option:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
Strings::Case.dashcase("HTTP Response Code", acronyms: ["HTTP"])
|
173
|
+
|
174
|
+
expect(dashed).to eq("HTTP-response-code")
|
175
|
+
```
|
176
|
+
|
177
|
+
### 2.5 pascalcase
|
178
|
+
|
179
|
+
To convert a string into a pascal case, that is, a case with all the words capitilized and compounded together without a space, use `pascalcase` method. For example:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
Strings::Case.pascalcase("HTTP Response Code")
|
183
|
+
# => "HttpResponseCode"
|
184
|
+
```
|
185
|
+
|
186
|
+
To preserve the acronyms use the `:acronyms` option:
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
Strings::Case.pascalcase("HTTP Response Code")
|
190
|
+
# => "HTTPResponseCode"
|
191
|
+
```
|
192
|
+
|
193
|
+
### 2.6 pathcase
|
194
|
+
|
195
|
+
To convert a string into a file path use `pathcase`:
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
Strings::Case.pathcase("HTTP Response Code")
|
199
|
+
# => "http/response/code"
|
200
|
+
````
|
201
|
+
|
202
|
+
To preserve the acronyms use the `:acronyms` option:
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
Strings::Case.pathcase("HTTP Response Code", acronyms: ["HTTP"])
|
206
|
+
# => "HTTP/response/code"
|
207
|
+
```
|
208
|
+
|
209
|
+
By default the `/` is used as a path separator. To change this use a `:sep` option. For example, on Windows the file path separator is `\`:
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
Strings::Case.pathcase("HTTP Response Code", separator: "\\")
|
213
|
+
# => "http\response\code"
|
214
|
+
```
|
215
|
+
|
216
|
+
### 2.7 `sentencecase`
|
217
|
+
|
218
|
+
To turn a string into a sentence use `sentencecase`:
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
Strings::Case.sentencecase("HTTP Response Code")
|
222
|
+
# => "Http response code"
|
223
|
+
```
|
224
|
+
|
225
|
+
To preserve the `HTTP` acronym use the `:acronyms` option:
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
Strings::Case.sentencecase("HTTP Response Code", acronyms: ["HTTP"])
|
229
|
+
# => "HTTP response code"
|
230
|
+
```
|
231
|
+
|
232
|
+
### 2.8 `snakecase` | `underscore`
|
233
|
+
|
234
|
+
To convert a string into a snake case by lowercasing all the characters and separating them with an `_` use `snakecase` or `underscore` methods. For example:
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
Strings::Case.snakecase("HTTP Response Code")
|
238
|
+
# => "http_response_code"
|
239
|
+
```
|
240
|
+
|
241
|
+
To preserve acronyms in your string use the `:acronyms` option. For example:
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
Strings::Case.snakecase("HTTP Response Code", acronyms: ["HTTP"])
|
245
|
+
# => "HTTP_response_code"
|
246
|
+
```
|
247
|
+
|
248
|
+
### 2.9 `titlecase`
|
249
|
+
|
250
|
+
To convert a string into a space delimited words that have their first letter capitalized use `titlecase`. For example:
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
Strings::Case.titlecase("HTTPResponseCode")
|
254
|
+
# => "Http Response Code"
|
255
|
+
```
|
256
|
+
|
257
|
+
To preserve the `HTTP` acronym use the `:acronyms` option:
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
Strings::Case.titlecase("HTTP response code", acronyms: ["HTTP"])
|
261
|
+
# => "HTTP Response Code"
|
262
|
+
```
|
263
|
+
|
264
|
+
## 3. Extending String class
|
265
|
+
|
266
|
+
Though it is highly discouraged to pollute core Ruby classes, you can add the required methods to `String` class by using refinements.
|
267
|
+
|
268
|
+
For example, if you wish to only extend strings with `wrap` method do:
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
module MyStringExt
|
272
|
+
refine String do
|
273
|
+
def snakecase(*args)
|
274
|
+
Strings::Case.snakecase(self, *args)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
```
|
279
|
+
|
280
|
+
Then `snakecase` method will be available for any strings where refinement is applied:
|
281
|
+
|
282
|
+
```ruby
|
283
|
+
using MyStringExt
|
284
|
+
|
285
|
+
"foo bar baz".snakecase
|
286
|
+
# => "foo_bar_baz"
|
287
|
+
```
|
288
|
+
|
289
|
+
However, if you want to include all the **Strings::Case** methods, you can use provided extensions file:
|
290
|
+
|
291
|
+
```ruby
|
292
|
+
require "strings/case/extensions"
|
293
|
+
|
294
|
+
using Strings::Case::Extensions
|
295
|
+
```
|
296
|
+
|
297
|
+
## Development
|
298
|
+
|
299
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
300
|
+
|
301
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
302
|
+
|
303
|
+
## Contributing
|
304
|
+
|
305
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/strings-case. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
306
|
+
|
307
|
+
## License
|
308
|
+
|
309
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
310
|
+
|
311
|
+
## Code of Conduct
|
312
|
+
|
313
|
+
Everyone interacting in the Strings::Case project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/strings-case/blob/master/CODE_OF_CONDUCT.md).
|
314
|
+
|
315
|
+
## Copyright
|
316
|
+
|
317
|
+
Copyright (c) 2019 Piotr Murach. See LICENSE for further details.
|
data/Rakefile
ADDED
data/lib/strings-case.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "strings/case"
|
data/lib/strings/case.rb
ADDED
@@ -0,0 +1,304 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "case/version"
|
4
|
+
|
5
|
+
module Strings
|
6
|
+
module Case
|
7
|
+
DIGITS = ("0".."9").freeze
|
8
|
+
UP_LETTERS = ("A".."Z").freeze
|
9
|
+
DOWN_LETTERS = ("a".."z").freeze
|
10
|
+
DELIMITERS = [" ", "\n", "\t", "_", ".", "-", "#", "?", "!"].freeze
|
11
|
+
NONALPHANUMERIC = (32..127).map(&:chr) -
|
12
|
+
(DIGITS.to_a + DOWN_LETTERS.to_a + UP_LETTERS.to_a + DELIMITERS)
|
13
|
+
UPCASE = /(?<!\p{Lu})\p{Lu}$/.freeze
|
14
|
+
LOWERCASE = /\p{Lu}(?=\p{Ll})/.freeze
|
15
|
+
|
16
|
+
class Error < StandardError; end
|
17
|
+
|
18
|
+
# Prevent changing case
|
19
|
+
module NullCase
|
20
|
+
def downcase
|
21
|
+
self
|
22
|
+
end
|
23
|
+
alias upcase downcase
|
24
|
+
alias capitalize downcase
|
25
|
+
end
|
26
|
+
|
27
|
+
# Convert string to camel case:
|
28
|
+
# * start with a lowercase character
|
29
|
+
# * every subsequent word has its first character uppercased
|
30
|
+
# * all words are compounded together
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# camelcase("foo bar baz") # => "fooBarBaz"
|
34
|
+
#
|
35
|
+
# @param [String] string
|
36
|
+
# the string to camelcase
|
37
|
+
# @param [Array[String]] acronyms
|
38
|
+
# the acronyms to use to prevent modifications
|
39
|
+
# @param [String] separator
|
40
|
+
# the separator for linking words, by default none
|
41
|
+
#
|
42
|
+
# @api public
|
43
|
+
def camelcase(string, acronyms: [], separator: "")
|
44
|
+
res = parsecase(string, acronyms: acronyms, sep: separator, casing: :capitalize)
|
45
|
+
|
46
|
+
return res if res.to_s.empty?
|
47
|
+
|
48
|
+
acronyms_regex = /^(#{acronyms.join("|")})/
|
49
|
+
if !acronyms.empty? && (res =~ acronyms_regex)
|
50
|
+
res
|
51
|
+
else
|
52
|
+
res[0].downcase + res[1..-1]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
module_function :camelcase
|
56
|
+
|
57
|
+
alias lower_camelcase camelcase
|
58
|
+
module_function :lower_camelcase
|
59
|
+
|
60
|
+
# Converts string to a constant
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# constantcase("foo bar baz") # => "FOO_BAR_BAZ"
|
64
|
+
#
|
65
|
+
# @param [String] string
|
66
|
+
# the string to turn into constant
|
67
|
+
# @param [Array[String]] acronyms
|
68
|
+
# the acronyms to use to prevent modifications
|
69
|
+
# @param [String] separator
|
70
|
+
# the words separator, by default "_"
|
71
|
+
#
|
72
|
+
# @api public
|
73
|
+
def constcase(string, separator: "_")
|
74
|
+
parsecase(string, sep: separator, casing: :upcase)
|
75
|
+
end
|
76
|
+
module_function :constcase
|
77
|
+
|
78
|
+
alias constantcase constcase
|
79
|
+
module_function :constantcase
|
80
|
+
|
81
|
+
# Convert string to a HTTP Header
|
82
|
+
#
|
83
|
+
# @example
|
84
|
+
# headercase("foo bar baz") # = "Foo-Bar-Baz"
|
85
|
+
#
|
86
|
+
# @param [String] string
|
87
|
+
# the string to turn into header
|
88
|
+
# @param [Array[String]] acronyms
|
89
|
+
# the acronyms to use to prevent modifications
|
90
|
+
# @param [String] separator
|
91
|
+
# the words separator, by default "-"
|
92
|
+
#
|
93
|
+
# @api public
|
94
|
+
def headercase(string, acronyms: [], separator: "-")
|
95
|
+
parsecase(string, acronyms: acronyms, sep: separator, casing: :capitalize)
|
96
|
+
end
|
97
|
+
module_function :headercase
|
98
|
+
|
99
|
+
# Converts string to lower case words linked by hyphenes
|
100
|
+
#
|
101
|
+
# @example
|
102
|
+
# kebabcase("fooBarBaz") # => "foo-bar-baz"
|
103
|
+
#
|
104
|
+
# kebabcase("__FOO_BAR__") # => "foo-bar"
|
105
|
+
#
|
106
|
+
# @param [String] string
|
107
|
+
# the string to convert to dashed string
|
108
|
+
# @param [Array[String]] acronyms
|
109
|
+
# the acronyms to use to prevent modifications
|
110
|
+
# @param [String] separator
|
111
|
+
# the separator for linking words, by default hyphen
|
112
|
+
#
|
113
|
+
# @return [String]
|
114
|
+
#
|
115
|
+
# @api public
|
116
|
+
def kebabcase(string, acronyms: [], separator: "-")
|
117
|
+
parsecase(string, acronyms: acronyms, sep: separator)
|
118
|
+
end
|
119
|
+
module_function :kebabcase
|
120
|
+
|
121
|
+
alias dashcase kebabcase
|
122
|
+
module_function :dashcase
|
123
|
+
|
124
|
+
# Convert string to pascal case:
|
125
|
+
# * every word has its first character uppercased
|
126
|
+
# * all words are compounded together
|
127
|
+
#
|
128
|
+
# @example
|
129
|
+
# pascalcase("foo bar baz") # => "FooBarBaz"
|
130
|
+
#
|
131
|
+
# @param [String] string
|
132
|
+
# the string to convert to camel case with capital letter
|
133
|
+
# @param [Array[String]] acronyms
|
134
|
+
# the acronyms to use to prevent modifications
|
135
|
+
# @param [String] separator
|
136
|
+
# the separator for linking words, by default none
|
137
|
+
#
|
138
|
+
# @api public
|
139
|
+
def pascalcase(string, acronyms: [], separator: "")
|
140
|
+
parsecase(string, acronyms: acronyms, sep: separator, casing: :capitalize)
|
141
|
+
end
|
142
|
+
module_function :pascalcase
|
143
|
+
|
144
|
+
alias upper_camelcase pascalcase
|
145
|
+
module_function :upper_camelcase
|
146
|
+
|
147
|
+
# Convert string into a file path.
|
148
|
+
#
|
149
|
+
# By default uses `/` as a path separator.
|
150
|
+
#
|
151
|
+
# @example
|
152
|
+
# pathcase("foo bar baz") # => "foo/bar/baz"
|
153
|
+
#
|
154
|
+
# pathcase("FooBarBaz") # => "foo/bar/baz"
|
155
|
+
#
|
156
|
+
# @param [String] string
|
157
|
+
# the string to convert to file path
|
158
|
+
# @param [Array[String]] acronyms
|
159
|
+
# the acronyms to use to prevent modifications
|
160
|
+
# @param [String] separator
|
161
|
+
# the separator for linking words, by default `/`
|
162
|
+
#
|
163
|
+
# @api public
|
164
|
+
def pathcase(string, acronyms: [], separator: "/")
|
165
|
+
parsecase(string, acronyms: acronyms, sep: separator)
|
166
|
+
end
|
167
|
+
module_function :pathcase
|
168
|
+
|
169
|
+
# Convert string int a sentence
|
170
|
+
#
|
171
|
+
# @example
|
172
|
+
# sentencecase("foo bar baz") # => "Foo bar baz"
|
173
|
+
#
|
174
|
+
# @param [String] string
|
175
|
+
# the string to convert to sentence
|
176
|
+
# @param [Array[String]] acronyms
|
177
|
+
# the acronyms to use to prevent modifications
|
178
|
+
# @param [String] separator
|
179
|
+
# the separator for linking words, by default a space
|
180
|
+
#
|
181
|
+
# @api public
|
182
|
+
def sentencecase(string, acronyms: [], separator: " ")
|
183
|
+
res = parsecase(string, acronyms: acronyms, sep: separator, casing: :downcase)
|
184
|
+
|
185
|
+
return res if res.to_s.empty?
|
186
|
+
|
187
|
+
res[0].upcase + res[1..-1]
|
188
|
+
end
|
189
|
+
module_function :sentencecase
|
190
|
+
|
191
|
+
# Convert string into a snake_case
|
192
|
+
#
|
193
|
+
# @example
|
194
|
+
# snakecase("foo bar baz") # => "foo_bar_baz"
|
195
|
+
#
|
196
|
+
# snakecase("ЗдравствуйтеПривет") # => "здравствуйте_привет"
|
197
|
+
#
|
198
|
+
# snakecase("HTTPResponse") # => "http_response"
|
199
|
+
#
|
200
|
+
# @param [String] string
|
201
|
+
# the string to convert to snake case
|
202
|
+
# @param [Array[String]] acronyms
|
203
|
+
# the acronyms to use to prevent modifications
|
204
|
+
# @param [String] separator
|
205
|
+
# the separator for linking words, by default `_`
|
206
|
+
#
|
207
|
+
# @api public
|
208
|
+
def snakecase(string, acronyms: [], separator: "_")
|
209
|
+
parsecase(string, acronyms: acronyms, sep: separator)
|
210
|
+
end
|
211
|
+
module_function :snakecase
|
212
|
+
|
213
|
+
alias underscore snakecase
|
214
|
+
module_function :underscore
|
215
|
+
|
216
|
+
# Convert string into a title case
|
217
|
+
#
|
218
|
+
# @example
|
219
|
+
# titlecase("foo bar baz") # => "Foo Bar Baz"
|
220
|
+
#
|
221
|
+
# @param [String] string
|
222
|
+
# the string to convert to title case
|
223
|
+
# @param [Array[String]] acronyms
|
224
|
+
# the acronyms to use to prevent modifications
|
225
|
+
# @param [String] separator
|
226
|
+
# the separator for linking words, by default a space
|
227
|
+
#
|
228
|
+
# @api public
|
229
|
+
def titlecase(string, acronyms: [], separator: " ")
|
230
|
+
parsecase(string, acronyms: acronyms, sep: separator, casing: :capitalize)
|
231
|
+
end
|
232
|
+
module_function :titlecase
|
233
|
+
|
234
|
+
# Parse string and transform to desired case
|
235
|
+
#
|
236
|
+
# @api private
|
237
|
+
def parsecase(string, acronyms: [], sep: "_", casing: :downcase)
|
238
|
+
return if string.nil?
|
239
|
+
|
240
|
+
words = split_into_words(string, sep: sep)
|
241
|
+
|
242
|
+
no_case = ->(w) { acronyms.include?(w) ? w.extend(NullCase) : w }
|
243
|
+
|
244
|
+
words
|
245
|
+
.map(&no_case)
|
246
|
+
.map(&casing)
|
247
|
+
.join(sep)
|
248
|
+
end
|
249
|
+
module_function :parsecase
|
250
|
+
private_class_method :parsecase
|
251
|
+
|
252
|
+
# Split string into words
|
253
|
+
#
|
254
|
+
# @return [Array[String]]
|
255
|
+
# the split words
|
256
|
+
#
|
257
|
+
# @api private
|
258
|
+
def split_into_words(string, sep: nil)
|
259
|
+
words = []
|
260
|
+
word = []
|
261
|
+
last = string.length - 1
|
262
|
+
|
263
|
+
string.each_char.with_index do |char, i|
|
264
|
+
combine = word[-1].to_s + char
|
265
|
+
|
266
|
+
if combine =~ UPCASE
|
267
|
+
if word.size <= 1 # don't allow single letter words
|
268
|
+
word << char
|
269
|
+
else
|
270
|
+
words << word.join
|
271
|
+
word = [char]
|
272
|
+
end
|
273
|
+
elsif combine =~ LOWERCASE
|
274
|
+
letter = word.pop
|
275
|
+
if word.size <= 1 # don't allow single letter words
|
276
|
+
word << letter << char
|
277
|
+
else
|
278
|
+
words << word.join
|
279
|
+
word = [letter, char]
|
280
|
+
end
|
281
|
+
elsif DELIMITERS.include?(char)
|
282
|
+
words << word.join unless word.empty?
|
283
|
+
if i.zero? && char == sep
|
284
|
+
words << ""
|
285
|
+
else
|
286
|
+
word = []
|
287
|
+
end
|
288
|
+
elsif NONALPHANUMERIC.include?(char)
|
289
|
+
# noop
|
290
|
+
else
|
291
|
+
word << char
|
292
|
+
end
|
293
|
+
|
294
|
+
if last == i
|
295
|
+
word = [""] if char == sep
|
296
|
+
words << word.join unless word.empty?
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
words
|
301
|
+
end
|
302
|
+
module_function :split_into_words
|
303
|
+
end # Case
|
304
|
+
end # Strings
|