verse 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/.gitignore +14 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +22 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +22 -0
- data/README.md +106 -0
- data/Rakefile +8 -0
- data/lib/verse.rb +31 -0
- data/lib/verse/alignment.rb +94 -0
- data/lib/verse/sanitizer.rb +18 -0
- data/lib/verse/truncation.rb +78 -0
- data/lib/verse/version.rb +5 -0
- data/lib/verse/wrapping.rb +123 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/unit/alignment/align_spec.rb +33 -0
- data/spec/unit/alignment/left_spec.rb +33 -0
- data/spec/unit/alignment/right_spec.rb +33 -0
- data/spec/unit/sanitizer/sanitize_spec.rb +23 -0
- data/spec/unit/truncate_spec.rb +10 -0
- data/spec/unit/truncation/new_spec.rb +28 -0
- data/spec/unit/truncation/truncate_spec.rb +63 -0
- data/spec/unit/wrap_spec.rb +10 -0
- data/spec/unit/wrapping/new_spec.rb +27 -0
- data/spec/unit/wrapping/wrap_spec.rb +88 -0
- data/tasks/console.rake +10 -0
- data/tasks/coverage.rake +11 -0
- data/tasks/spec.rake +29 -0
- data/verse.gemspec +22 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c1d878680201432d1d1d982be8af68dd04f63a8e
|
4
|
+
data.tar.gz: 4b2a2ff0056cf352051636ab8d974afafcf7a097
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 75e7dafdb2d0264ffa9457d1fae6a42159cb8a5650fa5ba87b75371fb1686ebae80c006541df13d83f7f1a753503c9749c2d64ab9f6df1760128e3ece77a8523
|
7
|
+
data.tar.gz: 86da8ab2fc5690ffb84795b8bf892e51b9d36289cfd054546885926946b8c819c739813dac99e9d86559e2eafbb640c22440b7ab31fa0742728a1dae47bd623f
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0
|
data/.travis.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
language: ruby
|
2
|
+
bundler_args: --without yard benchmarks
|
3
|
+
script: "bundle exec rake ci"
|
4
|
+
rvm:
|
5
|
+
- 1.9.3
|
6
|
+
- 2.0.0
|
7
|
+
- 2.1.0
|
8
|
+
- 2.2.0
|
9
|
+
- ruby-head
|
10
|
+
matrix:
|
11
|
+
include:
|
12
|
+
- rvm: jruby-19mode
|
13
|
+
- rvm: jruby-20mode
|
14
|
+
- rvm: jruby-21mode
|
15
|
+
- rvm: jruby-head
|
16
|
+
- rvm: rbx-2
|
17
|
+
allow_failures:
|
18
|
+
- rvm: ruby-head
|
19
|
+
- rvm: jruby-head
|
20
|
+
fast_finish: true
|
21
|
+
branches:
|
22
|
+
only: master
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
group :development do
|
6
|
+
gem 'rake', '~> 10.3.2'
|
7
|
+
gem 'rspec', '~> 3.1.0'
|
8
|
+
gem 'yard', '~> 0.8.7'
|
9
|
+
end
|
10
|
+
|
11
|
+
group :metrics do
|
12
|
+
gem 'coveralls', '~> 0.7.0'
|
13
|
+
gem 'simplecov', '~> 0.8.2'
|
14
|
+
gem 'yardstick', '~> 0.9.9'
|
15
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Piotr Murach
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# Verse
|
2
|
+
[][gem]
|
3
|
+
[][travis]
|
4
|
+
[][codeclimate]
|
5
|
+
[][coverage]
|
6
|
+
[][inchpages]
|
7
|
+
|
8
|
+
[gem]: http://badge.fury.io/rb/verse
|
9
|
+
[travis]: http://travis-ci.org/peter-murach/verse
|
10
|
+
[codeclimate]: https://codeclimate.com/github/peter-murach/verse
|
11
|
+
[coverage]: https://coveralls.io/r/peter-murach/verse
|
12
|
+
[inchpages]: http://inch-ci.org/github/peter-murach/verse
|
13
|
+
|
14
|
+
> Text transformations such as truncation, wrapping, aligning, indentation and grouping of words.
|
15
|
+
|
16
|
+
## Features
|
17
|
+
|
18
|
+
* No monkey-patching String class
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'verse'
|
26
|
+
```
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
```bash
|
31
|
+
$ bundle
|
32
|
+
```
|
33
|
+
|
34
|
+
Or install it yourself as:
|
35
|
+
|
36
|
+
```bash
|
37
|
+
$ gem install verse
|
38
|
+
```
|
39
|
+
|
40
|
+
## 1 Usage
|
41
|
+
|
42
|
+
### 1.1 align
|
43
|
+
|
44
|
+
**Verse** allows you to align text:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
alignment = Verse::Alignment.new "for there is no folly of the beast\n" +
|
48
|
+
" of the earth which\n" +
|
49
|
+
" is not infinitely\n" +
|
50
|
+
" outdone by the madness of men"
|
51
|
+
```
|
52
|
+
|
53
|
+
Then using `right`, `left` or `center` methods and passing width you can align the text:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
alignemnt.right(40) # =>
|
57
|
+
" for there is no folly of the beast\n" +
|
58
|
+
" of the earth which\n" +
|
59
|
+
" is not infinitely\n" +
|
60
|
+
" outdone by the madness of men"
|
61
|
+
```
|
62
|
+
|
63
|
+
### 1.2 truncate
|
64
|
+
|
65
|
+
Using **Verse** you can truncate a given text:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
truncation = Verse::Truncation.new "for there is no folly of the beast of the earth " +
|
69
|
+
"which is not infinitely outdone by the madness of men"
|
70
|
+
|
71
|
+
```
|
72
|
+
|
73
|
+
Then to shorten the text to given length call `truncate`:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
truncation.truncate(20) # => "for there is no fol…"
|
77
|
+
```
|
78
|
+
|
79
|
+
### 1.3 wrap
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
wrapping = Verse::Wrapping.new "Think not, is my eleventh commandment; " +
|
83
|
+
"and sleep when you can, is my twelfth."
|
84
|
+
|
85
|
+
```
|
86
|
+
|
87
|
+
Then to wrap the text to given length call `wrap`:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
wrapping.wrap(30)
|
91
|
+
# => "Think not, is my eleventh"
|
92
|
+
"commandment; and sleep when"
|
93
|
+
"you can, is my twelfth."
|
94
|
+
```
|
95
|
+
|
96
|
+
## Contributing
|
97
|
+
|
98
|
+
1. Fork it ( https://github.com/peter-murach/verse/fork )
|
99
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
100
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
101
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
102
|
+
5. Create a new Pull Request
|
103
|
+
|
104
|
+
## Copyright
|
105
|
+
|
106
|
+
Copyright (c) 2015 Piotr Murach. See LICENSE for further details.
|
data/Rakefile
ADDED
data/lib/verse.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'verse/alignment'
|
4
|
+
require 'verse/sanitizer'
|
5
|
+
require 'verse/truncation'
|
6
|
+
require 'verse/wrapping'
|
7
|
+
require 'verse/version'
|
8
|
+
|
9
|
+
module Verse
|
10
|
+
SPACE = ' '.freeze
|
11
|
+
NEWLINE = "\n".freeze
|
12
|
+
TAB = "\n".freeze
|
13
|
+
|
14
|
+
# Truncate a text at a given length
|
15
|
+
#
|
16
|
+
# @see Verse::Truncation#truncate
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def self.truncate(text, truncate_at, options = {})
|
20
|
+
Truncation.truncate(text, truncate_at, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Wrap a text into lines at wrap length
|
24
|
+
#
|
25
|
+
# @see Verse::Wrapping#wrap
|
26
|
+
#
|
27
|
+
# @api public
|
28
|
+
def self.wrap(text, wrap_at, options = {})
|
29
|
+
Wrapping.wrap(text, wrap_at, options = {})
|
30
|
+
end
|
31
|
+
end # Verse
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Verse
|
4
|
+
# A class responsible for text alignment
|
5
|
+
class Alignment
|
6
|
+
|
7
|
+
attr_reader :fill
|
8
|
+
|
9
|
+
attr_reader :direction
|
10
|
+
|
11
|
+
# Initialize an Alignment
|
12
|
+
#
|
13
|
+
# @api public
|
14
|
+
def initialize(text, options = {})
|
15
|
+
@text = text
|
16
|
+
@fill = options.fetch(:fill) { SPACE }
|
17
|
+
@direction = options.fetch(:direction) { :left }
|
18
|
+
end
|
19
|
+
|
20
|
+
# Aligns text to the left
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
def left(width, options = {})
|
26
|
+
align(width, :left, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Centers text within the width
|
30
|
+
#
|
31
|
+
# @return [String]
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
def center(width, options = {})
|
35
|
+
align(width, :center, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Aligns text to the right
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
# @api public
|
43
|
+
def right(width, options = {})
|
44
|
+
align(width, :right, options)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Aligns text within the width.
|
48
|
+
#
|
49
|
+
# If the text is greater than the width then unmodified
|
50
|
+
# string is returned.
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
# alignment = Verse::Alignment.new "the madness of men"
|
54
|
+
#
|
55
|
+
# alignment.align(22, :left)
|
56
|
+
# # => "the madness of men "
|
57
|
+
#
|
58
|
+
# alignment.align(22, :center)
|
59
|
+
# # => " the madness of men "
|
60
|
+
#
|
61
|
+
# alignment.align(22, :right)
|
62
|
+
# # => " the madness of men"
|
63
|
+
#
|
64
|
+
# @api public
|
65
|
+
def align(width, direction = :left, options = {})
|
66
|
+
filler = options.fetch(:fill) { fill }
|
67
|
+
method = convert_to_method(direction)
|
68
|
+
process_lines { |line| line.send(method, width, filler) }
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
# @api private
|
74
|
+
def convert_to_method(direction)
|
75
|
+
case direction
|
76
|
+
when :left then :ljust
|
77
|
+
when :right then :rjust
|
78
|
+
when :center then :center
|
79
|
+
else
|
80
|
+
fail ArgumentError, "Unknown alignment `#{direction}`."
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# @api private
|
85
|
+
def process_lines
|
86
|
+
lines = text.split(NEWLINE)
|
87
|
+
lines.reduce([]) do |aligned, line|
|
88
|
+
aligned << yield(line.strip)
|
89
|
+
end.join("\n")
|
90
|
+
end
|
91
|
+
|
92
|
+
attr_reader :text
|
93
|
+
end # Alignment
|
94
|
+
end # Verse
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Verse
|
4
|
+
class Sanitizer
|
5
|
+
ANSI_MATCHER = /(\[)?\033(\[)?[;?\d]*[\dA-Za-z](\])?/.freeze
|
6
|
+
|
7
|
+
# Strip ANSI characters from the text
|
8
|
+
#
|
9
|
+
# @param [String] text
|
10
|
+
#
|
11
|
+
# @return [String]
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
def sanitize(text)
|
15
|
+
text.gsub(ANSI_MATCHER, '')
|
16
|
+
end
|
17
|
+
end # Sanitizer
|
18
|
+
end # Verse
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Verse
|
4
|
+
# A class responsible for text truncation operations
|
5
|
+
class Truncation
|
6
|
+
DEFAULT_TRAILING = '…'.freeze
|
7
|
+
|
8
|
+
DEFAULT_LENGTH = 30.freeze
|
9
|
+
|
10
|
+
attr_reader :separator
|
11
|
+
|
12
|
+
attr_reader :trailing
|
13
|
+
|
14
|
+
# Initialize a Truncation
|
15
|
+
#
|
16
|
+
# @param [String] text
|
17
|
+
# the text to be truncated
|
18
|
+
#
|
19
|
+
# @param [Hash] options
|
20
|
+
# @option options [Symbol] :separator the character for splitting words
|
21
|
+
# @option options [Symbol] :trailing the character for ending sentence
|
22
|
+
#
|
23
|
+
# @api public
|
24
|
+
def initialize(text, options = {})
|
25
|
+
@text = text
|
26
|
+
@sanitizer = Sanitizer.new
|
27
|
+
@separator = options.fetch(:separator) { nil }
|
28
|
+
@trailing = options.fetch(:trailing) { DEFAULT_TRAILING }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Truncate a text at a given length
|
32
|
+
#
|
33
|
+
# @see Verse::Truncation#truncate
|
34
|
+
#
|
35
|
+
# @api public
|
36
|
+
def self.truncate(text, truncate_at, options = {})
|
37
|
+
new(text).truncate(truncate_at, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Truncate a text at a given length (defualts to 30)
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# truncation = Verse::Truncation.new
|
44
|
+
# "The sovereignest thing on earth is parmacetti for an inward bruise."
|
45
|
+
#
|
46
|
+
# truncation.truncate
|
47
|
+
# # => "The sovereignest thing on ear…"
|
48
|
+
#
|
49
|
+
# truncate(20)
|
50
|
+
# # => "The sovereignest th…"
|
51
|
+
#
|
52
|
+
# truncate(20, separator: ' ' )
|
53
|
+
# # => "The sovereignest…"
|
54
|
+
#
|
55
|
+
# truncate(40, trailing: '... (see more)' )
|
56
|
+
# # => "The sovereignest thing on... (see more)"
|
57
|
+
#
|
58
|
+
# @api public
|
59
|
+
def truncate(truncate_at = DEFAULT_LENGTH, options = {})
|
60
|
+
if text.length <= truncate_at.to_i || truncate_at.to_i.zero?
|
61
|
+
return text.dup
|
62
|
+
end
|
63
|
+
trail = options.fetch(:trailing) { trailing }
|
64
|
+
separation = options.fetch(:separator) { separator }
|
65
|
+
|
66
|
+
chars = @sanitizer.sanitize(text).chars.to_a
|
67
|
+
return chars.join if chars.length <= truncate_at
|
68
|
+
length_without_trailing = truncate_at - trail.chars.to_a.size
|
69
|
+
stop = chars[0, length_without_trailing].rindex(separation)
|
70
|
+
|
71
|
+
chars[0, stop || length_without_trailing].join + trail
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
attr_reader :text
|
77
|
+
end # Truncation
|
78
|
+
end # Verse
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Verse
|
4
|
+
# A class responsible for text wrapping
|
5
|
+
class Wrapping
|
6
|
+
DEFAULT_WIDTH = 80.freeze
|
7
|
+
|
8
|
+
attr_reader :indent
|
9
|
+
|
10
|
+
attr_reader :padding
|
11
|
+
|
12
|
+
# Initialize a Wrapping
|
13
|
+
#
|
14
|
+
# @param [String] text
|
15
|
+
# the text to be wrapped
|
16
|
+
#
|
17
|
+
# @param [Hash] options
|
18
|
+
# @option options [Symbol] :indent the indentation
|
19
|
+
# @option options [Symbol] :padding the desired spacing
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
def initialize(text, options = {})
|
23
|
+
@text = text
|
24
|
+
@indent = options.fetch(:indent) { 0 }
|
25
|
+
@padding = options.fetch(:padding) { [] }
|
26
|
+
@line_width = options.fetch(:line_width) { DEFAULT_WIDTH }
|
27
|
+
@sanitizer = Sanitizer.new
|
28
|
+
end
|
29
|
+
|
30
|
+
# Wrap a text into lines no longer than wrap_at
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def self.wrap(text, wrap_at, options = {})
|
34
|
+
new(text).wrap(wrap_at, options)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Wrap a text into lines no longer than wrap_at length.
|
38
|
+
# Preserves existing lines and existing word boundaries.
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# wrapping = Verse::Wrapping.new "Some longish text"
|
42
|
+
#
|
43
|
+
# wrapping.wrap(8)
|
44
|
+
# # => "Some\nlongish\ntext"
|
45
|
+
#
|
46
|
+
# wrapping.wrap(8, indent: 4)
|
47
|
+
# # => > Some
|
48
|
+
# > longish
|
49
|
+
# > text
|
50
|
+
#
|
51
|
+
# @api public
|
52
|
+
def wrap(wrap_at = DEFAULT_WIDTH, options = {})
|
53
|
+
if text.length < wrap_at.to_i || wrap_at.to_i.zero?
|
54
|
+
return text.dup
|
55
|
+
end
|
56
|
+
|
57
|
+
indentation = options.fetch(:indent) { indent }
|
58
|
+
spacing = options.fetch(:padding) { padding }
|
59
|
+
|
60
|
+
text.split(NEWLINE, -1).map do |line|
|
61
|
+
pad_line(indent_line(wrap_line(line, wrap_at), indentation), spacing)
|
62
|
+
end * NEWLINE
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Calculate string length without color escapes
|
68
|
+
#
|
69
|
+
# @param [String] string
|
70
|
+
#
|
71
|
+
# @api private
|
72
|
+
def actual_length(string, at)
|
73
|
+
at + (string.length - @sanitizer.sanitize(string).length)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Wrap line at given length
|
77
|
+
#
|
78
|
+
# @param [String] line
|
79
|
+
#
|
80
|
+
# @return [String]
|
81
|
+
#
|
82
|
+
# @api private
|
83
|
+
def wrap_line(line, at)
|
84
|
+
wrap_at = actual_length(line, at)
|
85
|
+
line.strip.gsub(/\n/, ' ').squeeze(' ')
|
86
|
+
.gsub(/(.{1,#{wrap_at}})(?:\s+|$\n?)|(.{1,#{wrap_at}})/, "\\1\\2\n")
|
87
|
+
.strip
|
88
|
+
end
|
89
|
+
|
90
|
+
# Indent string by given value
|
91
|
+
#
|
92
|
+
# @param [String] text
|
93
|
+
#
|
94
|
+
# @return [String]
|
95
|
+
#
|
96
|
+
# @api private
|
97
|
+
def indent_line(text, indent)
|
98
|
+
text.split(NEWLINE).each do |line|
|
99
|
+
line.insert(0, SPACE * indent)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Add padding to each line in wrapped text
|
104
|
+
#
|
105
|
+
# @param [String] text
|
106
|
+
# the wrapped text
|
107
|
+
#
|
108
|
+
# @return [String]
|
109
|
+
#
|
110
|
+
# @api private
|
111
|
+
def pad_line(text, padding)
|
112
|
+
return text if text.empty? || padding.empty?
|
113
|
+
|
114
|
+
padding_left = SPACE * padding[3].to_i
|
115
|
+
padding_right = SPACE * padding[1].to_i
|
116
|
+
text.map! do |part|
|
117
|
+
part.insert(0, padding_left).insert(-1, padding_right)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
attr_reader :text
|
122
|
+
end # Wrapping
|
123
|
+
end # Verse
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
if RUBY_VERSION > '1.9' and (ENV['COVERAGE'] || ENV['TRAVIS'])
|
4
|
+
require 'simplecov'
|
5
|
+
require 'coveralls'
|
6
|
+
|
7
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
8
|
+
SimpleCov::Formatter::HTMLFormatter,
|
9
|
+
Coveralls::SimpleCov::Formatter
|
10
|
+
]
|
11
|
+
|
12
|
+
SimpleCov.start do
|
13
|
+
command_name 'spec'
|
14
|
+
add_filter 'spec'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'verse'
|
19
|
+
|
20
|
+
RSpec.configure do |config|
|
21
|
+
config.expect_with :rspec do |expectations|
|
22
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
23
|
+
end
|
24
|
+
|
25
|
+
config.mock_with :rspec do |mocks|
|
26
|
+
mocks.verify_partial_doubles = true
|
27
|
+
end
|
28
|
+
|
29
|
+
# Limits the available syntax to the non-monkey patched syntax that is recommended.
|
30
|
+
config.disable_monkey_patching!
|
31
|
+
|
32
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
33
|
+
# be too noisy due to issues in dependencies.
|
34
|
+
config.warnings = true
|
35
|
+
|
36
|
+
if config.files_to_run.one?
|
37
|
+
config.default_formatter = 'doc'
|
38
|
+
end
|
39
|
+
|
40
|
+
config.profile_examples = 2
|
41
|
+
|
42
|
+
config.order = :random
|
43
|
+
|
44
|
+
Kernel.srand config.seed
|
45
|
+
end
|
46
|
+
|
47
|
+
def unindent(text)
|
48
|
+
text.gsub(/^[ \t]*/, '').chomp
|
49
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Alignment, '.align' do
|
6
|
+
it "centers line" do
|
7
|
+
text = "the madness of men"
|
8
|
+
alignment = Verse::Alignment.new(text)
|
9
|
+
expect(alignment.center(22)).to eq(" the madness of men ")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "centers multiline text" do
|
13
|
+
text = "for there is no folly of the beast\n of the earth which\n is not infinitely\n outdone by the madness of men"
|
14
|
+
alignment = Verse::Alignment.new(text)
|
15
|
+
expect(alignment.center(40)).to eq([
|
16
|
+
" for there is no folly of the beast \n",
|
17
|
+
" of the earth which \n",
|
18
|
+
" is not infinitely \n",
|
19
|
+
" outdone by the madness of men "
|
20
|
+
].join)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "centers multiline text with fill of '*'" do
|
24
|
+
text = "for there is no folly of the beast\n of the earth which\n is not infinitely\n outdone by the madness of men"
|
25
|
+
alignment = Verse::Alignment.new(text, fill: '*')
|
26
|
+
expect(alignment.center(40)).to eq([
|
27
|
+
"***for there is no folly of the beast***\n",
|
28
|
+
"***********of the earth which***********\n",
|
29
|
+
"***********is not infinitely************\n",
|
30
|
+
"*****outdone by the madness of men******"
|
31
|
+
].join)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Alignment, '.left' do
|
6
|
+
it "aligns line to left" do
|
7
|
+
text = "the madness of men"
|
8
|
+
alignment = Verse::Alignment.new(text)
|
9
|
+
expect(alignment.left(22)).to eq("the madness of men ")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "aligns multiline text to left" do
|
13
|
+
text = "for there is no folly of the beast\n of the earth which\n is not infinitely\n outdone by the madness of men"
|
14
|
+
alignment = Verse::Alignment.new(text)
|
15
|
+
expect(alignment.left(40)).to eq([
|
16
|
+
"for there is no folly of the beast \n",
|
17
|
+
"of the earth which \n",
|
18
|
+
"is not infinitely \n",
|
19
|
+
"outdone by the madness of men "
|
20
|
+
].join)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "centers multiline text with fill of '*'" do
|
24
|
+
text = "for there is no folly of the beast\n of the earth which\n is not infinitely\n outdone by the madness of men"
|
25
|
+
alignment = Verse::Alignment.new(text, fill: '*')
|
26
|
+
expect(alignment.left(40)).to eq([
|
27
|
+
"for there is no folly of the beast******\n",
|
28
|
+
"of the earth which**********************\n",
|
29
|
+
"is not infinitely***********************\n",
|
30
|
+
"outdone by the madness of men***********"
|
31
|
+
].join)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Alignment, '.right' do
|
6
|
+
it "aligns line to left" do
|
7
|
+
text = "the madness of men"
|
8
|
+
alignment = Verse::Alignment.new(text)
|
9
|
+
expect(alignment.right(22)).to eq(" the madness of men")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "aligns multiline text to left" do
|
13
|
+
text = "for there is no folly of the beast\n of the earth which\n is not infinitely\n outdone by the madness of men"
|
14
|
+
alignment = Verse::Alignment.new(text)
|
15
|
+
expect(alignment.right(40)).to eq([
|
16
|
+
" for there is no folly of the beast\n",
|
17
|
+
" of the earth which\n",
|
18
|
+
" is not infinitely\n",
|
19
|
+
" outdone by the madness of men"
|
20
|
+
].join)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "centers multiline text with fill of '*'" do
|
24
|
+
text = "for there is no folly of the beast\n of the earth which\n is not infinitely\n outdone by the madness of men"
|
25
|
+
alignment = Verse::Alignment.new(text, fill: '*')
|
26
|
+
expect(alignment.right(40)).to eq([
|
27
|
+
"******for there is no folly of the beast\n",
|
28
|
+
"**********************of the earth which\n",
|
29
|
+
"***********************is not infinitely\n",
|
30
|
+
"***********outdone by the madness of men"
|
31
|
+
].join)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Sanitizer, '.sanitize' do
|
6
|
+
subject(:sanitizer) { described_class.new }
|
7
|
+
|
8
|
+
{
|
9
|
+
"\e[20h" => '',
|
10
|
+
"\e[?1h" => '',
|
11
|
+
"\e[20l" => '',
|
12
|
+
"\e[?9l" => '',
|
13
|
+
"\eO" => '',
|
14
|
+
"\e[m" => '',
|
15
|
+
"\e[0m" => '',
|
16
|
+
"\eA" => '',
|
17
|
+
"\e[0;33;49;3;9;4m\e[0m" => ''
|
18
|
+
}.each do |code, expected|
|
19
|
+
it "strips #{code} from string" do
|
20
|
+
expect(sanitizer.sanitize(code)).to eq(expected)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Truncation, '#new' do
|
6
|
+
let(:text) { 'There go the ships; there is that Leviathan whom thou hast made to play therein.'}
|
7
|
+
|
8
|
+
it "defaults to no separator and unicode trailing" do
|
9
|
+
truncation = Verse::Truncation.new text
|
10
|
+
expect(truncation.separator).to eq(nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "defaults to unicode trailing" do
|
14
|
+
truncation = Verse::Truncation.new text
|
15
|
+
expect(truncation.trailing).to eq('…')
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
it "allows to setup global separator value" do
|
20
|
+
truncation = Verse::Truncation.new text, separator: ' '
|
21
|
+
expect(truncation.separator).to eq(' ')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "allows to setup global trailing value" do
|
25
|
+
truncation = Verse::Truncation.new text, trailing: '...'
|
26
|
+
expect(truncation.trailing).to eq('...')
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Truncation, '.truncate' do
|
6
|
+
let(:text) { 'ラドクリフ、マラソン五輪代表に1万m出場にも含み' }
|
7
|
+
|
8
|
+
it "doesn't change text for 0 length" do
|
9
|
+
truncation = Verse::Truncation.new(text)
|
10
|
+
expect(truncation.truncate(0)).to eq(text)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "doensn't change text for nil length" do
|
14
|
+
truncation = Verse::Truncation.new(text)
|
15
|
+
expect(truncation.truncate(nil)).to eq(text)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "doesn't change text for equal length" do
|
19
|
+
truncation = Verse::Truncation.new(text)
|
20
|
+
expect(truncation.truncate(text.length)).to eq(text)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'truncates text' do
|
24
|
+
truncation = Verse::Truncation.new(text)
|
25
|
+
trailing = '…'
|
26
|
+
expect(truncation.truncate(12)).to eq("ラドクリフ、マラソン五#{trailing}")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "doesn't truncate text when length exceeds content" do
|
30
|
+
truncation = Verse::Truncation.new(text)
|
31
|
+
expect(truncation.truncate(100)).to eq(text)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'truncates text with string separator' do
|
35
|
+
truncation = Verse::Truncation.new(text)
|
36
|
+
trailing = '…'
|
37
|
+
expect(truncation.truncate(12, separator: ' ')).to eq("ラドクリフ、マラソン五#{trailing}")
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'truncates text with regex separator' do
|
41
|
+
truncation = Verse::Truncation.new(text)
|
42
|
+
trailing = '…'
|
43
|
+
expect(truncation.truncate(12, separator: /\s/)).to eq("ラドクリフ、マラソン五#{trailing}")
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'truncates text with custom trailing' do
|
47
|
+
truncation = Verse::Truncation.new(text)
|
48
|
+
trailing = '... (see more)'
|
49
|
+
expect(truncation.truncate(20, trailing: trailing)).to eq("ラドクリフ、#{trailing}")
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'correctly truncates with ANSI characters' do
|
53
|
+
text = "This is a \e[1m\e[34mbold blue text\e[0m"
|
54
|
+
truncation = Verse::Truncation.new(text)
|
55
|
+
expect(truncation.truncate).to eq 'This is a bold blue text'
|
56
|
+
end
|
57
|
+
|
58
|
+
it "finishes on word boundary" do
|
59
|
+
text = "for there is no folly of the beast of the earth"
|
60
|
+
truncation = Verse::Truncation.new(text)
|
61
|
+
expect(truncation.truncate(20, separator: ' ')).to eq('for there is no…')
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Wrapping, '#new' do
|
6
|
+
let(:text) { "There go the ships; there is that Leviathan whom thou hast made to play therein."}
|
7
|
+
|
8
|
+
it "defaults indentation to 0" do
|
9
|
+
wrapping = Verse::Wrapping.new(text)
|
10
|
+
expect(wrapping.indent).to eq(0)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "defaults paddnig to empty array" do
|
14
|
+
wrapping = Verse::Wrapping.new(text)
|
15
|
+
expect(wrapping.padding).to eq([])
|
16
|
+
end
|
17
|
+
|
18
|
+
it "allows to set global indenation" do
|
19
|
+
wrapping = Verse::Wrapping.new(text, indent: 5)
|
20
|
+
expect(wrapping.indent).to eq(5)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "allows to set global padding" do
|
24
|
+
wrapping = Verse::Wrapping.new(text, padding: [1,2,3,4])
|
25
|
+
expect(wrapping.padding).to eq([1,2,3,4])
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Wrapping, '.wrap' do
|
6
|
+
context 'when unicode' do
|
7
|
+
let(:text) { 'ラドクリフ、マラソン五輪代表に1万m出場にも含み' }
|
8
|
+
|
9
|
+
it "doesn't wrap at zero length" do
|
10
|
+
wrapping = Verse::Wrapping.new(text)
|
11
|
+
expect(wrapping.wrap(0)).to eq(text)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "doesn't wrap at nil length" do
|
15
|
+
wrapping = Verse::Wrapping.new(text)
|
16
|
+
expect(wrapping.wrap(nil)).to eq(text)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'wraps at 8 characters' do
|
20
|
+
wrapping = Verse::Wrapping.new(text)
|
21
|
+
expect(wrapping.wrap(8)).to eq("ラドクリフ、マラ\nソン五輪代表に1\n万m出場にも含み")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "doesn't wrap at length exceeding content length" do
|
25
|
+
wrapping = Verse::Wrapping.new(text)
|
26
|
+
expect(wrapping.wrap(100)).to eq(text)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when long text' do
|
31
|
+
it "wraps long text at 45 characters" do
|
32
|
+
text =
|
33
|
+
"What of it, if some old hunks of a sea-captain orders me to get a broom
|
34
|
+
and sweep down the decks? What does that indignity amount to, weighed,
|
35
|
+
I mean, in the scales of the New Testament? Do you think the archangel
|
36
|
+
Gabriel thinks anything the less of me, because I promptly and
|
37
|
+
respectfully obey that old hunks in that particular instance? Who ain't
|
38
|
+
a slave? Tell me that. Well, then, however the old sea-captains may
|
39
|
+
order me about--however they may thump and punch me about, I have the
|
40
|
+
satisfaction of knowing that it is all right;
|
41
|
+
"
|
42
|
+
wrapping = Verse::Wrapping.new(text)
|
43
|
+
expect(wrapping.wrap(45)).to eq unindent <<-EOS
|
44
|
+
What of it, if some old hunks of a\n sea-captain orders me to get a broom
|
45
|
+
and sweep down the decks? What does that\n indignity amount to, weighed,
|
46
|
+
I mean, in the scales of the New Testament?\n Do you think the archangel
|
47
|
+
Gabriel thinks anything the less of me,\n because I promptly and
|
48
|
+
respectfully obey that old hunks in that\nparticular instance? Who ain't
|
49
|
+
a slave? Tell me that. Well, then, however\n the old sea-captains may
|
50
|
+
order me about--however they may thump and\n punch me about, I have the
|
51
|
+
satisfaction of knowing that it is all right;\n
|
52
|
+
EOS
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when indented' do
|
57
|
+
let(:length) { 8 }
|
58
|
+
let(:indent) { 4 }
|
59
|
+
|
60
|
+
it "wraps with indentation" do
|
61
|
+
text = 'ラドクリフ、マラソン五輪代表に1万m出場にも含み'
|
62
|
+
wrapping = Verse::Wrapping.new(text)
|
63
|
+
expect(wrapping.wrap(8, indent: 4)).to eq(" ラドクリフ、マラ\n ソン五輪代表に1\n 万m出場にも含み")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with ansi colors' do
|
68
|
+
it "wraps text with ANSII codes" do
|
69
|
+
text = "\[\033[01;32m\]Hey have\[\033[01;34m\]some cake\[\033[00m\]"
|
70
|
+
wrapping = Verse::Wrapping.new(text)
|
71
|
+
expect(wrapping.wrap(8)).to eq("\[\033[01;32m\]Hey have\[\033[01;34m\]some\ncake\[\033[00m\]")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with newlines' do
|
76
|
+
it "preserves newlines for both prefix and postfix" do
|
77
|
+
text = "\n\nラドクリフ、マラソン五輪代表に1万m出場にも含み\n\n\n"
|
78
|
+
wrapping = Verse::Wrapping.new(text)
|
79
|
+
expect(wrapping.wrap(10)).to eq("\n\nラドクリフ、マラソン\n五輪代表に1万m出場\nにも含み\n\n\n")
|
80
|
+
end
|
81
|
+
|
82
|
+
it "preserves newlines with padding" do
|
83
|
+
text = "\n\nラドクリフ、マラソン五輪代表に1万m出場にも含み\n\n"
|
84
|
+
wrapping = Verse::Wrapping.new(text)
|
85
|
+
expect(wrapping.wrap(10, padding: [1,2,3,4])).to eq("\n\n ラドクリフ、マラソン \n 五輪代表に1万m出場 \n にも含み \n\n")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/tasks/console.rake
ADDED
data/tasks/coverage.rake
ADDED
data/tasks/spec.rake
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
desc 'Run all specs'
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
8
|
+
task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace :spec do
|
12
|
+
desc 'Run unit specs'
|
13
|
+
RSpec::Core::RakeTask.new(:unit) do |task|
|
14
|
+
task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Run integration specs'
|
18
|
+
RSpec::Core::RakeTask.new(:integration) do |task|
|
19
|
+
task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
rescue LoadError
|
24
|
+
%w[spec spec:unit spec:integration].each do |name|
|
25
|
+
task name do
|
26
|
+
$stderr.puts "In order to run #{name}, do `gem install rspec`"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/verse.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'verse/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "verse"
|
8
|
+
spec.version = Verse::VERSION
|
9
|
+
spec.authors = ["Piotr Murach"]
|
10
|
+
spec.email = [""]
|
11
|
+
spec.summary = %q{}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(spec)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: verse
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Piotr Murach
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
description: ''
|
28
|
+
email:
|
29
|
+
- ''
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- .gitignore
|
35
|
+
- .rspec
|
36
|
+
- .ruby-version
|
37
|
+
- .travis.yml
|
38
|
+
- Gemfile
|
39
|
+
- LICENSE.txt
|
40
|
+
- README.md
|
41
|
+
- Rakefile
|
42
|
+
- lib/verse.rb
|
43
|
+
- lib/verse/alignment.rb
|
44
|
+
- lib/verse/sanitizer.rb
|
45
|
+
- lib/verse/truncation.rb
|
46
|
+
- lib/verse/version.rb
|
47
|
+
- lib/verse/wrapping.rb
|
48
|
+
- spec/spec_helper.rb
|
49
|
+
- spec/unit/alignment/align_spec.rb
|
50
|
+
- spec/unit/alignment/left_spec.rb
|
51
|
+
- spec/unit/alignment/right_spec.rb
|
52
|
+
- spec/unit/sanitizer/sanitize_spec.rb
|
53
|
+
- spec/unit/truncate_spec.rb
|
54
|
+
- spec/unit/truncation/new_spec.rb
|
55
|
+
- spec/unit/truncation/truncate_spec.rb
|
56
|
+
- spec/unit/wrap_spec.rb
|
57
|
+
- spec/unit/wrapping/new_spec.rb
|
58
|
+
- spec/unit/wrapping/wrap_spec.rb
|
59
|
+
- tasks/console.rake
|
60
|
+
- tasks/coverage.rake
|
61
|
+
- tasks/spec.rake
|
62
|
+
- verse.gemspec
|
63
|
+
homepage: ''
|
64
|
+
licenses:
|
65
|
+
- MIT
|
66
|
+
metadata: {}
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 2.0.3
|
84
|
+
signing_key:
|
85
|
+
specification_version: 4
|
86
|
+
summary: ''
|
87
|
+
test_files:
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
- spec/unit/alignment/align_spec.rb
|
90
|
+
- spec/unit/alignment/left_spec.rb
|
91
|
+
- spec/unit/alignment/right_spec.rb
|
92
|
+
- spec/unit/sanitizer/sanitize_spec.rb
|
93
|
+
- spec/unit/truncate_spec.rb
|
94
|
+
- spec/unit/truncation/new_spec.rb
|
95
|
+
- spec/unit/truncation/truncate_spec.rb
|
96
|
+
- spec/unit/wrap_spec.rb
|
97
|
+
- spec/unit/wrapping/new_spec.rb
|
98
|
+
- spec/unit/wrapping/wrap_spec.rb
|
99
|
+
has_rdoc:
|