|
|
tex_wrap (version 1.00) | tex_wrap.py |
Implements TeX's algorithm for breaking paragraphs into lines.
This module provides a straightforward implementation of the algorithm
used by TeX to format paragraphs. The algorithm uses dynamic
programming to find a globally optimal division into lines, enabling
it to produce more attractive results than a first-fit or best-fit
algorithm can. For a full description, see the reference.
The module provides the ObjectList class, which is a list of Box,
Glue, and Penalty instances. The elements making up a paragraph of
text should be assembled into a single ObjectList. Boxes represent
characters of type, and their only attribute is width. Glue
represents a space of variable size; in addition to a preferred width,
glue can also stretch and shrink, to an amount that's specified by the
user. Penalties are used to encourage or discourage breaking a line
at a given point. Positive values discourage line breaks at a given
point, and a value of INFINITY forbids breaking the line at the
penalty. Negative penalty values encourage line breaks at a given
point, and a value of -INFINITY forces a line break at a particular
point.
The compute_breakpoints() method of ObjectList returns a list of
integers containing the indexes at which the paragraph should be
broken. If you're setting the text to be ragged-right (or
ragged-left, I suppose), then simply loop over the text and insert
breaks at the appropriate points. For full justification, you'll have
to loop over each line's contents, calculate its adjustment ratio by
calling compute_adjustment_ratio(), and for each bit of glue, call its
compute_width() method to figure out how long this dab of glue should
be.
Reference:
"Breaking Paragraphs into Lines", D.E. Knuth and M.F. Plass,
chapter 3 of _Digital Typography_, CSLI Lecture Notes #78.
Implemented by A.M. Kuchling <akuchlin@mems-exchange.org>
Classes |
| |
- Box
- Glue
- Penalty
- UserList.UserList
-
- ObjectList
- _BreakNode
class Glue |
|
Class representing a bit of glue. Glue has a preferred width,
but it can stretch up to an additional distance, and can shrink
by a certain amount. Line breaks can be placed at any point where
glue immediately follows a box. |
|
- __init__(self, width, stretch, shrink)
- compute_width(self, r)
- Return how long this glue should be, for the given adjustment
ratio r.
- is_box(self)
- is_forced_break(self)
- is_glue(self)
- is_penalty(self)
|
class ObjectList(UserList.UserList) |
|
Class representing a list of Box, Glue, and Penalty objects.
Supports the same methods as regular Python lists. |
|
- add_active_node(self, active_nodes, node)
- Add a node to the active node list.
The node is added so that the list of active nodes is always
sorted by line number, and so that the set of (position, line,
fitness_class) tuples has no repeated values.
- add_closing_penalty(self)
- Add the standard glue and penalty for the end of a paragraph
- compute_adjustment_ratio(self, pos1, pos2, line, line_lengths)
- Compute adjustment ratio for the line between pos1 and pos2
- compute_breakpoints(self, line_lengths, looseness=0, tolerance=1, fitness_demerit=100, flagged_demerit=100)
- Compute a list of optimal breakpoints for the paragraph
represented by this ObjectList, returning them as a list of
integers, each one the index of a breakpoint.
line_lengths : a list of integers giving the lengths of each
line. The last element of the list is reused
for subsequent lines.
looseness : An integer value. If it's positive, the paragraph
will be set to take that many lines more than the
optimum value. If it's negative, the paragraph is
set as tightly as possible. Defaults to zero,
meaning the optimal length for the paragraph.
tolerance : the maximum adjustment ratio allowed for a line.
Defaults to 1.
fitness_demerit : additional value added to the demerit score
when two consective lines are in different
fitness classes.
flagged_demerit : additional value added to the demerit score
when breaking at the second of two flagged
penalties.
- is_feasible_breakpoint(self, i)
- Return true if position 'i' is a feasible breakpoint.
- is_forced_break(self, i)
- Return true if position 'i' is a forced breakpoint.
- measure_shrink(self, pos1, pos2)
- Add up the shrink between positions 1 and 2
- measure_stretch(self, pos1, pos2)
- Add up the stretch between positions 1 and 2
- measure_width(self, pos1, pos2)
- Add up the widths between positions 1 and 2
|
class Penalty |
|
Class representing a penalty. Negative penalty values
encourage line breaks at a given point, and positive values
discourage breaks. A value of INFINITY either absolutely requires
or forbids a break. Penalties have a width of zero unless a break
is taken at the penalty point, at which point the value of the
penalty's 'width' attribute is used. |
|
- __init__(self, width, penalty, flagged=0)
- is_box(self)
- is_forced_break(self)
- is_glue(self)
- is_penalty(self)
|
class _BreakNode |
|
Internal class representing an active breakpoint. |
|
- __init__(self, position, line, fitness_class, totalwidth, totalstretch, totalshrink, demerits, previous=None)
- __repr__(self)
| |
Constants |
| |
INFINITY = 1000 __doc__ = "\nImplements TeX's algorithm for breaking paragra...ed by A.M. Kuchling <akuchlin@mems-exchange.org>\n" __file__ = './tex_wrap.pyc' __name__ = 'tex_wrap' __version__ = '1.00' |
Download [7K]
Signature
|