]> git.plutz.net Git - confetti/blobdiff - pages/cards.sh
unify ics parser
[confetti] / pages / cards.sh
index 0ead803fb32304a581ba5fcdaae35bcd2e8413de..3f0be4a8167ac0d2db5cafb57f09aea19ba60f9e 100755 (executable)
@@ -102,14 +102,17 @@ listcards() {
 }
 
 vcf_parse() {
+  unset key
   sed -r ':X;N;$!bX; s;\r\n[ \t];;g; s;\r\n;\n;g;' "$1" \
   | sed -rn '
-    # === turn property names to upper case ===
-    h; s;^([^\;:]+);;;
-    x; s;^([^\;:]+).*$;\1;;
+    # === turn property names to upper case, strip group names ===
+    h; s;^([^;:]+);;;
+    x; s;^([^;:\.]+\.)?([^;:]+).*$;\2;;
     y;abcdefghijklmnopqrstuvwxyz;ABCDEFGHIJKLMNOPQRSTUVWXYZ;
     G; s;\n;;;
 
+    
+
     # === Normalise various known vendor properties ===
                 s;^X-MS-CARDPICTURE(\;|:);PHOTO\1;;
                         s;^X-GENDER(\;|:);GENDER\1;;
@@ -129,73 +132,76 @@ vcf_parse() {
         s;^X-KADDRESSBOOK-X-SPOUSENAME(\;|:);RELATED\;VALUE=text\;TYPE=spouse\1;;
 
     # === Normalise obsolete vendor IM properties ===
-            s;^X-AIM((\;[a-zA-Z0-9-]+|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):;IMPP\1:aim:;;
-            s;^X-ICQ((\;[a-zA-Z0-9-]+|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):;IMPP\1:aim:;;
-    s;^X-GOOGLE-TALK((\;[a-zA-Z0-9-]+|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):;IMPP\1:xmpp:;;
-         s;^X-JABBER((\;[a-zA-Z0-9-]+|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):;IMPP\1:xmpp:;;
-            s;^X-MSN((\;[a-zA-Z0-9-]+|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):;IMPP\1:msn:;;
-          s;^X-YAHOO((\;[a-zA-Z0-9-]+|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):;IMPP\1:ymsgr:;;
-            s;^X-SIP((\;[a-zA-Z0-9-]+|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):(sip:)?;IMPP\1:sip:;;
+            s;^X-AIM((\;[a-Z0-9-]+|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:aim:;;
+            s;^X-ICQ((\;[a-Z0-9-]+|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:aim:;;
+    s;^X-GOOGLE-TALK((\;[a-Z0-9-]+|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:xmpp:;;
+         s;^X-JABBER((\;[a-Z0-9-]+|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:xmpp:;;
+            s;^X-MSN((\;[a-Z0-9-]+|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:msn:;;
+          s;^X-YAHOO((\;[a-Z0-9-]+|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:ymsgr:;;
+            s;^X-SIP((\;[a-Z0-9-]+|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(sip:)?;IMPP\1:sip:;;
 
     # === Update obsolete LABEL property ===
-    s;^LABEL((\;[a-zA-Z0-9-]+|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):(.*)$;ADR\1\;LABEL="\5":;;
+    s;^LABEL((\;[a-Z0-9-]+|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)$;ADR\1\;LABEL="\5":;;
 
-    /^([a-zA-Z0-9-]+)((\;[a-zA-Z0-9-]+=?|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):(.*)$/{
+    /^([A-Z0-9-]+)((\;[a-Z0-9-]+=?|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)$/{
       h;
-      s;^([a-zA-Z0-9-]+)((\;[a-zA-Z0-9-]+=?|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):(.*)$;key='\''\1'\'';;
+      s;^([A-Z0-9-]+)((\;[a-Z0-9-]+=?|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)$;key='\''\1'\'';;
       H; g;
-      s;^([a-zA-Z0-9-]+)((\;[a-zA-Z0-9-]+=?|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):([^\n]*)\n.*$;\6;;
+
+      s;^([A-Z0-9-]+)((\;[a-Z0-9-]+=?|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):([^\n]*)\n.*$;\2;;
       s;'\'';'\'\\\\\'\'';g
-      s;^.*$;value='\''&'\'';
-      H; g;
-      s;^([a-zA-Z0-9-]+)((\;[a-zA-Z0-9-]+=?|\;[a-zA-Z0-9-]+=([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*)*):([^\n]*)\n.*$;\2;;
+      s;\;([A-Z0-9-]+)(=|=(([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*))?;\ntag[\1]='\''\3'\'';g
+      s;^\n+;;; s;\n+$;;;
+      /^.+$/H; g;
+
+      s;^([A-Z0-9-]+)((\;[a-Z0-9-]+=?|\;[a-Z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):([^\n]*)\n.*$;\6;;
+      # :X s;((^|[^\\])(\\\\)*)[;,];\1\n;g; s;((^|[^\\])(\\\\)*)\\([;,]);\4;g; tX;
       s;'\'';'\'\\\\\'\'';g
-      s;\;([a-zA-Z0-9-]+)(=|=(([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*))?;\ntag[\1]='\''\3'\'';g
+      s;^.*$;value='\''&'\'';
       H; g;
-      s;^[^\n]*[\n ]+;;
 
-      s;\n[\n ]+;\n;g; s;\n$;;;
+      s;^[^\n]*[\n ]+;;
+      s;\n+$;;;
 
       p;
     }
-    '
+    ' \
+  | while read -r line; do
+    declare -A tag
+    case "$line" in
+      value*) eval "$line";;
+      tag*)   eval "$line";;
+      key*)
+        if [ -z "$key" ]; then
+          eval "$line"
+        else
+          values[${key}]="${value//\\r\\n/$BR}"
+          for t in ${(k)tag}; do
+            values[${key}_${t}]="${tag[$t]}"
+          done
+          eval "$line"
+          if [ -n "$values[$key]" ]; then
+            n=0
+            while [ -n "$values[$key$n]" ]; do n=$(($n + 1)); done
+            key=$key$n
+          fi
+          unset value
+          unset tag
+        fi
+      ;;
+    esac
+  done
 }
 
 view_card() {  #Parameter: Cardfile
   id="$1"
   cardfile="$_DATA/vcard/${id}"
   cachefile="$_DATA/cache/${id}.cache"
-  unset key
   if [ "$cachefile" -nt "$cardfile" ]; then
     cat "$cachefile"
   else
-    declare -A tags
     declare -A values
-    vcf_parse "$cardfile" |while read -r line; do
-      declare -A tag
-      case "$line" in
-        value*) eval "$line";;
-        tag*)   eval "$line";;
-        key*)
-          if [ -z "$key" ]; then
-            eval "$line"
-          else
-            values[$key]="${value//\\r\\n/$BR}"
-            for t in ${(k)tag}; do
-              tags[${key}_$t]="$tag[$t]"
-            done
-            eval "$line"
-            if [ -n "$values[$key]" ]; then
-              n=0
-              while [ -n "$values[$key$n]" ]; do n=$(($n + 1)); done
-              key=$key$n
-            fi
-            unset value
-            unset tag
-          fi
-        ;;
-      esac
-    done
+    vcf_parse "$cardfile"
     . $view_card |tee "$cachefile"
   fi
 }
@@ -205,34 +211,8 @@ edit_card() {  #Parameter: Cardfile
   cardfile="$_DATA/vcard/$id"
   tempfile="$_DATA/temp/$id"
   [ -f "$tempfile" ] && cardfile="$tempfile"
-  unset key
 
-  declare -A tags
   declare -A values
-  vcf_parse "$cardfile" |while read -r line; do
-    declare -A tag
-    case "$line" in
-      value*) eval "$line";;
-      tag*)   eval "$line";;
-      key*)
-        if [ -z "$key" ]; then
-          eval "$line"
-        else
-          [ -n "$value" ] && values[$key]="${value//\\r\\n/$BR}" || values[$key]='\r'
-          for t in ${(k)tag}; do
-            tags[${key}_$t]="$tag[$t]"
-          done
-          eval "$line"
-          if [ -n "$values[$key]" ]; then
-            n=0
-            while [ -n "$values[${key}${n}]" ]; do n=$(($n + 1)); done
-            key=$key$n
-          fi
-            unset value
-            unset tag
-        fi
-      ;;
-    esac
-  done
+  vcf_parse "$cardfile"
   . $edit_card
 }