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 INPUTinputForm = new Form()// CREATE TEXT FIELDtextField = new Form.Field.String("textInput",null,new Date().getFullYear().toString())// ADD THE FIELD TO THE FORMinputForm.addField(textField)// VALIDATE THE USER INPUTinputForm.validate = function(formObject){textValue = formObject.values["textInput"]if(!textValue){return false}intValue = parseInt(textValue)validation = (isNaN(intValue) || intValue < 1979 || intValue >= 3000) ? false:truereturn validation}// PRESENT THE FORM TO THE USERformPrompt = "Enter the year for the calendar:"formObject = await inputForm.show(formPrompt,"Continue")// PROCESSING USING THE DATA EXTRACTED FROM THE FORMtextValue = formObject.values["textInput"]calendarYear = Number(textValue)// CALENDAR PROPERTIEScellWidth = 100cellHeight = 75indent = 36for (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 TitletitleShape = cnvs.addShape('Rectangle',new Rect(indent, indent, cellWidth * 7, cellHeight))titleShape.text = monthName + " " + calendarYear.toString()setUpMonthTitle(titleShape)dayIndex = 1for (var r = 1; r <= rowCount; r++ ){leftOffset = indenttopOffset = indent + (cellHeight * r)for (var c = 0; c < 7; c++ ){cell = cnvs.addShape('Rectangle',new Rect(leftOffset, topOffset, cellWidth, cellHeight))leftOffset = leftOffset + cellWidthif (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 = cnvsbreak}}}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.whiteshape.shadowColor = nullshape.strokeType = StrokeType.Singleshape.strokeColor = Color.blackshape.strokePattern = StrokeDash.Solidshape.strokeThickness = 2shape.textSize = 48shape.fontName = "Helvetica-Bold"shape.textColor = Color.blackshape.textHorizontalPadding = 10shape.textHorizontalAlignment = HorizontalTextAlignment.Center}function setupCell(shape){shape.fillColor = Color.whiteshape.shadowColor = nullshape.strokeType = StrokeType.Singleshape.strokeColor = Color.blackshape.strokePattern = StrokeDash.Solidshape.strokeThickness = 2shape.textSize = 18shape.fontName = "Helvetica"shape.textColor = Color.blackshape.textHorizontalPadding = 10shape.textVerticalPadding = 10shape.textVerticalPlacement = VerticalTextPlacement.Topshape.textHorizontalAlignment = HorizontalTextAlignment.Right}function setUpEmptyCell(shape){shape.fillColor = Color.White(0.8,1)shape.shadowColor = nullshape.strokeType = StrokeType.Singleshape.strokeColor = Color.blackshape.strokePattern = StrokeDash.Solidshape.strokeThickness = 2shape.textSize = 18shape.fontName = "Helvetica"shape.textColor = Color.blackshape.textHorizontalPadding = 10shape.textVerticalPadding = 10shape.textVerticalPlacement = VerticalTextPlacement.Topshape.textHorizontalAlignment = HorizontalTextAlignment.Right}function daysInMonth(month, year){return new Date(year, month, 0).getDate();}function startingWeekdayIndexForMonth(month, year){// returns 0-6 with 0 as Sundayreturn 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"});}