| 
									
										
										
										
											2000-02-04 15:39:30 +00:00
										 |  |  | """Generic output formatting.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Formatter objects transform an abstract flow of formatting events into | 
					
						
							|  |  |  | specific output events on writer objects. Formatters manage several stack | 
					
						
							|  |  |  | structures to allow various properties of a writer object to be changed and | 
					
						
							|  |  |  | restored; writers need not be able to handle relative changes nor any sort | 
					
						
							|  |  |  | of ``change back'' operation. Specific writer properties which may be | 
					
						
							|  |  |  | controlled via formatter objects are horizontal alignment, font, and left | 
					
						
							|  |  |  | margin indentations. A mechanism is provided which supports providing | 
					
						
							|  |  |  | arbitrary, non-exclusive style settings to a writer as well. Additional | 
					
						
							|  |  |  | interfaces facilitate formatting events which are not reversible, such as | 
					
						
							| 
									
										
										
										
											2001-01-14 23:36:06 +00:00
										 |  |  | paragraph separation. | 
					
						
							| 
									
										
										
										
											2000-02-04 15:39:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Writer objects encapsulate device interfaces. Abstract devices, such as | 
					
						
							|  |  |  | file formats, are supported as well as physical devices. The provided | 
					
						
							|  |  |  | implementations all work with abstract devices. The interface makes | 
					
						
							|  |  |  | available mechanisms for setting the properties which formatter objects | 
					
						
							| 
									
										
										
										
											2001-01-14 23:36:06 +00:00
										 |  |  | manage and inserting data into the output. | 
					
						
							| 
									
										
										
										
											2000-02-04 15:39:30 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2013-10-04 11:38:59 -04:00
										 |  |  | import warnings | 
					
						
							| 
									
										
										
										
											2015-10-16 12:09:33 -07:00
										 |  |  | warnings.warn('the formatter module is deprecated', DeprecationWarning, | 
					
						
							|  |  |  |               stacklevel=2) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AS_IS = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-10-06 15:31:30 +00:00
										 |  |  | class NullFormatter: | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |     """A formatter which does nothing.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If the writer parameter is omitted, a NullWriter instance is created. | 
					
						
							|  |  |  |     No methods of the writer are called by NullFormatter instances. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Implementations should inherit from this class if implementing a writer | 
					
						
							|  |  |  |     interface but don't need to inherit any implementation. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											1995-10-06 15:31:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-07 21:29:49 +00:00
										 |  |  |     def __init__(self, writer=None): | 
					
						
							| 
									
										
										
										
											2002-06-01 01:29:16 +00:00
										 |  |  |         if writer is None: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             writer = NullWriter() | 
					
						
							|  |  |  |         self.writer = writer | 
					
						
							| 
									
										
										
										
											1995-10-06 15:31:30 +00:00
										 |  |  |     def end_paragraph(self, blankline): pass | 
					
						
							|  |  |  |     def add_line_break(self): pass | 
					
						
							| 
									
										
										
										
											1996-10-08 21:57:47 +00:00
										 |  |  |     def add_hor_rule(self, *args, **kw): pass | 
					
						
							|  |  |  |     def add_label_data(self, format, counter, blankline=None): pass | 
					
						
							| 
									
										
										
										
											1995-10-06 15:31:30 +00:00
										 |  |  |     def add_flowing_data(self, data): pass | 
					
						
							|  |  |  |     def add_literal_data(self, data): pass | 
					
						
							|  |  |  |     def flush_softspace(self): pass | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def push_alignment(self, align): pass | 
					
						
							|  |  |  |     def pop_alignment(self): pass | 
					
						
							| 
									
										
										
										
											1995-10-06 15:31:30 +00:00
										 |  |  |     def push_font(self, x): pass | 
					
						
							|  |  |  |     def pop_font(self): pass | 
					
						
							|  |  |  |     def push_margin(self, margin): pass | 
					
						
							|  |  |  |     def pop_margin(self): pass | 
					
						
							|  |  |  |     def set_spacing(self, spacing): pass | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def push_style(self, *styles): pass | 
					
						
							|  |  |  |     def pop_style(self, n=1): pass | 
					
						
							|  |  |  |     def assert_line_data(self, flag=1): pass | 
					
						
							| 
									
										
										
										
											1995-10-06 15:31:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | class AbstractFormatter: | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |     """The standard formatter.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This implementation has demonstrated wide applicability to many writers, | 
					
						
							|  |  |  |     and may be used directly in most circumstances.  It has been used to | 
					
						
							|  |  |  |     implement a full-featured World Wide Web browser. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 16:19:23 +00:00
										 |  |  |     #  Space handling policy:  blank spaces at the boundary between elements | 
					
						
							|  |  |  |     #  are handled by the outermost context.  "Literal" data is not checked | 
					
						
							|  |  |  |     #  to determine context, so spaces in literal data are handled directly | 
					
						
							|  |  |  |     #  in all circumstances. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |     def __init__(self, writer): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.writer = writer            # Output device | 
					
						
							|  |  |  |         self.align = None               # Current alignment | 
					
						
							|  |  |  |         self.align_stack = []           # Alignment stack | 
					
						
							|  |  |  |         self.font_stack = []            # Font state | 
					
						
							|  |  |  |         self.margin_stack = []          # Margin state | 
					
						
							|  |  |  |         self.spacing = None             # Vertical spacing state | 
					
						
							|  |  |  |         self.style_stack = []           # Other state, e.g. color | 
					
						
							|  |  |  |         self.nospace = 1                # Should leading space be suppressed | 
					
						
							|  |  |  |         self.softspace = 0              # Should a space be inserted | 
					
						
							|  |  |  |         self.para_end = 1               # Just ended a paragraph | 
					
						
							|  |  |  |         self.parskip = 0                # Skipped space between paragraphs? | 
					
						
							|  |  |  |         self.hard_break = 1             # Have a hard break | 
					
						
							|  |  |  |         self.have_label = 0 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def end_paragraph(self, blankline): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if not self.hard_break: | 
					
						
							|  |  |  |             self.writer.send_line_break() | 
					
						
							|  |  |  |             self.have_label = 0 | 
					
						
							|  |  |  |         if self.parskip < blankline and not self.have_label: | 
					
						
							|  |  |  |             self.writer.send_paragraph(blankline - self.parskip) | 
					
						
							|  |  |  |             self.parskip = blankline | 
					
						
							|  |  |  |             self.have_label = 0 | 
					
						
							|  |  |  |         self.hard_break = self.nospace = self.para_end = 1 | 
					
						
							|  |  |  |         self.softspace = 0 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def add_line_break(self): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if not (self.hard_break or self.para_end): | 
					
						
							|  |  |  |             self.writer.send_line_break() | 
					
						
							|  |  |  |             self.have_label = self.parskip = 0 | 
					
						
							|  |  |  |         self.hard_break = self.nospace = 1 | 
					
						
							|  |  |  |         self.softspace = 0 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def add_hor_rule(self, *args, **kw): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if not self.hard_break: | 
					
						
							|  |  |  |             self.writer.send_line_break() | 
					
						
							| 
									
										
										
										
											2003-02-27 20:14:51 +00:00
										 |  |  |         self.writer.send_hor_rule(*args, **kw) | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.hard_break = self.nospace = 1 | 
					
						
							|  |  |  |         self.have_label = self.para_end = self.softspace = self.parskip = 0 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def add_label_data(self, format, counter, blankline = None): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if self.have_label or not self.hard_break: | 
					
						
							|  |  |  |             self.writer.send_line_break() | 
					
						
							|  |  |  |         if not self.para_end: | 
					
						
							|  |  |  |             self.writer.send_paragraph((blankline and 1) or 0) | 
					
						
							| 
									
										
										
											
												Remove uses of the string and types modules:
x in string.whitespace => x.isspace()
type(x) in types.StringTypes => isinstance(x, basestring)
isinstance(x, types.StringTypes) => isinstance(x, basestring)
type(x) is types.StringType => isinstance(x, str)
type(x) == types.StringType => isinstance(x, str)
string.split(x, ...) => x.split(...)
string.join(x, y) => y.join(x)
string.zfill(x, ...) => x.zfill(...)
string.count(x, ...) => x.count(...)
hasattr(types, "UnicodeType") => try: unicode except NameError:
type(x) != types.TupleTuple => not isinstance(x, tuple)
isinstance(x, types.TupleType) => isinstance(x, tuple)
type(x) is types.IntType => isinstance(x, int)
Do not mention the string module in the rlcompleter docstring.
This partially applies SF patch http://www.python.org/sf/562373
(with basestring instead of string). (It excludes the changes to
unittest.py and does not change the os.stat stuff.)
											
										 
											2002-06-03 15:58:32 +00:00
										 |  |  |         if isinstance(format, str): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             self.writer.send_label_data(self.format_counter(format, counter)) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.writer.send_label_data(format) | 
					
						
							|  |  |  |         self.nospace = self.have_label = self.hard_break = self.para_end = 1 | 
					
						
							|  |  |  |         self.softspace = self.parskip = 0 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def format_counter(self, format, counter): | 
					
						
							|  |  |  |         label = '' | 
					
						
							|  |  |  |         for c in format: | 
					
						
							| 
									
										
										
										
											2001-05-11 19:25:08 +00:00
										 |  |  |             if c == '1': | 
					
						
							|  |  |  |                 label = label + ('%d' % counter) | 
					
						
							|  |  |  |             elif c in 'aA': | 
					
						
							|  |  |  |                 if counter > 0: | 
					
						
							|  |  |  |                     label = label + self.format_letter(c, counter) | 
					
						
							|  |  |  |             elif c in 'iI': | 
					
						
							|  |  |  |                 if counter > 0: | 
					
						
							|  |  |  |                     label = label + self.format_roman(c, counter) | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |                 label = label + c | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |         return label | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def format_letter(self, case, counter): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         label = '' | 
					
						
							|  |  |  |         while counter > 0: | 
					
						
							|  |  |  |             counter, x = divmod(counter-1, 26) | 
					
						
							| 
									
										
										
										
											2001-05-11 19:25:08 +00:00
										 |  |  |             # This makes a strong assumption that lowercase letters | 
					
						
							|  |  |  |             # and uppercase letters form two contiguous blocks, with | 
					
						
							|  |  |  |             # letters in order! | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             s = chr(ord(case) + x) | 
					
						
							|  |  |  |             label = s + label | 
					
						
							|  |  |  |         return label | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def format_roman(self, case, counter): | 
					
						
							|  |  |  |         ones = ['i', 'x', 'c', 'm'] | 
					
						
							|  |  |  |         fives = ['v', 'l', 'd'] | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |         label, index = '', 0 | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         # This will die of IndexError when counter is too big | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |         while counter > 0: | 
					
						
							|  |  |  |             counter, x = divmod(counter, 10) | 
					
						
							|  |  |  |             if x == 9: | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |                 label = ones[index] + ones[index+1] + label | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |             elif x == 4: | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |                 label = ones[index] + fives[index] + label | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 if x >= 5: | 
					
						
							|  |  |  |                     s = fives[index] | 
					
						
							|  |  |  |                     x = x-5 | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     s = '' | 
					
						
							|  |  |  |                 s = s + ones[index]*x | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |                 label = s + label | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |             index = index + 1 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |         if case == 'I': | 
					
						
							| 
									
										
										
										
											2001-02-09 11:10:16 +00:00
										 |  |  |             return label.upper() | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |         return label | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Remove uses of the string and types modules:
x in string.whitespace => x.isspace()
type(x) in types.StringTypes => isinstance(x, basestring)
isinstance(x, types.StringTypes) => isinstance(x, basestring)
type(x) is types.StringType => isinstance(x, str)
type(x) == types.StringType => isinstance(x, str)
string.split(x, ...) => x.split(...)
string.join(x, y) => y.join(x)
string.zfill(x, ...) => x.zfill(...)
string.count(x, ...) => x.count(...)
hasattr(types, "UnicodeType") => try: unicode except NameError:
type(x) != types.TupleTuple => not isinstance(x, tuple)
isinstance(x, types.TupleType) => isinstance(x, tuple)
type(x) is types.IntType => isinstance(x, int)
Do not mention the string module in the rlcompleter docstring.
This partially applies SF patch http://www.python.org/sf/562373
(with basestring instead of string). (It excludes the changes to
unittest.py and does not change the os.stat stuff.)
											
										 
											2002-06-03 15:58:32 +00:00
										 |  |  |     def add_flowing_data(self, data): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if not data: return | 
					
						
							| 
									
										
										
											
												Remove uses of the string and types modules:
x in string.whitespace => x.isspace()
type(x) in types.StringTypes => isinstance(x, basestring)
isinstance(x, types.StringTypes) => isinstance(x, basestring)
type(x) is types.StringType => isinstance(x, str)
type(x) == types.StringType => isinstance(x, str)
string.split(x, ...) => x.split(...)
string.join(x, y) => y.join(x)
string.zfill(x, ...) => x.zfill(...)
string.count(x, ...) => x.count(...)
hasattr(types, "UnicodeType") => try: unicode except NameError:
type(x) != types.TupleTuple => not isinstance(x, tuple)
isinstance(x, types.TupleType) => isinstance(x, tuple)
type(x) is types.IntType => isinstance(x, int)
Do not mention the string module in the rlcompleter docstring.
This partially applies SF patch http://www.python.org/sf/562373
(with basestring instead of string). (It excludes the changes to
unittest.py and does not change the os.stat stuff.)
											
										 
											2002-06-03 15:58:32 +00:00
										 |  |  |         prespace = data[:1].isspace() | 
					
						
							|  |  |  |         postspace = data[-1:].isspace() | 
					
						
							|  |  |  |         data = " ".join(data.split()) | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if self.nospace and not data: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         elif prespace or self.softspace: | 
					
						
							|  |  |  |             if not data: | 
					
						
							|  |  |  |                 if not self.nospace: | 
					
						
							|  |  |  |                     self.softspace = 1 | 
					
						
							|  |  |  |                     self.parskip = 0 | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             if not self.nospace: | 
					
						
							|  |  |  |                 data = ' ' + data | 
					
						
							|  |  |  |         self.hard_break = self.nospace = self.para_end = \ | 
					
						
							|  |  |  |                           self.parskip = self.have_label = 0 | 
					
						
							|  |  |  |         self.softspace = postspace | 
					
						
							|  |  |  |         self.writer.send_flowing_data(data) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def add_literal_data(self, data): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if not data: return | 
					
						
							|  |  |  |         if self.softspace: | 
					
						
							|  |  |  |             self.writer.send_flowing_data(" ") | 
					
						
							|  |  |  |         self.hard_break = data[-1:] == '\n' | 
					
						
							|  |  |  |         self.nospace = self.para_end = self.softspace = \ | 
					
						
							|  |  |  |                        self.parskip = self.have_label = 0 | 
					
						
							|  |  |  |         self.writer.send_literal_data(data) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-09-30 16:49:58 +00:00
										 |  |  |     def flush_softspace(self): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if self.softspace: | 
					
						
							|  |  |  |             self.hard_break = self.para_end = self.parskip = \ | 
					
						
							|  |  |  |                               self.have_label = self.softspace = 0 | 
					
						
							|  |  |  |             self.nospace = 1 | 
					
						
							|  |  |  |             self.writer.send_flowing_data(' ') | 
					
						
							| 
									
										
										
										
											1995-09-30 16:49:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def push_alignment(self, align): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if align and align != self.align: | 
					
						
							|  |  |  |             self.writer.new_alignment(align) | 
					
						
							|  |  |  |             self.align = align | 
					
						
							|  |  |  |             self.align_stack.append(align) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.align_stack.append(self.align) | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def pop_alignment(self): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if self.align_stack: | 
					
						
							|  |  |  |             del self.align_stack[-1] | 
					
						
							|  |  |  |         if self.align_stack: | 
					
						
							|  |  |  |             self.align = align = self.align_stack[-1] | 
					
						
							|  |  |  |             self.writer.new_alignment(align) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.align = None | 
					
						
							|  |  |  |             self.writer.new_alignment(None) | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-15 18:46:22 +00:00
										 |  |  |     def push_font(self, font): | 
					
						
							|  |  |  |         size, i, b, tt = font | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if self.softspace: | 
					
						
							|  |  |  |             self.hard_break = self.para_end = self.softspace = 0 | 
					
						
							|  |  |  |             self.nospace = 1 | 
					
						
							|  |  |  |             self.writer.send_flowing_data(' ') | 
					
						
							|  |  |  |         if self.font_stack: | 
					
						
							|  |  |  |             csize, ci, cb, ctt = self.font_stack[-1] | 
					
						
							|  |  |  |             if size is AS_IS: size = csize | 
					
						
							|  |  |  |             if i is AS_IS: i = ci | 
					
						
							|  |  |  |             if b is AS_IS: b = cb | 
					
						
							|  |  |  |             if tt is AS_IS: tt = ctt | 
					
						
							|  |  |  |         font = (size, i, b, tt) | 
					
						
							|  |  |  |         self.font_stack.append(font) | 
					
						
							|  |  |  |         self.writer.new_font(font) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def pop_font(self): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if self.font_stack: | 
					
						
							|  |  |  |             del self.font_stack[-1] | 
					
						
							|  |  |  |         if self.font_stack: | 
					
						
							|  |  |  |             font = self.font_stack[-1] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             font = None | 
					
						
							|  |  |  |         self.writer.new_font(font) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def push_margin(self, margin): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.margin_stack.append(margin) | 
					
						
							| 
									
										
										
										
											2008-09-09 19:31:25 +00:00
										 |  |  |         fstack = [m for m in self.margin_stack if m] | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if not margin and fstack: | 
					
						
							|  |  |  |             margin = fstack[-1] | 
					
						
							|  |  |  |         self.writer.new_margin(margin, len(fstack)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def pop_margin(self): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if self.margin_stack: | 
					
						
							|  |  |  |             del self.margin_stack[-1] | 
					
						
							| 
									
										
										
										
											2008-09-09 19:31:25 +00:00
										 |  |  |         fstack = [m for m in self.margin_stack if m] | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if fstack: | 
					
						
							|  |  |  |             margin = fstack[-1] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             margin = None | 
					
						
							|  |  |  |         self.writer.new_margin(margin, len(fstack)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def set_spacing(self, spacing): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.spacing = spacing | 
					
						
							|  |  |  |         self.writer.new_spacing(spacing) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def push_style(self, *styles): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if self.softspace: | 
					
						
							|  |  |  |             self.hard_break = self.para_end = self.softspace = 0 | 
					
						
							|  |  |  |             self.nospace = 1 | 
					
						
							|  |  |  |             self.writer.send_flowing_data(' ') | 
					
						
							|  |  |  |         for style in styles: | 
					
						
							|  |  |  |             self.style_stack.append(style) | 
					
						
							|  |  |  |         self.writer.new_styles(tuple(self.style_stack)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def pop_style(self, n=1): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         del self.style_stack[-n:] | 
					
						
							|  |  |  |         self.writer.new_styles(tuple(self.style_stack)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def assert_line_data(self, flag=1): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.nospace = self.hard_break = not flag | 
					
						
							|  |  |  |         self.para_end = self.parskip = self.have_label = 0 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NullWriter: | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |     """Minimal writer interface to use in testing & inheritance.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     A writer which only provides the interface definition; no actions are | 
					
						
							|  |  |  |     taken on any methods.  This should be the base class for all writers | 
					
						
							|  |  |  |     which do not need to inherit any implementation methods. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											1996-05-29 00:02:30 +00:00
										 |  |  |     def __init__(self): pass | 
					
						
							| 
									
										
										
										
											1996-12-31 20:50:51 +00:00
										 |  |  |     def flush(self): pass | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def new_alignment(self, align): pass | 
					
						
							|  |  |  |     def new_font(self, font): pass | 
					
						
							|  |  |  |     def new_margin(self, margin, level): pass | 
					
						
							|  |  |  |     def new_spacing(self, spacing): pass | 
					
						
							|  |  |  |     def new_styles(self, styles): pass | 
					
						
							|  |  |  |     def send_paragraph(self, blankline): pass | 
					
						
							|  |  |  |     def send_line_break(self): pass | 
					
						
							|  |  |  |     def send_hor_rule(self, *args, **kw): pass | 
					
						
							|  |  |  |     def send_label_data(self, data): pass | 
					
						
							|  |  |  |     def send_flowing_data(self, data): pass | 
					
						
							|  |  |  |     def send_literal_data(self, data): pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-29 00:02:30 +00:00
										 |  |  | class AbstractWriter(NullWriter): | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |     """A writer which can be used in debugging formatters, but not much else.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Each method simply announces itself by printing its name and | 
					
						
							|  |  |  |     arguments on standard output. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def new_alignment(self, align): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("new_alignment(%r)" % (align,)) | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |     def new_font(self, font): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("new_font(%r)" % (font,)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def new_margin(self, margin, level): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("new_margin(%r, %d)" % (margin, level)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def new_spacing(self, spacing): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("new_spacing(%r)" % (spacing,)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def new_styles(self, styles): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("new_styles(%r)" % (styles,)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_paragraph(self, blankline): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("send_paragraph(%r)" % (blankline,)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_line_break(self): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("send_line_break()") | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def send_hor_rule(self, *args, **kw): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("send_hor_rule()") | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_label_data(self, data): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("send_label_data(%r)" % (data,)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_flowing_data(self, data): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("send_flowing_data(%r)" % (data,)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_literal_data(self, data): | 
					
						
							| 
									
										
										
										
											2007-02-09 05:37:30 +00:00
										 |  |  |         print("send_literal_data(%r)" % (data,)) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-29 00:02:30 +00:00
										 |  |  | class DumbWriter(NullWriter): | 
					
						
							| 
									
										
										
										
											2002-05-29 16:18:42 +00:00
										 |  |  |     """Simple writer class which writes output on the file object passed in
 | 
					
						
							|  |  |  |     as the file parameter or, if file is omitted, on standard output.  The | 
					
						
							|  |  |  |     output is simply word-wrapped to the number of columns specified by | 
					
						
							|  |  |  |     the maxcol parameter.  This class is suitable for reflowing a sequence | 
					
						
							|  |  |  |     of paragraphs. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, file=None, maxcol=72): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.file = file or sys.stdout | 
					
						
							|  |  |  |         self.maxcol = maxcol | 
					
						
							|  |  |  |         NullWriter.__init__(self) | 
					
						
							|  |  |  |         self.reset() | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def reset(self): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.col = 0 | 
					
						
							|  |  |  |         self.atbreak = 0 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_paragraph(self, blankline): | 
					
						
							| 
									
										
										
										
											1999-01-12 18:13:27 +00:00
										 |  |  |         self.file.write('\n'*blankline) | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.col = 0 | 
					
						
							|  |  |  |         self.atbreak = 0 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_line_break(self): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.file.write('\n') | 
					
						
							|  |  |  |         self.col = 0 | 
					
						
							|  |  |  |         self.atbreak = 0 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-05-28 23:50:49 +00:00
										 |  |  |     def send_hor_rule(self, *args, **kw): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.file.write('\n') | 
					
						
							|  |  |  |         self.file.write('-'*self.maxcol) | 
					
						
							|  |  |  |         self.file.write('\n') | 
					
						
							|  |  |  |         self.col = 0 | 
					
						
							|  |  |  |         self.atbreak = 0 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_literal_data(self, data): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.file.write(data) | 
					
						
							| 
									
										
										
										
											2001-02-09 11:10:16 +00:00
										 |  |  |         i = data.rfind('\n') | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if i >= 0: | 
					
						
							|  |  |  |             self.col = 0 | 
					
						
							|  |  |  |             data = data[i+1:] | 
					
						
							| 
									
										
										
										
											2001-02-09 11:10:16 +00:00
										 |  |  |         data = data.expandtabs() | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         self.col = self.col + len(data) | 
					
						
							|  |  |  |         self.atbreak = 0 | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def send_flowing_data(self, data): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         if not data: return | 
					
						
							| 
									
										
										
											
												Remove uses of the string and types modules:
