Calendar OCR
Each Meadows franchise publishes its own monthly flavor calendar, usually as an image or PDF.
The risky errors were one cell wide. A flavor could land on the next day and the schedule would still look right. I built the importer around that failure.
A schedule appears only after its source calendar passes a whole-image audit and deterministic date checks.
Finding each calendar
The Meadows location directory supplies the franchise list, but the calendars themselves are scattered across franchise sites. Some sites link an image or PDF directly. Others route through Linktree or embed the calendar in Google Sites. For Instagram, the importer uses the post’s Open Graph image URL to recover the complete image.
A small resolver for each publishing route locates the current calendar. The first page of a PDF is rendered to PNG before transcription.
Preserving the date grid
Plain OCR found most flavor names but lost the relationship between text and date boxes. Vision models preserved more of the layout, yet could still shift a flavor to an adjacent day. I made the printed date the anchor for every entry, including cells that contain two dates.
Qwen3.6-35B-A3B-MLX-8bit was the most reliable on the calendars I tested. It reads the printed date inside each cell instead of assuming entries appear in sequence. Custard and starred yogurt stay in separate fields. When one grid cell is divided between two printed dates, each flavor stays with the date printed on its side. Closures and promotions stay with the dates they cover.
- Choc. Toasted Coconut
Cookies-N-Cream - Butter Pecan
Mallocup
Transcribe once, audit independently
Qwen produces the first schedule. Gemma 4 then receives the whole source image and that transcription, compares them cell by cell, and returns complete replacement entries only for dates that are missing or disagree with the image. Keeping corrections local avoids rewriting thirty correct days to fix one wrong cell.
The two models have different jobs: Qwen recovers the schedule; Gemma checks its correspondence with the page. The audit sees the complete calendar so it can catch misplaced entries, spanning closures, and split cells that a crop would hide.
A complete month or no import
A deterministic validator decides whether the month can publish. The schedule must contain every date from the first through the last day of the month exactly once. An ordinary date also needs at least one custard flavor; a documented closure or blank source cell can remain empty. A missing date, duplicate date, date outside the month, or unresolved image-audit finding rejects the import. Failed months stay unpublished.