Ruby 2.4

PrettyPrint

class PrettyPrint

父类:对象

这个类实现了一个好的打印算法。它为分组结构找到换行符和好的缩进。

默认情况下,该类假定基本元素是字符串,字符串中的每个字节都有单列宽度。但是通过给某些方法提供合适的参数,它可以用于其他情况:

  • newline对象和空间生成块:: new

  • #text的可选宽度参数

  • #breakable有几种候选用途:

  • 使用比例字体的文本格式

  • 具有与字节数不同的列的多字节字符

  • 非字符串格式

错误

  • 基于框的格式?

  • 其他(更好)的模型/算法?

报告bugs.ruby-lang.org上的任何错误

参考

Christian Lindig,严格漂亮,2000年3月,www.st.cs.uni-sb.de/~ lindig/papers/#pretty

Philip Wadler,一个好的打印机,1998年3月,homepages.inf.ed.ac.uk/ wadler/topics/language-design.html#prettier

作者

Tanaka Akira akr@fsij.org

属性

genspaceR

一个lambda或Proc,它接受Fixnum的一个参数,并返回相应数量的空格。

默认情况下这是:

lambda {|n| ' ' * n}

group_queueR

相当印刷的堆栈中的PrettyPrint :: GroupQueue

indentR

要缩进的空格数量

maxwidthR

在将行分隔到换行符之前,行的最大宽度

这默认为79,应该是一个Fixnum

newlineR

附加output到添加新行的值。

这个默认为“n”,应该是String

outputR

输出对象。

这个默认为'',并且应该接受<<方法

公共类方法

format(output =''。dup,maxwidth = 79,newline =“\ n”,genspace = lambda {| n |''* n}){| q | ...}显示源文件

这是一个方便的方法,它与以下相同:

begin q = PrettyPrint.new(output, maxwidth, newline, &genspace) ... q.flush output end

# File lib/prettyprint.rb, line 44 def PrettyPrint.format(output=''.dup, maxwidth=79, newline="\n", genspace=lambda {|n| ' ' * n}) q = PrettyPrint.new(output, maxwidth, newline, &genspace) yield q q.flush output end

new(output =''。dup,maxwidth = 79,newline =“\ n”,&genspace)显示源文件

为好的打印创建一个缓冲区。

output是输出目标。如果没有指定,则假定为''。它应该有一个<<方法,它接受obj#text的第一个参数sep,#breakable的第一个参数newline,:: new 的第一个参数,以及:: new的给定块的结果。

maxwidth指定最大行长度。如果没有指定,则假定为79。但是,maxwidth如果提供长时间不可破坏的文本,实际输出可能会溢出。

newline用于换行符。如果未指定,则使用“n”。

该块用于生成空格。{|宽度| ''* width}被使用,如果没有给出。

# File lib/prettyprint.rb, line 81 def initialize(output=''.dup, maxwidth=79, newline="\n", &genspace) @output = output @maxwidth = maxwidth @newline = newline @genspace = genspace || lambda {|n| ' ' * n} @output_width = 0 @buffer_width = 0 @buffer = [] root_group = Group.new(0) @group_stack = [root_group] @group_queue = GroupQueue.new(root_group) @indent = 0 end

singleline_format(output =''dup,maxwidth = nil,newline = nil,genspace = nil){| q | ...}显示源文件

这与::格式类似,但结果没有中断。

maxwidthnewline并被genspace忽略。

breakable块中的调用不会中断一行,只会被视为一个调用text

# File lib/prettyprint.rb, line 58 def PrettyPrint.singleline_format(output=''.dup, maxwidth=nil, newline=nil, genspace=nil) q = SingleLine.new(output) yield q output end

公共实例方法

break_outmost_groups()显示源文件

将缓冲区分成短于最大宽度的行

# File lib/prettyprint.rb, line 159 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) @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

breakable(sep=' ', width=sep.length) Show source

这说“如果需要,你可以在这里打破一条线”,并且如果一条线在这一点上没有被破坏,则插入一个width列文本sep

如果sep未指定,则使用“”。

如果width未指定,sep.length则使用。sep例如,当你是一个多字节字符时,你将不得不指定它。

