349 lines
11 KiB
Python
Executable File
349 lines
11 KiB
Python
Executable File
'''
|
|
Create HTML formatted files.
|
|
|
|
Author: Jason Hayes <jason.hayes@rockstarsandiego.com>
|
|
'''
|
|
import os
|
|
import sys
|
|
|
|
|
|
## Enum Classes ##
|
|
|
|
class HeaderStyle:
|
|
H1 = 'h1'
|
|
H2 = 'h2'
|
|
H3 = 'h3'
|
|
H4 = 'h4'
|
|
H5 = 'h5'
|
|
H6 = 'h6'
|
|
|
|
class WidthStyle:
|
|
Percentage = '%'
|
|
Fixed = ''
|
|
Proportional = '*'
|
|
NoWidth = None
|
|
|
|
class AlignStyle:
|
|
Left = 'left'
|
|
Center = 'center'
|
|
Right = 'right'
|
|
|
|
# Stretches the lines so that each line has equal width.
|
|
Justify = 'justify'
|
|
|
|
# Aligns the content to a specific character.
|
|
Char = 'char'
|
|
|
|
class TextStyle:
|
|
Bold = 1
|
|
Italics = 2
|
|
Underline = 4
|
|
|
|
class FontFace:
|
|
Arial = 'arial'
|
|
Calibri = 'calibri'
|
|
Verdana = 'verdana'
|
|
SansSerif = 'sans-serif'
|
|
|
|
class Color:
|
|
'''
|
|
Useful HTML color codes.
|
|
'''
|
|
AliceBlue = 'aliceblue'
|
|
Aqua = 'aqua'
|
|
AntiqueWhite = 'antiquewhite'
|
|
Aquamarine = 'aquamarine'
|
|
Azure = 'azure'
|
|
Biege = 'beige'
|
|
Black = 'black'
|
|
Blue = 'blue'
|
|
ForestGreen = 'forestgreen'
|
|
Gray = 'gray'
|
|
Green = 'green'
|
|
GreenYellow = 'greenyellow'
|
|
LightSlateGray = 'lightslategray'
|
|
Magenta = 'magenta'
|
|
Maroon = 'maroon'
|
|
MediumBlue = 'mediumblue'
|
|
MediumPurple = 'mediumpurple'
|
|
MistyRose = 'mistyrose'
|
|
Navy = 'navy'
|
|
Olive = 'olive'
|
|
Orange = 'orange'
|
|
OrangeRed = 'orangered'
|
|
PaleGreen = 'palegreen'
|
|
PaleVioletRed = 'palevioletred'
|
|
Plum = 'plum'
|
|
Purple = 'purple'
|
|
Red = 'red'
|
|
SaddleBrown = 'saddlebrown'
|
|
Salmon = 'salmon'
|
|
SeaGreen = 'seagreen'
|
|
Sienna = 'sienna'
|
|
SkyBlue = 'skyblue'
|
|
SlateGray = 'slategray'
|
|
SteelBlue = 'steelblue'
|
|
Tan = 'tan'
|
|
Thistle = 'thistle'
|
|
Turqoise = 'turqoise'
|
|
Wheat = 'wheat'
|
|
White = 'white'
|
|
WhiteSmoke = 'whitesmoke'
|
|
Yellow = 'yellow'
|
|
YellowGreen = 'yellowgreen'
|
|
|
|
|
|
## Style Classes ##
|
|
|
|
class TableCellStyle( object ):
|
|
def __init__( self,
|
|
fontStyle,
|
|
backgroundColor = Color.White,
|
|
width = 100,
|
|
widthStyle = WidthStyle.Proportional,
|
|
align = AlignStyle.Left ):
|
|
|
|
self.FontStyle = fontStyle
|
|
self.Width = width
|
|
self.BackgroundColor = backgroundColor
|
|
self.WidthStyle = widthStyle
|
|
self.Align = align
|
|
|
|
def Render( self, text ):
|
|
if self.WidthStyle == WidthStyle.NoWidth:
|
|
html = '<td bgcolor="{0}" align="{1}">'.format( self.BackgroundColor, self.Align )
|
|
|
|
else:
|
|
html = '<td bgcolor="{0}" align="{1}" width="{2}{3}">'.format( self.BackgroundColor, self.Align, self.Width, self.WidthStyle )
|
|
|
|
html += self.FontStyle.Render( text )
|
|
html += '</td>\n'
|
|
|
|
return html
|
|
|
|
class FontStyle( object ):
|
|
def __init__( self,
|
|
fontSize = 3,
|
|
fontFace = FontFace.Calibri,
|
|
foregroundColor = Color.Black,
|
|
backgroundColor = Color.White,
|
|
hyperLink = None,
|
|
textStyleFlags = None ):
|
|
|
|
self.FontSize = fontSize
|
|
self.FontFace = fontFace
|
|
self.ForegroundColor = foregroundColor
|
|
self.BackgroundColor = backgroundColor
|
|
self.Hyperlink = hyperLink
|
|
self.TextStyleFlags = textStyleFlags
|
|
|
|
def Render( self, text ):
|
|
html = ''
|
|
|
|
if self.TextStyleFlags:
|
|
if self.TextStyleFlags & TextStyle.Bold:
|
|
text = '<b>{0}</b>'.format( text )
|
|
|
|
if self.TextStyleFlags & TextStyle.Italics:
|
|
text = '<i>{0}</i>'.format( text )
|
|
|
|
if self.TextStyleFlags & TextStyle.Underline:
|
|
text = '<u>{0}</u>'.format( text )
|
|
|
|
if self.Hyperlink:
|
|
html += '<a href="{0}">'.format( self.Hyperlink )
|
|
|
|
html += '<font size="{0}" face="{1}" color="{2}">{3}</font>'.format( self.FontSize, self.FontFace, self.ForegroundColor, text )
|
|
|
|
if self.Hyperlink:
|
|
html += '</a>'
|
|
|
|
return html
|
|
|
|
|
|
## Table Classes ##
|
|
|
|
class TableCellItem( object ):
|
|
def __init__( self, text, tableCellStyle ):
|
|
self.Text = text
|
|
self.TableCellStyle = tableCellStyle
|
|
|
|
def Render( self ):
|
|
return self.TableCellStyle.Render( self.Text )
|
|
|
|
class Table( object ):
|
|
def __init__( self,
|
|
caption = None,
|
|
captionStyle = None,
|
|
captionAlign = AlignStyle.Left,
|
|
numColumns = 1,
|
|
border = 1,
|
|
cellSpacing = 1,
|
|
cellPadding = 1,
|
|
width = 100,
|
|
widthStyle = WidthStyle.Fixed,
|
|
align = AlignStyle.Left ):
|
|
|
|
self.Align = align
|
|
self.Border = border
|
|
self.Caption = caption
|
|
self.CaptionStyle = captionStyle
|
|
self.CaptionAlign = captionAlign
|
|
self.CellSpacing = cellSpacing
|
|
self.CellPadding = cellPadding
|
|
self.Width = width
|
|
self.WidthStyle = widthStyle
|
|
|
|
self.__numColumns = numColumns
|
|
self.__table = []
|
|
|
|
def AddItem( self, text, tableCellStyle ):
|
|
if not isinstance( tableCellStyle, TableCellStyle ):
|
|
assert 0, 'Requires instance of a TableCellStyle object! {0}'.format( tableCellStyle )
|
|
|
|
if len( self.__table ) == 0:
|
|
self.__table.append( [ TableCellItem( text, tableCellStyle ) ] )
|
|
|
|
else:
|
|
|
|
# Get the current row.
|
|
row = self.__table[ -1 ]
|
|
|
|
# Create a new row if the current one is full.
|
|
if len( row ) == self.__numColumns:
|
|
self.__table.append( [ TableCellItem( text, tableCellStyle ) ] )
|
|
|
|
# Extend the current row if there is room.
|
|
else:
|
|
row.append( TableCellItem( text, tableCellStyle ) )
|
|
|
|
def Render( self ):
|
|
html = '<table border="{0}" cellspacing="{1}" cellpadding="{2}" width="{3}{4}">\n'.format( self.Border, self.CellSpacing, self.CellPadding, self.Width, self.WidthStyle )
|
|
|
|
if self.Caption:
|
|
if self.CaptionStyle == None:
|
|
self.CaptionStyle = FontStyle()
|
|
|
|
html += '<caption align="{1}">{0}</caption>\n'.format( self.CaptionStyle.Render( self.Caption ), self.CaptionAlign )
|
|
|
|
for row in self.__table:
|
|
html += '\t<tr>\n'
|
|
|
|
for item in row:
|
|
html += '\t\t{0}'.format( item.Render() )
|
|
|
|
html += '\t</tr>\n'
|
|
|
|
html += '</table>\n'
|
|
|
|
return html
|
|
|
|
|
|
## Classes ##
|
|
|
|
class Document( object ):
|
|
def __init__( self, filename, title ):
|
|
self.__filename = filename
|
|
|
|
self.__html = '<html>\n'
|
|
|
|
# Set title.
|
|
self.__html += '<head>\n'
|
|
self.__html += '<title>{0}</title>\n'.format( title )
|
|
self.__html += '</head>\n'
|
|
self.__html += '<body>\n'
|
|
|
|
|
|
## Properties ##
|
|
|
|
@property
|
|
def Filename( self ):
|
|
return self.__filename
|
|
|
|
@property
|
|
def Html( self ):
|
|
return self.__html
|
|
|
|
|
|
## Methods ##
|
|
|
|
def AddRawHtml( self, rawHtml ):
|
|
self.__html += '{0}\n'.format( rawHtml )
|
|
|
|
def AddHeader( self, text, fontStyle, headerStyle = HeaderStyle.H1 ):
|
|
if not isinstance( fontStyle, FontStyle ):
|
|
assert 0, 'Requires a FontStyle object! {0}'.format( fontStyle )
|
|
|
|
self.__html += '<header>\n'
|
|
self.__html += '\t<{0}>{1}</{0}>\n'.format( headerStyle, fontStyle.Render( text ) )
|
|
self.__html += '</header>\n'
|
|
|
|
def AddLineBreak( self ):
|
|
self.__html += '<br>\n'
|
|
|
|
def AddHorizontalLine( self ):
|
|
self.__html += '<hr>\n'
|
|
|
|
def AddDetails( self, summary, text, fontStyle, opened = False ):
|
|
self.__html += '<details {0}>\n'.format( 'open' if opened else '' )
|
|
self.__html += '<summary>{0}</summary>\n'.format( fontStyle.Render( summary ) )
|
|
self.__html += fontStyle.Render( text )
|
|
self.__html += '</details>\n'
|
|
|
|
def AddLine( self, text, fontStyle ):
|
|
if not isinstance( fontStyle, FontStyle ):
|
|
assert 0, 'Requires a FontStyle object! {0}'.format( fontStyle )
|
|
|
|
self.__html += fontStyle.Render( text )
|
|
|
|
def AddTable( self, table ):
|
|
self.__html += table.Render()
|
|
|
|
def AddFooter( self, text, fontStyle ):
|
|
if not isinstance( fontStyle, FontStyle ):
|
|
assert 0, 'Requires a FontStyle object! {0}'.format( fontStyle )
|
|
|
|
self.__html += '<footer>\n'
|
|
self.__html += fontStyle.Render( text )
|
|
self.__html += '</footer>\n'
|
|
|
|
def Write( self ):
|
|
self.__html += '</body>\n'
|
|
self.__html += '</html>'
|
|
|
|
try:
|
|
doc = open( self.__filename, 'w' )
|
|
doc.write( self.__html )
|
|
|
|
except IOError, error:
|
|
sys.stderr.write( 'An exception occurred while attempting to create the HTML document! {0}'.format( error ) )
|
|
|
|
finally:
|
|
doc.close()
|
|
|
|
'''
|
|
writer = Writer( 'x:\\temp\\index.html', 'Python Coding Standards' )
|
|
fontStyle = FontStyle()
|
|
|
|
headerFontStyle = FontStyle( fontSize = 4 )
|
|
|
|
writer.AddHeader( 'RS.Utils.Html.Writer Example', headerFontStyle )
|
|
writer.AddLine( 'hi there', fontStyle )
|
|
|
|
#fontStyle.ForegroundColor = 'red'
|
|
|
|
tableCellStyle = TableCellStyle( fontStyle )
|
|
headerCellStyle = TableCellStyle( fontStyle, backgroundColor = 'gray' )
|
|
|
|
table = Table( numColumns = 2, cellSpacing = 0, width = 50, widthStyle = WidthStyle.Percentage )
|
|
table.AddItem( 'hello', headerCellStyle )
|
|
table.AddItem( 'world', headerCellStyle )
|
|
table.AddItem( 'how', tableCellStyle )
|
|
table.AddItem( 'are you', tableCellStyle )
|
|
|
|
writer.AddTable( table )
|
|
writer.AddTable( table )
|
|
|
|
writer.AddLine( 'hellew', fontStyle )
|
|
writer.Write()
|
|
''' |