Thread: Calendar
View Single Post
E.g. in this version, I have changed the font of the title to Trebuchet MS, the day names and numbers to Gill Sans, and added some shading to the boxes:

(* Written by T.K.Egan
* 12 Feb 2007
* inspired by need and http://forums.omnigroup.com/
*
* updated by T.K.Egan
* 14 Feb 2007
* added headers and "editing cells"
*
* requires bsd subsystem and OmniGraffle Professional to be installed
*)

-- preferences (you might edit these...)
property kHorizontalPadding : 10
property kVerticalPadding : 10
property kTitleTextSize : 24
property kHeaderTextSize : 18
property kNormalTextSize : 12
property kUseShortDayNames : true


-- constant data... With so much built in to Applescript these seem like odd omissions
set kMonths to {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
set kFullDayNames to {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
set kShortDayNames to {"Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"}

-- program body begins... Editing the below will almost certainely change the program's behavior
if kUseShortDayNames then
set myDays to kShortDayNames
else
set myDays to kFullDayNames
end if
display dialog "What year is this calendar for:" default answer (year of (current date))
set myYear to text returned of result
set myMonth to (choose from list kMonths with prompt "Now choose the month:" without empty selection allowed and multiple selections allowed)
set myDocumentName to myMonth & " " & myYear as string
set myArgs to (listIndex(myMonth, kMonths) as string) & " " & myYear
set myCalendar to (do shell script "cal " & myArgs)
set AppleScript's text item delimiters to ASCII character 13
set myLines to every text item of myCalendar
set AppleScript's text item delimiters to "" -- always restore delimiters
--first two lines are trash the third line has the day numbers
set myInterestingLine to item 3 of myLines
set myLeadingDayBoxWidthMultiplier to countLeadingSpaces(myInterestingLine) div 3
-- the last line is blank, the next to last line has the last date
set myInterestingLine to item -2 of myLines
set myLastDay to ((characters (length of myInterestingLine) through -2 of myInterestingLine) as string) as number
set myTrailingDayBoxWidthMultiplier to 7 - ((myLeadingDayBoxWidthMultiplier + myLastDay) mod 7)
tell application "OmniGraffle Professional"
activate
make new document with properties {name:myDocumentName}
end tell

set myDayCounter to 0
set myVerticalCursor to kVerticalPadding
set myHeaderCellHeight to kNormalTextSize * 1.5
tell document myDocumentName of application "OmniGraffle Professional"
set myCanvasSize to canvasSize of first canvas
end tell
set myFullWidth to (first item of myCanvasSize as number) - 2 * kHorizontalPadding
set myCalendarDayBoxWidth to myFullWidth div 7
set myCalendarDayBoxHeight to ((second item of myCanvasSize as number) - (2 * kVerticalPadding + myHeaderCellHeight + kTitleTextSize * 1.5)) div ((count myLines) - 3) -- first two and final lines are bogus
tell document myDocumentName of application "OmniGraffle Professional"
--make header
make new shape at end of graphics of first canvas with properties {origin:{kHorizontalPadding, myVerticalCursor}, size:{myFullWidth, kTitleTextSize * 1.5}, draws shadow:false, draws stroke:false, name:"Rectangle", fill color:{65535, 65535, 65535}, text:{font:"Trebuchet MS", size:kTitleTextSize, alignment:center, text:myDocumentName}}
set myVerticalCursor to myVerticalCursor + kTitleTextSize * 1.5
repeat with theDay in myDays
make new shape at end of graphics of first canvas with properties {origin:{myDayCounter * myCalendarDayBoxWidth + kHorizontalPadding, myVerticalCursor}, size:{myCalendarDayBoxWidth, myHeaderCellHeight}, draws shadow:false, name:"Rectangle", fill color:{55535, 55535, 55535}, text:{font:"Gill Sans", size:kHeaderTextSize, alignment:center, text:theDay}}
set myDayCounter to myDayCounter + 1
end repeat
set myVerticalCursor to myVerticalCursor + myHeaderCellHeight
-- make leader
if myLeadingDayBoxWidthMultiplier is greater than 0 then
make new shape at end of graphics of first canvas with properties {origin:{kHorizontalPadding, myVerticalCursor}, size:{myCalendarDayBoxWidth * myLeadingDayBoxWidthMultiplier, myCalendarDayBoxHeight}, draws shadow:false, name:"Rectangle", fill color:{50000, 50000, 50000}, text:{font:"Gill Sans", size:kNormalTextSize}}
end if
set myDayCounter to 0
set myDayOfWeekCounter to myLeadingDayBoxWidthMultiplier
-- make normal calendar day boxes
repeat while myDayCounter is less than myLastDay
repeat while myDayOfWeekCounter is less than 7 and myDayCounter is less than myLastDay
--make a calendar day box
make new shape at end of graphics of first canvas with properties {origin:{myDayOfWeekCounter * myCalendarDayBoxWidth + kHorizontalPadding, myVerticalCursor + kHeaderTextSize + 1}, size:{myCalendarDayBoxWidth, myCalendarDayBoxHeight - (kHeaderTextSize + 1)}, draws shadow:false, name:"Rectangle", text placement:top, fill color:{60000, 60000, 60000}, text:{font:"Gill Sans", size:kNormalTextSize, alignment:left}}
make new shape at end of graphics of first canvas with properties {origin:{myDayOfWeekCounter * myCalendarDayBoxWidth + kHorizontalPadding, myVerticalCursor}, size:{myCalendarDayBoxWidth, myCalendarDayBoxHeight}, draws shadow:false, name:"Rectangle", text placement:top, fill color:{65535, 65535, 65535}, text:{font:"Gill Sans", size:kHeaderTextSize, alignment:right, text:myDayCounter + 1 as string}}
set myDayCounter to myDayCounter + 1
set myDayOfWeekCounter to myDayOfWeekCounter + 1
end repeat
set myDayOfWeekCounter to 0
set myVerticalCursor to myVerticalCursor + myCalendarDayBoxHeight
end repeat
-- make trailing box
if myTrailingDayBoxWidthMultiplier is greater than 0 then
make new shape at end of graphics of first canvas with properties {origin:{kHorizontalPadding + (7 - myTrailingDayBoxWidthMultiplier) * myCalendarDayBoxWidth, myVerticalCursor - myCalendarDayBoxHeight}, size:{myCalendarDayBoxWidth * myTrailingDayBoxWidthMultiplier, myCalendarDayBoxHeight}, draws shadow:false, name:"Rectangle", fill color:{50000, 50000, 50000}, text:{font:"Gill Sans", size:kNormalTextSize}}
end if
end tell

on listIndex(theItem, theList)
repeat with i from 1 to the count of theList
if item i of theList as string = theItem as string then return i
end repeat
return -1
end listIndex

on countLeadingSpaces(theLine)
set myCounter to 1
set myOldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to ""
set myLineAsCharList to every text item of theLine
set AppleScript's text item delimiters to myOldDelimiters
repeat while item myCounter of myLineAsCharList is " "
set myCounter to myCounter + 1
end repeat
return myCounter - 1
end countLeadingSpaces

Last edited by JKT; 2007-02-24 at 04:03 PM..