prettypr
prettypr
模块
漂亮打字员
模块摘要
一个通用的漂亮打印机库。
描述
一个通用漂亮的打印机库。该模块使用严格样式的上下文传递John Hughes算法的实现,如“漂亮打印库的设计”中所述。段式格式化,空文档,浮动文档和空字符串是我自己添加到算法中的。
要开始,你应该阅读关于document()
数据类型; 主要构造的功能:text/1
,above/2
,beside/2
,nest/2
,sep/1
,和par/2
;和主要的布局功能format/3
。
如果您只想格式化纯文本段落,则可能需要使用该text_par/2
函数,如下例所示:
prettypr:format(prettypr:text_par("Lorem ipsum dolor sit amet"), 20)
数据类型
document()
一个抽象的基于字符的“文档”,代表一些可能的布局,可以处理以产生一个具体的布局。然后可以将具体布局渲染为包含换行符的字符序列,这些字符序列可以传递给使用固定宽度字体的打印机或终端。
例如,一个文档sep([text("foo"), text("bar")])
代表这两种布局
foo bar
和
foo
bar
选择哪种布局取决于可用的水平空间。处理文档时,主要参数是纸张宽度
和线宽
(也称为“色带宽度”)。在生成的布局中,只要可以避免文本宽度(默认情况下为80个字符),则不应打印文本,并且每行文本(其缩进不计,因此“ribbon”)应该优先不超过指定的线宽
(默认为65)。
可以使用此模块的构造函数将文档合并到一个新文档中。请注意,新文档通常代表更多数量的可能布局,而不仅仅是组件的总和。
出口
above(D1::document(), D2::document()) ->document()
垂直连接文档。返回表示文件的级联的文档D1
和D2
使得第一行D2
如下直接的最后一行下面D1
,和的第一个字符D2
是在同一水平列的第一个字符D1
,在其所有可能的布局。
例子:
ab cd => ab
cd
abc
abc fgh => de
de ij fgh
ij
beside(D1::document(), D2::document()) ->document()
水平连接文档。返回一个表示文档连接的文档,D1
并且在所有可能的布局中,D2
最后一个字符与第一个字符D1
水平相邻D2
。(注意:任何缩进D2
都会丢失。)
例子:
ab cd => abcd
ab ef ab
cd gh => cdef
gh
best(D::document(), PaperWidth::integer(), LineWidth::integer()) -> empty |document()
为文档选择“best”布局,创建相应的固定布局文档。如果不能生成布局,则原子empty
返回。有关PaperWidth
和的详细信息LineWidth
,请参阅format/3
。该函数是幂等的。
此功能的一个可能用途是计算文档的固定布局,然后将其作为较大文档的一部分包含在内。例如:
above(text("Example:"), nest(8, best(D, W - 12, L - 6)))
将格式化D
为缩进8的显示文本示例,其右边距相对于W
周围文档的纸张宽度缩进4 ,其最大单独行长度比L
周围文档的行长度短6 。
此函数由format/3
函数在作为文本排列之前准备文档。
break(D::document()) ->document()
在给定文档的末尾强制换行。这是一个效用函数; empty/0
详情请参阅。
empty() ->document()
生成空白文档,既没有高度也没有宽度。(empty
因此与text
具有零宽度但高度为1 的空字符串不同)。
空文件偶尔有用; 特别是他们拥有的财产above(X, empty())
将在X
不留下空行的情况下强制新的行; 由于这是一个常见的习惯用法,因此效用函数break/1
将在这种情况下放置给定的文档。
另见:
text/1
。
floating(D::document()) ->document()
相当于floating(D, 0, 0)
。
floating(D::document(), Hp::integer(), Vp::integer()) ->document()
创建一个“floating”文档。结果表示与之相同的一组布局D
; 然而,根据浮动文档的相对水平和垂直优先级,浮动文档可以相对于其旁边或上面的其他浮动文档移动。这些优先级用Hp
和Vp
参数设置;如果省略,则默认为零。
注意:浮动文档似乎运行良好,但目前不如您希望的那么一般,在嵌入特定环境时会失去效果。可以嵌套浮动操作符(即使具有不同的优先级),但影响可能难以预测。在任何情况下,请注意算法重新排列浮动文档的方式等于“bubblesort”,所以不要指望它能够快速排序大量浮动文档。
follow(D1::document(), D2::document()) ->document()
相当于follow(D1, D2, 0)
。
follow(D1::document(), D2::document(), Offset::integer()) ->document()
通过单个空格或换行符和意向来分隔两个文档。换句话说,其中一个布局
abc def
或
abc
def
将在后一种情况下使用可选的偏移量生成。这对于排版编程语言结构通常很有用。
这是一个实用程序函数,请参见par/2
更多细节。
另见:
follow/2
。
format(D::document()) -> string()
相当于format(D, 80)
。
format(D::document(), PaperWidth::integer()) -> string()
相当于format(D, PaperWidth, 65)
。
format(D::document(), PaperWidth::integer(), LineWidth::integer()) -> string()
计算文档的布局并返回相应的文本。查看document()
更多信息。如果不能选择布局,则抛出no_layout
。
PaperWidth
指定要为其布置文本的字段的总宽度(在字符位置中)。LineWidth
指定在任意一行上打印的文本所需的最大宽度(以字符数为单位),而不考虑前导和尾随空白。这些参数需要适当平衡以产生良好的布局。默认情况下,PaperWidth
是80并且LineWidth
是65。
另见:
best/3
。
nest(N::integer(), D::document()) ->document()
将文档缩进右侧的许多字符位置。请注意,这N
可能是负值,将文本左移或零,在这种情况下D
返回的值不变。
null_text(Characters::string()) ->document()
类似于text/1
,但结果被视为具有零宽度。这与字符串的实际长度无关。空文本通常用于标记,它应该对实际布局没有影响。
标准示例是将源代码格式化为<pre>...</pre>标记为HTML的HTML ,并使用例如<i>和<b>使源代码的一部分脱颖而出。在这种情况下,标记不会在HTML浏览器中查看文本的宽度,因此布局引擎应该简单地假装标记的宽度为零。
另见:
empty/0
,text/1
。
par(Docs::[document()]) ->document()
相当于par(Ds, 0)
。
par(Docs::[document()], Offset::integer()) ->document()
以段落式布局排列文档。返回一个文档,表示Docs
文档序列(非空)的所有可能的左对齐段落式布局。元素在Docs
水平方向上由单个空格字符分隔,并在垂直方向上以单个分行符分隔。第一个(如果有的话)之后的所有行都缩进到相同的左列,其缩进由Offset
相对于第一个元素的位置的可选参数指定Docs
。例如,对于-4的偏移量,可以生成以下布局,以获取表示数字0到15的文档列表:
0 1 2 3
4 5 6 7 8 9
10 11 12 13
14 15
或偏移量为+2:
0 1 2 3 4 5 6
7 8 9 10 11
12 13 14 15
效用函数text_par/2
可用于将一串文本轻松转换为par
将其分解为单词的表示形式。
请注意,每当文档Docs
包含换行符时,它将被放置在单独的行上。因此,无论是布局如
ab cd
ef
也不
ab
cd ef
将会生成。然而,一个有用的习惯用于使前一个变体成为可能(当需要时)是beside(par([D1, text("")], N), D2)
两个文件D1
和D2
。这将打破和之间的界限D1
,D2
如果D1
包含换行符(或者如果需要的话),并且可选地D2
通过N
字符位置进一步缩进。效用函数follow/3
创建该环境的两个文件D1
和D2
,和一个可选的整数N
。
另见:
par/1
,text_par/2
。
sep(Docs::[document()]) ->document()
水平或垂直排列文档,以空格分隔。返回一个文档,表示(非空)Docs
文档序列的两个可选布局,使得所有元素Docs
都水平连接,并用空格字符分隔,或者所有元素垂直连接(没有额外的分隔)。
注意:如果某个文档Docs
包含换行符,则将始终选择垂直布局。
例子:
ab
ab cd ef => ab cd ef | cd
ef
ab ab
cd ef => cd
ef
另见:
par/2
。
text(Characters::string()) ->document()
产生表示固定的,不
可破解的字符序列的文档。该字符串应该只包含可打印
字符(制表符允许的,但是不
推荐),和不
换行,换行,垂直制表符,等。制表符(\t
)被解释为1-8空格字符填充,以8个字符下一列内字符串
。
另见:
empty/0
,,,null_text/1
,,,text_par/2
...
text_par(Text::string()) ->document()
相当于text_par(Text, 0)
...
text_par(Text::string(), Indentation::integer()) ->document()
生成表示段落格式纯文本的文档。任选Indentation
参数指定段落第一行的额外缩进。例如,text_par("Lorem ipsum dolor sit amet", N)
能代表
Lorem ipsum dolor
sit amet
如果N
=0,或
Lorem ipsum
dolor sit amet
如果N
=2,或
Lorem ipsum dolor
sit amet
如果N
=-2。
(与par/2
函数相比,缩进的符号相反,并且行为会根据符号略有不同,以便匹配段落文本的预期布局。)
请注意,这只是一个效用函数,它将所有将给定字符串拆分为由空格分隔的单词以及par
使用适当的缩进(包含text
元素列表)进行的所有工作。
另请参阅:
par/2
,text/1
,text_par/1
。
richard@gmail.com