<div dir="ltr"><div>Hi,</div><div><br></div><div>Sorry for not getting back earlier to you. That script's terrific, thanks a lot!</div><div>Maybe I'll try to tune it to output markdown instead of html (which can then easily be turned into multiple formats, using pandoc, <a href="https://pandoc.org/">https://pandoc.org/</a>). Since everything is in a table, it should not be too hard.</div><div><br></div><div>Thanks again!<br></div><div>Clément.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mer. 18 déc. 2019 à 17:13, Tim Chase <<a href="mailto:remind@tim.thechases.com">remind@tim.thechases.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">here's a modest script to generate output akin to what you described.<br>
A few caveats:<br>
<br>
1) if an event begins before your START_TIME or after your END_TIME,<br>
it doesn't get printed<br>
<br>
2) it prints whole-day events at the top<br>
<br>
3) if something has a DURATION specified, only its start gets<br>
noted, it doesn't extend <br>
<br>
4) it doesn't respect start-of-week, so it really only creates one<br>
column/entry for each date output, so if "rem" outputs more than one<br>
week, you'll get that many columns (the `rem -s` is REALLY wide)<br>
<br>
The actual generation portion is moved out to functions, so if you<br>
wanted to emit LaTeX or some other markup instead, it shouldn't be as<br>
taxing.<br>
<br>
Usage:<br>
<br>
 $ rem -s+ | awk -f planner.awk > this_week.html<br>
<br>
or, if you want to override the START_TIME/END_TIME for your day<br>
<br>
 $ rem -s+ | awk -vSTART_TIME=7:00 -vEND_TIME=16:00 -vNO_WRAP=1 -f<br>
 planner.awk > this_week_as_fragment.html<br>
<br>
the NO_WRAP=1 controls whether it gets wrapped in some basic HTML to<br>
form a whole page (the default behavior if NO_WRAP is unset) or just<br>
the <table> is emitted (any non-blank value for NO_WRAP).<br>
<br>
If wrapped (the default) you can then point your favorite browser at<br>
it to print if you want:<br>
<br>
  $ firefox this_week.html &<br>
