verse 0.2.1 → 0.3.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 +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
|