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

    \n') - print str(t) - print '-'*79 - - t2 = Table([ - ('1', '2'), - ['3', '4'] - ], width='100%', header_row=('col1', 'col2'), - col_width=('', '75%')) - f.write(str(t2) + '

    \n') - print t2 - print '-'*79 - - t2.rows.append(['5', '6']) - t2.rows[1][1] = TableCell('new', bgcolor='red') - t2.rows.append(TableRow(['7', '8'], attribs={'align': 'center'})) - f.write(str(t2) + '

    \n') - print t2 - print '-'*79 - - # sample table with column attributes and styles: - table_data = [ - ['Smith', 'John', 30, 4.5], - ['Carpenter', 'Jack', 47, 7], - ['Johnson', 'Paul', 62, 10.55], - ] - htmlcode = HTML.table(table_data, - header_row = ['Last name', 'First name', 'Age', 'Score'], - col_width=['', '20%', '10%', '10%'], - col_align=['left', 'center', 'right', 'char'], - col_styles=['font-size: large', '', 'font-size: small', 'background-color:yellow']) - f.write(htmlcode + '

    \n') - print htmlcode - print '-'*79 - - def gen_table_squares(n): - """ - Generator to create table rows for integers from 1 to n - """ -## # First, header row: -## yield TableRow(('x', 'square(x)'), header=True, bgcolor='blue') -## # Then all rows: - for x in range(1, n+1): - yield (x, x*x) - - t = Table(rows=gen_table_squares(10), header_row=('x', 'square(x)')) - f.write(str(t) + '

    \n') - - print '-'*79 - l = List(['aaa', 'bbb', 'ccc']) - f.write(str(l) + '

    \n') - l.ordered = True - f.write(str(l) + '

    \n') - l.start=10 - f.write(str(l) + '

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

  • %s\n' % str(line) + result += '\n' % tag + return result + + +##class Link (object): +## """ +## a Link object is used to create link in HTML. ( tag) +## +## Attributes: +## - text: str, text of the link +## - url: str, URL of the link +## - attribs: dict, additional attributes for the A tag +## +## Reference: http://www.w3.org/TR/html4 +## """ +## +## def __init__(self, text, url=None, attribs=None): +## """Link constructor""" +## self.text = text +## self.url = url +## if attribs: +## self.attribs = attribs +## else: +## self.attribs = {} +## +## def __str__(self): +## """return the HTML code for the link as a string""" +## attribs_str = "" +## if self.url: self.attribs['href'] = self.url +## for attr in self.attribs: +## attribs_str += ' %s="%s"' % (attr, self.attribs[attr]) +## return '%s' % (attribs_str, text) + + +#=== FUNCTIONS ================================================================ + +# much simpler definition of a link as a function: +def Link(text, url): + return '%s' % (url, text) + +def link(text, url): + return '%s' % (url, text) + +def table(*args, **kwargs): + 'return HTML code for a table as a string. See Table class for parameters.' + return str(Table(*args, **kwargs)) + +def list(*args, **kwargs): + 'return HTML code for a list as a string. See List class for parameters.' + return str(List(*args, **kwargs)) + + +#=== MAIN ===================================================================== + +# Show sample usage when this file is launched as a script. + +if __name__ == '__main__': + + # open an HTML file to show output in a browser + f = open('test.html', 'w') + + t = Table() + t.rows.append(TableRow(['A', 'B', 'C'], header=True)) + t.rows.append(TableRow(['D', 'E', 'F'])) + t.rows.append(('i', 'j', 'k')) + f.write(str(t) + '

    \n') + print(str(t)) + print('-'*79) + + t2 = Table([ + ('1', '2'), + ['3', '4'] + ], width='100%', header_row=('col1', 'col2'), + col_width=('', '75%')) + f.write(str(t2) + '

    \n') + print(t2) + print('-'*79) + + t2.rows.append(['5', '6']) + t2.rows[1][1] = TableCell('new', bgcolor='red') + t2.rows.append(TableRow(['7', '8'], attribs={'align': 'center'})) + f.write(str(t2) + '

    \n') + print(t2) + print('-'*79) + + # sample table with column attributes and styles: + table_data = [ + ['Smith', 'John', 30, 4.5], + ['Carpenter', 'Jack', 47, 7], + ['Johnson', 'Paul', 62, 10.55], + ] + htmlcode = HTML.table(table_data, + header_row = ['Last name', 'First name', 'Age', 'Score'], + col_width=['', '20%', '10%', '10%'], + col_align=['left', 'center', 'right', 'char'], + col_styles=['font-size: large', '', 'font-size: small', 'background-color:yellow']) + f.write(htmlcode + '

    \n') + print(htmlcode) + print('-'*79) + + def gen_table_squares(n): + """ + Generator to create table rows for integers from 1 to n + """ +## # First, header row: +## yield TableRow(('x', 'square(x)'), header=True, bgcolor='blue') +## # Then all rows: + for x in range(1, n+1): + yield (x, x*x) + + t = Table(rows=gen_table_squares(10), header_row=('x', 'square(x)')) + f.write(str(t) + '

    \n') + + print('-'*79) + l = List(['aaa', 'bbb', 'ccc']) + f.write(str(l) + '

    \n') + l.ordered = True + f.write(str(l) + '

    \n') + l.start=10 + f.write(str(l) + '

    \n') + + f.close() diff --git a/HTML_tutorial.py b/HTML_tutorial.py index bf01dde..50fa0e5 100644 --- a/HTML_tutorial.py +++ b/HTML_tutorial.py @@ -1,208 +1,208 @@ -# HTML.py tutorial - P. Lagadec - -# see also http://www.decalage.info/en/python/html for more details and -# updates. - - -import HTML - -# open an HTML file to show output in a browser -HTMLFILE = 'HTML_tutorial_output.html' -f = open(HTMLFILE, 'w') - - -#=== TABLES =================================================================== - -# 1) a simple HTML table may be built from a list of lists: - -table_data = [ - ['Last name', 'First name', 'Age'], - ['Smith', 'John', 30], - ['Carpenter', 'Jack', 47], - ['Johnson', 'Paul', 62], - ] - -htmlcode = HTML.table(table_data) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - -#------------------------------------------------------------------------------- - -# 2) a header row may be specified: it will appear in bold in browsers - -table_data = [ - ['Smith', 'John', 30], - ['Carpenter', 'Jack', 47], - ['Johnson', 'Paul', 62], - ] - -htmlcode = HTML.table(table_data, - header_row=['Last name', 'First name', 'Age']) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - - -#------------------------------------------------------------------------------- - -# 3) you may also create a Table object and add rows one by one: - -t = HTML.Table(header_row=['x', 'square(x)', 'cube(x)']) -for x in range(1,10): - t.rows.append([x, x*x, x*x*x]) -htmlcode = str(t) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - - -#------------------------------------------------------------------------------- - -# 4) rows may be any iterable (list, tuple, ...) including a generator: -# (this is useful to save memory when generating a large table) - -def gen_rows(i): - 'rows generator' - for x in range(1,i): - yield [x, x*x, x*x*x] - -htmlcode = HTML.table(gen_rows(10), header_row=['x', 'square(x)', 'cube(x)']) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - - -#------------------------------------------------------------------------------- - -# 5) to choose a specific background color for a cell, use a TableCell -# object: - -HTML_COLORS = ['Black', 'Green', 'Silver', 'Lime', 'Gray', 'Olive', 'White', - 'Maroon', 'Navy', 'Red', 'Blue', 'Purple', 'Teal', 'Fuchsia', 'Aqua'] - -t = HTML.Table(header_row=['Name', 'Color']) -for colorname in HTML_COLORS: - colored_cell = HTML.TableCell(' ', bgcolor=colorname) - t.rows.append([colorname, colored_cell]) -htmlcode = str(t) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - - -#------------------------------------------------------------------------------- - -# 6) A simple way to generate a test report: - -# dictionary of test results, indexed by test id: -test_results = { - 'test 1': 'success', - 'test 2': 'failure', - 'test 3': 'success', - 'test 4': 'error', - } - -# dict of colors for each result: -result_colors = { - 'success': 'lime', - 'failure': 'red', - 'error': 'yellow', - } - -t = HTML.Table(header_row=['Test', 'Result']) -for test_id in sorted(test_results): - # create the colored cell: - color = result_colors[test_results[test_id]] - colored_result = HTML.TableCell(test_results[test_id], bgcolor=color) - # append the row with two cells: - t.rows.append([test_id, colored_result]) -htmlcode = str(t) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - -#------------------------------------------------------------------------------- - -# 7) sample table with column attributes and styles: -table_data = [ - ['Smith', 'John', 30, 4.5], - ['Carpenter', 'Jack', 47, 7], - ['Johnson', 'Paul', 62, 10.55], - ] -htmlcode = HTML.table(table_data, - header_row = ['Last name', 'First name', 'Age', 'Score'], - col_width=['', '20%', '10%', '10%'], - col_align=['left', 'center', 'right', 'char'], - col_styles=['font-size: large', '', 'font-size: small', 'background-color:yellow']) -f.write(htmlcode + '

    \n') -print htmlcode -print '-'*79 - - - -#=== LISTS =================================================================== - -# 1) a HTML list (with bullets) may be built from a Python list of strings: - -a_list = ['john', 'paul', 'jack'] -htmlcode = HTML.list(a_list) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - - -# 2) it is easy to change it into a numbered (ordered) list: - -htmlcode = HTML.list(a_list, ordered=True) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - - -# 3) Lines of a list may also be added one by one, when using the List class: - -html_list = HTML.List() -for i in range(1,10): - html_list.lines.append('square(%d) = %d' % (i, i*i)) -htmlcode = str(html_list) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - - -# 4) To save memory, a large list may be built from a generator: - -def gen_lines(i): - 'lines generator' - for x in range(1,i): - yield 'square(%d) = %d' % (x, x*x) -htmlcode = HTML.list(gen_lines(10)) -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - - -#=== LINKS =================================================================== - -# How to create a link: - -htmlcode = HTML.link('Decalage website', 'http://www.decalage.info') -print htmlcode -f.write(htmlcode) -f.write('

    ') -print '-'*79 - - -f.close() -print '\nOpen the file %s in a browser to see the result.' % HTMLFILE +# HTML.py tutorial - P. Lagadec + +# see also http://www.decalage.info/en/python/html for more details and +# updates. + + +import HTML + +# open an HTML file to show output in a browser +HTMLFILE = 'HTML_tutorial_output.html' +f = open(HTMLFILE, 'w') + + +#=== TABLES =================================================================== + +# 1) a simple HTML table may be built from a list of lists: + +table_data = [ + ['Last name', 'First name', 'Age'], + ['Smith', 'John', 30], + ['Carpenter', 'Jack', 47], + ['Johnson', 'Paul', 62], + ] + +htmlcode = HTML.table(table_data) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + +#------------------------------------------------------------------------------- + +# 2) a header row may be specified: it will appear in bold in browsers + +table_data = [ + ['Smith', 'John', 30], + ['Carpenter', 'Jack', 47], + ['Johnson', 'Paul', 62], + ] + +htmlcode = HTML.table(table_data, + header_row=['Last name', 'First name', 'Age']) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + + +#------------------------------------------------------------------------------- + +# 3) you may also create a Table object and add rows one by one: + +t = HTML.Table(header_row=['x', 'square(x)', 'cube(x)']) +for x in range(1,10): + t.rows.append([x, x*x, x*x*x]) +htmlcode = str(t) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + + +#------------------------------------------------------------------------------- + +# 4) rows may be any iterable (list, tuple, ...) including a generator: +# (this is useful to save memory when generating a large table) + +def gen_rows(i): + 'rows generator' + for x in range(1,i): + yield [x, x*x, x*x*x] + +htmlcode = HTML.table(gen_rows(10), header_row=['x', 'square(x)', 'cube(x)']) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + + +#------------------------------------------------------------------------------- + +# 5) to choose a specific background color for a cell, use a TableCell +# object: + +HTML_COLORS = ['Black', 'Green', 'Silver', 'Lime', 'Gray', 'Olive', 'White', + 'Maroon', 'Navy', 'Red', 'Blue', 'Purple', 'Teal', 'Fuchsia', 'Aqua'] + +t = HTML.Table(header_row=['Name', 'Color']) +for colorname in HTML_COLORS: + colored_cell = HTML.TableCell(' ', bgcolor=colorname) + t.rows.append([colorname, colored_cell]) +htmlcode = str(t) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + + +#------------------------------------------------------------------------------- + +# 6) A simple way to generate a test report: + +# dictionary of test results, indexed by test id: +test_results = { + 'test 1': 'success', + 'test 2': 'failure', + 'test 3': 'success', + 'test 4': 'error', + } + +# dict of colors for each result: +result_colors = { + 'success': 'lime', + 'failure': 'red', + 'error': 'yellow', + } + +t = HTML.Table(header_row=['Test', 'Result']) +for test_id in sorted(test_results): + # create the colored cell: + color = result_colors[test_results[test_id]] + colored_result = HTML.TableCell(test_results[test_id], bgcolor=color) + # append the row with two cells: + t.rows.append([test_id, colored_result]) +htmlcode = str(t) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + +#------------------------------------------------------------------------------- + +# 7) sample table with column attributes and styles: +table_data = [ + ['Smith', 'John', 30, 4.5], + ['Carpenter', 'Jack', 47, 7], + ['Johnson', 'Paul', 62, 10.55], + ] +htmlcode = HTML.table(table_data, + header_row = ['Last name', 'First name', 'Age', 'Score'], + col_width=['', '20%', '10%', '10%'], + col_align=['left', 'center', 'right', 'char'], + col_styles=['font-size: large', '', 'font-size: small', 'background-color:yellow']) +f.write(htmlcode + '

    \n') +print(htmlcode) +print('-'*79) + + + +#=== LISTS =================================================================== + +# 1) a HTML list (with bullets) may be built from a Python list of strings: + +a_list = ['john', 'paul', 'jack'] +htmlcode = HTML.list(a_list) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + + +# 2) it is easy to change it into a numbered (ordered) list: + +htmlcode = HTML.list(a_list, ordered=True) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + + +# 3) Lines of a list may also be added one by one, when using the List class: + +html_list = HTML.List() +for i in range(1,10): + html_list.lines.append('square(%d) = %d' % (i, i*i)) +htmlcode = str(html_list) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + + +# 4) To save memory, a large list may be built from a generator: + +def gen_lines(i): + 'lines generator' + for x in range(1,i): + yield 'square(%d) = %d' % (x, x*x) +htmlcode = HTML.list(gen_lines(10)) +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + + +#=== LINKS =================================================================== + +# How to create a link: + +htmlcode = HTML.link('Decalage website', 'http://www.decalage.info') +print(htmlcode) +f.write(htmlcode) +f.write('

    ') +print('-'*79) + + +f.close() +print('\nOpen the file %s in a browser to see the result.' % HTMLFILE)