*/ // must be run within Dokuwiki if (!defined('DOKU_INC')) die(); if (!defined('DOKU_LF')) define('DOKU_LF', "\n"); if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once DOKU_PLUGIN.'syntax.php'; class syntax_plugin_bible extends DokuWiki_Syntax_Plugin { # Required. Define plugin type (see https://www.dokuwiki.org/devel:syntax_plugins) public function getType() { return 'substition'; } # Required. Define paragraph handling (see https://www.dokuwiki.org/devel:syntax_plugins) public function getPType() { return 'normal'; } # Required. Define sort order to determine which plugin trumps which. This value was somewhat arbitrary ## And can be changed without really affecting the plugin. (see https://www.dokuwiki.org/devel:syntax_plugins) public function getSort() { return 275; } #Plugin Part 1 of 3. This is the actual plugin. This part defines how to invoke the plugin public function connectTo($mode) { # Define all 73 books of the Catholic Bible. ## There are 66 books in the Protestant Bible, so this list will need altering if you plan to use that. $validBibleBooksArr = array("Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy", "Josue", "Judges", "Ruth", "1 Kings", "2 Kings", "3 Kings", "4 Kings", "1 Paralipomenon", "2 Paralipomenon", "1 Esdras", "2 Esdras", "Tobias", "Judith", "Esther", "Job", "Psalms", "Proverbs", "Ecclesiastes", "Canticles", "Wisdom", "Ecclesiasticus", "Isaias", "Jeremias", "Lamentations", "Baruch", "Ezechiel", "Daniel", "Osee", "Joel", "Amos", "Abdias", "Jonas", "Micheas", "Nahum", "Habacuc", "Sophonias", "Aggeus", "Zacharias", "Malachias", "1 Machabees", "2 Machabees", "Matthew", "Mark", "Luke", "John", "Acts", "Romans", "1 Corinthians", "2 Corinthians", "Galatians", "Ephesians", "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians", "1 Timothy", "2 Timothy", "Titus", "Philemon", "Hebrews", "James", "1 Peter", "2 Peter", "1 John", "2 John", "3 John", "Jude", "Apocalypse"); # Now, for each of those books, register two regular expressions: ## One for "through verses" like chapter 2 verses 19 through 24 (Mark 2:19-24) ## One for just a single verse (Mark 2:19) ## The order of registry is important! Make sure the through-verse is first or else the single verse will gobble everything. foreach ($validBibleBooksArr as $bibleBook){ $this->Lexer->addSpecialPattern($bibleBook . ' \d+:\d+-\d+',$mode,'plugin_bible'); $this->Lexer->addSpecialPattern($bibleBook . ' \d+:\d+',$mode,'plugin_bible'); } } #Plugin Part 2 of 3. This is the handler - the workhorse - which takes the matched result from part 1 and modifies it. public function handle($match, $state, $pos, &$handler){ $data = array(); # Blank array # Make sure that we're dealing with the match from our regexp in part 1, which is in the DOKU_LEXER_SPECIAL context. switch ($state){ case DOKU_LEXER_SPECIAL : # Okay awesome, lets process that regexp match. Call my custom function called _fetchBibleVerse(). $bibleLink = $this->_fetchBibleVerse($match); # Modified match obtained! Now return that to Dokuwiki for collection in Part 3. return array($bibleLink, $state, $pos); } return $data; # Upon failure, return that blank array } #Plugin part 3 of 3. This takes that result from part 2 and actually renders it to the page. public function render($mode, &$renderer, $data) { if($mode != 'xhtml') return false; # If mode is not html, like if it is metadata, just return. $renderer->doc .= $data[0]; # Otherwise, fetch that $bibleLink (stored in $data[0]) and pass it to the dokuwiki renderer. return true; } # This custom function takes a matched input value (like Mark 2:19-24 or Amos 1:1) and returns HTML code ## which turns that input into an with the bible verse as the hover-text. function _fetchBibleVerse($inputVerse) { # Set up variables for later $thisChapterName = ""; $thisChapterNum = ""; $thisVerse = ""; $throughVerse = ""; $matchingVerses = array(); $inputVerses = array(); # Have a look at that input and try to determine chapter name, number, verse number, and through-verse if it exists. ## Groups are defined by parenthesis. Group one is catching the Chapter Name, accounting for the fact that some chapters ## begin with a number. ## Group two is catching the chapter number ## Group three is catching the verse number ## Group 4 is required so that I can put a * after it, indicating that it may or may not be present ## Group 5 catches the "through verse" if it should exist. $result = preg_match("/^.*?(\d*?\s*?\w+) (\d+):(\d+)(-(\d+))*$/", $inputVerse, $matches); if ($result){ $chapterName = trim($matches[1]); $thisChapterName = $chapterName; $thisChapterNum = $matches[2]; $thisVerseNum = $matches[3]; $throughVerse = $matches[5]; # Define which bible text file matches the result ## Here is where you'll plug in a different version of the bible, should you desire. ## Make sure that the syntax of the text files matches that of the Douay Rhiems bible ## provided with this plugin. ## PLEASE NOTE -- The bible cannot be all in one text file or the memory limit imposed upon ## plugins by Dokuwiki will be reached, and the plugin will fail. You MUST separate by chapter. $filename = DOKU_PLUGIN . "bible/bible_douayRheims/" . $thisChapterName . ".txt"; $filename = str_replace(' ','_',$filename); # The user entered spaces, but filenames use underscores. if(!file_exists($filename)){ echo "ERROR, can't find matching bible file: " . $filename . "
\n"; return; } # Check for a through verse (like, Mark 2:7-9), expand it if found if ($throughVerse != ""){ # Through Verse supplied foreach (range($thisVerseNum, $throughVerse) as $verseNum){ # Push each valid verse defined by the range provided onto the inputVerses array array_push($inputVerses, $thisChapterName . " " . $thisChapterNum . ":" . $verseNum); } } else { # No through verse, just take the input array_push($inputVerses, $inputVerse); } # Now for each of the verses supplied (multiples are from through-verses), ## look for a match in the bible file, collect it for return. foreach ($inputVerses as $thisInputVerse){ foreach (file($filename) as $linenum => $line){ # Find matching verse ## Here is where the syntax of the bible text files is important. Every line must be: ## "CHAPTER:VERSE. CONTENT" $result = preg_match("/^.*?(\d+:\d+)\.(.*?)$/", $line, $matches); if ($result){ # looks like a verse $thisVerse = $matches[1]; $content = $matches[2]; $constructedVerse = $thisChapterName . " " . $thisVerse; # Form the verse into something similar to user input $constructedVerse = strtolower($constructedVerse); # Force it to lower case for comparison $lowInputVerse = strtolower($thisInputVerse); # Force user input to lower case for comparison if($lowInputVerse == $constructedVerse){ # Do they match? # This verse matches one of the verses that the user asked for! Push its contents into our matchingVerses array array_push($matchingVerses, $content); } } #Not a chapter or verse? Skip it. } } $matchingVersesOutput = implode(" ", $matchingVerses); # Flatten our matching verses array into a string joined by spaces. $matchingVersesOutput = trim($matchingVersesOutput); # Make it look pretty by trimming off any leading or trailing whitespace # FINALLY, return all matching verses smooshed together as the "title" or hover-text to an . return "" . $inputVerse . ""; } else { # Warn the user that some match is not a valid bible verse (Mark 445:9833) echo "Input does not appear to be a valid bible verse: " . $inputVerse . "
\n"; } } } // vim:ts=4:sw=4:et: