12-Canvas Calendar
Here’s an Omni Automation plug-in for OmniGraffle that creates a calendar for a specifed year. A calendar for each month of the specified year is placed on its own canvas, and the text shapes for each day of the month are named using the index of the month and the index of the day, for example: 2-24
Twelve Canvas Calendar
/*{
"type": "action",
"targets": ["omnigraffle"],
"author": "Otto Automator",
"identifier": "com.omni-automation.og.twelve-canvas-calendar",
"version": "1.4",
"description": "This action will add twelve canvases to current document, each containing a monthly calendar for the specified year.",
"label": "Twelve Canvas Calendar",
"shortLabel": "Calendar",
"paletteLabel": "Calendar",
"image": "calendar"
}*/
(() => {
const action = new PlugIn.Action(async function(selection, sender){
try {
var localeCode = "en-us"
// CREATE FORM FOR GATHERING USER INPUT
inputForm = new Form()
// CREATE TEXT FIELD
textField = new Form.Field.String(
"textInput",
null,
new Date().getFullYear().toString()
)
// ADD THE FIELD TO THE FORM
inputForm.addField(textField)
// VALIDATE THE USER INPUT
inputForm.validate = function(formObject){
textValue = formObject.values["textInput"]
if(!textValue){return false}
intValue = parseInt(textValue)
validation = (isNaN(intValue) || intValue < 1979 || intValue >= 3000) ? false:true
return validation
}
// PRESENT THE FORM TO THE USER
formPrompt = "Enter the year for the calendar:"
formObject = await inputForm.show(formPrompt,"Continue")
// PROCESSING USING THE DATA EXTRACTED FROM THE FORM
textValue = formObject.values["textInput"]
calendarYear = Number(textValue)
// CALENDAR PROPERTIES
cellWidth = 100
cellHeight = 75
indent = 36
for (var m = 1; m <= 12; m++ ){
monthName = nameOfMonth(m, localeCode)
dayCount = daysInMonth(m, calendarYear)
startDay = startingWeekdayIndexForMonth(m, calendarYear)
rowCount = weekCount(m, calendarYear)
cnvs = addCanvas()
cnvs.name = monthName
// Month Title
titleShape = cnvs.addShape('Rectangle',new Rect(indent, indent, cellWidth * 7, cellHeight))
titleShape.text = monthName + " " + calendarYear.toString()
setUpMonthTitle(titleShape)
dayIndex = 1
for (var r = 1; r <= rowCount; r++ ){
leftOffset = indent
topOffset = indent + (cellHeight * r)
for (var c = 0; c < 7; c++ ){
cell = cnvs.addShape('Rectangle',new Rect(leftOffset, topOffset, cellWidth, cellHeight))
leftOffset = leftOffset + cellWidth
if (r == 1 && c >= startDay){
cell.name = String(m) + "-" + String(dayIndex)
cell.text = dayIndex.toString()
setupCell(cell)
dayIndex = dayIndex + 1
} else if (r != 1 && dayIndex <= dayCount){
cell.name = String(m) + "-" + String(dayIndex)
cell.text = dayIndex.toString()
setupCell(cell)
dayIndex = dayIndex + 1
} else {
cell.name = "blank"
setUpEmptyCell(cell)
}
}
}
}
firstMonthName = nameOfMonth(1, localeCode)
for (cnvs of canvases){
console.log(cnvs.name)
if (cnvs.name === firstMonthName){
document.windows[0].selection.view.canvas = cnvs
break
}
}
}
catch(err){
if(!err.causedByUserCancelling){
new Alert(err.name, err.message).show()
}
}
});
action.validate = function(selection, sender){
return true
};
return action;
})();
function setUpMonthTitle(shape){
shape.fillColor = Color.white
shape.shadowColor = null
shape.strokeType = StrokeType.Single
shape.strokeColor = Color.black
shape.strokePattern = StrokeDash.Solid
shape.strokeThickness = 2
shape.textSize = 48
shape.fontName = "Helvetica-Bold"
shape.textColor = Color.black
shape.textHorizontalPadding = 10
shape.textHorizontalAlignment = HorizontalTextAlignment.Center
}
function setupCell(shape){
shape.fillColor = Color.white
shape.shadowColor = null
shape.strokeType = StrokeType.Single
shape.strokeColor = Color.black
shape.strokePattern = StrokeDash.Solid
shape.strokeThickness = 2
shape.textSize = 18
shape.fontName = "Helvetica"
shape.textColor = Color.black
shape.textHorizontalPadding = 10
shape.textVerticalPadding = 10
shape.textVerticalPlacement = VerticalTextPlacement.Top
shape.textHorizontalAlignment = HorizontalTextAlignment.Right
}
function setUpEmptyCell(shape){
shape.fillColor = Color.White(0.8,1)
shape.shadowColor = null
shape.strokeType = StrokeType.Single
shape.strokeColor = Color.black
shape.strokePattern = StrokeDash.Solid
shape.strokeThickness = 2
shape.textSize = 18
shape.fontName = "Helvetica"
shape.textColor = Color.black
shape.textHorizontalPadding = 10
shape.textVerticalPadding = 10
shape.textVerticalPlacement = VerticalTextPlacement.Top
shape.textHorizontalAlignment = HorizontalTextAlignment.Right
}
function daysInMonth(month, year){
return new Date(year, month, 0).getDate();
}
function startingWeekdayIndexForMonth(month, year){
// returns 0-6 with 0 as Sunday
return new Date(year, month - 1, 1).getDay();
}
function weekCount(month, year){
firstOfMonth = new Date(year, month - 1, 1);
lastOfMonth = new Date(year, month, 0);
used = firstOfMonth.getDay() + lastOfMonth.getDate();
return Math.ceil( used / 7);
}
function nameOfMonth(month, locale){
yr = new Date().getFullYear();
objDate = new Date(yr, month - 1, 1);
return objDate.toLocaleString(locale,{month:"long"});
}