[Pgp-tools-commit] r366 - in trunk: . debian sig2dot springgraph

myon at alioth.debian.org myon at alioth.debian.org
Wed Mar 12 21:44:02 UTC 2008


Author: myon
Date: 2008-03-12 21:44:00 +0000 (Wed, 12 Mar 2008)
New Revision: 366

Added:
   trunk/sig2dot/
   trunk/sig2dot/README.sig2dot
   trunk/sig2dot/changelog.sig2dot
   trunk/sig2dot/sig2dot
   trunk/sig2dot/sig2dot.1
   trunk/springgraph/
   trunk/springgraph/README.springgraph
   trunk/springgraph/changelog.springgraph
   trunk/springgraph/springgraph
   trunk/springgraph/springgraph.1
Modified:
   trunk/README
   trunk/debian/changelog
   trunk/debian/control
   trunk/debian/copyright
   trunk/debian/rules
Log:
* The 1.0 release.
* sig2dot, springgraph: new scripts joining the family, no longer provided
  as separate packages. We shamelessly bump our version number to something
  greater, and build transitional packages.

Modified: trunk/README
===================================================================
--- trunk/README	2008-03-05 16:28:31 UTC (rev 365)
+++ trunk/README	2008-03-12 21:44:00 UTC (rev 366)
@@ -10,6 +10,8 @@
 * gpgparticipants: create a list of key signing party participants,
   for use by the party organiser
 * keylookup: ncurses wrapper around gpg --search
+* sig2dot: converts a list of GnuPG signatures to a .dot file
+* springgraph: creates a graph from a .dot file
 
 For more information on each of these tools, please see their respective
 manpages. Please note that each individual project has its own license,

Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog	2008-03-05 16:28:31 UTC (rev 365)
+++ trunk/debian/changelog	2008-03-12 21:44:00 UTC (rev 366)
@@ -1,8 +1,13 @@
-signing-party (0.4.14-1) unreleased; urgency=low
+signing-party (1.0-1) unreleased; urgency=low
 
+  * The 1.0 release.
+
   [ Christoph Berg ]
   * gpglist: Do not barf on revokers (rvk). Thanks to Faidon Liambotis for
     spotting.
+  * sig2dot, springgraph: new scripts joining the family, no longer provided
+    as separate packages. We shamelessly bump our version number to something
+    greater, and build transitional packages.
 
   [ Thijs Kinkhorst ]
   * keylookup: cope with 16 or 40 nibble keyids, thanks Philippe Teuwen
