Your prescription for increased productivity and profitability
Time to think of gift giving. How about a custom calendar for a friend, colleague, or family member? Place a favorite picture that the recipient would appreciate at the top of a custom calendar and print it out. Just a little thoughtful gift to add your personality to the season.
Calendars for each month of the year are included on a single 8-1/2×11 page. Each of the calendars for the months are themselves tables. So you need to understand how to set up cell styles and table styles. (We will be covering this in future blogs.) For now, you can download the template from our Feature page. The rest is taken care of by a script (included with the download).
…The finished calendar
There is one little problem using tables for calendars in that some months may require six rows to show the dates rather than the normal five. The script will need to take that into consideration.
The template uses a text frame named “Dieline” to identify the area to be used by the calendars. The top portion of the script reserved for an image (566 pts x 140 pts) is named “Image.” The text frame over the oval area for the year is named “YearTitle” which includes styling with paragraph style “Calendar.”
At the top of the calendar area are two frames for the days of the week. These are named “tableHead1” and “tableHead2” respectively and are also used by the script to identify the values for the column widths.
The script assumes that the year to be displayed will be the year following the current year.
At the beginning of the script the user is asked to choose an image for the header portion of the page. To fit nicely in the header frame create an image 566 pts by 140 pts at 300 ppi.
set imageRef to choose file with prompt ("Choose file for Calendar Header")
The script uses the geometric bounds of the “Dieline” text frame to define the total width and height of the Calendar area. To calculate the height of the individual calendars, the total height minus the space allowed between the calendar frames (gap), is divided by 6.
tell spread 1 of document 1 set masterFrame to text frame "Dielist" copy geometric bounds of masterFrame to {y0, x0, y1, x1} set frameWid to x1 - x0 set frameHgt to y1 - y0 set calHgt to round ((frameHgt - (5 * gap)) / 6) ...
Text frames are then created to hold the calendar titles and the calendars.
The text frames for the month titles are named “title” plus a number for the month (as in “title1”.) These frames are also given a label that is the same as the month name. The text frames that hold the month calendars are named “month” plus a number for the month (as in “month1”). These are created in the handler named createFrameswhich takes the width of the calendar title frames and the value for the vertical space between the calendars (gap) as its arguments.
To create the text frames for each column, a loop (from 1 to 2) repeats within another loop (1 to 6) to produce the six rows of two columns necessary for the calendars. Notice in the code below how a temporary variable (tx) is used to define the left horizontal coordinate for each column within the loop:
--in the create frames loop set tx to x10 repeat with i from 1 to 6 set y1 to y0 + calHgt repeat with j from 1 to 2 set monthNum to monthNum + 1 set theLabel to item (monthNum + 1) of monthList set tBounds to {y0, tx, y0 + calHgt, tx + titleWid} make text frame with properties {geometric bounds:tBounds, ¬ name:"title" & monthNum, label:theLabel, applied object style:titleStyle} set calFrame to make text frame with properties ¬ {geometric bounds:{y0, tx + titleWid, y0 + calHgt, tx + titleWid + calWid}, name:"month" & monthNum} set tx to x20 end repeat set tx to x10 set y0 to y1 + gap end repeat
The values for the variables calWid (column width) and calHgt (row height) are returned and used in the createCalendarTable handler.
To control the process for creating the calendars, the script creates a list of lists (calList) in the getCalList() handler. This, and the year header at the top of the page take advantage of a number of date methods:
set theDay to date"February 1 2018" set nextDay to date "March 1 2018" set daysBetween to (nextDay - theDay) div days set yearStr to "" & ((year of (current date)) + 1) set calList to getCalList(yearStr)
The value for the yearStr variable is passed to the getCalList handler which returns the list of list. Each list within the list defines the number of days, number of blank cells needed for the first row, and the total number of rows needed for each month. As each list is created, the number of filled cells in the table’s bottom row (overfill) become the empty cells for the top row for the next month (thefill). A helper handler calculates the number of rows needed for the current month’s calendar plus the number of cells occupied by dates in the bottom row.
on getCalList(theYear) set calList to {} --days in month Dec previous year to Jan this year with exception of February set dayList to {31, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31} --get number of days in February set theDay to date ("February 1 " & theYear) set nextDay to date ("March 1 " & theYear) set item 3 of dayList to (nextDay - theDay) div days --Get day of week as number for December 1 of previous year set firstDay to date ("December 1 " & (theYear - 1)) --set contents of string for table cells before first day to empty string set thefill to (weekday of firstDay as number) - 1 --number of days in December of prevoius year set numDays to (item 1 of dayList) (*calculate number of rows, number of empty spaces at front, and filled cells on last row of calendar table*) set {numRows, overFill} to getnumRows(thefill, numDays) --list containing number days, number of empty cells at front and end of calendar table copy {numDays, thefill, numRows} to the end of calList (*filled cells of last row for last month becomes the empty frames for fir row of the next month*) copy overFill to thefill --repeat for remaining months repeat with i from 2 to count of dayList set numDays to (item i of dayList) set {numRows, overFill} to getnumRows(thefill, numDays) copy {numDays, thefill, numRows} to the end of calList copy overFill to thefill end repeat return calList end getCalList (*calculates number of rows needed to accommodate the number of days plus the empty cells at the front of the table. Returns the number of rows required for the table (numRows) and the number of filled cells in the table's last row -overFill.*) on getnumRows(thefill, numDays) set totalDays to numDays + thefill set numRows to totalDays div 7 if totalDays mod 7 > 0 then set numRows to numRows + 1 set overFill to 7 - ((numRows * 7) - totalDays) else set overFill to 0 end if return {numRows, overFill} end getnumRows
The result of this process is a list of lists with each item in the list indicating the number of days, the number of empty cells in first row of the table.and the number of rows needed to display the days. Notice that there are fourteen entries within calList to include the calendar for December of the previous year and January of the next year.
{{31, 5, 6}, {31, 1, 5}, {28, 4, 5}, {31, 4, 5}, {30, 0, 5}, {31, 2, 5}, {30, 5, 5}, {31, 0, 5}, {31, 3, 5}, {30, 6, 6}, {31, 1, 5}, {30, 4, 5}, {31, 6, 6}, {31, 2, 5}}
To populate the cells for the calendar tables, the script uses a list of strings (tableList). The calendar and the string list both depend on the master list (calList). The string is composed using the number of spaces defined by the number of filled cells of the previous month’s calendar. It is composed by extracting the number of elements needed from the blankList and numList properties identified at the top of the script.
if spaces > 0 then set spaceList to items 1 thru spaces of blankList set tableList to spaceList & items 1 thru numDays of numList else set tableList to items 1 thru numDays of numList end if
The calendar text frames (calItem) creates the table which is then populated with the list of strings (tableList).
tell calItem --the text frame for the calendar set tableRef to make table with properties {column count:7, header row count:0, body row count:numRows} end tell tell tableRef set height of rows 1 thru -1 to rowHgt set applied table style to calStyle tell cells to clear cell style overrides set contents to tableList end tell
You can download the script and the template from the Feature page here or from your browser at http://www.yourscriptdoctor.com/feature
Scripts are provided as examples for instruction. No representation is made for the correctness or completeness of the script. Users are advised to use the script as their own discretion