Tuesday, May 31, 2022

planner pages : LaTeX geeky joy

There are geeky things that I just love love love.  Not surprisingly, one of the disappointments of being a happy nerd is that it's hard to describe my math pursuits in a way that other people can understand, so it's hard to celebrate nifty news.  Anyone want to jump up and down about the time that I discovered a geometric quantification of anamorphic distortion?  No?  (It's so cool, I swear . . . ).  

Earlier this spring, I did a geeky thing that just delighted me; and I still think it's so much fun that I want to try to describe it, with some of the weird technical stuff embedded, but to explain to non-Texperts why this was such a cool adventure for me.  

Here's what I did: I designed monthly calendar pages for my planner, using a mathematical typesetting language called LaTeX.

When I first learned LaTeX, back in grad school, I thought its main (only?) use was to allow us to write those symbols that are part of every cartoon about math:  fractions, weird Greek letters, integral signs, arrows, and such.  It wasn't until a few decades later (of constant LaTeX use) that I discovered that there's a language-within-a-language, something called "PGF/TikZ", that lets people draw lines and other things positioned in highly precise locations.  I discovered this through playing with a fabulous graphing application called "GeoGebra", and it thrilled me so much that I'd often tell other mathematicians about it when we were schmoozing at conferences.  

Nerd-aside:
In GeoGebra Classic 5, if you "File:-->"Export" --> "Export as PFG/TikZ",
you go straight from the picture you created to a string of TikZ code.  

By having GeoGebra do the coding for me, I picked up knowledge myself along the way.  I learned, for example, that the command

\draw (10, 15) -- (18.8, 15);

draws a little line segment, 8.8 centimeters long, at a height of 15 centimeters.  Why is this cool?  For me, it was like discovering that mayonnaise jars have the same necks as regular canning jars, or that the fuel gauge on car dash has a little indication of which side the gas tank is on.  It's such a neat new aspect about something I already thought I knew so well!

So, knowing that I can put lines exactly where I want them, I knew I could create the outline of the calendar, and also (on the reverse side of the page) create lined pages for an index of notes and also a place for my monthly to-do lists  (the place to scribble things like, "wash windows", or "pick cherries",  for when I don't yet know which day in the month I'll want to do it).  


One side of my pages

But I don't want to have a line of code for each line in that page.  Shorter code is better, because it allows for easier changes down the road.  To make it easier to tweak all the lines at once (change color, change thickness), I googled "Latex for loops", and came up with the code to do this:

\foreach \n in {1,...,15} { 
\draw [dotted, line width = 0.75, color=browncolor]  (6.6, \n)  -- (8.8, \n);
\draw [dotted]  (6.6, \n.5)  -- (8.8, \n.5);
}

Figuring out this "for loop" snippet of code was like, I dunno, googling "how to fix my dishwasher" or "how to fold an origami frog" -- you know it's possible; it's just a question of learning from an expert.


The next step was to put in the words and numbers. LaTeX/TikZ can do that, too, with commands that look like this:

\draw (11.1, 16.2) node {\tiny Sunday};

This, too, was fairly easy to automate with the 12 month names. LaTeX has a date counter that you can advance, and so for each month, I used the code that extracted the name of the month, putting it first in just the right place for a tab (so cute!) and then at the top of the left and right pages, as such:   
\draw (18.8-\the\month*2/3, 17.5) node {\small \monthname};  % top tab

\draw (4.4, 16.6) node {\monthname\ \the\year};

\draw (14.4, 16.6) node {\monthname\ \the\year};


Months and tabs
It's actually that tab at the top that tickles me the most.   In the past, when I made pages, I'd have to tape on hand-written labels for tabs after the pages were printed, but I realized mid-project I could have the tab be part of the paper and just cut carefully.  Do you ever wonder why math teachers keep asking those annoying questions about when Train A meets Train B?  It's so that you can figure out questions like, "where do the tabs at the top of the page go, and how do you make sure the word "July" is printed in the same place on the front AND the back of the paper?"   Totally geek happiness, adding these tabs that slide along the top!  

Taped-on tabs from previous excel-formatted pages.

Okay, but HERE comes the part that was REALLY fun to figure out: where to put the numbers of the days (and -- especially -- where NOT to put them)?  This part was fun in a crossword-puzzle kind of way, or Sudoko, or some-such.  The reason this is tricky is that, on any good calendar page, there are days that are empty.  There are usually a bunch of blank blocks before "1" and again after the last day of the month. The fact that each month has a different number of days makes this even more fun to play with: the rhym "30 days hath September, April, June, and November" is helpful for memorizing, but not for coding.  So the puzzle is this: how do I tell my program when to write the days, and when not to?

The solution?  Learn the Ninja art of of "If-Then-Else".   For each box in the calendar grid, I built a command that checked whether the month of the counter ("\the\month") matched the month of the current calendar page (which for technical reasons is designated in my code as "#2"), and then drew the day (or not, depending) and then moved over into the next square:

\ifthenelse{\the\month=#2}  {\draw(17.7, #1) node  {\the\day};} { } \AdvanceDate[1]


Lovely, right? That line says if \the\month = #2, then draw stuff, otherwise do nothing (denoted "{}").  

But to add extra degrees of difficulties, every once in a while there's a month that spreads across six, not just five, calendar weeks.  April 2023 is one such month:  April 1 is on a Saturday, then there are four full weeks, and then April 30 is on the next Sunday. Where do I stick April 30?  I don't have space in my usual grid to add the 30th below the 23rd, so I decided to stick it at the top.  

April 30 (Sunday) and April 1 (Saturday) are both in the top row.

How to do this?  [Fast forward past many scratching-my-head hours, and many don't-quite-work attempts].  I finally hit upon a very workable solution: in the first two blocks of each page, time-travel forward 5 weeks to see if it's one of those "special" days, print that date if it is and don't print it if it isn't, and then travel back in time to the normal date to resume normal printing.  This is what time travel looks like in my LaTeX code:

\def\SpecialMonday{\AdvanceDate[35]\ifthenelse{\the\day>29} 

        {\draw(13.3, 15.7) node {\the\day}; }{ } \AdvanceDate[-35] }

I totally feel so clever.  

In fact, I was on such a roll that I decided to see if I could ALSO get people's birthdays automatically added on the right days.  And, what the heck, why not also see if I could add their current age?  More puzzling-challenge-searching, and I finally decided to use lists, together with a command that subtracts the birth year of the person from the current year.  So, for example, a list of events in January might have

 . . . 
, % 25
Lisa \BORN{1991} , % 26
 , % 27
. . . 

and then the command

\draw(11.1, 15.7-2.5) node {\small \em\textcolor{orangecolor}{\DTLlistelement{\Events}{\the\day}}};


would put Lisa's birthday and age on the bottom of the block for the 26th, whatever day (and age) it happens to be that year, while writing nothing on nearby days.
Birthday and age, generated automatically. 
Whoop!

So . . . here's the upshot of all this.  Excel versions come and go, but my LaTeX code is stable enough to last me a lifetime.  From here on in, I can change one line -- just updating what day is the first Sunday on  a new year (2023 begins on Sunday, January 1, 2023; 2024 "begins" on Sunday, December 31, 2023, etc), then hit "compile", and I'll have beautiful planner pages, with birthdays and etcetera all in exactly the right places.  

It'll be super easy to make new pages . . . but, ironically and pleasantly, it was a lot more fun having difficulty writing the code in the first place.  


No comments:

Post a Comment

Update, somewhere in January

By now, I'm kind of losing track of which day is which . . . ironic, because of spending so much time on and off of train tracks.  So I&...