"formatter" --- 通用格式化输出
******************************

3.4 版后已移除: 因为被使用的次数很少，此格式化模块已经被弃用了。

======================================================================

此模块支持两个接口定义，每个定义具有多个实现：*formatter* 接口和格式化
程序接口所需的 *writer* 接口。

格式化程序对象将格式化事件的抽象流转换为编写器对象上的特定输出事件。
格式化程序管理多个堆栈结构，以允许更改和还原编写器对象的各种属性;编写
器不需要能够处理相对更改或任何类型的“更改回来”操作。 可通过格式化程序
对象控制的特定编写器属性包括水平对齐方式、字体和左边距缩进。 提供了一
种机制，该机制还支持向编写器提供任意的非独占样式设置。 其他接口有助于
格式化不可逆的事件，例如段落分隔。

编写器对象封装设备接口。 支持抽象设备（如文件格式）以及物理设备。 提供
的实现都适用于抽象设备。 该接口提供了用于设置格式化程序对象管理的属性
以及将数据插入输出的机制。


格式化程序接口
==============

用于创建格式化程序的接口取决于要实例化的特定格式化程序类。 下面描述的
接口是所有格式化程序在初始化后必须支持的必需接口。

在模块级别定义一个数据元素：

formatter.AS_IS

   可以在传递给下面描述的``push_font()`` 方法的字体规范中使用的值，或
   作为任何其他 "push_property()``方法的新值使用。 推送 ``AS_IS" 值允
   许调用相应的``pop_property()`` 方法，而无需跟踪属性是否已更改。

为格式化程序实例对象定义了以下属性：

formatter.writer

   格式化程序与之交互的编写器实例。

formatter.end_paragraph(blanklines)

   关闭所有打开的段落，并在下一段之前至少插入*blanklines* （空白行 ）
   。

formatter.add_line_break()

   如果尚不存在硬换行符，请添加硬换行符。 这不会破坏逻辑段落。

formatter.add_hor_rule(*args, **kw)

   在输出中插入水平线。 如果当前段落中有数据，但逻辑段落未中断，则插入
   硬中断。 参数和关键字被传递给作者的 "send_line_break()" 方法。

formatter.add_flowing_data(data)

   提供应使用折叠空格设置格式的数据。在执行空格折叠时，也会考虑之前和
   连续调用 "add_flowing_data()" 的空格。 传递给此方法的数据应由输出设
   备进行自动换行。 请注意，由于需要依赖设备和字体信息，任何自动换行仍
   必须由编写器对象执行。

formatter.add_literal_data(data)

   提供应原封不动地传递给编写器的数据。空格（包括换行符和制表符）在
   *data* 的值中被认为是合法的。

formatter.add_label_data(format, counter)

   插入一个标签，该标签应放置在当前左边距的左侧。这应该用于构造项目符
   号列表或编号列表。 如果 *format* 值是字符串，则将其解释为 *counter*
   的格式规范，该规范应为整数。此格式设置的结果将成为标签的值;如果
   *format* 不是字符串，则直接用作标签值。标签值作为唯一的参数传递给编
   写器的 "send_label_data()" 方法。 非字符串标签值的解释取决于关联的
   编写器。

   格式规范是字符串，与计数器值结合使用，用于计算标签值。 格式字符串中
   的每个字符都将复制到标签值，并识别某些字符以指示计数器值上的转换。
   具体来说，字符``'1'`` 表示计数器值格式化程序为阿拉伯数字，字符
   ``'A'"和"'a'"分别表示计数器值的字母表示形式，大写和小写，"'I'`` 和
   ``'i'`` 表示罗马数字中的计数器值，大写和小写。 请注意，字母和罗马变
   换要求计数器值大于零。

formatter.flush_softspace()

   将从上一次调用 "add_flowing_data()" 缓冲的任何挂起空格发送到关联的
   编写器对象。 这应该在直接操作编写器对象之前调用。

formatter.push_alignment(align)

   将新的对齐设置推送到对齐堆栈上。 如果不需要更改，这可能是 "AS_IS"
   。 如果对齐值与以前的设置相比发生了更改，则使用 *align* 值调用编写
   器的 "new_alignment()" 方法。

formatter.pop_alignment()

   恢复以前的对齐方式。

formatter.push_font((size, italic, bold, teletype))

   更改编写器对象的部分或全部字体属性。未设置为 "AS_IS" 的属性设置为传
   入的值，而其他属性则保持其当前设置。编写器的 "new_font()" 方法是使
   用完全解析的字体规范调用的。

formatter.pop_font()

   恢复以前的字体。

formatter.push_margin(margin)

   将左边距缩进数增加 1，将逻辑标记 *margin* 与新缩进相关联。 初始保证
   金水平为 "0"。逻辑标记的更改值必须是真值;除 "AS_IS" 以外的 false 值
   不足以更改边距。

formatter.pop_margin()

   恢复以前的边距。

formatter.push_style(*styles)

   推送任意数量的任意样式规范。 所有样式都按顺序推送到样式堆栈上。 表
   示整个堆栈的元组（包括 "AS_IS" 值）将传递给编写器的 "new_styles()"
   方法。

