emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Broken worg link
@ 2018-02-27 14:57 Alex Branham
  2018-02-27 17:12 ` Eric S Fraga
  2018-03-04  8:47 ` Bastien
  0 siblings, 2 replies; 5+ messages in thread
From: Alex Branham @ 2018-02-27 14:57 UTC (permalink / raw)
  To: Org Mode List

On this page:

https://orgmode.org/worg/org-tutorials/org-google-sync.html

the link ical2org.awk 404s for me.

Thanks,
Alex

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Broken worg link
  2018-02-27 14:57 Broken worg link Alex Branham
@ 2018-02-27 17:12 ` Eric S Fraga
  2018-03-04  8:47 ` Bastien
  1 sibling, 0 replies; 5+ messages in thread
From: Eric S Fraga @ 2018-02-27 17:12 UTC (permalink / raw)
  To: Alex Branham; +Cc: Org Mode List


[-- Attachment #1.1: Type: text/plain, Size: 539 bytes --]

On Tuesday, 27 Feb 2018 at 08:57, Alex Branham wrote:
> On this page:
>
> https://orgmode.org/worg/org-tutorials/org-google-sync.html
>
> the link ical2org.awk 404s for me.

Ah, interesting.  I probably should have checked that link before
recommending looking at the code...

In the meantime, I attach my current version of this awk script which
does differ to what is on Worg in some subtle ways but the differences
should not matter for many use cases.

-- 
Eric S Fraga via Emacs 27.0.50, Org release_9.1.6-352-g92176c

[-- Attachment #1.2: ical2org.awk --]
[-- Type: application/octet-stream, Size: 14465 bytes --]

# awk script for converting an iCal formatted file to a sequence of org-mode headings.
# this may not work in general but seems to work for day and timed events from Google's
# calendar, which is really all I need right now...
#
# usage:
#   awk -f THISFILE < icalinputfile.ics > orgmodeentries.org --assign NAME=category
#
# where the category is used to define a CATEGORY for all entries in
# the file and also assign that label as a tag to each entry
#
# Note: change org meta information generated below for author and
# email entries!
#
# Known bugs:
# - not so much a bug as a possible assumption: date entries with no time
#   specified are assumed to be independent of the time zone.
#
# Eric S Fraga
# 20100629 - initial version
# 20100708 - added end times to timed events
#          - adjust times according to time zone information
#          - fixed incorrect transfer for entries with ":" embedded within the text
#          - added support for multi-line summary entries (which become headlines)
# 20100709 - incorporated time zone identification
#          - fixed processing of continuation lines as Google seems to
#            have changed, in the last day, the number of spaces at
#            the start of the line for each continuation...
#          - remove backslashes used to protect commas in iCal text entries
# no further revision log after this as the file was moved into a git
# repository...
#
# Last change: 2016.05.26 08:47:12
#----------------------------------------------------------------------------------

# a function to take the iCal formatted date+time, convert it into an
# internal form (seconds since time 0), and adjust according to the
# local time zone (specified by +-seconds calculated in the BEGIN
# section)

function datetimestamp(input)
{
    # convert the iCal Date+Time entry to a format that mktime can understand
    datespec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])T([0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 \\4 \\5 \\6", "g", input);
    # print "date spec : " datespec; convert this date+time into
    # seconds from the beginning of time and include adjustment for
    # time zone, as determined in the BEGIN section below.  The
    # adjustment is only included if the time stamp has a Z at the
    # end.  Of course, we should actually incorporate the time zone
    # information in the time stamp line but ...
    if (0 < index(input,"Z")) {
        # For time
        # zone adjustment, I have not tested edge effects, specifically
        # what happens when UTC time is a different day to local time and
        # especially when an event with a duration crosses midnight in UTC
        # time.  It should work but...
        timestamp = mktime(datespec) + seconds;
    }
    else {
        timestamp = mktime(datespec);
    }
    # print "date spec: " datespec;
    #timestamp = mktime(datespec);
    # print "adjusted    : " timestamp
    # print "Time stamp  : " strftime("%Y-%m-%d %H:%M", timestamp);
    return timestamp;
}

# version of above but for dates only
function datestamp(input)
{
    # create a date using midnight as the time
    datespec = gensub( "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 0 0 0", "g", input );
    # convert to internal representation
    timestamp = mktime(datespec);
    # and finally convert to something org understands
    datestring = strftime("%Y-%m-%d %a", timestamp);
    #print "In datestamp: datespec=" datespec " timestamp=" timestamp " datestring=" datestring;
    return datestring;
}

# start of the output file now
BEGIN {
    # use a colon to separate the type of data line from the actual contents
    FS = ":";
    
    # determine the number of seconds to use for adjusting for time
    # zone difference from UTC.  This is used in the function
    # datetimestamp above.  The time zone information returned by
    # strftime() is in hours * 100 so we multiply by 36 to get
    # seconds.  This does not work for time zones that are not an
    # integral multiple of hours (e.g. Newfoundland)
    seconds = gensub("([+-])0", "\\1", 1, strftime("%z")) * 36;
    
    date1 = "";			# for start of an event
    date2 = "";			# for end of an event, if specified
    entry = ""
    first = 1;			# true until an event has been found
    headline = ""
    icalentry = ""  # the full entry for inspection
    id = ""
    indescription = 0;
    inevent = 0;                # we have VEVENTS but also other items which we do not process
    location = "";              # outlook entries, at least, often include a location
    repeat = "";                # is item repeated? if so, how often
    time1 = "";			# for start of an event, if specified
    time2 = "";			# for end of an event, if specified
    todotype = "";              # type of TODO
    
    if (NAME == "")
        NAME = "ical2org";
    
    print "# -*- mode: auto-revert; mode: org; -*-"   # suggested by Henrik Holmboe
    print "#+TITLE:     Main Google calendar entries"
    print "#+AUTHOR:    Eric S Fraga"
    print "#+EMAIL:     e.fraga@ucl.ac.uk"
    print "#+DESCRIPTION: converted using the ical2org awk script"
    print "#+CATEGORY: " NAME
    print " "
}

# continuation lines (at least from Google) start with two spaces
# if the continuation is after a description or a summary, append the entry
# to the respective variable

/^[ ]+/ { 
    if (indescription) {
        entry = entry gensub("\r", "", "g", gensub("^[ ]+", "", 1, $0));
    } else if (insummary) {
        summary = summary gensub("\r", "", "g", gensub("^[ ]+", "", 1, $0))
    } else if (inuid) {
        id = id gensub("\r", "", "g", gensub("^[ ]+", "", 1, $0))
    }
    icalentry = icalentry "\n" $0
}

/^BEGIN:VEVENT/ {
    # start of an event.  if this is the first, output the preamble from the iCal file
    if (first) {
        print "* COMMENT original iCal preamble"
        print gensub("\r", "", "g", icalentry)
        icalentry = ""
    }
    havesummary = 0;
    inevent = 1;
    first = false;
    repeat = "";
}

/^BEGIN:VTODO/ {
    if (first){
        print "* COMMENT original iCal preamble";
        print gensub("\r", "", "g", icalentry);
        icalentry = "";
        first = false;
    }
    havesummary = 0;
    intodo = 1;
    repeat = "";
    todotype = "";
}
# any line that starts at the left with a non-space character is a new data field

/^[A-Z]/ {
    # we ignore DTSTAMP lines as they change every time you download
    # the iCal format file which leads to a change in the converted
    # org file as I output the original input.  This change, which is
    # really content free, makes a revision control system update the
    # repository and confuses.
    if (! index("DTSTAMP", $1)) icalentry = icalentry "\n" $0
    # this line terminates the collection of description and summary entries
    indescription = 0;
    if (insummary) {
        havesummary = 1;
    }
    insummary = 0;
}

# this type of entry represents a day entry, not timed, with date
# stamp YYYYMMDD.  For a todo item, this indicates a scheduled item.

/^DTSTART;VALUE=DATE/ {
    # print "DTSTART date only entry: " $0;
    # date1 = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3", "g", $2)
    date1 = datestamp($2);
    time1 = ""
}

# this represents a timed entry with date and time stamp
# YYYYMMDDTHHMMSS we ignore the seconds.  This entry may have a time
# zone specification which is currently ignored although it should be
# possible, not easy, to incorporate.  We assume that this information
# is only relevant for appointments and not TODO items.  We expect
# TODO items to have only a date for the START field and that date
# will be the scheduled date.  See above.

/^DTSTART(;TZID.*)?:/ {
    if (inevent) {
        # print "DTSTART line: " $0;
        # print "checking start time: " $2;
        date1 = strftime("%Y-%m-%d %a", datetimestamp($2));
        time1 = strftime(" %H:%M", datetimestamp($2));
        # print "====>         time: " time1;
        # print date;
    }
}

# and the same for the end date; here we extract only the time and append this to the 
# date+time found by the DTSTART entry.  We assume that entry was there, of course.
# should probably add some error checking here!  In time...

/^DTEND;VALUE=DATE/ {
    if (inevent) {
        # date2 = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]", "\\1-\\2-\\3", "g", $2)
        date2 = datestamp($2);
        time2 = ""
    }
}

/^DTEND(;TZID=[^:]*)?:/ {
    if (inevent) {
        # print $0
        date2 = strftime("%Y-%m-%d %a", datetimestamp($2));
        time2 = strftime("%H:%M", datetimestamp($2));
    }
}

# TODO items may (should?) have a DUE date/time.
/^DUE(;TZID=[^:]*)?:/ {
    if (intodo){
        date2 = strftime("%Y-%m-%d %a", datetimestamp($2));
        time2 = strftime("%H:%M", datetimestamp($2));
    }
}
# deadline with only a date
/^DUE;VALUE=DATE/ {
    # print "DUE;VALUE=DATE entry:" $0
    # print "... date part is >" $2 "<"
    # print "... date2 before " date2
    if (intodo) {
        #date2 = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3", "g", $2)
        date2 = datestamp($2);
        time2 = ""
    }
    # print "... date2 after " date2
}
# The description will the contents of the entry in org-mode.
# this line may be continued.

/^DESCRIPTION/ { 
    $1 = "";
    entry = entry "\n" gensub("\r", "", "g", $0);
    indescription = 1;
}

/^LOCATION/ {
    $1 = "";
    location = gensub("\r", "", "g", $0);
}

# the status of a TODO item: we know about NEEDS-ACTION and
# COMPLETED.  There may be others...
/^STATUS/ {
    if ($2 == "NEEDS-ACTION")
        todotype = "TODO";
    else if ($2 == "COMPLETED")
        todotype = "DONE";
    else
        todotype = "UNKNOWN";
}
# is there a repetition rule.  I don't know how general this is but
# Microsoft's Outlook calendar uses this for repeats

/^RRULE/ {
    # print ">>> Checking rule with string: " $2;
    i = match($2,"FREQ=[A-Z]+;");
    # printf(">>> Index=%d start=%d length=%d\n\n", i, RSTART, RLENGTH);
    frequency = substr($2, RSTART+5, RLENGTH-6);
    # print ">>> Frequency is " frequency "\n\n";
    i = match($2,"INTERVAL=[0-9]+;");
    interval = 1;               # default interval if none is found
    if (i>0) {
        interval = substr($2, RSTART+9, RLENGTH-10);
    }
    period = "";
    if (frequency == "DAILY") {
        period = "d";
    }
    else if (frequency == "WEEKLY") {
        period = "w";
    }
    else if(frequency == "MONTHLY") {
        period = "m";
    }
    else if(frequency == "YEARLY") {
        period = "y";
    }
    if (period != "") {
        repeat = sprintf(" +%d%s", interval, period);
    }
    # print ">>> Repeat is " repeat;
}

# the summary will be the org heading

/^SUMMARY/ { 
    $1 = "";
    if (!havesummary) {
        summary = gensub("\r", "", "g", $0);
        insummary = 1;
    }
}

# the unique ID will be stored as a property of the entry

/^UID/ { 
    $1 = "";
    id = gensub("\r", "", "g", $0);
    inuid = 1;
}

# when we reach the end of the event line, we output everything we
# have collected so far, creating a top level org headline with the
# date/time stamp, unique ID property and the contents, if any

/^END:VEVENT/ {
    # translate \n sequences to actual newlines and unprotect commas (,)
    print "* " gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary)) "  :" NAME ":"
    print ":PROPERTIES:"
    print ":ID:       " id
    if (location != "") {
        print ":LOCATION: " gensub("\\\\,", ",", "g", location);
    }
    print ":END:"
    if (date1 == date2) {
        if (time2 == "")
            print "  <" date1 time1 repeat ">"
        else
            print "  <" date1 time1 "-" time2 repeat ">"
    }
    else {
        if (time1 == "")
            print "<" date1 ">--<" date2 ">"
        else
            print "  <" date1 time1 ">--<" date2 " " time2 ">"
    }
    # for the entry, convert all embedded "\n" strings to actual newlines
    print ""
    # translate \n sequences to actual newlines and unprotect commas (,)
    print gensub("\\\\,", ",", "g", gensub("\\\\n", "\n", "g", entry));
    print "** COMMENT original iCal entry"
    print gensub("\r", "", "g", icalentry)
    summary = ""
    date = ""
    date1 = ""
    date2 = ""
    time1 = ""
    time2 = ""
    entry = ""
    icalentry = ""
    indescription = 0
    inevent = 0
    insummary = 0
    period = "";
    repeat = "";
}

