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 | ...}显示源文件
这与::格式类似,但结果没有中断。
maxwidth
,newline
并被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
这增加obj
了width
宽度列的文本。
如果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