diff --git a/bibtexbrowser.php b/bibtexbrowser.php
index 5c65979..71412af 100755
--- a/bibtexbrowser.php
+++ b/bibtexbrowser.php
@@ -1,284 +1,9 @@
-
-bibtexbrowser is a PHP script that creates publication lists from Bibtex files.
- bibtexbrowser is stable, mature and easy to install. It is used in [[users|60+ different universities]] around the globe.
-
-+++TOC+++
-
-=====Major features=====
-* **(11/2009)** bibtexbrowser generates [[http://www.monperrus.net/martin/accurate+bibliographic+metadata+and+google+scholar|Google Scholar metadata]] so as to improve the visibility of your papers on Google Scholar. Since Google has now [[http://scholar.google.com/intl/en/scholar/inclusion.html|documented this feature]], as of version ≥20100621, Google Scholar Metadata should be completely correct.
-* **(11/2009)** More and more academics use bibliographic software like [[http://www.zotero.org/|Zotero]] or [[http://www.mendeley.com/|Mendeley]]. bibtexbrowser generates [[http://ocoins.info/|COinS]] for automatic import of bibliographic entries with [[http://www.zotero.org/|Zotero]] and [[http://www.mendeley.com/|Mendeley]].
-* **(10/2009)** People can subscribe to the RSS publication feed of an individual or a group so as to being kept up-to-date: bibtexbrowser generates RSS feeds for all queries (simply add &rss at the end of the URL)! [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=monperrus.bib&all&rss|demo]]
-* **(02/2009)** bibtexbrowser can display all entries for an author with an academic style (i.e book, articles, conference, workshop): [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=metrics.bib&academic=Ducasse|demo]]
-* **(05/2008)**: bibtexbrowser can be used to embed a publication list into another page: [[http://www.monperrus.net/martin/|demo]]
-* **(04/2007)**: bibtexbrowser is easy to install: just a single file.
-
-=====Other features=====
-* **(10/2011)** if a bibtex entry contains a field gsid (like Google Scholar ID), bibtexbrowser includes a link [cites] to the cited-by page of Google Scholar (e.g. [[http://scholar.google.com/scholar?cites=15080874515065717592]])
-* **(03/2011)** bibtexbrowser includes a hide/show mechanism for bibtex entries (in Javascript, see configuration variable BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT)
-* **(10/2010)** bibtexbrowser now supports cross-references (Bibtex crossref)
-* **(09/2010)** bibtexbrowser now supports multiple bibtex files (''bibtexbrowser.php?bib=file1.bib;file2.bib'')
-* **(05/2010)** bibtexbrowser adds links to your co-author pages if you define the corresponding @string (see function addHomepageLink)
-* **(01/2010)** bibtexbrowser can handle user-defined bibliographic styles
-* **(10/2009)** bibtexbrowser is able to generate a bibtex file containing only the selected entries (simply add &astext at the end of the link)
-* **(10/2009)** bibtexbrowser is now independent of the configuration of register_globals
-* **(01/2009)** bibtexbrowser allows multi criteria search, e.g. [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=metrics.bib&type=inproceedings&year=2004|demo]]
-* bibtexbrowser replaces constants defined in @STRING
-* bibtexbrowser is very fast because it keeps a compiled version of the bibtex file (PHP object serialized)
-* bibtexbrowser is compatible with PHP 4.x and PHP 5.x
-* bibtexbrowser can display the menu and all entries without filtering from the file name passed as parameter [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=metrics.bib|demo]]
-* bibtexbrowser can display all entries out of a bibtex file [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=metrics.bib&all|demo]]
-* bibtexbrowser can display all entries for a given year [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=metrics.bib&year=2004|demo]]
-* bibtexbrowser can display a single bibtex entry [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=metrics.bib&key=monperrus08d|demo]]
-* bibtexbrowser can display found entries with a search word (it can be in any bib field) [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=metrics.bib&search=ocl|demo]]
-* bibtexbrowser can display all entries with a bib keyword
-* bibtexbrowser outputs valid XHTML 1.0 Transitional
-* bibtexbrowser can display all entries for an author [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=metrics.bib&author=Barbara+A.+Kitchenham|demo]]
-* bibtexbrowser can be used with different encodings (change the default iso-8859-1 encoding if your bib file is in UTF-8 ''define('ENCODING','UTF-8')'' )
-
-
-=====Download=====
-For feature requests, bug reports, or patch proposals, [[http://www.monperrus.net/martin/|please drop me an email ]] or comment this page. Don't hesitate to contact me to be added in the [[users|lists of bibtexbrowser users]] :-)
-
-You may try bibtexbrowser without installation by uploading your bibtex file at [[http://my.publications.li]].
-
-**[[http://www.monperrus.net/martin/bibtexbrowser.php.txt|Download bibtexbrowser]]** (Try the release candidate!)';} ?>
-
-
-=====Demo and screenshot=====
-
-Demo: [[http://www.monperrus.net/martin/bibtexbrowser.php?bib=metrics.bib|Here, you can browse a bibtex file dedicated to software metrics]]
-
-
-
-=====Basic installation=====
-
-Create a bib file with the publication records (e.g. csgroup2008.bib) and upload it to your server.
-* Use the link ''bibtexbrowser.php?bib=csgroup2008.bib'' (frameset based view)
-* Use the link ''bibtexbrowser.php?bib=csgroup2008.bib&all'' (pub list sorted by year)
-* Use the link ''bibtexbrowser.php?bib=csgroup2008.bib&all&academic'' (pub list sorted by publication type, then by year, see "Sectioning in academic mode" below)
-
-** Warning **: bibtexbrowser maintains a cached version of the parsed bibtex, for high performance, check that PHP can write in the working directory of PHP.
-
-**Handling mutliple bibtex files**: If you want to include several bibtex files, just give bibtexbrowser the files separated by semi-columns e.g:
-''bibtexbrowser.php?bib=strings.bib;csgroup2008.bib''
-
-
-
-=====UTF-8 support / ISO-8859-1 support=====
-
-^^By default, bibtexbrowser assumes that the bibtex file is UTF-8 encoded.
-If you want to change it to e.g. ISO-8859-1, add ''define('ENCODING','ISO-8859-1');'' into ''bibtexbrowser.local.php'' (see below).
-Note that if the bibtex only contains latex-encoded diacritics (e.g. ''\'e''), it does not matter.
-^^
-=====How to embed your publication list in your home page=====
-
-
-=====Sectioning in academic mode=====
-
-The default academic mode creates four sections :
-- books
-- articles and book chapters
-- workshop papers (for entries containing "workshop" in the field booktitle)
-- others.
-
-You may create your own one in ''bibtexbrowser.local.php'' (see also "By creating a bibtexbrowser.local.php" below):
-
-
-=====How to tailor bibtexbrowser?=====
-
-====By modifying the CSS====
-
-
-If bibtexbrowser.css exists, it is used, otherwise bibtexbrowser uses its own embedded CSS style (see function bibtexbrowserDefaultCSS). An example of CSS tailoring is:
-
-The bibliography style is encapsulated in a function. If you want to modify the bibliography style, you can copy the default style ([[bibtexbrowser-style-default.php.txt|source]]) in a new file, say ''bibtexbrowser-yourstyle.php'', and rename the function ''DefaultBibliographyStyle'' in say ''MyFancyBibliographyStyle''.
-Then, add in the file ''bibtexbrowser.local.php'' (see below):
-
-<?php
-include( 'bibtexbrowser-yourstyle.php' );
-define('BIBLIOGRAPHYSTYLE','MyFancyBibliographyStyle');
-?>
-
-
-[[http://www.monperrus.net/martin/bibtexbrowser-style-janos.php.txt|Janos Tapolcai contributed with this style, which looks like IEEE references]].
-For contributing with a new style, [[http://www.monperrus.net/martin/|please drop me an email ]]
-
-
-====By creating a bibtexbrowser.local.php====
-
-
-All the variable parts of bibtexbrowser can be modified with a file called ''bibtexbrowser.local.php''.
-
-
-<?php
-// ------------------------------- NOVICE LEVEL
-// if your bibtex file is UTF-8 encodedd
-// define("ENCODING","UTF-8");
-
-// number of bib items per page
-// define('PAGE_SIZE',50);
-
-// disable Javascript progressive enhancement
-// define('BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT',false);
-
-// may be default/year/x-abbrv
-// default => [1] The essence of metamodeling
-// year => [2005] The essence of metamodeling
-// x-abbrv => [SoSyM] The essence of metamodeling if the bibtex entry contains a field x-abbrv
-//define('ABBRV_TYPE','default');
-
-// see the other define(...) in the source, they are all overridable
-
-// ------------------------------- INTERMEDIATE LEVEL
-
-// if you are not satisifed with the default style
-// define('BIBLIOGRAPHYSTYLE','MyFancyBibliographyStyle');
-function MyFancyBibliographyStyle() {
- // see function DefaultBibliographyStyle
-}
-
-// if you are not satisifed with the default sections
-// define('BIBLIOGRAPHYSECTIONS','mySections');
-function mySections() {
-return
- array(
- // Books
- array(
- 'query' => array(Q_TYPE=>'book'),
- 'title' => 'Cool Books'
- ),
- // .. see function DefaultBibliographySections
-);
-}
-
-
-// ------------------------------- EXPERT LEVEL
-// define('BIBTEXBROWSER_URL','path/to/bibtexbrowser.php'); // if bibtexbrowser.php is in another directory in embedded mode
-// define('BIBTEXBROWSER_URL',''); // to get the individual bib pages embedded as well
-
-?>
-
-
-
-
-
-=====How to add links to the slides of a conference/workshop paper?=====
-
-You can simply fill the ''comment'' field of the bib entry with an HTML link:
-
-@inproceedings{foo,
-author="Jean Dupont",
-title="Bibtexbrowser",
-year=2009,
-booktitle="Proceedings of the BIB conference",
-comment={<a href="myslides.pdf">[slides]</a>}
-}
-
-
-This comment field can also be used to add acceptance rates and impact factors.
-
-=====Related tools=====
-
-Old-fashioned:
-[[http://nxg.me.uk/dist/bibhtml/|bibhtml]], [[http://www.litech.org/~wkiri/bib2html/|bib2html]], [[http://ilab.usc.edu/bibTOhtml/|bibtohtml]], [[http://people.csail.mit.edu/rahimi/bibtex/|bibtextohtml]], [[http://www.lri.fr/~filliatr/bibtex2html/|bibtex2html]], [[http://people.csail.mit.edu/mernst/software/bibtex2web.html |bibtex2web]], [[http://strategoxt.org/Stratego/BibtexTools|stratego bibtex module]]
-Unlike them, **bibtexbrowser is dynamic**.i.e.; generates the HTML pages on the fly. Thus, you do not need to regenerate the static HTML files each time the bib file is changed.
-
-Heavyweight:
-[[http://www.rennes.supelec.fr/ren/perso/etotel/PhpBibtexDbMng/|PHP BibTeX Database Manager]], [[http://gforge.inria.fr/projects/bibadmin/|bibadmin]], [[http://artis.imag.fr/Software/Basilic/|basilic]], [[http://phpbibman.sourceforge.net/|phpbibman]], [[http://www.aigaion.nl/|aigaion]], [[http://www.refbase.net/|refbase]], [[http://wikindx.sourceforge.net/|wikindx]], [[http://refdb.sourceforge.net/|refdb]]
-Unlike them, **bibtexbrowser does not need a MySQL database**
-
-
-Main competitor:
-[[http://code.google.com/p/simplybibtex/|SimplyBibtex]] has the same spirit, but the project seems dead since 2006
-
-Misc:
-[[http://www.sat.ltu.se/publications/publications.m|This matlab script is similar]]
-
-=====Copyright=====
-
-This script is a fork from an excellent script of the University of Texas at El Paso.
+
+URL: http://www.monperrus.net/martin/bibtexbrowser/
+Feedback & Bug Reports: martin.monperrus@gmail.com
-(C) 2006-2011 Martin Monperrus
+(C) 2006-2012 Martin Monperrus
(C) 2005-2006 The University of Texas at El Paso / Joel Garcia, Leonardo Ruiz, and Yoonsik Cheon
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -287,8 +12,8 @@ License, or (at your option) any later version.
*/
-// Wednesday, June 01 2011: bug found by Carlos Br�s
-// it should be possible to include( 'bibtexbrowser.php' ); several times in the same script
+// it is be possible to include( 'bibtexbrowser.php' ); several times in the same script
+// added on Wednesday, June 01 2011, bug found by Carlos Bras
if (!defined('BIBTEXBROWSER')) {
// this if block ends at the very end of this file, after all class and function declarations.
define('BIBTEXBROWSER','v__MTIME__');
@@ -303,7 +28,8 @@ define('BIBTEXBROWSER','v__MTIME__');
// change the following parameter
@define('ENCODING','UTF-8');//@define('ENCODING','iso-8859-1');//define('ENCODING','windows-1252');
// number of bib items per page
-@define('PAGE_SIZE',isset($_GET['nopage'])?(preg_match('/^\d+$/',$_GET['nopage'])?$_GET['nopage']:10000):25);
+// we use the same parameter 'num' as Google
+@define('PAGE_SIZE',isset($_GET['num'])?(preg_match('/^\d+$/',$_GET['num'])?$_GET['num']:10000):14);
// bibtexbrowser uses a small piece of Javascript to improve the user experience
// see http://en.wikipedia.org/wiki/Progressive_enhancement
// if you don't like it, you can be disable it by adding in bibtexbrowser.local.php
@@ -318,10 +44,28 @@ define('BIBTEXBROWSER','v__MTIME__');
// can we load bibtex files on external servers?
@define('BIBTEXBROWSER_LOCAL_BIB_ONLY', true);
+// the default view in {SimpleDisplay,AcademicDisplay,RSSDisplay,BibtexDisplay}
+@define('BIBTEXBROWSER_DEFAULT_DISPLAY','SimpleDisplay');
+
// the target frame of menu links
@define('BIBTEXBROWSER_MENU_TARGET','main'); // might be define('BIBTEXBROWSER_MENU_TARGET','_self'); in bibtexbrowser.local.php
-@define('ABBRV_TYPE','default');// may be default/year/x-abbrv
+@define('ABBRV_TYPE','index');// may be year/x-abbrv/key/none/index
+
+// Wrapper to use when we are included by another script
+@define('BIBTEXBROWSER_EMBEDDED_WRAPPER', 'NoWrapper');
+// default order functions
+@define('ORDER_FUNCTION','compare_bib_entry_by_year_and_month');
+// can be @define('ORDER_FUNCTION','compare_bib_entry_by_title');
+
+// only displaying the n newest entries
+@define('BIBTEXBROWSER_NEWEST',5);
+
+// do we add [bibtex] links ?
+// suggested by Sascha Schnepp
+@define('BIBTEXBROWSER_BIBTEX_LINKS',true);
+
+@define('BIBTEXBROWSER_DEBUG',false);
@define('COMMA_NAMES',false);// do have authors in a comma separated form?
@define('TYPES_SIZE',10); // number of entry types per table
@@ -346,6 +90,7 @@ define('BIBTEXBROWSER','v__MTIME__');
@define('Q_RESULT', 'result');
@define('Q_ACADEMIC', 'academic');
@define('Q_DB', 'bibdb');
+@define('Q_LATEST', 'latest');
@define('AUTHOR', 'author');
@define('EDITOR', 'editor');
@define('SCHOOL', 'school');
@@ -379,18 +124,25 @@ define('BIBTEXBROWSER','v__MTIME__');
@error_reporting(/*pp4php:serl*/E_ALL/*lres*/);
-/** parses $_GET[Q_FILE] and puts the result (an object of type BibDataBase)
- * in $_GET[Q_DB]
- * See also zetDB()
+/** parses $_GET[Q_FILE] and puts the result (an object of type BibDataBase) in $_GET[Q_DB].
+See also zetDB().
*/
function setDB() {
- $_GET[Q_DB] = zetDB($_GET[Q_FILE]);
+ list($db, $parsed, $updated, $saved) = _zetDB(@$_GET[Q_FILE]);
+ $_GET[Q_DB] = $db;
+ return $updated;
}
-/** parses the $bibtex_filenames (usually semi-column separated) and returns an object of type BibDataBase
- * See also setDB()
- */
+/** parses the $bibtex_filenames (usually semi-column separated) and returns an object of type BibDataBase.
+See also setDB()
+*/
function zetDB($bibtex_filenames) {
+ list($db, $parsed, $updated, $saved) = _zetDB($bibtex_filenames);
+ return $db;
+}
+
+/** @nodoc */
+function _zetDB($bibtex_filenames) {
$db = null;
// Check if magic_quotes_runtime is active
@@ -459,11 +211,25 @@ function zetDB($bibtex_filenames) {
$parse=false;
foreach(explode(MULTIPLE_BIB_SEPARATOR, $bibtex_filenames) as $bib) {
// do we have a compiled version ?
- if (is_file($compiledbib) && is_readable($compiledbib)) {
- $db = @unserialize(file_get_contents($compiledbib));
+ if (is_file($compiledbib)
+ && is_readable($compiledbib)
+ && filesize($compiledbib)>0
+ ) {
+
+ $f = fopen($compiledbib,'r');
+ //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)) {
+ $s = filesize($compiledbib);
+ $ser = fread($f,$s);
+ $db = @unserialize($ser);
+ flock($f,LOCK_UN);
+ } else { die('could not get the lock'); }
+ fclose($f);
// basic test
// 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.'); }
$parse=true;
}
} else {$parse=true;}
@@ -473,255 +239,310 @@ function zetDB($bibtex_filenames) {
if ($parse) {
//echo '';
// then parsing the file
- $db = new BibDataBase();
- foreach(explode(MULTIPLE_BIB_SEPARATOR, $bibtex_filenames) as $bib) {
+ $db = createBibDataBase();
+ foreach(explode(MULTIPLE_BIB_SEPARATOR, $bibtex_filenames) as $bib) {
$db->load($bib);
}
}
+ $updated = false;
// now we may update the database
- foreach(explode(MULTIPLE_BIB_SEPARATOR, $bibtex_filenames) as $bib) {
+ if (!file_exists($compiledbib)) {
+ @touch($compiledbib);
+ $updated = true; // limit case
+ } else foreach(explode(MULTIPLE_BIB_SEPARATOR, $bibtex_filenames) as $bib) {
// is it up to date ? wrt to the bib file and the script
// then upgrading with a new version of bibtexbrowser triggers a new compilation of the bib file
if (filemtime($bib)>filemtime($compiledbib) || filemtime(__FILE__)>filemtime($compiledbib)) {
+ //echo "updating...";
$db->update($bib);
+ $updated = true;
}
}
-
+
+ //echo var_export($parse);
+ //echo var_export($updated);
+
+ $saved = false;
// are we able to save the compiled version ?
// note that the compiled version is saved in the current working directory
- if ((!is_file($compiledbib) && is_writable(getcwd())) || (is_file($compiledbib) && is_writable($compiledbib)) ) {
- // we can use file_put_contents
- // but don't do it for compatibility with PHP 4.3
- $f = fopen($compiledbib,'w');
+ if ( ($parse || $updated ) && is_writable($compiledbib)) {
+ // 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)) fwrite($f,serialize($db));
+ if (flock($f,LOCK_EX)) {
+// echo '';
+ ftruncate($f,0);
+ fwrite($f,serialize($db));
+ flock($f,LOCK_UN);
+ $saved = true;
+ } else { die('could not get the lock'); }
fclose($f);
} // end saving the cached verions
//else echo '';
- return $db;
-} // end function setDB
+ return array(&$db, $parse, $updated, $saved);
+} // end function setDB
+// factories
+// may be overridden in bibtexbrowser.local.php
+if (!function_exists('createBibDataBase')) {
+ /** factory method for openness @nodoc */
+ function createBibDataBase() { $x = new BibDataBase(); return $x;}
+}
+if (!function_exists('createBibEntry')) {
+ /** factory method for openness @nodoc */
+ function createBibEntry() { $x = new BibEntry(); return $x;}
+}
+if (!function_exists('createBibDBBuilder')) {
+ /** factory method for openness @nodoc */
+ function createBibDBBuilder() { $x = new BibDBBuilder(); return $x;}
+}
+if (!function_exists('createBasicDisplay')) {
+ /** factory method for openness @nodoc */
+ function createBasicDisplay() { $x = new SimpleDisplay(); return $x;}
+}
+if (!function_exists('createBibEntryDisplay')) {
+ /** factory method for openness @nodoc */
+ function createBibEntryDisplay() { $x = new BibEntryDisplay(); return $x;}
+}
+if (!function_exists('createMenuManager')) {
+ /** factory method for openness @nodoc */
+ function createMenuManager() { $x = new MenuManager(); return $x;}
+}
////////////////////////////////////////////////////////
-/** This class is a generic parser of bibtex files
- * It has no dependencies, i.e. it can be used outside of bibtexbrowser
- * To use it, simply instantiate it and pass it an object that will receive semantic events
- * The delegate is expected to have some methods
- * see classes BibDBBuilder and XMLPrettyPrinter
+/** is a generic parser of bibtex files.
+usage:
+
+ $delegate = new XMLPrettyPrinter();// or another delegate such as BibDBBuilder
+ $parser = new StateBasedBibtexParser($delegate);
+ $parser->parse('foo.bib');
+
+notes:
+ - It has no dependencies, it can be used outside of bibtexbrowser
+ - The delegate is expected to have some methods, see classes BibDBBuilder and XMLPrettyPrinter
*/
class StateBasedBibtexParser {
+
+ var $delegate;
+
+ function StateBasedBibtexParser(&$delegate) {
+ $this->delegate = &$delegate;
+ }
+
+ function parse($bibfilename) {
+ $delegate = &$this->delegate;
+ // STATE DEFINITIONS
+ @define('NOTHING',1);
+ @define('GETTYPE',2);
+ @define('GETKEY',3);
+ @define('GETVALUE',4);
+ @define('GETVALUEDELIMITEDBYQUOTES',5);
+ @define('GETVALUEDELIMITEDBYQUOTES_ESCAPED',6);
+ @define('GETVALUEDELIMITEDBYCURLYBRACKETS',7);
+ @define('GETVALUEDELIMITEDBYCURLYBRACKETS_ESCAPED',8);
+ @define('GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL',9);
+ @define('GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL_ESCAPED',10);
+ @define('GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL',11);
+ @define('GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL_ESCAPED',12);
+ @define('GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL',13);
+ @define('GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL_ESCAPED',14);
+
+
+ $state=NOTHING;
+ $entrytype='';
+ $entrykey='';
+ $entryvalue='';
+ $finalkey='';
+ $entrysource='';
+
+ // metastate
+ $isinentry = false;
+
+ $delegate->beginFile();
+
+ $handle = fopen($bibfilename, "r");
+ if (!$handle) die ('cannot open '.$bibfilename);
+ // if you encounter this error "Allowed memory size of xxxxx bytes exhausted"
+ // then decrease the size of the temp buffer below
+ $bufsize=BUFFERSIZE;
+ while (!feof($handle)) {
+ $sread=fread($handle,$bufsize);
+ //foreach(str_split($sread) as $s) {
+ for ( $i=0; $i < strlen( $sread ); $i++) { $s=$sread[$i];
+
+ if ($isinentry) $entrysource.=$s;
+
+ if ($state==NOTHING) {
+ // this is the beginning of an entry
+ if ($s=='@') {
+ $delegate->beginEntry();
+ $state = GETTYPE;
+ $isinentry = true;
+ $entrysource='@';
+ }
+ }
-function StateBasedBibtexParser($bibfilename, &$delegate) {
-
-
-// STATE DEFINITIONS
-@define('NOTHING',1);
-@define('GETTYPE',2);
-@define('GETKEY',3);
-@define('GETVALUE',4);
-@define('GETVALUEDELIMITEDBYQUOTES',5);
-@define('GETVALUEDELIMITEDBYQUOTES_ESCAPED',6);
-@define('GETVALUEDELIMITEDBYCURLYBRACKETS',7);
-@define('GETVALUEDELIMITEDBYCURLYBRACKETS_ESCAPED',8);
-@define('GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL',9);
-@define('GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL_ESCAPED',10);
-@define('GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL',11);
-@define('GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL_ESCAPED',12);
-@define('GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL',13);
-@define('GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL_ESCAPED',14);
-
-
-$state=NOTHING;
-$entrytype='';
-$entrykey='';
-$entryvalue='';
-$finalkey='';
-$entrysource='';
-
-// metastate
-$isinentry = false;
-
-$delegate->beginFile();
-
-$handle = fopen($bibfilename, "r");
-if (!$handle) die ('cannot open '.$bibfilename);
-// if you encounter this error "Allowed memory size of xxxxx bytes exhausted"
-// then decrease the size of the temp buffer below
-$bufsize=BUFFERSIZE;
-while (!feof($handle)) {
-$sread=fread($handle,$bufsize);
-//foreach(str_split($sread) as $s) {
-for ( $i=0; $i < strlen( $sread ); $i++) { $s=$sread[$i];
-
- if ($isinentry) $entrysource.=$s;
-
- if ($state==NOTHING) {
- // this is the beginning of an entry
- if ($s=='@') {
- $delegate->beginEntry();
- $state = GETTYPE;
- $isinentry = true;
- $entrysource='@';
- }
- }
+ else if ($state==GETTYPE) {
+ // this is the beginning of a key
+ if ($s=='{') {
+ $state = GETKEY;
+ $delegate->setEntryType($entrytype);
+ $entrytype='';
+ }
+ else $entrytype=$entrytype.$s;
+ }
+
+ else if ($state==GETKEY) {
+ // now we get the value
+ if ($s=='=') {
+ $state = GETVALUE;
+ $finalkey=$entrykey;
+ $entrykey='';}
+ // oups we only have the key :-) anyway
+ else if ($s=='}') {
+ $state = NOTHING;$isinentry = false;$delegate->endEntry($entrysource);
+ $entrykey='';
+ }
+ // OK now we look for values
+ else if ($s==',') {
+ $state=GETKEY;
+ $delegate->setEntryKey($entrykey);
+ $entrykey='';}
+ else { $entrykey=$entrykey.$s; }
+ }
+ // we just got a =, we can now receive the value, but we don't now whether the value
+ // is delimited by curly brackets, double quotes or nothing
+ else if ($state==GETVALUE) {
- else if ($state==GETTYPE) {
- // this is the beginning of a key
- if ($s=='{') {
- $state = GETKEY;
- $delegate->setEntryType($entrytype);
- $entrytype='';
- }
- else $entrytype=$entrytype.$s;
- }
+ // the value is delimited by double quotes
+ if ($s=='"') {
+ $state = GETVALUEDELIMITEDBYQUOTES;
+ }
+ // the value is delimited by curly brackets
+ else if ($s=='{') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS;
+ }
+ // the end of the key and no value found: it is the bibtex key e.g. \cite{Descartes1637}
+ else if ($s==',') {
+ $state = GETKEY;
+ $delegate->setEntryField(trim($finalkey),$entryvalue);
+ $entryvalue=''; // resetting the value buffer
+ }
+ // this is the end of the value AND of the entry
+ else if ($s=='}') {
+ $state = NOTHING;
+ $delegate->setEntryField(trim($finalkey),$entryvalue);
+ $isinentry = false;$delegate->endEntry($entrysource);
+ $entryvalue=''; // resetting the value buffer
+ }
+ else if ($s==' ' || $s=="\t" || $s=="\n" || $s=="\r" ) {
+ // blank characters are not taken into account when values are not in quotes or curly brackets
+ }
+ else { $entryvalue=$entryvalue.$s;}
+ }
- else if ($state==GETKEY) {
- // now we get the value
- if ($s=='=') {
- $state = GETVALUE;
- $finalkey=$entrykey;
- $entrykey='';}
- // oups we only have the key :-) anyway
- else if ($s=='}') {
- $state = NOTHING;$isinentry = false;$delegate->endEntry($entrysource);
- $entrykey='';
- }
- // OK now we look for values
- else if ($s==',') {
- $state=GETKEY;
- $delegate->setEntryKey($entrykey);
- $entrykey='';}
- else { $entrykey=$entrykey.$s; }
- }
- // we just got a =, we can now receive the value, but we don't now whether the value
- // is delimited by curly brackets, double quotes or nothing
- else if ($state==GETVALUE) {
-
- // the value is delimited by double quotes
- if ($s=='"') {
- $state = GETVALUEDELIMITEDBYQUOTES;
- }
- // the value is delimited by curly brackets
- else if ($s=='{') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS;
- }
- // the end of the key and no value found: it is the bibtex key e.g. \cite{Descartes1637}
- else if ($s==',') {
- $state = GETKEY;
- $delegate->setEntryField(trim($finalkey),$entryvalue);
- $entryvalue=''; // resetting the value buffer
- }
- // this is the end of the value AND of the entry
- else if ($s=='}') {
- $state = NOTHING;
- $delegate->setEntryField(trim($finalkey),$entryvalue);
- $isinentry = false;$delegate->endEntry($entrysource);
- $entryvalue=''; // resetting the value buffer
- }
- else if ($s==' ' || $s=="\t" || $s=="\n" || $s=="\r" ) {
- // blank characters are not taken into account when values are not in quotes or curly brackets
- }
- else { $entryvalue=$entryvalue.$s;}
- }
-
-
-/* GETVALUEDELIMITEDBYCURLYBRACKETS* handle entries delimited by curly brackets and the possible nested curly brackets */
- else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS) {
-
- if ($s=='\\') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_ESCAPED;
- $entryvalue=$entryvalue.$s;}
- else if ($s=='{') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
- else if ($s=='}') {
- $state = GETVALUE;}
- else { $entryvalue=$entryvalue.$s;}
- }
- // handle anti-slashed brackets
- else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_ESCAPED) {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS;
- $entryvalue=$entryvalue.$s;
- }
- // in first level of curly bracket
- else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL) {
- if ($s=='\\') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL_ESCAPED;
- $entryvalue=$entryvalue.$s;}
- else if ($s=='{') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
- else if ($s=='}') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS;$entryvalue=$entryvalue.$s;}
- else { $entryvalue=$entryvalue.$s;}
- }
- // handle anti-slashed brackets
- else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL_ESCAPED) {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL;
- $entryvalue=$entryvalue.$s;
- }
-
- // in second level of curly bracket
- else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL) {
- if ($s=='\\') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL_ESCAPED;
- $entryvalue=$entryvalue.$s;}
- else if ($s=='{') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
- else if ($s=='}') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
- else { $entryvalue=$entryvalue.$s;}
- }
- // handle anti-slashed brackets
- else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL_ESCAPED) {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL;
- $entryvalue=$entryvalue.$s;
- }
-
- // in third level of curly bracket
- else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL) {
- if ($s=='\\') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL_ESCAPED;
- $entryvalue=$entryvalue.$s;}
- else if ($s=='}') {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
- else { $entryvalue=$entryvalue.$s;}
- }
- // handle anti-slashed brackets
- else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL_ESCAPED) {
- $state = GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL;
- $entryvalue=$entryvalue.$s;
- }
-/* handles entries delimited by double quotes */
- else if ($state==GETVALUEDELIMITEDBYQUOTES) {
+ /* GETVALUEDELIMITEDBYCURLYBRACKETS* handle entries delimited by curly brackets and the possible nested curly brackets */
+ else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS) {
- if ($s=='\\') {
- $state = GETVALUEDELIMITEDBYQUOTES_ESCAPED;
- $entryvalue=$entryvalue.$s;}
- else if ($s=='"') {
- $state = GETVALUE;
- }
- else { $entryvalue=$entryvalue.$s;}
- }
- // handle anti-double quotes
- else if ($state==GETVALUEDELIMITEDBYQUOTES_ESCAPED) {
- $state = GETVALUEDELIMITEDBYQUOTES;
- $entryvalue=$entryvalue.$s;
- }
+ if ($s=='\\') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_ESCAPED;
+ $entryvalue=$entryvalue.$s;}
+ else if ($s=='{') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
+ else if ($s=='}') {
+ $state = GETVALUE;}
+ else { $entryvalue=$entryvalue.$s;}
+ }
+ // handle anti-slashed brackets
+ else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_ESCAPED) {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS;
+ $entryvalue=$entryvalue.$s;
+ }
+ // in first level of curly bracket
+ else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL) {
+ if ($s=='\\') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL_ESCAPED;
+ $entryvalue=$entryvalue.$s;}
+ else if ($s=='{') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
+ else if ($s=='}') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS;$entryvalue=$entryvalue.$s;}
+ else { $entryvalue=$entryvalue.$s;}
+ }
+ // handle anti-slashed brackets
+ else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL_ESCAPED) {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL;
+ $entryvalue=$entryvalue.$s;
+ }
+
+ // in second level of curly bracket
+ else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL) {
+ if ($s=='\\') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL_ESCAPED;
+ $entryvalue=$entryvalue.$s;}
+ else if ($s=='{') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
+ else if ($s=='}') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_1NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
+ else { $entryvalue=$entryvalue.$s;}
+ }
+ // handle anti-slashed brackets
+ else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL_ESCAPED) {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL;
+ $entryvalue=$entryvalue.$s;
+ }
+
+ // in third level of curly bracket
+ else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL) {
+ if ($s=='\\') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL_ESCAPED;
+ $entryvalue=$entryvalue.$s;}
+ else if ($s=='}') {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_2NESTEDLEVEL;$entryvalue=$entryvalue.$s;}
+ else { $entryvalue=$entryvalue.$s;}
+ }
+ // handle anti-slashed brackets
+ else if ($state==GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL_ESCAPED) {
+ $state = GETVALUEDELIMITEDBYCURLYBRACKETS_3NESTEDLEVEL;
+ $entryvalue=$entryvalue.$s;
+ }
+
+ /* handles entries delimited by double quotes */
+ else if ($state==GETVALUEDELIMITEDBYQUOTES) {
+
+ if ($s=='\\') {
+ $state = GETVALUEDELIMITEDBYQUOTES_ESCAPED;
+ $entryvalue=$entryvalue.$s;}
+ else if ($s=='"') {
+ $state = GETVALUE;
+ }
+ else { $entryvalue=$entryvalue.$s;}
+ }
+ // handle anti-double quotes
+ else if ($state==GETVALUEDELIMITEDBYQUOTES_ESCAPED) {
+ $state = GETVALUEDELIMITEDBYQUOTES;
+ $entryvalue=$entryvalue.$s;
+ }
-} // end for
-} // end while
-$delegate->endFile();
-fclose($handle);
-} // end function
+ } // end for
+ } // end while
+ $delegate->endFile();
+ fclose($handle);
+ //$d = &$this->delegate;print_r($d);
+ } // end function
} // end class
-/** This class can be used together with StateBasedBibParser */
+/** is a delegate for StateBasedBibParser.
+usage:
+see snippet of [[#StateBasedBibParser]]
+*/
class XMLPrettyPrinter {
function beginFile() {
header('Content-type: text/xml;');
@@ -754,23 +575,49 @@ class XMLPrettyPrinter {
}
} // end class XMLPrettyPrinter
-/** This class can be used together with StateBasedBibParser */
+/** builds arrays of BibEntry objects from a bibtex file.
+usage:
+
+ $empty_array = array();
+ $db = new BibDBBuilder(); // see also factory method createBibDBBuilder
+ $db->build('foo.bib'); // parses foo.bib
+ print_r($db->builtdb);// an associated array key -> BibEntry objects
+ print_r($db->stringdb);// an associated array key -> strings representing @string
+
+notes:
+ method build can be used several times, bibtex entries are accumulated in the builder
+*/
class BibDBBuilder {
/** A hashtable from keys to bib entries (BibEntry). */
- var $builtdb;
+ var $builtdb = array();
/** A hashtable of constant strings */
- var $stringdb;
+ var $stringdb = array();
+
+ var $filename;
var $currentEntry;
- function BibDBBuilder($filename, &$builtdb, &$stringdb) {
+ function setData(&$builtdb, &$stringdb) {
$this->builtdb = $builtdb;
$this->stringdb = $stringdb;
- new StateBasedBibtexParser($filename, $this);
+ return $this;
+ }
+
+ function build($filename) {
+ $this->filename = $filename;
+ $parser = new StateBasedBibtexParser($this);
+ $parser->parse($filename);
+ //print_r(array_keys(&$this->builtdb));
+ //print_r(&$this->builtdb);
}
+
+ function getBuiltDb() {
+ //print_r($this->builtdb);
+ return $this->builtdb;
+ }
function beginFile() {
}
@@ -794,6 +641,7 @@ class BibDBBuilder {
}
}
}
+ //print_r($this->builtdb);
}
function setEntryField($finalkey,$entryvalue) {
@@ -832,7 +680,8 @@ class BibDBBuilder {
}
function beginEntry() {
- $this->currentEntry = new BibEntry();
+ $this->currentEntry = createBibEntry();
+ $this->currentEntry->setFile($this->filename);
}
function endEntry($entrysource) {
@@ -871,8 +720,7 @@ class BibDBBuilder {
-/** extended version of the trim function
- * removes linebreaks, tabs, etc.
+/** is an extended version of the trim function, removes linebreaks, tabs, etc.
*/
function xtrim($line) {
$line = trim($line);
@@ -890,10 +738,9 @@ function xtrim($line) {
return $line;
}
-/** encapsulates the conversion of a single latex chars to the corresponding HTML entity
- * this works thanks to the regularity of html entities
- * it expects a **lower** char
- */
+/** encapsulates the conversion of a single latex chars to the corresponding HTML entity.
+It expects a **lower-case** char.
+*/
function char2html($line,$latexmodifier,$char,$entitiyfragment) {
$line = str_replace('\\'.$latexmodifier.$char,'&'.$char.''.$entitiyfragment.';', $line);
$line = str_replace('\\'.$latexmodifier.'{'.$char.'}','&'.$char.''.$entitiyfragment.';', $line);
@@ -902,10 +749,8 @@ function char2html($line,$latexmodifier,$char,$entitiyfragment) {
return $line;
}
-/** converts latex chars to HTML entities
- * it uses a naive algortihm
- * I still look for a comprehensive translation table from late chars to html
- * just have this http://isdc.unige.ch/Newsletter/help.html
+/** converts latex chars to HTML entities.
+(I still look for a comprehensive translation table from late chars to html, better than [[http://isdc.unige.ch/Newsletter/help.html]])
*/
function latex2html($line) {
$line = preg_replace('/([^\\\\])~/','\\1 ', $line);
@@ -980,10 +825,14 @@ function latex2html($line) {
return $line;
}
-/** Note that & are encoded as %26 and not as & so it does not break the Z3988 URL */
+/** encodes strings for Z3988 URLs. Note that & are encoded as %26 and not as &. */
function s3988($s) {return urlencode(utf8_encode($s));}
-/** @deprecated */
+/**
+see BibEntry->formatAuthor($author)
+@deprecated
+@nodoc
+*/
function formatAuthor() {
die('Sorry, this function does not exist anymore, however, you can simply use $bibentry->formatAuthor($author) instead.');
}
@@ -992,9 +841,16 @@ function formatAuthor() {
// BIB ENTRIES
// ----------------------------------------------------------------------
-/**
- * Class to represent a bibliographic entry.
- */
+/** represents a bibliographic entry.
+usage:
+
+notes:
+- BibEntry are usually obtained with getEntryByKey or multisearch
+*/
class BibEntry {
/** The fields (fieldName -> value) of this bib entry. */
@@ -1012,6 +868,15 @@ 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 = '';
+
/** Creates an empty new bib entry. Each bib entry is assigned a unique
* identification number. */
function BibEntry() {
@@ -1020,6 +885,12 @@ class BibEntry {
$this->text ='';
}
+ /** Sets the name of the file containing this entry */
+ function setFile($filename) {
+ $this->filename = $filename;
+ return $this;
+ }
+
/** Adds timestamp to this object */
function setTimestamp() {
$this->timestamp = time();
@@ -1038,8 +909,6 @@ class BibEntry {
/** Sets the key of this bib entry. */
function setKey($value) {
$this->setField('key',$value);
- // by default the ID is the key
- $this->id = $value;
}
/** Sets a field of this bib entry. */
@@ -1067,6 +936,8 @@ class BibEntry {
// thanks to Jacob Kellner
$this->fields[Q_TYPE] =trim($value);
}
+
+ function setIndex($index) { $this->index = $index; }
/** Tries to build a good URL for this entry */
function getURL() {
@@ -1074,7 +945,9 @@ class BibEntry {
$f = BIBTEXBROWSER_URL_BUILDER;
return $f($this);
}
- return BIBTEXBROWSER_URL.'?'.createQueryString(array('key'=>$this->getKey()));
+// echo $this->filename;
+// echo $this->getKey();
+ return BIBTEXBROWSER_URL.'?'.createQueryString(array('key'=>$this->getKey(), Q_FILE=>$this->filename));
}
/** Tries to build a good absolute URL for this entry */
@@ -1098,6 +971,14 @@ class BibEntry {
else return '';
}
+ /**
+ * Returns the last name of an author name.
+ */
+ function getLastName($author){
+ list($firstname, $lastname) = splitFullName($author);
+ return $lastname;
+ }
+
/** Has this entry the given field? */
function hasField($name) {
@@ -1304,29 +1185,29 @@ class BibEntry {
function getFields() {
return $this->fields;
}
-
- /** Returns the identification number. */
- function getId() {
- return $this->id;
- }
-
+
/** Returns the abbreviation. */
function getAbbrv() {
- if (ABBRV_TYPE == 'default') return $this->id;
- if (ABBRV_TYPE == 'year') return $this->getYear();
+ if (ABBRV_TYPE == 'index') return $this->index;
+ if (ABBRV_TYPE == 'none') return '';
+ if (ABBRV_TYPE == 'key') return '['.$this->getKey().']';
+ if (ABBRV_TYPE == 'year') return '['.$this->getYear().']';
if (ABBRV_TYPE == 'x-abbrv') {
if ($this->hasField('x-abbrv')) {return $this->getField('x-abbrv');}
- // otherwise
- return $this->getKey();
- }
+ return $this->abbrv;
+ }
- die('Unknown configuration value for ABBRV_TYPE');
+ // otherwise it is a user-defined function in bibtexbrowser.local.php
+ $f = ABBRV_TYPE;
+ return $f($this);
}
/** Sets the abbreviation (e.g. [OOPSLA] or [1]) */
function setAbbrv($abbrv) {
- return $this->id = $abbrv;
+ //if (!is_string($abbrv)) { throw new Exception('Illegal argument'); }
+ $this->abbrv = $abbrv;
+ return $this;
}
function getText() {
@@ -1363,16 +1244,21 @@ class BibEntry {
*/
function toTR() {
echo '
';
- echo '
['.$this->getAbbrv().']
';
+ echo '
';
+ //echo '';
+
+ echo $this->getAbbrv().'
';
echo '
';
echo bib2html($this);
$href = 'href="'.$this->getURL().'"';
- // we add biburl and title to be able to retrieve this important information
- // using Xpath expressions on the XHTML source
- echo " getKey()."\" {$href}>[bib]";
-
+ if (BIBTEXBROWSER_BIBTEX_LINKS) {
+ // we add biburl and title to be able to retrieve this important information
+ // using Xpath expressions on the XHTML source
+ echo " getKey()."\" {$href}>[bibtex]";
+ }
+
// returns an empty string if no url present
echo $this->getUrlLink();
@@ -1384,11 +1270,7 @@ class BibEntry {
if ($this->hasField('gsid')) {
echo ' [cites]';
}
-
-
echo "
\n";
-
-
}
/** Outputs an coins URL: see http://ocoins.info/cobg.html
@@ -1440,8 +1322,8 @@ class BibEntry {
}
// referrer, the id pf a collection of objects
- // 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]);
+ // 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());
@@ -1504,18 +1386,41 @@ function bib2html(&$bibentry) {
return $function($bibentry);
}
-/**bibtexbrowser uses this function which encapsulates the user-defined sections*/
+/** encapsulates the user-defined sections. @nodoc */
function _DefaultBibliographySections() {
$function = BIBLIOGRAPHYSECTIONS;
return $function();
}
+/** compares two instances of BibEntry by modification time
+ */
+function compare_bib_entry_by_mtime($a, $b)
+{
+ return -($a->getTimestamp()-$b->getTimestamp());
+}
+
+/** compares two instances of BibEntry by year
+ */
+function compare_bib_entry_by_year_and_month($a, $b)
+{
+ $year_cmp = -strcmp($a->getYear(),$b->getYear());
+ if ($year_cmp==0) { return compare_bib_entry_by_month($a, $b);}
+ return $year_cmp;
+}
+
+/** compares two instances of BibEntry by title
+ */
+function compare_bib_entry_by_title($a, $b)
+{
+ return strcmp($a->getTitle(),$b->getTitle());
+}
-/** 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());
@@ -1546,15 +1451,15 @@ 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)) {
+ 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;
}
- elseif (($val_a == FALSE) || ($val_a < $val_b)) {
+ elseif (($val_a === FALSE) || ($val_a < $val_b)) {
//a is not in the search array or a b is greater
$retval=-1;
}
- elseif (($val_b == FALSE) || (($val_a > $val_b))){
+ elseif (($val_b === FALSE) || (($val_a > $val_b))){
//b is not in the search array or a>b -> a is greater
$retval=1;
}
@@ -1563,7 +1468,7 @@ function compare_bib_entry_by_month($a, $b)
return $order*$retval;
}
-/** the default sections */
+/** is the default sectioning for AcademicDisplay (books, articles, proceedings, etc. ) */
function DefaultBibliographySections() {
return
array(
@@ -1596,7 +1501,206 @@ return
}
-include('bibtexbrowser-style-default.php');
+/** transforms a $bibentry into an HTML string.
+ It is called by function bib2html if the user did not choose a specific style
+ the default usable CSS styles are
+ .bibtitle { font-weight:bold; }
+ .bibbooktitle { font-style:italic; }
+ .bibauthor { }
+ .bibpublisher { }
+*/
+function DefaultBibliographyStyle(&$bibentry) {
+ $title = $bibentry->getTitle();
+ $type = $bibentry->getType();
+
+ // later on, all values of $entry will be joined by a comma
+ $entry=array();
+
+ // title
+ // usually in bold: .bibtitle { font-weight:bold; }
+ $title = ''.$title.'';
+ if ($bibentry->hasField('url')) $title = ' '.$title.'';
+
+
+ // author
+ if ($bibentry->hasField('author')) {
+ $coreInfo = $title . ' ('.$bibentry->getFormattedAuthorsImproved().')';}
+ else $coreInfo = $title;
+
+ // core info usually contains title + author
+ $entry[] = $coreInfo;
+
+ // now the book title
+ $booktitle = '';
+ if ($type=="inproceedings") {
+ $booktitle = 'In '.$bibentry->getField(BOOKTITLE); }
+ if ($type=="incollection") {
+ $booktitle = 'Chapter in '.$bibentry->getField(BOOKTITLE);}
+ if ($type=="inbook") {
+ $booktitle = 'Chapter in '.$bibentry->getField('chapter');}
+ if ($type=="article") {
+ $booktitle = 'In '.$bibentry->getField("journal");}
+
+ //// we may add the editor names to the booktitle
+ $editor='';
+ if ($bibentry->hasField(EDITOR)) {
+ $editor = $bibentry->getFormattedEditors();
+ }
+ if ($editor!='') $booktitle .=' ('.$editor.')';
+ // end editor section
+
+ // is the booktitle available
+ if ($booktitle!='') {
+ $entry[] = ''.$booktitle.'';
+ }
+
+
+ $publisher='';
+ if ($type=="phdthesis") {
+ $publisher = 'PhD thesis, '.$bibentry->getField(SCHOOL);
+ }
+ if ($type=="mastersthesis") {
+ $publisher = 'Master\'s thesis, '.$bibentry->getField(SCHOOL);
+ }
+ if ($type=="bachelorsthesis") {
+ $publisher = 'Bachelor\'s thesis, '.$bibentry->getField(SCHOOL);
+ }
+ if ($type=="techreport") {
+ $publisher = 'Technical report, '.$bibentry->getField("institution");
+ }
+
+ if ($type=="misc") {
+ $publisher = $bibentry->getField('howpublished');
+ }
+
+ if ($bibentry->hasField("publisher")) {
+ $publisher = $bibentry->getField("publisher");
+ }
+
+ if ($publisher!='') $entry[] = ''.$publisher.'';
+
+
+ if ($bibentry->hasField('volume')) $entry[] = "volume ".$bibentry->getField("volume");
+
+
+ if ($bibentry->hasField(YEAR)) $entry[] = $bibentry->getYear();
+
+ $result = implode(", ",$entry).'.';
+
+ // some comments (e.g. acceptance rate)?
+ if ($bibentry->hasField('comment')) {
+ $result .= " (".$bibentry->getField("comment").")";
+ }
+ if ($bibentry->hasField('note')) {
+ $result .= " (".$bibentry->getField("note").")";
+ }
+
+ // add the Coin URL
+ $result .= "\n".$bibentry->toCoins();
+
+ return $result;
+}
+
+
+
+/** is the Bibtexbrowser style contributed by Janos Tapolcai. It looks like the IEEE transaction style.
+usage:
+Add the following line in "bibtexbrowser.local.php"
+
*/
class IndependentYearMenu {
function IndependentYearMenu() {
@@ -1691,45 +1786,29 @@ class IndependentYearMenu {
}
}
-/** Class to encapsulates the header formatting and the powered by footer */
-class BibtexBrowserDisplay {
- /** the title */
- var $title;
-
- function getTitle() { return $this->title; }
-
- function display() { /* unimplemented */ }
-
- /** returns the url of this display (e.g. base on the query)*/
- function getURL() { return '';}
-
- /** returns the url of the RSS */
- function getRSS() { return '';}
-
- /** Returns the powered by part */
- function poweredby() {
- $poweredby = "\n".'
\n";}
- /** 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
- * Note how beautiful is this piece of code thanks to JQuery.
- */
- function javascript() {
+/** ^^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
+ 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
?>
+ $db = zetDB('metrics.bib');
+ $menu = new MenuManager();
+ $menu->setDB($db);
+ $menu->year_size=100;// should display all years :)
+ $menu->display();
+
*/
-class MenuManager extends BibtexBrowserDisplay {
+class MenuManager {
/** The bibliographic database, an instance of class BibDataBase. */
var $db;
- /** Creates a new display manager that uses the given bib database. */
- function MenuManager(&$db) {
+ var $type_size = TYPES_SIZE;
+ var $year_size = YEAR_SIZE;
+ var $author_size = AUTHORS_SIZE;
+ var $tag_size = TAGS_SIZE;
+
+ function MenuManager() {
+ }
+
+ /** sets the database that is used to create the menu */
+ function setDB(&$db) {
$this->db =$db;
+ return $this;
}
+ function getTitle() {
+ return '';
+ }
+
+
/** function called back by HTMLWrapper */
function display() {
echo $this->searchView().' ';
@@ -1806,18 +1906,18 @@ class MenuManager extends BibtexBrowserDisplay {
/** Displays and controls the types menu in a table. */
function typeVC() {
- $types = array();
- $types[''] = 'all types';
- foreach ($this->db->getTypes() as $type) {
- $types[$type] = $type;
- }
+ $types = array();
+ foreach ($this->db->getTypes() as $type) {
+ $types[$type] = $type;
+ }
+ $types[''] = 'all types';
// retreive or calculate page number to display
if (isset($_GET[Q_TYPE_PAGE])) {
$page = $_GET[Q_TYPE_PAGE];
}
else $page = 1;
- $this->displayMenu('Types', $types, $page, TYPES_SIZE, Q_TYPE_PAGE, Q_TYPE);
+ $this->displayMenu('Types', $types, $page, $this->type_size, Q_TYPE_PAGE, Q_TYPE);
}
/** Displays and controls the authors menu in a table. */
@@ -1832,7 +1932,7 @@ class MenuManager extends BibtexBrowserDisplay {
else $page = 1;
- $this->displayMenu('Authors', $authors, $page, AUTHORS_SIZE, Q_AUTHOR_PAGE,
+ $this->displayMenu('Authors', $authors, $page, $this->author_size, Q_AUTHOR_PAGE,
Q_AUTHOR);
}
@@ -1847,7 +1947,7 @@ class MenuManager extends BibtexBrowserDisplay {
} else $page = 1;
- if (count($tags)>0) $this->displayMenu('Keywords', $tags, $page, TAGS_SIZE, Q_TAG_PAGE,
+ if (count($tags)>0) $this->displayMenu('Keywords', $tags, $page, $this->tag_size, Q_TAG_PAGE,
Q_TAG);
}
@@ -1863,7 +1963,7 @@ class MenuManager extends BibtexBrowserDisplay {
else $page = 1;
- $this->displayMenu('Years', $years, $page, YEAR_SIZE, Q_YEAR_PAGE,
+ $this->displayMenu('Years', $years, $page, $this->year_size, Q_YEAR_PAGE,
Q_YEAR);
}
@@ -1893,9 +1993,9 @@ else $page = 1;
+ */
+class SimpleDisplay {
+
+ var $options = array();
+
+ function setDB(&$bibdatabase) {
+ $this->setEntries($bibdatabase->bibdb);
}
- function isDisplayed($index) {
- if ($index >= $this->startIndex && $index < $this->endIndex) return true;
- return false;
+ /** sets the entries to be shown */
+ function setEntries(&$entries) {
+ $this->entries = $entries;
}
+ function indexUp() {
+ $index=1;
+ foreach ($this->entries as $bib) {
+ $bib->setAbbrv((string)$index++);
+ } // end foreach
+ return $this->entries;
+ }
+
+ function newest(&$entries) {
+ return array_slice($entries,0,BIBTEXBROWSER_NEWEST);
+ }
- /** Displays a page bar consisting of clickable page numbers. */
- function displayPageBar($noPages, $page) {
-
- // bug found by benoit, first we have to reset the q_result
- $this->filter[Q_RESULT] = 1;
-
- $barSize = 10; // *2
- $start = ($page - $barSize) > 0 ? $page - $barSize : 1;
- $end = min($noPages, $start + $barSize * 2);
-
- echo '
';
-
- // fast reverse (<<)
- if ($start - $barSize*2 > 0) {
- $this->filter[Q_RESULT] = $page - $barSize * 2;
- $href = makeHref($this->filter);
- echo '[«]";
- }
-
- // reverse (<)
- if ($start > 1) {
- $this->filter[Q_RESULT] =$start - 1;
- $href = makeHref($this->filter);
- echo '[<]";
- }
+ function indexDown() {
+ $index=count($this->entries);
+ foreach ($this->entries as $bib) {
+ $bib->setAbbrv((string)$index--);
+ } // end foreach
+ return $this->entries;
+ }
+
+ function setTitle($title) { $this->title = $title; return $this; }
+ function getTitle() { return @$this->title ; }
+
+ /** Displays a set of bibtex entries in an HTML table */
+ function display() {
+
+ uasort($this->entries, ORDER_FUNCTION);
- // page numbers
- foreach (range($start, $end) as $i) {
- // default page is #1
- // we don't duplicate URLs
- if ($i > 1) $this->filter[Q_RESULT] = $i;
- $href = makeHref($this->filter);
- if ($i == $page) {
- // don't make links for current page
- echo '['. $i .']';
- } else {
- echo '['. $i .']';
+ if ($this->options) {
+ foreach($this->options as $fname=>$opt) {
+ $this->$fname($opt,$entries);
}
}
- // forward (>)
- if ($end < $noPages) {
- $this->filter[Q_RESULT] = $end + 1;
- $href = makeHref($this->filter);
- echo '[>]";
- }
-
- // fast forward (>>)
- if (($end + $barSize*2) <= $noPages) {
- $this->filter[Q_RESULT] =$end + $barSize * 2;
- $href = makeHref($this->filter);
- echo '[»]\n";
- }
- //print_r($this->filter);
- echo '
';
- }
-}
-
-/** creates an RSS link with text or image depending on the environment */
- function createRSSLink($filter) {
- // default label
- $label='[rss]';
- // auto adaptive code :-)
- //if (is_file('rss.png')) $label='';
- return ''.$label.'';
-}
-
-
-/**
- * Displays the summary information of each bib entries of the
- * current page. For each entry, this method displays the author,
- * title; the bib entries are displayed grouped by the
- * publication years. If the bib list is empty, an error message is
- * displayed.
- */
-class DefaultContentStrategy {
-
- /** $display: an instance of PagedDisplay */
- function display(&$display) {
- // create a year -> entries map to display by years
- $years = array();
- foreach ($display->result as $e) {
- $y = trim($e->getField(YEAR));
- $years[$y][$e->getKey()] = $e;
+ if (BIBTEXBROWSER_DEBUG) {
+ echo 'Style: '.BIBLIOGRAPHYSTYLE.' ';
+ echo 'Order: '.ORDER_FUNCTION.' ';
+ echo 'Abbrv: '.ABBRV_TYPE.' ';
+ echo 'Options: '.@implode(',',$this->options).' ';
}
- krsort($years);
-
+
?>
-
+
result)-(($display->page-1)*PAGE_SIZE);
- foreach ($years as $year => $entries) {
-
-
- if ($display->isDisplayed($index)) {
- ?>
-
-
-
- isDisplayed($index)) {
- $bib->setAbbrv($refnum--);
- $bib->toTR();
- }
- $index++;
-
- } // end foreach
- }
+ $count = count($this->entries);
+ $i=0;
+ foreach ($this->entries as $bib) {
+ // by default, index are in decrasing order
+ // so that when you add a publicaton recent , the indices of preceding publications don't change
+ $bib->setIndex('['.($count-($i++)).']');
+ $bib->toTR();
+ } // end foreach
?>
-
- Sorry, this bib entry does not exist.
- Back to bibtexbrowser
-
+ Sorry, this bib entry does not exist.
+ Back to bibtexbrowser
+ query=$query;
- $this->db=new BibDataBase();
- $this->db->bibdb = $entries;
- $this->title = query2title($query);
- }
+/** displays the publication records sorted by publication types (as configured by constant BIBLIOGRAPHYSECTIONS).
+usage:
+
';}
+ function getTitle() { return $this->title; }
+ function setTitle($title) { $this->title = $title; return $this; }
+ function setDB(&$bibdatabase) {
+ $this->setEntries($bibdatabase->bibdb);
+ }
+
+ /** sets the entries to be shown */
+ function setEntries(&$entries) {
+ $this->entries = $entries;
+ }
/** transforms a query to HTML
* $ query is an array (e.g. array(Q_TYPE=>'book'))
@@ -2241,17 +2292,20 @@ class AcademicDisplay extends BibtexBrowserDisplay {
*/
function search2html($query, $title) {
$entries = $this->db->multisearch($query);
+ uasort($entries, ORDER_FUNCTION);
if (count($entries)>0) {
- echo "\n".'
'.$title.'
'."\n";
+ echo "\n".'
'.$title.'
'."\n";
echo '
'."\n";
// by default the abbreviation is incermented over all
// searches
+
+ // since we don't know before hand all section, we can not index in decreasing order
static $count;
if ($count == NULL) { $count = 1; } // init
$id = $count;
foreach ($entries as $bib) {
- $bib->setAbbrv($id++);
+ $bib->setIndex('['.($id++).']');
$bib->toTR();
} // end foreach
$count = @$count + count($entries);
@@ -2261,16 +2315,16 @@ class AcademicDisplay extends BibtexBrowserDisplay {
}
function display() {
+ $this->db = createBibDataBase();
+ $this->db->bibdb = $this->entries;
+
+
foreach (_DefaultBibliographySections() as $section) {
$this->search2html($section['query'],$section['title']);
}
- echo $this->poweredby();
+ echo poweredby();
- if (BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT) {
- $this->javascript();
- }
-
}
}
@@ -2278,24 +2332,36 @@ class AcademicDisplay extends BibtexBrowserDisplay {
-/** Class to display a single bib entry.
- * This view is optimized for Google Scholar
- * */
-class BibEntryDisplay extends BibtexBrowserDisplay {
+/** displays a single bib entry.
+usage:
+
+notes:
+- the top-level header (usually <H1>) must be done by the caller.
+- this view is optimized for Google Scholar
+ */
+class BibEntryDisplay {
/** the bib entry to display */
var $bib;
- /** Creates an instance with the given bib entry and header.
- * It the object is an instance of BibIndexEntry, it may be
- * mutated to read the rest of the fields.
- */
- function BibEntryDisplay(&$bibentry) {
- $this->bib = $bibentry;
- $this->title = $this->bib->getTitle().' (bibtex)';
+ function BibEntryDisplay($bib=null) {
+ $this->bib = $bib;
+ }
+
+ function setEntries(&$entries) {
+ $this->bib = $entries[0];
//$this->title = $this->bib->getTitle().' (bibtex)'.$this->bib->getUrlLink();
}
+ /** returns the title */
+ function getTitle() {
+ return $this->bib->getTitle().' (bibtex)';
+ }
+
/** 2011/10/02: new display, inspired from Tom Zimmermann's home page */
function displayOnSteroids() {
$subtitle = '