# the end of a TODO item is similar to an event except that the dates
# are used for scheduling and deadline information

/^END:VTODO/ {
    # translate \n sequences to actual newlines and unprotect commas (,)
    print "* " todotype " " gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary)) "  :" NAME ":"
    # scheduling and deadline information come immediately after the
    # headline, before properties
    if (date1 != "") {
        if (date2 != "")
            if (time2 != "")
                print "SCHEDULED: <" date1 time1 "> DEADLINE: <" date2 " " time2 "> "
            else
                print "SCHEDULED: <" date1 time1 "> DEADLINE: <" date2 "> "
        else
            print "SCHEDULED: <" date1 time1 "> "
    } else if (date2 != "") {
        if (time2 != "")
            print "DEADLINE: <" date2 " " time2 "> "
        else
            print "DEADLINE: <" date2 "> "
    }
    # now come the properties which include the ID always and possibly
    # a location
    print ":PROPERTIES:"
    print ":ID:       " id
    if (location != "") {
        print ":LOCATION: " gensub("\\\\,", ",", "g", location);
    }
    print ":END:"
    # now the entry; we put in a blank line just because that's the
    # way I like it, ah ha ah ha... ;-)
    print ""
    # translate \n sequences to actual newlines and unprotect commas (,)
    print gensub("\\\\,", ",", "g", gensub("\\\\n", "\n", "g", entry));
    print "** COMMENT original iCal entry"
    print gensub("\r", "", "g", icalentry)
    summary = "";
    date = "";
    date1 = "";
    date2 = "";
    time1 = "";
    time2 = "";
    entry = "";
    icalentry = "";
    indescription = 0;
    inevent = 0;
    insummary = 0;
    intodo = 0;
    period = "";
    repeat = "";
}

