<?php
/*
Plugin Name: Scripturizer
Version: 1.4 fork
Plugin URI: http://xastanford.org/archives/scripturizer-in-php/
Description: Changes Bible references to hyperlinks
Author: Dean Peters, ported by Glen Davis
Author URI: http://www.healyourchurchwebsite.com/
*/

/*
Copyright (c) 2002-2004
  Dean Peters   <http://www.HealYourChurchWebSite.com>

Additional Credits:
  Jonathan Fox  <http://vulpecula.us/~jon/>
  Jason Rust <http://rustyparts.com/blip/>
  Joseph Markey <http://thegreatlands.com/archives/000032.html>

MovableType Scripturizer Plug-In Tutorial
  Rob Hulson    <http://www.robhulson.com/archives/000073.html>

Translation to PHP for Wordpress 5/28/2004
  Glen Davis <http://www.xastanford.org/>
  *added NET Bible, Message, NIRV
  *now able to specify translation on fly as in Gen 1:1, CEV
  *altered the book regex to suit my tastes (period is optional on abbrev, for example)

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

The Software is provided "as is", without warranty of any kind, express or
implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose and noninfringement. In no event shall
the authors or copyright holders be liable for any claim, damages or other
liability, whether in an action of contract, tort or otherwise, arising
from, out of or in connection with the Software or the use or other
dealings in the Software.
*/

define('DEFAULT_BIBLE_TRANSLATION','NIV');

function 
scripturize ($text '',$bible DEFAULT_BIBLE_TRANSLATION){
    
// skip everything within a hyperlink, a <pre> block, a <code> block, or a tag
    // we skip tags because something like <img src="blah" alt="John 3:16"> should not be messed with
    
$anchor_regex '<a\s+href.*?<\/a>';
    
$pre_regex '<pre>.*<\/pre>';
    
$code_regex '<code>.*<\/code>';
    
$tag_regex '<(?:[^<>\s]*)(?:\s[^<>]*){0,1}>'// $tag_regex='<[^>]+>';
    
$split_regex "/((?:$anchor_regex)|(?:$pre_regex)|(?:$code_regex)|(?:$tag_regex))/i";

  
$parsed_text preg_split($split_regex,$text,-1,PREG_SPLIT_DELIM_CAPTURE);
  
$linked_text '';

  while (list(
$key,$value) = each($parsed_text)) {
      if (
preg_match($split_regex,$value)) {
         
$linked_text .= $value// if it is an HTML element or within a link, just leave it as is
      
} else {
        
$linked_text .= scripturizeAddLinks($value,$bible); // if it's text, parse it for Bible references
      
}
  }

  return 
$linked_text;
}

function 
scripturizeAddLinks($text '',$bible DEFAULT_BIBLE_TRANSLATION) {
    
$volume_regex '1|2|3|I|II|III|1st|2nd|3rd|First|Second|Third';

    
$book_regex  'Genesis|Exodus|Leviticus|Numbers|Deuteronomy|Joshua|Judges|Ruth|Samuel|Kings|Chronicles|Ezra|Nehemiah|Esther';
    
$book_regex .= '|Job|Psalms?|Proverbs?|Ecclesiastes|Songs? of Solomon|Song of Songs|Isaiah|Jeremiah|Lamentations|Ezekiel|Daniel|Hosea|Joel|Amos|Obadiah|Jonah|Micah|Nahum|Habakkuk|Zephaniah|Haggai|Zechariah|Malachi';
    
$book_regex .= '|Mat+hew|Mark|Luke|John|Acts?|Acts of the Apostles|Romans|Corinthians|Galatians|Ephesians|Phil+ippians|Colossians|Thessalonians|Timothy|Titus|Philemon|Hebrews|James|Peter|Jude|Revelations?';

//split these up from the Perl code because I want to be able to have an optional period at the end of just the abbreviations

    
$abbrev_regex  'Gen|Ex|Exo|Lev|Num|Nmb|Deut?|Josh?|Judg?|Jdg|Rut|Sam|Ki?n|Chr(?:on?)?|Ezr|Neh|Est';
    
$abbrev_regex .= '|Jb|Psa?|Pr(?:ov?)?|Eccl?|Song?|Isa|Jer|Lam|Eze|Dan|Hos|Joe|Amo|Oba|Jon|Mic|Nah|Hab|Zeph?|Hag|Zech?|Mal';
    
$abbrev_regex .= '|Mat|Mr?k|Lu?k|Jh?n|Jo|Act|Rom|Cor|Gal|Eph|Col|Phi|The?|Thess?|Tim|Tit|Phile|Heb|Ja?m|Pe?t|Ju?d|Rev';

    
$book_regex='(?:'.$book_regex.')|(?:'.$abbrev_regex.')\.?';

    
$verse_regex="\d{1,3}(?::\d{1,3})?(?:\s?(?:[-&,]\s?\d+))*";

    
$translation_regex 'NIV|NASB|AMP|NLT|KJV|ESV|CEV|NET|NKJV|KJ21|ASV|WE|YLT|DARBY|WYC|NIV-UK|MSG|NIRV';

// note that this will be executed as PHP code after substitution thanks to the /e at the end!

    
$passage_regex '/(?:('.$volume_regex.')\s)?('.$book_regex.')\s('.$verse_regex.')(?:\s?[,-]?\s?((?:'.$translation_regex.')|\s?\((?:'.$translation_regex.')\)))?/e';

    
$replacement_regex "scripturizeLinkReference('\\0','\\1','\\2','\\3','\\4','$bible')";

    
$text=preg_replace($passage_regex,$replacement_regex,$text);

    return 
$text;
}

