diff --git a/bibtexbrowser.php b/bibtexbrowser.php index c535cfe..a0eb1b1 100755 --- a/bibtexbrowser.php +++ b/bibtexbrowser.php @@ -1,6 +1,6 @@ -URL: http://www.monperrus.net/martin/bibtexbrowser/ +URL: http://www.monperrus.net/martin/bibtexbrowser/ Feedback & Bug Reports: martin.monperrus@gmail.com (C) 2013 Matthieu Guillaumin @@ -24,7 +24,7 @@ define('BIBTEXBROWSER','v__GITHUB__'); // you may have bibtexbrowser_configure('ENCODING', 'latin1) in bibtexbrowser.local.php global $CONFIGURATION; $CONFIGURATION = array(); -function bibtexbrowser_configure($key, $value) { +function bibtexbrowser_configure($key, $value) { global $CONFIGURATION; $CONFIGURATION[$key]=$value; } @@ -47,7 +47,7 @@ function bibtexbrowser_configure($key, $value) { // if you don't like it, you can be disable it by adding in bibtexbrowser.local.php // @define('BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT',false); @define('BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT',true); -// if you disable the Javascript progressive enhancement, +// if you disable the Javascript progressive enhancement, // you may want the links to be open in a new window/tab // if yes, add in bibtexbrowser.local.php define('BIBTEXBROWSER_BIB_IN_NEW_WINDOW',true); @define('BIBTEXBROWSER_BIB_IN_NEW_WINDOW',false); @@ -63,21 +63,21 @@ function bibtexbrowser_configure($key, $value) { @define('BIBTEXBROWSER_DEFAULT_TEMPLATE','HTMLTemplate'); // the target frame of menu links -@define('BIBTEXBROWSER_MENU_TARGET','main'); // might be define('BIBTEXBROWSER_MENU_TARGET','_self'); in bibtexbrowser.local.php +@define('BIBTEXBROWSER_MENU_TARGET','main'); // might be define('BIBTEXBROWSER_MENU_TARGET','_self'); in bibtexbrowser.local.php @define('ABBRV_TYPE','index');// may be year/x-abbrv/key/none/index/keys-index //the default view in the "main" (right hand side) frame @define('BIBTEXBROWSER_DEFAULT_FRAME','year=latest'); // year=latest,all and all valid bibtexbrowser queries -// Wrapper to use when we are included by another script +// Wrapper to use when we are included by another script @define('BIBTEXBROWSER_EMBEDDED_WRAPPER', 'NoWrapper'); // Main class to use @define('BIBTEXBROWSER_MAIN', 'Dispatcher'); // default order functions -// Contract Returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal. +// Contract Returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal. // can be @define('ORDER_FUNCTION','compare_bib_entry_by_title'); @define('ORDER_FUNCTION','compare_bib_entry_by_year'); @define('ORDER_FUNCTION_FINE','compare_bib_entry_by_month'); @@ -102,7 +102,7 @@ function bibtexbrowser_configure($key, $value) { // should authors be linked to [none/homepage/resultpage] // none: nothing // their homepage if defined as @strings -// their publication lists according to this bibtex +// their publication lists according to this bibtex @define('BIBTEXBROWSER_AUTHOR_LINKS','homepage'); // BIBTEXBROWSER_LAYOUT defines the HTML rendering layout of the produced HTML @@ -152,7 +152,7 @@ function bibtexbrowser_configure($key, $value) { // in embedded mode, we still need a URL for displaying bibtex entries alone // this is usually resolved to bibtexbrowser.php -// but can be overridden in bibtexbrowser.local.php +// but can be overridden in bibtexbrowser.local.php // for instance with @define('BIBTEXBROWSER_URL',''); // links to the current page with ? @define('BIBTEXBROWSER_URL',basename(__FILE__)); @@ -226,7 +226,7 @@ function _zetDB($bibtex_filenames) { // otherwise it does not work set_magic_quotes_runtime(false); } - + // default bib file, if no file is specified in the query string. if (!isset($bibtex_filenames) || $bibtex_filenames == "") { default_message(); @@ -240,7 +240,7 @@ function _zetDB($bibtex_filenames) { // ---------------------------- HANDLING unexistent files foreach(explode(MULTIPLE_BIB_SEPARATOR, $bibtex_filenames) as $bib) { - + // get file extension to only allow .bib files $ext = pathinfo($bib, PATHINFO_EXTENSION); // this is a security protection @@ -261,13 +261,13 @@ function _zetDB($bibtex_filenames) { // (imagine the number of requests from search engine bots...) $bib_is_unmodified = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ; foreach(explode(MULTIPLE_BIB_SEPARATOR, $bibtex_filenames) as $bib) { - $bib_is_unmodified = - $bib_is_unmodified + $bib_is_unmodified = + $bib_is_unmodified && (strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])>filemtime($bib)); } // end for each - if ( $bib_is_unmodified && !headers_sent()) { + if ( $bib_is_unmodified && !headers_sent()) { header("HTTP/1.1 304 Not Modified"); - exit; + exit; } @@ -278,15 +278,15 @@ function _zetDB($bibtex_filenames) { $compiledbib = 'bibtexbrowser_'.md5($bibtex_filenames).'.dat'; $parse=filemtime(__FILE__)>@filemtime($compiledbib); - + // do we have a compiled version ? - if (is_file($compiledbib) - && is_readable($compiledbib) + if (is_file($compiledbib) + && is_readable($compiledbib) && filesize($compiledbib)>0 ) { $f = fopen($compiledbib,'r+'); // some Unix seem to consider flock as a writing operation //we use a lock to avoid that a call to bibbtexbrowser made while we write the object loads an incorrect object - if (flock($f,LOCK_EX)) { + if (flock($f,LOCK_EX)) { $s = filesize($compiledbib); $ser = fread($f,$s); $db = @unserialize($ser); @@ -297,7 +297,7 @@ function _zetDB($bibtex_filenames) { // do we have an correct version of the file if (!is_a($db,'BibDataBase')) { unlink($compiledbib); - if (BIBTEXBROWSER_DEBUG) { die('$db not a BibDataBase. please reload.'); } + if (BIBTEXBROWSER_DEBUG) { die('$db not a BibDataBase. please reload.'); } $parse=true; } } else {$parse=true;} @@ -309,10 +309,10 @@ function _zetDB($bibtex_filenames) { $db = createBibDataBase(); foreach(explode(MULTIPLE_BIB_SEPARATOR, $bibtex_filenames) as $bib) { $db->load($bib); - } + } } - - $updated = false; + + $updated = false; // now we may update the database if (!file_exists($compiledbib)) { @touch($compiledbib); @@ -326,7 +326,7 @@ function _zetDB($bibtex_filenames) { $updated = true; } } - + // echo var_export($parse); // echo var_export($updated); @@ -337,7 +337,7 @@ function _zetDB($bibtex_filenames) { // we use 'a' because the file is not locked between fopen and flock $f = fopen($compiledbib,'a'); //we use a lock to avoid that a call to bibbtexbrowser made while we write the object loads an incorrect object - if (flock($f,LOCK_EX)) { + if (flock($f,LOCK_EX)) { // echo ''; ftruncate($f,0); fwrite($f,serialize($db)); @@ -347,7 +347,7 @@ function _zetDB($bibtex_filenames) { fclose($f); } // end saving the cached verions //else echo ''; - + return array(&$db, $parse, $updated, $saved); } // end function setDB @@ -405,9 +405,9 @@ notes: - The delegate is expected to have some methods, see classes BibDBBuilder and XMLPrettyPrinter */ class StateBasedBibtexParser { - + var $delegate; - + function StateBasedBibtexParser(&$delegate) { $this->delegate = &$delegate; } @@ -667,7 +667,7 @@ usage: print_r($db->builtdb);// an associated array key -> BibEntry objects print_r($db->stringdb);// an associated array key -> strings representing @string -notes: +notes: method build can be used several times, bibtex entries are accumulated in the builder */ class BibDBBuilder { @@ -683,21 +683,21 @@ class BibDBBuilder { var $currentEntry; function build($bibfilename, $handle = NULL) { - - $this->filename = $bibfilename; + + $this->filename = $bibfilename; if ($handle == NULL) { $handle = fopen($bibfilename, "r"); } if (!$handle) die ('cannot open '.$bibfilename); - + $parser = new StateBasedBibtexParser($this); $parser->parse($handle); fclose($handle); //print_r(array_keys(&$this->builtdb)); //print_r(&$this->builtdb); } - + function getBuiltDb() { //print_r($this->builtdb); @@ -709,7 +709,7 @@ class BibDBBuilder { function endFile() { // resolving crossrefs - // we are careful with PHP 4 semantics + // we are careful with PHP 4 semantics foreach (array_keys($this->builtdb) as $key) { $bib = &$this->builtdb[$key]; if ($bib->hasField('crossref')) { @@ -730,7 +730,7 @@ class BibDBBuilder { } function setEntryField($finalkey,$entryvalue) { - // support for Bibtex concatenation + // support for Bibtex concatenation // see http://newton.ex.ac.uk/tex/pack/bibtex/btxdoc/node3.html // (?currentEntry->timestamp(); - + // we add a key if there is no key if (!$this->currentEntry->hasField(Q_KEY) && $this->currentEntry->getType()!='string') { $this->currentEntry->setField(Q_KEY,md5($this->currentEntry->getTitle().implode('',$this->currentEntry->getRawAuthors()))); } - + // we set the fulltext $this->currentEntry->text = $entrysource; - + // we format the author names in a special field // to enable search if ($this->currentEntry->hasField('author')) { @@ -791,18 +791,18 @@ class BibDBBuilder { // ignoring jabref comments if (($this->currentEntry->getType()=='comment')) { /* do nothing for jabref comments */ - } - + } + // we add it to the string database else if ($this->currentEntry->getType()=='string') { foreach($this->currentEntry->fields as $k => $v) { $k!=Q_INNER_TYPE and $this->stringdb[$k]=new StringEntry($k,$v,$this->filename); } } - + // we add it to the database else { - $this->builtdb[$this->currentEntry->getKey()] = $this->currentEntry; + $this->builtdb[$this->currentEntry->getKey()] = $this->currentEntry; } } } // end class BibDBBuilder @@ -859,14 +859,14 @@ function latex2html($line) { $line = str_replace($k, '__MATH'.$index.'__', $line); $index++; } - + $line = preg_replace('/([^\\\\])~/','\\1 ', $line); // performance increases with this test // bug found by Serge Barral: what happens if we have curly braces only (typically to ensure case in Latex) // added && strpos($line,'{')===false if (strpos($line,'\\')===false && strpos($line,'{')===false) return $line; - + // we should better replace this before the others // in order not to mix with the HTML entities coming after (just in case) $line = str_replace('\\&','&', $line); @@ -889,7 +889,7 @@ function latex2html($line) { $line = char2html($line,"'",'u',"acute"); $line = char2html($line,"'",'y',"acute"); $line = char2html($line,"'",'n',"acute"); - + $line = char2html($line,'`','a',"grave"); $line = char2html($line,'`','e',"grave"); $line = char2html($line,'`','i',"grave"); @@ -928,7 +928,7 @@ function latex2html($line) { $line = str_replace('\\l','ł',$line); $line = str_replace('\\L','Ł',$line); - $line = str_replace('\\k{a}','ą',$line); + $line = str_replace('\\k{a}','ą',$line); // clean out extra tex curly brackets, usually used for preserving capitals $line = str_replace('}','', $line); @@ -946,8 +946,8 @@ function latex2html($line) { function s3988($s) {return urlencode(utf8_encode($s));} /** -see BibEntry->formatAuthor($author) -@deprecated +see BibEntry->formatAuthor($author) +@deprecated @nodoc */ function formatAuthor() { @@ -984,21 +984,21 @@ class BibEntry { /** A timestamp to trace when entries have been created */ var $timestamp; - + /** The name of the file containing this entry */ var $filename; - + /** The short name of the entry (parameterized by ABBRV_TYPE) */ var $abbrv; - + /** The index in a list of publications (e.g. [1] Foo */ var $index = ''; - + /** returns a debug string representation */ function __toString() { return $this->getType()." ".$this->getKey(); } - + /** Creates an empty new bib entry. Each bib entry is assigned a unique * identification number. */ function BibEntry() { @@ -1008,11 +1008,11 @@ class BibEntry { } /** Sets the name of the file containing this entry */ - function setFile($filename) { + function setFile($filename) { $this->filename = $filename; return $this; } - + /** Adds timestamp to this object */ function timestamp() { $this->timestamp = time(); @@ -1042,13 +1042,13 @@ class BibEntry { // we assume that "comment" is never latex code // but instead could contain HTML code (with links using the character "~" for example) // so "comment" is not transformed too - if ($name!='url' && $name!='comment') { - $value = xtrim($value); + if ($name!='url' && $name!='comment') { + $value = xtrim($value); $value = latex2html($value); } else { //echo "xx".$value."xx\n"; } - + $this->fields[$name] = $value; } @@ -1057,10 +1057,10 @@ class BibEntry { // 2009-10-25 added trim // to support space e.g. "@article {" // as generated by ams.org - // thanks to Jacob Kellner + // thanks to Jacob Kellner $this->fields[Q_INNER_TYPE] =trim($value); } - + function setIndex($index) { $this->index = $index; } /** Tries to build a good URL for this entry. The URL should be absolute (better for the generated RSS) */ @@ -1095,7 +1095,7 @@ class BibEntry { return ''; } - /** returns a "[pdf]" link if relevant. modified to exploit the new method, while keeping backward compatibility */ + /** returns a "[pdf]" link if relevant. modified to exploit the new method, while keeping backward compatibility */ function getUrlLink($iconurl = NULL, $label = 'pdf') { if ($this->hasField('url')) { return $this->getLink('url', $iconurl, $label); @@ -1104,7 +1104,7 @@ class BibEntry { return $this->getLink('pdf', $iconurl, $label); } // Adding link to PDF file exported by Zotero - // ref: https://github.com/monperrus/bibtexbrowser/pull/14 + // ref: https://github.com/monperrus/bibtexbrowser/pull/14 if ($this->hasField('file')) { return $this->getLink('file', $iconurl, $label); } @@ -1144,7 +1144,7 @@ class BibEntry { /** replace [$ext] with an icon whose url is defined in a string * e.g. getIconOrTxt('pdf') will print '[pdf]' - * or getIconOrTxt('pdf','http://link/to/icon.png') will use the icon linked by the url, or print '[pdf'] + * or getIconOrTxt('pdf','http://link/to/icon.png') will use the icon linked by the url, or print '[pdf'] * if the url does not point to a valid file (using the "alt" property of the "img" html tag) */ function getIconOrTxt($txt,$iconurl=NULL) { @@ -1232,7 +1232,7 @@ class BibEntry { } return $authors; } - + /** * Returns the formated author name w.r.t to the user preference encoded in COMMA_NAMES */ @@ -1275,26 +1275,26 @@ class BibEntry { * @see getFormattedAuthorsImproved() */ function formattedAuthors() { return $this->getFormattedAuthorsImproved(); } - + /** Adds to getFormattedAuthors() the home page links and returns a string (not an array). Is configured with BIBTEXBROWSER_AUTHOR_LINKS and COMMA_NAMES. */ function getFormattedAuthorsImproved() { $array_authors = $this->getFormattedAuthors(); - + if (BIBTEXBROWSER_AUTHOR_LINKS=='homepage') { foreach ($array_authors as $k => $author) { $array_authors[$k]=$this->addHomepageLink($author); } } - + if (BIBTEXBROWSER_AUTHOR_LINKS=='resultpage') { foreach ($array_authors as $k => $author) { $array_authors[$k]=$this->addAuthorPageLink($author); } } - + if (COMMA_NAMES) {$sep = '; ';} else {$sep = ', ';} - + return implode($sep ,$array_authors); } @@ -1304,7 +1304,7 @@ class BibEntry { return "$author"; } - + /** Returns the authors of this entry as an array in a canonical form */ function getCanonicalAuthors() { $authors = array(); @@ -1335,7 +1335,7 @@ class BibEntry { /** add the link to the homepage if it is defined in a string * e.g. @string{hp_MartinMonperrus="http://www.monperrus.net/martin"} - * The string is a concatenation of firstname, lastname, prefixed by hp_ + * The string is a concatenation of firstname, lastname, prefixed by hp_ * Warning: by convention @string are case sensitive so please be keep the same case as author names * @thanks Eric Bodden for the idea */ @@ -1368,7 +1368,7 @@ class BibEntry { if (COMMA_NAMES) {$sep = '; ';} else {$sep = ', ';} return implode($sep, $editors).', '.(count($editors)>1?'eds.':'ed.'); } - + /** Returns the year of this entry? */ function getYear() { return $this->getField('year'); @@ -1377,11 +1377,11 @@ class BibEntry { /** Returns the value of the given field? */ function getField($name) { // 2010-06-07: profiling showed that this is very costly - // hence returning the value directly + // hence returning the value directly //if ($this->hasField($name)) // {return $this->fields[strtolower($name)];} //else return 'missing '.$name; - + return @$this->fields[strtolower($name)]; } @@ -1391,7 +1391,7 @@ class BibEntry { function getFields() { return $this->fields; } - + /** Returns the raw, undecorated abbreviation depending on ABBRV_TYPE. */ function getRawAbbrv() { if (ABBRV_TYPE == 'index') return $this->index; @@ -1433,12 +1433,12 @@ class BibEntry { /** Returns the verbatim text of this bib entry. */ return $this->text; } - + /** Returns true if this bib entry contains the given phrase (PREG regexp) * in the given field. if $field is null, all fields are considered. * Note that this method is NOT case sensitive */ function hasPhrase($phrase, $field = null) { - + // 2010-01-25 // bug found by jacob kellner // we have to search in the formatted fileds and not in the raw entry @@ -1561,7 +1561,7 @@ class BibEntry { } // referrer, the id of a collection of objects - // see also http://www.openurl.info/registry/docs/pdf/info-sid.pdf + // see also http://www.openurl.info/registry/docs/pdf/info-sid.pdf $url_parts[]='rfr_id='.s3988('info:sid/'.@$_SERVER['HTTP_HOST'].':'.@$_GET[Q_FILE]); $url_parts[]='rft.date='.s3988($this->getYear()); @@ -1619,7 +1619,7 @@ class BibEntry { $s.=$this->getText(); return $s; } - + /** returns the first and last page of the entry as an array ([0]->first, [2]->last) */ function getPages() { preg_match('/([0-9]+).*?([0-9]+)/',$this->getField('pages'),$matches); @@ -1679,7 +1679,7 @@ function bib2links_default(&$bibentry) { } $str .= ''; - + return $str; } @@ -1722,7 +1722,7 @@ function compare_bib_entry_by_mtime($a, $b) /** compares two instances of BibEntry by year */ function compare_bib_entry_by_year($a, $b) -{ +{ return -strcmp($a->getYear(),$b->getYear()); } @@ -1741,14 +1741,14 @@ function compare_bib_entry_by_raw_abbrv($a, $b) } -/** compares two instances of BibEntry by month +/** compares two instances of BibEntry by month * @author Jan Geldmacher */ function compare_bib_entry_by_month($a, $b) -{ +{ // this was the old behavior // return strcmp($a->getKey(),$b->getKey()); - + //bibkey which is used for sorting $sort_key = 'month'; //desired order of values @@ -1775,7 +1775,7 @@ function compare_bib_entry_by_month($a, $b) $val_a = array_search(strtolower($a->fields[$sort_key]), $sort_order_values); $val_b = array_search(strtolower($b->fields[$sort_key]), $sort_order_values); - + if (($val_a === FALSE && $val_b === FALSE) || ($val_a === $val_b)) { //neither a nor b are in the search array or a=b -> both are equal $retval=0; @@ -1787,15 +1787,15 @@ function compare_bib_entry_by_month($a, $b) elseif (($val_b === FALSE) || (($val_a > $val_b))){ //b is not in the search array or a>b -> a is greater $retval=1; - } + } } - + return $order*$retval; } /** is the default sectioning for AcademicDisplay (books, articles, proceedings, etc. ) */ function DefaultBibliographySections() { -return +return array( // Books array( @@ -1850,7 +1850,7 @@ function DefaultBibliographyStyle(&$bibentry) { // usually in bold: .bibtitle { font-weight:bold; } $title = ''.$title.''; if ($bibentry->hasField('url')) $title = ' '.$title.''; - + // author if ($bibentry->hasField('author')) { @@ -1898,7 +1898,7 @@ function DefaultBibliographyStyle(&$bibentry) { if ($type=="techreport") { $publisher = __('Technical report').', '.$bibentry->getField("institution"); } - + if ($type=="misc") { $publisher = $bibentry->getField('howpublished'); } @@ -2038,7 +2038,7 @@ function JanosBibliographyStyle(&$bibentry) { // ---------------------------------------------------------------------- // DISPLAY MANAGEMENT // ---------------------------------------------------------------------- -/** orders two BibEntry as defined by ORDER_FUNCTION +/** orders two BibEntry as defined by ORDER_FUNCTION * (by default compares two instances of BibEntry by year and then month) */ function compare_bib_entries($bib1, $bib2) { @@ -2047,7 +2047,7 @@ function compare_bib_entries($bib1, $bib2) { if ($cmp ==0) { $f2 = ORDER_FUNCTION_FINE; $cmp = $f2($bib1, $bib2); - } + } return $cmp; } @@ -2114,16 +2114,16 @@ usage: */ class IndependentYearMenu { - function IndependentYearMenu() { + function IndependentYearMenu() { if (!isset($_GET[Q_DB])) {die('Did you forget to call setDB() before instantiating this class?');} $yearIndex = $_GET[Q_DB]->yearIndex(); echo '
Year: '; $formatedYearIndex = array(); - $formatedYearIndex[] = ''.*')).'>All'; + $formatedYearIndex[] = ''.*')).'>All'; foreach($yearIndex as $year) { $formatedYearIndex[] = '$year)).'>'.$year.''; } - + // by default the separator is a | echo implode('|',$formatedYearIndex); echo '
'; @@ -2143,13 +2143,13 @@ function poweredby() { /** ^^adds a touch of AJAX in bibtexbrowser to display bibtex entries inline. It uses the HIJAX design pattern: the Javascript code fetches the normal bibtex HTML page and extracts the bibtex. - In other terms, URLs and content are left perfectly optimized for crawlers + In other terms, URLs and content are left perfectly optimized for crawlers Note how beautiful is this piece of code thanks to JQuery.^^ */ function javascript() { // we use jquery with the official content delivery URLs // Microsoft and Google also provide jquery with their content delivery networks -?> +?>