# Local Variables:
# time-stamp-line-limit: 1000
# time-stamp-format: "%04y.%02m.%02d %02H:%02M:%02S"
# time-stamp-active: t
# time-stamp-start: "Last change:[ \t]+"
# time-stamp-end: "$"
# End:

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 194 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Broken Worg link
@ 2018-02-27 18:21 Thomas S. Dye
  2018-03-04  8:46 ` Bastien
  0 siblings, 1 reply; 5+ messages in thread
From: Thomas S. Dye @ 2018-02-27 18:21 UTC (permalink / raw)
  To: emacs-org list

Aloha all,

https://orgmode.org/worg/org-contrib/babel/languages.html 404s 
here.

All the best,
Tom

--
Thomas S. Dye
http://www.tsdye.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Broken Worg link
  2018-02-27 18:21 Broken Worg link Thomas S. Dye
@ 2018-03-04  8:46 ` Bastien
  0 siblings, 0 replies; 5+ messages in thread
From: Bastien @ 2018-03-04  8:46 UTC (permalink / raw)
  To: Thomas S. Dye; +Cc: emacs-org list

Hi Thomas,

"Thomas S. Dye" <tsd@tsdye.com> writes:

> https://orgmode.org/worg/org-contrib/babel/languages.html 404s here.

thanks a lot for reporting this -- it took me a while, but it was a
problem in the nginx configuration.