x in string.whitespace => x.isspace()
type(x) in types.StringTypes => isinstance(x, basestring)
isinstance(x, types.StringTypes) => isinstance(x, basestring)
type(x) is types.StringType => isinstance(x, str)
type(x) == types.StringType => isinstance(x, str)
string.split(x, ...) => x.split(...)
string.join(x, y) => y.join(x)
string.zfill(x, ...) => x.zfill(...)
string.count(x, ...) => x.count(...)
hasattr(types, "UnicodeType") => try: unicode except NameError:
type(x) != types.TupleTuple => not isinstance(x, tuple)
isinstance(x, types.TupleType) => isinstance(x, tuple)
type(x) is types.IntType => isinstance(x, int)
Do not mention the string module in the rlcompleter docstring.
This partially applies SF patch http://www.python.org/sf/562373
(with basestring instead of string). (It excludes the changes to
unittest.py and does not change the os.stat stuff.)
											
										 
											2002-06-03 15:58:32 +00:00
										 |  |  |         atbreak = self.atbreak or data[0].isspace() | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         col = self.col | 
					
						
							|  |  |  |         maxcol = self.maxcol | 
					
						
							|  |  |  |         write = self.file.write | 
					
						
							| 
									
										
										
										
											2001-02-09 11:10:16 +00:00
										 |  |  |         for word in data.split(): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |             if atbreak: | 
					
						
							|  |  |  |                 if col + len(word) >= maxcol: | 
					
						
							|  |  |  |                     write('\n') | 
					
						
							|  |  |  |                     col = 0 | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     write(' ') | 
					
						
							|  |  |  |                     col = col + 1 | 
					
						
							|  |  |  |             write(word) | 
					
						
							|  |  |  |             col = col + len(word) | 
					
						
							|  |  |  |             atbreak = 1 | 
					
						
							|  |  |  |         self.col = col | 
					
						
							| 
									
										
										
											
												Remove uses of the string and types modules:
