UPDATE * 30-mar-03, UPDATE2 * 14-Feb-04 this code has been modified and updated (twice). Please refer to the article entitled “Scripturizer 1.2, now with MT Plugin-ability” for a new and improved version that also includes a MovableType plugin.
I’ve been working on a tool that will take sermons from my pastor and format and post them to my church web site. The first and biggest step was “scripturizing” – that is, hyperlinking Scripture References to the BibleGateway. Which we did in my article entitled “Scripturizer – core engine.”
One of the excellent comments I recieved (from Jonathan Fox) mentioned that my original implementation was a bit too “greedy” … meaning that phrases such as “my new job will start if john acts up” would have “Scripturized” job, john and acts even though they were not scripture references. Moreover, the BibleGateway link would not validate due to not encoding the & sign. So I wrote a subroutine that would make sure we were dealing with verse/references and would encode properly.
Once this was done, the next step was to convert it into a Perl module so it could be reused in any variety of situations. Please to not breeze past this point. Regardless of the language you prefer, abtracting your work into modules and classes is an important time saver downline as are common practices in the world of software resuability and reliability. If you don’t believe me, just check out the CPAN – which is the primary reason I still prefer Perl for many projects.
You can find some pretty good how-to information regarding Perl Modules over at the Perl Circus for as long as that site lasts. The end product is something that looks like this (sans comments):
package Sermonizer::Scripturizer;
#############################################################
# Sermonizer::Scripturizer (c) 2002 Dean Peters #
# http://www.healyourchurchwebsite.com #
#############################################################
# This package hyperlinks Scripture references in text #
#############################################################
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(addLinks encodePassage);
sub addLinks {
my @data = @_;
my @output;
my $volumes = "I+|1st|2nd|3rd|First|Second|Third|1|2|3";
my $books = "Genesis|Exodus|Leviticus|Numbers|Deuteronomy|Joshua|Judges|Ruth|Samuel|Kings|Chronicles|Ezra|Nehemiah|Esther|Job|Psalm|Proverbs|Ecclesiastes|Song of Solomon|Isaiah|Jeremiah|Lamentations|Ezekiel|Daniel|Hosea|Joel|Amos|Obadiah|Jonah|Micah|Nahum|Habakkuk|Zephaniah|Haggai|Zechariah|Malachi|Matthew|Mark|Luke|John|Acts|Romans|Corinthians|Galatians|Ephesians|Philippians|Colossians|Thessalonians|Timothy|Titus|Philemon|Hebrews|James|Peter|Jude|Revelation";
my $link = "http://biblegateway.com/cgi-bin/bible?language=english&version=NIV&passage=";
foreach (@data) {
# include instances of James 2:1-13, 14 - 16, 17 & 18
my $verses = qr{ \d+ (: \d+)* \s* (?: [-&] \s* \d+)* }x;
my $passage;
# don't just match, replace
s/
(?:($volumes)\s*)* # any number of vols.
\s*
($books) # the book
\s*
( $verses (?: \s* , \s* $verses)* )
/$passage = ($1 ? "$1 ":"").($2 ? $2:"").($3 ? " $3":"");
"<a>$passage"
/gcex;
push (@output, $_);
}
return @output;
}
sub encodePassage {
my ($vol, $bk, $ver) = @_;
$ver =~ s/:/%3A/gi; # convert to encoded colon
$ver =~ s/[,&;]/%2C/gi; # convert to encoded comma
$ver =~ s/\s*//gi;
my $passage = ($vol ? "$vol+":"").($bk ? "$bk+":"").($ver ? "$ver":"");
return $passage;
}
1;
__END__
=head1 NAME
Sermonizer::Scripturizer - hyperlink Scripture references in text
=head1 SYNOPSIS
use Sermonizer::Scripturizer;
foreach (addLinks()) { print $_; };
=head1 DESCRIPTION
Sermonizer::Scripturizer searches a text stream and replaces any
instances of a Scripture reference with a hyperlink to the to the
Bible Gateway online Bible.
=head1 BUGS
Need to allow user to define which online Bible to use
Need to not link up Scripture already linked
It's probably make sense to create instance variables global to the scope of the module to contain the book volumes, etc.
=head1 AUTHOR
Copyright Dean Peters 2002,
=head1 EXAMPLE
BEGIN { push(@INC, "C:/Inetpub/wwwroot/perl/lib/"); }
use Sermonizer::Scripturizer;
my $filename = "sermon01.txt";
open(FILE, $filename ) or die "Couldn't open the file '$filename'. \n$!";
foreach (addLinks()) {
print $_;
}
close FILE;
=cut
Installation and Use
I suspect a number of you will have some problems with your scripts not finding “Sermonizer::Scripturizer” … an error that reads “Can’t locate Sermonizer/Scripturizer.pm in @INC (@INC contains: /perl/lib /perl/sit
e/lib .)“. This is because the @INC array contains a list of directories that are use to search for all external files/modules that are used by the perl script – and Scripturizer.pm ain’t in that path. Since the @INC array tells the Perl interpreter where to look for the files/modules/external scripts you need to create as subdirectory named “Sermonizer.” Then you copy Scripturizer.pm into that directory. Then atop perl program that needs ‘Scripturizing’, you write ‘BEGIN { push(@INC, “C:/Inetpub/wwwroot/lib/”); }‘. In the end, your test script may look like this:
BEGIN { push(@INC, “C:/Inetpub/wwwroot/perl/lib/”); }
use Sermonizer::Scripturizer;
my $filename = “sermon01.txt”;
open(FILE, $filename ) or die “Couldn’t open the file ‘$filename’. \n$!”;
foreach (addLinks(<FILE>)) {
print $_;
}
close FILE;
As always, your mileage may vary