cstrittmatter@0: #!/usr/bin/python cstrittmatter@0: # -*- coding: iso-8859-1 -*- cstrittmatter@0: """ cstrittmatter@0: HTML.py - v0.04 2009-07-28 Philippe Lagadec cstrittmatter@0: cstrittmatter@0: This module provides a few classes to easily generate HTML code such as tables cstrittmatter@0: and lists. cstrittmatter@0: cstrittmatter@0: Project website: http://www.decalage.info/python/html cstrittmatter@0: cstrittmatter@0: License: CeCILL (open-source GPL compatible), see source code for details. cstrittmatter@0: http://www.cecill.info cstrittmatter@0: """ cstrittmatter@0: cstrittmatter@0: __version__ = '0.04' cstrittmatter@0: __date__ = '2009-07-28' cstrittmatter@0: __author__ = 'Philippe Lagadec' cstrittmatter@0: cstrittmatter@0: #--- LICENSE ------------------------------------------------------------------ cstrittmatter@0: cstrittmatter@0: # Copyright Philippe Lagadec - see http://www.decalage.info/contact for contact info cstrittmatter@0: # cstrittmatter@0: # This module provides a few classes to easily generate HTML tables and lists. cstrittmatter@0: # cstrittmatter@0: # This software is governed by the CeCILL license under French law and cstrittmatter@0: # abiding by the rules of distribution of free software. You can use, cstrittmatter@0: # modify and/or redistribute the software under the terms of the CeCILL cstrittmatter@0: # license as circulated by CEA, CNRS and INRIA at the following URL cstrittmatter@0: # "http://www.cecill.info". cstrittmatter@0: # cstrittmatter@0: # A copy of the CeCILL license is also provided in these attached files: cstrittmatter@0: # Licence_CeCILL_V2-en.html and Licence_CeCILL_V2-fr.html cstrittmatter@0: # cstrittmatter@0: # As a counterpart to the access to the source code and rights to copy, cstrittmatter@0: # modify and redistribute granted by the license, users are provided only cstrittmatter@0: # with a limited warranty and the software's author, the holder of the cstrittmatter@0: # economic rights, and the successive licensors have only limited cstrittmatter@0: # liability. cstrittmatter@0: # cstrittmatter@0: # In this respect, the user's attention is drawn to the risks associated cstrittmatter@0: # with loading, using, modifying and/or developing or reproducing the cstrittmatter@0: # software by the user in light of its specific status of free software, cstrittmatter@0: # that may mean that it is complicated to manipulate, and that also cstrittmatter@0: # therefore means that it is reserved for developers and experienced cstrittmatter@0: # professionals having in-depth computer knowledge. Users are therefore cstrittmatter@0: # encouraged to load and test the software's suitability as regards their cstrittmatter@0: # requirements in conditions enabling the security of their systems and/or cstrittmatter@0: # data to be ensured and, more generally, to use and operate it in the cstrittmatter@0: # same conditions as regards security. cstrittmatter@0: # cstrittmatter@0: # The fact that you are presently reading this means that you have had cstrittmatter@0: # knowledge of the CeCILL license and that you accept its terms. cstrittmatter@0: cstrittmatter@0: #--- THANKS -------------------------------------------------------------------- cstrittmatter@0: cstrittmatter@0: # - Michal Cernoevic, for the idea of column styles. cstrittmatter@0: cstrittmatter@0: #--- REFERENCES ---------------------------------------------------------------- cstrittmatter@0: cstrittmatter@0: # HTML 4.01 specs: http://www.w3.org/TR/html4/struct/tables.html cstrittmatter@0: cstrittmatter@0: # Colors: http://www.w3.org/TR/html4/types.html#type-color cstrittmatter@0: cstrittmatter@0: # Columns alignement and style, one of the oldest and trickiest bugs in Mozilla: cstrittmatter@0: # https://bugzilla.mozilla.org/show_bug.cgi?id=915 cstrittmatter@0: cstrittmatter@0: cstrittmatter@0: #--- CONSTANTS ----------------------------------------------------------------- cstrittmatter@0: cstrittmatter@0: # Table style to get thin black lines in Mozilla/Firefox instead of 3D borders cstrittmatter@0: #TABLE_STYLE_THINBORDER = "border: 1px solid #000000; border-collapse: collapse;" cstrittmatter@0: #TABLE_STYLE_THINBORDER = "border: 1px solid #000000;" cstrittmatter@0: cstrittmatter@0: cstrittmatter@0: #=== CLASSES =================================================================== cstrittmatter@0: cstrittmatter@0: class TableCell (object): cstrittmatter@0: """ cstrittmatter@0: a TableCell object is used to create a cell in a HTML table. (TD or TH) cstrittmatter@0: cstrittmatter@0: Attributes: cstrittmatter@0: - text: text in the cell (may contain HTML tags). May be any object which cstrittmatter@0: can be converted to a string using str(). cstrittmatter@0: - header: bool, false for a normal data cell (TD), true for a header cell (TH) cstrittmatter@0: - bgcolor: str, background color cstrittmatter@0: - width: str, width cstrittmatter@0: - align: str, horizontal alignement (left, center, right, justify or char) cstrittmatter@0: - char: str, alignment character, decimal point if not specified cstrittmatter@0: - charoff: str, see HTML specs cstrittmatter@0: - valign: str, vertical alignment (top|middle|bottom|baseline) cstrittmatter@0: - style: str, CSS style cstrittmatter@0: - attribs: dict, additional attributes for the TD/TH tag cstrittmatter@0: cstrittmatter@0: Reference: http://www.w3.org/TR/html4/struct/tables.html#h-11.2.6 cstrittmatter@0: """ cstrittmatter@0: cstrittmatter@0: def __init__(self, text="", bgcolor=None, header=False, width=None, cstrittmatter@0: align=None, char=None, charoff=None, valign=None, style=None, cstrittmatter@0: attribs=None): cstrittmatter@0: """TableCell constructor""" cstrittmatter@0: self.text = text cstrittmatter@0: self.bgcolor = bgcolor cstrittmatter@0: self.header = header cstrittmatter@0: self.width = width cstrittmatter@0: self.align = align cstrittmatter@0: self.char = char cstrittmatter@0: self.charoff = charoff cstrittmatter@0: self.valign = valign cstrittmatter@0: self.style = style cstrittmatter@0: self.attribs = attribs cstrittmatter@0: if attribs==None: cstrittmatter@0: self.attribs = {} cstrittmatter@0: cstrittmatter@0: def __str__(self): cstrittmatter@0: """return the HTML code for the table cell as a string""" cstrittmatter@0: attribs_str = "" cstrittmatter@0: if self.bgcolor: self.attribs['bgcolor'] = self.bgcolor cstrittmatter@0: if self.width: self.attribs['width'] = self.width cstrittmatter@0: if self.align: self.attribs['align'] = self.align cstrittmatter@0: if self.char: self.attribs['char'] = self.char cstrittmatter@0: if self.charoff: self.attribs['charoff'] = self.charoff cstrittmatter@0: if self.valign: self.attribs['valign'] = self.valign cstrittmatter@0: if self.style: self.attribs['style'] = self.style cstrittmatter@0: for attr in self.attribs: cstrittmatter@0: attribs_str += ' %s="%s"' % (attr, self.attribs[attr]) cstrittmatter@0: if self.text: cstrittmatter@0: text = str(self.text) cstrittmatter@0: else: cstrittmatter@0: # An empty cell should at least contain a non-breaking space cstrittmatter@0: text = ' ' cstrittmatter@0: if self.header: cstrittmatter@0: return '%s' % (attribs_str, text) cstrittmatter@0: else: cstrittmatter@0: return '%s' % (attribs_str, text) cstrittmatter@0: cstrittmatter@0: #------------------------------------------------------------------------------- cstrittmatter@0: cstrittmatter@0: class TableRow (object): cstrittmatter@0: """ cstrittmatter@0: a TableRow object is used to create a row in a HTML table. (TR tag) cstrittmatter@0: cstrittmatter@0: Attributes: cstrittmatter@0: - cells: list, tuple or any iterable, containing one string or TableCell cstrittmatter@0: object for each cell cstrittmatter@0: - header: bool, true for a header row (TH), false for a normal data row (TD) cstrittmatter@0: - bgcolor: str, background color cstrittmatter@0: - col_align, col_valign, col_char, col_charoff, col_styles: see Table class cstrittmatter@0: - attribs: dict, additional attributes for the TR tag cstrittmatter@0: cstrittmatter@0: Reference: http://www.w3.org/TR/html4/struct/tables.html#h-11.2.5 cstrittmatter@0: """ cstrittmatter@0: cstrittmatter@0: def __init__(self, cells=None, bgcolor=None, header=False, attribs=None, cstrittmatter@0: col_align=None, col_valign=None, col_char=None, cstrittmatter@0: col_charoff=None, col_styles=None): cstrittmatter@0: """TableCell constructor""" cstrittmatter@0: self.bgcolor = bgcolor cstrittmatter@0: self.cells = cells cstrittmatter@0: self.header = header cstrittmatter@0: self.col_align = col_align cstrittmatter@0: self.col_valign = col_valign cstrittmatter@0: self.col_char = col_char cstrittmatter@0: self.col_charoff = col_charoff cstrittmatter@0: self.col_styles = col_styles cstrittmatter@0: self.attribs = attribs cstrittmatter@0: if attribs==None: cstrittmatter@0: self.attribs = {} cstrittmatter@0: cstrittmatter@0: def __str__(self): cstrittmatter@0: """return the HTML code for the table row as a string""" cstrittmatter@0: attribs_str = "" cstrittmatter@0: if self.bgcolor: self.attribs['bgcolor'] = self.bgcolor cstrittmatter@0: for attr in self.attribs: cstrittmatter@0: attribs_str += ' %s="%s"' % (attr, self.attribs[attr]) cstrittmatter@0: result = '' % attribs_str cstrittmatter@0: for cell in self.cells: cstrittmatter@0: col = self.cells.index(cell) # cell column index cstrittmatter@0: if not isinstance(cell, TableCell): cstrittmatter@0: cell = TableCell(cell, header=self.header) cstrittmatter@0: # apply column alignment if specified: cstrittmatter@0: if self.col_align and cell.align==None: cstrittmatter@0: cell.align = self.col_align[col] cstrittmatter@0: if self.col_char and cell.char==None: cstrittmatter@0: cell.char = self.col_char[col] cstrittmatter@0: if self.col_charoff and cell.charoff==None: cstrittmatter@0: cell.charoff = self.col_charoff[col] cstrittmatter@0: if self.col_valign and cell.valign==None: cstrittmatter@0: cell.valign = self.col_valign[col] cstrittmatter@0: # apply column style if specified: cstrittmatter@0: if self.col_styles and cell.style==None: cstrittmatter@0: cell.style = self.col_styles[col] cstrittmatter@0: result += str(cell) cstrittmatter@0: result += '\n' cstrittmatter@0: return result cstrittmatter@0: cstrittmatter@0: #------------------------------------------------------------------------------- cstrittmatter@0: cstrittmatter@0: class Table (object): cstrittmatter@0: """ cstrittmatter@0: a Table object is used to create a HTML table. (TABLE tag) cstrittmatter@0: cstrittmatter@0: Attributes: cstrittmatter@0: - rows: list, tuple or any iterable, containing one iterable or TableRow cstrittmatter@0: object for each row cstrittmatter@0: - header_row: list, tuple or any iterable, containing the header row (optional) cstrittmatter@0: - border: str or int, border width cstrittmatter@0: - style: str, table style in CSS syntax (thin black borders by default) cstrittmatter@0: - width: str, width of the table on the page cstrittmatter@0: - attribs: dict, additional attributes for the TABLE tag cstrittmatter@0: - col_width: list or tuple defining width for each column cstrittmatter@0: - col_align: list or tuple defining horizontal alignment for each column cstrittmatter@0: - col_char: list or tuple defining alignment character for each column cstrittmatter@0: - col_charoff: list or tuple defining charoff attribute for each column cstrittmatter@0: - col_valign: list or tuple defining vertical alignment for each column cstrittmatter@0: - col_styles: list or tuple of HTML styles for each column cstrittmatter@0: cstrittmatter@0: Reference: http://www.w3.org/TR/html4/struct/tables.html#h-11.2.1 cstrittmatter@0: """ cstrittmatter@0: cstrittmatter@0: def __init__(self, rows=None, border='1', style=None, width=None, cstrittmatter@0: cellspacing=None, cellpadding=4, attribs=None, header_row=None, cstrittmatter@0: col_width=None, col_align=None, col_valign=None, cstrittmatter@0: col_char=None, col_charoff=None, col_styles=None): cstrittmatter@0: """TableCell constructor""" cstrittmatter@0: self.border = border cstrittmatter@0: self.style = style cstrittmatter@0: # style for thin borders by default cstrittmatter@0: #if style == None: self.style = TABLE_STYLE_THINBORDER cstrittmatter@0: self.width = width cstrittmatter@0: self.cellspacing = cellspacing cstrittmatter@0: self.cellpadding = cellpadding cstrittmatter@0: self.header_row = header_row cstrittmatter@0: self.rows = rows cstrittmatter@0: if not rows: self.rows = [] cstrittmatter@0: self.attribs = attribs cstrittmatter@0: if not attribs: self.attribs = {} cstrittmatter@0: self.col_width = col_width cstrittmatter@0: self.col_align = col_align cstrittmatter@0: self.col_char = col_char cstrittmatter@0: self.col_charoff = col_charoff cstrittmatter@0: self.col_valign = col_valign cstrittmatter@0: self.col_styles = col_styles cstrittmatter@0: cstrittmatter@0: def __str__(self): cstrittmatter@0: """return the HTML code for the table as a string""" cstrittmatter@0: attribs_str = "" cstrittmatter@0: #if self.border: self.attribs['border'] = self.border cstrittmatter@0: if self.style: self.attribs['style'] = self.style cstrittmatter@0: if self.width: self.attribs['width'] = self.width cstrittmatter@0: if self.cellspacing: self.attribs['cellspacing'] = self.cellspacing cstrittmatter@0: if self.cellpadding: self.attribs['cellpadding'] = self.cellpadding cstrittmatter@0: for attr in self.attribs: cstrittmatter@0: attribs_str += ' %s="%s"' % (attr, self.attribs[attr]) cstrittmatter@0: result = '\n' % attribs_str cstrittmatter@0: # insert column tags and attributes if specified: cstrittmatter@0: if self.col_width: cstrittmatter@0: for width in self.col_width: cstrittmatter@0: result += ' \n' % width cstrittmatter@0: # First insert a header row if specified: cstrittmatter@0: if self.header_row: cstrittmatter@0: if not isinstance(self.header_row, TableRow): cstrittmatter@0: result += str(TableRow(self.header_row, header=True)) cstrittmatter@0: else: cstrittmatter@0: result += str(self.header_row) cstrittmatter@0: # Then all data rows: cstrittmatter@0: for row in self.rows: cstrittmatter@0: if not isinstance(row, TableRow): cstrittmatter@0: row = TableRow(row) cstrittmatter@0: # apply column alignments and styles to each row if specified: cstrittmatter@0: # (Mozilla bug workaround) cstrittmatter@0: if self.col_align and not row.col_align: cstrittmatter@0: row.col_align = self.col_align cstrittmatter@0: if self.col_char and not row.col_char: cstrittmatter@0: row.col_char = self.col_char cstrittmatter@0: if self.col_charoff and not row.col_charoff: cstrittmatter@0: row.col_charoff = self.col_charoff cstrittmatter@0: if self.col_valign and not row.col_valign: cstrittmatter@0: row.col_valign = self.col_valign cstrittmatter@0: if self.col_styles and not row.col_styles: cstrittmatter@0: row.col_styles = self.col_styles cstrittmatter@0: result += str(row) cstrittmatter@0: result += '' cstrittmatter@0: return result cstrittmatter@0: cstrittmatter@0: cstrittmatter@0: #------------------------------------------------------------------------------- cstrittmatter@0: cstrittmatter@0: class List (object): cstrittmatter@0: """ cstrittmatter@0: a List object is used to create an ordered or unordered list in HTML. cstrittmatter@0: (UL/OL tag) cstrittmatter@0: cstrittmatter@0: Attributes: cstrittmatter@0: - lines: list, tuple or any iterable, containing one string for each line cstrittmatter@0: - ordered: bool, choice between an ordered (OL) or unordered list (UL) cstrittmatter@0: - attribs: dict, additional attributes for the OL/UL tag cstrittmatter@0: cstrittmatter@0: Reference: http://www.w3.org/TR/html4/struct/lists.html cstrittmatter@0: """ cstrittmatter@0: cstrittmatter@0: def __init__(self, lines=None, ordered=False, start=None, attribs=None): cstrittmatter@0: """List constructor""" cstrittmatter@0: if lines: cstrittmatter@0: self.lines = lines cstrittmatter@0: else: cstrittmatter@0: self.lines = [] cstrittmatter@0: self.ordered = ordered cstrittmatter@0: self.start = start cstrittmatter@0: if attribs: cstrittmatter@0: self.attribs = attribs cstrittmatter@0: else: cstrittmatter@0: self.attribs = {} cstrittmatter@0: cstrittmatter@0: def __str__(self): cstrittmatter@0: """return the HTML code for the list as a string""" cstrittmatter@0: attribs_str = "" cstrittmatter@0: if self.start: self.attribs['start'] = self.start cstrittmatter@0: for attr in self.attribs: cstrittmatter@0: attribs_str += ' %s="%s"' % (attr, self.attribs[attr]) cstrittmatter@0: if self.ordered: tag = 'ol' cstrittmatter@0: else: tag = 'ul' cstrittmatter@0: result = '<%s%s>\n' % (tag, attribs_str) cstrittmatter@0: for line in self.lines: cstrittmatter@0: result += '
  • %s\n' % str(line) cstrittmatter@0: result += '\n' % tag cstrittmatter@0: return result cstrittmatter@0: cstrittmatter@0: #=== FUNCTIONS ================================================================ cstrittmatter@0: cstrittmatter@0: # much simpler definition of a link as a function: cstrittmatter@0: def Link(text, url): cstrittmatter@0: return '%s' % (url, text) cstrittmatter@0: cstrittmatter@0: def link(text, url): cstrittmatter@0: return '%s' % (url, text) cstrittmatter@0: cstrittmatter@0: def table(*args, **kwargs): cstrittmatter@0: 'return HTML code for a table as a string. See Table class for parameters.' cstrittmatter@0: return str(Table(*args, **kwargs)) cstrittmatter@0: cstrittmatter@0: def list(*args, **kwargs): cstrittmatter@0: 'return HTML code for a list as a string. See List class for parameters.' cstrittmatter@0: return str(List(*args, **kwargs)) cstrittmatter@0: cstrittmatter@0: cstrittmatter@0: #=== MAIN ===================================================================== cstrittmatter@0: cstrittmatter@0: # Show sample usage when this file is launched as a script. cstrittmatter@0: cstrittmatter@0: if __name__ == '__main__': cstrittmatter@0: cstrittmatter@0: # open an HTML file to show output in a browser cstrittmatter@0: f = open('test.html', 'w') cstrittmatter@0: cstrittmatter@0: t = Table() cstrittmatter@0: t.rows.append(TableRow(['A', 'B', 'C'], header=True)) cstrittmatter@0: t.rows.append(TableRow(['D', 'E', 'F'])) cstrittmatter@0: t.rows.append(('i', 'j', 'k')) cstrittmatter@0: f.write(str(t) + '

    \n') cstrittmatter@0: print (str(t)) cstrittmatter@0: f.close()