File: prettypr.3

package info (click to toggle)
erlang-manpages 1%3A12.b.3-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 4,188 kB
  • ctags: 2
  • sloc: makefile: 68; perl: 30; sh: 15
file content (357 lines) | stat: -rw-r--r-- 12,807 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
.TH prettypr 3 "syntax_tools  1.5.5" "Ericsson AB" "ERLANG MODULE DEFINITION"
.SH MODULE
prettypr \- A generic pretty printer library\&.
.SH DESCRIPTION
.LP
A generic pretty printer library\&. This module uses a strict-style context passing implementation of John Hughes algorithm, described in "The design of a Pretty-printing Library"\&. The paragraph-style formatting, empty documents, floating documents, and null strings are my own additions to the algorithm\&.
.LP
To get started, you should read about the document() data type; the main constructor functions: text/1, above/2, beside/2, nest/2, sep/1, and par/2; and the main layout function format/3\&.
.LP
If you simply want to format a paragraph of plain text, you probably want to use the text_par/2 function, as in the following example: 

.nf
  prettypr:format(prettypr:text_par("Lorem ipsum dolor sit amet"), 20)
.fi

.SH DATA TYPES
.RS 2
.TP 4
.B
\fIdocument()\fR:

.RS 4
.LP
An abstract character-based "document" representing a number of possible layouts, which can be processed to produce a single concrete layout\&. A concrete layout can then be rendered as a sequence of characters containing linebreaks, which can be passed to a printer or terminal that uses a fixed-width font\&.
.LP

.LP
For example, a document \fIsep([text("foo"), text("bar")])\fR represents the two layouts 

.nf
     foo bar
.fi
.LP
and 

.nf
     foo
     bar
.fi
.LP

.LP
Which layout is chosen depends on the available horizontal space\&. When processing a document, the main parameters are the \fIpaper width\fR and the \fIline width\fR (also known as the "ribbon width")\&. In the resulting layout, no text should be printed beyond the paper width (which by default is 80 characters) as long as it can be avoided, and each single line of text (its indentation not counted, hence "ribbon") should preferably be no wider than the specified line width (which by default is 65)\&.
.LP

.LP
Documents can be joined into a single new document using the constructor functions of this module\&. Note that the new document often represents a larger number of possible layouts than just the sum of the components\&.
.LP

.RE
.RE
.SH EXPORTS
.LP
.B
above(D1::document(), D2::document()) -> document()
.br
.RS
.LP
Concatenates documents vertically\&. Returns a document representing the concatenation of the documents \fID1\fR and \fID2\fR such that the first line of \fID2\fR follows directly below the last line of \fID1\fR, and the first character of \fID2\fR is in the same horizontal column as the first character of \fID1\fR, in all possible layouts\&.
.LP
Examples: 

.nf
     ab  cd  =>  ab
                 cd
 
                    abc
     abc   fgh  =>   de
      de    ij      fgh
                     ij
.fi
.RE
.LP
.B
beside(D1::document(), D2::document()) -> document()
.br
.RS
.LP
Concatenates documents horizontally\&. Returns a document representing the concatenation of the documents \fID1\fR and \fID2\fR such that the last character of \fID1\fR is horizontally adjacent to the first character of \fID2\fR, in all possible layouts\&. (Note: any indentation of \fID2\fR is lost\&.)
.LP
Examples: 

.nf
     ab  cd  =>  abcd
 
     ab  ef      ab
     cd  gh  =>  cdef
                   gh
.fi
.RE
.LP
.B
best(D::document(), PaperWidth::integer(), LineWidth::integer()) -> empty | document()
.br
.RS
.LP
Selects a "best" layout for a document, creating a corresponding fixed-layout document\&. If no layout could be produced, the atom \fIempty\fR is returned instead\&. For details about \fIPaperWidth\fR and \fILineWidth\fR, see format/3\&. The function is idempotent\&.
.LP
One possible use of this function is to compute a fixed layout for a document, which can then be included as part of a larger document\&. For example: 

.nf
     above(text("Example:"), nest(8, best(D, W - 12, L - 6)))
