Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/AnonR/anonr.TX.../opt/imh-pyth.../lib/python3....
File: formatter.py
"""Generic output formatting.
[0] Fix | Delete
[1] Fix | Delete
Formatter objects transform an abstract flow of formatting events into
[2] Fix | Delete
specific output events on writer objects. Formatters manage several stack
[3] Fix | Delete
structures to allow various properties of a writer object to be changed and
[4] Fix | Delete
restored; writers need not be able to handle relative changes nor any sort
[5] Fix | Delete
of ``change back'' operation. Specific writer properties which may be
[6] Fix | Delete
controlled via formatter objects are horizontal alignment, font, and left
[7] Fix | Delete
margin indentations. A mechanism is provided which supports providing
[8] Fix | Delete
arbitrary, non-exclusive style settings to a writer as well. Additional
[9] Fix | Delete
interfaces facilitate formatting events which are not reversible, such as
[10] Fix | Delete
paragraph separation.
[11] Fix | Delete
[12] Fix | Delete
Writer objects encapsulate device interfaces. Abstract devices, such as
[13] Fix | Delete
file formats, are supported as well as physical devices. The provided
[14] Fix | Delete
implementations all work with abstract devices. The interface makes
[15] Fix | Delete
available mechanisms for setting the properties which formatter objects
[16] Fix | Delete
manage and inserting data into the output.
[17] Fix | Delete
"""
[18] Fix | Delete
[19] Fix | Delete
import sys
[20] Fix | Delete
import warnings
[21] Fix | Delete
warnings.warn('the formatter module is deprecated', DeprecationWarning,
[22] Fix | Delete
stacklevel=2)
[23] Fix | Delete
[24] Fix | Delete
[25] Fix | Delete
AS_IS = None
[26] Fix | Delete
[27] Fix | Delete
[28] Fix | Delete
class NullFormatter:
[29] Fix | Delete
"""A formatter which does nothing.
[30] Fix | Delete
[31] Fix | Delete
If the writer parameter is omitted, a NullWriter instance is created.
[32] Fix | Delete
No methods of the writer are called by NullFormatter instances.
[33] Fix | Delete
[34] Fix | Delete
Implementations should inherit from this class if implementing a writer
[35] Fix | Delete
interface but don't need to inherit any implementation.
[36] Fix | Delete
[37] Fix | Delete
"""
[38] Fix | Delete
[39] Fix | Delete
def __init__(self, writer=None):
[40] Fix | Delete
if writer is None:
[41] Fix | Delete
writer = NullWriter()
[42] Fix | Delete
self.writer = writer
[43] Fix | Delete
def end_paragraph(self, blankline): pass
[44] Fix | Delete
def add_line_break(self): pass
[45] Fix | Delete
def add_hor_rule(self, *args, **kw): pass
[46] Fix | Delete
def add_label_data(self, format, counter, blankline=None): pass
[47] Fix | Delete
def add_flowing_data(self, data): pass
[48] Fix | Delete
def add_literal_data(self, data): pass
[49] Fix | Delete
def flush_softspace(self): pass
[50] Fix | Delete
def push_alignment(self, align): pass
[51] Fix | Delete
def pop_alignment(self): pass
[52] Fix | Delete
def push_font(self, x): pass
[53] Fix | Delete
def pop_font(self): pass
[54] Fix | Delete
def push_margin(self, margin): pass
[55] Fix | Delete
def pop_margin(self): pass
[56] Fix | Delete
def set_spacing(self, spacing): pass
[57] Fix | Delete
def push_style(self, *styles): pass
[58] Fix | Delete
def pop_style(self, n=1): pass
[59] Fix | Delete
def assert_line_data(self, flag=1): pass
[60] Fix | Delete
[61] Fix | Delete
[62] Fix | Delete
class AbstractFormatter:
[63] Fix | Delete
"""The standard formatter.
[64] Fix | Delete
[65] Fix | Delete
This implementation has demonstrated wide applicability to many writers,
[66] Fix | Delete
and may be used directly in most circumstances. It has been used to
[67] Fix | Delete
implement a full-featured World Wide Web browser.
[68] Fix | Delete
[69] Fix | Delete
"""
[70] Fix | Delete
[71] Fix | Delete
# Space handling policy: blank spaces at the boundary between elements
[72] Fix | Delete
# are handled by the outermost context. "Literal" data is not checked
[73] Fix | Delete
# to determine context, so spaces in literal data are handled directly
[74] Fix | Delete
# in all circumstances.
[75] Fix | Delete
[76] Fix | Delete
def __init__(self, writer):
[77] Fix | Delete
self.writer = writer # Output device
[78] Fix | Delete
self.align = None # Current alignment
[79] Fix | Delete
self.align_stack = [] # Alignment stack
[80] Fix | Delete
self.font_stack = [] # Font state
[81] Fix | Delete
self.margin_stack = [] # Margin state
[82] Fix | Delete
self.spacing = None # Vertical spacing state
[83] Fix | Delete
self.style_stack = [] # Other state, e.g. color
[84] Fix | Delete
self.nospace = 1 # Should leading space be suppressed
[85] Fix | Delete
self.softspace = 0 # Should a space be inserted
[86] Fix | Delete
self.para_end = 1 # Just ended a paragraph
[87] Fix | Delete
self.parskip = 0 # Skipped space between paragraphs?
[88] Fix | Delete
self.hard_break = 1 # Have a hard break
[89] Fix | Delete
self.have_label = 0
[90] Fix | Delete
[91] Fix | Delete
def end_paragraph(self, blankline):
[92] Fix | Delete
if not self.hard_break:
[93] Fix | Delete
self.writer.send_line_break()
[94] Fix | Delete
self.have_label = 0
[95] Fix | Delete
if self.parskip < blankline and not self.have_label:
[96] Fix | Delete
self.writer.send_paragraph(blankline - self.parskip)
[97] Fix | Delete
self.parskip = blankline
[98] Fix | Delete
self.have_label = 0
[99] Fix | Delete
self.hard_break = self.nospace = self.para_end = 1
[100] Fix | Delete
self.softspace = 0
[101] Fix | Delete
[102] Fix | Delete
def add_line_break(self):
[103] Fix | Delete
if not (self.hard_break or self.para_end):
[104] Fix | Delete
self.writer.send_line_break()
[105] Fix | Delete
self.have_label = self.parskip = 0
[106] Fix | Delete
self.hard_break = self.nospace = 1
[107] Fix | Delete
self.softspace = 0
[108] Fix | Delete
[109] Fix | Delete
def add_hor_rule(self, *args, **kw):
[110] Fix | Delete
if not self.hard_break:
[111] Fix | Delete
self.writer.send_line_break()
[112] Fix | Delete
self.writer.send_hor_rule(*args, **kw)
[113] Fix | Delete
self.hard_break = self.nospace = 1
[114] Fix | Delete
self.have_label = self.para_end = self.softspace = self.parskip = 0
[115] Fix | Delete
[116] Fix | Delete
def add_label_data(self, format, counter, blankline = None):
[117] Fix | Delete
if self.have_label or not self.hard_break:
[118] Fix | Delete
self.writer.send_line_break()
[119] Fix | Delete
if not self.para_end:
[120] Fix | Delete
self.writer.send_paragraph((blankline and 1) or 0)
[121] Fix | Delete
if isinstance(format, str):
[122] Fix | Delete
self.writer.send_label_data(self.format_counter(format, counter))
[123] Fix | Delete
else:
[124] Fix | Delete
self.writer.send_label_data(format)
[125] Fix | Delete
self.nospace = self.have_label = self.hard_break = self.para_end = 1
[126] Fix | Delete
self.softspace = self.parskip = 0
[127] Fix | Delete
[128] Fix | Delete
def format_counter(self, format, counter):
[129] Fix | Delete
label = ''
[130] Fix | Delete
for c in format:
[131] Fix | Delete
if c == '1':
[132] Fix | Delete
label = label + ('%d' % counter)
[133] Fix | Delete
elif c in 'aA':
[134] Fix | Delete
if counter > 0:
[135] Fix | Delete
label = label + self.format_letter(c, counter)
[136] Fix | Delete
elif c in 'iI':
[137] Fix | Delete
if counter > 0:
[138] Fix | Delete
label = label + self.format_roman(c, counter)
[139] Fix | Delete
else:
[140] Fix | Delete
label = label + c
[141] Fix | Delete
return label
[142] Fix | Delete
[143] Fix | Delete
def format_letter(self, case, counter):
[144] Fix | Delete
label = ''
[145] Fix | Delete
while counter > 0:
[146] Fix | Delete
counter, x = divmod(counter-1, 26)
[147] Fix | Delete
# This makes a strong assumption that lowercase letters
[148] Fix | Delete
# and uppercase letters form two contiguous blocks, with
[149] Fix | Delete
# letters in order!
[150] Fix | Delete
s = chr(ord(case) + x)
[151] Fix | Delete
label = s + label
[152] Fix | Delete
return label
[153] Fix | Delete
[154] Fix | Delete
def format_roman(self, case, counter):
[155] Fix | Delete
ones = ['i', 'x', 'c', 'm']
[156] Fix | Delete
fives = ['v', 'l', 'd']
[157] Fix | Delete
label, index = '', 0
[158] Fix | Delete
# This will die of IndexError when counter is too big
[159] Fix | Delete
while counter > 0:
[160] Fix | Delete
counter, x = divmod(counter, 10)
[161] Fix | Delete
if x == 9:
[162] Fix | Delete
label = ones[index] + ones[index+1] + label
[163] Fix | Delete
elif x == 4:
[164] Fix | Delete
label = ones[index] + fives[index] + label
[165] Fix | Delete
else:
[166] Fix | Delete
if x >= 5:
[167] Fix | Delete
s = fives[index]
[168] Fix | Delete
x = x-5
[169] Fix | Delete
else:
[170] Fix | Delete
s = ''
[171] Fix | Delete
s = s + ones[index]*x
[172] Fix | Delete
label = s + label
[173] Fix | Delete
index = index + 1
[174] Fix | Delete
if case == 'I':
[175] Fix | Delete
return label.upper()
[176] Fix | Delete
return label
[177] Fix | Delete
[178] Fix | Delete
def add_flowing_data(self, data):
[179] Fix | Delete
if not data: return
[180] Fix | Delete
prespace = data[:1].isspace()
[181] Fix | Delete
postspace = data[-1:].isspace()
[182] Fix | Delete
data = " ".join(data.split())
[183] Fix | Delete
if self.nospace and not data:
[184] Fix | Delete
return
[185] Fix | Delete
elif prespace or self.softspace:
[186] Fix | Delete
if not data:
[187] Fix | Delete
if not self.nospace:
[188] Fix | Delete
self.softspace = 1
[189] Fix | Delete
self.parskip = 0
[190] Fix | Delete
return
[191] Fix | Delete
if not self.nospace:
[192] Fix | Delete
data = ' ' + data
[193] Fix | Delete
self.hard_break = self.nospace = self.para_end = \
[194] Fix | Delete
self.parskip = self.have_label = 0
[195] Fix | Delete
self.softspace = postspace
[196] Fix | Delete
self.writer.send_flowing_data(data)
[197] Fix | Delete
[198] Fix | Delete
def add_literal_data(self, data):
[199] Fix | Delete
if not data: return
[200] Fix | Delete
if self.softspace:
[201] Fix | Delete
self.writer.send_flowing_data(" ")
[202] Fix | Delete
self.hard_break = data[-1:] == '\n'
[203] Fix | Delete
self.nospace = self.para_end = self.softspace = \
[204] Fix | Delete
self.parskip = self.have_label = 0
[205] Fix | Delete
self.writer.send_literal_data(data)
[206] Fix | Delete
[207] Fix | Delete
def flush_softspace(self):
[208] Fix | Delete
if self.softspace:
[209] Fix | Delete
self.hard_break = self.para_end = self.parskip = \
[210] Fix | Delete
self.have_label = self.softspace = 0
[211] Fix | Delete
self.nospace = 1
[212] Fix | Delete
self.writer.send_flowing_data(' ')
[213] Fix | Delete
[214] Fix | Delete
def push_alignment(self, align):
[215] Fix | Delete
if align and align != self.align:
[216] Fix | Delete
self.writer.new_alignment(align)
[217] Fix | Delete
self.align = align
[218] Fix | Delete
self.align_stack.append(align)
[219] Fix | Delete
else:
[220] Fix | Delete
self.align_stack.append(self.align)
[221] Fix | Delete
[222] Fix | Delete
def pop_alignment(self):
[223] Fix | Delete
if self.align_stack:
[224] Fix | Delete
del self.align_stack[-1]
[225] Fix | Delete
if self.align_stack:
[226] Fix | Delete
self.align = align = self.align_stack[-1]
[227] Fix | Delete
self.writer.new_alignment(align)
[228] Fix | Delete
else:
[229] Fix | Delete
self.align = None
[230] Fix | Delete
self.writer.new_alignment(None)
[231] Fix | Delete
[232] Fix | Delete
def push_font(self, font):
[233] Fix | Delete
size, i, b, tt = font
[234] Fix | Delete
if self.softspace:
[235] Fix | Delete
self.hard_break = self.para_end = self.softspace = 0
[236] Fix | Delete
self.nospace = 1
[237] Fix | Delete
self.writer.send_flowing_data(' ')
[238] Fix | Delete
if self.font_stack:
[239] Fix | Delete
csize, ci, cb, ctt = self.font_stack[-1]
[240] Fix | Delete
if size is AS_IS: size = csize
[241] Fix | Delete
if i is AS_IS: i = ci
[242] Fix | Delete
if b is AS_IS: b = cb
[243] Fix | Delete
if tt is AS_IS: tt = ctt
[244] Fix | Delete
font = (size, i, b, tt)
[245] Fix | Delete
self.font_stack.append(font)
[246] Fix | Delete
self.writer.new_font(font)
[247] Fix | Delete
[248] Fix | Delete
def pop_font(self):
[249] Fix | Delete
if self.font_stack:
[250] Fix | Delete
del self.font_stack[-1]
[251] Fix | Delete
if self.font_stack:
[252] Fix | Delete
font = self.font_stack[-1]
[253] Fix | Delete
else:
[254] Fix | Delete
font = None
[255] Fix | Delete
self.writer.new_font(font)
[256] Fix | Delete
[257] Fix | Delete
def push_margin(self, margin):
[258] Fix | Delete
self.margin_stack.append(margin)
[259] Fix | Delete
fstack = [m for m in self.margin_stack if m]
[260] Fix | Delete
if not margin and fstack:
[261] Fix | Delete
margin = fstack[-1]
[262] Fix | Delete
self.writer.new_margin(margin, len(fstack))
[263] Fix | Delete
[264] Fix | Delete
def pop_margin(self):
[265] Fix | Delete
if self.margin_stack:
[266] Fix | Delete
del self.margin_stack[-1]
[267] Fix | Delete
fstack = [m for m in self.margin_stack if m]
[268] Fix | Delete
if fstack:
[269] Fix | Delete
margin = fstack[-1]
[270] Fix | Delete
else:
[271] Fix | Delete
margin = None
[272] Fix | Delete
self.writer.new_margin(margin, len(fstack))
[273] Fix | Delete
[274] Fix | Delete
def set_spacing(self, spacing):
[275] Fix | Delete
self.spacing = spacing
[276] Fix | Delete
self.writer.new_spacing(spacing)
[277] Fix | Delete
[278] Fix | Delete
def push_style(self, *styles):
[279] Fix | Delete
if self.softspace:
[280] Fix | Delete
self.hard_break = self.para_end = self.softspace = 0
[281] Fix | Delete
self.nospace = 1
[282] Fix | Delete
self.writer.send_flowing_data(' ')
[283] Fix | Delete
for style in styles:
[284] Fix | Delete
self.style_stack.append(style)
[285] Fix | Delete
self.writer.new_styles(tuple(self.style_stack))
[286] Fix | Delete
[287] Fix | Delete
def pop_style(self, n=1):
[288] Fix | Delete
del self.style_stack[-n:]
[289] Fix | Delete
self.writer.new_styles(tuple(self.style_stack))
[290] Fix | Delete
[291] Fix | Delete
def assert_line_data(self, flag=1):
[292] Fix | Delete
self.nospace = self.hard_break = not flag
[293] Fix | Delete
self.para_end = self.parskip = self.have_label = 0
[294] Fix | Delete
[295] Fix | Delete
[296] Fix | Delete
class NullWriter:
[297] Fix | Delete
"""Minimal writer interface to use in testing & inheritance.
[298] Fix | Delete
[299] Fix | Delete
A writer which only provides the interface definition; no actions are
[300] Fix | Delete
taken on any methods. This should be the base class for all writers
[301] Fix | Delete
which do not need to inherit any implementation methods.
[302] Fix | Delete
[303] Fix | Delete
"""
[304] Fix | Delete
def __init__(self): pass
[305] Fix | Delete
def flush(self): pass
[306] Fix | Delete
def new_alignment(self, align): pass
[307] Fix | Delete
def new_font(self, font): pass
[308] Fix | Delete
def new_margin(self, margin, level): pass
[309] Fix | Delete
def new_spacing(self, spacing): pass
[310] Fix | Delete
def new_styles(self, styles): pass
[311] Fix | Delete
def send_paragraph(self, blankline): pass
[312] Fix | Delete
def send_line_break(self): pass
[313] Fix | Delete
def send_hor_rule(self, *args, **kw): pass
[314] Fix | Delete
def send_label_data(self, data): pass
[315] Fix | Delete
def send_flowing_data(self, data): pass
[316] Fix | Delete
def send_literal_data(self, data): pass
[317] Fix | Delete
[318] Fix | Delete
[319] Fix | Delete
class AbstractWriter(NullWriter):
[320] Fix | Delete
"""A writer which can be used in debugging formatters, but not much else.
[321] Fix | Delete
[322] Fix | Delete
Each method simply announces itself by printing its name and
[323] Fix | Delete
arguments on standard output.
[324] Fix | Delete
[325] Fix | Delete
"""
[326] Fix | Delete
[327] Fix | Delete
def new_alignment(self, align):
[328] Fix | Delete
print("new_alignment(%r)" % (align,))
[329] Fix | Delete
[330] Fix | Delete
def new_font(self, font):
[331] Fix | Delete
print("new_font(%r)" % (font,))
[332] Fix | Delete
[333] Fix | Delete
def new_margin(self, margin, level):
[334] Fix | Delete
print("new_margin(%r, %d)" % (margin, level))
[335] Fix | Delete
[336] Fix | Delete
def new_spacing(self, spacing):
[337] Fix | Delete
print("new_spacing(%r)" % (spacing,))
[338] Fix | Delete
[339] Fix | Delete
def new_styles(self, styles):
[340] Fix | Delete
print("new_styles(%r)" % (styles,))
[341] Fix | Delete
[342] Fix | Delete
def send_paragraph(self, blankline):
[343] Fix | Delete
print("send_paragraph(%r)" % (blankline,))
[344] Fix | Delete
[345] Fix | Delete
def send_line_break(self):
[346] Fix | Delete
print("send_line_break()")
[347] Fix | Delete
[348] Fix | Delete
def send_hor_rule(self, *args, **kw):
[349] Fix | Delete
print("send_hor_rule()")
[350] Fix | Delete
[351] Fix | Delete
def send_label_data(self, data):
[352] Fix | Delete
print("send_label_data(%r)" % (data,))
[353] Fix | Delete
[354] Fix | Delete
def send_flowing_data(self, data):
[355] Fix | Delete
print("send_flowing_data(%r)" % (data,))
[356] Fix | Delete
[357] Fix | Delete
def send_literal_data(self, data):
[358] Fix | Delete
print("send_literal_data(%r)" % (data,))
[359] Fix | Delete
[360] Fix | Delete
[361] Fix | Delete
class DumbWriter(NullWriter):
[362] Fix | Delete
"""Simple writer class which writes output on the file object passed in
[363] Fix | Delete
as the file parameter or, if file is omitted, on standard output. The
[364] Fix | Delete
output is simply word-wrapped to the number of columns specified by
[365] Fix | Delete
the maxcol parameter. This class is suitable for reflowing a sequence
[366] Fix | Delete
of paragraphs.
[367] Fix | Delete
[368] Fix | Delete
"""
[369] Fix | Delete
[370] Fix | Delete
def __init__(self, file=None, maxcol=72):
[371] Fix | Delete
self.file = file or sys.stdout
[372] Fix | Delete
self.maxcol = maxcol
[373] Fix | Delete
NullWriter.__init__(self)
[374] Fix | Delete
self.reset()
[375] Fix | Delete
[376] Fix | Delete
def reset(self):
[377] Fix | Delete
self.col = 0
[378] Fix | Delete
self.atbreak = 0
[379] Fix | Delete
[380] Fix | Delete
def send_paragraph(self, blankline):
[381] Fix | Delete
self.file.write('\n'*blankline)
[382] Fix | Delete
self.col = 0
[383] Fix | Delete
self.atbreak = 0
[384] Fix | Delete
[385] Fix | Delete
def send_line_break(self):
[386] Fix | Delete
self.file.write('\n')
[387] Fix | Delete
self.col = 0
[388] Fix | Delete
self.atbreak = 0
[389] Fix | Delete
[390] Fix | Delete
def send_hor_rule(self, *args, **kw):
[391] Fix | Delete
self.file.write('\n')
[392] Fix | Delete
self.file.write('-'*self.maxcol)
[393] Fix | Delete
self.file.write('\n')
[394] Fix | Delete
self.col = 0
[395] Fix | Delete
self.atbreak = 0
[396] Fix | Delete
[397] Fix | Delete
def send_literal_data(self, data):
[398] Fix | Delete
self.file.write(data)
[399] Fix | Delete
i = data.rfind('\n')
[400] Fix | Delete
if i >= 0:
[401] Fix | Delete
self.col = 0
[402] Fix | Delete
data = data[i+1:]
[403] Fix | Delete
data = data.expandtabs()
[404] Fix | Delete
self.col = self.col + len(data)
[405] Fix | Delete
self.atbreak = 0
[406] Fix | Delete
[407] Fix | Delete
def send_flowing_data(self, data):
[408] Fix | Delete
if not data: return
[409] Fix | Delete
atbreak = self.atbreak or data[0].isspace()
[410] Fix | Delete
col = self.col
[411] Fix | Delete
maxcol = self.maxcol
[412] Fix | Delete
write = self.file.write
[413] Fix | Delete
for word in data.split():
[414] Fix | Delete
if atbreak:
[415] Fix | Delete
if col + len(word) >= maxcol:
[416] Fix | Delete
write('\n')
[417] Fix | Delete
col = 0
[418] Fix | Delete
else:
[419] Fix | Delete
write(' ')
[420] Fix | Delete
col = col + 1
[421] Fix | Delete
write(word)
[422] Fix | Delete
col = col + len(word)
[423] Fix | Delete
atbreak = 1
[424] Fix | Delete
self.col = col
[425] Fix | Delete
self.atbreak = data[-1].isspace()
[426] Fix | Delete
[427] Fix | Delete
[428] Fix | Delete
def test(file = None):
[429] Fix | Delete
w = DumbWriter()
[430] Fix | Delete
f = AbstractFormatter(w)
[431] Fix | Delete
if file is not None:
[432] Fix | Delete
fp = open(file)
[433] Fix | Delete
elif sys.argv[1:]:
[434] Fix | Delete
fp = open(sys.argv[1])
[435] Fix | Delete
else:
[436] Fix | Delete
fp = sys.stdin
[437] Fix | Delete
try:
[438] Fix | Delete
for line in fp:
[439] Fix | Delete
if line == '\n':
[440] Fix | Delete
f.end_paragraph(1)
[441] Fix | Delete
else:
[442] Fix | Delete
f.add_flowing_data(line)
[443] Fix | Delete
finally:
[444] Fix | Delete
if fp is not sys.stdin:
[445] Fix | Delete
fp.close()
[446] Fix | Delete
f.end_paragraph(0)
[447] Fix | Delete
[448] Fix | Delete
[449] Fix | Delete
if __name__ == '__main__':
[450] Fix | Delete
test()
[451] Fix | Delete
[452] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function