#!/usr/local/bin/perl sub man { print << ; # -------Description-------------------------------------- # # generate literature references list in HTML-format # from BibTeX-format. allows you to keep an organized # virtual bookshelf with only few additions to your # BibTeX-references. # # + uses title, author and year field to display # information from reference # + uses nice icons :-) # + uses comma separated entries in field 'topics' # to categorize references # + uses URL in field 'sourceURL' to hyperlink the # title to the source # + uses URL in field 'url' to hyperlink the book icon # to a local copy (same field is used by bibsearch.pl # and contains a full URL; bookshelf changes this to # a relative URL, if it starts with users html-home) # + the resulting page provides a link to the BibTeX-file # + each entry may be linked to its BibTeX-reference # + the script also # + converts german special characters # + converts occurrences of \$\\Pi\$ in titles # + removes {}, \\em, \\bf and enclosing "" # + topics may be grouped into hierarchies based on # comments in the BibTex-source: # % TOPICS # % group1 : topic1, topic2, topic3 # % group2 : group1, topic4 # % ENDTOPICS # # - no real parser for BibTeX # + multi-line fields allowed for author and title # - important fields should be terminated by ',' # (year or topics as last field in entry will do ;-) # - entries have to be delimited by empty lines # +- text following empty line and not starting with # @...{ is ignored (if e.g. an abstract field # contains empty lines, insert spaces there) # } require 'getopts.pl'; sub usage { print << ; # # bookshelf [-hmscitlobT] # # -------Options------------------------------------------ # # -h : help (print this usage info) # -m : man (print longer usage info) # -e : edit BibTeX source file # -s : split HTML (generate directory # with one file per topic) # -c : classes (rudimentary support for supercategories) # -i : info (link each entry to its BibTeX-reference) # -t : text (no icons, implies -l) # -l : show only one hyperlink per reference # (url overrules sourceURL) # -o name: output to name.html (name/ with -s) # -b name: input from name # -T text: title (use text instead of Virtual Bookshelf) # # -------Defaults----------------------------------------- # # BibTeX : \$HOME/public_html/bib/bookshelf.bib # HTML : \$HOME/public_html/bib/bookshelf.html # topics directory (for -s): \$HOME/public_html/bib/bookshelf/ # reference-file (for -i): \$HOME/public_html/bib/bibtex.html # } # -d reserved for debugging purposes do Getopts('u:o:b:T:cistlhmkde'); if ($opt_h) { &usage(); exit; } if ($opt_m) { &usage(); &man(); exit; } $user = $opt_u || $ENV{'USER'}; @pwent = getpwnam($user); die "unknown user $user" unless @pwent; $username = $pwent[6]; $username =~ s/,.*$//; # get rid of these (where do they come from??) $userdir = $pwent[7]; ##--- variable settings --------------------- # you will certainly need to customize here.. chop($DATE = `date`); chop($pwd = `pwd`); $localhome = "$userdir/webpages"; $mailbase = "ukc.ac.uk"; $wwwbase = "http://www.cs.ukc.ac.uk/people/staff/"; $webhome = "$wwwbase/$user"; # please don't rely on my icons directory ;-) # use your own, *local* collection $iconsdir1 = "$webhome/icons"; if ($opt_b) { $bibdir = $pwd; $bibtex = $opt_b; } else { $bibdir = "$localhome/bib"; $bibtex = "bookshelf.bib"; } if ($opt_e) { $EDITOR = $ENV{'EDITOR'}; if ($EDITOR =~ /%d.*%s/) { $EDITOR = sprintf($EDITOR,1,"$bibdir/$bibtex") } else { $EDITOR = "$EDITOR $bibdir/$bibtex" } exec($EDITOR); } if ($opt_o) { $shelfdir = $pwd; $bookshelf = "$opt_o.html"; $bookdir = "$opt_o" if $opt_s; } else { $shelfdir = "$localhome/bib"; $bookdir = "bookshelf" if $opt_s; $bookshelf = "bookshelf.html"; } $INFO_FILE = "bibtex.html"; $shelftitle = $opt_T || "$username 's Virtual Bookshelf"; $PI = "\"PI\""; $PLUS = "\"+\""; $LAMBDA = "\"lambda\""; $FAST = "\"FAST\""; $shelfpic = "\"\""; $littleshelf = "\"\""; $book_read = "\"[+]\""; $book_empty = "\"[-]\""; $info = "\"[BibTeX]\""; #$info = "\"[BibTeX]\""; ##--- no need to customize below?? ---------- if ($opt_i) { chdir($shelfdir); open(INFO,"> $INFO_FILE") || die "cannot write $INFO_FILE\n$!"; print INFO < BibTeX
HEADER

  chdir($bibdir);

  open(BIB,"$bibtex") || die $!;

  $/='';
  $*=1;

  while()
  {
    if (/^@[^{]*{\s*([^,]*)\s*,/) { print INFO "% $1 

\n"; } print INFO; } close(BIB); print INFO <

$user\@$mailbase
FOOTER close(INFO); } if ($opt_t) { $opt_l = 1; $shelfpic = ""; $littleshelf = ""; $book_read = ""; $book_empty = ""; } # need to work with relative paths here # chdir($bibdir) || die "cannot chdir to $bibdir\n$!"; open(BIB,$bibtex) || die "cannot read $bibdir/$bibtex\n$!"; $/=''; $*=1; while() { $i++; if (/^@([^{]*){/) { $TYPE[$i] = $1; if (($TYPE[$i] =~ /string/i) || ($TYPE[$i] eq '')) { $i--; next; } } if ($opt_c && /%\s*TOPICS\s*%\s*((.|\n)*)\s*%\s*ENDTOPICS/) { &process_topics($1); } if ($opt_k && /%\s*KEYS\s*%\s*((.|\n)*)\s*%\s*ENDKEYS/) { &process_keys($1); } if (/%\s*DESCRIPTION\s*%\s*((.|\n)*)\s*%\s*ENDDESCRIPTION/) { &process_description($1); } if (/^%[^\n]*\n/) { $i--; next; } if (/^@[^{]*{\s*([^,]*)\s*,/) { $KEY[$i] = $1; print STDERR "$i: $1\n" if $opt_d } s/{\\"a}/ä/g; s/{\\"o}/ö/g; s/{\\"u}/ü/g; s/{\\"A}/Ä/g; s/{\\"O}/Ö/g; s/{\\"U}/Ü/g; s/{\\ss}/ß/g; s/{\\rm//g; s/{\\sc([^}]*)}/$1/g; s/{\\em([^}]*)}/$1<\/em>/g; s/{\\bf([^}]*)}/$1<\/b>/g; s/\\-//g; if (/topics\s*=\s*{([^}]+)}/i) { $TOPICS[$i] = $1; } s/{|}//g; if (/editor\s*=\s*"\s*([^=]*)",\s*\S+\s*=/i) { $EDITOR[$i] = "[$1 (ed)]"; } elsif (/editor\s*=\s*([^=]*),\s*\S+\s*=/i) { $EDITOR[$i] = "[$1 (ed)]"; } if (/author\s*=\s*"\s*([^=]*)",\s*\S+\s*=/i) { $AUTHOR[$i] = $1; } elsif (/author\s*=\s*([^=]*),\s*\S+\s*=/i) { $AUTHOR[$i] = $1; } if (/\btitle\s*=\s*"\s*([^=]*)",\s*\S+\s*=/i) { $TITLE[$i] = $1; } elsif (/\btitle\s*=\s*([^=]*),\s*\S+\s*=/i) { $TITLE[$i] = $1; } if (/url\s*=\s*([^=]*),\s*\S+\s*=/) { $URL[$i] = $1; } if (/sourceURL\s*=\s*,\s*\S+\s*=/) { } elsif (/sourceURL\s*=\s*"\s*([^=]*)",\s*\S+\s*=/) { $SOURCE[$i] = $1; } elsif (/sourceURL\s*=\s*([^=]*),\s*\S+\s*=/) { $SOURCE[$i] = $1; } if (/abstractURL\s*=\s*"\s*([^=]*)",\s*\S+\s*=/) { $ABSTRACT[$i] = $1; } elsif (/abstractURL\s*=\s*([^=]*),\s*\S+\s*=/) { $ABSTRACT[$i] = $1; } if (/year\s*=\D*(\d+)\D/i) { $YEAR[$i] = $1; } $urls++ if ($SOURCE[$i] || $URL[$i]); } close(BIB); foreach $entry (1..$i) { $TITLE[$entry] =~ s/\$\\pi\$/$PI/g; $TITLE[$entry] =~ s/\\pired/$PI-Red/g; $TITLE[$entry] =~ s/\$\^\+\$/$PLUS/g; $TITLE[$entry] =~ s/\$\\lambda\$/$LAMBDA/g; $TITLE[$entry] =~ s/^fast #/$FAST/g; if ($opt_s) { $RELPATH = "../.."; } else { $RELPATH = ".."; } if (defined($URL[$entry])) { unless ($opt_o) { $URL[$entry] =~ s|$wwwbase$user|$RELPATH|; } # $REF = "$book_read"; } else { $REF = "$book_empty"; } if (defined($TOPICS[$entry])) { @topics = split(',',$TOPICS[$entry]); } else { @topics = ("Miscellaneous") } if (defined($SOURCE[$entry])) { $TITLE = "$TITLE[$entry]"; } elsif (defined($ABSTRACT[$entry])) { $TITLE = "$TITLE[$entry]"; } else { $TITLE = "$TITLE[$entry]"; } # if ($opt_l && defined($URL[$entry])) if (defined($URL[$entry])) { $TITLE = "$TITLE[$entry]"; # $REF = $book_empty; $REF = $book_read; } if ($opt_i) { # $INFO = "$info"; $REF = "$REF"; } # else # { $INFO = ""; } foreach $topic (@topics) { if (defined($sub{$topic})) { print <$REF$TITLE
$AUTHOR[$entry]$EDITOR[$entry] ($TYPE[$entry], $YEAR[$entry])\n

ENTRY } } # need to work with relative paths here # chdir($shelfdir) || die "cannot chdir to $shelfdir\n$!"; if ($opt_s) { (mkdir($bookdir,0755) || die "cannot create $shelfdir/$bookdir\n$!") unless -e $bookdir; } open(SHELF,"> $bookshelf") || die "cannot create $shelfdir/$bookshelf\n$!"; print SHELF < $shelftitle $shelfpic

$shelftitle

$i entries, $urls available online ($DATE)

$DESCRIPTION HEADER print SHELF "

\n"; if ($opt_s) { foreach $topic (keys%TOPIC) { $tmp = $topic; # remove dangerous characters from filename $tmp =~ s|[^\w-]|_|g; $FILE{$topic} = "$bookdir/$tmp.html"; $HREF{$topic} = $FILE{$topic}; } } else { foreach $topic (keys%TOPIC) { $HREF{$topic} = "#$topic"; } } foreach $topic (sort (keys%TOPIC,@classes)) { if (defined($super{$topic})) { next; } elsif (defined($sub{$topic})) { &print_subtopics($topic); } else { print SHELF "
$topic\n"; } } print SHELF "
\n"; if ($opt_s) { foreach $topic (sort keys%TOPIC) { open(TMP,"> $FILE{$topic}") || die "cannot create $FILE{$topic}\n$!"; print TMP < Virtual Bookshelf: $topic

$topic

$topic_keys{$topic}
$TOPIC{$topic}

$user\@$mailbase
HERE close(TMP); } } else { foreach $topic (sort keys%TOPIC) { print SHELF <

$littleshelf $topic

\n
$TOPIC{$topic}\n
HERE } } print SHELF <
generated by bookshelf, $DATE
$user\@$mailbase
FOOTER close(SHELF); sub process_description { $DESCRIPTION = "\n$_[0]\n\n
\n"; $DESCRIPTION =~ s/\$MAIL/$user\@$mailbase/g; $DESCRIPTION =~ s/%//g; } sub process_keys { local ( @TOPIC_LIST ) = split('%',$_[0]); foreach (@TOPIC_LIST) { if (/\s*(\S.*\S)\s*:\s*(.*)$/) { $topic = $1; if (defined($keys{$topic})) { $topic_keys{$topic} .= $2; } else { push(@key_topics,$topic); $topic_keys{$topic} = "Keywords: $2"; } foreach $key (split(/,\s*/,$2)) { $topic{$key} = $topic; } } } } sub process_topics { local ( @TOPIC_LIST ) = split('%',$_[0]); foreach (@TOPIC_LIST) { if (/\s*(\S.*\S)\s*:\s*(.*)$/) { $class = $1; if (defined($sub{$class})) { $sub{$class} .= $2; } else { push(@classes,$class); $sub{$class} = $2; } foreach $topic (split(/,\s*/,$2)) { $super{$topic} = $class; } } } } sub print_subtopics { local ($topic) = shift; print SHELF "
$topic
\n"; foreach $subtopic (sort split(/,\s*/,$sub{$topic})) { if (defined($sub{$subtopic})) { &print_subtopics($subtopic); } elsif (defined($HREF{$subtopic})) { print SHELF "
$subtopic\n"; } else { print SHELF "
$subtopic\n"; } } print SHELF "
\n"; }