1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/prettyprint.rb: re-implemented for incremental output to handle

huge data.  API is changed a bit.

* lib/pp.rb: adapt new pretty printing API.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2600 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2002-06-27 06:27:20 +00:00
parent 264d2e4da9
commit e50f2d285f
3 changed files with 302 additions and 298 deletions

View file

@ -1,3 +1,10 @@
Thu Jun 27 15:22:18 2002 Tanaka Akira <akr@m17n.org>
* lib/prettyprint.rb: re-implemented for incremental output to handle
huge data. API is changed a bit.
* lib/pp.rb: adapt new pretty printing API.
Thu Jun 27 08:28:18 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net> Thu Jun 27 08:28:18 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* parse.y (literal_concat_string): non-string last expression in * parse.y (literal_concat_string): non-string last expression in

View file

@ -57,8 +57,8 @@ I like the latter. If you do too, this library is for you.
It returns (({nil})). It returns (({nil})).
== Customized output == Output Customization
To define your customized pretty printing function for your class, To define your customized pretty printing function for your classes,
redefine a method (({pretty_print(((|pp|)))})) in the class. redefine a method (({pretty_print(((|pp|)))})) in the class.
It takes an argument ((|pp|)) which is an instance of the class ((<PP>)). It takes an argument ((|pp|)) which is an instance of the class ((<PP>)).
The method should use PP#text, PP#breakable, PP#nest, PP#group and The method should use PP#text, PP#breakable, PP#nest, PP#group and
@ -118,9 +118,9 @@ end
class PP < PrettyPrint class PP < PrettyPrint
def PP.pp(obj, width=79, out=$>) def PP.pp(obj, width=79, out=$>)
pp = PP.new pp = PP.new(out, width)
pp.guard_inspect_key {pp.pp obj} pp.guard_inspect_key {pp.pp obj}
pp.format(out, width) pp.flush
#$pp = pp #$pp = pp
out << "\n" out << "\n"
end end
@ -134,7 +134,7 @@ class PP < PrettyPrint
@@sharing_detection = val @@sharing_detection = val
end end
def initialize def initialize(out, width=79)
super super
@sharing_detection = @@sharing_detection @sharing_detection = @@sharing_detection
end end

View file

