strings 0.0.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9e41ccf14d9b18a56b33fd8c8fd48b77a8c2a5a
4
- data.tar.gz: ea3bca3b3650cb4ac10804193afd41a22b5817ee
3
+ metadata.gz: 6d3712358619d5f8d24a776c05e69e721a95bde5
4
+ data.tar.gz: 06a4637fe88656f23a5e2d72f88184c6ed2a77fe
5
5
  SHA512:
6
- metadata.gz: a8282b356021b4cd2d059cb931f0bb7a3be630bd1f1debb8611e4c92849e1670ecbd99e9b9946507f1103fb6f77c9fe67cca438355a14c24ca4e2b836170e55a
7
- data.tar.gz: f0c99f23df7d37de8b16bc35881ef58e0b87148d9cc17af93a8150257c94afb7034592ceb4415d3a5b816bb300703dfa4b0ffc8336028350e5f35a82e86001df
6
+ metadata.gz: e486b066d003f2f7445cea67b571b48c6705d34b07a684d489eb179d1fed143c6b9ed2fce4cfab5698e036947e9984c0ef3a47b00c1906141db18e2de8f8819d
7
+ data.tar.gz: f4f9057f7003aaf5837f40d1d27de423e8288f94f4016c5590af01d0d09e39fd05d431f3090566e0baae0f5b5cb8f5bc195212d1f32e0aa51a95ff8d0b234ba1
data/.rspec CHANGED
@@ -1,2 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
+ --require spec_helper
4
+ --warnings
@@ -1,5 +1,22 @@
1
- sudo: false
1
+ ---
2
2
  language: ruby
3
+ sudo: false
4
+ cache: bundler
5
+ before_install: "gem update bundler"
6
+ script: "bundle exec rake ci"
3
7
  rvm:
4
- - 2.3.1
5
- before_install: gem install bundler -v 1.15.4
8
+ - 2.0.0
9
+ - 2.1.10
10
+ - 2.2.8
11
+ - 2.3.6
12
+ - 2.4.3
13
+ - ruby-head
14
+ - jruby-9000
15
+ - jruby-head
16
+ matrix:
17
+ allow_failures:
18
+ - rvm: ruby-head
19
+ - rvm: jruby-head
20
+ fast_finish: true
21
+ branches:
22
+ only: master
@@ -0,0 +1,7 @@
1
+ # Change log
2
+
3
+ ## [v0.1.0] - 2018-01-07
4
+
5
+ * Inital implementation and release
6
+
7
+ [v0.1.0]: https://github.com/piotrmurach/verse/compare/v0.1.0
data/Gemfile CHANGED
@@ -2,5 +2,14 @@ source "https://rubygems.org"
2
2
 
3
3
  git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
- # Specify your gem's dependencies in strings.gemspec
6
5
  gemspec
6
+
7
+ group :metrics do
8
+ gem 'coveralls', '~> 0.8.1'
9
+ gem 'simplecov', '~> 0.10.0'
10
+ gem 'yardstick', '~> 0.9.9'
11
+ end
12
+
13
+ group :benchmarks do
14
+ gem 'benchmark-ips'
15
+ end
data/README.md CHANGED
@@ -1,7 +1,24 @@
1
+ <div align="center">
2
+ <img width="225" src="https://cdn.rawgit.com/piotrmurach/strings/master/assets/strings_logo.png" alt="strings logo" />
3
+ </div>
4
+
1
5
  # Strings
2
6
 
