Home
       tics2tsv - ics2txt - convert icalendar .ics file to plain text
  HTML git clone git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ics2txt
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
       ---
       tics2tsv (2949B)
       ---
            1 #!/usr/bin/awk -f
            2 
            3 function isleap(year)
            4 {
            5         return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)
            6 }
            7 
            8 function mdays(mon, year)
            9 {
           10         return (mon == 2) ? (28 + isleap(year)) : (30 + (mon + (mon > 7)) % 2)
           11 }
           12 
           13 function timegm(tm,
           14         sec, mon, day)
           15 {
           16         sec = tm["sec"] + tm["min"] * 60 + tm["hour"] * 3600
           17 
           18         day = tm["mday"] - 1
           19 
           20         for (mon = tm["mon"] - 1; mon > 0; mon--)
           21                 day = day + mdays(mon, tm["year"])
           22 
           23         # constants: x * 365 + x / 400 - x / 100 + x / 4
           24         day = day + int(tm["year"] / 400) * 146097
           25         day = day + int(tm["year"] % 400 / 100) * 36524
           26         day = day + int(tm["year"] % 100 / 4) * 1461
           27         day = day + int(tm["year"] % 4 / 1) * 365
           28 
           29         return sec + (day - 719527) * 86400
           30 }
           31 
           32 function print_vevent(ev, fields,
           33         i)
           34 {
           35         for (i = 1; i in fields; i++)
           36                 printf("%s%s", (i > 1 ? "\t" : ""), ev[fields[i]])
           37         printf("\n")
           38 }
           39 
           40 function ical_parse_line(str, content, params,
           41         i, eq)
           42 {
           43         if ((i = index(str, ":")) == 0)
           44                 return -1
           45         content["value"] = substr(str, i + 1)
           46         str = substr(str, 1, i - 1)
           47 
           48         if ((i = index(str, ";")) == 0) {
           49                 content["name"] = str
           50                 return 0
           51         }
           52         content["name"] = substr(str, 1, i - 1)
           53         str = substr(str, i + 1)
           54 
           55         while ((i = index(str, ";")) > 0) {
           56                 if ((eq = index(str, "=")) == 0)
           57                         return -1
           58                 param[substr(str, 1, eq - 1)] = substr(str, eq + 1, i - 1)
           59                 str = substr(str, eq + 1)
           60         }
           61         if ((eq = index(str, "=")) == 0)
           62                 return -1
           63         params[substr(str, 1, eq - 1)] = substr(str, eq + 1)
           64         return 0
           65 }
           66 
           67 function ical_set_tz(tzid)
           68 {
           69         gsub("'", "", tzid)
           70         cmd = "TZ='" tzid "' exec date +%z" 
           71         cmd | getline tzid
           72         close(cmd)
           73         TZ = substr(tzid, 1, 1) substr(tzid, 2, 2)*3600 + substr(tzid, 4, 2)*60
           74 }
           75 
           76 function ical_to_epoch(content, param,
           77         tz, cmd)
           78 {
           79         if (param["TZID"])
           80                 ical_set_tz(param["TZID"])
           81 
           82         tm["year"] = substr(content["value"], 1, 4)
           83         tm["mon"] = substr(content["value"], 5, 2)
           84         tm["mday"] = substr(content["value"], 7, 2)
           85         tm["hour"] = substr(content["value"], 10, 2)
           86         tm["min"] = substr(content["value"], 12, 2)
           87         tm["sec"] = substr(content["value"], 14, 2)
           88 
           89         return timegm(tm) + TZ
           90 }
           91 
           92 BEGIN {
           93         split("DTSTART DTEND CATEGORIES LOCATION SUMMARY DESCRIPTION URL",
           94           FIELDS, " ")
           95         DT["DTSTART"] = DT["DTEND"] = DT["DUE"] = 1
           96 
           97         # by default: "CATEGORIES" -> "cat", "LOCATION" -> "loc"...
           98         translate["DTSTART"] = "beg"
           99         translate["DTEND"] = "end"
          100 
          101         for (i = 1; i in FIELDS; i++) {
          102                 if (!(s = translate[FIELDS[i]]))
          103                         s = tolower(substr(FIELDS[i], 1, 3))
          104                 printf("%s%s", (i > 1 ? "\t" : ""), s)
          105         }
          106         printf("\n")
          107 
          108         FS = "[:;]"
          109 }
          110 
          111 {
          112         gsub("\r", "")
          113         gsub("\t", "\\\\t")
          114 }
          115 
          116 sub("^ ", "") {
          117         content["value"] = content["value"] $0
          118         next
          119 }
          120 
          121 {
          122         delete content
          123         delete param
          124 
          125         if (ical_parse_line($0, content, params) < 0)
          126                 next
          127 
          128         if (content["name"] == "TZID") {
          129                 ical_set_tz(content["value"])
          130         } else if (DT[content["name"]]) {
          131                 vevent[content["name"]] = ical_to_epoch(content, params)
          132         } else {
          133                 vevent[content["name"]] = content["value"]
          134         }
          135 }
          136 
          137 /^END:VEVENT/ {
          138         print_vevent(vevent, FIELDS)
          139         delete vevent
          140         next
          141 }