Well, all this Perl stuff has come to fruition.  I have completed a
fairly nice-looking Web interface to Sword that allows you to search and
compare multiple translations (kind of slow because it actually performs
the search in every translation) and browse chapter by chapter.  Search
terms are highlighted even in browse.  You can enter arbitrary
book/chapter/verse ranges and it will display everything.

And it works with mod_perl, so SWMgr should be staying around!!  I'll
have to check whether it actually is sometime, but mod_perl is supposed
to do something like that.

I have attached the CGI script as well as the image.  All you need is
to:
- install sword, some Bible modules and the Sword-0.3 package I sent
earlier
- put the script in cgi-bin or mod_perl dir somewhere
- make it executable
- put the image somewhere
- set the image_dir (at the top of the script) to where the image is
(from the web--if it's in your docroot)

Or to try it out, go here:
http://cy209696-a.cospgs1.co.home.com/~john/perl/sword.pl
(If name resolution doesn't work:)
http://24.253.114.106/~john/perl/sword.pl

Please don't pound my poor little box too hard though :)

--John

#!/usr/bin/perl

use strict;

use Sword;
use CGI;

# CONFIG
my $image_dir="/~john/sword";

my $p = new CGI;

print $p->header;
print <<"EOM";
<HEAD>
<TITLE>Sword Bible Interface</TITLE>
</HEAD>
<BODY BGCOLOR=lightgray>
<CENTER><A HREF=sword.pl><IMG BORDER=0 SRC="$image_dir/sword_web.gif"></A></CENTER>
EOM

sub next_chapter {
	my ($mod, $book, $chap) = @_;

	if($chap >= $mod->get_num_chapters($book)) {
		my @books = $mod->get_books;
		my $book_num = $mod->{BOOKS}{$book}{real_book_num};
		if($book_num == (@books - 1)) {
			return "";
		} else {
			return $books[$book_num + 1] . " 1";
		}
	} else {
		return "$book " . ($chap+1);
	}
}

sub prev_chapter {
	my ($mod, $book, $chap) = @_;

	if($chap <= 1) {
		my @books = $mod->get_books;
		my $book_num = $mod->{BOOKS}{$book}{real_book_num};
		if($book_num == 0) {
			return "";
		} else {
			return $books[$book_num - 1] . " " . $mod->get_num_chapters($book);
		}
	} else {
		return "$book " . ($chap-1);
	}
}

sub print_verse_range {
	my ($p, $mods, @range) = @_;

	my @mods = @{$mods};
	my $search = $p->param("search");

	#
	# Print header
	#
	print "<TABLE BORDER=1>\n";
	print "<TR>\n";
	print "<TD>&nbsp;</TD>\n";
	
	foreach my $mod (@mods) {
		print "<TH>", $mod->get_name(), "</TH>\n";
	}

	print "</TR>\n";
	
	#
	# Set up loop
	#

	my @vis;
	foreach my $mod (@mods) {
		push @vis, $mod->get_iterator();
	}
	my $prev_book;
	my $prev_chapter;

	my $result_ind = 0;
	my ($result_low, $result_high) = Sword::Module::_as_verse_range($range[$result_ind]);
	foreach my $vi (@vis) {
		$vi->go_to_verse($result_low);
	}
	do {
		if($vis[0]->get_book ne $prev_book || $vis[0]->get_chapter_num != $prev_chapter) {
			$prev_book = $vis[0]->get_book;
			$prev_chapter = $vis[0]->get_chapter_num;
			my $q = new CGI($p);
			my $chap = prev_chapter($mods[0], $vis[0]->get_book, $vis[0]->get_chapter_num);
			$q->param("browse", $chap);
			my $prev_url = $q->self_url if $chap;
			$chap = next_chapter($mods[0], $vis[0]->get_book, $vis[0]->get_chapter_num);
			$q->param("browse", $chap);
			my $next_url = $q->self_url if $chap;
			$chap = $vis[0]->get_book . " " . $vis[0]->get_chapter_num;
			$q->param("browse", ($vis[0]->get_book . " " . $vis[0]->get_chapter_num));
			my $chap_url = $q->self_url if $chap;;

			print "<TR>\n";
			print "<TD colspan=", (@vis + 1), "><CENTER><B>";

			if($prev_url) {
				print "<A HREF='$prev_url'>&lt;&lt;</A>&nbsp;&nbsp;";
			}
			if($chap_url) {
				print "<A HREF='$chap_url'>$prev_book $prev_chapter</A>";
			}
			if($next_url) {
				print "&nbsp;&nbsp;<A HREF='$next_url'>&gt;&gt;</A>";
			}
			print "</B></CENTER></TD>\n";
			print "</TR>\n";
		}
		print "<TR>\n";
		print "<TH>", $vis[0]->get_key, "</TH>\n";
		foreach my $vi (@vis) {
			my $verse = $vi->get_verse;
			if($verse =~ s/($search)/<B><I>$1<\/I><\/B>/g) {
				print "<TD BGCOLOR=green>$verse</TD>\n";
			} else {
				print "<TD>$verse</TD>\n";
			}
		}
		print "</TR>\n";

		foreach my $vi (@vis) {
			$vi->next;
		}
		if($mods[0]->verse_greater($vis[0]->get_key(), $result_high)) {
			$result_ind++;
			last if $result_ind >= @range;
			($result_low, $result_high) = Sword::Module::_as_verse_range($range[$result_ind]);
			foreach my $vi (@vis) {
				$vi->go_to_verse($result_low);
			}
		}
	} while($result_ind < @range);

	#
	# Print footer
	#
	print "</TABLE>\n";
}


if($p->param("browse")) {
	my @mod_names = $p->param("mod_name");
	my @mods;
	foreach my $mod_name (@mod_names) {
		my $mod = Sword::get_module($mod_name);
		push @mods, $mod;
	}
	my @verse_range = $mods[0]->parse_verse_range($p->param("browse"), 0, 1);
	print_verse_range $p, \@mods, @verse_range;
} elsif($p->param("search")) {
	my @mod_names = $p->param("mod_name");
	my @search_results;
	my @mods;

	foreach my $mod_name (@mod_names) {
		my $mod = Sword::get_module($mod_name);
		push @mods, $mod;
		my @sr = $mod->search_verses($p->param("search"));
		@search_results = $mod->union_verse_list(\@search_results, \@sr);
	}

	if(!@search_results) {
		print "<H2><FONT COLOR=red>I'm afraid your search didn't turn up anything.  Try again, better luck!</FONT></H2>\n";
	} else {
		print_verse_range $p, \@mods, @search_results;
	}
} else {
# MAIN FORM
	print qq^
<CENTER>
<H2>Search/Browse</H2>

<FORM METHOD=get NAME=mainform>
<TABLE>
<TR>
<TD COLSPAN=2><CENTER>Enter a list of books/chapters and verses you want to look up<BR>
(Enter nothing to perform a normal search.)</CENTER></TD>
</TR>
<TR>
<TD><B>Books/Chapters:</B><BR>
(i.e. Acts 17-18;John 3:16)</TD>
<TD><INPUT TYPE=text NAME=browse></TD>
</TR>
<TR>
<TD COLSPAN=2><CENTER>Enter a search term or a verse you wish to lookup<BR>
(enter a book/chapter to browse and highlight searched terms):</CENTER></TD>
</TR>
<TR>
<TD><B>Search/Verse:</B></TD>
<TD><INPUT TYPE=text NAME=search></TD>
</TR>
<TD>Choose modules:</TD>
<TD>
<SELECT MULTIPLE NAME=mod_name>
^;
	my $first_one = 1;
	foreach my $mod_name (Sword::get_modules) {
		if($first_one) {
			print qq^<OPTION SELECTED VALUE="$mod_name">$mod_name</OPTION>
^;
			$first_one = 0;
		} else {
			print qq^<OPTION VALUE="$mod_name">$mod_name</OPTION>
^;
		}
	}

	print qq^</SELECT>
</TD>
</TR>
<TR>
<TD COLSPAN=2><INPUT TYPE=submit></TD>
</TR>
</TABLE>
</FORM>

</CENTER>
^;
}

print << "EOM";
<BR>
<BR>
<CENTER><ADDRESS><A HREF="http://www.johnkeiser.com";>John Keiser</A> was here!  This stuff is under the <A HREF="http://www.gnu.org/copyleft/gpl.html";>GPL</A>.  Copyleft (C) 2001.</ADDRESS></CENTER>
</BODY>
</HTML>
EOM

sword_web.gif

Reply via email to