aks@hub.ucsb.edu (Alan Stebbens) (08/08/90)
| Hi. I wrote a rolo(dex) mode for emacs about a year or so ago. I got | a few patches and comments just after its release, and having been | off the net for most of that time, I was just wondering if there | is anyone still using rolo, and if anyone has developed it much. | Just keeping up .... please use mail if you reply ... I use it quite a bit, both within Emacs and without. Of course, within Emacs, I use the "rolo.el" and companion elisp code. Many of my staff, though, do not use Emacs, not matter how much I harass them; so, I wrote a Perl script for them to make the ideas and "database" represented by "rolo" available. I know, I know: this is much like reinventing the wheel in the Unix domain, since there are many nice rolodex tools which use curses, X11, OpenLook and what-have-you. However, there were no tools which used a common rolodex database for both Emacs and non-Emacs usage. Now there is; the following code is given to the world, under the GNU CopyLeft. I know this is the "GNU Emacs" list, but, as Perl is also distributed by GNU, and since this code dovetails with the "rolo.el" code, I figured there might be someone else interested in it. This code looks for a configurable directory pathname, from either the envar ROLOPATH or, by default, /usr/local/lib/rolodex. Any files within this directory are assumed to be a rolodex-format file. Each file may have its own, possibly unique header, and configuration variables. You can also have a private rolodex, ~/.rolodex{,.otl}. Since each rolodex can have a header, which may or may not be identical to the one from the previous rolodex file, I made the display code recognize consecutively identical headers, and not redisplay the succeeding ones unless they were really unique. The alternate configuration strings, at the beginning of each rolodex file has never been tested. It seemed like a good idea to generalize the design a little, but real work kept creeping back at me so I never got to testing the parts that _I_ don't use much. Let me know how it goes with you, if you do try it. I've thought about adding a network client/server mode of operation, so the rolodex database can be centralized; but I figured it would be better to get some feedback, if any. A prettier output format might be nice, possibly using a "format" definition from the rolodex file itself. Also, perhaps it might be nice to do highlighting or underlining via curses to enhance the display. I'm sorry for not writing a "man" page (but not that sorry); someone else can do so if they really want to. The Perl code has many, many comments which can form the basis for a man page. The Perl code is immediately below, followed by a sample rolofile, with a sample, bogus vendor, showing the heirarchy stuff, and then some real vendors, with the personal contacts removed. Enjoy.. Alan Stebbens Computer Resource Manager <aks@hub.ucsb.edu> Center for Computational Sciences and Engineering (CCSE) W:(805) 893-8135 University of California, Santa Barbara F:(805) 893-8553 3111 Engineering I Santa Barbara, CA 93106 ============================= cut here =================================== #!/bin/perl # Copyright 1990, Alan K. Stebbens # This code is distributed under the GNU General Copyright License. # The idea for the rolodex database was borrowed from Paul Davis' elisp # code called "rolo.el". In fact, this code should work with the _same_ # database file(s). # # rolo [opts] string ... # # Search the rolodex for "string" # # opts: # -l list the filenames # -h omit the file headers # -e list the entries [default] # -t don't print the level hierarchy (terse) # -w match by word # -c count and print just the number of matches # # The rolodex consists of the files # # ~/.rolodex{.otl,} # /usr/local/lib/rolodex/* # # also if ROLOPATH is defined, it is used instead of /usr/local/lib/rolodex. # # The syntax of a rolodex file (hereafter called a "rolofile") is heirarchical # and pretty simple. # # As configured by default, each rolofile can contain an initial "header" which # will be printed above any output produced from that file, the end of the header # is recognized with a regular expression, called "RoloHeader". # A new rolodex entry is recognized with a regular expression called "RoloEntry". # Since the rolodex entries are heirarchical, and since the RoloEntry is configurable, # there needs to be a way to determine the depth of each entry, relative to the # others. The standard "RoloEntry" is to recognize leading asterisks; the standard # level, then, is the length of the asterisk string. If you change the RoloEntry, # you must also change RoloDepth to be a Perl expression which returns the depth # of the current RoloEntry. # A possible alternative for both might be: # # RoloEntry: "^(\d+)." # RoloLevel: "(0+$1)" # # Note that RoloLevel is eval'ed immediately after RoloEntry succeeds, allowing # pattern match substrings ($1, $2, etc.) to be used in RoloLevel. # Comment lines may be embedded anywhere within the rolodex file, even in the header # by beginning them with the string recognized by the regular expression contained # in the variable "RoloComment". # These strings have standard default values, but may be overridden, in each # file, by the first lines containing the following text (the values shown below # are the defaults). The strings *must* be quoted; embedded quotes must be escaped # with a backslash. # # RoloHeader: "^===" # RoloEntry: "^\*+" # RoloComment: "^#" $RoloPath = '/usr/local/lib/rolodex' unless $RoloPath = $ENV{'ROLOPATH'}; @RoloFiles = (grep(!/^#|[#~]$/,<~/.rolodex*>)); push(@RoloFiles,grep(!/^#|[#~]$/,eval("<$RoloPath/*>"))); $RoloHeader = "^==="; $RoloEntry = "^\\*+"; $RoloLevel = "(/^(\\*+)/ && length(\$1))"; $RoloComment = '^#'; # Scan the arguments $Headers = 1; # on by default $FileNames = 0; # off by default $Entries = 1; # on by default $LevelTree = 1; # on by default $CountMatches = 0; # off by default $WordMatch = 0; # match keywords as words @Search = (); # search patterns if ($#ARGV < $[) { print STDERR "usage: rolo [options] keyword ... Options are: -c count and print just the number of matches -e list the entries [default] -l list the filenames -h omit the file headers -p match with the following REGEXP pattern -t don't print the level hierarchy (terse) -w match by word "; exit 1; } while ($_ = shift) { if (/^-/) { $Headers = 0 if /^-.*h/; ($Entries = 0,$FileNames = 1) if /^-.*l/; ($Entries = 0,$CountMatches = 1) if /^-.*c/; $Entries = 1 if /^-.*e/; ($Headers = 0,$LevelTree = 0) if /^-.*t/; push(@Search,shift) if /^-.*p/; $WordMatch = 1 if /^-.*w/; next; } s/([^\w])/\\$1/g; # escape funny chars $_ = '\b'.$_.'\b' if $WordMatch; # do word matching maybe push(@Search,$_); } $Matches = 0; $MatchLevel = 0; $Header = ''; $OutHeader = ''; $OutFile = ''; # Scan the files now foreach $File (@RoloFiles) { open(FILE,$File) || do { warn "Can't open rolodex file $File because $!\n"; next; }; while (<FILE>) { next if /$RoloComment/; # until it's changed last unless /^(Rolo\w+):\s*(\S.*\S)\s*$/; # configuration? eval("\$$1 = ".$2.";"); warn "$@\n" if $@; } @RoloData = (); $#RoloData = 10; $Header = /$RoloComment/ ? '' : $_; $MatchLevel = 0; while (<FILE>) { next if /$RoloComment/; $Header .= $_; last if /$RoloHeader/; } if ($OutHeader) { $OutHeader =~ s/\s+/ /g; ($NewHeader = $Header) =~ s/\s+/ /g; $Header = '' if (length($NewHeader) == length($OutHeader) && $NewHeader eq $OutHeader); } # Now scan the file looking for rolodex entries $level = 0; line:while (<FILE>) { next if /$RoloComment/; if (/$RoloEntry/) { # new entry? $lastlevel = $level; $level = eval($RoloLevel); if ($MatchLevel && $MatchLevel < $level) { $RoloData[$MatchLevel] .= $_; } else { &ShowLevel($MatchLevel) if $MatchLevel >= $level; $RoloData[$level] = $_; } } else { $RoloData[$level] .= $_; } next if $MatchLevel; foreach $pat (@Search) { if (/$pat/i) { if ($Entries == 0 && $FileNames) { print $File."\n"; last line; } $MatchLevel = $level; } } } &ShowLevel($MatchLevel) if $MatchLevel; close FILE; } printf "%d matches\n", $Matches if $CountMatches; exit; sub ShowLevel { local($level) = $_[0]; if ($FileNames && $OutFile ne $File) { print ">>>File: $File <<<\n"; $OutFile = $File; } if ($Headers && $Header && $Entries) { print $Header; $OutHeader = $Header; $Header = ''; # we only do this once per file } for ($i = $LevelTree ? 1 : $level; $i <= $level; $i++) { print $RoloData[$i] if $Entries; $RoloData[$i] = ''; } $MatchLevel = ''; $Matches++; } ============================= cut here =================================== ============================================================================ GROUP ROLODEX <Last Name>, <First Name> W:<Work #> H:<Home #> P:<Pager #> F:<Fax #> M:<Modem #> C:<Cellular #> E:<email #> X:<ext #> R:<Other-radio #> <Address> <Miscellaneous Info, Key Words> ============================================================================ * Vendors ** ABC, Inc (Bogus Sample Vendor) W:800-555-1212 1234 Somestreet Way, Suite 13 Somecity, ST 99999 Product: Dingus with Bells & Whistles *** Sales Department **** Loser, Ima W:800-555-1213 Salesman **** Isuzi, Joe W:800-555-1214 Salesman *** Technical Support W:800-555-2100 F:800-555-2101 **** Idunno, Gee W:800-555-1215 System Engineer **** Whatzat, Hank W:800-555-1216 Product Engineer ** CACI, Inc. W:619-457-9681 3344 N. Torrey Pines Court, La Jolla, CA 92037 Simscript (Simulation Software) ** Cabletron Ethernet, Networking ** Cisco W:800-553-NETS(6387), -2447 Gateways, Routers, Terminal Servers ** Clearpoint W:818-706-1745 F:818-706-0503 5655 Linder Canyon Rd., Bldg 700, Westlake Village, CA 91362 Memory enhancements ** Dataram W:800-822-0071 Memory upgrades for Suns, SPARCs ** Fox Software W:419-874-0162 FoxBase: Relational database available on Unix, Mac's, & PC's. ** International Automations Assoc. (IAA) W:213-326-6008 F:213-326-6047 3246 Sepulveda Blvd, #209, Torrance, CA 90505 Reseller for 3Com Ethernet adapters ** Illinois Computer Cable Inc. W:800-326-2320 ** Mac Warehouse W:800-255-6227 ** MacConnection W:800-622-5472 ** MacZone W:800-248-0800 ** NeXT, Inc. W:415-366-0900 ** Novell/Kinetics 2180 Fortune Dr., San Jose, CA 95131 Networking for PC's and Mac's ** Oracle W:916-641-5566 Incredibly expensive, but highly functional databases ** Parity W:408-378-1000 Memory upgrades for Sun ** Proteon W:508-898-3100 2 Technology Drive, Westborough, MA 01581 Routers ** R-Squared (R^2) W:714-837-0960 Disk drives & Enclosures (SCSI, SMD) ** SCO Santa Cruz Operations, Inc. W: 408-425-7222 SCO Unix/386, FoxBase+ for Unix ** Technology Works, Inc. W:800-622-2210 4030 Braker Lane West, Suite 350, Austin, TX 78759 Memory (SIMMs)