strings-case 0.1.0

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: 5985a29d7cd211560f31949ea90cacd559ec100cc993c12cd2d5c2a6c0fdb683
4
+ data.tar.gz: 9e542cd6473627f1f5bad0b05ec47a0e8b667bcbf00377cac5a918da13524fad
5
+ SHA512:
6
+ metadata.gz: 9e73e4189c6af4a9458022af07b20a8863e9fb344dadd223a1e86ba16c44a2a798c7d8fd5f663b556e89f7c8577d060791eb05c59bc967c9d9e07faa39d07ac6
7
+ data.tar.gz: 7052e5e1fffd616a6c00fb92cb2869586a21232d062f1625c09503c79b396a21e645e432d63a648f479465ac99b25f25dfc83b1284009bff79a230d662ee7711
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # Change log
2
+
3
+ ## [v0.1.0] - 2019-11-11
4
+
5
+ * Initial implementation and release
6
+
7
+ [v0.1.0]: https://github.com/piotrmurach/strings-case/compare/v0.1.0
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 Version](https://badge.fury.io/rb/strings-case.svg)][gem]
8
+ [![Build Status](https://secure.travis-ci.org/piotrmurach/strings-case.svg?branch=master)][travis]
9
+ [![Build status](https://ci.appveyor.com/api/projects/status/yr87c96wxp1cw2ep?svg=true)][appveyor]
10
+ [![Maintainability](https://api.codeclimate.com/v1/badges/7938258c4af196a19843/maintainability)][codeclimate]
11
+ [![Coverage Status](https://coveralls.io/repos/github/piotrmurach/strings-case/badge.svg?branch=master)][coverage]
12
+ [![Inline docs](http://inch-ci.org/github/piotrmurach/strings-case.svg?branch=master)][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
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ FileList["tasks/**/*.rake"].each(&method(:import))
4
+
5
+ desc "Run all specs"
6
+ task ci: %w[ spec ]
7
+
8
+ task default: :spec
@@ -0,0 +1 @@
1
+ require_relative "strings/case"
@@ -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