verse 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +68 -4
- data/lib/verse.rb +11 -0
- data/lib/verse/padder.rb +176 -0
- data/lib/verse/padding.rb +94 -0
- data/lib/verse/sanitizer.rb +22 -1
- data/lib/verse/version.rb +1 -1
- data/lib/verse/wrapping.rb +9 -9
- data/spec/unit/pad_spec.rb +14 -0
- data/spec/unit/padder/accessors_spec.rb +14 -0
- data/spec/unit/padder/parse_spec.rb +39 -0
- data/spec/unit/padding/pad_spec.rb +54 -0
- data/spec/unit/sanitizer/replace_spec.rb +31 -0
- data/spec/unit/wrapping/wrap_spec.rb +28 -24
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7531f5a29482d44a943c00b361f49e6673bdd9c7
|
4
|
+
data.tar.gz: 1bc1d1680d157e66faf7a44ba9c3ed0a804e7828
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5348385613bff73636e6b5993ebcafbba3ce1093a0b15e01c7c089248b61c09175c1793c0af5e8fdf482b2c149a0e9d6ea5b3d190c4246c689d5deba220b0d8a
|
7
|
+
data.tar.gz: f1605d77c8ffaf24695739ca4df6bb646834b0ccfd3c2b3a51641cd0a48ab1729fafb57a079bc08a86522ace2f3c419991f1ee44c9826fbbcb1a2ea7899ce4f7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.3.0 (Feb 28, 2015)
|
2
|
+
|
3
|
+
* Add Sanitizer#replace for substitutiong linebreaks
|
4
|
+
* Add Padder for parsing padding values
|
5
|
+
* Add Padding for padding content around
|
6
|
+
* Change Wrapping#wrap to preserve whitespace characters
|
7
|
+
|
1
8
|
0.2.1 (Feb 15, 2015)
|
2
9
|
|
3
10
|
* Fix empty string alignment
|
data/README.md
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
## Features
|
17
17
|
|
18
18
|
* No monkey-patching String class
|
19
|
+
* Simple API that can be easily wrapped by other objects
|
19
20
|
* Supports multibyte character encodings such as UTF-8, EUC-JP
|
20
21
|
* Handles languages without whitespaces between words (like Chinese and Japanese)
|
21
22
|
|
@@ -43,8 +44,10 @@ $ gem install verse
|
|
43
44
|
|
44
45
|
* [1. Usage](#1-usage)
|
45
46
|
* [1.1 Align](#11-align)
|
46
|
-
* [1.2
|
47
|
-
* [1.3
|
47
|
+
* [1.2 Pad](#12-pad)
|
48
|
+
* [1.3 Replace](#13-replace)
|
49
|
+
* [1.4 Truncate](#14-truncate)
|
50
|
+
* [1.5 Wrap](#15-wrap)
|
48
51
|
|
49
52
|
## 1 Usage
|
50
53
|
|
@@ -84,7 +87,68 @@ alignment.center(20) # =>
|
|
84
87
|
" 場にも含み "
|
85
88
|
```
|
86
89
|
|
87
|
-
### 1.2
|
90
|
+
### 1.2 Pad
|
91
|
+
|
92
|
+
**Verse::Padding** provides facility to pad around text with a given padding.
|
93
|
+
|
94
|
+
The padding value needs to be one of the following values corresponding with CSS padding property:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
[1,1,1,1] # => pad text left & right with 1 character and add 1 line above & below
|
98
|
+
[1,1] # => as above
|
99
|
+
1 # => as above
|
100
|
+
```
|
101
|
+
|
102
|
+
You can pad around a single line of text with `pad` method like so:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
padding = Verse::Padding.new("Ignorance is the parent of fear.")
|
106
|
+
|
107
|
+
padding.pad([1,1,1,1]) # =>
|
108
|
+
" \n" +
|
109
|
+
" Ignorance is the parent of fear. \n" +
|
110
|
+
" "
|
111
|
+
```
|
112
|
+
|
113
|
+
In addition, you can `pad` multiline content:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
padding = Verse::Padding.new "It is the easiest thing\n" +
|
117
|
+
"in the world for a man\n" +
|
118
|
+
"to look as if he had \n" +
|
119
|
+
"a great secret in him."
|
120
|
+
|
121
|
+
padding.pad([1,1,1,1]) # =>
|
122
|
+
" \n" +
|
123
|
+
" It is the easiest thing \n" +
|
124
|
+
" in the world for a man \n" +
|
125
|
+
" to look as if he had \n" +
|
126
|
+
" a great secret in him. \n" +
|
127
|
+
" "
|
128
|
+
```
|
129
|
+
|
130
|
+
You can also specify `UTF-8` text as well:
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
padding = Verse::Padding.new "ラドクリフ、マラソン"
|
134
|
+
|
135
|
+
padding.pad([1,1,1,1]) # =>
|
136
|
+
" \n" +
|
137
|
+
" ラドクリフ、マラソン \n" +
|
138
|
+
" "
|
139
|
+
```
|
140
|
+
|
141
|
+
### 1.3 Replace
|
142
|
+
|
143
|
+
**Verse::Sanitizer** provides ability to sanitize text with unwanted characters. Given a text with line break characters, `replace` will remove or substitute all occurances of line breaks depending on surrounding context.
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
sanitizer = Verse::Sanitizer.new
|
147
|
+
sanitizer.replace("It is not down on any map;\r\n true places never are.")
|
148
|
+
# => "It is not down on any map; true places never are."
|
149
|
+
```
|
150
|
+
|
151
|
+
### 1.4 Truncate
|
88
152
|
|
89
153
|
Using **Verse::Truncation** you can truncate a given text after a given length.
|
90
154
|
|
@@ -114,7 +178,7 @@ truncation = Verse::Truncation.new 'ラドクリフ、マラソン五輪代表
|
|
114
178
|
truncation.truncate(12) # => "ラドクリフ…"
|
115
179
|
```
|
116
180
|
|
117
|
-
### 1.
|
181
|
+
### 1.5 Wrap
|
118
182
|
|
119
183
|
**Verse::Wrapping** allows you 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.
|
120
184
|
|
data/lib/verse.rb
CHANGED
@@ -4,6 +4,8 @@ require 'unicode_utils/display_width'
|
|
4
4
|
require 'unicode_utils/each_grapheme'
|
5
5
|
|
6
6
|
require 'verse/alignment'
|
7
|
+
require 'verse/padder'
|
8
|
+
require 'verse/padding'
|
7
9
|
require 'verse/sanitizer'
|
8
10
|
require 'verse/truncation'
|
9
11
|
require 'verse/wrapping'
|
@@ -26,6 +28,15 @@ module Verse
|
|
26
28
|
Alignment.align(text, width, direction, options)
|
27
29
|
end
|
28
30
|
|
31
|
+
# Pad a text around with a given padding
|
32
|
+
#
|
33
|
+
# @see Verse::Padding#pad
|
34
|
+
#
|
35
|
+
# @api public
|
36
|
+
def self.pad(text, padding, options = {})
|
37
|
+
Padding.pad(text, padding, options)
|
38
|
+
end
|
39
|
+
|
29
40
|
# Truncate a text at a given length
|
30
41
|
#
|
31
42
|
# @see Verse::Truncation#truncate
|
data/lib/verse/padder.rb
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Verse
|
4
|
+
# A class responsible for parsing padding value
|
5
|
+
#
|
6
|
+
# Used internally by {Verse::Padding}
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Padder
|
10
|
+
# Padding
|
11
|
+
#
|
12
|
+
# @return [Array[Integer]]
|
13
|
+
attr_reader :padding
|
14
|
+
|
15
|
+
# Initialize a Padder
|
16
|
+
#
|
17
|
+
# @api public
|
18
|
+
def initialize(padding)
|
19
|
+
@padding = padding
|
20
|
+
end
|
21
|
+
|
22
|
+
# Parse padding options
|
23
|
+
#
|
24
|
+
# Turn possible values into 4 element array
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# padder = TTY::Table::Padder.parse(5)
|
28
|
+
# padder.padding # => [5, 5, 5, 5]
|
29
|
+
#
|
30
|
+
# @param [Object] value
|
31
|
+
#
|
32
|
+
# @return [TTY::Padder]
|
33
|
+
# the new padder with padding values
|
34
|
+
#
|
35
|
+
# @api public
|
36
|
+
def self.parse(value = nil)
|
37
|
+
return value if value.is_a?(self)
|
38
|
+
|
39
|
+
new(convert_to_ary(value))
|
40
|
+
end
|
41
|
+
|
42
|
+
# Convert value to 4 element array
|
43
|
+
#
|
44
|
+
# @return [Array[Integer]]
|
45
|
+
# the 4 element padding array
|
46
|
+
#
|
47
|
+
# @api private
|
48
|
+
def self.convert_to_ary(value)
|
49
|
+
if value.class <= Numeric
|
50
|
+
[value, value, value, value]
|
51
|
+
elsif value.nil?
|
52
|
+
[]
|
53
|
+
elsif value.size == 2
|
54
|
+
[value[0], value[1], value[0], value[1]]
|
55
|
+
elsif value.size == 4
|
56
|
+
value
|
57
|
+
else
|
58
|
+
fail ArgumentError, 'Wrong :padding parameter, must be an array'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Top padding
|
63
|
+
#
|
64
|
+
# @return [Integer]
|
65
|
+
#
|
66
|
+
# @api public
|
67
|
+
def top
|
68
|
+
@padding[0].to_i
|
69
|
+
end
|
70
|
+
|
71
|
+
# Set top padding
|
72
|
+
#
|
73
|
+
# @param [Integer] val
|
74
|
+
#
|
75
|
+
# @return [nil]
|
76
|
+
#
|
77
|
+
# @api public
|
78
|
+
def top=(value)
|
79
|
+
@padding[0] = value
|
80
|
+
end
|
81
|
+
|
82
|
+
# Right padding
|
83
|
+
#
|
84
|
+
# @return [Integer]
|
85
|
+
#
|
86
|
+
# @api public
|
87
|
+
def right
|
88
|
+
@padding[1].to_i
|
89
|
+
end
|
90
|
+
|
91
|
+
# Set right padding
|
92
|
+
#
|
93
|
+
# @param [Integer] val
|
94
|
+
#
|
95
|
+
# @api public
|
96
|
+
def right=(value)
|
97
|
+
@padding[1] = value
|
98
|
+
end
|
99
|
+
|
100
|
+
# Bottom padding
|
101
|
+
#
|
102
|
+
# @return [Integer]
|
103
|
+
#
|
104
|
+
# @api public
|
105
|
+
def bottom
|
106
|
+
@padding[2].to_i
|
107
|
+
end
|
108
|
+
|
109
|
+
# Set bottom padding
|
110
|
+
#
|
111
|
+
# @param [Integer] value
|
112
|
+
#
|
113
|
+
# @return [nil]
|
114
|
+
#
|
115
|
+
# @api public
|
116
|
+
def bottom=(value)
|
117
|
+
@padding[2] = value
|
118
|
+
end
|
119
|
+
|
120
|
+
# Left padding
|
121
|
+
#
|
122
|
+
# @return [Integer]
|
123
|
+
#
|
124
|
+
# @api public
|
125
|
+
def left
|
126
|
+
@padding[3].to_i
|
127
|
+
end
|
128
|
+
|
129
|
+
# Set left padding
|
130
|
+
#
|
131
|
+
# @param [Integer] value
|
132
|
+
#
|
133
|
+
# @return [nil]
|
134
|
+
#
|
135
|
+
# @api public
|
136
|
+
def left=(value)
|
137
|
+
@padding[3] = value
|
138
|
+
end
|
139
|
+
|
140
|
+
# Check if padding is set
|
141
|
+
#
|
142
|
+
# @return [Boolean]
|
143
|
+
#
|
144
|
+
# @api public
|
145
|
+
def empty?
|
146
|
+
padding.empty?
|
147
|
+
end
|
148
|
+
|
149
|
+
# Check if vertical padding is applied
|
150
|
+
#
|
151
|
+
# @return [Boolean]
|
152
|
+
#
|
153
|
+
# @api public
|
154
|
+
def vertical?
|
155
|
+
top.nonzero? || bottom.nonzero?
|
156
|
+
end
|
157
|
+
|
158
|
+
# Check if horizontal padding is applied
|
159
|
+
#
|
160
|
+
# @return [Boolean]
|
161
|
+
#
|
162
|
+
# @api public
|
163
|
+
def horizontal?
|
164
|
+
left.nonzero? || right.nonzero?
|
165
|
+
end
|
166
|
+
|
167
|
+
# String represenation of this padder with padding values
|
168
|
+
#
|
169
|
+
# @return [String]
|
170
|
+
#
|
171
|
+
# @api public
|
172
|
+
def to_s
|
173
|
+
inspect
|
174
|
+
end
|
175
|
+
end # Padder
|
176
|
+
end # Verse
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Verse
|
4
|
+
# A class responsible for text indentation
|
5
|
+
class Padding
|
6
|
+
# Initialize a Padding
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
def initialize(text, options = {})
|
10
|
+
@text = text
|
11
|
+
@padding = Padder.parse(options[:padding])
|
12
|
+
end
|
13
|
+
|
14
|
+
# Pad content out
|
15
|
+
#
|
16
|
+
# @see Verse::Padding#pad
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def self.pad(text, padding, options)
|
20
|
+
new(text, options).pad(padding, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Apply padding to text
|
24
|
+
#
|
25
|
+
# @param [String] text
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
def pad(padding = (not_set = true), options = {})
|
31
|
+
return text if @padding.empty? && not_set
|
32
|
+
if !not_set
|
33
|
+
@padding = Padder.parse(padding)
|
34
|
+
end
|
35
|
+
text_copy = text.dup
|
36
|
+
column_width = maximum_length(text)
|
37
|
+
elements = []
|
38
|
+
if @padding.top > 0
|
39
|
+
elements << (SPACE * column_width + NEWLINE) * @padding.top
|
40
|
+
end
|
41
|
+
elements << text_copy
|
42
|
+
if @padding.bottom > 0
|
43
|
+
elements << (SPACE * column_width + NEWLINE) * @padding.bottom
|
44
|
+
end
|
45
|
+
elements.map { |el| pad_multi_line(el) }.join(NEWLINE)
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
# The text to pad
|
51
|
+
#
|
52
|
+
# @api private
|
53
|
+
attr_reader :text
|
54
|
+
|
55
|
+
# Apply padding to multi line text
|
56
|
+
#
|
57
|
+
# @param [String] text
|
58
|
+
#
|
59
|
+
# @return [String]
|
60
|
+
#
|
61
|
+
# @api private
|
62
|
+
def pad_multi_line(text)
|
63
|
+
text.split(NEWLINE).map { |part| pad_around(part) }
|
64
|
+
end
|
65
|
+
|
66
|
+
# Apply padding to left and right side of string
|
67
|
+
#
|
68
|
+
# @param [String] text
|
69
|
+
#
|
70
|
+
# @return [String]
|
71
|
+
#
|
72
|
+
# @api private
|
73
|
+
def pad_around(text)
|
74
|
+
text.insert(0, SPACE * @padding.left).
|
75
|
+
insert(-1, SPACE * @padding.right)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Determine maximum length for all multiline content
|
79
|
+
#
|
80
|
+
# @params [String] text
|
81
|
+
#
|
82
|
+
# @return [Integer]
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
def maximum_length(text)
|
86
|
+
lines = text.split(/\n/, -1)
|
87
|
+
display_width(lines.max_by { |line| display_width(line) } || '')
|
88
|
+
end
|
89
|
+
|
90
|
+
def display_width(string)
|
91
|
+
UnicodeUtils.display_width(string)
|
92
|
+
end
|
93
|
+
end # Padding
|
94
|
+
end # Verse
|
data/lib/verse/sanitizer.rb
CHANGED
@@ -4,15 +4,36 @@ module Verse
|
|
4
4
|
class Sanitizer
|
5
5
|
ANSI_MATCHER = /(\[)?\033(\[)?[;?\d]*[\dA-Za-z](\])?/.freeze
|
6
6
|
|
7
|
+
LINE_BREAK = "(\r\n+|\r+|\n+|\t+)".freeze
|
8
|
+
|
7
9
|
# Strip ANSI characters from the text
|
8
10
|
#
|
9
11
|
# @param [String] text
|
10
12
|
#
|
11
13
|
# @return [String]
|
12
14
|
#
|
13
|
-
# @api
|
15
|
+
# @api public
|
14
16
|
def sanitize(text)
|
15
17
|
text.gsub(ANSI_MATCHER, '')
|
16
18
|
end
|
19
|
+
|
20
|
+
# Replace separator with whitespace
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# replace(" \n ") # => " "
|
24
|
+
# replace("\n") # => " "
|
25
|
+
#
|
26
|
+
# @param [String] text
|
27
|
+
#
|
28
|
+
# @param [String] separator
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def replace(text, separator = LINE_BREAK)
|
34
|
+
text.gsub(/([ ]+)#{separator}/, "\\1").
|
35
|
+
gsub(/#{separator}(?<space>[ ]+)/, "\\k<space>").
|
36
|
+
gsub(/#{separator}/, ' ')
|
37
|
+
end
|
17
38
|
end # Sanitizer
|
18
39
|
end # Verse
|
data/lib/verse/version.rb
CHANGED
data/lib/verse/wrapping.rb
CHANGED
@@ -60,7 +60,7 @@ module Verse
|
|
60
60
|
#
|
61
61
|
# @api private
|
62
62
|
def format_paragraph(paragraph, wrap_at)
|
63
|
-
cleared_para =
|
63
|
+
cleared_para = @sanitizer.replace(paragraph)
|
64
64
|
lines = []
|
65
65
|
line = ''
|
66
66
|
word = ''
|
@@ -73,7 +73,7 @@ module Verse
|
|
73
73
|
char_length = display_width(char)
|
74
74
|
total_length += char_length
|
75
75
|
if line_length + word_length + char_length <= wrap_at
|
76
|
-
if
|
76
|
+
if char == SPACE || total_length == text_length
|
77
77
|
line << word + char
|
78
78
|
line_length += word_length + char_length
|
79
79
|
word = ''
|
@@ -85,26 +85,26 @@ module Verse
|
|
85
85
|
next
|
86
86
|
end
|
87
87
|
|
88
|
-
if
|
89
|
-
lines << line
|
88
|
+
if char == SPACE # ends with space
|
89
|
+
lines << line
|
90
90
|
line = ''
|
91
91
|
line_length = 0
|
92
|
-
word =
|
93
|
-
word_length =
|
92
|
+
word = word + char
|
93
|
+
word_length = word_length + char_length
|
94
94
|
elsif word_length + char_length <= wrap_at
|
95
|
-
lines << line
|
95
|
+
lines << line
|
96
96
|
line = word + char
|
97
97
|
line_length = word_length + char_length
|
98
98
|
word = ''
|
99
99
|
word_length = 0
|
100
100
|
else # hyphenate word - too long to fit a line
|
101
|
-
lines << word
|
101
|
+
lines << word
|
102
102
|
line_length = 0
|
103
103
|
word = char
|
104
104
|
word_length = char_length
|
105
105
|
end
|
106
106
|
end
|
107
|
-
lines << line
|
107
|
+
lines << line unless line.empty?
|
108
108
|
lines << word unless word.empty?
|
109
109
|
lines
|
110
110
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse, '#pad' do
|
6
|
+
it "pads text" do
|
7
|
+
text = 'ラドクリフ、マラソン五輪代表に1万m出場にも含み'
|
8
|
+
expect(Verse.pad(text, [1,1,1,1])).to eql([
|
9
|
+
' ',
|
10
|
+
' ラドクリフ、マラソン五輪代表に1万m出場にも含み ',
|
11
|
+
' '
|
12
|
+
].join("\n"))
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Padder, 'accessors' do
|
6
|
+
subject(:padder) { described_class }
|
7
|
+
|
8
|
+
it "allows to set padding through accessors" do
|
9
|
+
instance = padder.parse([1,2,3,4])
|
10
|
+
instance.top = 5
|
11
|
+
expect(instance.padding).to eq([5,2,3,4])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Padder, '#parse' do
|
6
|
+
subject(:padder) { described_class }
|
7
|
+
|
8
|
+
it "parses nil" do
|
9
|
+
instance = padder.parse(nil)
|
10
|
+
expect(instance.padding).to eq([])
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'parses self' do
|
14
|
+
value = described_class.new([])
|
15
|
+
instance = padder.parse(value)
|
16
|
+
expect(instance.padding).to eq([])
|
17
|
+
end
|
18
|
+
|
19
|
+
it "parses digit" do
|
20
|
+
instance = padder.parse(5)
|
21
|
+
expect(instance.padding).to eq([5,5,5,5])
|
22
|
+
end
|
23
|
+
|
24
|
+
it "parses 2-element array" do
|
25
|
+
instance = padder.parse([2,3])
|
26
|
+
expect(instance.padding).to eq([2,3,2,3])
|
27
|
+
end
|
28
|
+
|
29
|
+
it "parses 4-element array" do
|
30
|
+
instance = padder.parse([1,2,3,4])
|
31
|
+
expect(instance.padding).to eq([1,2,3,4])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "fails to parse unknown value" do
|
35
|
+
expect {
|
36
|
+
padder.parse(:unknown)
|
37
|
+
}.to raise_error
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Padding, '.pad' do
|
6
|
+
it "doesn't pad without padding option" do
|
7
|
+
text = "Ignorance is the parent of fear."
|
8
|
+
padding = Verse::Padding.new(text)
|
9
|
+
expect(padding.pad).to eq(text)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "pads content with specific padding" do
|
13
|
+
text = "Ignorance is the parent of fear."
|
14
|
+
padding = Verse::Padding.new(text)
|
15
|
+
expect(padding.pad([1,1,1,1])).to eq([
|
16
|
+
" ",
|
17
|
+
" Ignorance is the parent of fear. ",
|
18
|
+
" ",
|
19
|
+
].join("\n"))
|
20
|
+
end
|
21
|
+
|
22
|
+
it "pads content with global padding" do
|
23
|
+
text = "Ignorance is the parent of fear."
|
24
|
+
padding = Verse::Padding.new(text, padding: [1,1,1,1])
|
25
|
+
expect(padding.pad).to eq([
|
26
|
+
" ",
|
27
|
+
" Ignorance is the parent of fear. ",
|
28
|
+
" ",
|
29
|
+
].join("\n"))
|
30
|
+
end
|
31
|
+
|
32
|
+
it "pads unicode content" do
|
33
|
+
text = "ラドクリフ、マラソン"
|
34
|
+
padding = Verse::Padding.new(text)
|
35
|
+
expect(padding.pad([1,1,1,1])).to eq([
|
36
|
+
" ",
|
37
|
+
" ラドクリフ、マラソン ",
|
38
|
+
" "
|
39
|
+
].join("\n"))
|
40
|
+
end
|
41
|
+
|
42
|
+
it "pads multiline content" do
|
43
|
+
text = "It is the easiest thing\nin the world for a man\nto look as if he had \na great secret in him."
|
44
|
+
padding = Verse::Padding.new(text, padding: [1,1,1,1])
|
45
|
+
expect(padding.pad()).to eq([
|
46
|
+
" ",
|
47
|
+
" It is the easiest thing ",
|
48
|
+
" in the world for a man ",
|
49
|
+
" to look as if he had ",
|
50
|
+
" a great secret in him. ",
|
51
|
+
" ",
|
52
|
+
].join("\n"))
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Verse::Sanitizer, '.replace' do
|
6
|
+
subject(:sanitizer) { described_class.new }
|
7
|
+
|
8
|
+
{
|
9
|
+
" \n" => ' ',
|
10
|
+
"\n " => ' ',
|
11
|
+
"\n" => ' ',
|
12
|
+
"\n\n\n" => ' ',
|
13
|
+
" \n " => ' ',
|
14
|
+
" \n \n \n" => ' '
|
15
|
+
}.each do |string, expected|
|
16
|
+
it "replaces '#{string.gsub(/\n/, '\\n')}' with whitespace" do
|
17
|
+
expect(sanitizer.replace(string)).to eq(expected)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
{
|
22
|
+
" \r\n" => ' ',
|
23
|
+
"\r\n " => ' ',
|
24
|
+
"\r\n" => ' ',
|
25
|
+
" \r\n " => ' ',
|
26
|
+
}.each do |string, expected|
|
27
|
+
it "replaces '#{string.gsub(/\r\n/, '\\r\\n')}' with whitespace" do
|
28
|
+
expect(sanitizer.replace(string, "\r\n")).to eq(expected)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -34,13 +34,13 @@ RSpec.describe Verse::Wrapping, '.wrap' do
|
|
34
34
|
text = "for there is no folly of the beast of the earth which is not infinitely outdone by the madness of men "
|
35
35
|
wrapping = Verse::Wrapping.new(text)
|
36
36
|
expect(wrapping.wrap(16)).to eq([
|
37
|
-
"for there is no",
|
38
|
-
"folly of the",
|
39
|
-
"beast of the",
|
40
|
-
"earth which is",
|
41
|
-
"not infinitely",
|
42
|
-
"outdone by the",
|
43
|
-
"madness of men"
|
37
|
+
"for there is no ",
|
38
|
+
"folly of the ",
|
39
|
+
"beast of the ",
|
40
|
+
"earth which is ",
|
41
|
+
"not infinitely ",
|
42
|
+
"outdone by the ",
|
43
|
+
"madness of men "
|
44
44
|
].join("\n"))
|
45
45
|
end
|
46
46
|
|
@@ -55,30 +55,34 @@ RSpec.describe Verse::Wrapping, '.wrap' do
|
|
55
55
|
"にも含み"
|
56
56
|
].join("\n"))
|
57
57
|
end
|
58
|
+
|
59
|
+
it 'preserves whitespace' do
|
60
|
+
# text = " As for me, I am tormented"
|
61
|
+
text = " As for me, I am tormented with an everlasting itch for things remote. "
|
62
|
+
wrapping = Verse::Wrapping.new(text)
|
63
|
+
expect(wrapping.wrap(10)).to eq([
|
64
|
+
" As for ",
|
65
|
+
"me, I ",
|
66
|
+
"am ",
|
67
|
+
"tormented ",
|
68
|
+
"with an ",
|
69
|
+
"e",
|
70
|
+
"verlasting",
|
71
|
+
" itch ",
|
72
|
+
"for ",
|
73
|
+
"things ",
|
74
|
+
"remote. "
|
75
|
+
].join("\n"))
|
76
|
+
end
|
58
77
|
end
|
59
78
|
|
60
79
|
context 'when long text' do
|
61
80
|
it "wraps long text at 45 characters" do
|
62
81
|
text =
|
63
|
-
"What of it, if some old hunks of a sea-captain orders me to get a broom
|
64
|
-
and sweep down the decks? What does that indignity amount to, weighed,
|
65
|
-
I mean, in the scales of the New Testament? Do you think the archangel
|
66
|
-
Gabriel thinks anything the less of me, because I promptly and
|
67
|
-
respectfully obey that old hunks in that particular instance? Who ain't
|
68
|
-
a slave? Tell me that. Well, then, however the old sea-captains may
|
69
|
-
order me about--however they may thump and punch me about, I have the
|
70
|
-
satisfaction of knowing that it is all right;
|
71
|
-
"
|
82
|
+
"What of it, if some old hunks of a sea-captain orders me to get a broom and sweep down the decks? What does that indignity amount to, weighed, I mean, in the scales of the New Testament? Do you think the archangel Gabriel thinks anything the less of me, because I promptly and respectfully obey that old hunks in that particular instance? Who ain't a slave? Tell me that. Well, then, however the old sea-captains may order me about--however they may thump and punch me about, I have the satisfaction of knowing that it is all right;"
|
72
83
|
wrapping = Verse::Wrapping.new(text)
|
73
84
|
expect(wrapping.wrap(45)).to eq unindent <<-EOS
|
74
|
-
What of it, if some old hunks of a\
|
75
|
-
and sweep down the decks? What does that\n indignity amount to, weighed,
|
76
|
-
I mean, in the scales of the New Testament?\n Do you think the archangel
|
77
|
-
Gabriel thinks anything the less of me,\n because I promptly and
|
78
|
-
respectfully obey that old hunks in that\nparticular instance? Who ain't
|
79
|
-
a slave? Tell me that. Well, then, however\n the old sea-captains may
|
80
|
-
order me about--however they may thump and\n punch me about, I have the
|
81
|
-
satisfaction of knowing that it is all right;\n
|
85
|
+
What of it, if some old hunks of a \nsea-captain orders me to get a broom and \n sweep down the decks? What does that \nindignity amount to, weighed, I mean, in the \n scales of the New Testament? Do you think \nthe archangel Gabriel thinks anything the \nless of me, because I promptly and \nrespectfully obey that old hunks in that \nparticular instance? Who ain't a slave? Tell \nme that. Well, then, however the old \nsea-captains may order me about--however \nthey may thump and punch me about, I have \nthe satisfaction of knowing that it is all \nright;
|
82
86
|
EOS
|
83
87
|
end
|
84
88
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: verse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: unicode_utils
|
@@ -57,6 +57,8 @@ files:
|
|
57
57
|
- Rakefile
|
58
58
|
- lib/verse.rb
|
59
59
|
- lib/verse/alignment.rb
|
60
|
+
- lib/verse/padder.rb
|
61
|
+
- lib/verse/padding.rb
|
60
62
|
- lib/verse/sanitizer.rb
|
61
63
|
- lib/verse/truncation.rb
|
62
64
|
- lib/verse/version.rb
|
@@ -66,6 +68,11 @@ files:
|
|
66
68
|
- spec/unit/alignment/align_spec.rb
|
67
69
|
- spec/unit/alignment/left_spec.rb
|
68
70
|
- spec/unit/alignment/right_spec.rb
|
71
|
+
- spec/unit/pad_spec.rb
|
72
|
+
- spec/unit/padder/accessors_spec.rb
|
73
|
+
- spec/unit/padder/parse_spec.rb
|
74
|
+
- spec/unit/padding/pad_spec.rb
|
75
|
+
- spec/unit/sanitizer/replace_spec.rb
|
69
76
|
- spec/unit/sanitizer/sanitize_spec.rb
|
70
77
|
- spec/unit/truncate_spec.rb
|
71
78
|
- spec/unit/truncation/new_spec.rb
|
@@ -107,6 +114,11 @@ test_files:
|
|
107
114
|
- spec/unit/alignment/align_spec.rb
|
108
115
|
- spec/unit/alignment/left_spec.rb
|
109
116
|
- spec/unit/alignment/right_spec.rb
|
117
|
+
- spec/unit/pad_spec.rb
|
118
|
+
- spec/unit/padder/accessors_spec.rb
|
119
|
+
- spec/unit/padder/parse_spec.rb
|
120
|
+
- spec/unit/padding/pad_spec.rb
|
121
|
+
- spec/unit/sanitizer/replace_spec.rb
|
110
122
|
- spec/unit/sanitizer/sanitize_spec.rb
|
111
123
|
- spec/unit/truncate_spec.rb
|
112
124
|
- spec/unit/truncation/new_spec.rb
|