[Remind-Fans] Weekly Planner?
Tim Chase
remind at tim.thechases.com
Wed Dec 18 16:22:16 EST 2019
here's a modest script to generate output akin to what you described.
A few caveats:
1) if an event begins before your START_TIME or after your END_TIME,
it doesn't get printed
2) it prints whole-day events at the top
3) if something has a DURATION specified, only its start gets
noted, it doesn't extend
4) it doesn't respect start-of-week, so it really only creates one
column/entry for each date output, so if "rem" outputs more than one
week, you'll get that many columns (the `rem -s` is REALLY wide)
The actual generation portion is moved out to functions, so if you
wanted to emit LaTeX or some other markup instead, it shouldn't be as
taxing.
Usage:
$ rem -s+ | awk -f planner.awk > this_week.html
or, if you want to override the START_TIME/END_TIME for your day
$ rem -s+ | awk -vSTART_TIME=7:00 -vEND_TIME=16:00 -vNO_WRAP=1 -f
planner.awk > this_week_as_fragment.html
the NO_WRAP=1 controls whether it gets wrapped in some basic HTML to
form a whole page (the default behavior if NO_WRAP is unset) or just
the <table> is emitted (any non-blank value for NO_WRAP).
If wrapped (the default) you can then point your favorite browser at
it to print if you want:
$ firefox this_week.html &
Hope this helps.
-tim
------[>8 planner.awk >8]-------------------------
#!/usr/bin/awk -f
function err(s) {
print s >> "/dev/stderr"
exit
}
function hm2time(timestr) {
if (split(timestr, hm, /:/) > 1) {
h = int(hm[1])
m = int(hm[2])
return h * 60 + m
} else {
err(sprintf("Invalid time: [%s]", timestr))
}
}
function time2hm(t) {
h = int(t / 60)
m = t % 60
return sprintf("%02i:%02i", h, m)
}
function htmlescape(s) {
gsub(/&/, "&", s)
gsub(/</, "<", s)
gsub(/>/, ">", s)
return s
}
# to change the output type,
# adjust these functions:
function wrap_header(title) {
printf("<html><head><title>Calendar for %s</title></head><body>\n",
title) }
function wrap_footer() {
printf("</body></html>\n")
}
function headers_start() {
printf("<table><thead><tr>")
}
function emit_header(h) {
printf("<th>%s</th>", h)
}
function headers_end() {
printf("</tr></thead>\n")
}
function body_begin() {
printf("<tbody>\n")
}
function body_end() {
printf("</tbody></table>\n")
}
function row_start(time) {
printf("<tr><th>%s</th>", time)
}
function row_end() {
printf("</tr>\n")
}
function emit_cell(s) {
printf("<td>%s</td>", s)
}
function emit_list(items) {
printf("<td><ul>")
for (i in items) printf("<li>%s</li>", htmlescape(items[i]))
print "</ul></td>"
}
BEGIN {
if (START_TIME !~ /[0-9]+:[0-9]+/) START_TIME="7:00"
if (END_TIME !~ /[0-9]+:[0-9]+/) END_TIME="17:00"
START_TIME = hm2time(START_TIME)
END_TIME = hm2time(END_TIME)
if (INTERVAL=="") INTERVAL=30
else INTERVAL=int(INTERVAL)
WRAP = (NO_WRAP=="")
}
{
DATE = $1
SPECIAL = $2
TAG = $3
DUR = $4
TIME = $5
msg = $6
for (i=7; i<= NF; i++) msg = msg " " $i
}
SPECIAL != "*" { next }
DATE != last_date {
i2d[col_count++] = last_date = $1
}
TIME == "*" {
# all day
if (DATE in allday) allday[DATE]=allday[DATE] SUBSEP msg
else allday[DATE] = msg
}
TIME != "*" {
# a timed event
if (DATE in times) {
times[DATE]=times[DATE] SUBSEP TIME
} else {
times[DATE] = TIME
}
if ((DATE SUBSEP TIME) in dt2msg)
dt2msg[DATE, TIME] = dt2msg[DATE, TIME] SUBSEP msg
else
dt2msg[DATE, TIME] = msg
}
END {
if (WRAP) wrap_header(i2d[0])
headers_start()
emit_header("")
for (i=0; i<col_count; i++) {
date = i2d[i]
emit_header(date)
}
headers_end()
body_begin()
row_start("All day")
for (col=0; col<col_count; col++) {
if (col in i2d) {
date = i2d[col]
split(allday[i2d[col]], msgs, SUBSEP)
if (length(msgs) > 1) {
emit_list(msgs)
} else {
emit_cell(msgs[1])
}
}
}
row_end()
currently_printing_time = START_TIME
while (currently_printing_time <= END_TIME) {
row_start(time2hm(currently_printing_time))
for (col=0; col<col_count; col++) {
if (col in i2d) {
date = i2d[col]
split(times[date], subset_of_times, SUBSEP)
delete msgs_to_print
msg_index = 1
for (time_index in subset_of_times) {
item_time = subset_of_times[time_index]
if (item_time >= currently_printing_time &&
item_time < currently_printing_time + INTERVAL) {
if ((date, item_time) in dt2msg) {
msgs_to_print[msg_index++] = dt2msg[date, item_time]
}
}
}
if (length(msgs_to_print) > 1) {
emit_list(msgs_to_print)
} else {
emit_cell(msgs_to_print[1])
}
} else emit_cell("")
}
row_end()
currently_printing_time += INTERVAL
}
body_end()
if (WRAP) wrap_footer()
}
More information about the Remind-fans
mailing list