x in string.whitespace => x.isspace()
type(x) in types.StringTypes => isinstance(x, basestring)
isinstance(x, types.StringTypes) => isinstance(x, basestring)
type(x) is types.StringType => isinstance(x, str)
type(x) == types.StringType => isinstance(x, str)
string.split(x, ...) => x.split(...)
string.join(x, y) => y.join(x)
string.zfill(x, ...) => x.zfill(...)
string.count(x, ...) => x.count(...)
hasattr(types, "UnicodeType") => try: unicode except NameError:
type(x) != types.TupleTuple => not isinstance(x, tuple)
isinstance(x, types.TupleType) => isinstance(x, tuple)
type(x) is types.IntType => isinstance(x, int)
Do not mention the string module in the rlcompleter docstring.
This partially applies SF patch http://www.python.org/sf/562373
(with basestring instead of string). (It excludes the changes to
unittest.py and does not change the os.stat stuff.)
											
										 
											2002-06-03 15:58:32 +00:00
										 |  |  |         self.atbreak = data[-1].isspace() | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test(file = None): | 
					
						
							|  |  |  |     w = DumbWriter() | 
					
						
							|  |  |  |     f = AbstractFormatter(w) | 
					
						
							| 
									
										
										
										
											2002-06-01 01:29:16 +00:00
										 |  |  |     if file is not None: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         fp = open(file) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |     elif sys.argv[1:]: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         fp = open(sys.argv[1]) | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         fp = sys.stdin | 
					
						
							| 
									
										
										
										
											2015-01-05 09:19:40 +02:00
										 |  |  |     try: | 
					
						
							|  |  |  |         for line in fp: | 
					
						
							|  |  |  |             if line == '\n': | 
					
						
							|  |  |  |                 f.end_paragraph(1) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 f.add_flowing_data(line) | 
					
						
							|  |  |  |     finally: | 
					
						
							|  |  |  |         if fp is not sys.stdin: | 
					
						
							|  |  |  |             fp.close() | 
					
						
							| 
									
										
										
										
											1995-08-07 20:07:36 +00:00
										 |  |  |     f.end_paragraph(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     test() |