function 
scripturizeLinkReference($reference='',$volume='',$book='',$verse='',$translation='',$user_translation='') {
    if (
$volume) {
       
$volume str_replace('III','3',$volume);
       
$volume str_replace('II','2',$volume);
       
$volume str_replace('I','1',$volume);
       
$volume $volume{0}; // will remove st,nd,and rd (presupposes regex is correct)
    
}

   if(!
$translation) {
         if (!
$user_translation) {
             
$translation DEFAULT_BIBLE_TRANSLATION;
         } else {
             
$translation $user_translation;
         }
   } else {
       
$translation trim($translation,' ()'); // strip out any parentheses that might have made it this far
   
}

   
//if necessary, just choose part of the verse reference to pass to the web interfaces
   //they wouldn't know what to do with John 5:1-2, 5, 10-13 so I just give them John 5:1-2
   //this doesn't work quite right with something like 1:5,6 - it gets chopped to 1:5 instead of converted to 1:5-6
   
if ($verse) {
       
$verse strtok($verse,',& ');
   }

   switch (
$translation) {
        case 
'ESV':
        
// note: the ESV could actually support a mouseover reference
        // we could pull it directly from their site and include it in the $title text
        // http://www.gnpcb.org/esv/share/services/api/ for more info
             
$link 'http://www.gnpcb.org/esv/search/?go=Go&q=';
             
$title 'English Standard Version Bible';
             
$link sprintf('<a href="%s%s" title="%s">%s</a>',$link,htmlentities(urlencode(trim("$volume $book $verse"))),$title,trim($reference));
             break;
        case 
'NET':
             
$link 'http://www.bible.org/cgi-bin/netbible.pl?header=on';
             
$title 'New English Translation';
             
$chapter trim(strtok($verse,':'));
             
$verses trim(strtok('-,'));
             
$book scripturizeNETBook($volume.' '.$book);
             
$link sprintf('<a href="%s&book=%s&chapter=%s&verse=%s" title="%s">%s</a>',$link,htmlentities(urlencode($book)),$chapter,$verses,$title,trim($reference));
             break;
        default:
             
$link "http://biblegateway.com/cgi-bin/bible?language=english&version=$translation&passage=";
             
$title 'Bible Gateway';
             
$link sprintf('<a href="%s%s" title="%s">%s</a>',$link,htmlentities(urlencode(trim("$volume $book $verse"))),$title,trim($reference));
             break;
        
// should I add Libronix links? perhaps with define constant to enable/disable...
        // see http://www.logos.com/support/lbs/weblinking
        // libronixdls:keylink|ref=[en]bible:Gen%201:1|res=LLS:ESV
    
}

    return 
$link;
}

function 
scripturizeNETBook($book='') {
//need this function because NET Bible needs rigid input
//it's not perfect, so someone who intends to link to the NET Bible must be cautious with their syntax
//Jn 5:1 won't work, for example (must be 'joh' or 'john').
    
$book strtolower(trim($book));
    if (!
$book) return '';

    
$book preg_replace('/\s+/'''$book); //strip whitespace

    
switch ($book) {
           case 
'judges':
                
$book 'jdg';
                break;
           case 
'song of songs':
           case 
'song of solomon':
           case 
'song':
                
$book 'sos';
                break;
           case 
'philemon':
                 
$book 'phm';
                 break;
           default:
                   
$book substr($book,0,3);
    }
    return 
$book;
}

function 
scripturizePost($post_ID) {
    global 
$wpdb;
    global 
$tableposts;

    if (!isset(
$tableposts)) {
        
// detect variable change between versions - see http://wiki.wordpress.org/1.3/TableVariables
        
$tableposts=$wpdb->posts;
    }

    
$postdata=$wpdb->get_row("SELECT * FROM $tableposts WHERE ID = '$post_ID'");

    
$content scripturize($postdata->post_content);

    
$wpdb->query("UPDATE $tableposts SET post_content = '$content' WHERE ID = '$post_ID'");
    
    return 
$post_ID;
}

/*
// this one worked, so I want to be sure to keep it in case I botch the upgrade to be 1.3 compatible
function scripturizePost($post_ID) {
    global $wpdb;
    global $tableposts;

    $postdata=$wpdb->get_row("SELECT * FROM $tableposts WHERE ID = '$post_ID'");

    $content=scripturize($postdata->post_content);

    $wpdb->query("UPDATE $tableposts SET post_content = '$content' WHERE ID = $post_ID");
    
    return $post_ID;
}
*/

// you can use this one of two ways in WordPress, as an action or as a filter.
// a filter is retroactive (affects all previous posts in addition to all future posts)
// an action only affects future posts and those you happen to edit
// an action is therefore more efficient, but less useful if you have a lot of previous posts
// so if you're coming from Movable Type and used the plugin before, you might want to use a filter
// but it will slow down your site considerably...

// choose which you want and comment out the other

//add_filter('the_content','scripturize');

add_action('publish_post','scripturizePost',9);
add_action('edit_post','scripturizePost');

// NOTE: the generic_ping action (hooked to publish_post) is broken, so if you add any action to publish_post at default priority of 10 or higher it won't work.

// note, adding the edit_post action guarantees that if you add or change a scripture reference the link will be inserted
// HOWEVER, it will prevent you from removing a link you don't want!
?>