simplify and improve portability across mawk, gawk, nawk, busybox awk... - ics2txt - convert icalendar .ics file to plain text
(HTM) git clone git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ics2txt
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
---
(DIR) commit 24985c575e833254adb79215584947a601569ea1
(DIR) parent c6606df0960a765824c000aeb54e21691bcc94bb
(HTM) Author: Josuah Demangeon <me@josuah.net>
Date: Thu, 25 Jun 2020 21:11:17 +0200
simplify and improve portability across mawk, gawk, nawk, busybox awk...
Diffstat:
M README | 33 +++++++++++++++----------------
M ics2tsv | 32 ++++++++++++-------------------
M tcal2tsv | 12 ++++++------
M tsv2tcal | 4 ++--
4 files changed, 36 insertions(+), 45 deletions(-)
---
(DIR) diff --git a/README b/README
@@ -1,7 +1,5 @@
-ICS2TSV(1) General Commands Manual ICS2TSV(1)
-
NAME
- ics2tsv – convert ics file to simpler tsv or txt formats
+ ics2txt – convert ics file to simpler tsv or txt formats
SYNOPSIS
ics2txt <file.ics >file.txt
@@ -13,31 +11,34 @@ SYNOPSIS
tsv2ics <file.tsv >file.ics
DESCRIPTION
- ics2tsv is set of awk scripts to deal with iCal (.ics) format to publish,
+ ics2txt is set of awk scripts to deal with iCal (.ics) format to publish,
display and convert *.ics files, though a simple central TSV format.
They all read from either stdin or the file passed as argument, and write
to stdout.
- file.tsv files have one line per event, all with the following fields,
- separated by one tab:
- 1. Begining (epoch)
- 2. End (epoch)
- 3. Category
- 4. Location
- 5. Summary
- 6. Description
+ file.tsv have one line per event, with the first line declaring fields
+ order and presence, among:
+ “beg” Begining of event (epoch)
+ “end” End of event (epoch)
+ “cat” Category
+ “loc” Location
+ “sum” Summary
+ “des” Description
EXAMPLES
- Convert a calendar from HTTP .ics to custom .txt sorted by beginning
- date:
+ Convert a calendar from HTTP .ics to custom .txt sorted by start date:
curl $url.ics | ics2tsv | sort -n -k 1,1 | tsv2txt
Convert a custom .txt format back to an .ics file and publish it:
tcal2tsv cal.txt | tsv2ics | ssh www@$host 'cat >/var/www/cal.ics'
Split an file according to the category, saved as .tsv:
- tcal2tsv cal.txt | awk -F '\t' '{ f = $3".tsv"; print >>f }'
+
+ ics2tsv cal.txt | awk -F '\t' '
+ NR == 1 { for (i = 1; i <= NF; i++) F[$i] = i; next }
+ { print >>($F["cat"]".tsv") }
+ ´
SEE ALSO
cal(1), calendar(1), date(1), sort(1)
@@ -48,5 +49,3 @@ STANDARDS
AUTHORS
Josuah Demangeon <me@josuah.net>
-
-OpenBSD 6.6 March 1, 2020 OpenBSD 6.6
(DIR) diff --git a/ics2tsv b/ics2tsv
@@ -44,49 +44,41 @@ function ical_to_epoch(str, offset,
function print_event(ev, fields,
i)
{
- for (i = 1; i <= fields["len"]; i++)
+ for (i = 1; i in fields; i++)
printf("%s%s", (i > 1 ? "\t" : ""), ev[fields[i]])
printf("\n")
}
BEGIN {
FIELDS = "DTSTART DTEND CATEGORIES LOCATION SUMMARY DESCRIPTION"
- fields["len"] = split(FIELDS, fields, " ")
+ split(FIELDS, fields, " ")
# by default: "CATEGORIES" -> "cat", "LOCATION" -> "loc"...
translate["DTSTART"] = "beg"
translate["DTEND"] = "end"
- "date +%z" | getline offset_str
+ "date +%z" | getline
close("date +%z")
- hour = substr($0, 4, 2)
- min = substr($0, 6, 2)
- tzoffset = substr(zone, 3, 1) hour * 3600 + min * 60
+ TZ = substr($0, 3, 1) substr($0, 4, 2)*3600 + substr($0, 6, 2)*60
FS = "[:;]"
- for (i = 1; i <= fields["len"]; i++) {
+ for (i = 1; i in fields; i++) {
if (!(s = translate[fields[i]]))
s = tolower(substr(fields[i], 1, 3))
printf("%s%s", (i > 1 ? "\t" : ""), s)
}
-
printf("\n")
}
+/^ / {
+ ev[type] = ev[type] substr($0, 2, length($0) - 1)
+ next
+}
+
{
- gsub("\r", "")
- gsub("\t", "\\\\t")
- gsub("^ *", "")
- gsub(" *$", "")
-
- if (match($0, "^ ")) {
- ev[type] = ev[type] substr($0, 2, length($0) - 1)
- } else {
- type = $1
- i = index($0, ":")
- ev[type] = substr($0, i + 1, length($0) - i)
- }
+ i = index($0, ":")
+ ev[$1] = substr($0, i + 1, length($0) - i)
}
/^END:VEVENT/ {
(DIR) diff --git a/tcal2tsv b/tcal2tsv
@@ -42,9 +42,9 @@ function text_to_epoch(str, tz,
BEGIN {
FIELDS = "beg end cat loc sum des"
- fields["len"] = split(FIELDS, fields, " ")
+ split(FIELDS, fields, " ")
- for (i = 1; i <= fields["len"]; i++) {
+ for (i = 1; i in fields; i++) {
pos[fields[i]] = i
printf("%s%s", (i > 1 ? "\t" : ""), fields[i])
}
@@ -56,16 +56,16 @@ BEGIN {
}
/^TZ[+-]/ {
- TZOFFSET = substr($1, 3, 1) substr($0, 4, 2)*3600 + substr($0, 6, 2)*60
+ TZ = substr($1, 3, 1) substr($0, 4, 2)*3600 + substr($0, 6, 2)*60
while (getline && $0 ~ /^$/)
continue
}
/^[0-9]+-[0-9]+-[0-9]+/ {
if ("beg" in ev)
- ev["end"] = text_to_epoch($0, TZOFFSET)
+ ev["end"] = text_to_epoch($0, TZ)
else
- ev["beg"] = text_to_epoch($0, TZOFFSET)
+ ev["beg"] = text_to_epoch($0, TZ)
next
}
@@ -78,7 +78,7 @@ BEGIN {
}
/^$/ {
- for (i = 1; i <= fields["len"]; i++)
+ for (i = 1; i in fields; i++)
printf("%s%s", (i > 1 ? "\t" : ""), ev[fields[i]])
printf("\n")
delete ev
(DIR) diff --git a/tsv2tcal b/tsv2tcal
@@ -43,13 +43,13 @@ function gmtime(sec, tm)
function localtime(sec, tm,
tz, h, m)
{
- return gmtime(sec + TZOFFSET, tm)
+ return gmtime(sec + TZ, tm)
}
BEGIN {
"date +%z" | getline tz
close("date +%z")
- TZOFFSET = substr(tz, 1, 1) substr(tz, 2, 2)*3600 + substr(tz, 4, 2)*60
+ TZ = substr(tz, 1, 1) substr(tz, 2, 2)*3600 + substr(tz, 4, 2)*60
print("TZ" tz)