Category: Code-Snippets

  • Hyperlink Bible References using Scripturizer 1.3

    After almost a year of people emailing me and leaving comments, I’ve finally made the time to update my Scripturizer Perl Module. The changes aren’t big, but they provide dramatic relief to a series of annoyances that have encumbered some of you from adding more Scripture references to your blogs, church websites and other electronically distributed information. I apologize for taking so long to get around to such an important issue.

    Addition of Abbreviations:

    I think a comment by Werner Peters (no relation) on Rob Hulson’s blog sums up the need for this addition best when he writes:

    “It gets a little tedious writing out Deuteronomy every time!”

    Yeah, you’ve said a mouth full. So I’ve added various abbreviations to the new and improved version. I’ve done so a more hard-coded format than I like, but the regular expressions are complex enough. I want a novice to be able to look at the existing expressions for Books in the Bible and add or alter their own (expressions) as they need.

    This was a painstaking process I automated to some degree with some Perl to split book names after the first three characters, then again at the fourth or fifth character depending on the length and vowel placement. I then went through each of the expressions and added or subtracted based upon a list of common Bible queries over at the ESV Bible. Many thanks to Stephen Smith for directing my attention to this data, it was incredibly helpful!

    Finally, I took care of a small handful of typos, involving pluralization. I still need to write a “mop-up” option to weed-out typos such as “revalations” and “mathew.”

    Eliminate the addition of a space before non-white space bug.

    This bug is exceptionally annoying to those who like to encapsulate their scripture references between brackets or parenthesis, such as (1 John 1:9). So annoying that back last August, Jason Rust left a comment on my blog with a fix. A fix later tried and tested and nicely documented by Joseph Markey.

    Essentially, the bug was introduced when evaluating the space between a volume reference, e.g. 1 John 1:9, which in turn put a space in front of a non-volume reference such as John 1:9. The bug occurred when the character directly before the non-volume number scripture reference was anything other than a space.

    What the fix does is it pushes the evaluation for the space into a variable, then pushes it in front of the hyperlink. An approach that works much better than a hard-coded space as nothing before the reference is then accurately rendered as nothing just before the hyperlink.

    Eliminate the ‘c’ in the gcex modifier in the regular expression.

    This regular expression mode modifier did nothing in this context, except possibily eat up CPU and sometimes throw errors in the latest version of Perl.

    ESV Bible flip-flop

    The great people at the ESV Bible have been so helpful and responsive in the past, I figured why not say thanks in the form of directing those who select the English Standard Version option to the ESV online Bible website.

    In MovableType, that would be <$MTBodyEntry scripturize=”ESV”$>

    Using Scripturizer as a Perl Module, that would be print scripturize(”Phil. 4:6-7″, “ESV”).

    XHTML compliant hyperlinks

    Ampersands are now represented as &amp;

    Usage Notes

    Well, this is sorta a no-brainer. For those of you using the MovableType Scripturizer plug-in, leave the file /plugins/Scripturizer.pl alone.

    Replace the file /extlib/Sermonizer/Scripture.pm with the referenced code below. That should be it, but first make a backup of the old one just in case.

    Here is where I have it set-up on my PC for general purposes using ActiveState’s Perl Dev Kit: c:\perl\site\lib\Sermonizer\Scripturizer.pm.

    Future Iterations

    That’s pretty much it. If you can think of anything else, let me know and we’ll see about adding it.

    Otherwise, I’d like to work on something else Stephen Smith of ESV sent me, a routine that fetches a snippet via their webservice. His code works but I have some MT centric things I want to tackle when slicing-n-dicing an XML stream of Matthew 5. That and I feel a full-blown ESV.pm module coming on. Well, Stephen has already created one, but I’ve got these ideas … and this compiler … well, you get the picture.

    There is also a much needed death-blow to typos method subroutine that needs to be written. The question is, do I write it into the same pass, or do I run first a clean-up pass filter, then scripturize? Any thoughts would be appreciated.

    Again, thanks to everyone for their input. I couldn’t have done any of this without your valuable input. Even if I could, it wouldn’t have been as much fun.

    Download the PM … Sermonizer::Scripturizer.pm

    view it as text: Sermonizer::Scripturizer.pm

    Find a bug? Have a suggestion? Leave a comment. We’ll do our best to see it gets taken care of … quickly. Get it to me in the next couple of days and I’ll try to add it as an update to this article.

  • Using Cron with LWP::Simple and XML::RSS to retrieve news feeds

    Originally published on March 24, 2003 when the war in Iraq was heating up and I found direct links to popular RSS news feeds were effecting the speed in which pages loaded on a friend’s blog whom I help maintain. I’m re-posting this article for reasons that will become obvious later this week. Until then, enjoy this “Spidering Hack!-)”

    Adding some syndicated news feeds is a nice way of adding some compelling content to your site.

    The problem is that sometimes the news feed gets overrun during heavy news days, go offline and/or suffers a host of other connectivity issues that make YOUR site load slow because the software holds your user hostage while the feed retrieval portion of the application has to wait to timeout. You see this alot with PHPNuke and PostNuke sites.

    A simple way around this problem is to use a program that periodically retrieves the feed, slices-n-dices and effectively caches it into an easy to include file on your host. Doing this achieves five goals:

    1. user page loads are not penalized when feeds go down
    2. failures to connect do not harm the existing include file
    3. multiple attempts to read the feed to not penalize user
    4. feed can be mirrored for local/private use
    5. content can be formatted to taste

    Below is a little program I wrote Thursday to grab news feeds from an AP Wire I found via Scripting.com for inclusion on a the website of a friend who makes his living in the political area.

    Using the following CRONTAB syntax, the program is executed every 30 minutes:
    30 * * * * /home/YOURPATH/getap.pl>/dev/null

    The nice thing about this approach is that this particular feed does “get busy” from time to time and at one point on Friday went offline. My users did not notice because in most cases, I was able to get by the “busy signal” on the 2nd or 3rd attempt out of 10. In the case where the feed site went offline, my users merely viewed and older include file without interruption or delay.

    Anyway, since I haven’t posted anything worthwhile in the past few days, I figured this was a good penance:

    #!/usr/bin/perl -w
    # ———————————————————————–
    # copyright Dean Peters © 2003 – all rights reserved
    # http://www.HealYourChurchWebSite.com
    # ———————————————————————–
    #
    # getap.pl is free software. You can redistribute and modify it
    # freely without any consent of the developer, Dean Peters, if and
    # only if the following conditions are met:
    #
    # (a) The copyright info and links in the headers remains intact.
    # (b) The purpose of distribution or modification is non-commercial.
    #
    # Commercial distribution of this product without a written
    # permission from Dean Peters is strictly prohibited.
    # This script is provided on an as-is basis, without any warranty.
    # The author does not take any responsibility for any damage or
    # loss of data that may occur from use of this script.
    #
    # You may refer to our general terms &amp; conditions for clarification:
    # http://www.healyourchurchwebsite.com/archives/000002.shtml
    #
    # For more info. about this code, please refer to the following article:
    # http://www.healyourchurchwebsite.com/archives/000760.shtml
    #
    # combine this code with crontab for best results, e.g.:
    # 30 * * * * /home/YOURPATH/getap.pl&gt;/dev/null
    #
    # ———————————————————————–
    use XML::RSS;
    use LWP::Simple;
    # get content from feed — using 10 attempts
      my $content = getFeed("http://www.goupstate.com/apps/pbcs.dll/section?Category=RSS04&amp;mime=xml", 10);
    
    # save off feed to a file — make sure you have write access to file or directory
    saveFeed($content, "newsfeed.xml");
    
    # create customized output
    my $output = createOutput($content, 8);
    
    # save it
    saveFeed($output, "newsfeed.inc.php");
    sub getFeed {
         my ($url, $attempts) = @_;
         my $lc = 0;		# loop count
         my $content;
         while($lc $outfile") || die("Cannot Open File $outfile");
             print OUT $content;
         close(OUT);
    }
    sub createOutput {
         my ($content, $feedcount) = @_;
    
         # create new instance of XML::RSS
         my $rss = new XML::RSS;
    
         # parse the RSS content into an output string to be saved at end of parsing
         $rss-&gt;parse($content);
         my $title = $rss-&gt;{'channel'}-&gt;{'title'};
         my $output = "GoUpstate/AP NewsWire\n";
         my $i = 0;
         foreach my $item (@{$rss-&gt;{'items'}}) {
             next unless defined($item-&gt;{'title'}) &amp;&amp; defined($item-&gt;{'link'});
             $i += 1;
             next if $i &gt; $feedcount;
             $output .= "<a>{'link'}\"&gt;$item-&gt;{'title'}</a>\n";
         }
    
        # if a copyright &amp; link exists then post it
        my $copyright = $rss-&gt;{'channel'}-&gt;{'copyright'};
        my $link = $rss-&gt;{'channel'}-&gt;{'link'};
        my $description = $rss-&gt;{'channel'}-&gt;{'description'};
        $output .= "  <a>$copyright</a>\n"	if($copyright &amp;&amp; $link);
        $output .= "";
        return $output;
    }
    

    Of course, now I need to go ahead and practice what I preach and do the same here!

  • Scripturizer – core engine

    All week I’ve been leading you on, telling you that I’d give you some code that would encode your plain text with hyperlinks to the online Bible of your choosing. After some throwing some raw meat out into the comp.lang.perl.misc usenet group, I received fillet-mignon snippet from Jeff ‘japhy’ Pinyan that gave me enough of a match to compress the 400 some odd lines of Steve Lihn’s code into about 40 lines of code (provided you don’t count where I had to split long statements to fit this posting).

    This will obviously need to be rolled into a Perl module that might also include some other elements such as slicing and dicing sermons, dealing with acronyms and madding stuff like “Revelations” instead of “Revelation.”
    my $volumes = “I+|1st|2nd|3rd|First|Second|Third|1|2|3”;# I chopped these up so they’d stay within the margins of my blog
    my $books = “Genesis|Exodus|Leviticus|Numbers|Deuteronomy|Joshua|”;
    $books .= “Judges|Ruth|Samuel|Kings|Chronicles|Ezra|Nehemiah|Esther|”;
    $books .= “Job|Psalm|Proverbs|Ecclesiastes|Song of Solomon|Isaiah|”;
    $books .= “Jeremiah|Lamentations|Ezekiel|Daniel|Hosea|Joel|Amos|”;
    $books .= “Obadiah|Jonah|Micah|Nahum|Habakkuk|Zephaniah|Haggai|”;
    $books .= “Zechariah|Malachi|Matthew|Mark|Luke|John|Acts|Romans|”;
    $books .= “Corinthians|Galatians|Ephesians|Philippians|Colossians|”;
    $books .= “Thessalonians|Timothy|Titus|Philemon|Hebrews|James|Peter|”;
    $books .= “Jude|Revelation”;

    my $link = “http://biblegateway.com/cgi-bin/bible?passage=”;

    while(<DATA>) {

    my $passage;

    # this string will sit inside following expression
    my $verses = qr{ \d+ (: \d+)* \s* (?: [-&] \s* \d+)* }x;

    # replace instances
    s/
    (?:($volumes)\s*)*
    \s*
    ($books)
    \s*
    ( $verses (?: \s* , \s* $verses)* )
    /$passage = ($1 ? “$1 “:””).($2 ? $2:””).($3 ? ” $3″:””);
    ” <a href=\”$link”.encodePassage($1,$2,$3).”\”>$passage<\/a>”
    /gcex;

    print $_;
    }

    # make it validate
    sub encodePassage {
    my ($vol, $bk, $ver) = @_;
    $ver =~ s/:/%3A/gi;
    $ver =~ s/[,&;]/%2C/gi;
    $ver =~ s/\s*//gi;
    my $passage = ($vol ? “$vol+”:””).($bk ? “$bk+”:””).($ver ? “$ver”:””);
    return $passage;
    }

    __DATA__
    $Date: October 20, 2002
    $Type: Sermon
    $Scripture: James 2:1-13, 14 & 15
    $Version: NIV
    $Title: How Faith Works: “Determining the Worth of a Person”
    Foo

    $Text:
    … what Paul was thinking of when he wrote in Galatians 3 and said, “There is neither Jew nor Greek, SLAVE NOR FREE, male nor female, for you are all ONE in Christ Jesus.” (Galatians 3:28)

    Bar
    … and they were-it was the rich Sadducees who arrested Peter and John in Acts 4. Acts 13:50 says it was the wealthy “leading men” of the city of Antioch who persecuted Paul and Barnabas. Acts 16 says the wealthy owners of a demon-possessed girl dragged Paul into court and Acts 19 tells of the wealthy silversmiths in Ephesus who very nearly led a mob to kill him. James also says that it was the rich of that day who slandered the name of Jesus.

  • PERL program for linking Scripture references

    Here is an article that explains how the author used PERL script to interface thousands of Bible quotations with Bible Gateway. Included on the page is a link to a program that runs through a document an ‘Scripturizes’ Bible references. What I mean by ‘Scripturize’ is that it takes a Bible reference and converts it a hyperlink at the BibleGateway.

    I thought this might be useful to our discussion regarding regular expressions and fun stuff like that. Mostly because I suspect any of you who want to post sermons and Bible studies may also want to do the same. Granted, bib.pl was written back in 1998, so it employs some ‘old-school’ Perl parsing techniques. And later this week, we’re going to see how much of this can be reduced to a simple regular expression. Still, it offers some features and approaches we need to consider in our own “Scripturizer” application.

    One thing it does that my own concept didn’t … it deals with abbreviations for Bible book names..