Also, if anyone notices pages with wrong CSS-styling, it probably
comes comes from pages using #+head_html instead of #+head_html_extra.

See for example:

https://code.orgmode.org/bzg/worg/commit/932cc5d0d7d99ea4da4f3d8a8607d7293d60e44e

Best,

-- 
 Bastien

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Broken worg link
  2018-02-27 14:57 Broken worg link Alex Branham
  2018-02-27 17:12 ` Eric S Fraga
@ 2018-03-04  8:47 ` Bastien
  1 sibling, 0 replies; 5+ messages in thread
From: Bastien @ 2018-03-04  8:47 UTC (permalink / raw)
  To: Alex Branham; +Cc: Org Mode List

Hi Alex,

Alex Branham <alex.branham@gmail.com> writes:

> https://orgmode.org/worg/org-tutorials/org-google-sync.html
>
> the link ical2org.awk 404s for me.

It should work now, thanks for reporting this.

-- 
 Bastien

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-03-04  8:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-27 18:21 Broken Worg link Thomas S. Dye
2018-03-04  8:46 ` Bastien
  -- strict thread matches above, loose matches on Subject: below --
2018-02-27 14:57 Broken worg link Alex Branham
2018-02-27 17:12 ` Eric S Fraga
2018-03-04  8:47 ` Bastien

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).