diff options
| author | Nicolas Dufour <nicoduf@yahoo.fr> | 2012-01-18 20:49:57 +0000 |
|---|---|---|
| committer | JazzyNico <nicoduf@yahoo.fr> | 2012-01-18 20:49:57 +0000 |
| commit | 9019af105105ef44a42abc9d6657efaf83904fdf (patch) | |
| tree | ffb64f3995ba8b2c3f394bf24dd7712d3b2a1304 | |
| parent | add tooltip for powerstroke control points (diff) | |
| download | inkscape-9019af105105ef44a42abc9d6657efaf83904fdf.tar.gz inkscape-9019af105105ef44a42abc9d6657efaf83904fdf.zip | |
Extensions. Adding week number in the calendar extension (see Bug #620159)
(bzr r10907)
| -rw-r--r-- | share/extensions/svgcalendar.inx | 3 | ||||
| -rwxr-xr-x | share/extensions/svgcalendar.py | 313 |
2 files changed, 188 insertions, 128 deletions
diff --git a/share/extensions/svgcalendar.inx b/share/extensions/svgcalendar.inx index 56f5f62ab..75f843101 100644 --- a/share/extensions/svgcalendar.inx +++ b/share/extensions/svgcalendar.inx @@ -9,6 +9,7 @@ <param name="year" type="int" min="0" max="3000" _gui-text="Year (4 digits):">2011</param> <param name="month" type="int" min="0" max="12" _gui-text="Month (0 for all):">0</param> <param name="fill-empty-day-boxes" type="boolean" _gui-text="Fill empty day boxes with next month's days">true</param> + <param name="show-week-number" type="boolean" _gui-text="Show week number">false</param> <param name="start-day" type="enum" _gui-text="Week start day"> <_item value="sun">Sunday</_item> <_item value="mon">Monday</_item> @@ -33,12 +34,14 @@ <param name="color-day" type="string" _gui-text="Day color:">#000000</param> <param name="color-weekend" type="string" _gui-text="Weekend day color:">#787878</param> <param name="color-nmd" type="string" _gui-text="Next month day color:">#B0B0B0</param> + <param name="color-weeknr" type="string" _gui-text="Week number color:">#787878</param> </page> <page name="localization" _gui-text="Localization"> <_param name="l10n-help" type="description">You may change the names for other languages:</_param> <_param name="month-names" type="string" _gui-text="Month names:" xml:space="preserve">January February March April May June July August September October November December</_param> <_param name="day-names" type="string" _gui-text="Day names:" xml:space="preserve">Sun Mon Tue Wed Thu Fri Sat</_param> <_param name="day-names-help" type="description">The day names list must start from Sunday.</_param> + <_param name="weeknr-name" type="string" _gui-text="Week number column name:" xml:space="preserve">Wk</_param> <param name="encoding" _gui-text="Char Encoding:" type="enum"> <item value="arabic">arabic</item> <item value="big5-tw">big5-tw</item> diff --git a/share/extensions/svgcalendar.py b/share/extensions/svgcalendar.py index 8390c33f7..818dbd0a4 100755 --- a/share/extensions/svgcalendar.py +++ b/share/extensions/svgcalendar.py @@ -6,6 +6,12 @@ A calendar generator plugin for Inkscape, but also can be used as a standalone command line application. Copyright (C) 2008 Aurelio A. Heckert <aurium(a)gmail.com> +Week number option added by Olav Vitters and Nicolas Dufour (2012) + +More on ISO week number calculation on: +http://en.wikipedia.org/wiki/ISO_week_date +(The first week of a year is the week that contains the first Thursday +of the year.) 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 @@ -22,11 +28,15 @@ 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.2" +__version__ = "0.3" -import inkex, simplestyle, re, calendar +import calendar +import re from datetime import * +import inkex +import simplestyle + class SVGCalendar (inkex.Effect): def __init__(self): @@ -46,6 +56,10 @@ class SVGCalendar (inkex.Effect): action="store", type="inkbool", dest="fill_edb", default=True, help="Fill empty day boxes with next month days.") + self.OptionParser.add_option("--show-week-number", + action="store", type="inkbool", + dest="show_weeknr", default=False, + help="Include a week number column.") self.OptionParser.add_option("--start-day", action="store", type="string", dest="start_day", default="sun", @@ -94,15 +108,25 @@ class SVGCalendar (inkex.Effect): action="store", type="string", dest="color_nmd", default="#BBB", help='Color for the next month day, in enpty day boxes.') + self.OptionParser.add_option("--color-weeknr", + action="store", type="string", + dest="color_weeknr", default="#808080", + help='Color for the week numbers.') 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', + 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.') + self.OptionParser.add_option("--weeknr-name", + action="store", type="string", + dest="weeknr_name", default='Wk', + help='The week number column name for localization.') self.OptionParser.add_option("--encoding", action="store", type="string", dest="input_encode", default='utf-8', @@ -110,72 +134,78 @@ class SVGCalendar (inkex.Effect): def validate_options(self): #inkex.errormsg( self.options.input_encode ) - # 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: + # 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)+ + 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'] + 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 "'+ + 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: + 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 # Year 1 starts it's week at monday, obligatorily if self.options.year == 1: self.options.start_day = 'mon' - # Set the calendar start day: + # Set the calendar start day if self.options.start_day=='sun': - calendar.setfirstweekday(6) + calendar.setfirstweekday(6) else: - calendar.setfirstweekday(0) - # Convert string numbers with unit to user space float numbers: + calendar.setfirstweekday(0) + # Convert string numbers with unit to user space float numbers self.options.month_width = inkex.unittouu( self.options.month_width ) self.options.month_margin = inkex.unittouu( self.options.month_margin ) - # initial values: + # initial values month_x_pos = 0 month_y_pos = 0 + weeknr = 0 def calculate_size_and_positions(self): #month_margin month_width months_per_line auto_organize self.doc_w = inkex.unittouu(self.document.getroot().get('width')) self.doc_h = inkex.unittouu(self.document.getroot().get('height')) + if self.options.show_weeknr: + self.cols_before = 1 + else: + self.cols_before = 0 if self.options.auto_organize: - if self.doc_h > self.doc_w: - self.months_per_line = 3 - else: - self.months_per_line = 4 + if self.doc_h > self.doc_w: + self.months_per_line = 3 + else: + self.months_per_line = 4 else: - self.months_per_line = self.options.months_per_line + self.months_per_line = self.options.months_per_line #self.month_w = self.doc_w / self.months_per_line if self.options.auto_organize: - self.month_w = (self.doc_w * 0.8) / self.months_per_line - self.month_margin = self.month_w / 10 + self.month_w = (self.doc_w * 0.8) / self.months_per_line + self.month_margin = self.month_w / 10 else: - self.month_w = self.options.month_width - self.month_margin = self.options.month_margin - self.day_w = self.month_w / 7 + self.month_w = self.options.month_width + self.month_margin = self.options.month_margin + self.day_w = self.month_w / (7 + self.cols_before) 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 + 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.year_margin = (self.doc_w - self.month_w) / 2 self.style_day = { - 'font-size': str( self.day_w / 2 ), + 'font-size': str(self.day_w / 2), 'font-family': 'arial', 'text-anchor': 'middle', 'text-align': 'center', @@ -187,153 +217,180 @@ class SVGCalendar (inkex.Effect): 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-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_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-size'] = str(self.day_w * 2) self.style_year['font-weight'] = 'bold' + self.style_weeknr = self.style_day.copy() + self.style_weeknr['fill'] = self.options.color_weeknr + self.style_weeknr['font-size'] = str(self.day_w / 3) 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 + 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 + 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) + 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 ) } + 'x': str((self.month_w - self.day_w) / 2), + 'y': str(self.day_h / 5 )} try: - inkex.etree.SubElement(g, 'text', txt_atts).text = unicode(self.options.month_names[m-1], self.options.input_encode) + inkex.etree.SubElement(g, 'text', txt_atts).text = unicode( + self.options.month_names[m-1], + self.options.input_encode) except: - inkex.errormsg('You must select your correct system encode.') - exit(1) + inkex.errormsg(_('You must select a correct system encoding.')) + exit(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 ) } - try: - inkex.etree.SubElement(gw, 'text', txt_atts).text = unicode(wday, self.options.input_encode) - except: - inkex.errormsg('You must select your correct system encode.') - exit(1) - week_x += 1 + day_names = self.options.day_names[:] else: - w2 = self.options.day_names[1:] - w2.append(self.options.day_names[0]) - for wday in w2: + day_names = self.options.day_names[1:] + day_names.append(self.options.day_names[0]) + + if self.options.show_weeknr: + day_names.insert(0, self.options.weeknr_name) + + for wday in day_names: txt_atts = {'style': simplestyle.formatStyle(self.style_day_name), 'x': str( self.day_w * week_x ), 'y': str( self.day_h ) } try: - inkex.etree.SubElement(gw, 'text', txt_atts).text = unicode(wday, self.options.input_encode) + inkex.etree.SubElement(gw, 'text', txt_atts).text = unicode( + wday, + self.options.input_encode) except: - inkex.errormsg('You must select your correct system encode.') - exit(1) + inkex.errormsg(_('You must select a correct system encoding.')) + exit(1) 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) } + '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: - if self.options.year > 1: - before_month = \ - self.in_line_month( calendar.monthcalendar(self.options.year-1, 12) ) + if self.options.year > 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) ) + 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) ) + 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() + 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 and not self.options.fill_edb: - pass # draw nothing - elif 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 + if (self.weeknr != 0 and \ + ((self.options.start_day == 'mon' and week[0] != 0) or \ + (self.options.start_day == 'sun' and week[1] != 0))) or \ + (self.weeknr == 0 and \ + ((self.options.start_day == 'mon' and week[3] > 0) or \ + (self.options.start_day == 'sun' and week[4] > 0))): + self.weeknr += 1 + week_x = 0 + if self.options.show_weeknr: + # Remove leap week (starting previous year) and empty weeks + if self.weeknr != 0 and not (week[0] == 0 and week[6] == 0): + style = self.style_weeknr + txt_atts = {'style': simplestyle.formatStyle(style), + 'x': str(self.day_w * week_x), + 'y': str(self.day_h * (week_y + 2))} + inkex.etree.SubElement(gdays, 'text', txt_atts).text = str(self.weeknr) + week_x += 1 + else: + week_x += 1 + for day in week: + style = self.style_day + if self.is_weekend(week_x - self.cols_before): 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 and not self.options.fill_edb: + pass # draw nothing + elif 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 + 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) } + 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 ) } + '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) + for m in range(1, 13): + self.create_month(m) else: - self.create_month(self.options.month) + self.create_month(self.options.month) if __name__ == '__main__': #pragma: no cover |
