mailman  2.1.39
About: Mailman 2 - The GNU Mailing List Management System.
  Fossies Dox: mailman-2.1.39.tgz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

htmlformat.py
Go to the documentation of this file.
1# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
2#
3# This program is free software; you can redistribute it and/or
4# modify it under the terms of the GNU General Public License
5# as published by the Free Software Foundation; either version 2
6# of the License, or (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
16# USA.
17
18
19"""Library for program-based construction of an HTML documents.
20
21Encapsulate HTML formatting directives in classes that act as containers
22for python and, recursively, for nested HTML formatting objects.
23"""
24
25
26# Eventually could abstract down to HtmlItem, which outputs an arbitrary html
27# object given start / end tags, valid options, and a value. Ug, objects
28# shouldn't be adding their own newlines. The next object should.
29
30
31import types
32
33from Mailman import mm_cfg
34from Mailman import Utils
35from Mailman.i18n import _, get_translation
36
37from Mailman.CSRFcheck import csrf_token
38
39SPACE = ' '
40EMPTYSTRING = ''
41NL = '\n'
42
43
44
45# Format an arbitrary object.
46def HTMLFormatObject(item, indent):
47 "Return a presentation of an object, invoking their Format method if any."
48 if type(item) == type(''):
49 return item
50 elif not hasattr(item, "Format"):
51 return `item`
52 else:
53 return item.Format(indent)
54
56 result = {}
57 for (k,v) in d.items():
58 result[k.lower()] = v
59 return result
60
61# Given references to two dictionaries, copy the second dictionary into the
62# first one.
63def DictMerge(destination, fresh_dict):
64 for (key, value) in fresh_dict.items():
65 destination[key] = value
66
67class Table:
68 def __init__(self, **table_opts):
69 self.cells = []
70 self.cell_info = {}
71 self.row_info = {}
72 self.opts = table_opts
73
74 def AddOptions(self, opts):
75 DictMerge(self.opts, opts)
76
77 # Sets all of the cells. It writes over whatever cells you had there
78 # previously.
79
80 def SetAllCells(self, cells):
81 self.cells = cells
82
83 # Add a new blank row at the end
84 def NewRow(self):
85 self.cells.append([])
86
87 # Add a new blank cell at the end
88 def NewCell(self):
89 self.cells[-1].append('')
90
91 def AddRow(self, row):
92 self.cells.append(row)
93
94 def AddCell(self, cell):
95 self.cells[-1].append(cell)
96
97 def AddCellInfo(self, row, col, **kws):
99 if not self.cell_info.has_key(row):
100 self.cell_info[row] = { col : kws }
101 elif self.cell_info[row].has_key(col):
102 DictMerge(self.cell_info[row], kws)
103 else:
104 self.cell_info[row][col] = kws
105
106 def AddRowInfo(self, row, **kws):
107 kws = CaseInsensitiveKeyedDict(kws)
108 if not self.row_info.has_key(row):
109 self.row_info[row] = kws
110 else:
111 DictMerge(self.row_info[row], kws)
112
113 # What's the index for the row we just put in?
115 return len(self.cells)-1
116
117 # What's the index for the col we just put in?
119 return len(self.cells[-1])-1
120
121 def ExtractCellInfo(self, info):
122 valid_mods = ['align', 'valign', 'nowrap', 'rowspan', 'colspan',
123 'bgcolor']
124 output = ''
125
126 for (key, val) in info.items():
127 if not key in valid_mods:
128 continue
129 if key == 'nowrap':
130 output = output + ' NOWRAP'
131 continue
132 else:
133 output = output + ' %s="%s"' % (key.upper(), val)
134
135 return output
136
137 def ExtractRowInfo(self, info):
138 valid_mods = ['align', 'valign', 'bgcolor']
139 output = ''
140
141 for (key, val) in info.items():
142 if not key in valid_mods:
143 continue
144 output = output + ' %s="%s"' % (key.upper(), val)
145
146 return output
147
148 def ExtractTableInfo(self, info):
149 valid_mods = ['align', 'width', 'border', 'cellspacing', 'cellpadding',
150 'bgcolor']
151
152 output = ''
153
154 for (key, val) in info.items():
155 if not key in valid_mods:
156 continue
157 if key == 'border' and val == None:
158 output = output + ' BORDER'
159 continue
160 else:
161 output = output + ' %s="%s"' % (key.upper(), val)
162
163 return output
164
165 def FormatCell(self, row, col, indent):
166 try:
167 my_info = self.cell_info[row][col]
168 except:
169 my_info = None
170
171 output = '\n' + ' '*indent + '<td'
172 if my_info:
173 output = output + self.ExtractCellInfo(my_info)
174 item = self.cells[row][col]
175 item_format = HTMLFormatObject(item, indent+4)
176 output = '%s>%s</td>' % (output, item_format)
177 return output
178
179 def FormatRow(self, row, indent):
180 try:
181 my_info = self.row_info[row]
182 except:
183 my_info = None
184
185 output = '\n' + ' '*indent + '<tr'
186 if my_info:
187 output = output + self.ExtractRowInfo(my_info)
188 output = output + '>'
189
190 for i in range(len(self.cells[row])):
191 output = output + self.FormatCell(row, i, indent + 2)
192
193 output = output + '\n' + ' '*indent + '</tr>'
194
195 return output
196
197 def Format(self, indent=0):
198 output = '\n' + ' '*indent + '<table'
199 output = output + self.ExtractTableInfo(self.opts)
200 output = output + '>'
201
202 for i in range(len(self.cells)):
203 output = output + self.FormatRow(i, indent + 2)
204
205 output = output + '\n' + ' '*indent + '</table>\n'
206
207 return output
208
209
210class Link:
211 def __init__(self, href, text, target=None):
212 self.href = href
213 self.text = text
214 self.target = target
215
216 def Format(self, indent=0):
217 texpr = ""
218 if self.target != None:
219 texpr = ' target="%s"' % self.target
220 return '<a href="%s"%s>%s</a>' % (HTMLFormatObject(self.href, indent),
221 texpr,
222 HTMLFormatObject(self.text, indent))
223
225 """FontSize is being deprecated - use FontAttr(..., size="...") instead."""
226 def __init__(self, size, *items):
227 self.items = list(items)
228 self.size = size
229
230 def Format(self, indent=0):
231 output = '<font size="%s">' % self.size
232 for item in self.items:
233 output = output + HTMLFormatObject(item, indent)
234 output = output + '</font>'
235 return output
236
238 """Present arbitrary font attributes."""
239 def __init__(self, *items, **kw):
240 self.items = list(items)
241 self.attrs = kw
242
243 def Format(self, indent=0):
244 seq = []
245 for k, v in self.attrs.items():
246 seq.append('%s="%s"' % (k, v))
247 output = '<font %s>' % SPACE.join(seq)
248 for item in self.items:
249 output = output + HTMLFormatObject(item, indent)
250 output = output + '</font>'
251 return output
252
253
255 def __init__(self, *items):
256 if not items:
257 self.items = []
258 else:
259 self.items = items
260
261 def AddItem(self, obj):
262 self.items.append(obj)
263
264 def Format(self, indent=0):
265 output = []
266 for item in self.items:
267 output.append(HTMLFormatObject(item, indent))
268 return EMPTYSTRING.join(output)
269
270
272 align = 'right'
273
274 def __init__(self, *items):
275 Container.__init__(self, *items)
276
277 def Format(self, indent=0):
278 return ('<div align="%s">' % self.align) + \
279 Container.Format(self, indent) + \
280 '</div>'
281
282
283# My own standard document template. YMMV.
284# something more abstract would be more work to use...
285
287 title = None
288 language = None
289 bgcolor = mm_cfg.WEB_BG_COLOR
290 suppress_head = 0
291
292 def set_language(self, lang=None):
293 self.language = lang
294
295 def set_bgcolor(self, color):
296 self.bgcolor = color
297
298 def SetTitle(self, title):
299 self.title = title
300
301 def Format(self, indent=0, **kws):
302 charset = 'us-ascii'
303 if self.language and Utils.IsLanguage(self.language):
304 charset = Utils.GetCharSet(self.language)
305 output = ['Content-Type: text/html; charset=%s\n' % charset]
306 if not self.suppress_head:
307 kws.setdefault('bgcolor', self.bgcolor)
308 tab = ' ' * indent
309 output.extend([tab,
310 '<HTML>',
311 '<HEAD>'
312 ])
313 if mm_cfg.IMAGE_LOGOS:
314 output.append('<LINK REL="SHORTCUT ICON" HREF="%s">' %
315 (mm_cfg.IMAGE_LOGOS + mm_cfg.SHORTCUT_ICON))
316 # Hit all the bases
317 output.append('<META http-equiv="Content-Type" '
318 'content="text/html; charset=%s">' % charset)
319 if self.title:
320 output.append('%s<TITLE>%s</TITLE>' % (tab, self.title))
321 # Add CSS to visually hide some labeling text but allow screen
322 # readers to read it.
323 output.append("""\
324<style type="text/css">
325 div.hidden
326 {position:absolute;
327 left:-10000px;
328 top:auto;
329 width:1px;
330 height:1px;
331 overflow:hidden;}
332</style>
333""")
334 if mm_cfg.WEB_HEAD_ADD:
335 output.append(mm_cfg.WEB_HEAD_ADD)
336 output.append('%s</HEAD>' % tab)
337 quals = []
338 # Default link colors
339 if mm_cfg.WEB_VLINK_COLOR:
340 kws.setdefault('vlink', mm_cfg.WEB_VLINK_COLOR)
341 if mm_cfg.WEB_ALINK_COLOR:
342 kws.setdefault('alink', mm_cfg.WEB_ALINK_COLOR)
343 if mm_cfg.WEB_LINK_COLOR:
344 kws.setdefault('link', mm_cfg.WEB_LINK_COLOR)
345 for k, v in kws.items():
346 quals.append('%s="%s"' % (k, v))
347 output.append('%s<BODY %s' % (tab, SPACE.join(quals)))
348 # Language direction
349 direction = Utils.GetDirection(self.language)
350 output.append('dir="%s">' % direction)
351 # Always do this...
352 output.append(Container.Format(self, indent))
353 if not self.suppress_head:
354 output.append('%s</BODY>' % tab)
355 output.append('%s</HTML>' % tab)
356 return NL.join(output)
357
358 def addError(self, errmsg, tag=None):
359 if tag is None:
360 tag = _('Error: ')
361 self.AddItem(Header(3, Bold(FontAttr(
362 _(tag), color=mm_cfg.WEB_ERROR_COLOR, size='+2')).Format() +
363 Italic(errmsg).Format()))
364
365
367 """Document without head section, for templates that provide their own."""
368 suppress_head = 1
369
370
372 def Format(self, indent=0):
373 # If I don't start a new I ignore indent
374 output = '<%s>' % self.tag
375 output = output + Container.Format(self, indent)
376 output = '%s</%s>' % (output, self.tag)
377 return output
378
379
381 def Format(self, indent=0):
382 # If I don't start a new I ignore indent
383 output = '<%s>%s</%s>' % (
384 self.tag,
385 Utils.websafe(Container.Format(self, indent)),
386 self.tag)
387 return output
388
390 def __init__(self, num, *items):
391 self.itemsitems = items
392 self.tag = 'h%d' % num
393
395 tag = 'address'
396
398 tag = 'u'
399
401 tag = 'strong'
402
404 tag = 'em'
405
407 tag = 'pre'
408
410 tag = 'sub'
411
413 tag = 'sup'
414
416 tag = 'strike'
417
419 tag = 'center'
420
422 def __init__(self, action='', method='POST', encoding=None,
423 mlist=None, contexts=None, user=None, *items):
424 apply(Container.__init__, (self,) + items)
425 self.action = action
426 self.method = method
427 self.encoding = encoding
428 self.mlist = mlist
429 self.contexts = contexts
430 self.user = user
431
432 def set_action(self, action):
433 self.action = action
434
435 def Format(self, indent=0):
436 spaces = ' ' * indent
437 encoding = ''
438 if self.encoding:
439 encoding = 'enctype="%s"' % self.encoding
440 output = '\n%s<FORM action="%s" method="%s" %s>\n' % (
441 spaces, self.action, self.method, encoding)
442 if self.mlist:
443 output = output + \
444 '<input type="hidden" name="csrf_token" value="%s">\n' \
445 % csrf_token(self.mlist, self.contexts, self.user)
446 output = output + Container.Format(self, indent+2)
447 output = '%s\n%s</FORM>\n' % (output, spaces)
448 return output
449
450
452 def __init__(self, name, ty, value, checked, **kws):
453 self.name = name
454 self.type = ty
455 self.value = value
456 self.checked = checked
457 self.kws = kws
458
459 def Format(self, indent=0):
460 charset = get_translation().charset() or 'us-ascii'
461 output = ['<INPUT name="%s" type="%s" value="%s"' %
462 (self.name, self.type, self.value)]
463 for item in self.kws.items():
464 output.append('%s="%s"' % item)
465 if self.checked:
466 output.append('CHECKED')
467 output.append('>')
468 ret = SPACE.join(output)
469 if self.type == 'TEXT' and isinstance(ret, unicode):
470 ret = ret.encode(charset, 'xmlcharrefreplace')
471 return ret
472
473
475 def __init__(self, name, button_text):
476 InputObj.__init__(self, name, "SUBMIT", button_text, checked=0)
477
479 def __init__(self, name, value='', size=mm_cfg.TEXTFIELDWIDTH):
480 InputObj.__init__(self, name, "PASSWORD", value, checked=0, size=size)
481
483 def __init__(self, name, value='', size=mm_cfg.TEXTFIELDWIDTH):
484 if isinstance(value, str):
485 safevalue = Utils.websafe(value)
486 else:
487 safevalue = value
488 InputObj.__init__(self, name, "TEXT", safevalue, checked=0, size=size)
489
491 def __init__(self, name, value=''):
492 InputObj.__init__(self, name, 'HIDDEN', value, checked=0)
493
495 def __init__(self, name, text='', rows=None, cols=None, wrap='soft',
496 readonly=0):
497 if isinstance(text, str):
498 # Double escape HTML entities in non-readonly areas.
499 doubleescape = not readonly
500 safetext = Utils.websafe(text, doubleescape)
501 else:
502 safetext = text
503 self.name = name
504 self.text = safetext
505 self.rows = rows
506 self.cols = cols
507 self.wrap = wrap
508 self.readonly = readonly
509
510 def Format(self, indent=0):
511 charset = get_translation().charset() or 'us-ascii'
512 output = '<TEXTAREA NAME=%s' % self.name
513 if self.rows:
514 output += ' ROWS=%s' % self.rows
515 if self.cols:
516 output += ' COLS=%s' % self.cols
517 if self.wrap:
518 output += ' WRAP=%s' % self.wrap
519 if self.readonly:
520 output += ' READONLY'
521 output += '>%s</TEXTAREA>' % self.text
522 if isinstance(output, unicode):
523 output = output.encode(charset, 'xmlcharrefreplace')
524 return output
525
527 def __init__(self, name, rows=None, cols=None, **kws):
528 apply(InputObj.__init__, (self, name, 'FILE', '', 0), kws)
529
531 def __init__(self, name, value, checked=0, **kws):
532 apply(InputObj.__init__, (self, name, 'RADIO', value, checked), kws)
533
535 def __init__(self, name, value, checked=0, **kws):
536 apply(InputObj.__init__, (self, name, "CHECKBOX", value, checked), kws)
537
539 def __init__(self, size=10):
540 self.size = size
541 def Format(self, indent=0):
542 output = '<spacer type="vertical" height="%d">' % self.size
543 return output
544
546 Widget = None
547
548 def __init__(self, name, button_names, checked, horizontal, values):
549 self.name = name
550 self.button_names = button_names
551 self.checked = checked
552 self.horizontal = horizontal
553 self.values = values
554 assert len(values) == len(button_names)
555 # Don't assert `checked' because for RadioButtons it is a scalar while
556 # for CheckedBoxes it is a vector. Subclasses will assert length.
557
558 def ischecked(self, i):
559 raise NotImplemented
560
561 def Format(self, indent=0):
562 t = Table(cellspacing=5)
563 items = []
564 for i, name, value in zip(range(len(self.button_names)),
565 self.button_names,
566 self.values):
567 ischecked = (self.ischecked(i))
568 item = ('<label>' +
569 self.Widget(self.name, value, ischecked).Format() +
570 name + '</label>')
571 items.append(item)
572 if not self.horizontal:
573 t.AddRow(items)
574 items = []
575 if self.horizontal:
576 t.AddRow(items)
577 return t.Format(indent)
578
580 Widget = RadioButton
581
582 def __init__(self, name, button_names, checked=None, horizontal=1,
583 values=None):
584 if values is None:
585 values = range(len(button_names))
586 # BAW: assert checked is a scalar...
587 WidgetArray.__init__(self, name, button_names, checked, horizontal,
588 values)
589
590 def ischecked(self, i):
591 return self.checkedchecked == i
592
594 Widget = CheckBox
595
596 def __init__(self, name, button_names, checked=None, horizontal=0,
597 values=None):
598 if checked is None:
599 checked = [0] * len(button_names)
600 else:
601 assert len(checked) == len(button_names)
602 if values is None:
603 values = range(len(button_names))
604 WidgetArray.__init__(self, name, button_names, checked, horizontal,
605 values)
606
607 def ischecked(self, i):
608 return self.checked[i]
609
611 def Format(self, indent=0):
612 spaces = ' ' * indent
613 output = '\n%s<ul>\n' % spaces
614 for item in self.items:
615 output = output + '%s<li>%s\n' % \
616 (spaces, HTMLFormatObject(item, indent + 2))
617 output = output + '%s</ul>\n' % spaces
618 return output
619
621 def Format(self, indent=0):
622 spaces = ' ' * indent
623 output = '\n%s<ol>\n' % spaces
624 for item in self.items:
625 output = output + '%s<li>%s\n' % \
626 (spaces, HTMLFormatObject(item, indent + 2))
627 output = output + '%s</ol>\n' % spaces
628 return output
629
631 def Format(self, indent=0):
632 spaces = ' ' * indent
633 output = '\n%s<dl>\n' % spaces
634 for dt, dd in self.items:
635 output = output + '%s<dt>%s\n<dd>%s\n' % \
636 (spaces, HTMLFormatObject(dt, indent+2),
637 HTMLFormatObject(dd, indent+2))
638 output = output + '%s</dl>\n' % spaces
639 return output
640
641
642
643# Logo constants
644#
645# These are the URLs which the image logos link to. The Mailman home page now
646# points at the gnu.org site instead of the www.list.org mirror.
647#
648from mm_cfg import MAILMAN_URL
649PYTHON_URL = 'http://www.python.org/'
650GNU_URL = 'http://www.gnu.org/'
651
652# The names of the image logo files. These are concatentated onto
653# mm_cfg.IMAGE_LOGOS (not urljoined).
654DELIVERED_BY = 'mailman.jpg'
655PYTHON_POWERED = 'PythonPowered.png'
656GNU_HEAD = 'gnu-head-tiny.jpg'
657
658
660 t = Table(border=0, width='100%')
661 if mm_cfg.IMAGE_LOGOS:
662 def logo(file):
663 return mm_cfg.IMAGE_LOGOS + file
664 mmlink = '<img src="%s" alt="Delivered by Mailman" border=0>' \
665 '<br>version %s' % (logo(DELIVERED_BY), mm_cfg.VERSION)
666 pylink = '<img src="%s" alt="Python Powered" border=0>' % \
667 logo(PYTHON_POWERED)
668 gnulink = '<img src="%s" alt="GNU\'s Not Unix" border=0>' % \
669 logo(GNU_HEAD)
670 t.AddRow([mmlink, pylink, gnulink])
671 else:
672 # use only textual links
673 version = mm_cfg.VERSION
674 mmlink = Link(MAILMAN_URL,
675 _('Delivered by Mailman<br>version %(version)s'))
676 pylink = Link(PYTHON_URL, _('Python Powered'))
677 gnulink = Link(GNU_URL, _("Gnu's Not Unix"))
678 t.AddRow([mmlink, pylink, gnulink])
679 return t
680
681
683 def __init__(self, varname, values, legend,
684 selected=0, size=1, multiple=None):
685 self.varname = varname
686 self.values = values
687 self.legend = legend
688 self.size = size
689 self.multiple = multiple
690 # we convert any type to tuple, commas are needed
691 if not multiple:
692 if type(selected) == types.IntType:
693 self.selected = (selected,)
694 elif type(selected) == types.TupleType:
695 self.selected = (selected[0],)
696 elif type(selected) == types.ListType:
697 self.selected = (selected[0],)
698 else:
699 self.selected = (0,)
700
701 def Format(self, indent=0):
702 spaces = " " * indent
703 items = min( len(self.values), len(self.legend) )
704
705 # jcrey: If there is no argument, we return nothing to avoid errors
706 if items == 0:
707 return ""
708
709 text = "\n" + spaces + "<Select name=\"%s\"" % self.varname
710 if self.size > 1:
711 text = text + " size=%d" % self.size
712 if self.multiple:
713 text = text + " multiple"
714 text = text + ">\n"
715
716 for i in range(items):
717 if i in self.selected:
718 checked = " Selected"
719 else:
720 checked = ""
721
722 opt = " <option value=\"%s\"%s> %s </option>" % (
723 self.values[i], checked, self.legend[i])
724 text = text + spaces + opt + "\n"
725
726 return text + spaces + '</Select>'
def __init__(self, name, button_names, checked=None, horizontal=0, values=None)
Definition: htmlformat.py:597
def __init__(self, name, value, checked=0, **kws)
Definition: htmlformat.py:535
def Format(self, indent=0)
Definition: htmlformat.py:264
def __init__(self, *items)
Definition: htmlformat.py:255
def Format(self, indent=0)
Definition: htmlformat.py:631
def Format(self, indent=0, **kws)
Definition: htmlformat.py:301
def set_bgcolor(self, color)
Definition: htmlformat.py:295
def addError(self, errmsg, tag=None)
Definition: htmlformat.py:358
def set_language(self, lang=None)
Definition: htmlformat.py:292
def SetTitle(self, title)
Definition: htmlformat.py:298
def __init__(self, name, rows=None, cols=None, **kws)
Definition: htmlformat.py:527
def __init__(self, *items, **kw)
Definition: htmlformat.py:239
def Format(self, indent=0)
Definition: htmlformat.py:243
def Format(self, indent=0)
Definition: htmlformat.py:230
def __init__(self, size, *items)
Definition: htmlformat.py:226
def Format(self, indent=0)
Definition: htmlformat.py:435
def __init__(self, action='', method='POST', encoding=None, mlist=None, contexts=None, user=None, *items)
Definition: htmlformat.py:423
def set_action(self, action)
Definition: htmlformat.py:432
def __init__(self, num, *items)
Definition: htmlformat.py:390
def __init__(self, name, value='')
Definition: htmlformat.py:491
def Format(self, indent=0)
Definition: htmlformat.py:459
def __init__(self, name, ty, value, checked, **kws)
Definition: htmlformat.py:452
def __init__(self, *items)
Definition: htmlformat.py:274
def Format(self, indent=0)
Definition: htmlformat.py:277
def Format(self, indent=0)
Definition: htmlformat.py:621
def __init__(self, name, value='', size=mm_cfg.TEXTFIELDWIDTH)
Definition: htmlformat.py:479
def __init__(self, name, button_names, checked=None, horizontal=1, values=None)
Definition: htmlformat.py:583
def __init__(self, name, value, checked=0, **kws)
Definition: htmlformat.py:531
def __init__(self, varname, values, legend, selected=0, size=1, multiple=None)
Definition: htmlformat.py:684
def Format(self, indent=0)
Definition: htmlformat.py:701
def Format(self, indent=0)
Definition: htmlformat.py:372
def __init__(self, name, button_text)
Definition: htmlformat.py:475
def GetCurrentRowIndex(self)
Definition: htmlformat.py:114
def __init__(self, **table_opts)
Definition: htmlformat.py:68
def AddOptions(self, opts)
Definition: htmlformat.py:74
def FormatRow(self, row, indent)
Definition: htmlformat.py:179
def AddRow(self, row)
Definition: htmlformat.py:91
def GetCurrentCellIndex(self)
Definition: htmlformat.py:118
def AddRowInfo(self, row, **kws)
Definition: htmlformat.py:106
def ExtractCellInfo(self, info)
Definition: htmlformat.py:121
def AddCellInfo(self, row, col, **kws)
Definition: htmlformat.py:97
def FormatCell(self, row, col, indent)
Definition: htmlformat.py:165
def Format(self, indent=0)
Definition: htmlformat.py:197
def SetAllCells(self, cells)
Definition: htmlformat.py:80
def ExtractTableInfo(self, info)
Definition: htmlformat.py:148
def ExtractRowInfo(self, info)
Definition: htmlformat.py:137
def AddCell(self, cell)
Definition: htmlformat.py:94
def __init__(self, name, text='', rows=None, cols=None, wrap='soft', readonly=0)
Definition: htmlformat.py:496
def Format(self, indent=0)
Definition: htmlformat.py:510
def __init__(self, name, value='', size=mm_cfg.TEXTFIELDWIDTH)
Definition: htmlformat.py:483
def Format(self, indent=0)
Definition: htmlformat.py:611
def Format(self, indent=0)
Definition: htmlformat.py:541
def Format(self, indent=0)
Definition: htmlformat.py:561
def __init__(self, name, button_names, checked, horizontal, values)
Definition: htmlformat.py:548
def csrf_token(mlist, contexts, user=None)
Definition: CSRFcheck.py:39
def HTMLFormatObject(item, indent)
Definition: htmlformat.py:46
def CaseInsensitiveKeyedDict(d)
Definition: htmlformat.py:55
def DictMerge(destination, fresh_dict)
Definition: htmlformat.py:63
def get_translation()
Definition: i18n.py:55