word_wrapper 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Copyright © 2013 Stephen Pike. All Rights Reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
+
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+
7
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
10
+
11
+ THIS SOFTWARE IS PROVIDED BY [LICENSOR] "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,32 @@
1
+ Ruby word wrapping implementation
2
+ ============================================================
3
+
4
+ This is a pure ruby implementation of word wrapping. Currently supports the Greedy algorithm as well as Knuth's [Minimum Raggedness](http://en.wikipedia.org/wiki/Word_wrap#Knuth.27s_algorithm).
5
+
6
+ Install:
7
+
8
+ gem install word_wrapper
9
+
10
+ Usage:
11
+
12
+ require 'word_wrapper'
13
+
14
+ > text = "Before the law sits a gatekeeper. To this gatekeeper comes a man"
15
+
16
+ > puts WordWrapper::MinimumRaggedness.new(30, text).wrap
17
+
18
+ Before the law sits a
19
+ gatekeeper. To this
20
+ gatekeeper comes a man
21
+
22
+ > puts WordWrapper::Greedy.new(30, text).wrap
23
+
24
+ Before the law sits a
25
+ gatekeeper. To this gatekeeper
26
+ comes a man
27
+
28
+ Contributing:
29
+
30
+ You can run the tests if you have the Minitest gem installed with:
31
+
32
+ rake test
@@ -0,0 +1,6 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.pattern = 'test/**/*.rb'
6
+ end
@@ -0,0 +1,33 @@
1
+ class WordWrapper
2
+ class Greedy < WordWrapper
3
+ def wrap
4
+ words = @input.split
5
+ ans = ""
6
+ while words.any?
7
+ line = words.shift
8
+ while words.any? and (line.length + words[0].length) <= @width-1 # room for " "
9
+ line << " " << words.shift
10
+ end
11
+ ans << line << "\n"
12
+ end
13
+ @output = ans
14
+ end
15
+
16
+ def cost
17
+ compute_wrapping unless @cost
18
+ @cost
19
+ end
20
+
21
+ def compute_wrapping
22
+ @output = wrap
23
+ @cost = total_cost(@output)
24
+ end
25
+ end
26
+
27
+ if $0 == __FILE__ # run from cl
28
+ g = Greedy.new
29
+ g.compute_wrapping
30
+ puts g.output
31
+ puts "Greedy costs #{g.cost}"
32
+ end
33
+ end
@@ -0,0 +1,108 @@
1
+ class WordWrapper
2
+ class MinimumRaggedness < WordWrapper
3
+ attr_accessor :splits
4
+
5
+ # Return the c
6
+ # @param [Array<String]] words in the text
7
+ # @param [Integer] i left bound of words to check between
8
+ # @param [Integer] j right bound of words to check between
9
+ # @return [Integer] cost of a line containing the words from i to j
10
+ def cost_between(words, i, j)
11
+ @c ||= {}
12
+ @c[[i,j]] ||=
13
+ begin
14
+ # Special case for single words that are longer than @width.
15
+ # Mark their cost as 0 so they get their own line without
16
+ # messing up the algorithm
17
+ if j == i and words[j-1].length >= @width
18
+ cost = 0
19
+ else
20
+ cost = @width -
21
+ ((j - i) * OneSpaceWidth ) -
22
+ words[i-1..j-1].inject(0){ |acc, w| acc + w.length } # 0 indexed
23
+ cost = cost >= 0 ? cost**2 : Infinity
24
+ end
25
+ end
26
+ end
27
+
28
+ # Use dynamic programming to computer the optimal cost of this text.
29
+ # Recursively calls itself, keeping track of costs found as well as the
30
+ # array of splits required to give that cost (so we can actually generate
31
+ # the optimal text at the end).
32
+ #
33
+ # @param [Array<String>] words to split
34
+ # @param [Intger] j index to compute cost up through, goes from 1..length of words as we
35
+ # recursively compute costs.
36
+ #
37
+ # The evaluation looks like this (o is shorthand for optimal_cost):
38
+ #
39
+ # -- o(1, j) if c(1,j) < Inf
40
+ # o(j) = -
41
+ # -- min[ 1 <= k < j ] ( o(k) + c(k+1, j) ) if c(1,j) == Inf
42
+ #
43
+ # @return [Array<Integer, Array<String>>] (cost, [chain of splits that gives cost])
44
+ def optimal_cost(words, j)
45
+ @o ||= {}
46
+ @o[j] ||=
47
+ begin
48
+ ks = []
49
+ cost = cost_between words, 1, j
50
+ if cost == Infinity and j > 1
51
+ ks = (1..j-1)
52
+ candidates = {}
53
+ ks.collect do |k|
54
+ o = optimal_cost words, k
55
+ c = cost_between words, k + 1, j
56
+ # store both the chain of the child call and k
57
+ candidates[c + o[0]] = [o[1], k]
58
+ end
59
+ if candidates.any?
60
+ cost = candidates.keys.min
61
+ # ks is the chain of splits for this line of recursion
62
+ ks = candidates[cost][0] + [candidates[cost][1]]
63
+ end
64
+ end
65
+ # cost of this line, chain of splits that result in this cost
66
+ [cost,ks]
67
+ end
68
+ end
69
+
70
+ def cost
71
+ compute_wrapping unless @cost
72
+ @cost
73
+ end
74
+
75
+ def wrap
76
+ compute_wrapping unless @splits
77
+ prev = 0
78
+ ans = ""
79
+ @splits.each do |s|
80
+ ans << @words[prev..s-1].join(" ") << "\n"
81
+ prev = s
82
+ end
83
+ ans << @words[prev..@words.length].join(" ") << "\n"
84
+ ans
85
+ end
86
+
87
+ def compute_wrapping
88
+ @words = @input.split
89
+ @cost, @splits = optimal_cost(@words.dup, @words.length)
90
+ end
91
+
92
+ def solution?
93
+ cost != Infinity
94
+ end
95
+ end
96
+
97
+ if $0 == __FILE__ # from cl
98
+ m = MinimumRaggedness.new
99
+ m.compute_wrapping
100
+ if m.solution?
101
+ puts m.wrap
102
+ puts "Minimum Raggedness costs #{m.cost}"
103
+ else
104
+ puts "Couldn't wrap the input to #{m.width} characters"
105
+ puts "Possible issues: #{m.illegal_words.join(', ')}"
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,44 @@
1
+ # Implementation of word wrappign in Ruby. See README for usage.
2
+ class WordWrapper
3
+ OneSpaceWidth = 1
4
+ Infinity = 1/0.0
5
+ Width = 100
6
+
7
+ attr_accessor :width, :words, :output, :cost
8
+ def initialize(width = Width, text = nil)
9
+ @width = width
10
+ if text
11
+ @input = text
12
+ elsif ARGV[0]
13
+ begin
14
+ @input = File.read(ARGV[0])
15
+ rescue Errno::ENOENT => e
16
+ @input = ARGV[0]
17
+ end
18
+ else
19
+ raise "You need to supply an input string or file"
20
+ end
21
+ end
22
+
23
+ # Calculate the cost of a line. Cost is defined as
24
+ # [ Trailing whitespace ] ^ 2
25
+ # @param [String] line to compute cost for
26
+ def line_cost(line)
27
+ (@width - line.strip.length)**2 # no lines will ever start with whitespace
28
+ end
29
+
30
+ # The total cost of a block of text
31
+ # @param [String] text
32
+ def total_cost(text)
33
+ text.split("\n").inject(0){ |acc, line| acc + line_cost(line) }
34
+ end
35
+
36
+ # Any words in the text longer than the width of the output
37
+ # @return [Array<String>] illegal words
38
+ def illegal_words
39
+ @words.select{ |word| word.length > @width }
40
+ end
41
+ end
42
+
43
+ require "minimum_raggedness"
44
+ require "greedy"
@@ -0,0 +1 @@
1
+ Before the law sits a gatekeeper. To this gatekeeper comes a man from the country who asks to gain entry into the law. But the gatekeeper says that he cannot grant him entry at the moment. The man thinks about it and then asks if he will be allowed to come in sometime later on. “It is possible,” says the gatekeeper, “but not now.” The gate to the law stands open, as always, and the gatekeeper walks to the side, so the man bends over in order to see through the gate into the inside. When the gatekeeper notices that, he laughs and says: “If it tempts you so much, try going inside in spite of my prohibition. But take note. I am powerful. And I am only the most lowly gatekeeper. But from room to room stand gatekeepers, each more powerful than the other. I cannot endure even one glimpse of the third.” The man from the country has not expected such difficulties: the law should always be accessible for everyone, he thinks, but as he now looks more closely at the gatekeeper in his fur coat, at his large pointed nose and his long, thin, black Tartar’s beard, he decides that it would be better to wait until he gets permission to go inside. The gatekeeper gives him a stool and allows him to sit down at the side in front of the gate. There he sits for days and years. He makes many attempts to be let in, and he wears the gatekeeper out with his requests. The gatekeeper often interrogates him briefly, questioning him about his homeland and many other things, but they are indifferent questions, the kind great men put, and at the end he always tells him once more that he cannot let him inside yet. The man, who has equipped himself with many things for his journey, spends everything, no matter how valuable, to win over the gatekeeper. The latter takes it all but, as he does so, says, “I am taking this only so that you do not think you have failed to do anything.” During the many years the man observes the gatekeeper almost continuously. He forgets the other gatekeepers, and this first one seems to him the only obstacle for entry into the law. He curses the unlucky circumstance, in the first years thoughtlessly and out loud; later, as he grows old, he only mumbles to himself. He becomes childish and, since in the long years studying the gatekeeper he has also come to know the fleas in his fur collar, he even asks the fleas to help him persuade the gatekeeper. Finally his eyesight grows weak, and he does not know whether things are really darker around him or whether his eyes are merely deceiving him. But he recognizes now in the darkness an illumination which breaks inextinguishably out of the gateway to the law. Now he no longer has much time to live. Before his death he gathers in his head all his experiences of the entire time up into one question which he has not yet put to the gatekeeper. He waves to him, since he can no longer lift up his stiffening body. The gatekeeper has to bend way down to him, for the great difference has changed things considerably to the disadvantage of the man. “What do you still want to know now?” asks the gatekeeper. “You are insatiable.” “Everyone strives after the law,” says the man, “so how is it that in these many years no one except me has requested entry?” The gatekeeper sees that the man is already dying and, in order to reach his diminishing sense of hearing, he shouts at him, “Here no one else can gain entry, since this entrance was assigned only to you. I’m going now to close it.”
@@ -0,0 +1,3 @@
1
+ Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal.
2
+ Now we are engaged in a great civil war, testing whether that nation, or any nation, so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.
3
+ But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us—that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion—that we here highly resolve that these dead shall not have died in vain—that this nation, under God, shall have a new birth of freedom—and that government of the people, by the people, for the people, shall not perish from the earth.
@@ -0,0 +1 @@
1
+ Four score and seven years ago our fathers brought forth upon this continent a new nation, conceived in liberty and dedicated to the proposition that all men are created equal
@@ -0,0 +1 @@
1
+ Four score and seven years ago our fathers brought forth upon this continent a new nation
@@ -0,0 +1,119 @@
1
+ CHAPTER I
2
+
3
+ TREATS OF THE PLACE WHERE OLIVER TWIST WAS BORN AND OF THE
4
+ CIRCUMSTANCES ATTENDING HIS BIRTH
5
+
6
+ Among other public buildings in a certain town, which for many reasons
7
+ it will be prudent to refrain from mentioning, and to which I will
8
+ assign no fictitious name, there is one anciently common to most towns,
9
+ great or small: to wit, a workhouse; and in this workhouse was born; on
10
+ a day and date which I need not trouble myself to repeat, inasmuch as
11
+ it can be of no possible consequence to the reader, in this stage of
12
+ the business at all events; the item of mortality whose name is
13
+ prefixed to the head of this chapter.
14
+
15
+ For a long time after it was ushered into this world of sorrow and
16
+ trouble, by the parish surgeon, it remained a matter of considerable
17
+ doubt whether the child would survive to bear any name at all; in which
18
+ case it is somewhat more than probable that these memoirs would never
19
+ have appeared; or, if they had, that being comprised within a couple of
20
+ pages, they would have possessed the inestimable merit of being the
21
+ most concise and faithful specimen of biography, extant in the
22
+ literature of any age or country.
23
+
24
+ Although I am not disposed to maintain that the being born in a
25
+ workhouse, is in itself the most fortunate and enviable circumstance
26
+ that can possibly befall a human being, I do mean to say that in this
27
+ particular instance, it was the best thing for Oliver Twist that could
28
+ by possibility have occurred. The fact is, that there was considerable
29
+ difficulty in inducing Oliver to take upon himself the office of
30
+ respiration,--a troublesome practice, but one which custom has rendered
31
+ necessary to our easy existence; and for some time he lay gasping on a
32
+ little flock mattress, rather unequally poised between this world and
33
+ the next: the balance being decidedly in favour of the latter. Now,
34
+ if, during this brief period, Oliver had been surrounded by careful
35
+ grandmothers, anxious aunts, experienced nurses, and doctors of
36
+ profound wisdom, he would most inevitably and indubitably have been
37
+ killed in no time. There being nobody by, however, but a pauper old
38
+ woman, who was rendered rather misty by an unwonted allowance of beer;
39
+ and a parish surgeon who did such matters by contract; Oliver and
40
+ Nature fought out the point between them. The result was, that, after
41
+ a few struggles, Oliver breathed, sneezed, and proceeded to advertise
42
+ to the inmates of the workhouse the fact of a new burden having been
43
+ imposed upon the parish, by setting up as loud a cry as could
44
+ reasonably have been expected from a male infant who had not been
45
+ possessed of that very useful appendage, a voice, for a much longer
46
+ space of time than three minutes and a quarter.
47
+
48
+ As Oliver gave this first proof of the free and proper action of his
49
+ lungs, the patchwork coverlet which was carelessly flung over the iron
50
+ bedstead, rustled; the pale face of a young woman was raised feebly
51
+ from the pillow; and a faint voice imperfectly articulated the words,
52
+ 'Let me see the child, and die.'
53
+
54
+ The surgeon had been sitting with his face turned towards the fire:
55
+ giving the palms of his hands a warm and a rub alternately. As the
56
+ young woman spoke, he rose, and advancing to the bed's head, said, with
57
+ more kindness than might have been expected of him:
58
+
59
+ 'Oh, you must not talk about dying yet.'
60
+
61
+ 'Lor bless her dear heart, no!' interposed the nurse, hastily
62
+ depositing in her pocket a green glass bottle, the contents of which
63
+ she had been tasting in a corner with evident satisfaction.
64
+
65
+ 'Lor bless her dear heart, when she has lived as long as I have, sir,
66
+ and had thirteen children of her own, and all on 'em dead except two,
67
+ and them in the wurkus with me, she'll know better than to take on in
68
+ that way, bless her dear heart! Think what it is to be a mother,
69
+ there's a dear young lamb do.'
70
+
71
+ Apparently this consolatory perspective of a mother's prospects failed
72
+ in producing its due effect. The patient shook her head, and stretched
73
+ out her hand towards the child.
74
+
75
+ The surgeon deposited it in her arms. She imprinted her cold white
76
+ lips passionately on its forehead; passed her hands over her face;
77
+ gazed wildly round; shuddered; fell back--and died. They chafed her
78
+ breast, hands, and temples; but the blood had stopped forever. They
79
+ talked of hope and comfort. They had been strangers too long.
80
+
81
+ 'It's all over, Mrs. Thingummy!' said the surgeon at last.
82
+
83
+ 'Ah, poor dear, so it is!' said the nurse, picking up the cork of the
84
+ green bottle, which had fallen out on the pillow, as she stooped to
85
+ take up the child. 'Poor dear!'
86
+
87
+ 'You needn't mind sending up to me, if the child cries, nurse,' said
88
+ the surgeon, putting on his gloves with great deliberation. 'It's very
89
+ likely it _will_ be troublesome. Give it a little gruel if it is.' He
90
+ put on his hat, and, pausing by the bed-side on his way to the door,
91
+ added, 'She was a good-looking girl, too; where did she come from?'
92
+
93
+ 'She was brought here last night,' replied the old woman, 'by the
94
+ overseer's order. She was found lying in the street. She had walked
95
+ some distance, for her shoes were worn to pieces; but where she came
96
+ from, or where she was going to, nobody knows.'
97
+
98
+ The surgeon leaned over the body, and raised the left hand. 'The old
99
+ story,' he said, shaking his head: 'no wedding-ring, I see. Ah!
100
+ Good-night!'
101
+
102
+ The medical gentleman walked away to dinner; and the nurse, having once
103
+ more applied herself to the green bottle, sat down on a low chair
104
+ before the fire, and proceeded to dress the infant.
105
+
106
+ What an excellent example of the power of dress, young Oliver Twist
107
+ was! Wrapped in the blanket which had hitherto formed his only
108
+ covering, he might have been the child of a nobleman or a beggar; it
109
+ would have been hard for the haughtiest stranger to have assigned him
110
+ his proper station in society. But now that he was enveloped in the
111
+ old calico robes which had grown yellow in the same service, he was
112
+ badged and ticketed, and fell into his place at once--a parish
113
+ child--the orphan of a workhouse--the humble, half-starved drudge--to
114
+ be cuffed and buffeted through the world--despised by all, and pitied
115
+ by none.
116
+
117
+ Oliver cried lustily. If he could have known that he was an orphan,
118
+ left to the tender mercies of church-wardens and overseers, perhaps he
119
+ would have cried the louder.
@@ -0,0 +1,38 @@
1
+ require 'benchmark'
2
+ include Benchmark
3
+
4
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
5
+ require 'word_wrapper'
6
+
7
+ samples_dir = File.join(File.dirname(__FILE__), '..', 'samples')
8
+ @oliver_twist = File.read(File.join(samples_dir, "oliver-twist.txt"))
9
+ @before_the_law = File.read(File.join(samples_dir, "before-the-law.txt"))
10
+ @gettysburg = File.read(File.join(samples_dir, "getty-long.txt"))
11
+
12
+ def run_greedy(text, times=10000)
13
+ g = WordWrapper::Greedy.new(100, text)
14
+ times.times do
15
+ g.compute_wrapping
16
+ end
17
+ end
18
+
19
+ def run_mr(text, times=100)
20
+ g = WordWrapper::MinimumRaggedness.new(100, text)
21
+ times.times do
22
+ g.compute_wrapping
23
+ end
24
+ end
25
+
26
+ puts "Greedy algorithm"
27
+ Benchmark.bm do |x|
28
+ x.report("#{@gettysburg.split.length} words x 10000:") { run_greedy(@gettysburg) }
29
+ x.report("#{@before_the_law.split.length} words x 10000:") { run_greedy(@before_the_law) }
30
+ x.report("#{@oliver_twist.split.length} words x 10:") { run_greedy(@oliver_twist, 10) }
31
+ end
32
+
33
+ puts "\nMinimum Raggedness algorithm"
34
+ Benchmark.bm do |x|
35
+ x.report("#{@gettysburg.split.length} words x 10000:") { run_mr(@gettysburg) }
36
+ x.report("#{@before_the_law.split.length} words x 10000:") { run_mr(@before_the_law) }
37
+ x.report("#{@oliver_twist.split.length} words x 10:") { run_mr(@oliver_twist, 10) }
38
+ end
@@ -0,0 +1,80 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'word_wrapper'
3
+
4
+ require 'minitest/autorun'
5
+
6
+ class WordWrapperTest < MiniTest::Unit::TestCase
7
+ def setup
8
+ @short_text = "Four score and seven years ago our fathers brought forth upon this continent a new nation"
9
+ @med_text = "Four score and seven years ago our fathers brought forth upon this continent a new nation, conceived in liberty and dedicated to the proposition that all men are created equal"
10
+ end
11
+
12
+ def test_greedy_costs
13
+ assert_equal 90, WordWrapper::Greedy.new(13, @short_text).cost
14
+ assert_equal 264, WordWrapper::Greedy.new(13, @med_text).cost
15
+ end
16
+
17
+ def test_min_raggedness_costs
18
+ assert_equal 74, WordWrapper::MinimumRaggedness.new(13, @short_text).cost
19
+ assert_equal 204, WordWrapper::MinimumRaggedness.new(13, @med_text).cost
20
+ end
21
+
22
+ def test_optimal_word
23
+ assert_equal 0, WordWrapper::Greedy.new(13, "A"*13 ).cost
24
+ assert_equal 0, WordWrapper::MinimumRaggedness.new(13, "A"*13 ).cost
25
+ end
26
+
27
+ def test_greedy_output
28
+ assert_equal """Four score
29
+ and seven
30
+ years ago our
31
+ fathers
32
+ brought forth
33
+ upon this
34
+ continent a
35
+ new nation,
36
+ conceived in
37
+ liberty and
38
+ dedicated to
39
+ the
40
+ proposition
41
+ that all men
42
+ are created
43
+ equal
44
+ """, WordWrapper::Greedy.new(13,@med_text).wrap
45
+ end
46
+
47
+ def test_minimum_raggedness_output
48
+ assert_equal """Four score
49
+ and seven
50
+ years ago
51
+ our fathers
52
+ brought forth
53
+ upon this
54
+ continent a
55
+ new nation,
56
+ conceived in
57
+ liberty and
58
+ dedicated
59
+ to the
60
+ proposition
61
+ that all
62
+ men are
63
+ created equal
64
+ """, WordWrapper::MinimumRaggedness.new(13,@med_text).wrap
65
+ end
66
+
67
+ def test_minimum_raggedness_with_large_word
68
+ assert_equal """Before the
69
+ law sits a
70
+ gatekeeper.
71
+ To this
72
+ gatekeeper
73
+ comes
74
+ a man
75
+ """, WordWrapper::MinimumRaggedness
76
+ .new(10,
77
+ "Before the law sits a gatekeeper. To this gatekeeper comes a man")
78
+ .wrap
79
+ end
80
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: word_wrapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stephen Pike
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: &70312798021560 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70312798021560
25
+ description: Word wrapping implementation in ruby. Includes a naive greedy algorithm
26
+ (fast) and Knuth's minimum raggedness algorithm from TeX (slower for long texts).
27
+ email: scpike@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - lib/greedy.rb
33
+ - lib/minimum_raggedness.rb
34
+ - lib/word_wrapper.rb
35
+ - test/word_wrapper_bench.rb
36
+ - test/word_wrapper_test.rb
37
+ - samples/before-the-law.txt
38
+ - samples/getty-long.txt
39
+ - samples/getty-med.txt
40
+ - samples/getty-small.txt
41
+ - samples/oliver-twist.txt
42
+ - Rakefile
43
+ - README.md
44
+ - LICENSE
45
+ homepage: https://github.com/scpike/word-wrapping/tree/master/ruby
46
+ licenses:
47
+ - bsd
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubyforge_project:
66
+ rubygems_version: 1.8.15
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Pure ruby word wrapping
70
+ test_files: []
71
+ has_rdoc: