The colorful calendar

If you don’t own a copy of RagTime, then you might try Colendar instead (requires Mac OS X 10.5).

Some time ago I created a PDF calendar as an online giveaway for the customers of our company. To my very own surprise, this simple document was well embraced and soon the first change requests appeared in my inbox:

The original color scheme of the calendar matched the colors of the company logo: red, blue, green, with the colors changing from year to year. But some of our customers and agents wanted to have the calendar with a different color. Other people wanted the calendar in a different language or with Friday to be Sunday. US residents asked for calendar weeks matching their requirements and so on…

And every time I had to modify my original RagTime template, print a PDF and send it out. Let alone the work that came with the turn of the years…

When my colleagues lately asked me to create some more customized calendars for them, I finally decided to completely automate the calendar creation with AppleScript.

And because there are - unfortunately - so few RagTime documents to be found on the Internet, I am herewith sharing my work with you:

The Colorful Calendar (ca. 300.6 KB)

(current version 0.6, tested under Mac OS X 10.4, 10.5 and RagTime 5/6)

Colorful calendars created with the RagTime template

For a screenshot of the RagTime document in action, please click on the picture below:

Features of the colorful calendar
¢ DIN A4 Landscape
¢ Years 1804 - 2400
¢ ISO or US calendar weeks
¢ Colors of your very own choice! Yipeeee!
¢ Full localization: Choose a default language* or easily create your own!

  • English, German, French, Spanish & Italian
    ¢ Leap year-awareness
    ¢ Vintage Mac OS 7 progress bar indicating progress of the calendar creation! Now that’s cool! :cool:

Requirements
¢ Mac OS X
¢ RagTime 5 or 6
¢ Font: Andale Mono (most probably already installed)

FAQ
Q: How can I localize the calendar?
A: Open the Inventory of the RagTime document. There you will find a spreadsheet named ‘Dictionary’. Edit this spreadsheet to add any language.

Q: Sometimes values entered in the calendar configuration panel are not used for the calendar creation. Why?
A: After entering values in the calendar configuration panel, you must ‘leave’ the respective cells in order to update the settings. This is easily done by clicking anywhere in the calendar configuration panel before clicking on the ‘Create calendar’ button.

Q: Argh! Where is this damn calendar configuration panel?
A: Open the Inventory of the RagTime document. There you will find a drawing named ‘Cal Config Panel’. Open it.

Q: Can the calendar creation progress run in the background?
A: Yes, but don’t start working with other RagTime documents. The AppleScript works by addressing document 1, which is the foreground document. So while the calendar is created, the document should be in the foreground.

Have fun creating a rainbow of calendars!

P.S.: If you also want to start scripting RagTime and thereby automate your business publishing workflows, I highly recommend reading the following document:

Jürgen Schell: RagTime and AppleScript ¢ A Brief Introduction (RagTime Document)

After downloading, just add the missing ‘.rtd’-suffix to the file name, so you can easily open and read it in RagTime.

Important: Opening and saving the below script code in Script Editor won’t result in a usable AppleScript! That is because the script is targeted at a RagTime template, which you need to install on your Mac. Therefor please download the complete package here.


-- created: September 2007
-- modified: 10.09.2007
-- version: 0.6
-- history:
-- ¢ v0.6:
--   + fixed some date bugs, that could cause problems on non-european systems
--     (thanks to the discussion with RagTime & AppleScript expert Jürgen Schell)
--   + improved leap year check with code contributed by Jürgen Schell
--   + new routine for determining the number of days in a month
--   + the whole date calculation & manipulation is now less AppleScript-dependent
-- ¢ v0.5:
--   + first public release
-- possible features for the future:
-- not yet

on run
	my main()
end run

-- main handler controlling the creation of the calendar
on main()
	-- getting chosen user preferences from the 'Cal Config Panel'
	tell application "RagTime 6"
		tell document 1
			tell table "CCP Year"
				set calyear to value of cell "A1" as integer
			end tell
			tell table "CCP Color"
				set calcol to color of cell 1
				set caltint to tint of cell 1
			end tell
			tell table "CCP Sunday"
				set sunnumber to value of cell "A1" as integer
			end tell
			tell table "CCP Sunday Tint"
				set suntint to value of cell "A1"
			end tell
		end tell
	end tell
	-- retrieving more necessary calendar data
	set weekdaynames to my getweekdaynames()
	set monthnames to my getmonthnames()
	set calweekmode to my getcalweekmode()
	set yeardays to my getyeardaynumber(31, 12, calyear)
	-- beginning calendar creation
	
	-- 1. step: modifying the big calendar year on the upper right of the layout
	my crtbigcalnums(calyear, calcol, caltint)
	-- 2. step: modifying the header for the notes on the right side of the layout
	my crtnotestext(my getnotestext())
	-- initializing the progress bar in the 'Cal Config Panel'
	my prgbar's setmaxval(yeardays)
	my prgbar's initialize()
	-- 3. step: modifying the month columns
	repeat with i from 1 to 12
		set msg to "Currently processing '" & (item i of monthnames) & "'"
		my updatetextbox(msg)
		my crtmonthtable(i, calyear, calcol, caltint, sunnumber, suntint, calweekmode, weekdaynames, (item i of monthnames))
	end repeat
	-- last step: clean up progress bar...
	my prgbar's initialize()
	my updatetextbox("")
end main

-- sets the header of the notes to the given text
on crtnotestext(notestext)
	tell application "RagTime 6"
		tell document 1
			tell table "Events & Notes 1"
				set value of cell "A1" to notestext
			end tell
			tell table "Events & Notes 2"
				set value of cell "A1" to notestext
			end tell
		end tell
	end tell
end crtnotestext

-- sets the big calendar years to the given values
on crtbigcalnums(intyear, calcol, caltint)
	tell application "RagTime 6"
		tell document 1
			tell layout 1
				set text of graphic text 3 of page 1 to intyear
				set color of graphic text 3 of page 1 to calcol
				set tint of graphic text 3 of page 1 to caltint
				set text of graphic text 3 of page 2 to intyear
				set color of graphic text 3 of page 2 to calcol
				set tint of graphic text 3 of page 2 to caltint
			end tell
		end tell
	end tell
end crtbigcalnums

-- modifies a month column according to the given values
on crtmonthtable(intmonth, intyear, calcol, caltint, sunnumber, suntint, calweekmode, weekdaynames, monthname)
	set monthtables to {"01 January", "02 February", "03 March", "04 April", "05 May", "06 June", "07 July", "08 August", "09 September", "10 October", "11 November", "12 December"}
	
	set monthtable to item intmonth of monthtables
	set monthdays to my getmonthdays(intmonth, intyear)
	set weekdaynumber to my getweekdaynumber(1, intmonth, intyear)
	set yeardaynumber to my getyeardaynumber(1, intmonth, intyear)
	
	tell application "RagTime 6"
		tell document 1
			tell table monthtable
				-- header of the month table
				set color of row 1 to calcol
				set tint of row 1 to caltint
				set value of cell "B1" to monthname
				-- calendar part of the month table
				repeat with rownumber from 2 to 32
					-- 'whitening' the current row
					set color of row rownumber to {green:255, blue:255, red:255}
					set tint of row rownumber to 1.0
					-- normalizing the bottom border: maybe it was a Sunday before?
					set properties of bottom border of row rownumber to {pen width:0.25}
					-- deleting former values in the cells
					set cellrange to "A" & rownumber & ":E" & rownumber
					delete range cellrange
					if not (rownumber - 1) > monthdays then
						-- inserting day number
						set value of cell ("A" & rownumber) to (rownumber - 1)
						-- inserting weekday name
						set value of cell ("B" & rownumber) to item weekdaynumber of weekdaynames
						-- inserting calendar week
						if weekdaynumber is 4 then
							set strdate to ((rownumber - 1) & "." & intmonth & "." & intyear) as string
							set calweek to my getcalweek(strdate, calweekmode)
							set value of cell ("C" & rownumber) to calweek
						end if
						-- formatting Sundays
						if weekdaynumber is sunnumber then
							set properties of bottom border of row rownumber to {pen width:0.5}
							set color of row rownumber to calcol
							set tint of row rownumber to suntint
						end if
						-- setting year day number
						set value of cell ("E" & rownumber) to yeardaynumber
						-- updating relevant counters
						set yeardaynumber to yeardaynumber + 1
						set weekdaynumber to weekdaynumber + 1
						if weekdaynumber = 8 then
							set weekdaynumber to 1
						end if
						-- updating progress bar
						my prgbar's increment(1)
					end if
				end repeat
			end tell
		end tell
	end tell
end crtmonthtable

-- indicates if a given year is a leap year
-- the year must be passed as an integer
-- this improved code was contributed by Jürgen Schell,
-- AppleScript & RagTime Guru par excellence
on isleapyear(intyear)
	if intyear mod 400 = 0 then
		return true
	end if
	if intyear mod 100 = 0 then
		return false
	end if
	if intyear mod 4 = 0 then
		return true
	end if
	return false
end isleapyear

-- returns the number of days in a given month of a given year
-- month and year must both be passed as integers
-- is leap year-aware
on getmonthdays(intmonth, intyear)
	if intmonth is 2 and my isleapyear(intyear) then
		return 29
	else
		if intmonth is in {1, 3, 5, 7, 8, 10, 12} then
			return 31
		else if intmonth is in {4, 6, 9, 11} then
			return 30
		else if intmonth is in {2} then
			return 28
		end if
	end if
end getmonthdays

-- returns the calendar week for a given 'string date'
-- the string date must have the format 'dd.mm.yyyy'
on getcalweek(stringdate, calweekmode)
	tell application "RagTime 6"
		tell document 1
			tell table "AS Helper"
				if calweekmode is "ISO" then
					set cell "B2" to stringdate
					finish calculation
					return value of cell "C2" as integer
				else if calweekmode is "US" then
					set cell "B3" to stringdate
					finish calculation
					return value of cell "C3" as integer
				end if
			end tell
		end tell
	end tell
end getcalweek

-- returns the year day number for a given date
-- date must be passed as single integers (day, month, year)
on getyeardaynumber(intday, intmonth, intyear)
	set yeardaynumber to 0
	if intmonth = 1 then
		set yeardaynumber to intday
	else
		repeat with i from 1 to (intmonth - 1)
			set monthdays to my getmonthdays(i, intyear)
			set yeardaynumber to yeardaynumber + monthdays
		end repeat
		set yeardaynumber to yeardaynumber + intday
	end if
	return yeardaynumber
end getyeardaynumber

-- returns the weekday number for a given date
-- US format: 1 = Sunday, 7 = Monday
on getweekdaynumber(intday, intmonth, intyear)
	set stringdate to (intday & "." & intmonth & "." & intyear) as Unicode text
	tell application "RagTime 6"
		tell document 1
			tell table "AS Helper"
				set cell "B10" to stringdate
				finish calculation
				set weekdaynumber to value of cell "B11"
			end tell
		end tell
	end tell
	return (weekdaynumber as integer)
end getweekdaynumber

-- returns a list of 7 weekday names based on the language chosen
-- in the calendar config panel
on getweekdaynames()
	tell application "RagTime 6"
		tell document 1
			tell table "AS Helper"
				set columnnumber to value of cell "B6" as integer
			end tell
			tell table "Dictionary"
				set columncont to column columnnumber
				set weekdaynames to items 15 through 21 of columncont
			end tell
		end tell
	end tell
	
	return weekdaynames
end getweekdaynames

-- returns a list of 12 month names based on the language chosen
-- in the calendar config panel
on getmonthnames()
	tell application "RagTime 6"
		tell document 1
			tell table "AS Helper"
				set columnnumber to (value of cell "B6") as integer
			end tell
			tell table "Dictionary"
				set columncont to column columnnumber
				set monthnames to items 3 through 14 of columncont
			end tell
		end tell
	end tell
	
	return monthnames
end getmonthnames

-- returns the header for the notes according to the chosen language
on getnotestext()
	tell application "RagTime 6"
		tell document 1
			tell table "AS Helper"
				set columnnumber to (value of cell "B6") as integer
			end tell
			tell table "Dictionary"
				set columncont to column columnnumber
				set notestext to last item of columncont
			end tell
		end tell
	end tell
	
	return notestext
end getnotestext

-- returns the calendar week mode chosen in the calenar config panel,
-- 'ISO' or 'US'
on getcalweekmode()
	tell application "RagTime 6"
		tell document 1
			tell table "AS Helper"
				set calweekmode to value of cell "B7"
			end tell
		end tell
	end tell
	
	return calweekmode
end getcalweekmode

-- sets the text box below the progress bar to the given text
on updatetextbox(msg)
	tell application "RagTime 6"
		tell document 1
			tell table "CCP Text box"
				set value of cell "A1" to msg
			end tell
		end tell
	end tell
end updatetextbox

-- progress bar script
-- definitely needs polishing, but works and is fun :)
-- <<<BETA BETA BETA BETA BETA>>>
script prgbar
	property tablename : "CCP Progress bar"
	property curval : 0
	property minval : 1.0
	property maxval : 100.0
	using terms from application "RagTime 6"
		property bgrcol : {red:80.0, green:80.0, blue:100.0}
		property fillcol : {red:27.0, green:27.0, blue:27.0}
	end using terms from
	property bgrtint : 1.0
	property filltint : 1.0
	property tablelength : 10
	
	on setminval(usrval)
		set minval to usrval
	end setminval
	
	on setmaxval(usrval)
		set maxval to usrval
	end setmaxval
	
	on setbgrcol(usrcol)
		set bgrcol to usrcol
	end setbgrcol
	
	on setbgrtint(usrtint)
		set bgrtint to usrtint
	end setbgrtint
	
	on setfillcol(usrcol)
		set fillcol to usrcol
	end setfillcol
	
	on setfilltint(usrtint)
		set filltint to usrtint
	end setfilltint
	
	-- initializes the progress bar
	on initialize()
		set curval to 0
		my adjcolumnwidth()
		tell application "RagTime 6"
			tell document 1
				tell table tablename
					set color of every column to bgrcol
					set tint of every column to bgrtint
				end tell
			end tell
		end tell
	end initialize
	
	-- adjusts the column width to match the 
	-- maximum value of the progress bar
	-- = for a maxval of 300, we need 300 columns
	-- in the visible length of the table
	on adjcolumnwidth()
		-- 1 pt (point) = 0.035 cm (centimeters)
		set printerpoint to 0.035
		-- calculating cm-value
		-- 10 = length of progress indicator table in cm
		set columnwidth to tablelength / maxval
		-- converting cm-value to point-value
		set columnwidth to columnwidth / printerpoint
		
		tell application "RagTime 6"
			tell document 1
				tell table tablename
					set width of every column to columnwidth
				end tell
			end tell
		end tell
	end adjcolumnwidth
	
	-- increments the progress bar by the given value
	on increment(incrval)
		set curval to curval + incrval
		tell application "RagTime 6"
			tell document 1
				tell table tablename
					set color of columns (minval as integer) through (curval as integer) to fillcol
					set tint of columns (minval as integer) through (curval as integer) to filltint
				end tell
			end tell
		end tell
	end increment
end script