Additional Credits: Jonathan Fox Jason Rust Joseph Markey MovableType Scripturizer Plug-In Tutorial Rob Hulson Translation to PHP for Wordpress 5/28/2004 Glen Davis *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
 block, a  block, or a tag
    // we skip tags because something like John 3:16 should not be messed with
	$anchor_regex = '';
    $pre_regex = '
.*<\/pre>';
    $code_regex = '.*<\/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('%s',$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('%s',$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('%s',$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!
?>