3
- > The `Strings` is a module to wrap, truncate, indent, and otherwise transform strings.
7
+ [![Gem Version](https://badge.fury.io/rb/strings.svg)][gem]
8
+ [![Build Status](https://secure.travis-ci.org/piotrmurach/strings.svg?branch=master)][travis]
9
+ [![Build status](https://ci.appveyor.com/api/projects/status/e11tn1fgjwnfwp3r?svg=true)][appveyor]
10
+ [![Maintainability](https://api.codeclimate.com/v1/badges/4ca50e480f42af80678e/maintainability)][codeclimate]
11
+ [![Coverage Status](https://coveralls.io/repos/github/piotrmurach/strings/badge.svg?branch=master)][coverage]
12
+ [![Inline docs](http://inch-ci.org/github/piotrmurach/strings.svg?branch=master)][inchpages]
13
+
14
+ [gem]: http://badge.fury.io/rb/strings
15
+ [travis]: http://travis-ci.org/piotrmurach/strings
16
+ [appveyor]: https://ci.appveyor.com/project/piotrmurach/strings
17
+ [codeclimate]: https://codeclimate.com/github/piotrmurach/strings/maintainability
18
+ [coverage]: https://coveralls.io/github/piotrmurach/strings?branch=master
19
+ [inchpages]: http://inch-ci.org/github/piotrmurach/strings
4
20
 
21
+ > The `Strings` is a set of useful functions such as fold, truncate, wrap, and many more for transforming strings.
5
22
 
6
23
  ## Installation
7
24
 
@@ -19,9 +36,317 @@ Or install it yourself as:
19
36
 
20
37
  $ gem install strings
21
38
 
22
- ## Usage
39
+ ## Features
40
+
41
+ * No monkey-patching String class
42
+ * Functional API that can be easily wrapped by other objects
43
+ * Supports multibyte character encodings such as UTF-8, EUC-JP
44
+ * Handles languages without whitespaces between words (like Chinese and Japanese)
45
+ * Supports ANSI escape codes
46
+
47
+ ## Contents
48
+
49
+ * [1. Usage](#1-usage)
50
+ * [2. API](#2-api)
51
+ * [2.1 align](#21-align)
52
+ * [2.2 ansi?](#22-ansi)
53
+ * [2.3 fold](#23-fold)
54
+ * [2.4 pad](#24-pad)
55
+ * [2.5 sanitize](#25-sanitize)
56
+ * [2.6 truncate](#26-truncate)
57
+ * [2.7 wrap](#27-wrap)
58
+ * [3. Extending String class](#3-extending-string-class)
59
+
60
+ ## 1. Usage
61
+
62
+ **Strings** is a module with stateless function calls which can be executed directly or mixed into other classes.
63
+
64
+ For example, to wrap a text using [wrap](#22-wrap) method, you can call it directly:
65
+
66
+ ```ruby
67
+ text = "Think not, is my eleventh commandment; and sleep when you can, is my twelfth."
68
+ Strings.wrap(text, 30)
69
+ # =>
70
+ # "Think not, is my eleventh\n"
71
+ # "commandment; and sleep when\n"
72
+ # "you can, is my twelfth."
73
+ ```
74
+
75
+ or using namespaced name:
76
+
77
+ ```ruby
78
+ Strings::Wrap.wrap(text, 30)
79
+ ```
80
+
81
+ ## 2. API
82
+
83
+ ### 2.1 align
84
+
85
+ To align a given multiline text within a given `width` use `align`, `align_left`, `align_center` or `align_right`.
86
+
87
+ Given the following text:
88
+
89
+ ```ruby
90
+ text = "for there is no folly of the beast\nof the earth which\nis not infinitely\noutdone by the madness of men"
91
+ ```
92
+
93
+ Passing `text` as first argument, the maximum width and `:direction` to align to:
94
+
95
+ ```ruby
96
+ String.align(text, 40, direction: :center)
97
+ # =>
98
+ # " for there is no folly of the beast "
99
+ # " of the earth which "
100
+ # " is not infinitely "
101
+ # " outdone by the madness of men "
102
+ ```
103
+
104
+ You can also pass `:fill` option to replace default space character:
105
+
106
+ ```ruby
107
+ Strings.align(text, 40, direction: :center, fill: '*')
108
+ # =>
109
+ # "***for there is no folly of the beast***"
110
+ # "***********of the earth which***********"
111
+ # "***********is not infinitely************"
112
+ # "*****outdone by the madness of men******"
113
+ ```
114
+
115
+ It handles `UTF-8` text:
116
+
117
+ ```ruby
118
+ text = "ラドクリフ\n、マラソン五輪\n代表に1万m出\n場にも含み"
119
+ Strings.align_left(text, 20)
120
+ # =>
121
+ # "ラドクリフ "
122
+ # "、マラソン五輪 "
123
+ # "代表に1万m出 "
124
+ # "場にも含み "
125
+ ```
126
+
127
+ ### 2.2 ansi?
128
+
129
+ To check if a string includes ANSI escape codes use `ansi?` like so:
130
+
131
+ ```ruby
132
+ Strings.ansi?("\e[33;44mfoo\e[0m")).to eq(true)
133
+ # => true
134
+ ```
135
+
136
+ or
137
+
138
+ ```ruby
139
+ Strings::ANSI.ansi?("\e[33;44mfoo\e[0m")
140
+ # => true
141
+ ```
142
+
143
+ ### 2.3 fold
144
+
145
+ To fold a multiline text into a single line preserving whitespace characters use `fold`:
146
+
147
+ ```ruby
148
+ Strings.fold("\tfoo \r\n\n bar")
149
+ # => "foo bar"
150
+ ```
151
+
152
+ ### 2.4 pad
153
+
154
+ To pad around a text with a given padding use `pad` function where the seconds argument is a padding value that needs to be one of the following values corresponding with CSS padding property:
155
+
156
+ ```ruby
157
+ [1,1,1,1] # => pad text left & right with 1 character and add 1 line above & below
158
+ [1,2] # => pad text left & right with 2 characters and add 1 line above & below
159
+ 1 # => shorthand for [1,1,1,1]
160
+ ```
161
+
162
+ For example, to pad sentence with a padding of 1 space:
163
+
164
+ ```ruby
165
+ text = "Ignorance is the parent of fear."
166
+ Strings.pad(text, 1)
167
+ # =>
168
+ # " \n"
169
+ # " Ignorance is the parent of fear. \n"
170
+ # " "
171
+ ```
172
+
173
+ You can also pass `:fill` option to replace default space character:
174
+
175
+ ```ruby
176
+ text = "Ignorance is the parent of fear."
177
+ Strings.pad(text, [1, 2], fill: "*")
178
+ # =>
179
+ # "************************************\n"
180
+ # "**Ignorance is the parent of fear.**\n"
181
+ # "************************************"
182
+ ```
183
+
184
+ You can also apply padding to multiline content:
185
+
186
+ ```ruby
187
+ text = <<-TEXT
188
+ It is the easiest thing
189
+ in the world for a man
190
+ to look as if he had
191
+ a great secret in him.
192
+ TEXT
193
+
194
+ Strings.pad(text, 1)
195
+ # =>
196
+ # " \n"
197
+ # " It is the easiest thing \n"
198
+ # " in the world for a man \n"
199
+ # " to look as if he had \n"
200
+ # " a great secret in him. \n"
201
+ # " "
202
+ ```
203
+
204
+ The `pad` handles `UTF-8` text as well:
205
+
206
+ ```ruby
207
+ text = "ラドクリフ、マラソン"
208
+ Strings.pad(text, 1)
209
+ # =>
210
+ # " \n"
211
+ # " ラドクリフ、マラソン \n"
212
+ # " "
213
+ ```
214
+
215
+ ### 2.5 sanitize
23
216
 
24
- TODO: Write usage instructions here
217
+ To remove ANSI escape codes from a string use `sanitize`:
218
+
219
+ ```ruby
220
+ Strings.sanitize("\e[33;44mfoo\e[0m")
221
+ # => "foo"
222
+ ```
223
+
224
+ or namespaced:
225
+
226
+ ```ruby
227
+ Strings::ANSI.sanitize("\e[33;44mfoo\e[0m")
228
+ # => "foo"
229
+ ```
230
+
231
+ ### 2.6 truncate
232
+
233
+ You can truncate a given text after a given length with `truncate` method.
234
+
235
+ Given the following text:
236
+
237
+ ```ruby
238
+ text = "for there is no folly of the beast of the earth " +
239
+ "which is not infinitely outdone by the madness of men"
240
+ ```
241
+
242
+ To shorten the text to given length call `truncate`:
243
+
244
+ ```ruby
245
+ Strings.truncate(text, 20) # => "for there is no fol…"
246
+ ```
247
+
248
+ or directly using the module namesapce:
249
+
250
+ ```ruby
251
+ Strings::Truncate.truncate(text, 20) # => "for there is no fol…"
252
+ ```
253
+
254
+ If you want to split words on their boundaries use `:separator` option:
255
+
256
+ ```ruby
257
+ Strings.truncate(text, 20) # => "for there is no…"
258
+ ```
259
+
260
+ Use `:trailing` option (by default `…`) to provide omission characters:
261
+
262
+ ```ruby
263
+ Strings.truncate(text, 22, trailing: '... (see more)')
264
+ # => "for there...(see more)"
265
+ ```
266
+
267
+ You can also specify `UTF-8` text as well:
268
+
269
+ ```ruby
270
+ text = 'ラドクリフ、マラソン五輪代表に1万m出場にも含み'
271
+ Strings.truncate(text, 12) # => "ラドクリフ…"
272
+ ```
273
+
274
+ **Strings::Truncate** works with ANSI escape codoes:
275
+
276
+ ```ruby
277
+ text = "I try \e[34mall things\e[0m, I achieve what I can"
278
+ Strings.truncate(text, 18)
279
+ # => "I try \e[34mall things\e[0m…"
280
+ ```
281
+
282
+ ### 2.7 wrap
283
+
284
+ To wrap text into lines no longer than `wrap_at` argument length, the `wrap` method will break either on whitespace character or in case of east Asian characters on character boundaries.
285
+
286
+ Given the following text:
287
+
288
+ ```ruby
289
+ text "Think not, is my eleventh commandment; and sleep when you can, is my twelfth."
290
+ ```
291
+
292
+ Then to wrap the text to given length do:
293
+
294
+ ```ruby
295
+ Strings.wrap(text, 30)
296
+ # =>
297
+ # "Think not, is my eleventh\n"
298
+ # "commandment; and sleep when\n"
299
+ # "you can, is my twelfth."
300
+ ```
301
+
302
+ Similarly, to handle `UTF-8` text do:
303
+
304
+ ```ruby
305
+ text = "ラドクリフ、マラソン五輪代表に1万m出場にも含み"
306
+ Strings.wrap(text, 8)
307
+ # =>
308
+ # "ラドクリ\n"
309
+ # "フ、マラ\n"
310
+ # "ソン五輪\n"
311
+ # "代表に1\n"
312
+ # "万m出場\n"
313
+ # "にも含み"
314
+ ```
315
+
316
+ **Strings::Wrap** knows how to handle ANSI codes:
317
+
318
+ ```ruby
319
+ ansi_text = "\e[32;44mIgnorance is the parent of fear.\e[0m"
320
+ Strings.wrap(ansi_text, 14)
321
+ # =>
322
+ # "\e[32;44mIgnorance is \e[0m\n"
323
+ # "\e[32;44mthe parent of \e[0m\n"
324
+ # "\e[32;44mfear.\e[0m"
325
+ ```
326
+
327
+ You can also call `wrap` directly on **Strings::Wrap**:
328
+
329
+ ```ruby
330
+ Strings::Wrap.wrap(text, wrap_at)
331
+ ```
332
+
333
+ ## 3. Extending String class
334
+
335
+ Though it is highly discouraged to polute core Ruby classes, you can add the required methods to `String` class like so:
336
+
337
+ ```ruby
338
+ class String
339
+ def wrap(*args)
340
+ Strings.wrap(self, *args)
341
+ end
342
+ end
343
+ ```
344
+
345
+ then `wrap` method will be available for all strings in your system:
346
+
347
+ ```ruby
348
+ string.wrap(30)
349
+ ```
25
350
 
26
351
  ## Development
27
352
 
@@ -31,7 +356,13 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
31
356
 
32
357
  ## Contributing
33
358
 
34
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/strings. 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.
359
+ Bug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/strings. 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.
360
+
361
+ 1. Fork it ( https://github.com/piotrmurach/verse/fork )
362
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
363
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
364
+ 4. Push to the branch (`git push origin my-new-feature`)
365
+ 5. Create a new Pull Request
35
366
 
36
367
  ## License
37
368
 
@@ -39,4 +370,8 @@ The gem is available as open source under the terms of the [MIT License](http://
39
370
 
40
371
  ## Code of Conduct
41
372
 
42
- Everyone interacting in the Strings project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/strings/blob/master/CODE_OF_CONDUCT.md).
373
+ Everyone interacting in the Strings project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/strings/blob/master/CODE_OF_CONDUCT.md).
374
+
375
+ ## Copyright
376
+
377
+ Copyright (c) 2017-2018 Piotr Murach. See LICENSE for further details.
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
2
 
4
- RSpec::Core::RakeTask.new(:spec)
3
+ FileList['tasks/**/*.rake'].each(&method(:import))
5
4
 
6
- task :default => :spec
5
+ desc 'Run all specs'
6
+ task ci: %w[ spec ]
7
+
8
+ task default: :spec