Code

publishing calendar generator extension
authoraurium <aurium@users.sourceforge.net>
Thu, 22 Jan 2009 22:09:33 +0000 (22:09 +0000)
committeraurium <aurium@users.sourceforge.net>
Thu, 22 Jan 2009 22:09:33 +0000 (22:09 +0000)
share/extensions/svgcalendar.inx [new file with mode: 0644]
share/extensions/svgcalendar.py [new file with mode: 0755]

diff --git a/share/extensions/svgcalendar.inx b/share/extensions/svgcalendar.inx
new file mode 100644 (file)
index 0000000..da07d12
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">\r
+  <_name>Calendar Generator</_name>
+  <id>org.inkscape.calendar</id>\r
+
+  <dependency type="executable" location="extensions">svgcalendar.py</dependency>
+  <dependency type="executable" location="extensions">inkex.py</dependency>\r
+
+  <param name="tab" type="notebook">\r
+    <page name="tab" _gui-text="Configuration">\r
+      <param name="month" type="int" min="0" max="12" _gui-text="Month (0 for all)">0</param>
+      <param name="year" type="int" min="0" max="3000" _gui-text="Ano (0 for current)">0</param>
+      <param name="fill-empty-day-boxes" type="boolean" _gui-text="Fill empty day boxes with next month days">true</param>
+      <param name="start-day" type="enum" _gui-text="Week start day">\r
+        <_item value="sun">Sunday</_item>\r
+        <_item value="mon">Monday</_item>\r
+      </param>\r
+      <param name="weekend" type="enum" _gui-text="Weekend">\r
+        <_item value="sat+sun">Saturday and Sunday</_item>\r
+        <_item value="sat">Saturday</_item>\r
+        <_item value="sun">Sunday</_item>\r
+      </param>\r
+    </page>
+    <page name="tab" _gui-text="Colors">\r
+      <param name="color-year"     type="string" _gui-text="Year color">#808080</param>
+      <param name="color-month"    type="string" _gui-text="Month color">#686868</param>
+      <param name="color-day-name" type="string" _gui-text="Week day name color ">#909090</param>
+      <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>
+    </page>
+    <page name="tab" _gui-text="Localization">\r
+      <_param name="l10n-help" type="description">You may change the names for other languages:</_param>\r
+      <_param name="month-names"  type="string" _gui-text="Month names">January February March April May June July August September October November December</_param>
+      <_param name="day-names"  type="string" _gui-text="Day names">Sun Mon Tue Wed Thu Fri Sat</_param>
+      <_param name="day-names-help" type="description">(The day name list must start in sunday)</_param>\r
+    </page>
+  </param>
+  <effect>
+    <object-type>all</object-type>
+    <effects-menu>\r
+      <submenu _name="Misc"/>\r
+    </effects-menu>\r
+  </effect>
+  <script>
+    <command reldir="extensions" interpreter="python">svgcalendar.py</command>
+  </script>
+</inkscape-extension>
diff --git a/share/extensions/svgcalendar.py b/share/extensions/svgcalendar.py
new file mode 100755 (executable)
index 0000000..dba73ed
--- /dev/null
@@ -0,0 +1,292 @@
+#!/usr/bin/env python
+\r
+'''\r
+calendar.py
+A calendar generator plugin for Inkscape, but also can be used as a standalone
+command line application.
+\r
+Copyright (C) 2008 Aurelio A. Heckert <aurium(a)gmail.com>\r
+\r
+This program is free software; you can redistribute it and/or modify\r
+it under the terms of the GNU General Public License as published by\r
+the Free Software Foundation; either version 2 of the License, or\r
+(at your option) any later version.\r
+\r
+This program is distributed in the hope that it will be useful,\r
+but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+GNU General Public License for more details.\r
+\r
+You should have received a copy of the GNU General Public License\r
+along with this program; if not, write to the Free Software\r
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+'''\r
+
+__version__ = "0.1"
+
+import inkex, simplestyle, re, calendar
+from datetime import *
+\r
+class SVGCalendar (inkex.Effect):\r
+
+    def __init__(self):\r
+        inkex.Effect.__init__(self)\r
+        self.OptionParser.add_option("--tab",\r
+          action="store", type="string",\r
+          dest="tab")\r
+        self.OptionParser.add_option("--month",\r
+          action="store", type="int",\r
+          dest="month", default=0,\r
+          help="Month to be generated. If 0, then the entry year will be generated.")\r
+        self.OptionParser.add_option("--year",
+          action="store", type="int",\r
+          dest="year", default=0,\r
+          help="Year to be generated. If 0, then the current year will be generated.")\r
+        self.OptionParser.add_option("--fill-empty-day-boxes",
+          action="store", type="inkbool",\r
+          dest="fill_edb", default=True,\r
+          help="Fill empty day boxes with next month days.")\r
+        self.OptionParser.add_option("--start-day",
+          action="store", type="string",\r
+          dest="start_day", default="sun",\r
+          help='Week start day. ("sun" or "mon")')\r
+        self.OptionParser.add_option("--weekend",
+          action="store", type="string",\r
+          dest="weekend", default="sat+sun",\r
+          help='Define the weekend days. ("sat+sun" or "sat" or "sun")')\r
+        self.OptionParser.add_option("--color-year",
+          action="store", type="string",\r
+          dest="color_year", default="#888",\r
+          help='Color for the year header.')\r
+        self.OptionParser.add_option("--color-month",
+          action="store", type="string",\r
+          dest="color_month", default="#666",\r
+          help='Color for the month name header.')\r
+        self.OptionParser.add_option("--color-day-name",
+          action="store", type="string",\r
+          dest="color_day_name", default="#999",\r
+          help='Color for the week day names header.')\r
+        self.OptionParser.add_option("--color-day",
+          action="store", type="string",\r
+          dest="color_day", default="#000",\r
+          help='Color for the common day box.')\r
+        self.OptionParser.add_option("--color-weekend",
+          action="store", type="string",\r
+          dest="color_weekend", default="#777",\r
+          help='Color for the weekend days.')\r
+        self.OptionParser.add_option("--color-nmd",
+          action="store", type="string",\r
+          dest="color_nmd", default="#BBB",\r
+          help='Color for the next month day, in enpty day boxes.')\r
+        self.OptionParser.add_option("--month-names",
+          action="store", type="string",\r
+          dest="month_names", default='January February March April May June '+\
+                              'July August September October November December',\r
+          help='The month names for localization.')
+        self.OptionParser.add_option("--day-names",
+          action="store", type="string",\r
+          dest="day_names", default='Sun Mon Tue Wed Thu Fri Sat',\r
+          help='The week day names for localization.')\r
+
+    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:\r
+        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']\r
+        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),\r
+                    '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),\r
+                        '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),\r
+                        '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),\r
+                        '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),\r
+                    '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__':\r
+    e = SVGCalendar()\r
+    e.affect()\r