#!/usr/local/bin/perl
#
#
# Find out the path to the top level. Currnently top level is detected
# by looking hardcoded 'life' directory. Some other method should
# be used...
#
%month_name =
('Jan','January',
'Feb','Februrary',
'Mar','March',
'Apr','April',
'May','May',
'Jun','June',
'Jul','July',
'Aug','August',
'Sep','September',
'Oct','October',
'Nov','November',
'Dec','December');
require GDBM_File;
$GOTO = '/cgi-bin/life/goto';
$WARP = "warp";
$PRAW = "..";
$ICONS = "icons";
$MAPSDIR = "maps/map"; # dir for generated maps (path from root)
$CELL2_COLOR = "bgcolor=\"#aaeeaa\"";
$CELL_COLOR = "bgcolor=\"#98fcc8\"";
$BACKGROUND = "bgcolor=\"#66cc99\"";
# List of characters that differ from LATIN1 in LATIN2
# and their Unicode equivalents
%LATIN2 =
(0xA1,260,
0xB1,261,
0xC6,262,
0xE6,267,
0xCA,280,
0xEA,281,
0xA3,321,
0xB3,322,
0xD1,323,
0xF1,324,
0xA6,346,
0xB6,347,
0xAC,377,
0xBC,378,
0xAF,379,
0xBF,380);
#
# "Kingdom" codes for LOCATION
#
$PLANT = 'P';
$FUNGI = 'F';
$ANIMAL = 'A';
$KINGDOM = $ANIMAL;
$DO_SUBDIRS = 1;
$REDO_THUMBNAILS = 0; # Unconditionally redo thumbnail, if non-zero
$field = "lepidoptera";
$TOPDIR = '';
while (@ARGV)
{
if ($ARGV[0] eq "-onlythis")
{
$DO_SUBDIRS = 0;
}
elsif ($ARGV[0] eq "-all")
{
$redo_all = 1;
}
elsif ($ARGV[0] eq "-list")
{
shift(@ARGV);
$field = $ARGV[0];
}
elsif ($ARGV[0] eq '-kingdom')
{
shift(@ARGV);
$KINGDOM = $ARGV[0];
}
elsif ($ARGV[0] eq '-thumbnails')
{
$REDO_THUMBNAILS = 1;
}
elsif ($ARGV[0] eq '-topdir')
{
shift(@ARGV);
$TOPDIR = $ARGV[0];
}
else
{
warn "Unkown command parameter: '" . $ARGV[0] . "'\n";
warn "\t-onlythis Do only current level\n";
warn "\t-all Unconditionally redo all (html)\n";
warn "\t-list name List name that applies (default 'lepidoptera')\n";
warn "\t-kingdom [A|P|F] Animal/Plants/Fungi\n";
warn "\t-thumbnails Force regeneration of thumbnails\n";
warn "\t-topdir Alternate root and path to search";
exit;
}
shift(@ARGV);
}
if ($TOPDIR)
{
@branch = split(/\//, $TOPDIR);
$ROOT = @branch[0];
shift(@branch);
$TOPDIR = join("/", @branch);
$TOPDIR .= "/";
}
else
{
$ROOT = 'life';
}
@path = split(/\//, $ENV{'PWD'});
while (@path)
{
last if @path[0] eq $ROOT;
shift(@path);
}
$references = ".adm/references.lst";
$literature = "literature.lst";
$outlinks = "outlinks.lst";
$mappings = "mapping.lst";
$checklist = "${field}-list.html";
$fi_common = "${field}-Finnish-list.html";
$fi_index = "${field}-Finnish-index.html";
$en_common = "${field}-English-list.html";
$en_index = "${field}-English-index.html";
$start_dir = pop @path;
require "../" x scalar(@path) . "${TOPDIR}common.pl";
do load_mappings("$mappings");
%experts = ();
$author_fixed = 0;
$covered_area = "";
#
# If not starting within root, try to find the context from the previous level
#
# (this will not get author_fixed value correct, beware)
# $KINGDOM and lists will be incorrect too..
#
if (@path && open(INPUT, '../index.lst'))
{
local($name, $author, $rest, $foreign, $extra, $tmp);
$list = do load_list(INPUT);
$prev = "";
while ($_ = shift @$list)
{
next if ($_->{'type'} ne ':node');
($name, $author, $rest) = split(/[\t]+/,$_->{'name'},3);
$foreign = !$_->{'fi'};
$extra = $_->{'content'};
($author, $article, $location) = split(/;/,$author,3);
$rest = "$name\t$author;$article;$location\t$rest"
if ($article || $location);
$author = "" if ($author eq "-");
$author = " $author" if ($author);
$name =~ s/^-([^\s]*)\s+//;
$next = do next_item($list, ':node');
$next =~ s/^-([^\s]*)\s+//; # ..strip off higher taxon ref..
last if ($name eq $start_dir);
$prev = $name;
}
close(INPUT);
$name =~ s/^-([^\s]*)\s+//;
$foreign = 1 if (!$name);
do do_subdir($start_dir,$author,$rest,$next,$prev);
}
else
{
do do_subdir($start_dir);
# Should clanup unused maps, if redo-all from root!
if ($redo_all)
{
warn "Unused maps, remove?\n";
foreach $key (keys %MAPS)
{
warn "rm ${key}.gif\n" if ($MAPS{$key} == 0);
}
}
}
sub start_html
{
local($title, $heading) = @_;
print "
$title\n";
print "\n\t\n\n";
do frame_zap();
print "\n";
print "
$heading
\n" if ($heading);
}
sub end_html
{
if ($path[1] ne 'pisces')
{
print "
If you have corrections, comments or\n";
print " information to add into these pages, just send mail to\n";
do signature();
print ".\nKeep in mind that the taxononic information is copied from various sources, ";
print " and may include many inaccuracies. Expert help is welcome..\n";
print "
\n\n";
}
}
sub get_modified
{
local (@stat) = stat(INPUT);
local ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($stat[9]);
$year += 1900;
$mon += 1;
return "$mday.$mon.$year";
}
sub do_subdir
{
local(*INPUT);
local(*OUTPUT);
local($topdir, $key, $sp_count);
local($group, $author, $rest, $next, $prev) = @_;
local($old) = select;
local($redo_all) = $redo_all;
local($redo_level) = $redo_all;
local(%experts) = %experts;
local($curdir) = $curdir;
local(%lits, %refs, %determinavit, $root);
@FILES = grep(!/^\Q$group\E$/,@FILES);
local(@FILES);
opendir(DIR, '.');
@FILES = sort grep(!/^\..*$|^_[^.]*\.jpg$|^index\.html$/,readdir(DIR));
closedir DIR;
$topdir = "";
foreach $elem(@path)
{
$topdir .= "../";
}
$toproot = $topdir;
$topdir .= $TOPDIR;
# ..unfortunately "life" root is part of path -- need to fix this, for now need [1 .. construct! :-(
local($URL_BASE, $URL_FRACTION) = join('/', @path[1 .. $#path]) . "/${group}/index.html";
if (!$tibiale_25)
{
$tibiale_25 = do img_attributes
("${topdir}${ICONS}/tibiale-25.gif", "(Introduction)");
$fiflag = do img_attributes("${topdir}${ICONS}/fi.gif","Finnish: ");
$fichck = do img_attributes("${topdir}${ICONS}/fi-check.gif","fi");
$gbflag = do img_attributes("${topdir}${ICONS}/gb.gif","English: ");
$usflag = do img_attributes("${topdir}${ICONS}/us.gif","USA: ");
$seflag = do img_attributes("${topdir}${ICONS}/se.gif","Swedish: ");
$deflag = do img_attributes("${topdir}${ICONS}/de.gif","German: ");
$frflag = do img_attributes("${topdir}${ICONS}/fr.gif","French: ");
$esflag = do img_attributes("${topdir}${ICONS}/es.gif","Spanish: ");
$dkflag = do img_attributes("${topdir}${ICONS}/dk.gif","Danish: ");
$plflag = do img_attributes("${topdir}${ICONS}/pl.gif","Polish: ");
$eeflag = do img_attributes("${topdir}${ICONS}/ee.gif","Estonian: ");
$filler = do img_attributes("${topdir}${ICONS}/filler.gif",'');
$left_icon = do img_attributes("${topdir}${ICONS}/left.gif","<");
$right_icon = do img_attributes("${topdir}${ICONS}/right.gif",">");
opendir(DIR, "${topdir}${MAPSDIR}");
%MAPS = ();
$elem = map {$MAPS{"$1"} = 0 if (/([^\.]*)\.gif/);} readdir(DIR);
closedir(DIR);
do load_mappings("${topdir}${mappings}");
do load_outlinks("${topdir}${outlinks}");
do load_references("${topdir}${references}");
do load_literature("${topdir}${literature}");
if ((-r "${topdir}.adm/location.dir" && -r "${topdir}.adm/location.pag")
|| -r "${topdir}.adm/location")
{
dbmopen(LOCATION, "${topdir}.adm/location", 0444);
}
else
{
die "Cannot access location.*, run ./list.pl first";
}
if ((-r "${topdir}.adm/food.dir" && -r "${topdir}.adm/food.pag")
|| -r "${topdir}.adm/food")
{
dbmopen(FOOD, "${topdir}.adm/food", 0666);
}
else
{
die "Cannot access food.*, run ./plants.pl first";
}
dbmopen(OUTLINKS, "${topdir}.adm/outlinks", 0666);
dbmopen(INLINKS, "${topdir}.adm/inlinks", 0666);
}
if (!$redo_level)
{
$redo_all = do need_create("index.lst", "index.html") ||
do need_create("species.lst", "index.html");
$redo_level = $redo_all;
$redo_level = do need_create(".", "index.html") if (!$redo_level);
$elem = join('/',@path) . "/$group";
if ($redo_all)
{
warn "Updating all from $elem\n";
}
elsif ($redo_level)
{
warn "Updating node $elem\n";
}
}
if ($redo_level)
{
open(OUTPUT, '>index.html.new');
}
else
{
open(OUTPUT, '/dev/null');
}
select(OUTPUT);
do start_html("\u$group");
do list_navigation($group, $author, $rest, $next, $prev);
do motd_notice();
print "
";
do names($group, $group, "\u$group$author", $rest, 1, "
");
print "
\n";
push(path, $group);
$curdir = join('/', @path);
#
# If the level contains a special file 'determinavit.lst' containing
# credits for the identificators of taxa, then load the hash from
# it
#
if (open(INPUT, 'determinavit.lst'))
{
@FILES = grep(!/^determinavit\.lst$/,@FILES);
do load_determinavit(INPUT);
close(INPUT);
}
local($LAST_MODIFIED);
if (open(INPUT, 'species.lst'))
{
$LAST_MODIFIED = get_modified();
@FILES = grep(!/^species\.lst$/,@FILES);
$sp_count = do species_index($group, do load_list(INPUT));
close(INPUT);
}
elsif (open(INPUT, 'index.lst'))
{
$LAST_MODIFIED = get_modified();
@FILES = grep(!/^index\.lst$/,@FILES);
$sp_count = do group_index($group, do load_list(INPUT));
close(INPUT);
}
foreach (@FILES)
{
warn "${curdir}/$_\n"
if (!/\.lst~$/);
}
pop(path);
print "\n \n";
do end_html();
select($old);
close(OUTPUT);
rename 'index.html.new','index.html' if ($redo_level);
return $sp_count;
}
sub list_navigation
{
local($group, $author, $rest, $next, $prev) = @_;
local($elem, $links);
local($width) = "width=\"20%\"";
if (!$TOPDIR)
{
print "";
print "\n";
print "";
print "\n";
}
if (@path > 0)
{
local($first) = $TOPDIR;
$tmp = $toproot;
foreach $elem (@path)
{
if (!$first)
{
print do img("${topdir}${ICONS}/left.gif","",$left_icon);
print " \u$elem\n";
}
$first = 0;
last if (!($tmp =~ s/^\.\.\///));
}
$elem = $path[$#path];
}
print " \n";
return if ($TOPDIR); # no lists for alternate side branches..
print "\n" if ($GOTO);
}
sub goto_form
{
print "
";
print "";
print "
\n";
}
sub list_refs
{
local($links, $region, $photo, $group, $rest, $prev, $next) = @_;
local($oname, $author);
local($english, $finnish);
local($chk1, $chk2, $chk3, $r, $m);
local($width) = "width=\"20%\"";
$r = "$region-" if ($region);
$m = "\Q$r${photo}list\E";
$chk1 = $1 if($links =~ /\t$m=([^\t]+)/);
$m = "\Q${r}Finnish-${photo}list\E";
$chk2 = $1 if($links =~ /\t$m=([^\t]+)/);
$m = "\Q${r}English-${photo}list\E";
$chk3 = $1 if($links =~ /\t$m=([^\t]+)/);
# Override defaults from INLINKS, if any defined
$prev = $m if (($m = do get_link("\Q${r}${photo}list\E-prev", $links)));
$next = $m if (($m = do get_link("\Q${r}${photo}list\E-next", $links)));
print "
";
($loc, $title, $lockey) = split(/\t/, $LITERATURE_DATA[$lit], 3);
undef $lockey;
if ($loc =~ s/^\[([^\]]*)\]//)
{
$lockey = $1;
$lockey = "${topdir}${lockey}" if ($lockey =~ s/^life\///);
}
# $loc = "in $in, $loc" if ($in);
$loc = format_article($loc);
$loc = "$loc" if ($lockey);
print do taxon_text($title) . "\n$loc\n";
}
# The function assumes existence of %lits in scope and uses it implicitly
sub output_literature
{
if (scalar(%lits))
{
local ($key, $loc, $author, $title, $lockey);
local ($alist, $lit);
print " \n";
print "
\n";
}
}
# The function assumes existence of %experts scope and uses it implicitly
sub output_experts
{
local ($key);
if (scalar(%experts))
{
print " \n";
print "
\n";
}
# if (scalar(@images) > $tcols)
if ($i > $tcols)
{
while ($i % $tcols)
{
print "
$filler
\n";
$i++;
}
}
print "
\n";
}
#
# Prepare plain article reference for the presentation
# (make it italic, and some parts bold)
sub format_article
{
local($article) = @_;
local($publ, $name, $page);
$page = $2 if ($article =~ s/^([^:]+)(:.*)$/$1/);
$publ = $1 if ($article =~ s/^(in\s[^,]+(,|$))//);
$name = $1 if ($article =~ s/^([^][:()0-9]*)//);
$article =~ s/_([^_]+)_/$1<\/i>/g;
if ($name !~ /^\s*$/)
{
$article =~ s/([-0-9\.]+)(\s*(\([^)]+\))*)$/$1<\/b>$2/;
$name = "$name";
}
return "$publ$name$article$page";
}
sub print_article
{
local($article, $author) = @_;
local($publ, $name);
# should really have "plain" author as parameter without this juggling...
$author =~ s/^\s*(\(?)([^\<]+)\1.*$/$2/;
$article = '' if ($article eq '-');
if ($article)
{
# $article = do use_reference($1, 1, $author) . $article if ($article =~ s/^:([^,:;]+)//);
# $publ = $1 if ($article =~ s/^(in\s[^,:]+(,|$))//);
# $name = $1 if ($article =~ s/^([^][:()0-9]*)//);
# $article =~ s/_([^_]+)_/$1<\/i>/g;
# $article =~ s/([-0-9]+)(\s*(\([^):]+\))*):\s/$1<\/b>$2: /;
# $name = "$name" if ($name !~ /^\s*$/);
# $article = "$publ$name$article";
if ($article =~ s/^:([^,:;]+)//)
{
$article = do use_reference($1, 1, $author) . taxon_text($article);
}
else
{
$article = format_article($article);
}
}
return $article;
}
# Prepare plain author information for the presentation
# (make it bold, exclude year at end if preset)
sub print_author
{
local($author) = @_;
if ($author)
{
$author =~ s/([0-9\s,]*)$/<\/b>$1/;
$author = "$author";
}
return $author;
}
sub ref_text
{
local($inp) = @_;
local($out);
foreach (split(/\t/, $inp))
{
if (/^:/)
{
$out .= do text_reference($_);
}
else
{
$out .= do taxon_text($_);
}
}
return $out;
}
sub weblinks
{
local($newline, $key) = @_;
local($url,$id,$target,$anchor,@links, $pname);
return $newline if (!$key || $key eq '-');
$target = $OUTLINKS{"$KINGDOM$key"};
# warn "$group $taxon ($KINGDOM$key) --> $target\n";
return $newline if (!$target);
foreach (split(/\t/, $target))
{
($src, $id, $pname, $url) = split(/;/,$_,4);
if ($url)
{
$anchor = do ref_text($OUTLINK_ANCHOR{"$src/$id"});
$anchor = ", $anchor" if ($anchor);
$links[$#links+1] = "$pname$anchor "
. do use_reference($src,1);
}
}
if (@links)
{
print " " if ($newline);
$newline = 0;
print "\n";
foreach (@links)
{
print "$_ \n";
}
print "\n";
}
return $newline;
}
sub names
{
# type parameter:
# = 0, species names
# != 0, group name (genus, etc). Uppercase first letter and, when
# < 0, doing index entry (do not ouput synonyms/old names)
# > 0, doing heading entry (output everything)
#
local($group, $taxon, $name, $rest, $type, $delim) = @_;
local($oname, $author, $newline, $uncertain, $trailer, $refer, $rauthor, $rname);
local(@synonyms,@literature,@misid,@sensu,$article,$location, $columns, $sensu);
local($genus, $base, $tmp, $pname, $pauthor);
$name =~ s/(\?\?[^<>\s]*)/$1<\/font>/g;
print "$name\n";
print "$delim";
# return if (!$rest);
$newline = 0;
$columns = 2;
while ($rest ne "")
{
undef $sensu;
($oname, $author, $rest) = split(/[\t]+/,$rest,3);
next if ($author =~ /:LECL/ || $author =~ /:RUGL/);
if ($oname !~ /^:/)
{
next if ($type < 0);
$uncertain = ($oname =~ s/^\?//) ? '?' : '';
# $trailer = ($oname =~ s/(\(.*)$//) ? $1 : '';
$trailer = '';
($author, $article, $location) = split(/;/,$author,3);
$author = "" if ($author eq '-');
$pauthor = $author;
$pauthor = "$1$2" if ($pauthor =~ /^(.+)\sin\s[^,]+(,.+)$/);
#
# A special kludge to allow compact writing: treat
# "name author1;:REF, xxx;#author2" as two lines
# ->
# "name -;:REF, xxx;#author2
# and ANIMAL
# "name author1";
# and otherwise
# "name author1;;#author2
#
if ($oname !~ /^=/ &&
$article =~ /^:\w+\#?([\s,:]|$)/ &&
$location !~ /^#[^#]*\#/ && # exclude "missid." lines
$location =~ /^#[\w]+/ &&
$author ne '')
{
$rest = "$oname\t-;$article;$location\t$rest";
$article = '';
$location = '' if ($KINGDOM eq $ANIMAL);
}
if ($oname =~ s/^(-|=)([^\s]*)\s*//)
{
$sensu = ($1 eq '=');
$genus = $2;
# just for "× Festufolium", make more clever is need elsewhere
$genus =~ s/x__/× /;
($base) = ($oname =~ /([^ ]*)$/);
$oname =~ s/_/ × /g if ($oname =~ s/(^|\s)x_/$1/);
if ($type > 0)
{
# A group name, genus just indicates containing higher taxon (not really
# fully though out yet...
$oname = "$oname (\u${genus})" if ($genus);
}
elsif ($author)
{
if ($genus =~ s/^\?//)
{
$oname = "\u$genus $oname"
if ($genus && $location =~ /^\#/);
$pauthor = " $pauthor" . do use_reference("²",0);
}
elsif ($genus =~ s/^!//)
{
# Explicit record that this genus is
# not the original description! However, unless
# this is a reference, ignore the genus (its
# only used to record the fact that the original
# source told it was described in different
# genus.
if ($location =~ /^\#/)
{
$oname = "\u$genus $oname" if ($genus);
$pauthor = " ($pauthor)";
}
elsif ($genus eq $group)
{
# We know its not this genus!
$pauthor = " ($pauthor)";
}
else
{
# we don't know how to put parentheses
$genus = ''; # (would clutter up too much)
$pauthor = " $pauthor" . do use_reference("²",0);
}
}
elsif ($genus)
{
# ..for plants and fungi only
$pauthor = "($pauthor)"
if ($location =~ /^\#[\S]+/ && $KINGDOM ne $ANIMAL);
$oname = "\u$genus $oname";
$pauthor = " $pauthor";
}
else
{
$pauthor = " ($pauthor)";
}
}
else
{
$genus =~ s/^[\?!]//;
$oname = "\u$genus $oname" if ($genus);
}
}
else
{
($base) = ($oname =~ /([^ ]*)$/);
# $oname =~ s/_/ × /g if ($oname =~ s/^x_//);
$oname =~ s/_/ × /g if ($oname =~ s/(^|\s)x_/$1/);
if ($pauthor)
{
if ($author_fixed || $type)
{
$pauthor = " $pauthor";
}
else
{
$pauthor = " ($pauthor)" . do use_reference("¹",0);
}
}
}
if ($refer = ($location =~ s/^\#([^\#]*)//))
{
$rauthor = $1;
if ($article)
{
$article = do print_article($article, $rauthor);
$rauthor = "$1$2" if ($rauthor =~ /^(.+)\sin\s[^,]+(,.+)$/);
$article = "$rauthor, $article" if ($rauthor);
}
else
{
$article = " $rauthor";
# a bit of kludge... make it "revised status" for plants/fungi
# and just plain reference for animals. (due to extensive use
# of "taxa author1;;#author2" in plants... to indicate different
# status views). Should have some explicit way of distinguishing
# the actual reference to the status revision from later uses of
# that same revised status.... -- msa
undef $refer if ($KINGDOM ne $ANIMAL);
}
if ($location =~ s/^\#//)
{
undef $rname;
$rname = do taxon_text($location, $group)
if ($location);
$refer = 2
if ($location ne "\u$group $taxon");
}
}
elsif ($article || $location)
{
if ($type)
{
$location = do type_reference($location, $group);
}
elsif ($location)
{
$location =~ s/\s+\/\s+/; /g;
$location = "TL: $location";
}
$article = do print_article($article, $author) if ($article);
$article = "$article, $location" if ($location);
$columns = 0;
}
$pauthor =~ s/(\?\?[^<>\s]*)/$1<\/font>/g;
$article =~ s/(\?\?[^<>\s]*)/$1<\/font>/g;
if ($oname)
{
$pname = $oname;
$pname =~ s/((^|\s)[^\s]+\.)\s/<\/i>$1 /g;
$pname =~ s/(\[[^\]]*\])/<\/i>$1/g;
$pname =~ s/(\?\?[^<>\s]*)/$1<\/font>/g;
$pname = $type ?
"$uncertain\u${pname}" : "$uncertain${pname}$trailer";
}
else
{
$pname = "$uncertain$trailer";
}
if ($sensu)
{
$tmp = ($oname eq $taxon || $oname eq "\u$group $taxon") ? "= $uncertain" : "= $pname $pauthor";
# warn "($oname, $taxon) \n";
$sensu_list->[scalar(@$sensu_list)] = ["$tmp", $article];
$columns = 0; # multicolumn really doesn't work with "sensu" lines
}
elsif ($refer == 2)
{
# $article = "$pauthor $article" if ($pauthor);
$tmp = "$pname";
$tmp .= " $pauthor" if ($pauthor);
$tmp .= " (= $rname)" if ($rname);
$misid[$#misid+1] = [$tmp, $article];
}
elsif ($refer)
{
$literature[$#literature+1] = ["$pname $pauthor", $article];
}
else
{
$article = "; $article" if ($article);
$sensu_list = [];
$synonyms[$#synonyms+1] = ["$pname${pauthor}$article", $sensu_list];
}
next;
}
if ($oname =~ /^:en/)
{
print do img("${topdir}${ICONS}/gb.gif","",$gbflag),"$author\n";
}
elsif ($oname =~ /^:us/)
{
print do img("${topdir}${ICONS}/us.gif","",$usflag),"$author\n";
}
elsif ($oname =~ /^:fi/)
{
print do img("${topdir}${ICONS}/fi.gif","",$fiflag),"$author\n";
}
elsif ($oname =~ /^:se/)
{
print do img("${topdir}${ICONS}/se.gif","",$seflag),"$author\n";
}
elsif ($oname =~ /^:de/ || $oname =~ /^:ch-de/)
{
print do img("${topdir}${ICONS}/de.gif","",$deflag),"$author\n";
}
elsif ($oname =~ /^:fr/ || $oname =~ /^:ch-fr/)
{
print do img("${topdir}${ICONS}/fr.gif","",$frflag),"$author\n";
}
elsif ($oname =~ /^:es/)
{
print do img("${topdir}${ICONS}/es.gif","",$esflag),"$author\n";
}
elsif ($oname =~ /^:dk/)
{
print do img("${topdir}${ICONS}/dk.gif","",$dkflag),"$author\n";
}
elsif ($oname =~ /^:pl/)
{
$author = join('', map(($LATIN2{ord($_)} > 0 ? "$LATIN2{ord($_)};" : "$_"),
split(//, $author)));
print do img("${topdir}${ICONS}/pl.gif","",$plflag),"$author\n";
}
elsif ($oname =~ /^:ee/)
{
print do img("${topdir}${ICONS}/ee.gif","",$eeflag),"$author\n";
}
else
{
next;
}
$newline = 1;
}
$newline = do balanced_columns($newline, $columns, @synonyms) if (@synonyms);
$newline = do weblinks($newline, ($type > 0) ? $group : "$group $taxon")
if ($group ne '' && $type >= 0);
$newline = do balanced_text($newline, 2, 7, @literature) if (@literature);
if (@misid)
{
print "
Misidentified/misapplied:
\n";
do balanced_text($newline, 2, 7, @misid);
print "
";
}
}
# Output a set of text into multiple colums using table (if there
# are more than 1 text string)
sub balanced_columns
{
local($newline, $cols, @text) = @_;
local($rows, $r, $width, $sensu);
$rows = @text;
return $newline if (!$rows);
if ($cols < 1 || $rows < 4)
{
print " " if ($newline);
foreach (@text)
{
$sensu = $_->[1];
if (@$sensu)
{
print "