HTML_Cal.py code
                Home
News

NBMC
Psion
Python

LYD
SID

 
#! /usr/bin/python
### ---------------------------------------------------
### Name: html_cal.py
###
### Function:
###  HTMLized Calendar printing functions
###  Based on standard library module calendar.py Revision 2:
###  Same interface as the original except only monthly cals with week numbers.
###  prmonth() prints to stdout, HTMLmonth() returns a string
###  Month names, day and week numbers have pseudo HTML tags
###  that will be ignored by most current browsers (yes, it would have
###  been cleaner to use real HTML comments...) and can be used by
###  other programs to substitute real links based on dates.
###  CSS styles can then be used to customize appearance.
###  
### Version: 1999.08.24
###
### Author: Fred Pacquier <fredp@dial.oleane.com>
###
### Copyright: Blue Tango Software 1999
###
### Licence: PGPL (Pretty Generous Pacman's License) (just kiddin')
### ---------------------------------------------------

# Import functions and variables from time module
from time import gmtime, localtime, mktime, asctime, ctime, strftime

# Exception raised for bad input (with string parameter for details)
error = 'calendar.error'

# Note when comparing these calendars to the ones printed by cal(1):
# These calendars have Monday as the first day of the week, and Sunday as
# the last (European convention.)

# Constants for months referenced later
January = 1
February = 2

# Number of days per month (except for February in leap years)
mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

# Full and abbreviated names of weekdays
day_name = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', \
	    'Friday', 'Saturday', 'Sunday']
day_abbr = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']

# Full and abbreviated names of months (1-based arrays!!!)
month_name =          ['', 'January',   'February', 'March',    'April', \
		           'May',       'June',     'July',     'August', \
			   'September', 'October',  'November', 'December']
month_abbr =       ['   ', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', \
		           'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

# Return 1 for leap years, 0 for non-leap years
def isleap(year):
	return year % 4 == 0 and (year % 100 <> 0 or year % 400 == 0)

# Return number of leap years in range [y1, y2)
# Assume y1 <= y2 and no funny (non-leap century) years
def leapdays(y1, y2):
	return (y2+3)/4 - (y1+3)/4

# Return weekday (0-6 ~ Mon-Sun) for year (1970-...), month (1-12), day (1-31)
def weekday(year, month, day):
	secs = mktime((year, month, day, 0, 0, 0, 0, 0, 0))
	tuple = localtime(secs)
	return tuple[6]

# Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for year, month
def monthrange(year, month):
	if not 1 <= month <= 12: raise ValueError, 'bad month number'
	day1 = weekday(year, month, 1)
	ndays = mdays[month] + (month == February and isleap(year))
	return day1, ndays

# Return a matrix representing a month's calendar
# Each row represents a week; days outside this month are zero
# The eight element is the week number (from 0 to 52, weeks starting on Mondays)
def _monthcalendar(year, month):
	day1, ndays = monthrange(year, month)
	rows = []
	r7 = range(7)
	day = 1 - day1
	while day <= ndays:
		row = [0, 0, 0, 0, 0, 0, 0, 0]
		for i in r7:
			if 1 <= day <= ndays: row[i] = day
			if row[7]==0 and row[i]>0:
			   row[7]=int(strftime('%W',localtime(mktime((year, month, day, 0, 0, 0, 0, 0, 0)))))
			day = day + 1
		rows.append(row)
	return rows

# Caching interface to _monthcalendar
_mc_cache = {}
def monthcalendar(year, month):
	key = (year, month)
	if _mc_cache.has_key(key):
		return _mc_cache[key]
	else:
		_mc_cache[key] = ret = _monthcalendar(year, month)
		return ret

# Center a string in a field, add a prefix & suffix not used for calculation (hidden HTML tags)
def _center(str, prefix, suffix, width):
	n = width - len(str)
	if n <= 0: return prefix + str + suffix
	return ' '*((n+1)/2) + prefix + str + suffix + ' '*((n)/2)

# XXX The following code knows that print separates items with space!

# Print a single week (no newline) & week number
def prweek(week, width, month):
	for day in week[:-1]:
		if day == 0: s = p = ''
		else:
		   s = `day`
		   p = '<m%d>' % month
		print _center(s, p, '', width),
	print _center(`week[7]`, '<i><w>', '</i>', width),
	

# Return a header for a week (bold) & week number col.
def weekheader(width):
	str = ''
	if width >= 9: names = day_name
	else: names = day_abbr
	for i in range(7):
		if str: str = str + ' '
		str = str + _center(names[i%7][:width], '', '', width)
	str = '<b>' + str + ' ' + _center('Sem', '<i>', '</i>', width) + '</b>'
	return str

# Print a month's calendar with pseudo-HTML tags
def prmonth(year, month, w = 0, l = 0):
	w = max(2, w)
	l = max(1, l)
	print '<pre>'
	print _center(month_name[month], '<mn%d>' % month, '</mn%d>' % month, 7*(w+1) - 1),
	print '\n'*l,
	print weekheader(w),
	print '\n'*l,
	for week in monthcalendar(year, month):
		prweek(week, w, month)
		print '\n'*l,
	print '</pre>'

# a class that acts as a file but buffers to a string, for stdout redirection
class fakefile:
	def __init__(self):
	    self.buffer=''
	def write(self,s):
	    self.buffer=self.buffer+s
	def read(self):
	    return self.buffer

# same as prmonth(), but returns the calendar code in a string
def HTMLmonth(year, month, w = 0, l = 0):
	import sys
	ff = fakefile()
	sys.stdout = ff
	prmonth(year, month, w, l)
	buf = ff.read()
	del(ff)
	return buf
 
                Accueil
Chrono

Perso
Famille

C.P.
C.G.

Mail

* All text/software/photos © Fred Pacquier 1996-2000 *

^^^