@@ -15,7 +20,7 @@
   * caff: always update the user's key from their GnuPG home, to adequately
     cope with changed keys (Closes: #462897).
 
- -- Thijs Kinkhorst <thijs at debian.org>  Wed, 05 Mar 2008 17:27:01 +0100
+ -- Christoph Berg <myon at debian.org>  Wed, 12 Mar 2008 22:34:59 +0100
 
 signing-party (0.4.13-1) unstable; urgency=low
 

Modified: trunk/debian/control
===================================================================
--- trunk/debian/control	2008-03-05 16:28:31 UTC (rev 365)
+++ trunk/debian/control	2008-03-12 21:44:00 UTC (rev 366)
@@ -12,13 +12,16 @@
 Package: signing-party
 Architecture: all
 Depends: gnupg, libgnupg-interface-perl, libtext-template-perl, libmime-perl, libmailtools-perl
-Recommends: exim4 | mail-transport-agent, libtext-iconv-perl | libintl-perl | recode, dialog | whiptail, libpaper-utils
+Recommends: exim4 | mail-transport-agent, libtext-iconv-perl | libintl-perl | recode, dialog | whiptail, libpaper-utils,
+# springraph
+ libgd-gd2-noxpm-perl | libgd-gd2-perl
 Suggests: imagemagick | graphicsmagick-imagemagick-compat
-Replaces: keylookup (<< 3.0)
-Conflicts: keylookup (<< 3.0)
+Replaces: keylookup (<< 3.0), sig2dot (<< 1), springgraph (<< 1)
+Conflicts: keylookup (<< 3.0), sig2dot (<< 1), springgraph (<< 1)
+Provides: sig2dot, springgraph
 Description: Various OpenPGP related tools
  signing-party is a collection for all kinds of PGP/GnuPG related things,
- including signing scripts, party preparation scripts, etc.
+ including tools for signing keys, keyring analysis, and party preparation.
  .
   * caff: CA - Fire and Forget signs and mails a key
   * pgp-clean: removes all non-self signatures from key
@@ -29,4 +32,19 @@
   * gpgsigs: annotates list of GnuPG keys with already done signatures
   * gpgparticipants: create list of party participants for the organiser
   * keylookup: ncurses wrapper around gpg --search
+  * sig2dot: converts a list of GnuPG signatures to a .dot file
+  * springgraph: creates a graph from a .dot file
 
+Package: sig2dot
+Architecture: all
+Depends: signing-party (= ${binary:Version})
+Description: transitional package to pull in signing-party
+ This is an empty package to pull in signing-party in which sig2dot is
+ now included. It can safely be removed.
+
+Package: springgraph
+Architecture: all
+Depends: signing-party (= ${binary:Version})
+Description: transitional package to pull in signing-party
+ This is an empty package to pull in signing-party in which springgraph is
+ now included. It can safely be removed.

Modified: trunk/debian/copyright
===================================================================
--- trunk/debian/copyright	2008-03-05 16:28:31 UTC (rev 365)
+++ trunk/debian/copyright	2008-03-12 21:44:00 UTC (rev 366)
@@ -10,10 +10,17 @@
 Authors and Copyright:
   (c) 2000, 2002, 2004, 2005, 2006  Peter Palfrader <peter at palfrader.org>
   (c) 2004  Uli Martens <uli at youam.net>
-  (c) 2004, 2005, 2006  Christoph Berg <cb at df7cb.de>
+  (c) 2004-2008  Christoph Berg <cb at df7cb.de>
   (c) 2001-2005  Simon Richter <sjr at debian.org>
   (c) 2005, 2006, 2007  Thijs Kinkhorst <thijs at debian.org>
   (c) 2000, 2002  Christian Kurz <shorty at debian.org>
+
+  sig2dot and springgraph were originally written by:
+  (c) 2002 Darxus at ChaosReigns.com
+  http://www.chaosreigns.com/code/sig2dot/
+  http://www.chaosreigns.com/code/springgraph/
+  Modifications by Kevin Rosenberg.
+
   Other contributors:
   Enrico Zini
   Benjamin Hill
@@ -44,7 +51,8 @@
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-Licence for gpg-key2ps, gpg-mailkeys, gpgparticipants and keylookup:
+Licence for gpg-key2ps, gpg-mailkeys, gpgparticipants, keylookup, sig2dot,
+and springgraph:
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or

Modified: trunk/debian/rules
===================================================================
--- trunk/debian/rules	2008-03-05 16:28:31 UTC (rev 365)
+++ trunk/debian/rules	2008-03-12 21:44:00 UTC (rev 366)
@@ -25,6 +25,7 @@
 	dh_testroot
 	dh_clean -k
 	dh_installdirs
+	$(MAKE) install DESTDIR=$(CURDIR)/debian/signing-party
 	dh_install
 	dh_installman */*.1
 	install -d $(CURDIR)/debian/signing-party/usr/share/doc/signing-party/caff

Added: trunk/sig2dot/README.sig2dot
===================================================================
--- trunk/sig2dot/README.sig2dot	                        (rev 0)
+++ trunk/sig2dot/README.sig2dot	2008-03-12 21:44:00 UTC (rev 366)
@@ -0,0 +1,12 @@
+sig2dot
+-------
+
+Sig2dot parses the output of "gpg --list-sigs" into a format suitable
+for rendering into a graph by springgraph or graphviz.
+
+The syntax definition of the .dot files which sig2dot produces
+can be found in the graphviz man pages. A copy is here:
+ * http://www.graphviz.org/Documentation.php
+ * http://www.graphviz.org/cvs/doc/info/lang.html
+
+ -- Christoph Berg <cb at df7cb.de>  Sun,  6 Mar 2005 18:11:08 +0100

Added: trunk/sig2dot/changelog.sig2dot
===================================================================
--- trunk/sig2dot/changelog.sig2dot	                        (rev 0)
+++ trunk/sig2dot/changelog.sig2dot	2008-03-12 21:44:00 UTC (rev 366)
@@ -0,0 +1,169 @@
+sig2dot (0.37) unstable; urgency=low
+
+  * Add patch by Matteo Corti to make the graph title configurable.
+  * Fix targets in debian/rules.
+  * Bump Standards-Version.
+
+ -- Christoph Berg <myon at debian.org>  Wed, 31 May 2006 16:33:41 +0200
+
+sig2dot (0.36) unstable; urgency=low
+
+  * Patch by Thomas Huriaux: sig2dot must not include external signatures if
+    using a subset of your keyring (Closes: #302693).
+  * Patch by Eero Häkkinen: recognize trust signatures with a level >= 10
+    (Closes: #348783).
+
+ -- Christoph Berg <myon at debian.org>  Sat, 21 Jan 2006 10:08:40 +0100
+
+sig2dot (0.35) unstable; urgency=low
+
+  * Use strict and warnings.
+  * New -h/-q/-v options.
+  * Remove comment fields from UIDs (Closes: #318751).
+  * Support localized strings for revoked keys (Closes: #318740).
+  * Bump Standards-Version.
+
+ -- Christoph Berg <myon at debian.org>  Fri, 23 Sep 2005 13:27:33 +0200
+
+sig2dot (0.34-4) unstable; urgency=high
+
+  * Fix breakage with gnupg 1.4 (keys with trust signatures) noted by Matthew
+    Wilcox (Closes: #308271).
+
+ -- Christoph Berg <cb at df7cb.de>  Wed, 18 May 2005 23:48:47 +0200
+
+sig2dot (0.34-3) unstable; urgency=low
+
+  * New maintainer (Closes: #297446).
+  * Fixed to work with gpg 1.4 output, fixed some perl -w warnings.
+  * Updated pointer to dot syntax documentation.
+  * Fixed unescaped hyphens in sig2dot.1 and removed some whitespace.
+  * Removed redundant stuff in debian/rules and fixed non-functional dh_perl
+    call.
+  * Recommends: gnupg.
+
+ -- Christoph Berg <cb at df7cb.de>  Sun,  6 Mar 2005 20:18:41 +0100
+
+sig2dot (0.34-2) unstable; urgency=low
+
+  * Orphan as in bug #297446
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Sat,  5 Mar 2005 02:43:15 -0700
+
+sig2dot (0.34-1) unstable; urgency=low
+
+  * Incorporate patch from Thomas Huriaux
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Fri, 28 Jan 2005 20:00:15 -0700
+
+sig2dot (0.33-1) unstable; urgency=low
+
+  * Fix option -d processing (closes:285706)
+
+ -- root <kmr at debian.org>  Thu, 16 Dec 2004 05:44:21 -0700
+
+sig2dot (0.32-1) unstable; urgency=low
+
+  * Fix typo (closes:207025) 
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Sun, 24 Aug 2003 13:27:57 -0600
+
+sig2dot (0.31-1) unstable; urgency=low
+
+  * Avoid potential division by 0
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Wed, 20 Aug 2003 10:47:04 -0600
+
+sig2dot (0.30k-2) unstable; urgency=low
+
+  * Add -u parameter to man page.
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Thu, 31 Jul 2003 07:58:06 -0600
+
+sig2dot (0.30k-1) unstable; urgency=low
+
+  * Add localization patch by Marcus Frings (closes:202503)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Thu, 31 Jul 2003 00:55:01 -0600
+
+sig2dot (0.30j-1) unstable; urgency=low
+
+  * Revert patch (closes: 202484)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Tue, 22 Jul 2003 21:27:22 -0600
+
+sig2dot (0.30i-1) unstable; urgency=low
+
+  * Incorporate patch for renderdate option setting (closes: 201339)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Tue, 15 Jul 2003 10:24:28 -0600
+
+sig2dot (0.30h-1) unstable; urgency=low
+
+  * Incorporate patch for non-7bit names (closes:200329)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Mon,  7 Jul 2003 10:25:19 -0600
+
+sig2dot (0.30g-1) unstable; urgency=low
+
+  * Remove double quotes around names (closes:193123)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Fri, 16 May 2003 23:23:56 -0600
+
+sig2dot (0.30f-1) unstable; urgency=low
+
+  * Add -a option (closes:189417)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Sun, 11 May 2003 22:27:36 -0600
+
+sig2dot (0.30e-1) unstable; urgency=low
+
+  * Add N to regex (closes:188277)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Tue,  8 Apr 2003 19:34:50 -0600
+
+sig2dot (0.30d-1) unstable; urgency=low
+
+  * Improve comment (closes: 186608)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Fri, 28 Mar 2003 07:52:26 -0700
+
+sig2dot (0.30c-1) unstable; urgency=low
+
+  * Add another flag to regex (closes: 186138)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Mon, 24 Mar 2003 18:42:05 -0700
+
+sig2dot (0.30b-1) unstable; urgency=low
+
+  * Fix comment lines (closes: 183818)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Fri,  7 Mar 2003 19:42:39 -0700
+
+sig2dot (0.30a-1) unstable; urgency=low
+
+  * Fix manpage and copyright (closes: 183613) 
+  Thanks again for Marco Bodrato
+  * Update sig2dot comments with v0.30 information
+  
+ -- Kevin M. Rosenberg <kmr at debian.org>  Thu,  6 Mar 2003 07:01:09 -0700
+
+sig2dot (0.30-1) unstable; urgency=low
+
+  * Make regex more robust. Closes:#183496.
+  Thanks Marco Bodrato.
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Wed,  5 Mar 2003 11:11:09 -0700
+
+sig2dot (0.29-2) unstable; urgency=low
+
+  * Change architecture to all
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Fri, 21 Feb 2003 12:21:08 -0700
+
+sig2dot (0.29-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Tue, 18 Feb 2003 14:11:08 -0700
+

Added: trunk/sig2dot/sig2dot
===================================================================
--- trunk/sig2dot/sig2dot	                        (rev 0)
+++ trunk/sig2dot/sig2dot	2008-03-12 21:44:00 UTC (rev 366)
@@ -0,0 +1,433 @@
+#!/usr/bin/perl -w
+
+# sig2dot v0.29 (c) Darxus at ChaosReigns.com, released under the GPL
+# Download from: http://www.chaosreigns.com/code/sig2dot/
+# sig2dot v0.35-0.37 (c) 2005, 2006 Christoph Berg <cb at df7cb.de>
+# Download from: http://ftp.debian.org/debian/pool/main/s/sig2dot/
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+# Parses output of "gpg --list-sigs" into a format
+# suitable for rendering into a graph by graphviz 
+# (http://www.research.att.com/sw/tools/graphviz/) like so:
+#
+# $ gpg --list-sigs --keyring ./phillylinux.gpg | ./sig2dot.pl > phillylinux.dot
+# $ neato -Tps phillylinux.dot > phillylinux.ps
+# $ convert phillylinux.ps phillylinux.jpg
+#
+# Commandline options:
+#
+# -b
+#   Black and white / do not colorize.
+#
+# -d <date>
+#   Render graph as it appeared on <date> (ignores more recent
+#   signatures).  Date must be in the format "YYYY-MM-DD".
+#   Will also ignore keys that have since been revoked.
+#
+# -a
+#   Render all keys, even if they're not signed by any other key.
+#
+# -u <"string">
+#   Support localized output of GnuPG for unknown user IDs. For
+#   example, German users have to write (with sh quotation marks!)
+#   "[User-ID nicht gefunden]" if they use GnuPG with German
+#   messages. Default is "[User id not found]".
+#
+# -r <"string">
+#   Support localized output of GnuPG for revoked keys. For
+#   example, French users have to write "révoqué" if they use
+#   GnuPG with French messages. Default is "[revoked".
+#
+# -s stats.html
+#   Produces statistics file with number of signatures per node
+#
+# -t <"string">
+#   Graph title
+#
+# -h  print help
+# -v  print version
+# -q  be quiet
+#
+# Changes:
+#
+# v0.9 2000-09-14 19:20  strip trailing whitespace from $id more cleanly
+# v0.10 2000-09-14 19:33 skip revoked keys at the request of Peter Palfrader <ppalfrad at cosy.sbg.ac.at>
+# v0.11 Nov 22 21:38     use ID for node name instead of username for uniqueness
+# v0.12 Dec 15 16:20 use names instead of IDs again in stats.html
+# v0.13 Jun 19 03:15 red is proportional to signatures
+# v0.14 Jun 19 03:25 blue is proportional to other keys signed
+# v0.15 Jun 20 17:16 fixed blue, green is proportional to ratio
+# v0.16 Jun 20 18:55 uniqed %signedby
+# v0.17 Jan 10 19:10 Use overlap=scale instead of fixed edge lengths.  Requires new version of graphviz.
+# v0.18 Jan 23 11:53 stats.html is now valid html (v.01 transitional)
+# v0.23 May  3 18:52 bunch of new stuff, including -b flag (black & white), and fixes devision by zero error
+# v0.24 May  3 18:59 add black outline to nodes, prettier (changed node attribute "color" to "fillcolor")
+# v0.25 May  3 19:06 cleaned up anti- devision by zero code a little
+# v0.26 May  4 00:08 strip all non-digit characters from $renderdate
+# v0.27 May 10 00:23:49 2002 use {}'s to write 1 line per public key instead of one line per signature (much shorter)
+# v0.28 Feb 13 2003 Change regex to handle option trust digit 
+#                   <kevin at rosenberg.net>
+# v0.29 Feb 18 2003 Add -s option to optionally produce statistics file 
+#                   <kevin at rosenberg.net>
+# v0.30 Feb 18 2003 Make --list-sigs regex more robust 
+#                   Marco Bodrato <bodrato at gulp.linux.it>
+# v0.31 Jul 28 2003 Add -u option for localized output of GnuPG
+#                   Marcus Frings <protagonist at gmx.net>
+# further changes are documented in debian/changelog
+
+use strict;
+
+my $version = "0.37";
+
+my $chartchar = "*";
+my $renderdate = "";
+my ($stats, $color, $all, $not_found, $revokestr, $title);
+
+use Getopt::Std;
+my %opt;
+getopts('d:u:r:s:bahqvt:', \%opt);
+
+sub version {
+  print <<EOT;
+sig2dot $version
+Copyright (c) 2002 Darxus\@ChaosReigns.com
+Copyright (c) 2005, 2006 Christoph Berg <cb\@df7cb.de>
+EOT
+}
+
+if ($opt{h}) {
+  version();
+  print <<EOT;
+gpg --list-sigs | $0 [-abdhqsuv] > sigs.dot
+-a              Graph all keys, even if they do not have a signature
+-b              Black and white / do not colorize.
+-d YYYY-MM-DD   Render graph as it appeared on date.
+-h              Print this help and exit.
+-q              Be quiet.
+-r sting        key-is-revoked string (default: "[revoked").
+-s stats.html   Produces statistics file with number of signatures per node.
+-t title        Graph title
+-u string       user-id-not-found string (default: "[user id not found]").
+-v              Print version and exit.
+EOT
+  exit 0;
+}
+if ($opt{v}) {
+  version();
+  exit 0;
+}
+
+if ($opt{d}) { 
+  $renderdate = $opt{d}; 
+  print STDERR "Printing from date: $renderdate.\n";
+  $renderdate =~ s/\D+//g;
+}
+if ($opt{s}) { 
+  $stats = $opt{s}; 
+  print STDERR "Print statistics to $stats.\n";
+}
+if ($opt{b}) 
+{ 
+  $color = 0; 
+  print STDERR "Black and White.\n" unless $opt{q};
+} else { 
+  $color = 1; 
+  print STDERR "Color.\n" unless $opt{q};
+}
+if ($opt{a}) {
+  $all = 1;
+} else {
+  $all = 0;
+}
+
+if ($opt{u}) {
+  $not_found = lc $opt{u};
+} else {
+  $not_found = "[user id not found]"; # this changed from gpg 1.2 -> 1.4
+}
+
+if ($opt{r}) {
+  $revokestr = lc $opt{r};
+} else {
+  $revokestr = "[revoked"; # this changed from gpg 1.2 -> 1.4
+}
+
+if ($opt{t}) {
+  $title = lc $opt{t};
+} else {
+  $title = "Keyring Statistics";
+}
+
+my ($owner, %name, %revlist, %sigstmp, %signedbytmp, %idlist, @names, %revs);
+
+while (my $line = <>)
+{
+  chomp $line;
+
+# gpg 1.2
+#pub  1024D/807CAC25 2003-08-01 Michael Ablassmeier (abi) <abi#grinser.de>
+#sig         B3B2A12C 2004-01-28   [User id not found]
+#sig 3       9456ADE2 2004-02-07   Michael Schiansky <michael#schiansky.de>
+# gpg 1.4:
+#pub   1024D/807CAC25 2003-08-01
+#uid                  Michael Ablassmeier (abi) <abi#grinser.de>
+#sig          B3B2A12C 2004-01-28  [User ID not found]
+#sig 3        9456ADE2 2004-02-07  Michael Schiansky <michael#schiansky.de>
+
+                 # type                          id       date       name
+   if ($line =~ m#([\w]+)[ !\?][ \dLNPRTX]{0,8} +([^ ]+) +([^ ]+)(?: +"?([^<"]*))?#)
+# differences:
+# " " -> "[ !\?]" (to use 'gpg --check-sigs|sig2dot.mio|springgraph|display')
+# "[ \d]" -> "[ \dLRXP]" (signature attributes)
+# "[^<]+" -> "[^<]*" (to recognise "pub" lines whitout a name)
+#  if ($line =~ m#([\w]+) [ \d]? +([^ ]+) +([^ ]+) +([^<]+)#)
+#  if ($line =~ m#([\w]+) +([^ ]+) +([^ ]+) +([^<]+)#)
+
+  {
+    my $type = $1;
+    my $id = $2;
+    my $date = $3;
+    my $name = $4 || "";
+
+    $date =~ tr/-//d;
+    if ($type eq "pub" or $renderdate eq "" or $date <= $renderdate)
+    {
+      print STDERR "Using: $line\n" unless $opt{q};
+      # strip trailing whitespace more cleanly:
+      $name =~ s/\s+$//g;
+
+      #Remove re: http://bugs.debian.org/202484
+      #$name =~ s/[^a-zA-Z \.0-9]/_/g; # handle non-7bit names
+
+      if ($type eq "pub")
+      {
+        $id = (split('/',$id))[1];
+        $owner = $id;
+        $idlist{$id} = 1 if (index($name, $revokestr) < 0);
+      }
+
+      # remove comment field
+      $name{$id} = (split ' \(', $name)[0] if $name; # gpg 1.4 fixup
+
+      # skip revoked keys 
+      if (index($name, $revokestr) >= 0) {
+        $revlist{$id} = 1;
+        next;
+      }
+
+      if ($type eq "uid") {
+	$name{$owner} = $id; # gpg 1.4 fixup
+      }
+  
+#      unless (defined @{$sigs{$owner}})
+#      {
+#        @{$sigs{$owner}} = ();
+#      }
+      if ($type eq "sig" and lc $name ne $not_found)
+      {
+	if ($id ne $owner) {
+	  push (@{$sigstmp{$owner}},$id);
+	  push (@{$signedbytmp{$id}},$owner);
+	}
+	if ($all or $id ne $owner) {
+	  push (@names,$id,$owner);
+	}
+      }
+      if ($type eq "rev" and lc $name ne $not_found)
+      {
+	if ($id ne $owner) {
+	  push (@{$revs{$owner}},$id);
+	  #push (@{$revokedby{$id}},$owner);
+	}
+      }
+    } else {
+      print STDERR "Skipping due to date: $line\n";
+    }
+  } else {
+    print STDERR "Skipping due to regex: $line\n" if $line ne "";
+  }
+}
+
+my (%sigs, %signedby);
+
+for my $id (sort {$sigstmp{$a} <=> $sigstmp{$b}} keys %sigstmp) {
+  next if (defined $revlist{$id});
+  foreach my $owner (@{$signedbytmp{$id}}) {
+    next if (defined $revlist{$owner});
+    my $revoke = 0;
+    foreach my $revid (@{$revs{$owner}}) {
+      if ($revid eq $id) {
+        $revoke = 1;
+      }
+    }
+    #$res = $revlist{$id};
+    if (($revoke == 0)) {
+      push (@{$sigs{$owner}},$id);
+      push (@{$signedby{$id}},$owner);
+    }
+  }
+}
+
+print "digraph \"$title\" {\noverlap=scale\nsplines=true\nsep=.1\n";
+
+my %saw;
+ at saw{@names} = ();
+ at names = keys %saw;
+undef %saw;
+
+my $maxsigcount = 0;
+my (%sigcount);
+
+for my $owner (sort {$sigs{$a} <=> $sigs{$b}} keys %sigs)
+{
+  undef %saw;
+  @saw{@{$sigs{$owner}}} = ();
+  @{$sigs{$owner}} = keys %saw;
+  undef %saw;
+  undef %saw;
+  $signedby{$owner} ||= [];
+  @saw{@{$signedby{$owner}}} = ();
+  @{$signedby{$owner}} = keys %saw;
+  undef %saw;
+
+  $sigcount{$owner} = scalar(@{$sigs{$owner}});
+  if ($sigcount{$owner} > $maxsigcount)
+  {
+    $maxsigcount = $sigcount{$owner};
+  }
+}
+
+my %signedbycount;
+my ($maxsignedbycount, $maxratio) = (0, 0);
+
+for my $owner (sort {$signedby{$a} <=> $signedby{$b}} keys %signedby)
+{
+  $signedbycount{$owner} = scalar(@{$signedby{$owner}});
+  if ($signedbycount{$owner} > $maxsignedbycount)
+  {
+    $maxsignedbycount = $signedbycount{$owner};
+  }
+  if ($sigcount{$owner} and $sigcount{$owner} > 0) {
+    if ($signedbycount{$owner} / $sigcount{$owner} > $maxratio)
+    {
+      $maxratio = $signedbycount{$owner} / $sigcount{$owner};
+    }
+  }
+}
+print "//$maxratio\n";
+
+if ($stats) {
+    open (STATS,">$stats");
+    print STATS "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html><head><title>$title</title></head><body><table border=1>\n";
+
+    for my $owner (sort {$sigcount{$b} <=> $sigcount{$a}} keys %sigs)
+    {
+	print STATS "<tr><td>$name{$owner}<td>$sigcount{$owner}<td><img src=\"/images/pipe0.jpg\" height=15 width=",$sigcount{$owner} * 20," alt=\"". $chartchar x $sigcount{$owner} ."\">\n";
+    }
+    
+    print STATS "</table></body></html>\n";
+    close STATS;
+}
+
+print "node [style=filled]\n";
+for my $id (@names)
+{
+  if ((not exists $sigcount{$id}) and (not exists $signedbycount{$id}) and not $all) {
+    next;
+  }
+  next unless (defined $idlist{$id});
+  if ($color)
+  {
+    my ($red, $green, $blue) = (0, 1/3, 1/3);
+    if ($sigcount{$id}) {
+      $red = $sigcount{$id} / $maxsigcount;
+    }
+    if ($sigcount{$id} && $maxratio != 0)
+    {
+      $green = ($signedbycount{$id} / $sigcount{$id} / $maxratio * .75) * 2/3 + 1/3;
+    }
+    if ($signedbycount{$id} and $maxsignedbycount != 0) {
+      $blue = ($signedbycount{$id} / $maxsignedbycount) * 2/3 + 1/3;
+    }
+
+    my ($hue,$saturation,$value) = rgb2hsv($red,$green,$blue);
+    printf "//%d %d $red,$green,$blue\n", $sigcount{$id} || 0, $signedbycount{$id} || 0;
+    print "\"$id\" [fillcolor=\"$hue,$saturation,$value\",label=\"$name{$id}\"]\n";
+  } else {
+    print "\"$id\" [label=\"$name{$id}\"]\n";
+  }
+}
+#print "node [style=solid]\n";
+
+for my $owner (sort keys %sigs)
+{
+ print "{ ";
+  for my $id (@{$sigs{$owner}})
+  {
+    print "\"$id\" ";
+  }
+  print "} -> \"$owner\"\n";
+}
+
+print "}\n";
+
+#  Converts rgb to hsv.  All numbers are within range 0 to 1
+#  from http://twiki.org/cgi-bin/view/Codev/WebMap
+sub rgb2hsv {
+    my ($r, $g ,$b) = @_;
+    my $max = maxof($r, maxof($g, $b));
+    my $min = minof($r, minof($g, $b));
+    my $v = $max;
+    my ($s, $h);
+
+    if ($max > 0.0) {
+        $s = ($max - $min) / $max;
+    } else {
+        $s = 0;
+    }
+    if ($s > 0.0) {
+        my ($rc, $gc, $bc, $diff);
+            $diff = $max - $min;
+        $rc = ($max - $r) / $diff;
+        $gc = ($max - $g) / $diff;
+        $bc = ($max - $b) / $diff;
+        if ($r == $max) {
+            $h = ($bc - $gc) / 6.0;
+        } elsif ($g == $max) {
+            $h = (2.0 + $rc - $bc) / 6.0;
+        } else {
+            $h = (4.0 + $gc - $rc) / 6.0;
+        }
+    } else {
+       $h = 0.0;
+    }
+    if ($h < 0.0) {
+       $h += 1.0;
+    }
+    return ($h, $s, $v);
+}
+sub maxof {
+   my ($a, $b) = @_;
+
+   return $a>$b?$a:$b;
+}
+sub minof {
+   my ($a, $b) = @_;
+
+   return $a<$b?$a:$b;
+}
+
+# vim:sw=2:


Property changes on: trunk/sig2dot/sig2dot
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/sig2dot/sig2dot.1
===================================================================
--- trunk/sig2dot/sig2dot.1	                        (rev 0)
+++ trunk/sig2dot/sig2dot.1	2008-03-12 21:44:00 UTC (rev 366)
@@ -0,0 +1,80 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.\" First parameter, NAME, should be all caps
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
+.\" other parameters are allowed: see man(7), man(1)
+.TH SIG2DOT 1 "May 31, 2006"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+sig2dot \- creates a .dot file from a GPG signature listing
+.SH SYNOPSIS
+.B sig2dot [OPTIONS] < input-file > output-file
+.br
+.SH DESCRIPTION
+This manual page documents briefly the
+.B sig2dot
+command.
+Sig2dot parses the output of "gpg \-\-list\-sigs" and produces a .dot file
+that can be used as input to a graphing program.
+.SH OPTIONS
+\fIsig2dot\fP
+accepts the following options:
+.TP 16
+.B \-b
+Black and white / do not colorize.
+.TP 16
+.B \-d <date>
+Render graph as it appeared on <date> (ignores more recent
+signatures).  Date must be in the format "YYYY\-MM\-DD".
+Will also ignore keys that have since been revoked.
+.TP 16
+.B \-s <html-file-name>
+Produces a sory HTML statistics file with the number of signatures per node.
+.TP 16
+.B \-a
+Graph all keys, even if they do not have a signature
+.TP 16
+.B \-r "<key-revoked-string>"
+Sets the text for the key-revoked string used by GnuPG. The default is 
+what is used in the English version. This parameter can be set for versions 
+of GnuPG localized to other languages. Default: "[revoked".
+.TP 16
+.TP 16
+.B \-t "<title>"
+Sets the title for the graph generated. Default: "Keyring Statistics".
+.TP 16
+.B \-u "<user-not-found-string>"
+Sets the text for the user-not-found string used by GnuPG. The default is 
+what is used in the English version. This parameter can be set for versions 
+of GnuPG localized to other languages. Default: "[user id not found]".
+.TP 16
+.B \-q
+Be quiet.
+.TP 16
+.B \-h
+Print help and exit.
+.TP 16
+.B \-v
+Print version and exit.
+.SH EXAMPLE
+gpg \-\-list\-sigs | sig2dot > sigs.dot
+.sp 0
+springgraph < sigs.dot > sigs.png
+.SH SEE ALSO
+.B springgraph(1)
+.B gnupg(1)
+.SH AUTHORS
+Darxus at ChaosReigns.com with modifications by Kevin Rosenberg.
+Versions 0.35 and later are by Christoph Berg <cb at df7cb.de>.
+This manual page was written by Kevin M. Rosenberg <kmr at debian.org>,
+for the Debian GNU/Linux system (but may be used by others).

Added: trunk/springgraph/README.springgraph
===================================================================
--- trunk/springgraph/README.springgraph	                        (rev 0)
+++ trunk/springgraph/README.springgraph	2008-03-12 21:44:00 UTC (rev 366)
@@ -0,0 +1,26 @@
+springgraph
+-----------
+
+Springgraph will read in a .dot file description of a graph, which,
+for each node, specifies its name and which other nodes it is
+connected to, and then renders a graph. Each node is drawn as an
+ellipse, and each connection is drawn as an arrow. The node placement
+is a result of all of the nodes moving away from each other, while
+all nodes which are connected move toward each other. This movement
+is repeated until it stabilizes.
+
+Springgraph was written as an alternative to neato, which is part of
+graphviz. It attempts to read the same .dot files used by graphviz,
+but currently only supports a limited number of node attributes
+(label and fillcolor).
+
+Definition of the .dot files which springgraph renders can be found
+in the graphviz man pages. A copy is here:
+ * http://www.graphviz.org/Documentation.php
+ * http://www.graphviz.org/cvs/doc/info/lang.html
+
+Springgraph only supports the fillcolor and label node attributes, and can only
+handle two nodes per edge definition ("node1 -> node2", not "node1 -> node2 ->
+node3").
+
+ -- Christoph Berg <cb at df7cb.de>  Sun,  6 Mar 2005 17:44:47 +0100

Added: trunk/springgraph/changelog.springgraph
===================================================================
--- trunk/springgraph/changelog.springgraph	                        (rev 0)
+++ trunk/springgraph/changelog.springgraph	2008-03-12 21:44:00 UTC (rev 366)
@@ -0,0 +1,94 @@
+springgraph (0.82-7) UNRELEASED; urgency=low
+
+  * NOT RELEASED YET
+
+ -- Christoph Berg <myon at debian.org>  Sat, 28 Oct 2006 13:46:46 +0200
+
+springgraph (0.82-6) unstable; urgency=low
+
+  * Add missing targets in debian/rules (Closes: #395791).
+  * Build package in binary-indep.
+  * Use dh_perl.
+
+ -- Christoph Berg <myon at debian.org>  Sat, 28 Oct 2006 13:32:54 +0200
+
+springgraph (0.82-5) unstable; urgency=low
+
+  * Fix typo in manpage (Closes: #310340, thanks to A Costa for the patch).
+  * Add syntax example to manpage.
+  * Use ${perl:Depends}.
+  * Bump Standards-Version.
+
+ -- Christoph Berg <myon at debian.org>  Mon,  5 Sep 2005 14:01:12 +0200
+
+springgraph (0.82-4) unstable; urgency=low
+
+  * New maintainer (Closes: #297447).
+  * Removed redundant parts of debian/rules.
+  * Updated pointer to dot language documentation (Closes: #295700).
+
+ -- Christoph Berg <cb at df7cb.de>  Sun,  6 Mar 2005 16:37:47 +0100
+
+springgraph (0.82-3) unstable; urgency=low
+
+  * Orphan as in bug #297447
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Sat,  5 Mar 2005 02:44:42 -0700
+
+springgraph (0.82-2) unstable; urgency=low
+
+  * Add more documentation (closes:267495)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Mon, 23 Aug 2004 14:45:18 -0600
+
+springgraph (0.82-1) unstable; urgency=low
+
+  * Accept patch from Tobias Gruetzma for more layout options
+    (closes:234117)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Tue, 24 Feb 2004 08:53:45 -0700
+
+springgraph (0.81-1) unstable; urgency=low
+
+  * Caption stderr progress notes (closes:206147)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Wed, 20 Aug 2003 10:37:21 -0600
+
+springgraph (0.80.1-1) unstable; urgency=low
+
+  * Allow use of libgd-gd2-noxpm-perl (closes:188856)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Mon, 14 Apr 2003 08:15:30 -0600
+
+springgraph (0.80-1) unstable; urgency=low
+
+  * Apply speed-up patch from Marco Bodrato  (closes: 185532)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Wed, 19 Mar 2003 21:06:15 -0700
+
+springgraph (0.79-4) unstable; urgency=low
+
+  * Use libgd-gd2-perl rather than libgd-gd1-perl (closes:183919)
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Sat,  8 Mar 2003 05:20:43 -0700
+
+springgraph (0.79-3) unstable; urgency=low
+
+  * Change architecture to all
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Fri, 21 Feb 2003 12:19:36 -0700
+
+springgraph (0.79-2) unstable; urgency=low
+
+  * Added perl dependency
+  * Move to extra priority.
+  * Use dh_perl and ${perl:depend}
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Tue, 18 Feb 2003 19:21:04 -0700
+
+springgraph (0.79-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Kevin M. Rosenberg <kmr at debian.org>  Tue, 18 Feb 2003 14:11:08 -0700
+

Added: trunk/springgraph/springgraph
===================================================================
--- trunk/springgraph/springgraph	                        (rev 0)
+++ trunk/springgraph/springgraph	2008-03-12 21:44:00 UTC (rev 366)
@@ -0,0 +1,900 @@
+#!/usr/bin/perl -w
+
+# springgraph v0.79, (c) 2002 Darxus at ChaosReigns.com, released under the GPL
+# Download current version from:  http://www.chaosreigns.com/code/springgraph/
+#
+# This program attempts to render .dot files in a fashion similar to neato,
+# which is part of graphviz:  http://www.research.att.com/sw/tools/graphviz/.
+# I have never looked at any of the code in graphviz.
+#
+# Example usage:
+#
+# cat test.dot | ./springgraph.pl -s 3 > springgraph.png
+#
+# The "-s 3" specifies the scale, and is optional.  All of the node
+# locations are multiplied by this.  Increase the scale to eliminate
+# node overlaps.  Decrease the scale to make the graph smaller.
+#
+# Requirements:  GD.pm (http://www.perl.com/CPAN/authors/id/L/LD/LDS/)
+# 
+# Definition of the .dot files which springgraph renders
+# can be found in the graphviz man pages.  A copy is here:
+# http://www.unisa.edu.au/eie/csec/graphviz/dot.1.html.  Springgraph only
+# supports the fillcolor and label node attributes, and can only handle
+# two nodes per edge definition ("node1 -> node2", not "node1 -> node2
+# -> node3").
+# 
+# Springgraph fully supports the .dot files generated by sig2dot
+# (http://www.chaosreigns.com/code/sig2dot), which generates .dot files
+# from GPG/PGP signature relationships.
+# 
+# Thanks to the following for help with the math for the arrowheads:
+# Mike Joseph <mj at doze.net>
+# Walt Mankowski <waltman at pobox.com>
+# Jeff Weisberg <jaw+plug at tcp4me.com>
+#
+# Yes, the placement of the freaking arrowheads was by far the hardest
+# part of writing this program.
+#
+# Thanks to Hartmut Palm for cylinder translation/rotation code in
+# VRML.pm:  http://dc.gfz-potsdam.de/~palm/vrmlperl/
+
+# v0.26 May 06 16:12:30 2002 
+# v0.27 May 06 18:15:38 2002 cleanup
+# v0.44 May 06 23:56:45 2002 
+# v0.56 May 07 05:10:02 2002
+# v0.60 May 07 23:27:29 2002 arrow heads !! (not filled in due to segfault)
+# v0.61 May 07          2002 handle absence of beginning double-quote in fillcolor attribute
+# v0.62 May 08 19:44:04 2002 use getopts to get scale argument
+# v0.63 May 08 21:29:48 2002 made fillcolor optional again
+# v0.64 May 08 22:28:40 2002 render http://www.research.att.com/sw/tools/graphviz/examples/undirected/ER.dot.txt
+#                            and http://www.research.att.com/sw/tools/graphviz/examples/undirected/process.dot.txt
+#                            (added support for undirected graphs ("--" links)
+# v0.65 May 08 22:44:00 2002 render http://www.research.att.com/sw/tools/graphviz/examples/directed/fsm.dot.txt
+#                            (do not attempt to draw a line from a node to itself and cause a devision by zero)
+# v0.67 May 09 05:53:16 2002 support multiple nodes on one link line, adjusted detection of completion
+#                            render http://www.research.att.com/sw/tools/graphviz/examples/directed/unix.dot.txt
+#                            (support node names containing spaces)
+# v0.68 May 09 17:29:06 2002 cleaned up link line processing a bit (removed extraneous define checks)
+# v0.69 May 09 18:23:19 2002 render http://www.research.att.com/sw/tools/graphviz/examples/undirected/inet.dot.txt
+#                            (support {} lists in link (edge) lines)
+# v0.70 May 10 00:39:20 2002 Strip double-quotes that were getting missed to support sig2dot v0.27.
+# v0.71 May 11 20:06:17 2002 don't draw twice, added some 3D math (but not output yet)
+# v0.72 May 11 21:31:20 2002 3D output !!! (via -p flag)
+# v0.73 May 11 22:34:23 2002 added labels to 3D output
+# v0.74 May 12 02:07:29 2002 output 3D output suitable for animation
+# v0.75 May 13 01:45:41 2002 beginnings of vrml output (-v) - colored spheres
+# v0.76 May 13 04:30:13 2002 added connections between nodes to vrml
+#                            output, thanks cylinder translation/rotation
+#                            code from VRML.pm by Hartmut Palm:
+#                            http://dc.gfz-potsdam.de/~palm/vrmlperl/
+# v0.77 May 13 04:41:53 2002 made colors optional in pov and vrml output
+# v0.78 May 13 06:31:34 2002 removed extra cylinders from vrml output
+# v0.79 May 13 07:20:23 2002 made 2d output background transparent
+# v0.80 Mar 19 2003 optimization patch from Marco Bodrato
+# v0.81 Aug 20 2003 Caption stderr progress notes
+
+use GD;
+use Getopt::Std;
+use strict;
+use vars qw(
+$push
+$pull
+%node
+$im
+$source
+$dest
+$nodenum
+$blue
+$black
+$opt_b
+$bgcol
+ at bgcolor
+$dist
+$iter
+$maxiter
+$percent
+$xdist
+$ydist
+$newdist2
+$xmove
+$ymove
+$movecount
+$rate
+$nodes
+%link
+$continue
+$done
+$line
+ at nodelist
+%saw
+$name
+$label
+$margin
+$minx
+$miny
+$maxx
+$maxy
+$scale
+$nodesize
+$powderblue
+$linecol
+$h
+$s
+$v
+$r
+$g
+$b
+$color
+$maxxlength
+$minxlength
+$pi
+$twopi
+$angle
+ at point
+$width
+$height
+$arrowlength
+$arrowwidth
+$num
+$opt_s
+$edge
+ at parts
+$part
+ at sources
+ at dests
+$sourcesstring
+$destsstring
+$pov
+$opt_p
+$zdist
+$zmove
+$pov_or_vrml
+$opt_v
+$vrml
+$opt_t
+$trans
+$opt_h
+$opt_l
+ at linecolor
+);
+
+$push = 2000;
+$pull = .1;
+$maxiter = 400;
+$rate = 2;
+$nodes = 5;
+#$done = 0.1;
+$done = 0.3;
+#$done = 3;
+$margin = 20;
+#$nodesize = 80;
+$nodesize = 40;
+$arrowlength = 10; # pixels
+$arrowwidth = 10; 
+
+srand 1; #comment out this line to generate graphs differently every time
+
+$pi = 3.141592653589793238462643383279502884197169399375105; # from memory
+$twopi = $pi * 2;
+
+getopts('s:pvhtb:l:');
+
+# -s: set scale
+if ($opt_s)
+{
+  $scale = $opt_s;
+} else {
+  $scale = 1;
+}
+
+# -p: Output as Pov-Ray
+if ($opt_p)
+{
+  $pov = 1;
+} else {
+  $pov = 0;
+}
+
+# -v: Output as VRML
+if ($opt_v)
+{
+  $vrml = 1;
+} else {
+  $vrml = 0;
+}
+
+# -h: Show some help
+if ($opt_h) {
+  usage();
+  exit 1;
+}
+
+# -t: Make background transparent
+if ($opt_t)
+{
+  $trans = 1;
+} else {
+  $trans = 0;
+}
+
+# -b: Set background color
+if ($opt_b)
+{
+  $trans = 0;
+  $opt_b =~ m/^(..)(..)(..)$/ or die "Invalid color: $opt_b";
+  @bgcolor = (hex($1), hex($2), hex($3));
+} else {
+  @bgcolor = (255, 255, 255);
+}
+
+# -l: Set line color
+if ($opt_l)
+{
+  $trans = 0;
+  $opt_l =~ m/^(..)(..)(..)$/ or die "Invalid color: $opt_l";
+  @linecolor = (hex($1), hex($2), hex($3));
+} else {
+  @linecolor = (169, 169, 169);
+}
+
+$done = $done / $scale;
+
+while ($line = <STDIN>)
+{
+  undef $name;
+  next if ($line =~ m#^//#);
+  chomp $line;
+  # 2 = arro1, 1 = no arrow
+  if ($line =~ m#^(.*-[>-][^\[]*)#)
+  {
+    $edge = $1;
+    @parts = split(/(-[->])/,$edge);
+    for $part (0 .. $#parts)
+    {
+      if (defined $parts[$part+2] and $parts[$part] ne '->' and $parts[$part] ne '--')
+      {
+        #print ":$parts[$part]:".$parts[$part+1].":".$parts[$part+2].":\n";
+        undef @sources;
+        undef @dests;
+        $parts[$part] =~ s/^\s*"?//;
+        $parts[$part] =~ s/"?\s*$//;
+        $parts[$part+2] =~ s/^\s*"?//;
+        $parts[$part+2] =~ s/"?\s*;?\s*$//;
+        if ($parts[$part] =~ m#^{(.*)}$#)
+        {
+          $sourcesstring = $1;
+          #print STDERR "sourcesstring:$sourcesstring:\n";
+          @sources = split(/[\s*;?\s*]/,$sourcesstring);
+        } else {
+          $sources[0] = $parts[$part];
+        }
+        if ($parts[$part+2] =~ m#^{(.*)}$#)
+        {
+          $destsstring = $1;
+          #print STDERR "destsstring:$destsstring:\n";
+          @dests = split(/[\s*;?\s*]/,$destsstring);
+        } else {
+          $dests[0] = $parts[$part+2];
+        }
+        for $source (@sources)
+        {
+          next if ($source eq "");
+          for $dest (@dests)
+          {
+            next if ($dest eq "");
+            $source =~ s/^\s*"?//;
+            $source =~ s/"?\s*$//;
+            $dest =~ s/^\s*"?//;
+            $dest =~ s/"?\s*;?\s*$//;
+            $link{$source}{$dest} = 2 if ($parts[$part+1] eq '->');
+            $link{$source}{$dest} = 1 if ($parts[$part+1] eq '--');
+            push (@nodelist,$source,$dest);
+            #print STDERR "$source ".$parts[$part+1]." $dest\n";
+          }
+        }
+      }
+    }
+
+#    $source = $1;
+#    $dest = $2;
+#    $source =~ s/^\W*//;
+#    $source =~ s/\W*$//;
+#    $dest =~ s/^\W*//;
+#    $dest =~ s/\W*$//;
+#    $link{$source}{$dest} = 2;
+#    push (@nodelist,$source,$dest);
+#    print STDERR "source:$source:dest:$dest:\n";
+  } else {
+#    if ($line =~ m#^edge# or $line =~ m#^node#)
+#    {
+#      print STDERR "Skipping: $line\n";
+#      next;
+#    }
+    if ($line =~ m#^(\S+).*\[.*\]#)
+    {
+      $name = $1;
+      $name =~ tr/"//d;
+      if ($name eq 'node' or $name eq 'edge')
+      {
+        next;
+      }
+      #print STDERR "name:$name:\n";
+    }
+    if ($line =~ m#\[.*label=([^,\]]*).*\]#)
+    {
+      $label = $1;
+      $label =~ tr/"//d;
+      $node{$name}{'label'} = $label;
+      #print STDERR "label:$label:\n";
+    }
+    if ($line =~ m#\[.*fillcolor="?([\d\.]+),([\d\.]+),([\d\.]+).*\]#)
+    {
+      $h = $1;
+      $s = $2;
+      $v = $3;
+      #print STDERR "hsv:$h:$s:$v:\n";
+      $h = $h * 360;
+      ($r,$g,$b) = &hsv2rgb($h,$s,$v);
+      $node{$name}{r} = $r;
+      $node{$name}{g} = $g;
+      $node{$name}{b} = $b;
+      #print STDERR "rgb:$r:$g:$b:\n";
+    }
+  }
+}
+
+undef %saw;
+ at saw{@nodelist} = ();
+ at nodelist = sort keys %saw;  # remove sort if undesired
+undef %saw;
+
+if ($pov or $vrml) {
+  $pov_or_vrml = 1;
+} else {
+  $pov_or_vrml = 0;
+}
+
+for $nodenum (@nodelist)
+{
+  $node{$nodenum}{x}=rand;# $maxx;
+  $node{$nodenum}{y}=rand;# $maxy;
+  $node{$nodenum}{z}=rand if $pov_or_vrml;
+  unless(defined $node{$nodenum}{'label'})
+  {
+    $node{$nodenum}{'label'} = $nodenum;
+  }
+}
+
+print STDERR "springgraph iterating until reaches $done\n\n";
+
+#&draw;
+$continue = 1;
+$iter = 0;
+while($continue > $done)
+{
+  $continue = $done;
+  $iter++;
+  for $nodenum (@nodelist)
+  {
+    $node{$nodenum}{oldx} = $node{$nodenum}{x};
+    $node{$nodenum}{oldy} = $node{$nodenum}{y};
+    $node{$nodenum}{oldz} = $node{$nodenum}{z} if $pov_or_vrml;
+    $xmove = 0;
+    $ymove = 0;
+  }
+  for $source (@nodelist)
+  {
+    $movecount = 0;
+    for $dest (@nodelist)
+    {
+      next if ($source eq $dest);
+      $xdist = $node{$source}{oldx} - $node{$dest}{oldx};
+      $ydist = $node{$source}{oldy} - $node{$dest}{oldy};
+      $dist = $xdist*$xdist + $ydist*$ydist;
+      if ($pov_or_vrml)
+      {
+	$zdist = $node{$source}{oldz} - $node{$dest}{oldz};
+        $dist += $zdist*$zdist;
+      }
+      # $distance = sqrt($dist);
+      $percent = $push / $dist;
+      if ($link{$source}{$dest})
+      {
+         $percent -= $pull;
+      }
+      if ($link{$dest}{$source})
+      {
+         $percent -= $pull;
+      }
+      $percent *= $rate;
+      $xmove -= $xdist * $percent;
+      $ymove -= $ydist * $percent;
+      $zmove -= $zdist * $percent if $pov_or_vrml;
+      $movecount++;
+      # $pullmove = $pull * $dist;
+      # $pushmove = $push / $dist;
+      # print STDERR "dist: $dist, pull: $pullmove, push: $pushmove\n";
+      # print STDERR "$source to ${dest}, Dist: $dist Want: $wantdist (${percent}x)\n";
+      # print STDERR "is: $node[$source]{oldx} $node[$source]{oldy} $xdist $ydist, want: $wantxdist $wantydist ($newdist2)\n";
+
+    }
+    $xmove = $xmove / $movecount;
+    $ymove = $ymove / $movecount;
+    $zmove = $zmove / $movecount if $pov_or_vrml;
+    $node{$source}{x} -= $xmove;
+    $node{$source}{y} -= $ymove;
+    $node{$source}{z} -= $zmove if $pov_or_vrml;
+    if ($xmove > $continue)
+    {
+      $continue = $xmove;
+    }
+    if ($ymove > $continue)
+    {
+      $continue = $ymove;
+    }
+    if (($pov_or_vrml) and $zmove > $continue)
+    {
+      $continue = $zmove;
+    }
+  }
+  #print STDERR "$iter\n";
+  if (0)
+  {
+    &draw;
+    open (XV,"| xv -wait 1 -");
+    #open (XV,"| xloadimage -delay 1 stdin");
+    binmode XV;
+    print XV $im->png;
+    close XV;
+  }
+  if ($iter % 20 == 0)
+  {
+    print STDERR "$continue\n";
+  }
+}
+print STDERR "Iterations: $iter\n";
+for $source (@nodelist)
+{
+  for $color ('r', 'g', 'b')
+  {
+    $node{$source}{$color} = 255 unless (defined $node{$source}{$color});
+  }
+}
+if ($pov)
+{
+  &drawpov;
+} elsif ($vrml) {
+  &drawvrml;
+} else {
+  &draw;
+}
+
+undef $maxx;
+undef $maxy;
+sub draw
+{
+  for $nodenum (@nodelist)
+  {
+    if (!(defined $maxx) or (($node{$nodenum}{x} + (length($node{$nodenum}{'label'}) * 8 + 16)/2) > $maxx + (length($node{$nodenum}{'label'}) * 8 + 16)/2))
+    {
+      $maxx = $node{$nodenum}{x};# + (length($node{$nodenum}{'label'}) * 8 + 16)/2/2
+      $maxxlength = (length($node{$nodenum}{'label'}) * 8 + 16)/2;
+    }
+    if (!(defined $minx) or (($node{$nodenum}{x} - (length($node{$nodenum}{'label'}) * 8 + 16)/2) < $minx - (length($node{$nodenum}{'label'}) * 8 + 16)/2))
+    {
+      $minx = $node{$nodenum}{x};# - (length($node{$nodenum}{'label'}) * 8 + 16)/2/2
+      $minxlength = (length($node{$nodenum}{'label'}) * 8 + 16)/2;
+    }
+
+    $maxy = $node{$nodenum}{y} if (!(defined $maxy) or $node{$nodenum}{y} > $maxy);
+    $miny = $node{$nodenum}{y} if (!(defined $miny) or $node{$nodenum}{y} < $miny);
+  }
+  for $nodenum (@nodelist)
+  {
+    #$node{$nodenum}{x} = ($node{$nodenum}{x} - $minx) * $scale + $margin;
+    $node{$nodenum}{x} = ($node{$nodenum}{x} - $minx) * $scale + $minxlength -1 ;# + $margin;
+    $node{$nodenum}{y} = ($node{$nodenum}{y} - $miny) * $scale + $nodesize/2 - 1;
+  }
+  $maxx = ($maxx - $minx) * $scale + $minxlength + $maxxlength;# + $margin*2;
+  $maxy = ($maxy - $miny) * $scale + $nodesize/2*2;
+  $im = new GD::Image($maxx,$maxy);
+  $bgcol = $im->colorAllocate(@bgcolor);
+  $im->transparent($bgcol) if $trans; # make transparent
+  $blue = $im->colorAllocate(0,0,255);
+  $powderblue = $im->colorAllocate(176,224,230);
+  $black = $im->colorAllocate(0,0,0);
+  $linecol = $im->colorAllocate(@linecolor);
+
+  for $source (@nodelist)
+  {
+    #print STDERR "node: $source $node[$source]{x},$node[$source]{y}\n";
+    for $dest (@nodelist)
+    {
+      if (defined $link{$source}{$dest} and $link{$source}{$dest} == 2 and $source ne $dest)
+      {
+        $dist = sqrt( abs($node{$source}{x}-$node{$dest}{x})**2 +  abs($node{$source}{y}-$node{$dest}{y})**2 );
+        $xdist = $node{$source}{x} - $node{$dest}{x};
+        $ydist = $node{$source}{y} - $node{$dest}{y};
+
+        $angle = &acos($xdist/$dist);
+        #$angle = atan2($ydist,$xdist);
+        #$angle += $pi if $ydist < 0;
+        #$dist = abs(cos($angle))*(length($node{$dest}{'label'}) * 8 + 16)/2 + abs(sin($angle))*$nodesize/2;
+        $width = (length($node{$dest}{'label'}) * 8 + 16)/2;
+        $height = $nodesize/2;
+        $dist = sqrt( ($height**2 * $width**2) / ( ($height**2 * (cos($angle)**2) ) + ($width**2 * (sin($angle)**2) ) ));
+        #$dist = $dist*40;
+        $xmove = cos($angle)*$dist;
+        $ymove = sin($angle)*$dist;
+        #$ymove = -$ymove if $ydist < 0; # the part mj omitted
+        $point[0]{x} = $xmove;
+        $point[0]{y} = $ymove;
+
+        $xmove = cos($angle)*($dist+$arrowlength-3);
+        $ymove = sin($angle)*($dist+$arrowlength-3);
+        #$ymove = -$ymove if $ydist < 0; # the part mj omitted
+        $point[3]{x} = $xmove;
+        $point[3]{y} = $ymove;
+
+        #$angle = $angle + $arrowwidth/2;
+        $dist = 4;
+        $xmove = $xmove + cos($angle)*$dist;
+        $ymove = $ymove + sin($angle)*$dist;
+        #$ymove = -$ymove if $ydist < 0; # the part mj omitted
+
+        $angle = $angle + $twopi/4; 
+        $dist = $arrowwidth/2;
+        $xmove = $xmove + cos($angle)*$dist;
+        $ymove = $ymove + sin($angle)*$dist;
+        #$ymove = -$ymove if $ydist < 0; # the part mj omitted
+        $point[1]{x} = $xmove;
+        $point[1]{y} = $ymove;
+
+        $angle = $angle + $twopi/2;
+        $dist = $arrowwidth;
+        $xmove = $xmove + cos($angle)*$dist;
+        $ymove = $ymove + sin($angle)*$dist;
+        #$ymove = -$ymove if $ydist < 0; # the part mj omitted
+        $point[2]{x} = $xmove;
+        $point[2]{y} = $ymove;
+
+        for $num (0 .. 3)
+        {
+          $point[$num]{y} = - $point[$num]{y} if $ydist < 0;
+        }
+        
+        $im->line($node{$dest}{x}+$point[0]{x},$node{$dest}{y}+$point[0]{y},$node{$dest}{x}+$point[1]{x},$node{$dest}{y}+$point[1]{y},$linecol);
+        $im->line($node{$dest}{x}+$point[1]{x},$node{$dest}{y}+$point[1]{y},$node{$dest}{x}+$point[2]{x},$node{$dest}{y}+$point[2]{y},$linecol);
+        $im->line($node{$dest}{x}+$point[2]{x},$node{$dest}{y}+$point[2]{y},$node{$dest}{x}+$point[0]{x},$node{$dest}{y}+$point[0]{y},$linecol);
+#        $xmove = int($node{$dest}{x}+$point[3]{x});
+#        $ymove = int($node{$dest}{y}+$point[3]{y});
+#        $im->fillToBorder($xmove,$ymove,$linecol,$powderblue);
+        #$im->fillToBorder($node{$dest}{x}+$point[3]{x},$node{$dest}{y}+$point[3]{y},$linecol,$linecol);
+        #$im->line($point[1]{x},$point[1]{y},$point[2]{x},$point[2]{y},$linecol);
+        #$im->line($point[2]{x},$point[2]{y},$point[0]{x},$point[0]{y},$linecol);
+        #$im->fillToBorder($point[3]{x},$point[3]{y},$linecol,$linecol);
+        #$im->arc($point[3]{x},$point[3]{y},10,10,0,360,$black);
+
+#        $im->arc($point[0]{x},$point[0]{y},20,20,0,360,$black);
+#        $im->arc($point[1]{x},$point[1]{y},20,20,0,360,$black);
+#        $im->arc($point[2]{x},$point[2]{y},20,20,0,360,$black);
+        #$im->arc($node{$dest}{x}+$xmove,$node{$dest}{y}+$ymove,20,20,0,360,$black);
+      }
+    }
+  }
+  for $source (@nodelist)
+  {
+    for $dest (@nodelist)
+    {
+      if ($link{$source}{$dest})
+      {
+        $im->line($node{$source}{x},$node{$source}{y},$node{$dest}{x},$node{$dest}{y},$linecol);
+      }
+    }
+  }
+
+  for $source (@nodelist)
+  {
+    $im->arc($node{$source}{x},$node{$source}{y},(length($node{$source}{'label'}) * 8 + 16),$nodesize,0,360,$black);
+    #$im->arc($node{$source}{x},$node{$source}{y},$nodesize,$nodesize,0,360,$black);
+    if (defined $node{$source}{r} and defined $node{$source}{g} and defined $node{$source}{b})
+    {
+      $color = $im->colorResolve($node{$source}{r},$node{$source}{g},$node{$source}{b});
+    } else
+    {
+      $color = $bgcol;
+    }
+    $im->fillToBorder($node{$source}{x},$node{$source}{y},$black,$color);
+  }
+  for $source (@nodelist)
+  {
+    $im->string(gdLargeFont,$node{$source}{x} - (length($node{$source}{'label'}) * 8 / 2) ,$node{$source}{y}-8,$node{$source}{'label'},$black);
+  }
+
+
+  binmode STDOUT;
+  print $im->png;
+}
+
+sub drawpov
+{
+  print'// Generated by springgraph, by Darxus at ChaosReigns.com: 
+// http://www.ChaosReigns.com/code/springgraph/
+
+#include "colors.inc"
+#include "shapes.inc"
+#include "textures.inc"
+#include "glass.inc"
+#include "stones.inc"
+light_source {<0, 400, -500> color White rotate <0, 360*clock, 0>}
+light_source {<400, 0, -500> color White rotate <0, 360*clock, 0>}
+';
+
+  for $source (@nodelist)
+  {
+    $node{$source}{x} = $node{$source}{x} * $scale;
+    $node{$source}{y} = $node{$source}{y} * $scale;
+    $node{$source}{z} = $node{$source}{z} * $scale;
+    $node{$source}{r} = $node{$source}{r} / 256;
+    $node{$source}{g} = $node{$source}{g} / 256;
+    $node{$source}{b} = $node{$source}{b} / 256;
+  }
+  for $source (@nodelist)
+  {
+    print "sphere { <$node{$source}{x},$node{$source}{y},$node{$source}{z}>, 15 pigment {color rgb<$node{$source}{r},$node{$source}{g},$node{$source}{b}>}}\n";
+    print "text { ttf \"crystal.ttf\", \"$node{$source}{'label'}\", 0.5, 0 translate 2*x rotate <0, 360*clock, 0> translate -0.375*y scale 10 translate <$node{$source}{x},$node{$source}{y},$node{$source}{z}> pigment {color rgb<$node{$source}{r},$node{$source}{g},$node{$source}{b}>}}\n";
+    #print "text { ttf \"crystal.ttf\", \"$node{$source}{'label'}\", 0.5, 0 translate -".scalar(length($node{$source}{'label'})*0.25)."*x scale 10 translate <$node{$source}{x},$node{$source}{y},$node{$source}{z}> pigment {color rgb<$node{$source}{r},$node{$source}{g},$node{$source}{b}>}}\n";
+    for $dest (@nodelist)
+    {
+      if ($link{$source}{$dest})
+      {
+        print "cylinder {<$node{$source}{x},$node{$source}{y},$node{$source}{z}>,<$node{$dest}{x},$node{$dest}{y},$node{$dest}{z}> 0.5 pigment {color rgb<0.5,0.5,0.5>}}\n";
+      }
+    }
+  }
+  print 'camera {
+   location  <0, 0, -500>
+   up        <0.0,  1.0,  0>
+   right     <4/3,  0.0,  0>
+   look_at   <0,    0,   -1>
+   rotate <0, 360*clock, 0>
+}
+';
+
+}
+
+
+sub drawvrml
+{
+  my ($t,$r,$length,$color);
+  print'#VRML V2.0 utf8
+
+WorldInfo {
+  info ["Generated by springgraph, by Darxus at ChaosReigns.com: http://www.ChaosReigns.com/code/springgraph/"]
+}
+
+';
+
+  for $source (@nodelist)
+  {
+    $node{$source}{x} = $node{$source}{x} * $scale;
+    $node{$source}{y} = $node{$source}{y} * $scale;
+    $node{$source}{z} = $node{$source}{z} * $scale;
+    for $color ('r', 'g', 'b')
+    {
+      if (defined $node{$source}{$color})
+      {
+        $node{$source}{$color} = $node{$source}{$color} / 256;
+      }
+    }
+  }
+  for $source (@nodelist)
+  {
+print "
+Transform {
+  translation $node{$source}{x} $node{$source}{y} $node{$source}{z}
+  children [
+    Shape{
+        appearance Appearance {
+           material Material {
+              diffuseColor $node{$source}{r} $node{$source}{g} $node{$source}{b}
+           }
+        }
+        geometry Sphere{radius 15}
+    }
+  ]
+}
+";
+
+    #print "sphere { <$node{$source}{x},$node{$source}{y},$node{$source}{z}>, 15 pigment {color rgb<$node{$source}{r},$node{$source}{g},$node{$source}{b}>}}\n";
+    #print "text { ttf \"crystal.ttf\", \"$node{$source}{'label'}\", 0.5, 0 translate 2*x rotate <0, 360*clock, 0> translate -0.375*y scale 10 translate <$node{$source}{x},$node{$source}{y},$node{$source}{z}> pigment {color rgb<$node{$source}{r},$node{$source}{g},$node{$source}{b}>}}\n";
+    #print "text { ttf \"crystal.ttf\", \"$node{$source}{'label'}\", 0.5, 0 translate -".scalar(length($node{$source}{'label'})*0.25)."*x scale 10 translate <$node{$source}{x},$node{$source}{y},$node{$source}{z}> pigment {color rgb<$node{$source}{r},$node{$source}{g},$node{$source}{b}>}}\n";
+    for $dest (@nodelist)
+    {
+      if ($link{$source}{$dest})
+      {
+        ($t,$r,$length) = &cylinder($node{$source}{x},$node{$source}{y},$node{$source}{z},$node{$dest}{x},$node{$dest}{y},$node{$dest}{z});
+        print "
+Transform {
+  translation $t
+  rotation $r
+  children [
+    Shape{
+        appearance Appearance {
+           material Material {
+              diffuseColor 0.5 0.5 0.5
+           }
+        }
+        geometry Cylinder {
+          radius 0.5
+          height $length
+          top FALSE
+          bottom FALSE
+        }
+    }
+  ]
+}
+";
+
+
+        
+      }
+    }
+  }
+#  print 'camera {
+#   location  <0, 0, -500>
+#   up        <0.0,  1.0,  0>
+#   right     <4/3,  0.0,  0>
+#   look_at   <0,    0,   -1>
+#   rotate <0, 360*clock, 0>
+#}
+#';
+
+}
+
+
+
+
+sub hsv2rgb
+{
+#from http://faqchest.dynhost.com/prgm/perlu-l/perl-01/perl-0101/perl-010100/perl01010410_17820.html
+
+# Given an h/s/v array, return an r/g/b array.
+# The r/g/b values will each be between 0 and 255.
+# The h value will be between 0 and 360, and
+# the s and v values will be between 0 and 1.
+#
+
+                      my $h = shift;
+                      my $s = shift;
+                      my $v = shift;
+
+                      # limit this to h values between 0 and 360 and s/v values
+                      # between 0 and 1
+
+                      unless (defined($h) && defined($s) && defined($v) &&
+                             $h >= 0 && $s >= 0 && $v >= 0 &&
+                             $h <= 360 && $s <= 1 && $v <= 1) {
+                        return (undef, undef, undef);
+                      }
+
+                      my $r;
+                      my $g;
+                      my $b;
+
+                      # 0.003 is less than 1/255; use this to make the floating point
+                      # approximation of zero, since the resulting rgb values will
+                      # normally be used as integers between 0 and 255.  Feel free to
+                      # change this approximation of zero to something else, if this
+                      # suits you.
+                      if ($s < 0.003) {
+                        $r = $g = $b = $v;
+                      }
+                      else {
+
+                        $h /= 60;
+                        my $sector = int($h);
+                        my $fraction = $h - $sector;
+
+                        my $p = $v * (1 - $s);
+                        my $q = $v * (1 - ($s * $fraction));
+                        my $t = $v * (1 - ($s * (1 - $fraction)));
+
+                        if ($sector == 0) {
+                          $r = $v;
+                          $g = $t;
+                          $b = $p;
+                        }
+                        elsif ($sector == 1) {
+                          $r = $q;
+                          $g = $v;
+                          $b = $p;
+                        }
+                        elsif ($sector == 2) {
+                          $r = $p;
+                          $g = $v;
+                          $b = $t;
+                        }
+                        elsif ($sector == 3) {
+                          $r = $p;
+                          $g = $q;
+                          $b = $v;
+                        }
+                        elsif ($sector == 4) {
+                          $r = $t;
+                          $g = $p;
+                          $b = $v;
+                        }
+                        else {
+                          $r = $v;
+                          $g = $p;
+                          $b = $q;
+                        }
+                      }
+
+                      # Convert the r/g/b values to all be between 0 and 255; use the
+                      # ol' 0.003 approximation again, with the same comment as above.
+
+                      $r = ($r < 0.003 ? 0.0 : $r * 255);
+                      $g = ($g < 0.003 ? 0.0 : $g * 255);
+                      $b = ($b < 0.003 ? 0.0 : $b * 255);
+
+                      return ($r, $g, $b);
+                    }
+
+# from perlfunc(1)
+sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
+
+
+sub cylinder {
+    my ($x1,$y1,$z1,$x2,$y2,$z2) = @_;
+    my ($t, $r, $length, $rx, $ry, $rz, $dist);
+
+    $x1 = 0 unless $x1;
+    $x2 = 0 unless $x2;
+    $y1 = 0 unless $y1;
+    $y2 = 0 unless $y2;
+    $z1 = 0 unless $z1;
+    $z2 = 0 unless $z2;
+    my $dx=$x1-$x2;
+    my $dy=$y1-$y2;
+    my $dz=$z1-$z2;
+    if (1) {
+        unless (0) {
+            $length = sqrt($dx*$dx + $dy*$dy + $dz*$dz);
+            $rx = $dx;
+            $ry = ($dy+$length);
+            $rz = $dz;
+            $dist = sqrt(abs($rx)**2 + abs($ry)**2);
+            $dist = sqrt(abs($rz)**2 + abs($dist)**2);
+            $rx = $rx / $dist;
+            $ry = $ry / $dist;
+            $rz = $rz / $dist;
+            $t = ($x1-($dx/2))." ".($y1-($dy/2))." ".($z1-($dz/2));
+            $r = "$rx $ry $rz $pi";
+        }
+    }
+    return ($t,$r,$length);
+}
+
+sub usage {
+print <<END
+springgraph - Render a .dot file into a graphic
+
+Usage: springgraph [-p] [-v] [-s scale] [-t] [-b color] [-l color] [-h]
+
+   -p   Create a file that can be rendered with POV-Ray
+   -v   Create a VRML file
+   -s   This option specifies the scale. All of the node locations
+        are multiplied by this. Increase the scale to eliminate node
+        overlaps. Decrease the scale to make the graph smaller. 
+   -t   Make the background of the resulting image transpaent.
+   -b   set background color of image, specify it in the form RRGGBB,
+        in hex digits, e.g. FFFFFF is white, 000000 is black, FF0000
+        is red, ...
+   -l   set the line color, same format as the background color
+   -h   show this help
+
+END
+}


Property changes on: trunk/springgraph/springgraph
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/springgraph/springgraph.1
===================================================================
--- trunk/springgraph/springgraph.1	                        (rev 0)
+++ trunk/springgraph/springgraph.1	2008-03-12 21:44:00 UTC (rev 366)
@@ -0,0 +1,84 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.\" First parameter, NAME, should be all caps
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
+.\" other parameters are allowed: see man(7), man(1)
+.TH SPRINGGRAPH 1 "September 5, 2005"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+springgraph \- renders a graph from a .dot file
+.SH SYNOPSIS
+.B springgraph [OPTIONS] < input-file > output-file.png
+.br
+.SH DESCRIPTION
+This manual page documents briefly the
+.B springgraph
+command.
+This manual page was written for the Debian distribution
+because the original program does not have a manual page.
+.PP
+Springgraph will read in a .dot file description of a graph, which,
+for each node, specifies its name and which other nodes it is
+connected to, and then renders a graph. The output is a PNG
+file. Each node is drawn as an
+ellipse, and each connection is drawn as an arrow. The node placement
+is a result of all of the nodes moving away from each other, while all
+nodes which are connected move toward each other. This movement is
+repeated until it stabilizes.
+
+Springgraph was written as an alternative to neato, which is part of
+graphviz. It attempts to read the same .dot files used by graphviz,
+but currently only supports a limited number of node attributes (label
+and fillcolor) and can only handle two nodes per edge definition ("node1 ->
+node2", not "node1 -> node2 -> node3").
+.SH OPTIONS
+\fIspringgraph\fP
+accepts the following options:
+.TP 16
+.B \-p
+Create a file that can be rendered with POV-Ray
+.TP 16
+.B \-v
+create a VRML file
+.TP 16
+.B \-s
+this option specifies the scale. All of the node locations
+are multiplied by this. Increase the scale to eliminate node
+overlaps. Decrease the scale to make the graph smaller. 
+.TP 16
+.B \-t
+make the background of the resulting image transparent.
+.TP 16
+.B \-b
+set background color of image, specify it in the form RRGGBB,
+in hex digits, e.g. FFFFFF is white, 000000 is black, FF0000
+is red, ...
+.TP 16
+.B \-l
+set the line color, same format as the background color
+.TP 16
+.B \-h
+display usage synopsis
+.SH EXAMPLE
+ digraph {
+  "rene" -> "myon";
+  "mvo" -> "rene";
+ }
+.SH SEE ALSO
+neato(1)
+sig2dot(1)
+http://www.graphviz.org/Documentation.php
+http://www.graphviz.org/cvs/doc/info/lang.html
+.SH AUTHOR
+This manual page was written by Kevin M. Rosenberg <kmr at debian.org>,
+for the Debian GNU/Linux system (but may be used by others).




More information about the Pgp-tools-commit mailing list