formatter.pop_style(n=1)

   弹出传递给 "push_style()" 的最后一个 *n* 样式规范。 表示修订后的堆
   栈的元组（包括 "AS_IS" 值）将传递给编写器的 "new_styles()" 方法。

formatter.set_spacing(spacing)

   设置编写器的间距样式。

formatter.assert_line_data(flag=1)

   通知格式化程序数据已添加到带外当前段落。 当编写器被直接操作时，应使
   用此方法。 如果编写器操作在输出末尾生成了硬换行符，则可以将可选的
   *flag* 参数设置为 false。


实现格式化程序
==============

此模块提供了格式化程序对象的两种实现。大多数应用程序可以使用这些类之一
，而无需修改或子类化。

class formatter.NullFormatter(writer=None)

   什么都不做的格式化程序。 如果省略 *writer* ，则会创建一个
   "NullWriter" 实例。 编写器的任何方法都不会被 "NullFormatter" 实例调
   用。 如果实现编写器接口，则实现应从此类继承，但不需要继承任何实现。

class formatter.AbstractFormatter(writer)

   标准格式化程序。 此实现已证明对许多编写器具有广泛的适用性，并且在大
   多数情况下可以直接使用。 它已被用于实现功能齐全的万维网浏览器。


编写器界面
==========

用于创建编写器的接口取决于要实例化的特定编写器类。 下面描述的接口是所
有编写器初始化后必须支持的必需接口。请注意，虽然大多数应用程序可以使用
"AbstractFormatter" 类作为格式化程序，但编写器通常必须由应用程序提供。

writer.flush()

   刷新任何缓冲输出或设备控制事件。

writer.new_alignment(align)

   设置对齐样式。  *align* 值可以是任何对象，但按照惯例是字符串或
   "None"，其中 "None" 表示应使用编写器的“首选”对齐方式。常规的*对齐*
   值为 "'left'"、 "'center'"、"'right'" 和 "'justify'"。

writer.new_font(font)

   设置字体样式。 *font* 的值将为 "None"，表示应使用设备的默认字体或格
   式为 "(size, italic, bold, teletype)" 的元组。 大小将是一个字符串，
   指示应使用的字体大小;特定字符串及其解释必须由应用程序定义。
   *italic*、*bold* 和 *teletype* 值是布尔值，指定应使用哪些字体属性。

writer.new_margin(margin, level)

   将边距级别设置为整数 *level*，将逻辑标记设置为 *margin*。逻辑标签的
   解释由作者自行决定;对逻辑标记值的唯一限制是，对于 *level* 的非零值
   ，它不是假值。

writer.new_spacing(spacing)

   将间距样式设置为  *spacing*。

writer.new_styles(styles)

   设置其他样式。*styles* 值是任意值的元组;值 "AS_IS" 应忽略。*styles*
   元组可以解释为集合或堆栈，具体取决于应用程序和编写器实现的要求。

writer.send_line_break()

   断开当前行。

writer.send_paragraph(blankline)

   生成至少空白行 *blankline* 或等效行的段落分隔。*blankline* 值将是一
   个整数。 请注意，如果需要换行符，实现将在此调用之前收到对
   "send_line_break()" 的调用; 此方法不应包括结束段落的最后一行。它只
   负责段落之间的垂直间距。

writer.send_hor_rule(*args, **kw)

   在输出设备上显示水平线。 此方法的参数完全特定于应用程序和编写器，应
   谨慎解释。 该方法实现可能假定已通过 "send_line_break()" 发出换行符
   。

writer.send_flowing_data(data)

   输出字符数据，可以根据需要进行自动换行和重排。 在对此方法的任何调用
   序列中，编写器可能假定多个空格字符的范围已折叠为单个空格字符。

writer.send_literal_data(data)

   输出已格式化为显示的字符数据。 通常，这应解释为应保留由换行符指示的
   换行符，并且不应引入新的换行符。 数据可能包含嵌入的换行符和制表符，
   这与提供给 "send_formatted_data()" 接口的数据不同。

writer.send_label_data(data)

   如果可能，将  *data* 设置为当前左边距的左侧。 *data* 的值不受限制;
   非字符串值的处理完全取决于应用程序和编写器。 此方法仅在行首调用。


编写器实现
==========

本模块提供了编写器对象接口的三个实现作为示例。 大多数应用程序需要从
"NullWriter" 类派生新的编写器类。

class formatter.NullWriter

   仅提供接口定义的编写器;不会对任何方法执行任何操作。 这应该是不需要
   继承任何实现方法的所有编写器的基类。

class formatter.AbstractWriter

   一个可用于调试格式化程序的编写器，但不能用于其他很多。 每个方法只是
   通过在标准输出上打印其名称和参数来宣布自己。

class formatter.DumbWriter(file=None, maxcol=72)

   简单的编写器类，它将输出写入作为  *file* 传入的 *file object* ，或
   者，如果省略 *file* ，则写入标准输出。 输出只是自动换行为 *maxcol*
   指定的列数。 此类适用于重排段落序列。
