1prettypr(3) Erlang Module Definition prettypr(3)
2
3
4
6 prettypr - A generic pretty printer library.
7
9 A generic pretty printer library. This module uses a strict-style con‐
10 text passing implementation of John Hughes algorithm, described in "The
11 design of a Pretty-printing Library". The paragraph-style formatting,
12 empty documents, floating documents, and null strings are my own addi‐
13 tions to the algorithm.
14
15 To get started, you should read about the document() data type; the
16 main constructor functions: text/1, above/2, beside/2, nest/2, sep/1,
17 and par/2; and the main layout function format/3.
18
19 If you simply want to format a paragraph of plain text, you probably
20 want to use the text_par/2 function, as in the following example:
21
22 prettypr:format(prettypr:text_par("Lorem ipsum dolor sit amet"), 20)
23
25 deep_string() = [char() | deep_string()]:
26
27
28 document() = null | #text{s=deep_string()} | #nest{n=integer(),
29 d=document()} | #beside{d1=document(), d2=document()} |
30 #above{d1=document(), d2=document()} | #sep{ds=[document()], i=inte‐
31 ger(), p=boolean()} | #float{d=document(), h=integer(), v=integer()}
32 | #union{d1=document(), d2=document()} | #fit{d=document()}:
33
34
36 above(D1::document(), D2::document()) -> #above{d1=document(), d2=docu‐
37 ment()}
38
39 Concatenates documents vertically. Returns a document represent‐
40 ing the concatenation of the documents D1 and D2 such that the
41 first line of D2 follows directly below the last line of D1, and
42 the first character of D2 is in the same horizontal column as
43 the first character of D1, in all possible layouts.
44
45 Examples:
46
47 ab cd => ab
48 cd
49
50 abc
51 abc fgh => de
52 de ij fgh
53 ij
54
55 beside(D1::document(), D2::document()) -> #beside{d1=document(),
56 d2=document()}
57
58 Concatenates documents horizontally. Returns a document repre‐
59 senting the concatenation of the documents D1 and D2 such that
60 the last character of D1 is horizontally adjacent to the first
61 character of D2, in all possible layouts. (Note: any indentation
62 of D2 is lost.)
63
64 Examples:
65
66 ab cd => abcd
67
68 ab ef ab
69 cd gh => cdef
70 gh
71
72 best(D::document(), W::integer(), R::integer()) -> empty | document()
73
74 Selects a "best" layout for a document, creating a corresponding
75 fixed-layout document. If no layout could be produced, the atom
76 empty is returned instead. For details about PaperWidth and
77 LineWidth, see format/3. The function is idempotent.
78
79 One possible use of this function is to compute a fixed layout
80 for a document, which can then be included as part of a larger
81 document. For example:
82
83 above(text("Example:"), nest(8, best(D, W - 12, L - 6)))
84
85 will format D as a displayed-text example indented by 8, whose
86 right margin is indented by 4 relative to the paper width W of
87 the surrounding document, and whose maximum individual line
88 length is shorter by 6 than the line length L of the surrounding
89 document.
90
91 This function is used by the format/3 function to prepare a doc‐
92 ument before being laid out as text.
93
94 break(D::document()) -> #above{d1=document(), d2=document()}
95
96 Forces a line break at the end of the given document. This is a
97 utility function; see empty/0 for details.
98
99 empty() -> null
100
101 Yields the empty document, which has neither height nor width.
102 (empty is thus different from an empty text string, which has
103 zero width but height 1.)
104
105 Empty documents are occasionally useful; in particular, they
106 have the property that above(X, empty()) will force a new line
107 after X without leaving an empty line below it; since this is a
108 common idiom, the utility function break/1 will place a given
109 document in such a context.
110
111 See also: text/1.
112
113 floating(D::document()) -> #float{d=document(), h=integer(), v=inte‐
114 ger()}
115
116 Equivalent to floating(D, 0, 0).
117
118 floating(D::document(), H::integer(), V::integer()) -> #float{d=docu‐
119 ment(), h=integer(), v=integer()}
120
121 Creates a "floating" document. The result represents the same
122 set of layouts as D; however, a floating document may be moved
123 relative to other floating documents immediately beside or above
124 it, according to their relative horizontal and vertical priori‐
125 ties. These priorities are set with the Hp and Vp parameters; if
126 omitted, both default to zero.
127
128 Notes: Floating documents appear to work well, but are currently
129 less general than you might wish, losing effect when embedded in
130 certain contexts. It is possible to nest floating-operators
131 (even with different priorities), but the effects may be diffi‐
132 cult to predict. In any case, note that the way the algorithm
133 reorders floating documents amounts to a "bubblesort", so don't
134 expect it to be able to sort large sequences of floating docu‐
135 ments quickly.
136
137 follow(D1::document(), D2::document()) -> #beside{d1=document(),
138 d2=document()}
139
140 Equivalent to follow(D1, D2, 0).
141
142 follow(D1::document(), D2::document(), N::integer()) -> #beside{d1=doc‐
143 ument(), d2=document()}
144
145 Separates two documents by either a single space, or a line
146 break and indentation. In other words, one of the layouts
147
148 abc def
149
150 or
151
152 abc
153 def
154
155 will be generated, using the optional offset in the latter case.
156 This is often useful for typesetting programming language con‐
157 structs.
158
159 This is a utility function; see par/2 for further details.
160
161 See also: follow/2.
162
163 format(D::document()) -> string()
164
165 Equivalent to format(D, 80).
166
167 format(D::document(), W::integer()) -> string()
168
169 Equivalent to format(D, PaperWidth, 65).
170
171 format(D::document(), W::integer(), R::integer()) -> string()
172
173 Computes a layout for a document and returns the corresponding
174 text. See document() for further information. Throws no_layout
175 if no layout could be selected.
176
177 PaperWidth specifies the total width (in character positions) of
178 the field for which the text is to be laid out. LineWidth speci‐
179 fies the desired maximum width (in number of characters) of the
180 text printed on any single line, disregarding leading and trail‐
181 ing white space. These parameters need to be properly balanced
182 in order to produce good layouts. By default, PaperWidth is 80
183 and LineWidth is 65.
184
185 See also: best/3.
186
187 nest(N::integer(), D::document()) -> document()
188
189 Indents a document a number of character positions to the right.
190 Note that N may be negative, shifting the text to the left, or
191 zero, in which case D is returned unchanged.
192
193 null_text(S::string()) -> #text{s=deep_string()}
194
195 Similar to text/1, but the result is treated as having zero
196 width. This is regardless of the actual length of the string.
197 Null text is typically used for markup, which is supposed to
198 have no effect on the actual layout.
199
200 The standard example is when formatting source code as HTML to
201 be placed within <pre>...</pre> markup, and using e.g. <i> and
202 <b> to make parts of the source code stand out. In this case,
203 the markup does not add to the width of the text when viewed in
204 an HTML browser, so the layout engine should simply pretend that
205 the markup has zero width.
206
207 See also: empty/0, text/1.
208
209 par(Ds::[document()]) -> #sep{ds=[document()], i=integer(), p=bool‐
210 ean()}
211
212 Equivalent to par(Ds, 0).
213
214 par(Ds::[document()], N::integer()) -> #sep{ds=[document()], i=inte‐
215 ger(), p=boolean()}
216
217 Arranges documents in a paragraph-like layout. Returns a docu‐
218 ment representing all possible left-aligned paragraph-like lay‐
219 outs of the (nonempty) sequence Docs of documents. Elements in
220 Docs are separated horizontally by a single space character and
221 vertically with a single line break. All lines following the
222 first (if any) are indented to the same left column, whose in‐
223 dentation is specified by the optional Offset parameter relative
224 to the position of the first element in Docs. For example, with
225 an offset of -4, the following layout can be produced, for a
226 list of documents representing the numbers 0 to 15:
227
228 0 1 2 3
229 4 5 6 7 8 9
230 10 11 12 13
231 14 15
232
233 or with an offset of +2:
234
235 0 1 2 3 4 5 6
236 7 8 9 10 11
237 12 13 14 15
238
239 The utility function text_par/2 can be used to easily transform
240 a string of text into a par representation by splitting it into
241 words.
242
243 Note that whenever a document in Docs contains a line break, it
244 will be placed on a separate line. Thus, neither a layout such
245 as
246
247 ab cd
248 ef
249
250 nor
251
252 ab
253 cd ef
254
255 will be generated. However, a useful idiom for making the former
256 variant possible (when wanted) is beside(par([D1, text("")], N),
257 D2) for two documents D1 and D2. This will break the line be‐
258 tween D1 and D2 if D1 contains a line break (or if otherwise
259 necessary), and optionally further indent D2 by N character po‐
260 sitions. The utility function follow/3 creates this context for
261 two documents D1 and D2, and an optional integer N.
262
263 See also: par/1, text_par/2.
264
265 sep(Ds::[document()]) -> #sep{ds=[document()], i=integer(), p=bool‐
266 ean()}
267
268 Arranges documents horizontally or vertically, separated by
269 whitespace. Returns a document representing two alternative lay‐
270 outs of the (nonempty) sequence Docs of documents, such that ei‐
271 ther all elements in Docs are concatenated horizontally, and
272 separated by a space character, or all elements are concatenated
273 vertically (without extra separation).
274
275 Note: If some document in Docs contains a line break, the verti‐
276 cal layout will always be selected.
277
278 Examples:
279
280 ab
281 ab cd ef => ab cd ef | cd
282 ef
283
284 ab ab
285 cd ef => cd
286 ef
287
288 See also: par/2.
289
290 text(S::string()) -> #text{s=deep_string()}
291
292 Yields a document representing a fixed, unbreakable sequence of
293 characters. The string should contain only printable characters
294 (tabs allowed but not recommended), and not newline, line feed,
295 vertical tab, etc. A tab character (\t) is interpreted as pad‐
296 ding of 1-8 space characters to the next column of 8 characters
297 within the string.
298
299 See also: empty/0, null_text/1, text_par/2.
300
301 text_par(S::string()) -> document()
302
303 Equivalent to text_par(Text, 0).
304
305 text_par(S::string(), N::integer()) -> document()
306
307 Yields a document representing paragraph-formatted plain text.
308 The optional Indentation parameter specifies the extra indenta‐
309 tion of the first line of the paragraph. For example,
310 text_par("Lorem ipsum dolor sit amet", N) could represent
311
312 Lorem ipsum dolor
313 sit amet
314
315 if N = 0, or
316
317 Lorem ipsum
318 dolor sit amet
319
320 if N = 2, or
321
322 Lorem ipsum dolor
323 sit amet
324
325 if N = -2.
326
327 (The sign of the indentation is thus reversed compared to the
328 par/2 function, and the behaviour varies slightly depending on
329 the sign in order to match the expected layout of a paragraph of
330 text.)
331
332 Note that this is just a utility function, which does all the
333 work of splitting the given string into words separated by
334 whitespace and setting up a par with the proper indentation,
335 containing a list of text elements.
336
337 See also: par/2, text/1, text_par/1.
338
340 Richard Carlsson <carlsson.richard@gmail.com>
341
342
343
344 syntax_tools 3.1 prettypr(3)