#!/bin/sh
+# vi:syntax=bash
# Copyright 2024 Paul Hänsch
#
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
. "$_EXEC/cgilite/cgilite.sh"
. "$_EXEC/acl.sh"
. "$_EXEC/tools.sh"
--depth) depth="$2" shift 2;;
\#*) tags="${tags}${tags:+ }${1###}"; shift 1;;
\!*) ntags="${ntags}${ntags:+ }${1##!}"; shift 1;;
- --h1|--h2|--h3|--h4|--h5|--h6|--label)
- labeltype="${1#--}" label="$2"; shift 2;;
- --alt-label)
- altlabel="$2"; shift 2;;
+ --date|--from) fromdate="$2"; shift 2;;
+ --weekstart|--ws|-ws) ws="$2"; shift 2;;
--) shift 1; break;;
*) if [ ! "$dir" ]; then
dir="$1"
[ "$depth" -ge 0 -o "$depth" -le 0 ] 2>&- || depth=0
read DY DM DD <<-EOF
- $(date +"%Y %m %d")
+ $(isdate "$fromdate" \
+ && date -ud "$fromdate" +"%Y %m %d" \
+ || date -u +"%Y %m %d"
+ )
EOF
-dstart="$(date -d "${DY}-${DM}-01" +%s)"
-[ "$DM" -lt 12 ] \
-&& dend="$(date -d "${DY}-$(( ${DM#0} + 1))-01" +%s)" \
-|| dend="$(date -d "$(( ${DY#0} + 1))-01-01" +%s)"
+case $ws in
+ 0|[sS]*) ws=0;;
+ 1|[mM]*) ws=1;;
+ *) ws=0;;
+esac
+
+rrexpand() {
+ # Recurrence Expansion
+ # read recurring event specifications and expand them to a list of
+ # single events within the specified time frame
-expand() {
- local start="$1" end="$2" rrfreq="$3" rrint="$4" rrend="$5" evtitle="$6" evlink="$7"
- local dstart dend
+ local dstart="$1" dend="$2"
+ local junk1 start end rrfreq rrint rrend evtitle evlink junk2
+
+ while read -r junk1 start end rrfreq rrint rrend evtitle evlink junk2; do
+ [ "$rrend" -eq -1 ] && rrend=9999999999
+
+ if [ "$start" -lt "$dend" ] &&
+ [ "$end" -gt "$dstart" -o "$rrend" -gt "$dstart" ]; then
+ case $rrint in
+ day) rrex_day;;
+ week) rrex_week;;
+ month) rrex_month;;
+ year) rrex_year;;
+ *):
+ printf '%i %i %s %s\n' "$start" "$end" "$evtitle" "$evlink"
+ ;;
+ esac
+ fi
+ done
+}
+
+rrex_day() {
+ # helper for rrexpand daily/N-day expansion
local nstart nend
- [ "$rrend" -eq -1 ] && rrend=9999999999
-
- case $rrint in
- day)
- nend=$(( rrfreq * 86400 - (dstart - end) % (rrfreq * 86400) + dstart ))
- nstart=$(( start - end + nend))
- debug "[ $nend -lt $dend -a $nstart -lt $rrend ]"
- while [ "$nend" -lt "$dend" -a "$nstart" -lt "$rrend" ]; do
- printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
- # printf '%i %i %s\n' "$nstart" "$nend" "$evlink"
- nstart="$((nstart + rrfreq * 86400))"
- nend="$((nstart - start + end))"
- done
- ;;
- week)
- nend=$(( rrfreq * 604800 - (dstart - end) % (rrfreq * 604800) + dstart ))
- nstart=$(( start - end + nend))
- while [ "$nend" -lt "$dend" -a "$nstart" -lt "$rrend" ]; do
- printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
- nstart="$((nstart + rrfreq * 7 * 86400))"
- nend="$((nstart - start + end))"
- done
- ;;
- month)
- { read _y _m _d; read y m d; } <<-EOF
- $(date -d @$dstart +"%Y %_m %_d"
- date -d @$start +"%Y %_m %_d"
+ nend=$(( rrfreq * 86400 - (dstart - end) % (rrfreq * 86400) + dstart ))
+ nstart=$(( start - end + nend))
+ while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
+ [ "$nstart" -ge "$start" ] \
+ && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
+ nstart="$((nstart + rrfreq * 86400))"
+ nend="$((nstart - start + end))"
+ done
+}
+
+rrex_week() {
+ # helper for rrexpand weekly/N-week expansion
+ local nstart nend
+
+ nend=$(( 0 * 604800 - (dstart - end) % (rrfreq * 604800) + dstart ))
+ nstart=$(( start - end + nend))
+ while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
+ [ "$nstart" -ge "$start" -a "$nstart" -ge "$dstart" ] \
+ && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
+ nstart="$((nstart + rrfreq * 7 * 86400))"
+ nend="$((nstart - start + end))"
+ done
+}
+
+rrex_month() {
+ # helper for rrexpand monthly/N-month expansion
+ local nstart nend
+
+ { read _y _m _d; read y m d start_time; } <<-EOF
+ $(date -ud @$dstart +"%Y %_m %_d"
+ date -ud @$start +"%Y %_m %_d %T"
)
EOF
- _m=$((_y * 12 + _m)) m=$((y * 12 + m))
- while :; do
- m=$(( rrfreq - ((_m - m - 1) % rrfreq + 1) + _m ))
- nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")"
- if isdate "$nstart" && [ "$(date -d "$nstart" +%s)" -ge "$dstart" ]; then
- break
- fi >/dev/null
- _m="$((_m + rrfreq))"
- done
- nstart="$(date -d "$nstart $start_time" +%s)"
- nend="$((end - start + nstart))"
- while [ "$nend" -lt "$dend" -a "$nstart" -lt "$rrend" ]; do
- printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
- m="$((m + rrfreq))"
- nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")"
- nstart="$(date -d "$nstart $start_time" +%s)"
- nend="$((nstart - start + end))"
- done
- ;;
- year)
- { read _y _m _d; read y m d; } <<-EOF
- $(date -d @$dstart +"%Y %_m %_d"
- date -d @$start +"%Y %_m %_d"
+ _m=$((_y * 12 + _m)) m=$((y * 12 + m))
+ while :; do
+ m=$(( rrfreq - ((_m - m - 1) % rrfreq + 1) + _m ))
+ nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")"
+ if isdate "$nstart" && [ "$(date -ud "$nstart" +%s)" -ge "$dstart" ]; then
+ break
+ fi >/dev/null
+ _m="$((_m + rrfreq))"
+ done
+ nstart="$(date -ud "$nstart $start_time" +%s)"
+ nend="$((end - start + nstart))"
+ while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
+ [ "$nstart" -ge "$start" ] \
+ && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
+ m="$((m + rrfreq))"
+ nstart="$(printf '%04i-%02i-%02i' "$(( (m - 1) / 12 ))" "$(( (m - 1) % 12 + 1 ))" "$d")"
+ nstart="$(date -ud "$nstart $start_time" +%s)"
+ nend="$((nstart - start + end))"
+ done
+}
+
+rrex_year() {
+ # helper for rrexpand yearly/N-year expansion
+ local nstart nend
+
+ { read _y _m _d; read y m d start_time; } <<-EOF
+ $(date -ud @$dstart +"%Y %_m %_d"
+ date -ud @$start +"%Y %_m %_d %T"
)
EOF
- while :; do
- y=$(( rrfreq - ((_y - y - 1) % rrfreq + 1) + _y ))
- nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")"
- if isdate "$nstart" && [ "$(date -d "$nstart" +%s)" -ge "$dstart" ]; then
- break
- fi >/dev/null
- _y="$((_y + rrfreq))"
- done
- nstart="$(date -d "$nstart $start_time" +%s)"
- nend="$((end - start + nstart))"
- while [ "$nend" -lt "$dend" -a "$nstart" -lt "$rrend" ]; do
- printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
- y="$((y + rrfreq))"
- nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")"
- nstart="$(date -d "$nstart $start_time" +%s)"
- nend="$((nstart - start + end))"
- done
- ;;
- *):
- printf '%i %i %s %s\n' "$start" "$end" "$evtitle" "$evlink"
- ;;
- esac
+ while :; do
+ y=$(( rrfreq - ((_y - y - 1) % rrfreq + 1) + _y ))
+ nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")"
+ if isdate "$nstart" && [ "$(date -ud "$nstart" +%s)" -ge "$dstart" ]; then
+ break
+ fi >/dev/null
+ _y="$((_y + rrfreq))"
+ done
+ nstart="$(date -ud "$nstart $start_time" +%s)"
+ nend="$((end - start + nstart))"
+ while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do
+ [ "$nstart" -ge "$start" ] \
+ && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink"
+ y="$((y + rrfreq))"
+ nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")"
+ nstart="$(date -ud "$nstart $start_time" +%s)"
+ nend="$((nstart - start + end))"
+ done
}
events="$(
then
cat "$_DATA/pages/${pagedir}/#events"
fi
- done \
- | while read -r junk1 tstart tend rrfreq rrint rrend evtitle evlink junk2; do
- if [ "$tend" -gt "$dstart" -a "$tstart" -lt "$dend" ] \
- || [ "$rrend" -gt "$dstart" -o "$rrend" -eq -1 ]; then
- expand "$tstart" "$tend" "$rrfreq" "$rrint" "$rrend" "$evtitle" "$evlink"
- fi
- done \
- | debug \
- | sort -n
+ done
)"
-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\\n "$events" \
+ | 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>'
+}
+
+%rem cal_list
+cal_month