-lday=''
-
-printf '<ul class="macro calendar">\n'
-printf '%s\n' "${events}" \
-| while read start end name link; do
- day="$((start / 86400))"
- if [ "$day" != "$lday" ]; then
- [ "$lday" ] && printf '</ul></li>'
- date -d "@$start" +'<li><label>%A, %F</label><ul class="day">'
- lday="$day"
- fi
- printf '<li>%s: <a href="%s">%s</a></li>' \
- "$(date -d "@$start" +"%T")" "$(URL "${link%%#*}")#$(URL "${link#*#}")" "$(HTML "${name}")"
-done
-printf '</ul></li></ul>'
+cal_list() {
+ # Print list view for upcoming events
+ local lday='' events sdate=$(date -ud "${DY}-${DM}-${DD}" +%s)
+
+ events="$(
+ printf %s\\n "$events" \
+ | rrexpand "$sdate" "$((sdate + 42 * 86400))" \
+ | sort -n
+ )"
+
+ printf '<ul class="macro calendar cal_list">\n'
+ printf '%s\n' "${events}" \
+ | while read start end name link; do
+ day="$((start / 86400))"
+ if [ "$day" != "$lday" ]; then
+ [ "$lday" ] && printf '</ul></li>'
+ date -ud "@$start" +'<li><label>%A, %F</label><ul class="day">'
+ lday="$day"
+ fi
+ printf '<li>%s - <a href="%s">%s</a></li>' \
+ "$(date -ud "@$start" +"%H:%M")" "$(URL "${link%%#*}")#$(URL "${link#*#}")" "$(HTML "${name}")"
+ done
+ printf '</ul></li></ul>'
+}
+
+cal_month() {
+ local ws events calmonth
+ local iday idow mname dcnt dow dcal start end title link n
+
+ calmonth="$(GET calmonth || printf %i "$((DY * 12 + DM))")"
+ DY="$(( (calmonth - 1) / 12 ))"
+ DM="$(( (calmonth - 1) % 12 + 1 ))"
+
+ read -r iday idow mname <<-EOF
+ $(date -ud "${DY}-${DM}-01" +"%s %u %B")
+ EOF
+ dcnt=$((iday - idow * 86400 + ws * 86400))
+ dow=$ws
+ dcal="$(date -ud @"$dcnt" +%d)"
+
+ events="$(
+ printf %s\\n "$events" \
+ | rrexpand "$dcnt" "$((dcnt + 42 * 86400))" \
+ | sort -n
+ )"
+
+ printf '<table class="macro calendar cal_month">'
+ printf '<thead><tr><th><a href="%s"><</a></th><th colspan=5>%s</th><th><a href="%s">></a></th></tr><tr>' \
+ "./?calmonth=$((DY * 12 + DM -1))" "$mname" "./?calmonth=$((DY * 12 + DM + 1))"
+ for n in 0 1 2 3 4 5 6; do date -ud @"$((dcnt + n * 86400))" +'<th>%a</th>'; done
+ printf '</tr></thead><tbody>'
+ while :; do
+ [ $dow = $ws ] && printf '<tr>'
+ printf '<td><label>%02i</label>' "$dcal"
+
+ evlist="$(
+ printf %s "${events}${events:+${BR}}" \
+ | while read start end title link; do
+ if [ "$((start / 86400))" -lt "$((dcnt / 86400))" -a "$end" -gt "$dcnt" ]; then
+ printf '<li><a href="%s\#%s">%s</a></li>' \
+ "$(UNSTRING "${link%%#*}" |URL)" \
+ "$(UNSTRING "${link#*#}" |URL)" \
+ "$(UNSTRING "$title" |HTML)"
+ elif [ "$((start / 86400))" -eq "$((dcnt / 86400))" ]; then
+ printf '<li>%s - <a href="%s\#%s">%s</a></li>' \
+ "$(date -ud @"$start" +%H:%M)" \
+ "$(UNSTRING "${link%%#*}" |URL)" \
+ "$(UNSTRING "${link#*#}" |URL)" \
+ "$(UNSTRING "$title" |HTML)"
+ fi
+ done
+ )"
+ [ "$evlist" ] && printf '<ul>%s</ul>' "$evlist"
+
+ printf '</td>\n'
+ [ $dow = $(( (ws + 6) % 7)) ] && printf '</tr>\n'
+
+ dcnt=$(( dcnt + 86400 ))
+ dow=$(( (dow + 1) % 7 ))
+ [ $dcal -lt 28 ] \
+ && dcal=$((dcal + 1)) \
+ || dcal=$(date -ud @"$dcnt" +%d)
+ [ $dcnt -gt $((iday + 28 * 86400)) -a $dcal -le 7 -a $dow = $ws ] \
+ && break
+ done
+ printf '</tbody></table>'
+}
+
+# cal_list
+cal_month