* @date 2005-08-10 * * Modifications: 2006-07-03 Jean-Francois Lalande. * Adding: * - Chronological ordering support * - Type of references groups * - PDF and POSTSCRIPT links * * Modifications: 2006-08-22 Jean-Francois Lalande. * - Fix for hyphaned name in OSBib (reported to developers) */ /** * Parameters for the plugin: * * - $conf['bibtex_format'] * default: "APA" * This control the formatting output of the bibtex plugin. * Options are: APA, ieee, britishmedicaljournal, chicago, harvard, mla, turabian * * - $conf['bibtex_sort_year'] * default: no value (no sorting by date) * Controls the sorting of the references by year. * Options are: 1 (most recent) or -1 (oldest first) * * - $conf['bibtex_sort_type'] * default: no value (no sorting by type) * Controls the sorting of the references by type. * Options are: 1 (ascending order) or -1 (descending order) * The values for each type of reference is controlled by * the array of $conf["bibtex_types_order"]. You can overide this array * in your local configuration. You can find an example of this array in * the syntax.php file of this plugin. * * - $conf["bibtex_types_order"] * default: see below * If the 'bibtex_sort_type' has been activated, this array controls * the order of appearing of the different type of references. For each kind * of reference a value is associated. For example a book is 10, an article 7 * and a techreport 1. If the same value is given for two kinds of references * they are grouped (in the example inproceedings and conference are grouped) * * Example of array: * $conf["bibtex_types_order"] = array ( * "book"=> 10, * "inbook"=> 9, * "phdthesis"=> 8, * "article"=> 7, * "inproceedings"=> 3, * "conference"=> 3, * "techreport"=> 1, * ); * * - $conf["bibtex_types_names"] * default see below * If the 'bibtex_sort_type' has beec activated, this array controls * the name of the section for each group of references. The idea * is to personalize the titles for exemple for the entries 'inbook' by * putting a label "Chapter in books". For each level defined in the * array $conf["bibtex_types_order"], we associate a label. * * Example of array: * $conf["bibtex_types_names"] = array ( * 10 => "Books", * 9 => "Chapters in books", * 8 => "Phd Thesis", * 7 => "Articles", * 3 => "Proceedings", * 1 => "Technical reports", * ); * * - $conf['bibtex_types_title_level'] * default: 2 * This parameter sets the level of the label of each section of reference. * By default the level is 2 corresponding to h2 tags. * * * Example of parameters for activating all features: * * $conf['bibtex_format'] = "ieee"; * $conf['bibtex_sort_year'] = 1; * $conf['bibtex_sort_type'] = 1; * $conf['bibtex_sort_type_title'] = 1; * * Special parameters in the bibtex entry: * * - The tag 'file' is considered as an internal document of dokuwiki * - The tag 'pdf' is considerd as an external url * - The tag 'postscript' is considered as an external url */ // Default values global $conf; if(!isset($conf["bibtex_types_order"])) { $conf["bibtex_types_order"] = array ( "book"=> 10, "inbook"=> 9, "phdthesis"=> 8, "article"=> 7, "inproceedings"=> 3, "conference"=> 3, "techreport"=> 1, ); } if(!isset($conf["bibtex_types_names"])) { $conf["bibtex_types_names"] = array ( 10 => "Books", 9 => "Chapters in books", 8 => "Phd Thesis", 7 => "Articles", 3 => "Proceedings", 1 => "Technical reports", ); } if(!isset($conf["bibtex_types_title_level"])) { $conf['bibtex_types_title_level'] = 2; } if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); /** * usort callback for years */ function compare_year($a, $b) { global $conf; // No sorting if ($conf['bibtex_sort_year'] == "") return 0; $adist = $a['year']; $bdist = $b['year']; if ($adist == $bdist) { return 0; } return ($adist < $bdist) ? $conf['bibtex_sort_year'] : -$conf['bibtex_sort_year']; } /** * usort callback for types */ function compare_type($a, $b) { global $conf; // No sorting if ($conf['bibtex_sort_type'] == "") return 0; $adist = $conf["bibtex_types_order"][$a['bibtexEntryType']]; $bdist = $conf["bibtex_types_order"][$b['bibtexEntryType']]; if ($adist == $bdist) { // If the year sorting is activated... if ($conf['bibtex_sort_year'] != "") { return compare_year($a,$b); } else { return 0; } } return ($adist < $bdist) ? $conf['bibtex_sort_type'] : -$conf['bibtex_sort_type']; } /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_bibtex extends DokuWiki_Syntax_Plugin { function getInfo(){ return array( 'author' => 'Christophe Ambroise', 'email' => 'ambroise@utc.fr', 'date' => '2006-06-29', 'name' => 'Bitext Plugin', 'desc' => 'parses bibtex blocks', 'url' => 'http://www.hds.utc.fr/~ambroise/doku.php?id=softwares:dokuwikibibtexplugin' ); } /** * What kind of syntax are we? */ function getType(){ return 'protected'; } /** * Where to sort in? */ function getSort(){ return 102; } /** * Connect pattern to lexer */ function connectTo($mode) { $this->Lexer->addEntryPattern('Lexer->addExitPattern('','plugin_bibtex'); } /** * Handle the match */ function handle($match, $state, $pos) { if ( $state == DOKU_LEXER_UNMATCHED ) { $matches = preg_split('/>/u',$match,2); $matches[0] = trim($matches[0]); if ( trim($matches[0]) == '' ) { $matches[0] = NULL; } return array($matches[1],$matches[0]); } return TRUE; } /** * Create output */ function render($mode, &$renderer, $data) { global $conf; if($mode == 'xhtml' && strlen($data[0]) > 1) { $renderer->doc .= $this->createCitations($data[0]); return true; } } function createCitations(&$data) { global $conf; $pathToOsbib = DOKU_PLUGIN.'bibtex/OSBib/'; include_once($pathToOsbib.'format/bibtexParse/PARSEENTRIES.php'); include_once( $pathToOsbib.'format/BIBFORMAT.php'); // Getting conf (JFL) if ($conf['bibtex_format'] != "") { $bibtex_format = $conf['bibtex_format']; } else { $bibtex_format = "APA"; } /* Get the bibtex entries into an associative array */ $parse = NEW PARSEENTRIES(); $parse->expandMacro = TRUE; $parse->fieldExtract = TRUE; $parse->removeDelimit = TRUE; $parse->loadBibtexString($data); $parse->extractEntries(); list($preamble, $strings, $entries) = $parse->returnArrays(); /* Format the entries array for html output */ $bibformat = NEW BIBFORMAT($pathToOsbib, TRUE); $bibformat->cleanEntry=TRUE; // The entries will be transformed into nice utf8 list($info, $citation, $styleCommon, $styleTypes) = $bibformat->loadStyle(DOKU_PLUGIN.'bibtex/OSBib/styles/bibliography/', $bibtex_format); $bibformat->getStyle($styleCommon, $styleTypes); $citations='
'; // Sorting ? if ($conf['bibtex_sort_year'] != "") { usort($entries, "compare_year"); } if ($conf['bibtex_sort_type'] != "") { usort($entries, "compare_type"); } foreach ($entries as $entry){ // Get the resource type ('book', 'article', 'inbook' etc.) $resourceType = $entry['bibtexEntryType']; if ($conf['bibtex_sort_type_title'] == 1) { if ($conf['bibtex_types_order'][$resourceType] != $conf['bibtex_types_order'][$resourceTypeLast]) { $resourceTypeLast = $resourceType; $value = $conf['bibtex_types_order'][$resourceType]; $citations.=""; $citations.=$conf['bibtex_types_names'][$value]; $citations.=""; } } // In this case, BIBFORMAT::preProcess() adds all the resource elements automatically to the BIBFORMAT::item array... $bibformat->preProcess($resourceType, $entry); // Finally, get the formatted resource string ready for printing to the web browser or exporting to RTF, OpenOffice or plain text $citations.= '
[' . $entry['year'] . ", " . $entry['bibtexEntryType'] . $this->toDownload($entry) . ']
'. $bibformat->map() . "
\n" ; } $citations.= "
"; return $citations; //$entry['bibtexCitation'] } function toDownload($entry) { $string=""; if(array_key_exists('file',$entry)){ $string.= " | ".$this->internalmedia($entry['file']); } if(array_key_exists('url',$entry)){ $string.= " | ".$this->externallink($entry['url'],"www"); } if(array_key_exists('pdf',$entry)){ $string.= " | ".$this->externallink($entry['pdf'],"pdf"); } if(array_key_exists('postscript',$entry)){ $string.= " | ".$this->externallink($entry['postscript'],"ps"); } return $string; } function externallink($url, $name = NULL) { global $conf; $name = $this->_getLinkTitle($name, $url, $isImage); // add protocol on simple short URLs if(substr($url,0,3) == 'ftp' && (substr($url,0,6) != 'ftp://')) $url = 'ftp://'.$url; if(substr($url,0,3) == 'www') $url = 'http://'.$url; if ( !$isImage ) { $class='urlextern'; } else { $class='media'; } //prepare for formating $link['target'] = $conf['target']['extern']; $link['style'] = ''; $link['pre'] = ''; $link['suf'] = ''; $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"'; $link['class'] = $class; $link['url'] = $url; $link['name'] = $name; $link['title'] = $this->_xmlEntities($url); if($conf['relnofollow']) $link['more'] .= ' rel="nofollow"'; list($ext,$mime) = mimetype($url); if(substr($mime,0,15) == 'application/pdf' || substr($mime,0,24) == 'application/octet-stream'){ // add file icons $link['class'] = 'urlextern'; if(@file_exists(DOKU_INC.'lib/images/fileicons/'.$ext.'.png')){ $link['style']='background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$ext.'.png)'; }elseif(@file_exists(DOKU_INC.'lib/images/fileicons/'.$ext.'.gif')){ $link['style']='background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$ext.'.gif)'; }else{ $link['style']='background-image: url('.DOKU_BASE.'lib/images/fileicons/file.gif)'; } //$link['url'] = ml($src,array('id'=>$ID,'cache'=>$cache),true); } //output formatted return $this->_formatLink($link); } function internalmedia ($src, $title=NULL, $align=NULL, $width=NULL, $height=NULL, $cache=NULL, $linking=NULL) { global $conf; global $ID; resolve_mediaid(getNS($ID),$src, $exists); $link = array(); $link['class'] = 'media'; $link['style'] = ''; $link['pre'] = ''; $link['suf'] = ''; $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"'; $link['target'] = $conf['target']['media']; $link['title'] = $this->_xmlEntities($src); list($ext,$mime) = mimetype($src); if(substr($mime,0,5) == 'image'){ // link only jpeg images // if ($ext != 'jpg' && $ext != 'jpeg') $noLink = TRUE; $link['url'] = ml($src,array('id'=>$ID,'cache'=>$cache),($linking=='direct')); }elseif($mime == 'application/x-shockwave-flash'){ // don't link flash movies $noLink = TRUE; }else{ // add file icons $link['class'] = 'urlextern'; if(@file_exists(DOKU_INC.'lib/images/fileicons/'.$ext.'.png')){ $link['style']='background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$ext.'.png)'; }elseif(@file_exists(DOKU_INC.'lib/images/fileicons/'.$ext.'.gif')){ $link['style']='background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$ext.'.gif)'; }else{ $link['style']='background-image: url('.DOKU_BASE.'lib/images/fileicons/file.gif)'; } $link['url'] = ml($src,array('id'=>$ID,'cache'=>$cache),true); } $link['name'] = $this->_media ($src, $title, $align, $width, $height, $cache); //output formatted if ($linking == 'nolink' || $noLink){ return $link['name']; } else { return $this->_formatLink($link); } } function _formatLink($link){ //make sure the url is XHTML compliant (skip mailto) if(substr($link['url'],0,7) != 'mailto:'){ $link['url'] = str_replace('&','&',$link['url']); $link['url'] = str_replace('&amp;','&',$link['url']); } //remove double encodings in titles $link['title'] = str_replace('&amp;','&',$link['title']); $ret = ''; $ret .= $link['pre']; $ret .= ' */ function _getLinkTitle($title, $default, & $isImage, $id=NULL) { global $conf; $isImage = FALSE; if ( is_null($title) ) { if ($conf['useheading'] && $id) { $heading = p_get_first_heading($id); if ($heading) { return $this->_xmlEntities($heading); } } return $this->_xmlEntities($default); } else if ( is_string($title) ) { return $this->_xmlEntities($title); } else if ( is_array($title) ) { $isImage = TRUE; return $this->_imageTitle($title); } } function _xmlEntities($string) { return htmlspecialchars($string); } function _simpleTitle($name){ global $conf; if($conf['useslash']){ $nssep = '[:;/]'; }else{ $nssep = '[:;]'; } $name = preg_replace('!.*'.$nssep.'!','',$name); //if there is a hash we use the ancor name only $name = preg_replace('!.*#!','',$name); return $name; } /** * Renders internal and external media * * @author Andreas Gohr */ function _media ($src, $title=NULL, $align=NULL, $width=NULL, $height=NULL, $cache=NULL) { $ret = ''; list($ext,$mime) = mimetype($src); if(substr($mime,0,5) == 'image'){ //add image tag $ret .= '_xmlEntities($title).'"'; $ret .= ' alt="'.$this->_xmlEntities($title).'"'; }elseif($ext == 'jpg' || $ext == 'jpeg'){ //try to use the caption from IPTC/EXIF require_once(DOKU_INC.'inc/JpegMeta.php'); $jpeg =& new JpegMeta(mediaFN($src)); if($jpeg !== false) $cap = $jpeg->getTitle(); if($cap){ $ret .= ' title="'.$this->_xmlEntities($cap).'"'; $ret .= ' alt="'.$this->_xmlEntities($cap).'"'; } }else{ $ret .= ' alt=""'; } if ( !is_null($width) ) $ret .= ' width="'.$this->_xmlEntities($width).'"'; if ( !is_null($height) ) $ret .= ' height="'.$this->_xmlEntities($height).'"'; $ret .= ' />'; }elseif($mime == 'application/x-shockwave-flash'){ $ret .= '_xmlEntities($width).'"'; if ( !is_null($height) ) $ret .= ' height="'.$this->_xmlEntities($height).'"'; $ret .= '>'.DOKU_LF; $ret .= ''.DOKU_LF; $ret .= ''.DOKU_LF; $ret .= '_xmlEntities($width).'"'; if ( !is_null($height) ) $ret .= ' height="'.$this->_xmlEntities($height).'"'; $ret .= ' type="application/x-shockwave-flash"'. ' pluginspage="http://www.macromedia.com/go/getflashplayer">'.DOKU_LF; $ret .= ''.DOKU_LF; }elseif(!is_null($title)){ // well at least we have a title to display $ret .= $this->_xmlEntities($title); }else{ // just show the sourcename $ret .= $this->_xmlEntities(noNS($src)); } return $ret; } } ?>