diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-22 02:31:46 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-22 02:31:46 +0000 |
commit | 9ce732561568d940e9ddf2cf6cf798b3dc65ccd7 (patch) | |
tree | 95b1f5f4075867e334a4d4e5fa3c451286cf1b6e | |
parent | 5024bd594de298ae1772d9224c6164aff42ff1fb (diff) |
* prettyprint.rb: FillGroup implemented.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2111 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | lib/pp.rb | 61 | ||||
-rw-r--r-- | lib/prettyprint.rb | 177 |
3 files changed, 188 insertions, 54 deletions
@@ -1,3 +1,7 @@ +Fri Feb 22 11:30:01 2002 Tanaka Akira <[email protected]> + + * prettyprint.rb: FillGroup implemented. + Thu Feb 21 21:40:18 2002 Usaku Nakamura <[email protected]> * ext/extmk.rb.in (create_makefile): remove unnecessary -L option from @@ -6,38 +6,46 @@ == Which seems better? non-pretty-printed output by (({p})) is: - #<PP:0x806486c @stack=[], @nest=[0], @buf=#<PP::Group:0x8064844 @tail=0, @singleline_length=9, @buf=[#<PP::Group:0x80647cc @tail=0, @singleline_length=9, @buf=[#<PP::Text:0x8064768 @text="[">, #<PP::Group:0x80646c8 @tail=1, @singleline_length=1, @buf=[#<PP::Text:0x8064664 @text="1">]>, #<PP::Text:0x80646b4 @text=",">, #<PP::Breakable:0x8064650 @indent=1, @sep=" ">, #<PP::Group:0x8064614 @tail=1, @singleline_length=1, @buf=[#<PP::Text:0x80645b0 @text="2">]>, #<PP::Text:0x8064600 @text=",">, #<PP::Breakable:0x806459c @indent=1, @sep=" ">, #<PP::Group:0x8064560 @tail=1, @singleline_length=1, @buf=[#<PP::Text:0x80644fc @text="3">]>, #<PP::Text:0x806472c @text="]">]>]>> + #<PP:0x81a0d10 @stack=[], @genspace=#<Proc:0x81a0cc0>, @nest=[0], @newline="\n", @buf=#<PrettyPrint::Group:0x81a0c98 @group=0, @tail=0, @buf=[#<PrettyPrint::Group:0x81a0ba8 @group=1, @tail=0, @buf=[#<PrettyPrint::Text:0x81a0b30 @tail=2, @width=1, @text="[">, #<PrettyPrint::Group:0x81a0a68 @group=2, @tail=1, @buf=[#<PrettyPrint::Text:0x81a09f0 @tail=1, @width=1, @text="1">], @singleline_width=1>, #<PrettyPrint::Text:0x81a0a7c @tail=0, @width=1, @text=",">, #<PrettyPrint::Breakable:0x81a0a2c @group=2, @genspace=#<Proc:0x81a0cc0>, @newline="\n", @indent=1, @tail=2, @sep=" ", @width=1>, #<PrettyPrint::Group:0x81a09c8 @group=2, @tail=1, @buf=[#<PrettyPrint::Text:0x81a0950 @tail=1, @width=1, @text="2">], @singleline_width=1>, #<PrettyPrint::Text:0x81a0af4 @tail=0, @width=1, @text="]">], @singleline_width=6>], @singleline_width=6>, @sharing_detection=false> pretty-printed output by (({pp})) is: - #<PP:0x403279c + #<PP:0x40d0688 @buf= - #<PP::Group:0x4032666 + #<PrettyPrint::Group:0x40d064c @buf= - [#<PP::Group:0x4032666 - @buf= - [#<PP::Text:0x40326de @text="[">, - #<PP::Group:0x4032666 - @buf=[#<PP::Text:0x40326de @text="1">], - @singleline_length=1, - @tail=1>, - #<PP::Text:0x40326de @text=",">, - #<PP::Breakable:0x40326b6 @indent=1, @sep=" ">, - #<PP::Group:0x4032666 - @buf=[#<PP::Text:0x40326de @text="2">], - @singleline_length=1, - @tail=1>, - #<PP::Text:0x40326de @text=",">, - #<PP::Breakable:0x40326b6 @indent=1, @sep=" ">, - #<PP::Group:0x4032666 - @buf=[#<PP::Text:0x40326de @text="3">], - @singleline_length=1, - @tail=1>, - #<PP::Text:0x40326de @text="]">], - @singleline_length=9, - @tail=0>], - @singleline_length=9, + [#<PrettyPrint::Group:0x40d05d4 + @buf= + [#<PrettyPrint::Text:0x40d0598 @tail=2, @text="[", @width=1>, + #<PrettyPrint::Group:0x40d0534 + @buf=[#<PrettyPrint::Text:0x40d04f8 @tail=1, @text="1", @width=1>], + @group=2, + @singleline_width=1, + @tail=1>, + #<PrettyPrint::Text:0x40d053e @tail=0, @text=",", @width=1>, + #<PrettyPrint::Breakable:0x40d0516 + @genspace=#<Proc:0x40d0656>, + @group=2, + @indent=1, + @newline="\n", + @sep=" ", + @tail=2, + @width=1>, + #<PrettyPrint::Group:0x40d04e4 + @buf=[#<PrettyPrint::Text:0x40d04a8 @tail=1, @text="2", @width=1>], + @group=2, + @singleline_width=1, + @tail=1>, + #<PrettyPrint::Text:0x40d057a @tail=0, @text="]", @width=1>], + @group=1, + @singleline_width=6, + @tail=0>], + @group=0, + @singleline_width=6, @tail=0>, + @genspace=#<Proc:0x40d0656>, @nest=[0], + @newline="\n", + @sharing_detection=false, @stack=[]> I like the latter. If you do too, this library is for you. @@ -110,6 +118,7 @@ class PP < PrettyPrint pp = PP.new pp.guard_inspect_key {pp.pp obj} pp.format(out, width) + #$pp = pp out << "\n" end diff --git a/lib/prettyprint.rb b/lib/prettyprint.rb index 6d4a6f97b5..b05da3f56f 100644 --- a/lib/prettyprint.rb +++ b/lib/prettyprint.rb @@ -49,6 +49,11 @@ non-string formatting, etc. --- group {...} groups line break hints added in the block. + The line break hints are all to be breaked or not. + +--- fill_group {...} + groups line break hints added in the block. + The each line break hints may be breaked or not differently. --- format(out[, width]) outputs buffered data to ((|out|)). @@ -65,17 +70,13 @@ non-string formatting, etc. a result of a given block for (({PrettyPrint.new})). == Bugs -* Line breaks in a group is constrained to whether all line break hints are - to be breaked or not. Maybe, non-constrained version of - PrettyPrint#group should be provided to filling multi lines. - -* Box based formatting? +* Box based formatting? Other (better) model/algorithm? == References -Strictly Pretty, Christian Lindig, March 2000, +Christian Lindig, Strictly Pretty, March 2000, ((<URL:http://www.gaertner.de/~lindig/papers/strictly-pretty.html>)) -A prettier printer, Philip Wadler, March 1998, +Philip Wadler, A prettier printer, March 1998, ((<URL:http://cm.bell-labs.com/cm/cs/who/wadler/topics/recent.html#prettier>)) =end @@ -98,40 +99,36 @@ class PrettyPrint end def nest(indent) - nest_enter(indent) + @nest << @nest.last + indent begin yield ensure - nest_leave + @nest.pop end end - def nest_enter(indent) - @nest << @nest.last + indent - end - - def nest_leave - @nest.pop - end - def group - group_enter + g = Group.new + @buf << g + @stack << @buf + @buf = g begin yield ensure - group_leave + @buf = @stack.pop end end - def group_enter - g = Group.new + def fill_group + g = FillGroup.new @buf << g @stack << @buf @buf = g - end - - def group_leave - @buf = @stack.pop + begin + yield + ensure + @buf = @stack.pop + end end def format(out, width=79) @@ -147,8 +144,10 @@ class PrettyPrint end def update_tails(tails, group) + @tail = tails[-1][1] tails[-1][1] += @width end + attr_reader :tail def singleline_width return @width @@ -174,6 +173,7 @@ class PrettyPrint end def update_tails(tails, group) + @tail = tails[-1][1] if group == tails[-1][0] tails[-2][1] += @width + tails[-1][1] tails[-1][1] = 0 @@ -182,6 +182,7 @@ class PrettyPrint tails << [group, 0] end end + attr_reader :tail def singleline_width return @width @@ -209,18 +210,19 @@ class PrettyPrint end def update_tails(tails, group) - @tail = tails.empty? ? 0 : tails[-1][1] + @tail = tails[-1][1] len = 0 @buf.reverse_each {|obj| obj.update_tails(tails, group + 1) len += obj.singleline_width } @singleline_width = len - while !tails.empty? && group <= tails[-1][0] + while group < tails[-1][0] tails[-2][1] += tails[-1][1] tails.pop end end + attr_reader :tail def singleline_width return @singleline_width @@ -233,7 +235,7 @@ class PrettyPrint def multiline_output(out, group, margin, width) if margin + singleline_width + @tail <= width singleline_output(out) - margin += singleline_width + margin += @singleline_width else @buf.each {|obj| margin = obj.multiline_output(out, group + 1, margin, width) @@ -242,6 +244,20 @@ class PrettyPrint return margin end end + + class FillGroup < Group + def multiline_output(out, group, margin, width) + @buf.each {|obj| + if margin + obj.singleline_width + obj.tail <= width + obj.singleline_output(out) + margin += obj.singleline_width + else + margin = obj.multiline_output(out, group + 1, margin, width) + end + } + return margin + end + end end if __FILE__ == $0 @@ -674,8 +690,113 @@ End end + class Fill < RUNIT::TestCase + def setup + @pp = PrettyPrint.new + @pp.fill_group { + @pp.text 'abc' + @pp.breakable + @pp.text 'def' + @pp.breakable + @pp.text 'ghi' + @pp.breakable + @pp.text 'jkl' + @pp.breakable + @pp.text 'mno' + @pp.breakable + @pp.text 'pqr' + @pp.breakable + @pp.text 'stu' + } + end + + def test_0_6 + expected = <<'End'.chomp +abc +def +ghi +jkl +mno +pqr +stu +End + @pp.format(out='', 0) + assert_equal(expected, out) + @pp.format(out='', 6) + assert_equal(expected, out) + end + + def test_7_10 + expected = <<'End'.chomp +abc def +ghi jkl +mno pqr +stu +End + @pp.format(out='', 7) + assert_equal(expected, out) + @pp.format(out='', 10) + assert_equal(expected, out) + end + + def test_11_14 + expected = <<'End'.chomp +abc def ghi +jkl mno pqr +stu +End + @pp.format(out='', 11) + assert_equal(expected, out) + @pp.format(out='', 14) + assert_equal(expected, out) + end + + def test_15_18 + expected = <<'End'.chomp +abc def ghi jkl +mno pqr stu +End + @pp.format(out='', 15) + assert_equal(expected, out) + @pp.format(out='', 18) + assert_equal(expected, out) + end + + def test_19_22 + expected = <<'End'.chomp +abc def ghi jkl mno +pqr stu +End + @pp.format(out='', 19) + assert_equal(expected, out) + @pp.format(out='', 22) + assert_equal(expected, out) + end + + def test_23_26 + expected = <<'End'.chomp +abc def ghi jkl mno pqr +stu +End + @pp.format(out='', 23) + assert_equal(expected, out) + @pp.format(out='', 26) + assert_equal(expected, out) + end + + def test_27 + expected = <<'End'.chomp +abc def ghi jkl mno pqr stu +End + @pp.format(out='', 27) + assert_equal(expected, out) + end + + end + RUNIT::CUI::TestRunner.run(WadlerExample.suite) RUNIT::CUI::TestRunner.run(StrictPrettyExample.suite) RUNIT::CUI::TestRunner.run(TailGroup.suite) RUNIT::CUI::TestRunner.run(NonString.suite) + RUNIT::CUI::TestRunner.run(Fill.suite) end |