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