|
||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||
java.lang.Objectde.uka.ilkd.pp.Layouter<Exc>
Exc - The type of exceptions that might be thrown by the backend.public class Layouter<Exc extends java.lang.Exception>
This class pretty-prints information using line breaks and indentation. For instance, it can be used to print
while (i>0) {
i--;
j++;
}
instead of
while (i>0) { i
--; j++;}
if a maximum line width of 15 characters is chosen.
The formatted output is directed to a backend which
might write it to an I/O stream, append it to the text of a GUI
componenet or store it in a string. The Backend interface
encapsulates the concept of backend. Apart from handling the
output, the backend is also asked for the available line width and
for the amount of space needed to print a string. This makes it
possible to include e.g. HTML markup in the output which does not
take up any space. There are two convenience implementations
WriterBackend and StringBackend, which write the
output to a Writer, resp. a
String.
The layouter internally keeps track of a current indentation level. Think of nicely indented Java source code. Then the indentation level at any point is the number of blank columns to be inserted at the begining of the next line if you inserted a line break. To increase the indentation level of parts of the text, the input to the layouter is separated into blocks. The indentation level changes when a block is begun, and it is reset to its previous value when a block is ended. Of course, blocks maybe nested.
In order to break text among several lines, the layouter needs to be told where line breaks are allowed. A break is a position in the text where there is either a line break (with appropriate indentation) or a number of spaces, if enough material fits in one line. In order to handle the indentation level properly, breaks should only occur inside blocks. There are in fact two kinds of blocks: consistent and inconsistent ones. In a consistent block, lines are broken either at all or at none of the breaks. In an inconsistent block, as much material as possible is put on one line before it is broken.
Consider the program above. It should be printed either as
while (i>0) { i--; j++; }
or, if there is not enough space on the line, as
while (i>0) {
i--;
j++;
}
Given a Layouter object l, we could say:
l.beginC(2).print("while (i>0) {").brk(1,0)
.print("i--;").brk(1,0)
.print("j++;").brk(1,-2)
.print("{").end();
The call to beginC(int) starts a consistent block,
increasing the indentation level by 2. The print(String)
methods gives some actual text to be output. The call to brk(int,int) inserts a break. The first argument means that one
space should be printed at this position if the line is
not broken. The second argument is an offset to be added
to the indentation level for the next line, if the line is
broken. The effect of this parameter can be seen in the call
brk(1,-2). The offset of -2 outdents the
last line by 2 positions, which aligns the closing brace with the
while.
If the lines in a block are broken, one sometimes wants to insert
spaces up to the current indentation level at a certain position
without allowing a line break there. This can be done using the
ind(int,int) method. For instance, one wants to output either
...[Good and Bad and Ugly]...or
...[ Good
and Bad
and Ugly]...
Note the four spaces required before Good. We do this
by opening a block which sets the indentation level to the column
where the G ends up and outdenting the lines with
the and:
l.print("...[").beginC(4).ind(0,0).print("Good").brk(1,-4)
.print("and ").print("Bad").brk(1,-4)
.print("and ").print("Ugly").end().print("]...");
Again, the first argument to ind(int,int) is a number of
spaces to print if the block we are in is printed on one line. The
second argument is an offset to be added to the current indentation
level to determine the column to which we should skip.
When all text has been sent to a Layouter and all blocks have been
ended, the close() method should be closed. This sends
all pending output to the backend and invokes the Backend.close() method, which usually closes I/O streams, etc.
Some applications need to keep track of where certain parts of the
input text end up in the output. For this purpose, the Layouter
class provides the mark(Object) method.
The public methods of this class may be divided into two
categories: A small number of primitive methods, as
described above, and a host of convenience methods which
simplify calling the primitive ones for often-used arguments. For
instance, a call to beginC() is shorthand for
beginC(ind), where ind is the default
indentation selected when the Layouter was constructed.
Most of the methods can throw an UnbalancedBlocksException,
which indicates that the sequence of method calls was illegal, i.e.
more blocks were ended than begun, the Layouter is closed before all
blocks are ended, a break occurs outside of any block, etc.
The backend might throw exceptions of the type indicated by the
type parameter Exc.
Such exceptions get passed through to the caller of the
Layouter. Note that since text usually gets buffered before it is
sent to the backend, exceptions thrown by calls to Layouter methods
might not be caused directly by that method call but by an earlier
one getting forwarded to the backend.
The algorithm used is essentially the classical one from
Derek C. Oppen: Prettyprinting, TOPLAS volume 2 number 4,
ACM, 1980, pp. 465-483, with some minor extensions. It has the
property that if the input contains enough actual text, i.e.
not just arbitrarily long sequences of calls to beginC,
mark, etc., then pretty-printing uses constant
space, and time linear in the size of the input. In fact,
output will begin before the whole input has been given, so
this class can be used to pretty-print a stream of
data.
Backend| Field Summary | |
|---|---|
static int |
DEFAULT_INDENTATION
= 2 : The default indentation for some of the convenience constructors |
static int |
DEFAULT_LINE_WIDTH
= 80 : The line width for some of the convenience factories. |
| Constructor Summary | |
|---|---|
Layouter(Backend<Exc> back,
int indentation)
Construts a newly allocated Layouter which will send output to the given Backend and has the given default indentation. |
|
| Method Summary | |
|---|---|
Layouter<Exc> |
begin(boolean consistent)
Begin a block with default indentation. |
Layouter<Exc> |
begin(boolean consistent,
int indent)
Begin a block. |
Layouter<Exc> |
beginC()
Begin a consistent block. |
Layouter<Exc> |
beginC(int indent)
Begin a consistent block. |
Layouter<Exc> |
beginI()
Begin an inconsistent block. |
Layouter<Exc> |
beginI(int indent)
Begin an inconsistent block. |
Layouter<Exc> |
brk()
Print a break with zero offset and width one. |
Layouter<Exc> |
brk(int width)
Print a break with zero offset. |
Layouter<Exc> |
brk(int width,
int offset)
Print a break. |
void |
close()
Close the Layouter. |
Layouter<Exc> |
end()
Ends the innermost block. |
Layouter<Exc> |
flush()
Output any information currently kept in buffers. |
static Layouter<java.io.IOException> |
getWriterLayouter(java.io.Writer writer)
Factory method for a Layouter with a WriterBackend. |
static Layouter<java.io.IOException> |
getWriterLayouter(java.io.Writer writer,
int lineWidth)
Factory method for a Layouter with a WriterBackend. |
static Layouter<java.io.IOException> |
getWriterLayouter(java.io.Writer writer,
int lineWidth,
int indentation)
Factory method for a Layouter with a WriterBackend. |
Layouter<Exc> |
ind()
Indent with zero offset and zero width. |
Layouter<Exc> |
ind(int width,
int offset)
Indent to a current indentation level if surrounding block is broken. |
Layouter<Exc> |
mark(java.lang.Object o)
This leads to a call of the Backend.mark(Object) method
of the backend, when the material preceding the call to
mark has been printed to the backend, including
any inserted line breaks and indentation. |
Layouter<Exc> |
nl()
Print a break with zero offset and large width. |
Layouter<Exc> |
pre(java.lang.String s)
Layout prefromated text. |
Layouter<Exc> |
print(java.lang.String s)
Output text material. |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
public static final int DEFAULT_LINE_WIDTH
public static final int DEFAULT_INDENTATION
| Constructor Detail |
|---|
public Layouter(Backend<Exc> back,
int indentation)
Backend and has the given default indentation.
back - the Backendindentation - the default indentation| Method Detail |
|---|
public static Layouter<java.io.IOException> getWriterLayouter(java.io.Writer writer)
WriterBackend.
The line width is taken to be DEFAULT_LINE_WIDTH, and the
default indentation DEFAULT_INDENTATION.
writer - the Writer the Backend is going to use
public static Layouter<java.io.IOException> getWriterLayouter(java.io.Writer writer,
int lineWidth)
WriterBackend.
The default indentation is taken from DEFAULT_INDENTATION.
writer - the Writer the Backend is going to uselineWidth - the maximum lineWidth the Backend is going to use
public static Layouter<java.io.IOException> getWriterLayouter(java.io.Writer writer,
int lineWidth,
int indentation)
WriterBackend.
writer - the Writer the Backend is going to uselineWidth - the maximum lineWidth the Backend is going to useindentation - the default indentation
public Layouter<Exc> print(java.lang.String s)
throws Exc extends java.lang.Exception
s should not
contain newline characters. If you have a string with newline
characters, and want to retain its formatting, consider using
the pre(String s) method. The Layouter will not
insert any line breaks in such a string.
s - the String to print.
Exc extends java.lang.Exception
public Layouter<Exc> begin(boolean consistent,
int indent)
consistent is set, breaks
are either all broken or all not broken. The indentation
level is increased by indent.
consistent - true for consistent blockindent - increment to indentation level
public Layouter<Exc> end()
throws Exc extends java.lang.Exception
Exc extends java.lang.Exception
public Layouter<Exc> brk(int width,
int offset)
throws Exc extends java.lang.Exception
width spaces if the
line is not broken at this point. If it is
broken, indentation is added to the current indentation level,
plus the value of offset.
width - space to insert if not brokenoffset - offset relative to current indentation level
Exc extends java.lang.Exception
public Layouter<Exc> ind(int width,
int offset)
throws Exc extends java.lang.Exception
width spaces. Otherwise, indent to the current
indentation level, plus offset, unless that
position has already been exceeded on the current line. If
that is the case, nothing is printed. No line break is
possible at this point.
width - space to insert if not brokenoffset - offset relative to current indentation level
Exc extends java.lang.Exception
public Layouter<Exc> mark(java.lang.Object o)
throws Exc extends java.lang.Exception
Backend.mark(Object) method
of the backend, when the material preceding the call to
mark has been printed to the backend, including
any inserted line breaks and indentation. The Object
argument to mark is passed through unchanged to
the backend and may be used by the application to pass
information about the purpose of the mark.
o - an object to be passed through to the backend.
Exc extends java.lang.Exception
public Layouter<Exc> flush()
throws Exc extends java.lang.Exception
flush or
close() then.
Exc extends java.lang.Exception
public void close()
throws Exc extends java.lang.Exception
Backend.close() method of the backend is called, which
closes any open I/O streams, etc.
Exc extends java.lang.Exceptionpublic Layouter<Exc> beginI()
public Layouter<Exc> beginC()
public Layouter<Exc> beginI(int indent)
indent
to the indentation level.
indent - the indentation for this block
public Layouter<Exc> beginC(int indent)
indent
to the indentation level.
indent - the indentation for this block
public Layouter<Exc> begin(boolean consistent)
consistent - true for consistent block
public Layouter<Exc> brk(int width)
throws Exc extends java.lang.Exception
width - space to insert if not broken
Exc extends java.lang.Exception
public Layouter<Exc> brk()
throws Exc extends java.lang.Exception
Exc extends java.lang.Exception
public Layouter<Exc> nl()
throws Exc extends java.lang.Exception
Exc extends java.lang.Exception
public Layouter<Exc> ind()
throws Exc extends java.lang.Exception
Exc extends java.lang.Exception
public Layouter<Exc> pre(java.lang.String s)
throws Exc extends java.lang.Exception
s
(separated by \n) gets printed as a string and newlines become
forced breaks.
s - the pre-formatted string
Exc extends java.lang.Exception
|
||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||