Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: UIDs in calendar



Slightly less trivial calendar patch... this allows the use of
identifiers so as to be able to update events cleanly, and also allows
the lines to be hidden from human view.

Index: Doc/Zsh/calsys.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/calsys.yo,v
retrieving revision 1.9
diff -u -r1.9 calsys.yo
--- Doc/Zsh/calsys.yo	16 Aug 2007 09:31:47 -0000	1.9
+++ Doc/Zsh/calsys.yo	16 Aug 2007 11:27:53 -0000
@@ -50,6 +50,12 @@
 (note the date may not be continued in this way).  An initial ampersand
 (tt(&)) is ignored for compatibility.
 
+An indented line on which the first non-whitespace character is tt(#)
+is not displayed with the calendar entry, but is still scanned for
+information.  This can be used to hide information useful to the
+calendar system but not to the user, such as the unique identifier
+used by tt(calendar_add).
+
 The Emacs extension that a date with no description may refer to a number
 of succeeding events at different times is not supported.
 
@@ -289,13 +295,18 @@
 example(Feb 1, 2006 14:30 Pointless bureaucratic meeting
 Mar 27, 2006 11:00 Mutual recrimination and finger pointing
   Bring water pistol and waterproofs
+Mar 31, 2006 14:00 Very serious managerial pontification
+  # UID 12C7878A9A50
 Apr 10, 2006 13:30 Even more pointless blame assignment exercise WARN 30 mins
 May 18, 2006 16:00 Regular moaning session RPT monthly, 3rd Thursday)
 
-The second entry has a continuation line.  The third entry will produce
-a warning 30 minutes before the event (to allow you to equip yourself
-appropriately).  The fourth entry repeats after a month on the 3rd
-Thursday, i.e. June 15, 2006, at the same time.
+The second entry has a continuation line.  The third entry has a
+continuation line that will not be shown when the entry is displayed, but
+the unique identifier will be used by the tt(calendar_add) function when
+updating the event.  The fourth entry will produce a warning 30 minutes
+before the event (to allow you to equip yourself appropriately).  The fifth
+entry repeats after a month on the 3rd Thursday, i.e. June 15, 2006, at the
+same time.
 
 texinode(Calendar System User Functions)(Calendar Styles)(Calendar File and Date Formats)(Calendar Function System)
 sect(User Functions)
@@ -415,16 +426,32 @@
 findex(calendar_add)
 item(tt(calendar_add) [ tt(-BL) ] var(event ...))(
 Adds a single event to the calendar in the appropriate location.
+The event can contain multiple lines, as described in
+ifnzman(noderef(Calendar File and Date Formats))\
+ifzman(the section Calendar File Format above).
 Using this function ensures that the calendar file is sorted in date
 and time order.  It also makes special arrangments for locking
-the file will it is altered.  The old calendar is left in a file
+the file while it is altered.  The old calendar is left in a file
 with the suffix tt(.old).
 
 The option tt(-B) indicates that backing up the calendar file will be
 handled by the caller and should not be performed by tt(calendar_add).  The
 option tt(-L) indicates that tt(calendar_add) does not need to lock the
-calendar file up the old one as it is already locked.  These options will
-not usually be needed by users.
+calendar file as it is already locked.  These options will not usually be
+needed by users.
+
+The function can use a unique identifier stored with each event to ensure
+that updates to existing events are treated correctly.  The entry
+should contain the word tt(UID), followed by whitespace, followed by
+a word consisting entirely of hexadecimal digits of arbitrary length
+(all digits are significant, including leading zeroes).  As the UID
+is not directly useful to the user, it is convenient to hide it on
+an indented continuation line starting with a tt(#), for example:
+
+example(Aug 31, 2007 09:30  Celebrate the end of the holidays
+  # UID 045B78A0)
+
+The second line will not be shown by the tt(calendar) function.
 )
 findex(calendar_edit)
 item(tt(calendar_edit))(
Index: Functions/Calendar/calendar
===================================================================
RCS file: /cvsroot/zsh/zsh/Functions/Calendar/calendar,v
retrieving revision 1.5
diff -u -r1.5 calendar
--- Functions/Calendar/calendar	16 Aug 2007 09:31:48 -0000	1.5
+++ Functions/Calendar/calendar	16 Aug 2007 11:27:53 -0000
@@ -293,6 +293,13 @@
       showline=${line%%$'\n'*}
     else
       showline=$line
+      match=()
+      # Strip continuation lines starting " #".
+      while [[ $showline = (#b)(*$'\n')[[:space:]]##\#[^$'\n']##(|$'\n'(*)) ]]; do
+	showline="$match[1]$match[3]"
+      done
+      # Strip trailing empty lines
+      showline=${showline%%[[:space:]]#}
     fi
     if (( showall || (t >= start && (remaining || t <= stop || icount < showcount)) ))
     then
Index: Functions/Calendar/calendar_add
===================================================================
RCS file: /cvsroot/zsh/zsh/Functions/Calendar/calendar_add,v
retrieving revision 1.3
diff -u -r1.3 calendar_add
--- Functions/Calendar/calendar_add	31 Jan 2007 16:53:39 -0000	1.3
+++ Functions/Calendar/calendar_add	16 Aug 2007 11:27:53 -0000
@@ -12,7 +12,7 @@
 
 local calendar newfile REPLY lastline opt
 local -a calendar_entries lockfiles
-integer newdate done rstat nolock nobackup
+integer my_date done rstat nolock nobackup
 
 autoload -U calendar_{read,lockfiles,scandate}
 
@@ -42,10 +42,20 @@
   print "$0: failed to parse date/time" >&2
   return 1
 fi
-(( newdate = $REPLY ))
+(( my_date = $REPLY ))
 
 # $calendar doesn't necessarily exist yet.
 
+local -a match mbegin mend
+local my_uid their_uid
+
+# Match a UID, a unique identifier for the entry inherited from
+# text/calendar format.
+local uidpat='(|*[[:space:]])UID[[:space:]]##(#b)([[:xdigit:]]##)(|[[:space:]]*)'
+if [[ "$*" = ${~uidpat} ]]; then
+  my_uid=$match[1]
+fi
+
 # start of block for following always to clear up lockfiles.
 {
   (( nolock )) || calendar_lockfiles $calendar || return 1
@@ -55,15 +65,22 @@
 
     {
       for line in $calendar_entries; do
-	if (( ! done )) && calendar_scandate -a $line && (( REPLY > newdate )); then
+	if (( ! done )) && calendar_scandate -a $line && (( REPLY > my_date )); then
 	  print -r -- "$*"
 	  (( done = 1 ))
-	elif [[ $REPLY -eq $newdate && $line = "$*" ]]; then
+	fi
+	# Don't save this entry if it has the same UID as the new one.
+	if [[ -n $my_uid && $line = ${~uidpat} ]]; then
+	  their_uid=$match[1]
+	  [[ ${(U)my_uid} = ${(U)their_uid} ]] && continue
+	fi
+	if [[ $REPLY -eq $my_date && $line = "$*" ]]; then
+	  (( done )) && continue # paranoia: shouldn't happen
 	  (( done = 1 ))
 	fi
 	print -r -- $line
-	done
-	(( done )) || print -r -- "$*"
+      done
+      (( done )) || print -r -- "$*"
     } >$newfile
     if (( ! nobackup )); then
       if ! mv $calendar $calendar.old; then

-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


.



Messages sorted by: Reverse Date, Date, Thread, Author