From 6741d19ec5be2e76369d84bd705bde8767972e00 Mon Sep 17 00:00:00 2001 From: aurium Date: Thu, 22 Jan 2009 22:09:33 +0000 Subject: [PATCH] publishing calendar generator extension --- share/extensions/svgcalendar.inx | 48 +++++ share/extensions/svgcalendar.py | 292 +++++++++++++++++++++++++++++++ 2 files changed, 340 insertions(+) create mode 100644 share/extensions/svgcalendar.inx create mode 100755 share/extensions/svgcalendar.py diff --git a/share/extensions/svgcalendar.inx b/share/extensions/svgcalendar.inx new file mode 100644 index 000000000..da07d1218 --- /dev/null +++ b/share/extensions/svgcalendar.inx @@ -0,0 +1,48 @@ + + + <_name>Calendar Generator + org.inkscape.calendar + + svgcalendar.py + inkex.py + + + + 0 + 0 + true + + <_item value="sun">Sunday + <_item value="mon">Monday + + + <_item value="sat+sun">Saturday and Sunday + <_item value="sat">Saturday + <_item value="sun">Sunday + + + + #808080 + #686868 + #909090 + #000000 + #787878 + #B0B0B0 + + + <_param name="l10n-help" type="description">You may change the names for other languages: + <_param name="month-names" type="string" _gui-text="Month names">January February March April May June July August September October November December + <_param name="day-names" type="string" _gui-text="Day names">Sun Mon Tue Wed Thu Fri Sat + <_param name="day-names-help" type="description">(The day name list must start in sunday) + + + + all + + + + + + diff --git a/share/extensions/svgcalendar.py b/share/extensions/svgcalendar.py new file mode 100755 index 000000000..dba73ed11 --- /dev/null +++ b/share/extensions/svgcalendar.py @@ -0,0 +1,292 @@ +#!/usr/bin/env python + +''' +calendar.py +A calendar generator plugin for Inkscape, but also can be used as a standalone +command line application. + +Copyright (C) 2008 Aurelio A. Heckert + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' + +__version__ = "0.1" + +import inkex, simplestyle, re, calendar +from datetime import * + +class SVGCalendar (inkex.Effect): + + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("--tab", + action="store", type="string", + dest="tab") + self.OptionParser.add_option("--month", + action="store", type="int", + dest="month", default=0, + help="Month to be generated. If 0, then the entry year will be generated.") + self.OptionParser.add_option("--year", + action="store", type="int", + dest="year", default=0, + help="Year to be generated. If 0, then the current year will be generated.") + self.OptionParser.add_option("--fill-empty-day-boxes", + action="store", type="inkbool", + dest="fill_edb", default=True, + help="Fill empty day boxes with next month days.") + self.OptionParser.add_option("--start-day", + action="store", type="string", + dest="start_day", default="sun", + help='Week start day. ("sun" or "mon")') + self.OptionParser.add_option("--weekend", + action="store", type="string", + dest="weekend", default="sat+sun", + help='Define the weekend days. ("sat+sun" or "sat" or "sun")') + self.OptionParser.add_option("--color-year", + action="store", type="string", + dest="color_year", default="#888", + help='Color for the year header.') + self.OptionParser.add_option("--color-month", + action="store", type="string", + dest="color_month", default="#666", + help='Color for the month name header.') + self.OptionParser.add_option("--color-day-name", + action="store", type="string", + dest="color_day_name", default="#999", + help='Color for the week day names header.') + self.OptionParser.add_option("--color-day", + action="store", type="string", + dest="color_day", default="#000", + help='Color for the common day box.') + self.OptionParser.add_option("--color-weekend", + action="store", type="string", + dest="color_weekend", default="#777", + help='Color for the weekend days.') + self.OptionParser.add_option("--color-nmd", + action="store", type="string", + dest="color_nmd", default="#BBB", + help='Color for the next month day, in enpty day boxes.') + self.OptionParser.add_option("--month-names", + action="store", type="string", + dest="month_names", default='January February March April May June '+\ + 'July August September October November December', + help='The month names for localization.') + self.OptionParser.add_option("--day-names", + action="store", type="string", + dest="day_names", default='Sun Mon Tue Wed Thu Fri Sat', + help='The week day names for localization.') + + def validate_options(self): + # Convert string names lists in real lists: + m = re.match( '\s*(.*[^\s])\s*', self.options.month_names ) + self.options.month_names = re.split( '\s+', m.group(1) ) + m = re.match( '\s*(.*[^\s])\s*', self.options.day_names ) + self.options.day_names = re.split( '\s+', m.group(1) ) + # Validate names lists: + if len(self.options.month_names) != 12: + inkex.errormsg('The month name list "'+ + str(self.options.month_names)+ + '" is invalid. Using default.') + self.options.month_names = ['January','February','March', + 'April', 'May', 'June', + 'July', 'August', 'September', + 'October','November','December'] + if len(self.options.day_names) != 7: + inkex.errormsg('The day name list "'+ + str(self.options.day_names)+ + '" is invalid. Using default.') + self.options.day_names = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'] + # Convert year 0 to current year: + if self.options.year == 0: self.options.year = datetime.today().year + # Set the calendar start day: + if self.options.start_day=='sun': + calendar.setfirstweekday(6) + else: + calendar.setfirstweekday(0) + + # initial values: + month_x_pos = 0 + month_y_pos = 0 + + def calculate_size_and_positions(self): + self.doc_w = inkex.unittouu(self.document.getroot().get('width')) + self.doc_h = inkex.unittouu(self.document.getroot().get('height')) + if self.doc_h > self.doc_w: + self.months_per_line = 3 + else: + self.months_per_line = 4 + #self.month_w = self.doc_w / self.months_per_line + self.month_w = (self.doc_w * 0.8) / self.months_per_line + self.month_margin = self.month_w / 10 + self.day_w = self.month_w / 7 + self.day_h = self.month_w / 9 + self.month_h = self.day_w * 7 + if self.options.month == 0: + self.year_margin = (( self.doc_w + self.day_w - + (self.month_w*self.months_per_line) - + (self.month_margin*(self.months_per_line-1)) + ) / 2 ) #- self.month_margin + else: + self.year_margin = ( self.doc_w - self.month_w ) / 2 + self.style_day = { + 'font-size': str( self.day_w / 2 ), + 'font-family': 'arial', + 'text-anchor': 'middle', + 'text-align': 'center', + 'fill': self.options.color_day + } + self.style_weekend = self.style_day.copy() + self.style_weekend['fill'] = self.options.color_weekend + self.style_nmd = self.style_day.copy() + self.style_nmd['fill'] = self.options.color_nmd + self.style_month = self.style_day.copy() + self.style_month['fill'] = self.options.color_month + self.style_month['font-size'] = str( self.day_w / 1.5 ) + self.style_month['font-weight'] = 'bold' + self.style_day_name = self.style_day.copy() + self.style_day_name['fill'] = self.options.color_day_name + self.style_day_name['font-size'] = str( self.day_w / 3 ) + self.style_year = self.style_day.copy() + self.style_year['fill'] = self.options.color_year + self.style_year['font-size'] = str( self.day_w * 2 ) + self.style_year['font-weight'] = 'bold' + + def is_weekend(self, pos): + # weekend values: "sat+sun" or "sat" or "sun" + if self.options.start_day=='sun': + if self.options.weekend=='sat+sun' and pos==0: return True + if self.options.weekend=='sat+sun' and pos==6: return True + if self.options.weekend=='sat' and pos==6: return True + if self.options.weekend=='sun' and pos==0: return True + else: + if self.options.weekend=='sat+sun' and pos==5: return True + if self.options.weekend=='sat+sun' and pos==6: return True + if self.options.weekend=='sat' and pos==5: return True + if self.options.weekend=='sun' and pos==6: return True + return False + + def in_line_month(self, cal): + cal2 = [] + for week in cal: + for day in week: + if day != 0: + cal2.append(day) + return cal2 + + def write_month_header(self, g, m): + txt_atts = {'style': simplestyle.formatStyle(self.style_month), + 'x': str( (self.month_w - self.day_w) / 2 ), + 'y': str( self.day_h / 5 ) } + inkex.etree.SubElement(g, 'text', txt_atts).text = self.options.month_names[m-1] + gw = inkex.etree.SubElement(g, 'g') + week_x = 0 + if self.options.start_day=='sun': + for wday in self.options.day_names: + txt_atts = {'style': simplestyle.formatStyle(self.style_day_name), + 'x': str( self.day_w * week_x ), + 'y': str( self.day_h ) } + inkex.etree.SubElement(gw, 'text', txt_atts).text = wday + week_x += 1 + else: + w2 = self.options.day_names[1:] + w2.append(self.options.day_names[0]) + for wday in w2: + txt_atts = {'style': simplestyle.formatStyle(self.style_day_name), + 'x': str( self.day_w * week_x ), + 'y': str( self.day_h ) } + inkex.etree.SubElement(gw, 'text', txt_atts).text = wday + week_x += 1 + + def create_month(self, m): + txt_atts = { + 'transform': 'translate('+str(self.year_margin + + (self.month_w + self.month_margin) * + self.month_x_pos) + + ','+str((self.day_h * 4) + + (self.month_h * self.month_y_pos))+')', + 'id': 'month_'+str(m)+'_'+str(self.options.year) } + g = inkex.etree.SubElement(self.year_g, 'g', txt_atts) + self.write_month_header(g, m) + gdays = inkex.etree.SubElement(g, 'g') + cal = calendar.monthcalendar(self.options.year,m) + if m == 1: + before_month = \ + self.in_line_month( calendar.monthcalendar(self.options.year-1, 12) ) + else: + before_month = \ + self.in_line_month( calendar.monthcalendar(self.options.year, m-1) ) + if m == 12: + next_month = \ + self.in_line_month( calendar.monthcalendar(self.options.year+1, 1) ) + else: + next_month = \ + self.in_line_month( calendar.monthcalendar(self.options.year, m+1) ) + if len(cal) < 6: # add a line after the last week + cal.append([0,0,0,0,0,0,0]) + if len(cal) < 6: # add a line before the first week (Feb 2009) + cal.reverse() + cal.append([0,0,0,0,0,0,0]) + cal.reverse() + # How mutch before month days will be showed: + bmd = cal[0].count(0) + cal[1].count(0) + before = True + week_y = 0 + for week in cal: + week_x = 0 + for day in week: + style = self.style_day + if self.is_weekend(week_x): style = self.style_weekend + if day == 0: style = self.style_nmd + txt_atts = {'style': simplestyle.formatStyle(style), + 'x': str( self.day_w * week_x ), + 'y': str( self.day_h * (week_y+2) ) } + if day==0: + if before: + inkex.etree.SubElement(gdays, 'text', txt_atts).text = str( before_month[-bmd] ) + bmd -= 1 + else: + inkex.etree.SubElement(gdays, 'text', txt_atts).text = str( next_month[bmd] ) + bmd += 1 + else: + inkex.etree.SubElement(gdays, 'text', txt_atts).text = str(day) + before = False + week_x += 1 + week_y += 1 + self.month_x_pos += 1 + if self.month_x_pos >= self.months_per_line: + self.month_x_pos = 0 + self.month_y_pos += 1 + + def effect(self): + self.validate_options() + self.calculate_size_and_positions() + parent = self.document.getroot() + txt_atts = { + 'id': 'year_'+str(self.options.year) } + self.year_g = inkex.etree.SubElement(parent, 'g', txt_atts) + txt_atts = {'style': simplestyle.formatStyle(self.style_year), + 'x': str( self.doc_w / 2 ), + 'y': str( self.day_w * 1.5 ) } + inkex.etree.SubElement(self.year_g, 'text', txt_atts).text = str(self.options.year) + if self.options.month == 0: + for m in range(1,13): + self.create_month(m) + else: + self.create_month(self.options.month) + + +if __name__ == '__main__': + e = SVGCalendar() + e.affect() -- 2.30.2