lovely-rufus 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md DELETED
@@ -1,70 +0,0 @@
1
- Lovely Rufus
2
- ============
3
-
4
- Lovely Rufus is an executable and a Ruby library for wrapping paragraphs of text in the spirit of [Par](http://www.nicemice.net/par/).
5
-
6
-
7
-
8
- usage
9
- -----
10
-
11
- Lovely Rufus can be used from the command-line by piping text through the `lovely-rufus` executable:
12
-
13
- $ echo 'The Ballyshannon foundered off the coast of Cariboo, And down in fathoms many went the captain and the crew;' | lovely-rufus
14
- The Ballyshannon foundered off the coast of Cariboo,
15
- And down in fathoms many went the captain and the crew;
16
- $
17
-
18
- Lovely Rufus can also be used from Ruby code through the `Wrapper` class:
19
-
20
- $ irb
21
- >> require 'lovely-rufus'
22
- >> text = 'The Ballyshannon foundered off the coast of Cariboo, And down in fathoms many went the captain and the crew;'
23
- >> puts LovelyRufus::Wrapper.new(text).wrapped
24
- The Ballyshannon foundered off the coast of Cariboo,
25
- And down in fathoms many went the captain and the crew;
26
- >>
27
-
28
- Note that `Wrapper#wrapped` can take optional desired width:
29
-
30
- $ irb
31
- >> require 'lovely-rufus'
32
- >> text = 'The Ballyshannon foundered off the coast of Cariboo, And down in fathoms many went the captain and the crew;'
33
- >> puts LovelyRufus::Wrapper.new(text).wrapped(15)
34
- The
35
- Ballyshannon
36
- foundered off
37
- the coast of
38
- Cariboo, And
39
- down in fathoms
40
- many went the
41
- captain and the
42
- crew;
43
- >>
44
-
45
-
46
-
47
- features
48
- --------
49
-
50
- Currently, Lovely Rufus sports the following features:
51
-
52
- * paragraphs are wrapped to the specified width,
53
- * one-letter words are not left at ends of lines,
54
- * email quotes (`>`) are handled properly and normalised (`> > >` → `>>>`),
55
- * email-quoted paragraph breaks are cleared,
56
- * code comments (starting with `#` and `//`) are handled properly,
57
- * multiple paragraphs are wrapped independently.
58
-
59
-
60
-
61
- name and history
62
- ----------------
63
-
64
- Lovely Rufus was created as a [Ruby Mendicant University](http://blog.majesticseacreature.com/tag/rubymendicant) project and is named after [a certain _Love Actually_ character](http://en.wikipedia.org/wiki/Love_Actually#Rufus) who’s [exceptionally good at wrapping](http://www.youtube.com/watch?v=W6E1wPwOaE4).
65
-
66
-
67
-
68
- ---
69
-
70
- © MMX-MMXIII Piotr Szotkowski <chastell@chastell.net>, licensed under AGPL 3 (see LICENCE)
data/Rakefile DELETED
@@ -1,18 +0,0 @@
1
- require 'rake/testtask'
2
- require 'reek/rake/task'
3
- require 'rubocop/rake_task'
4
-
5
- task default: %i[spec rubocop]
6
-
7
- Rake::TestTask.new :spec do |task|
8
- task.test_files = FileList['spec/**/*_spec.rb']
9
- task.warning = true
10
- end
11
-
12
- Reek::Rake::Task.new do |task|
13
- task.config_files = 'config/reek.yml'
14
- task.fail_on_error = false
15
- task.reek_opts = '--quiet'
16
- end
17
-
18
- Rubocop::RakeTask.new
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative '../lib/lovely-rufus'
4
- LovelyRufus::Executable.new.run
File without changes
@@ -1,5 +0,0 @@
1
- require 'delegate'
2
- require 'optparse'
3
-
4
- require_relative 'lovely-rufus/executable'
5
- require_relative 'lovely-rufus/wrapper'
@@ -1,25 +0,0 @@
1
- module LovelyRufus class Executable
2
- def initialize args = ARGV
3
- @settings = settings_from args
4
- end
5
-
6
- def run input = $stdin
7
- puts Wrapper.new(input.read).wrapped settings.width
8
- end
9
-
10
- attr_reader :settings
11
- private :settings
12
-
13
- private
14
-
15
- def settings_from args
16
- Struct.new(:width).new.tap do |settings|
17
- settings.width = 72
18
- OptionParser.new do |opts|
19
- opts.on '-w', '--width WIDTH', Integer, 'Wrapping width' do |width|
20
- settings.width = width
21
- end
22
- end.parse! args
23
- end
24
- end
25
- end end
@@ -1,93 +0,0 @@
1
- module LovelyRufus class Wrapper
2
- NBSP = ' '
3
-
4
- def initialize text
5
- @paras = text.split(%r{\n[/#> ]*\n}).map { |para| Para.new para.strip }
6
- end
7
-
8
- def wrapped max_width = 72
9
- return '' if paras.all?(&:empty?)
10
-
11
- paras.map do |para|
12
- para.wrap_recursively max_width
13
- end.join "\n\n"
14
- end
15
-
16
- attr_reader :paras
17
- private :paras
18
-
19
- private
20
-
21
- class Para
22
- def initialize text
23
- @text = text
24
- end
25
-
26
- def empty?
27
- text.empty?
28
- end
29
-
30
- def wrap_recursively max_width
31
- best = wrap_to_width max_width
32
- (max_width - 1).downto 1 do |width|
33
- shorter = wrap_to_width width
34
- break if shorter.lines.count > best.lines.count
35
- break if shorter.lines.map(&:size).max > best.lines.map(&:size).max
36
- best = shorter
37
- end
38
- best
39
- end
40
-
41
- def wrap_to_width width
42
- quotes = text[/^([\/#> ]*)/]
43
- leader = quotes.empty? ? '' : quotes.tr(' ', '') + ' '
44
- width -= leader.size if width > leader.size
45
- text.lines
46
- .map { |line| line[quotes.size..-1] }.join # drop quotes
47
- .tr("\n", ' ') # unwrap para
48
- .gsub(/ ([^ ]) /, " \\1#{NBSP}") # glue 1-letter words
49
- .gsub(/(.{1,#{width}})( |$\n?)/, "\\1\n") # wrap to width
50
- .tap { |par| remove_hangouts par, width } # handle hangouts
51
- .lines.map { |line| line.insert 0, leader }.join # re-insert leader
52
- .tr(NBSP, ' ') # drop glue spaces
53
- .chomp # final touch
54
- end
55
-
56
- attr_reader :text
57
- private :text
58
-
59
- private
60
-
61
- def find_hangout_line lines
62
- lines.find.with_index do |line, i|
63
- i < lines.size - 1 and
64
- space = hangout_last_space(line) and
65
- (hangout_to_previous_line i, lines, space or
66
- hangout_to_next_line i, lines, space)
67
- end
68
- end
69
-
70
- def hangout_last_space line
71
- line.rindex(/[ #{NBSP}]/)
72
- end
73
-
74
- def hangout_to_next_line i, lines, space
75
- (i < lines.size - 2 or lines.size == 2) and
76
- space + 1 >= lines[i + 1].size
77
- end
78
-
79
- def hangout_to_previous_line i, lines, space
80
- i > 0 and space + 1 >= lines[i - 1].size
81
- end
82
-
83
- def remove_hangouts para, width
84
- lines = para.split "\n"
85
- hangout_line = find_hangout_line lines
86
- if hangout_line
87
- hangout_line << NBSP
88
- fixed = self.class.new lines.join(' ').gsub "#{NBSP} ", NBSP
89
- para.replace fixed.wrap_to_width width
90
- end
91
- end
92
- end
93
- end end
@@ -1,14 +0,0 @@
1
- Gem::Specification.new do |gem|
2
- gem.name = 'lovely-rufus'
3
- gem.version = '0.0.4'
4
- gem.summary = 'lovely-rufus: text wrapper'
5
- gem.homepage = 'http://github.com/chastell/lovely-rufus'
6
- gem.author = 'Piotr Szotkowski'
7
- gem.email = 'chastell@chastell.net'
8
-
9
- gem.files = `git ls-files -z`.split "\0"
10
- gem.executables = gem.files.grep(%r{^bin/}).map { |path| File.basename path }
11
- gem.test_files = gem.files.grep %r{^spec/.*\.rb$}
12
-
13
- gem.add_dependency 'lovely_rufus'
14
- end
@@ -1,188 +0,0 @@
1
- # returns unwrapped input if it’s short enough
2
- - input: ‘Etiquette’ by Sir William Schwenck Gilbert
3
- output: ‘Etiquette’ by Sir William Schwenck Gilbert
4
-
5
- # wraps short input if requested to wrap it shorter (and avoids hangouts)
6
- - width: 16
7
- input: ‘Etiquette’ by Sir William Schwenck Gilbert
8
- output: |-
9
- ‘Etiquette’
10
- by Sir William
11
- Schwenck Gilbert
12
-
13
- # certain tricky hangout situations are catered for
14
- - input: |-
15
- dropping spaces, it-would-look-like this written-by-Sir-William-Schwenck-Gilbert
16
- output: |-
17
- dropping spaces, it-would-look-like this
18
- written-by-Sir-William-Schwenck-Gilbert
19
-
20
- # next-to-last hangouts are taken care of in two-line paragraphs
21
- - input: |-
22
- Well, the old ones go mmmmmbbbbzzzzttteeeeeep as they start up and
23
- the new ones go whupwhupwhupwhooopwhooooopwhooooooommmmmmmmmm.
24
- output: |-
25
- Well, the old ones go mmmmmbbbbzzzzttteeeeeep as they start up
26
- and the new ones go whupwhupwhupwhooopwhooooopwhooooooommmmmmmmmm.
27
-
28
- # unwrapping works with quoted text
29
- - input: |-
30
- > For some reason recently lovely-rufus
31
- > versions can’t wrap.
32
- output: |-
33
- > For some reason recently lovely-rufus versions can’t wrap.
34
-
35
- # wraps long input to 72 characters by default
36
- - input: The Ballyshannon foundered off the coast of Cariboo, And down in fathoms many went the captain and the crew;
37
- output: |-
38
- The Ballyshannon foundered off the coast of Cariboo,
39
- And down in fathoms many went the captain and the crew;
40
-
41
- # rewraps multiline paragraphs
42
- - input: |-
43
- Down went the owners — greedy men
44
- whom hope of gain allured:
45
- Oh, dry the starting tear,
46
- for they were heavily insured.
47
- output: |-
48
- Down went the owners — greedy men whom hope of gain allured:
49
- Oh, dry the starting tear, for they were heavily insured.
50
-
51
- # wrapped paragraphs are as short as possible
52
- - input: |-
53
- Besides the captain and the mate, the owners and the crew,
54
- The passengers were also drowned, excepting only two:
55
- Young PETER GRAY, who tasted teas for BAKER, CROOP, AND CO.,
56
- And SOMERS, who from Eastern shores imported indigo.
57
- output: |-
58
- Besides the captain and the mate, the owners and the crew,
59
- The passengers were also drowned, excepting only two: Young
60
- PETER GRAY, who tasted teas for BAKER, CROOP, AND CO., And
61
- SOMERS, who from Eastern shores imported indigo.
62
-
63
- # one-letter words are not left at line ends
64
- - width: 39
65
- input: |-
66
- These passengers, by reason of their clinging to a mast,
67
- Upon a desert island were eventually cast.
68
- They hunted for their meals, as ALEXANDER SELKIRK used,
69
- But they couldn’t chat together — they had not been introduced.
70
- output: |-
71
- These passengers, by reason of
72
- their clinging to a mast, Upon
73
- a desert island were eventually
74
- cast. They hunted for their meals,
75
- as ALEXANDER SELKIRK used, But they
76
- couldn’t chat together — they had
77
- not been introduced.
78
-
79
- # multiple paragraphs are wrapped independently
80
- - input: |-
81
- For PETER GRAY, and SOMERS too, though certainly in trade,
82
- Were properly particular about the friends they made;
83
- And somehow thus they settled it without a word of mouth —
84
- That GRAY should take the northern half while SOMERS took the south.
85
-
86
- On PETER’S portion oysters grew — a delicacy rare,
87
- But oysters were a delicacy PETER couldn’t bear.
88
- On SOMERS’ side was turtle, on the shingle lying thick,
89
- Which SOMERS couldn’t eat, because it always made him sick.
90
- output: |-
91
- For PETER GRAY, and SOMERS too, though certainly in trade, Were
92
- properly particular about the friends they made; And somehow
93
- thus they settled it without a word of mouth — That GRAY should
94
- take the northern half while SOMERS took the south.
95
-
96
- On PETER’S portion oysters grew — a delicacy rare, But
97
- oysters were a delicacy PETER couldn’t bear. On SOMERS’
98
- side was turtle, on the shingle lying thick, Which
99
- SOMERS couldn’t eat, because it always made him sick.
100
-
101
- # email-quoted paragraphs are wrapped regardless of quotes
102
- - input: |-
103
- > On PETER’S portion oysters grew — a delicacy rare,
104
- > But oysters were a delicacy PETER couldn’t bear.
105
- > On SOMERS’ side was turtle, on the shingle lying thick,
106
- > Which SOMERS couldn’t eat, because it always made him sick.
107
- output: |-
108
- > On PETER’S portion oysters grew — a delicacy rare, But
109
- > oysters were a delicacy PETER couldn’t bear. On SOMERS’
110
- > side was turtle, on the shingle lying thick, Which
111
- > SOMERS couldn’t eat, because it always made him sick.
112
-
113
- # email quotes can be of any depth
114
- - input: |-
115
- >> GRAY gnashed his teeth with envy as he saw a mighty store
116
- >> Of turtle unmolested on his fellow-creature’s shore:
117
- >> The oysters at his feet aside impatiently he shoved,
118
- >> For turtle and his mother were the only things he loved.
119
- output: |-
120
- >> GRAY gnashed his teeth with envy as he saw a mighty store
121
- >> Of turtle unmolested on his fellow-creature’s shore: The
122
- >> oysters at his feet aside impatiently he shoved, For turtle
123
- >> and his mother were the only things he loved.
124
-
125
- # email quotes are normalised upon wrapping
126
- - input: |-
127
- > > >And SOMERS sighed in sorrow as he settled in the south,
128
- > > >For the thought of PETER’S oysters brought the water to his mouth.
129
- > > >He longed to lay him down upon the shelly bed, and stuff:
130
- > > >He had often eaten oysters, but had never had enough.
131
- output: |-
132
- >>> And SOMERS sighed in sorrow as he settled in the south, For
133
- >>> the thought of PETER’S oysters brought the water to his mouth.
134
- >>> He longed to lay him down upon the shelly bed, and stuff: He
135
- >>> had often eaten oysters, but had never had enough.
136
-
137
- # quoted paragraph breaks are cleared
138
- - input: |-
139
- >> How they wished an introduction to each other they had had
140
- >> When on board The Ballyshannon! And it drove them nearly mad
141
- >> To think how very friendly with each other they might get,
142
- >> If it wasn’t for the arbitrary rule of etiquette!
143
- >
144
- > One day, when out a-hunting for the mus ridiculus,
145
- > GRAY overheard his fellow-man soliloquising thus:
146
- > ‘I wonder how the playmates of my youth are getting on,
147
- > MCCONNELL, S. B. WALTERS, PADDY BYLES, and ROBINSON?’
148
- output: |-
149
- >> How they wished an introduction to each other they had had
150
- >> When on board The Ballyshannon! And it drove them nearly
151
- >> mad To think how very friendly with each other they might
152
- >> get, If it wasn’t for the arbitrary rule of etiquette!
153
-
154
- > One day, when out a-hunting for the mus ridiculus, GRAY overheard his
155
- > fellow-man soliloquising thus: ‘I wonder how the playmates of my youth
156
- > are getting on, MCCONNELL, S. B. WALTERS, PADDY BYLES, and ROBINSON?’
157
-
158
- # code comments are handled like email-quoted text
159
- - input: |-
160
- // These simple words made PETER as delighted as could be,
161
- // Old chummies at the Charterhouse were ROBINSON and he!
162
- // He walked straight up to SOMERS, then he turned extremely red,
163
- // Hesitated, hummed and hawed a bit, then cleared his throat, and said:
164
- //
165
- # ‘I beg your pardon—pray forgive me if I seem too bold,
166
- # But you have breathed a name I knew familiarly of old.
167
- # You spoke aloud of ROBINSON – I happened to be by—
168
- # You know him?’ ‘Yes, extremely well.’ ‘Allow me – so do I!’
169
- #
170
- It was enough: they felt they could more sociably get on,
171
- For (ah, the magic of the fact!) they each knew ROBINSON!
172
- And MR. SOMERS’ turtle was at PETER’S service quite,
173
- And MR. SOMERS punished PETER’S oyster-beds all night.
174
- output: |-
175
- // These simple words made PETER as delighted as could be, Old
176
- // chummies at the Charterhouse were ROBINSON and he! He walked
177
- // straight up to SOMERS, then he turned extremely red, Hesitated,
178
- // hummed and hawed a bit, then cleared his throat, and said:
179
-
180
- # ‘I beg your pardon—pray forgive me if I seem too bold,
181
- # But you have breathed a name I knew familiarly of old.
182
- # You spoke aloud of ROBINSON – I happened to be by— You
183
- # know him?’ ‘Yes, extremely well.’ ‘Allow me – so do I!’
184
-
185
- It was enough: they felt they could more sociably get on,
186
- For (ah, the magic of the fact!) they each knew ROBINSON!
187
- And MR. SOMERS’ turtle was at PETER’S service quite, And
188
- MR. SOMERS punished PETER’S oyster-beds all night.
@@ -1,25 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- module LovelyRufus describe Executable do
4
- describe '#run' do
5
- it 'outputs passed text' do
6
- text = StringIO.new 'some text'
7
- -> { Executable.new.run text }.must_output "some text\n"
8
- end
9
-
10
- it 'wraps passed text to desired width' do
11
- text = StringIO.new 'some text'
12
- -> { Executable.new(%w[--width 4]).run text }.must_output "some\ntext\n"
13
- end
14
-
15
- it 'supports short arguments' do
16
- text = StringIO.new 'some text'
17
- -> { Executable.new(%w[-w4]).run text }.must_output "some\ntext\n"
18
- end
19
-
20
- it 'outputs properly wrapped input' do
21
- text = StringIO.new 'some more text'
22
- -> { Executable.new(%w[-w4]).run text }.must_output "some\nmore\ntext\n"
23
- end
24
- end
25
- end end