1<?php 2/** 3 * Songlist Plugin: Extract and generate a list of songs from a given page, the songs are indexed by IDs. 4 * 5 * Syntax: <songlist {src=]page> 6 * src the page that contains the lines of the form 7 * text to be inserted on a line|ID 8 * 9 * @license GPL v2+ (http://www.gnu.org/licenses/gpl.html) 10 * @author Reinhold Kainhofer <reinhold@kainhofer.com> 11 */ 12 13if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 14if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 15require_once(DOKU_PLUGIN.'syntax.php'); 16 17/** 18 * All DokuWiki plugins to extend the parser/rendering mechanism 19 * need to inherit from this class 20 */ 21class syntax_plugin_songlist extends DokuWiki_Syntax_Plugin { 22 /** 23 * return some info 24 */ 25 function getInfo(){ 26 return array( 27 'author' => 'Reinhold Kainhofer', 28 'email' => 'reinhold@kainhofer.com', 29 'date' => '2008-09-03', 30 'name' => 'Songlist Plugin', 31 'desc' => 'Automatically generate a list with lines taken from a master page. Each song is identified by an ID. 32 Syntax: <songlist src=pagename>', 33 'url' => 'http://wiki.splitbrain.org/plugin:songlist', 34 ); 35 } 36 37 function getType(){ return 'substition';} 38 function getAllowedTypes() { return array('container','substition','protected','disabled','formatting','paragraphs'); } 39 function getPType(){ return 'block';} 40 41 function getSort(){ return 999; } 42 43 /** Connect pattern to lexer */ 44 function connectTo($mode) { 45 $this->Lexer->addSpecialPattern('<songlist\s*.*?>.*?</songlist.*?>',$mode,'plugin_songlist'); 46 } 47 48 function normalize_id($id) { 49 return preg_replace("/[,'!?.\ ]/", "", strtolower ($id) ); 50 } 51 52 /** 53 * Handle the match 54 */ 55 function handle($match, $state, $pos, &$handler){ 56 // 57 global $entrymap; 58 // 59 switch ($state) { 60 case DOKU_LEXER_SPECIAL: 61 if ( preg_match( "/^<songlist\s*(?:src=|)\"?([^ ]*?)\"?\s*>/", $match, $matches ) ) { 62 $filename=$matches[1]; 63 $entrymap = $this->readPatternFile( $filename, $entrymap ); 64 } 65 $data = $match; 66 $data = preg_replace( ":\</?songlist.*?\>:", "", $data ); 67 $line = strtok( $data, "\n" ); 68 while ($line !== false ) { 69 $id = $this->normalize_id ($line); 70 if ( $entrymap[$id] ) { 71 $result .= $entrymap[$id]."\n"; 72 } else { 73 $result .= $line."\n"; 74 } 75 $line = strtok( "\n" ); 76 } 77 return array( $state, $result ); 78 break; 79 } 80 return false; 81 } 82 83 /** 84 * Create output 85 */ 86 function render($mode, &$renderer, $indata) { 87 // 88 if($mode == 'xhtml'){ 89 list($instr, $data) = $indata; 90 switch ($instr) { 91 case DOKU_LEXER_SPECIAL: 92 $renderer->doc .= p_render( 'xhtml', p_get_instructions($data), $info ); 93 break; 94 } 95 return true; 96 } 97 return false; 98 } 99 100 function readPatternFile( $pagename, $tmp ) 101 { 102 $replacements = $tmp; 103 $pages = array( $pagename ); 104 $loadedPages = array(); 105 foreach( $pages as $page ) 106 { 107 $page = cleanID( $page ); 108 // 109 // don't read in pages that were already read 110 if( in_array( $page, $loadedPages ) ) continue; 111 $loadedPages[] = $page; 112 // 113 // Only use pages that the user is allowed to read 114 if ( auth_quickaclcheck( $page ) < AUTH_READ ) continue; 115 // 116 // get the actual filename and load it into the array 117 $filename = wikiFN( $page ); 118 if( !file_exists( $filename ) ) continue; 119 // 120 // Read all lines from the file and parse them 121 $handle = fopen ( $filename, "r" ); 122 while ( !feof($handle) ) { 123 $buffer = fgets( $handle, 4096 ); 124 if ( preg_match( "/^(.*)\|([-a-zA-Z0-9_ ,!?ßäöüÄÖÜ']+)\n?$/", $buffer, $matches ) ) { 125 $id = $this->normalize_id ($matches[2]); 126 $replacements[$id] = $matches[1]; 127 } 128 } 129 } 130 return $replacements; 131 } 132} 133