.fi
.LP
will format \fID\fR as a displayed-text example indented by 8, whose right margin is indented by 4 relative to the paper width \fIW\fR of the surrounding document, and whose maximum individual line length is shorter by 6 than the line length \fIL\fR of the surrounding document\&.
.LP
This function is used by the format/3 function to prepare a document before being laid out as text\&.
.RE
.LP
.B
break(D::document()) -> document()
.br
.RS
.LP
Forces a line break at the end of the given document\&. This is a utility function; see empty/0 for details\&.
.RE
.LP
.B
empty() -> document()
.br
.RS
.LP
Yields the empty document, which has neither height nor width\&. (\fIempty\fR is thus different from an empty text string, which has zero width but height 1\&.)
.LP
Empty documents are occasionally useful; in particular, they have the property that \fIabove(X, empty())\fR will force a new line after \fIX\fR without leaving an empty line below it; since this is a common idiom, the utility function break/1 will place a given document in such a context\&. 
.LP
\fISee also:\fR text/1\&.
.RE
.LP
.B
floating(D::document()) -> document()
.br
.RS
.LP
Equivalent to floating(D, 0, 0)\&.
.RE
.LP
.B
floating(D::document(), Hp::integer(), Vp::integer()) -> document()
.br
.RS
.LP
Creates a "floating" document\&. The result represents the same set of layouts as \fID\fR; however, a floating document may be moved relative to other floating documents immediately beside or above it, according to their relative horizontal and vertical priorities\&. These priorities are set with the \fIHp\fR and \fIVp\fR parameters; if omitted, both default to zero\&.
.LP
Notes: Floating documents appear to work well, but are currently less general than you might wish, losing effect when embedded in certain contexts\&. It is possible to nest floating-operators (even with different priorities), but the effects may be difficult to predict\&. In any case, note that the way the algorithm reorders floating documents amounts to a "bubblesort", so don\&'t expect it to be able to sort large sequences of floating documents quickly\&.
.RE
.LP
.B
follow(D1::document(), D2::document()) -> document()
.br
.RS
.LP
Equivalent to follow(D1, D2, 0)\&.
.RE
.LP
.B
follow(D1::document(), D2::document(), Offset::integer()) -> document()
.br
.RS
.LP
Separates two documents by either a single space, or a line break and intentation\&. In other words, one of the layouts 

.nf
     abc def
.fi
.LP
or 

.nf
     abc
      def
.fi
.LP
will be generated, using the optional offset in the latter case\&. This is often useful for typesetting programming language constructs\&.
.LP
This is a utility function; see par/2 for further details\&. 
.LP
\fISee also:\fR follow/2\&.
.RE
.LP
.B
format(D::document()) -> string()
.br
.RS
.LP
Equivalent to format(D, 80)\&.
.RE
.LP
.B
format(D::document(), PaperWidth::integer()) -> string()
.br
.RS
.LP
Equivalent to format(D, PaperWidth, 65)\&.
.RE
.LP
.B
format(D::document(), PaperWidth::integer(), LineWidth::integer()) -> string()
.br
.RS
.LP
Computes a layout for a document and returns the corresponding text\&. See document() for further information\&. Throws \fIno_layout\fR if no layout could be selected\&.
.LP
\fIPaperWidth\fR specifies the total width (in character positions) of the field for which the text is to be laid out\&. \fILineWidth\fR specifies the desired maximum width (in number of characters) of the text printed on any single line, disregarding leading and trailing white space\&. These parameters need to be properly balanced in order to produce good layouts\&. By default, \fIPaperWidth\fR is 80 and \fILineWidth\fR is 65\&. 
.LP
\fISee also:\fR best/3\&.
.RE
.LP
.B
nest(N::integer(), D::document()) -> document()
.br
.RS
.LP
Indents a document a number of character positions to the right\&. Note that \fIN\fR may be negative, shifting the text to the left, or zero, in which case \fID\fR is returned unchanged\&.
.RE
.LP
.B
null_text(Characters::string()) -> document()
.br
.RS
.LP
Similar to text/1, but the result is treated as having zero width\&. This is regardless of the actual length of the string\&. Null text is typically used for markup, which is supposed to have no effect on the actual layout\&.
.LP
The standard example is when formatting source code as HTML to be placed within \fI<pre>\&.\&.\&.</pre>\fR markup, and using e\&.g\&. \fI<i>\fR and \fI<b>\fR to make parts of the source code stand out\&. In this case, the markup does not add to the width of the text when viewed in an HTML browser, so the layout engine should simply pretend that the markup has zero width\&. 
.LP
\fISee also:\fR empty/0, text/1\&.
.RE
.LP
.B
par(Docs::[document()]) -> document()
.br
.RS
.LP
Equivalent to par(Ds, 0)\&.
.RE
.LP
.B
par(Docs::[document()], Offset::integer()) -> document()
.br
.RS
.LP
Arranges documents in a paragraph-like layout\&. Returns a document representing all possible left-aligned paragraph-like layouts of the (nonempty) sequence \fIDocs\fR of documents\&. Elements in \fIDocs\fR are separated horizontally by a single space character and vertically with a single line break\&. All lines following the first (if any) are indented to the same left column, whose indentation is specified by the optional \fIOffset\fR parameter relative to the position of the first element in \fIDocs\fR\&. For example, with an offset of -4, the following layout can be produced, for a list of documents representing the numbers 0 to 15:

