forked from nichtich/life-in-weeks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
calendar.tex
157 lines (130 loc) · 4.51 KB
/
calendar.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
%
% This LaTeX file creates a calendar of all weeks in a person's lifetime,
% similar to the life calendar created by Tim Urban in his blog:
% <http://waitbutwhy.com/2014/05/life-weeks.html>
%
% This calendar correctly handles leap years, weekdays and calendar years.
%
% Each week takes 5mm x 5mm (shown as rectangle of 4mm x 4mm), so at most
% 82 years fit onto a A3 page of paper.
%
% To create a PDF, manage to install required LaTeX packages and run:
%
% $ pdflatex calendar.tex
%
\documentclass[a3paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepackage{xcolor}
\usepackage{calc}
\usepackage{datenumber}
\newcounter{birthday}
\newcounter{firstday}
\newcounter{firstweek}
\newcounter{daysleft}
\newcounter{weeksleft}
\newcounter{tmp}
% expected life span in years
\newcommand{\firstyear}{0}
\newcommand{\lastyear}{81}
% birthday
\setmydatenumber{birthday}{1990}{1}{1}
% page and font layout
\usepackage[left=0mm,top=3mm,bottom=0mm,right=0mm,nohead,nofoot]{geometry}
\setlength{\parindent}{0pt}
\renewcommand{\familydefault}{\sfdefault}
\tikzstyle{week}=[
draw, shape=rectangle,
minimum width=4mm, minimum height=4mm
]
\tikzset{partial/.style n args={1}{
week, draw=none,
append after command={
[shorten <= -0.5\pgflinewidth]
($(\tikzlastnode.north west)!#1/7!(\tikzlastnode.north east)$)
edge (\tikzlastnode.north west)
(\tikzlastnode.north west)
edge (\tikzlastnode.south west)
(\tikzlastnode.south west) edge
($(\tikzlastnode.south west)!#1/7!(\tikzlastnode.south east)$)
}
}
}
\begin{document}
\thispagestyle{empty}
\begin{center}
\begin{tikzpicture}
\setdatebynumber{\thebirthday}
\newcounter{birthdaymonth}\setcounter{birthdaymonth}{\thedatemonth}
\newcounter{birthdayday}\setcounter{birthdayday}{\thedateday}
\node[anchor=south east,yshift=1mm] at (0,0) {\scriptsize age};
\foreach \age in {\firstyear,...,\lastyear} {
% left: year of age
\node[anchor=east] at (0,-5mm*\age) {\age};
% days counter at first day of this year of life
\setcounter{firstday}{\thedatenumber}
% first week
\ifnum\value{datedayname}>1
% partial week
\setcounter{firstweek}{\the\numexpr8-\value{datedayname}\relax}
\node[rotate=180,partial=\thefirstweek] at (5mm,-5mm*\age) {};
\else
% full week (starting at monday)
\setcounter{firstweek}{7}
\node[week] at (5mm,-5mm*\age) {};
\fi
% skip to the day before next birthday
\addtocounter{dateyear}{1}
\setdatenumber{\thedateyear}{\thebirthdaymonth}{\thebirthdayday}
\prevdate
% number of days in this year of life (358...365)
\setcounter{daysleft}{\thedatenumber}
\addtocounter{daysleft}{-\thefirstday}
\addtocounter{daysleft}{-\thefirstweek}
\addtocounter{daysleft}{1}
% full weeks left in this year of life (51...52)
\pgfmathparse{int(floor(\thedaysleft/7))}
\setcounter{weeksleft}{\pgfmathresult}
% days left in the last week (0...6)
\addtocounter{daysleft}{-7*\theweeksleft}
\ifnum\value{daysleft}>0
\node[partial=\thedaysleft] at (5mm*\theweeksleft+5mm,-5mm*\age) {};
\fi
\pgfmathsetlengthmacro{\endofyear}{5mm*\theweeksleft+2.5mm+5mm*\thedaysleft/7}
% end of year
\setcounter{tmp}{\thedatenumber}
\setdatenumber{\thedateyear}{1}{1}
\setcounter{daysleft}{\thedatenumber}
\addtocounter{daysleft}{-\thefirstday}
\addtocounter{daysleft}{1}
%\node[color=blue] at (0,-5mm*\age) {\thedaysleft};
\pgfmathsetlengthmacro{\newyear}{2.5mm+5mm/7*\thedaysleft-5mm/7*\thefirstweek}
\pgfmathsetlengthmacro{\startofyear}{7.5mm-\thefirstweek*5mm/7}
%\draw[thick,color=red] (\endofyear,-5mm*\age+2.5mm) to +(0,-5mm);
%\draw[thick,color=blue] (\startofyear,-5mm*\age+2.5mm) to +(0,-5mm);
%\draw[thick,color=green] (\newyear,-5mm*\age+2.5mm) to +(0,-5mm);
% draw full weeks
\foreach \week in {2,...,\theweeksleft}
\node[week] at (5mm*\week,-5mm*\age) {};
% right: calendar year at the day before next birthday
\setdatebynumber{\thetmp}
\ifodd\thedateyear
\begin{scope}[on background layer]
\path[fill=gray!20]
(\startofyear,-5mm*\age+2.5mm) rectangle (\newyear,-5mm*\age-2.5mm);
\end{scope}
\else
\begin{scope}[on background layer]
\path[fill=gray!20]
(\newyear,-5mm*\age-2.5mm) rectangle (\endofyear,-5mm*\age+2.5mm);
\end{scope}
\node[anchor=west] at (52.5*5mm,-5mm*\age) {\thedateyear};
\fi
% skip to next birthday
\nextdate
\setdatenumber{\thedateyear}{\thebirthdaymonth}{\thebirthdayday}
}
\end{tikzpicture}
\end{center}
\end{document}