# File lib/prettyprint.rb, line 223 def breakable(sep=' ', width=sep.length) group = @group_stack.last if group.break? flush @output << @newline @output << @genspace.call(@indent) @output_width = @indent @buffer_width = 0 else @buffer << Breakable.new(sep, width, self) @buffer_width += width break_outmost_groups end end

current_group() Show source

返回最近添加到堆栈的组。

受影响的例子:

out = "" => "" q = PrettyPrint.new(out) => #<PrettyPrint:0x82f85c0 @output="", @maxwidth=79, @newline="\n", @genspace=#<Proc:0x82f8368@/home/vbatts/.rvm/rubies/ruby-head/lib/ruby/2.0.0/prettyprint.rb:82 (lambda)>, @output_width=0, @buffer_width=0, @buffer=[], @group_stack=[#<PrettyPrint::Group:0x82f8138 @depth=0, @breakables=[], @break=false>], @group_queue=#<PrettyPrint::GroupQueue:0x82fb7c0 @queue=[[#<PrettyPrint::Group:0x82f8138 @depth=0, @breakables=[], @break=false>]]>, @indent=0> q.group { q.text q.current_group.inspect q.text q.newline q.group(q.current_group.depth + 1) { q.text q.current_group.inspect q.text q.newline q.group(q.current_group.depth + 1) { q.text q.current_group.inspect q.text q.newline q.group(q.current_group.depth + 1) { q.text q.current_group.inspect q.text q.newline } } } } => 284 puts out #<PrettyPrint::Group:0x8354758 @depth=1, @breakables=[], @break=false> #<PrettyPrint::Group:0x8354550 @depth=2, @breakables=[], @break=false> #<PrettyPrint::Group:0x83541cc @depth=3, @breakables=[], @break=false> #<PrettyPrint::Group:0x8347e54 @depth=4, @breakables=[], @break=false>

# File lib/prettyprint.rb, line 154 def current_group @group_stack.last end

fill_breakable(sep=' ', width=sep.length) Show source

除了决定是否决定破解决定外,这与可破密的类似。

一个组下的两个fill_breakable可能会导致4个结果:(break,break),(break,non-break),(non-break,break),(non-break,non-break)。这与易碎性不同,因为组下的两个易碎可能会导致2个结果:(break,break),(non-break,non-break)。

sep如果一行在这一点上没有被破解,则插入文本。

如果sep未指定,则使用“”。

如果width未指定,sep.length则使用。sep例如,当你是一个多字节字符时,你将不得不指定它。

# File lib/prettyprint.rb, line 211 def fill_breakable(sep=' ', width=sep.length) group { breakable sep, width } end

flush() Show source

输出缓冲数据。

# File lib/prettyprint.rb, line 287 def flush @buffer.each {|data| @output_width = data.output(@output, @output_width) } @buffer.clear @buffer_width = 0 end

group(indent = 0,open_obj ='',close_obj ='',open_width = open_obj.length,close_width = close_obj.length){ ...}显示源文件

在该块中添加组线断点提示。换行提示全部使用或不使用。

如果indent指定,则方法调用被视为嵌套(缩进){...}。

如果open_obj指定,text open_obj, open_width则在分组之前调用。如果close_obj指定,text close_obj, close_width则在分组后调用。

# File lib/prettyprint.rb, line 248 def group(indent=0, open_obj='', close_obj='', open_width=open_obj.length, close_width=close_obj.length) text open_obj, open_width group_sub { nest(indent) { yield } } text close_obj, close_width end

group_sub() { || ... } Show source

取一个块并排队一个进一步缩进1级的新组。

# File lib/prettyprint.rb, line 259 def group_sub group = Group.new(@group_stack.last.depth + 1) @group_stack.push group @group_queue.enq group begin yield ensure @group_stack.pop if group.breakables.empty? @group_queue.delete group end end end

nest(indent) { || ... } Show source

换行符后增加左边距indent,在块中添加换行符。

# File lib/prettyprint.rb, line 276 def nest(indent) @indent += indent begin yield ensure @indent -= indent end end

text(obj, width=obj.length) Show source

这增加objwidth宽度列的文本。

如果width未指定,则使用obj.length。

# File lib/prettyprint.rb, line 179 def text(obj, width=obj.length) 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