.nf
         0 1 2 3
     4 5 6 7 8 9
     10 11 12 13
     14 15
.fi
.LP
or with an offset of +2: 

.nf
     0 1 2 3 4 5 6
       7 8 9 10 11
       12 13 14 15
.fi
.LP
The utility function text_par/2 can be used to easily transform a string of text into a \fIpar\fR representation by splitting it into words\&.
.LP
Note that whenever a document in \fIDocs\fR contains a line break, it will be placed on a separate line\&. Thus, neither a layout such as 

.nf
     ab cd
        ef
.fi
.LP
nor 

.nf
     ab
     cd ef
.fi
.LP
will be generated\&. However, a useful idiom for making the former variant possible (when wanted) is \fIbeside(par([D1, text("")], N), D2)\fR for two documents \fID1\fR and \fID2\fR\&. This will break the line between \fID1\fR and \fID2\fR if \fID1\fR contains a line break (or if otherwise necessary), and optionally further indent \fID2\fR by \fIN\fR character positions\&. The utility function follow/3 creates this context for two documents \fID1\fR and \fID2\fR, and an optional integer \fIN\fR\&. 
.LP
\fISee also:\fR par/1, text_par/2\&.
.RE
.LP
.B
sep(Docs::[document()]) -> document()
.br
.RS
.LP
Arranges documents horizontally or vertically, separated by whitespace\&. Returns a document representing two alternative layouts of the (nonempty) sequence \fIDocs\fR of documents, such that either all elements in \fIDocs\fR are concatenated horizontally, and separated by a space character, or all elements are concatenated vertically (without extra separation)\&.
.LP
Note: If some document in \fIDocs\fR contains a line break, the vertical layout will always be selected\&.
.LP
Examples: 

.nf
                                  ab
     ab  cd  ef  =>  ab cd ef  |  cd
                                  ef
 
     ab           ab
     cd  ef  =>   cd
                  ef
.fi
.LP

.LP
\fISee also:\fR par/2\&.
.RE
.LP
.B
text(Characters::string()) -> document()
.br
.RS
.LP
Yields a document representing a fixed, unbreakable sequence of characters\&. The string should contain only \fIprintable\fR characters (tabs allowed but not recommended), and \fInot\fR newline, line feed, vertical tab, etc\&. A tab character (\fI\et\fR) is interpreted as padding of 1-8 space characters to the next column of 8 characters \fIwithin the string\fR\&. 
.LP
\fISee also:\fR empty/0, null_text/1, text_par/2\&.
.RE
.LP
.B
text_par(Text::string()) -> document()
.br
.RS
.LP
Equivalent to text_par(Text, 0)\&.
.RE
.LP
.B
text_par(Text::string(), Indentation::integer()) -> document()
.br
.RS
.LP
Yields a document representing paragraph-formatted plain text\&. The optional \fIIndentation\fR parameter specifies the extra indentation of the first line of the paragraph\&. For example, \fItext_par("Lorem ipsum dolor sit amet", N)\fR could represent 

.nf
     Lorem ipsum dolor
     sit amet
.fi
.LP
if \fIN\fR = 0, or 

.nf
       Lorem ipsum
     dolor sit amet
.fi
.LP
if \fIN\fR = 2, or 

.nf
     Lorem ipsum dolor
       sit amet
.fi
.LP
if \fIN\fR = -2\&.
.LP
(The sign of the indentation is thus reversed compared to the par/2 function, and the behaviour varies slightly depending on the sign in order to match the expected layout of a paragraph of text\&.)
.LP
Note that this is just a utility function, which does all the work of splitting the given string into words separated by whitespace and setting up a par with the proper indentation, containing a list of text elements\&. 
.LP
\fISee also:\fR par/2, text/1, text_par/1\&.
.RE