<br>
Hope this helps.<br>
<br>
-tim<br>
<br>
------[>8 planner.awk >8]-------------------------  <br>
#!/usr/bin/awk -f<br>
function err(s) {<br>
  print s >> "/dev/stderr"<br>
  exit<br>
}<br>
<br>
function hm2time(timestr) {<br>
  if (split(timestr, hm, /:/) > 1) {<br>
    h = int(hm[1])<br>
    m = int(hm[2])<br>
    return h * 60 + m<br>
  } else {<br>
    err(sprintf("Invalid time: [%s]", timestr))<br>
  }<br>
}<br>
<br>
function time2hm(t) {<br>
  h = int(t / 60)<br>
  m = t % 60<br>
  return sprintf("%02i:%02i", h, m)<br>
}<br>
<br>
function htmlescape(s) {<br>
  gsub(/&/, "&amp;", s)<br>
  gsub(/</, "&lt;", s)<br>
  gsub(/>/, "&gt;", s)  <br>
  return s<br>
}<br>
<br>
# to change the output type,<br>
# adjust these functions:<br>
function wrap_header(title) {<br>
  printf("<html><head><title>Calendar for %s</title></head><body>\n",<br>
title) }<br>
function wrap_footer() {<br>
  printf("</body></html>\n")<br>
}<br>
function headers_start() {<br>
  printf("<table><thead><tr>")<br>
}<br>
function emit_header(h) {<br>
  printf("<th>%s</th>", h)<br>
}<br>
function headers_end() {<br>
  printf("</tr></thead>\n")<br>
}<br>
function body_begin() {<br>
  printf("<tbody>\n")<br>
}<br>
function body_end() {<br>
  printf("</tbody></table>\n")<br>
}<br>
function row_start(time) {<br>
  printf("<tr><th>%s</th>", time)<br>
}<br>
function row_end() {<br>
  printf("</tr>\n")<br>
}<br>
function emit_cell(s) {<br>
  printf("<td>%s</td>", s)<br>
}<br>
function emit_list(items) {<br>
  printf("<td><ul>")<br>
  for (i in items) printf("<li>%s</li>", htmlescape(items[i]))<br>
  print "</ul></td>"<br>
}<br>
<br>
BEGIN {<br>
  if (START_TIME !~ /[0-9]+:[0-9]+/) START_TIME="7:00"<br>
  if (END_TIME !~ /[0-9]+:[0-9]+/) END_TIME="17:00"<br>
<br>
  START_TIME = hm2time(START_TIME)<br>
  END_TIME = hm2time(END_TIME)<br>
<br>
  if (INTERVAL=="") INTERVAL=30<br>
  else INTERVAL=int(INTERVAL)<br>
<br>
  WRAP = (NO_WRAP=="")<br>
}<br>
<br>
{<br>
  DATE = $1<br>
  SPECIAL = $2<br>
  TAG = $3<br>
  DUR = $4<br>
  TIME = $5<br>
  msg = $6<br>
  for (i=7; i<= NF; i++) msg = msg " " $i<br>
}<br>
<br>
SPECIAL != "*" { next }<br>
<br>
DATE != last_date {<br>
  i2d[col_count++] = last_date = $1<br>
}<br>
<br>
TIME == "*" {<br>
  # all day<br>
  if (DATE in allday) allday[DATE]=allday[DATE] SUBSEP msg<br>
  else allday[DATE] = msg<br>
}<br>
<br>
TIME != "*" {<br>
  # a timed event<br>
  if (DATE in times) {<br>
    times[DATE]=times[DATE] SUBSEP TIME<br>
  } else {<br>
    times[DATE] = TIME<br>
  }<br>
  if ((DATE SUBSEP TIME) in dt2msg)<br>
    dt2msg[DATE, TIME] = dt2msg[DATE, TIME] SUBSEP  msg<br>
  else<br>
    dt2msg[DATE, TIME] = msg<br>
}<br>
<br>
END {<br>
  if (WRAP) wrap_header(i2d[0])<br>
  headers_start()<br>
  emit_header("")<br>
  for (i=0; i<col_count; i++) {<br>
    date = i2d[i]<br>
    emit_header(date)<br>
  }<br>
  headers_end()<br>
  body_begin()<br>
  row_start("All day")<br>
  for (col=0; col<col_count; col++) {<br>
    if (col in i2d) {<br>
      date = i2d[col]<br>
      split(allday[i2d[col]], msgs, SUBSEP)<br>
      if (length(msgs) > 1) {<br>
        emit_list(msgs)<br>
      } else {<br>
        emit_cell(msgs[1])<br>
      }<br>
    }<br>
  }<br>
  row_end()<br>
<br>
  currently_printing_time = START_TIME<br>
  while (currently_printing_time <= END_TIME) {<br>
    row_start(time2hm(currently_printing_time))<br>
    for (col=0; col<col_count; col++) {<br>
      if (col in i2d) {<br>
        date = i2d[col]<br>
        split(times[date], subset_of_times, SUBSEP)<br>
        delete msgs_to_print<br>
        msg_index = 1<br>
        for (time_index in subset_of_times) {<br>
          item_time = subset_of_times[time_index]<br>
          if (item_time >= currently_printing_time &&<br>
              item_time < currently_printing_time + INTERVAL) {<br>
            if ((date, item_time) in dt2msg) {<br>
              msgs_to_print[msg_index++] = dt2msg[date, item_time]<br>
            }<br>
          }<br>
        }<br>
<br>
        if (length(msgs_to_print) > 1) {<br>
          emit_list(msgs_to_print)<br>
        } else {<br>
          emit_cell(msgs_to_print[1])<br>
        }<br>
      } else emit_cell("")<br>
    }<br>
    row_end()<br>
    currently_printing_time += INTERVAL<br>
  }<br>
  body_end()<br>
  if (WRAP) wrap_footer()<br>
}<br>
_______________________________________________<br>
Remind-fans mailing list<br>
<a href="mailto:Remind-fans@lists.skoll.ca" target="_blank">Remind-fans@lists.skoll.ca</a><br>
<a href="https://dianne.skoll.ca/mailman/listinfo/remind-fans" rel="noreferrer" target="_blank">https://dianne.skoll.ca/mailman/listinfo/remind-fans</a><br>
Remind is at <a href="https://dianne.skoll.ca/projects/remind/" rel="noreferrer" target="_blank">https://dianne.skoll.ca/projects/remind/</a></blockquote></div>