@ -3,10 +3,10 @@
=begin =begin
= PrettyPrint = PrettyPrint
The class implements pretty printing algorithm. The class implements pretty printing algorithm.
It finds line breaks and nice indentations for grouped structure. It finds line breaks and nice indentations for grouped structure.
By default, the class assumes that primitive elements are strings and By default, the class assumes that primitive elements are strings and
each byte in the strings have single column in width. each byte in the strings have single column in width.
But it can be used for other situasions But it can be used for other situasions
by giving suitable arguments for some methods: by giving suitable arguments for some methods:
newline object and space generation block for (({PrettyPrint.new})), newline object and space generation block for (({PrettyPrint.new})),
@ -17,17 +17,30 @@ text formatting using proportional fonts,
multibyte characters which has columns diffrent to number of bytes, multibyte characters which has columns diffrent to number of bytes,
non-string formatting, etc. non-string formatting, etc.
== class methods == class methods
--- PrettyPrint.new([newline]) [{|width| ...}] --- PrettyPrint.new(output[, maxwidth[, newline]]) [{|width| ...}]
creates a buffer for pretty printing. creates a buffer for pretty printing.
((|output|)) is a output target. It should have a (({<<})) method
which accepts
the first argument ((|obj|)) of (({PrettyPrint#text})),
the first argument ((|sep|)) of (({PrettyPrint#breakable})),
the first argument ((|newline|)) of (({PrettyPrint.new})),
and
the result of a given block for (({PrettyPrint.new})).
((|maxwidth|)) specifies maximum line length.
If it is not specified, 79 is assumed.
However actual outputs may overflow ((|maxwidth|)) if
long non-breakable texts are provided.
((|newline|)) is used for line breaks. ((|newline|)) is used for line breaks.
(({"\n"})) is used if it is not specified. (({"\n"})) is used if it is not specified.
The block is used to generate spaces. The block is used to generate spaces.
(({{|width| ' ' * width}})) is used if it is not given. (({{|width| ' ' * width}})) is used if it is not given.
== methods == methods
--- text(obj[, width]) --- text(obj[, width])
adds ((|obj|)) as a text of ((|width|)) columns in width. adds ((|obj|)) as a text of ((|width|)) columns in width.
@ -45,31 +58,19 @@ non-string formatting, etc.
character, for example. character, for example.
--- nest(indent) {...} --- nest(indent) {...}
increases left margin after newline with ((|indent|)) for line breaks added in the block. increases left margin after newline with ((|indent|)) for line breaks added
in the block.
--- group {...} --- group {...}
groups line break hints added in the block. groups line break hints added in the block.
The line break hints are all to be breaked or not. The line break hints are all to be breaked or not.
--- fill_group {...} --- flush
groups line break hints added in the block. outputs buffered data.
The each line break hints may be breaked or not differently.
--- format(out[, width])
outputs buffered data to ((|out|)).
It tries to restrict the line length to ((|width|)) but it may
overflow.
If ((|width|)) is not specified, 79 is assumed.
((|out|)) must have a method named (({<<})) which accepts
a first argument ((|obj|)) of (({PrettyPrint#text})),
a first argument ((|sep|)) of (({PrettyPrint#breakable})),
a first argument ((|newline|)) of (({PrettyPrint.new})),
and
a result of a given block for (({PrettyPrint.new})).
== Bugs == Bugs
* Current API is for minimalists. More useful methods are required.
* Box based formatting? Other (better) model/algorithm? * Box based formatting? Other (better) model/algorithm?
== References == References
@ -82,180 +83,180 @@ Philip Wadler, A prettier printer, March 1998,
=end =end
class PrettyPrint class PrettyPrint
def initialize(newline="\n", &genspace) def initialize(output, maxwidth=79, newline="\n", &genspace)
@output = output
@maxwidth = maxwidth
@newline = newline @newline = newline
@genspace = genspace || lambda {|n| ' ' * n} @genspace = genspace || lambda {|n| ' ' * n}
@buf = Group.new
@nest = [0] @output_width = 0
@stack = [] @buffer_width = 0
@buffer = []
root_group = Group.new(0)
@group_stack = [root_group]
@group_queue = GroupQueue.new(root_group)
@indent = 0
end
def break_outmost_groups
while @maxwidth < @output_width + @buffer_width
return unless group = @group_queue.deq
until group.breakables.empty?
data = @buffer.shift
@output_width = data.output(@output, @output_width, @newline, @genspace)
@buffer_width -= data.width
end
while !@buffer.empty? && Text === @buffer.first
text = @buffer.shift
@output_width = text.output(@output, @output_width)
@buffer_width -= text.width
end
end
end end
def text(obj, width=obj.length) def text(obj, width=obj.length)
@buf << Text.new(obj, width) if @buffer.empty?
@output << obj
@output_width += width
else
text = @buffer.last
unless Text === text
text = Text.new
@buffer << text
end
text.add(obj, width)
@buffer_width += width
break_outmost_groups
end
end end
def breakable(sep=' ', width=sep.length) def breakable(sep=' ', width=sep.length)
@buf << Breakable.new(sep, width, @nest.last, @newline, @genspace) group = @group_stack.last
end if group.break?
flush
def nest(indent) @output << @newline
@nest << @nest.last + indent @output << @genspace.call(@indent)
begin @output_width = @indent
yield @buffer_width = 0
ensure else
@nest.pop @buffer << Breakable.new(sep, width, @indent, group)
@buffer_width += width
break_outmost_groups
end end
end end
def group def group
g = Group.new group = Group.new(@group_stack.last.depth + 1)
@buf << g @group_stack.push group
@stack << @buf @group_queue.enq group
@buf = g
begin begin
yield yield
ensure ensure
@buf = @stack.pop @group_stack.pop
end end
end end
def fill_group def nest(indent)
g = FillGroup.new @indent += indent
@buf << g
@stack << @buf
@buf = g
begin begin
yield yield
ensure ensure
@buf = @stack.pop @indent -= indent
end end
end end
def format(out, width=79) def flush
tails = [[-1, 0]] @buffer.each {|data|
@buf.update_tails(tails, 0) @output_width = data.output(@output, @output_width, @newline, @genspace)
@buf.multiline_output(out, 0, 0, width) }
@buffer.clear
@buffer_width = 0
end end
class Text class Text
def initialize(text, width) def initialize
@text = text @objs = []
@width = width @width = 0
end
attr_reader :width
def output(out, output_width, newline=nil, genspace=nil)
@objs.each {|obj| out << obj}
output_width + @width
end end
def update_tails(tails, group) def add(obj, width)
@tail = tails[-1][1] @objs << obj
tails[-1][1] += @width @width += width
end
attr_reader :tail
def singleline_width
return @width
end
def singleline_output(out)
out << @text
end
def multiline_output(out, group, margin, width)
singleline_output(out)
return margin + singleline_width
end end
end end
class Breakable class Breakable
def initialize(sep, width, indent, newline, genspace) def initialize(sep, width, indent, group)
@sep = sep @obj = sep
@width = width @width = width
@indent = indent @indent = indent
@newline = newline @group = group
@genspace = genspace @group.breakables.push self
end end
attr_reader :obj, :width, :indent
def update_tails(tails, group) def output(out, output_width, newline, genspace)
@tail = tails[-1][1] @group.breakables.shift
if group == tails[-1][0] if @group.break?
tails[-2][1] += @width + tails[-1][1] out << newline
tails[-1][1] = 0 out << genspace.call(@indent)
@indent
else else
tails[-1][1] += @width out << @obj
tails << [group, 0] output_width + @width
end end
end end
attr_reader :tail
def singleline_width
return @width
end
def singleline_output(out)
out << @sep
end
def multiline_output(out, group, margin, width)
out << @newline
out << @genspace.call(@indent)
return @indent
end
end end
class Group class Group
def initialize def initialize(depth)
@buf = [] @depth = depth
@singleline_width = nil @breakables = []
@break = false
end
attr_reader :depth, :breakables
def break
@break = true
end end
def <<(obj) def break?
@buf << obj @break
end
def update_tails(tails, group)
@tail = tails[-1][1]
len = 0
@buf.reverse_each {|obj|
obj.update_tails(tails, group + 1)
len += obj.singleline_width
}
@singleline_width = len
while group < tails[-1][0]
tails[-2][1] += tails[-1][1]
tails.pop
end
end
attr_reader :tail
def singleline_width
return @singleline_width
end
def singleline_output(out)
@buf.each {|obj| obj.singleline_output(out)}
end
def multiline_output(out, group, margin, width)
if margin + singleline_width + @tail <= width
singleline_output(out)
margin += @singleline_width
else
@buf.each {|obj|
margin = obj.multiline_output(out, group + 1, margin, width)
}
end
return margin
end end
end end
class FillGroup < Group class GroupQueue
def multiline_output(out, group, margin, width) def initialize(*groups)
@buf.each {|obj| @queue = []
if margin + obj.singleline_width + obj.tail <= width groups.each {|g| enq g}
obj.singleline_output(out) end
margin += obj.singleline_width
else def enq(group)
margin = obj.multiline_output(out, group + 1, margin, width) depth = group.depth
end @queue << [] until depth < @queue.length
@queue[depth] << group
end
def deq
@queue.each {|gs|
(gs.length-1).downto(0) {|i|
unless gs[i].breakables.empty?
group = gs.slice!(i, 1).first
group.break
return group
end
}
gs.each {|group| group.break}
gs.clear
} }
return margin return nil
end end
end end
end end
@ -266,20 +267,6 @@ if __FILE__ == $0
class WadlerExample < RUNIT::TestCase class WadlerExample < RUNIT::TestCase
def setup def setup
@hello = PrettyPrint.new
@hello.group {
@hello.group {
@hello.group {
@hello.group {
@hello.text 'hello'; @hello.breakable; @hello.text 'a'
}
@hello.breakable; @hello.text 'b'
}
@hello.breakable; @hello.text 'c'
}
@hello.breakable; @hello.text 'd'
}
@tree = Tree.new("aaaa", Tree.new("bbbbb", Tree.new("ccc"), @tree = Tree.new("aaaa", Tree.new("bbbbb", Tree.new("ccc"),
Tree.new("dd")), Tree.new("dd")),
Tree.new("eee"), Tree.new("eee"),
@ -288,6 +275,22 @@ if __FILE__ == $0
Tree.new("ii"))) Tree.new("ii")))
end end
def hello(width)
out = ''
hello = PrettyPrint.new(out, width)
hello.group {
hello.group {
hello.group {
hello.group {
hello.text 'hello'
hello.breakable; hello.text 'a'}
hello.breakable; hello.text 'b'}
hello.breakable; hello.text 'c'}
hello.breakable; hello.text 'd'}
hello.flush
out
end
def test_hello_00_06 def test_hello_00_06
expected = <<'End'.chomp expected = <<'End'.chomp
hello hello
@ -296,8 +299,8 @@ b
c c
d d
End End
@hello.format(out='', 0); assert_equal(expected, out) assert_equal(expected, hello(0))
@hello.format(out='', 6); assert_equal(expected, out) assert_equal(expected, hello(6))
end end
def test_hello_07_08 def test_hello_07_08
@ -307,8 +310,8 @@ b
c c
d d
End End
@hello.format(out='', 7); assert_equal(expected, out) assert_equal(expected, hello(7))
@hello.format(out='', 8); assert_equal(expected, out) assert_equal(expected, hello(8))
end end
def test_hello_09_10 def test_hello_09_10
@ -317,8 +320,8 @@ hello a b
c c
d d
End End
@hello.format(out='', 9); assert_equal(expected, out) out = hello(9); assert_equal(expected, out)
@hello.format(out='', 10); assert_equal(expected, out) out = hello(10); assert_equal(expected, out)
end end
def test_hello_11_12 def test_hello_11_12
@ -326,20 +329,26 @@ End
hello a b c hello a b c
d d
End End
@hello.format(out='', 11); assert_equal(expected, out) assert_equal(expected, hello(11))
@hello.format(out='', 12); assert_equal(expected, out) assert_equal(expected, hello(12))
end end
def test_hello_13 def test_hello_13
expected = <<'End'.chomp expected = <<'End'.chomp
hello a b c d hello a b c d
End End
@hello.format(out='', 13); assert_equal(expected, out) assert_equal(expected, hello(13))
end
def tree(width)
out = ''
pp = PrettyPrint.new(out, width)
@tree.show(pp)
pp.flush
out
end end
def test_tree_00_19 def test_tree_00_19
pp = PrettyPrint.new
@tree.show(pp)
expected = <<'End'.chomp expected = <<'End'.chomp
aaaa[bbbbb[ccc, aaaa[bbbbb[ccc,
dd], dd],
@ -348,13 +357,11 @@ aaaa[bbbbb[ccc,
hhh, hhh,
ii]] ii]]
End End
pp.format(out='', 0); assert_equal(expected, out) assert_equal(expected, tree(0))
pp.format(out='', 19); assert_equal(expected, out) assert_equal(expected, tree(19))
end end
def test_tree_20_22 def test_tree_20_22
pp = PrettyPrint.new
@tree.show(pp)
expected = <<'End'.chomp expected = <<'End'.chomp
aaaa[bbbbb[ccc, dd], aaaa[bbbbb[ccc, dd],
eee, eee,
@ -362,34 +369,35 @@ aaaa[bbbbb[ccc, dd],
hhh, hhh,
ii]] ii]]
End End
pp.format(out='', 20); assert_equal(expected, out) assert_equal(expected, tree(20))
pp.format(out='', 22); assert_equal(expected, out) assert_equal(expected, tree(22))
end end
def test_tree_23_43 def test_tree_23_43
pp = PrettyPrint.new
@tree.show(pp)
expected = <<'End'.chomp expected = <<'End'.chomp
aaaa[bbbbb[ccc, dd], aaaa[bbbbb[ccc, dd],
eee, eee,
ffff[gg, hhh, ii]] ffff[gg, hhh, ii]]
End End
pp.format(out='', 23); assert_equal(expected, out) assert_equal(expected, tree(23))
pp.format(out='', 43); assert_equal(expected, out) assert_equal(expected, tree(43))
end end
def test_tree_44 def test_tree_44
pp = PrettyPrint.new assert_equal(<<'End'.chomp, tree(44))
@tree.show(pp)
pp.format(out='', 44)
assert_equal(<<'End'.chomp, out)
aaaa[bbbbb[ccc, dd], eee, ffff[gg, hhh, ii]] aaaa[bbbbb[ccc, dd], eee, ffff[gg, hhh, ii]]
End End
end end
def test_tree_alt_00_18 def tree_alt(width)
pp = PrettyPrint.new out = ''
pp = PrettyPrint.new(out, width)
@tree.altshow(pp) @tree.altshow(pp)
pp.flush
out
end
def test_tree_alt_00_18
expected = <<'End'.chomp expected = <<'End'.chomp
aaaa[ aaaa[
bbbbb[ bbbbb[
@ -404,13 +412,11 @@ aaaa[
] ]
] ]
End End
pp.format(out='', 0); assert_equal(expected, out) assert_equal(expected, tree_alt(0))
pp.format(out='', 18); assert_equal(expected, out) assert_equal(expected, tree_alt(18))
end end
def test_tree_alt_19_20 def test_tree_alt_19_20
pp = PrettyPrint.new
@tree.altshow(pp)
expected = <<'End'.chomp expected = <<'End'.chomp
aaaa[ aaaa[
bbbbb[ ccc, dd ], bbbbb[ ccc, dd ],
@ -422,13 +428,11 @@ aaaa[
] ]
] ]
End End
pp.format(out='', 19); assert_equal(expected, out) assert_equal(expected, tree_alt(19))
pp.format(out='', 20); assert_equal(expected, out) assert_equal(expected, tree_alt(20))
end end
def test_tree_alt_20_49 def test_tree_alt_20_49
pp = PrettyPrint.new
@tree.altshow(pp)
expected = <<'End'.chomp expected = <<'End'.chomp
aaaa[ aaaa[
bbbbb[ ccc, dd ], bbbbb[ ccc, dd ],
@ -436,17 +440,15 @@ aaaa[
ffff[ gg, hhh, ii ] ffff[ gg, hhh, ii ]
] ]
End End
pp.format(out='', 21); assert_equal(expected, out) assert_equal(expected, tree_alt(21))
pp.format(out='', 49); assert_equal(expected, out) assert_equal(expected, tree_alt(49))
end end
def test_tree_alt_50 def test_tree_alt_50
pp = PrettyPrint.new
@tree.altshow(pp)
expected = <<'End'.chomp expected = <<'End'.chomp
aaaa[ bbbbb[ ccc, dd ], eee, ffff[ gg, hhh, ii ] ] aaaa[ bbbbb[ ccc, dd ], eee, ffff[ gg, hhh, ii ] ]
End End
pp.format(out='', 50); assert_equal(expected, out) assert_equal(expected, tree_alt(50))
end end
class Tree class Tree
@ -507,29 +509,32 @@ End
end end
class StrictPrettyExample < RUNIT::TestCase class StrictPrettyExample < RUNIT::TestCase
def setup def prog(width)
@pp = PrettyPrint.new out = ''
@pp.group { pp = PrettyPrint.new(out, width)
@pp.group {@pp.nest(2) { pp.group {
@pp.text "if"; @pp.breakable; pp.group {pp.nest(2) {
@pp.group { pp.text "if"; pp.breakable;
@pp.nest(2) { pp.group {
@pp.group {@pp.text "a"; @pp.breakable; @pp.text "=="} pp.nest(2) {
@pp.breakable; @pp.text "b"}}}} pp.group {pp.text "a"; pp.breakable; pp.text "=="}
@pp.breakable pp.breakable; pp.text "b"}}}}
@pp.group {@pp.nest(2) { pp.breakable
@pp.text "then"; @pp.breakable; pp.group {pp.nest(2) {
@pp.group { pp.text "then"; pp.breakable;
@pp.nest(2) { pp.group {
@pp.group {@pp.text "a"; @pp.breakable; @pp.text "<<"} pp.nest(2) {
@pp.breakable; @pp.text "2"}}}} pp.group {pp.text "a"; pp.breakable; pp.text "<<"}
@pp.breakable pp.breakable; pp.text "2"}}}}
@pp.group {@pp.nest(2) { pp.breakable
@pp.text "else"; @pp.breakable; pp.group {pp.nest(2) {
@pp.group { pp.text "else"; pp.breakable;
@pp.nest(2) { pp.group {
@pp.group {@pp.text "a"; @pp.breakable; @pp.text "+"} pp.nest(2) {
@pp.breakable; @pp.text "b"}}}}} pp.group {pp.text "a"; pp.breakable; pp.text "+"}
pp.breakable; pp.text "b"}}}}}
pp.flush
out
end end
def test_00_04 def test_00_04
@ -547,8 +552,8 @@ else
+ +
b b
End End
@pp.format(out='', 0); assert_equal(expected, out) assert_equal(expected, prog(0))
@pp.format(out='', 4); assert_equal(expected, out) assert_equal(expected, prog(4))
end end
def test_05 def test_05
@ -565,7 +570,7 @@ else
a + a +
b b
End End
@pp.format(out='', 5); assert_equal(expected, out) assert_equal(expected, prog(5))
end end
def test_06 def test_06
@ -580,7 +585,7 @@ else
a + a +
b b
End End
@pp.format(out='', 6); assert_equal(expected, out) assert_equal(expected, prog(6))
end end
def test_07 def test_07
@ -594,7 +599,7 @@ then
else else
a + b a + b
End End
@pp.format(out='', 7); assert_equal(expected, out) assert_equal(expected, prog(7))
end end
def test_08 def test_08
@ -606,7 +611,7 @@ then
else else
a + b a + b
End End
@pp.format(out='', 8); assert_equal(expected, out) assert_equal(expected, prog(8))
end end
def test_09 def test_09
@ -617,7 +622,7 @@ then
else else
a + b a + b
End End
@pp.format(out='', 9); assert_equal(expected, out) assert_equal(expected, prog(9))
end end
def test_10 def test_10
@ -627,7 +632,7 @@ then
a << 2 a << 2
else a + b else a + b
End End
@pp.format(out='', 10); assert_equal(expected, out) assert_equal(expected, prog(10))
end end
def test_11_31 def test_11_31
@ -636,23 +641,24 @@ if a == b
then a << 2 then a << 2
else a + b else a + b
End End
@pp.format(out='', 11); assert_equal(expected, out) assert_equal(expected, prog(11))
@pp.format(out='', 15); assert_equal(expected, out) assert_equal(expected, prog(15))
@pp.format(out='', 31); assert_equal(expected, out) assert_equal(expected, prog(31))
end end
def test_32 def test_32
expected = <<'End'.chomp expected = <<'End'.chomp
if a == b then a << 2 else a + b if a == b then a << 2 else a + b
End End
@pp.format(out='', 32); assert_equal(expected, out) assert_equal(expected, prog(32))
end end
end end
class TailGroup < RUNIT::TestCase class TailGroup < RUNIT::TestCase
def test_1 def test_1
pp = PrettyPrint.new out = ''
pp = PrettyPrint.new(out, 10)
pp.group { pp.group {
pp.group { pp.group {
pp.text "abc" pp.text "abc"
@ -665,52 +671,56 @@ End
pp.text "jkl" pp.text "jkl"
} }
} }
pp.format(out='', 10) pp.flush
assert_equal("abc\ndefghi jkl", out) assert_equal("abc defghi\njkl", out)
end end
end end
class NonString < RUNIT::TestCase class NonString < RUNIT::TestCase
def setup def format(width)
@pp = PrettyPrint.new('newline') {|n| "#{n} spaces"} out = []
@pp.text(3, 3) pp = PrettyPrint.new(out, width, 'newline') {|n| "#{n} spaces"}
@pp.breakable(1, 1) pp.text(3, 3)
@pp.text(3, 3) pp.breakable(1, 1)
pp.text(3, 3)
pp.flush
out
end end
def test_6 def test_6
@pp.format(out=[], 6) assert_equal([3, "newline", "0 spaces", 3], format(6))
assert_equal([3, "newline", "0 spaces", 3], out)
end end
def test_7 def test_7
@pp.format(out=[], 7) assert_equal([3, 1, 3], format(7))
assert_equal([3, 1, 3], out)
end end
end end
class Fill < RUNIT::TestCase class Fill < RUNIT::TestCase
def setup def format(width)
@pp = PrettyPrint.new out = ''
@pp.fill_group { pp = PrettyPrint.new(out, width)
@pp.text 'abc' pp.group {
@pp.breakable pp.text 'abc'
@pp.text 'def' pp.group { pp.breakable }
@pp.breakable pp.text 'def'
@pp.text 'ghi' pp.group { pp.breakable }
@pp.breakable pp.text 'ghi'
@pp.text 'jkl' pp.group { pp.breakable }
@pp.breakable pp.text 'jkl'
@pp.text 'mno' pp.group { pp.breakable }
@pp.breakable pp.text 'mno'
@pp.text 'pqr' pp.group { pp.breakable }
@pp.breakable pp.text 'pqr'
@pp.text 'stu' pp.group { pp.breakable }
pp.text 'stu'
} }
pp.flush
out
end end
def test_0_6 def test_00_06
expected = <<'End'.chomp expected = <<'End'.chomp
abc abc
def def
@ -720,23 +730,19 @@ mno
pqr pqr
stu stu
End End
@pp.format(out='', 0) assert_equal(expected, format(0))
assert_equal(expected, out) assert_equal(expected, format(6))
@pp.format(out='', 6)
assert_equal(expected, out)
end end
def test_7_10 def test_07_10
expected = <<'End'.chomp expected = <<'End'.chomp
abc def abc def
ghi jkl ghi jkl
mno pqr mno pqr
stu stu
End End
@pp.format(out='', 7) assert_equal(expected, format(7))
assert_equal(expected, out) assert_equal(expected, format(10))
@pp.format(out='', 10)
assert_equal(expected, out)
end end
def test_11_14 def test_11_14
@ -745,10 +751,8 @@ abc def ghi
jkl mno pqr jkl mno pqr
stu stu
End End
@pp.format(out='', 11) assert_equal(expected, format(11))
assert_equal(expected, out) assert_equal(expected, format(14))
@pp.format(out='', 14)
assert_equal(expected, out)
end end
def test_15_18 def test_15_18
@ -756,10 +760,8 @@ End
abc def ghi jkl abc def ghi jkl
mno pqr stu mno pqr stu
End End
@pp.format(out='', 15) assert_equal(expected, format(15))
assert_equal(expected, out) assert_equal(expected, format(18))
@pp.format(out='', 18)
assert_equal(expected, out)
end end
def test_19_22 def test_19_22
@ -767,10 +769,8 @@ End
abc def ghi jkl mno abc def ghi jkl mno
pqr stu pqr stu
End End
@pp.format(out='', 19) assert_equal(expected, format(19))
assert_equal(expected, out) assert_equal(expected, format(22))
@pp.format(out='', 22)
assert_equal(expected, out)
end end
def test_23_26 def test_23_26
@ -778,18 +778,15 @@ End
abc def ghi jkl mno pqr abc def ghi jkl mno pqr
stu stu
End End
@pp.format(out='', 23) assert_equal(expected, format(23))
assert_equal(expected, out) assert_equal(expected, format(26))
@pp.format(out='', 26)
assert_equal(expected, out)
end end
def test_27 def test_27
expected = <<'End'.chomp expected = <<'End'.chomp
abc def ghi jkl mno pqr stu abc def ghi jkl mno pqr stu
End End
@pp.format(out='', 27) assert_equal(expected, format(27))
assert_equal(expected, out)
end end
end end