diff --git a/src/BibDBBuilder.php b/src/BibDBBuilder.php new file mode 100644 index 0000000..3939734 --- /dev/null +++ b/src/BibDBBuilder.php @@ -0,0 +1,161 @@ + + $empty_array = array(); + $db = new BibDBBuilder(); // see also factory method createBibDBBuilder + $db->build('bibacid-utf8.bib'); // parses bib file + 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 extends ParserDelegate { + + /** A hashtable from keys to bib entries (BibEntry). */ + var $builtdb = array(); + + /** A hashtable of constant strings */ + var $stringdb = array(); + + var $filename; + + var $currentEntry; + + function build($bibfilename, $handle = NULL) { + + $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); + return $this->builtdb; + } + + function beginFile() { + } + + function endFile() { + // resolving crossrefs + // we are careful with PHP 4 semantics + foreach (array_keys($this->builtdb) as $key) { + $bib = $this->builtdb[$key]; + if ($bib->hasField('crossref')) { + if (isset($this->builtdb[$bib->getField('crossref')])) { + $crossrefEntry = $this->builtdb[$bib->getField('crossref')]; + $bib->crossref = $crossrefEntry; + foreach($crossrefEntry->getFields() as $k => $v) { + // copying the fields of the cross ref + // only if they don't exist yet + if (!$bib->hasField($k)) { + $bib->setField($k,$v); + } + } + } + } + } + //print_r($this->builtdb); + } + + function setEntryField($fieldkey,$entryvalue) { + $fieldkey=trim($fieldkey); + // support for Bibtex concatenation + // see http://newton.ex.ac.uk/tex/pack/bibtex/btxdoc/node3.html + // (?$v) { + // spaces are allowed when using # and they are not taken into account + // however # is not itself replaced by a space + // warning: @strings are not case sensitive + // see http://newton.ex.ac.uk/tex/pack/bibtex/btxdoc/node3.html + $stringKey=strtolower(trim($v)); + if (isset($this->stringdb[$stringKey])) + { + // this field will be formated later by xtrim and latex2html + $entryvalue_array[$k]=$this->stringdb[$stringKey]->value; + + // we keep a trace of this replacement + // so as to produce correct bibtex snippets + $this->currentEntry->constants[$stringKey]=$this->stringdb[$stringKey]->value; + } + } + $entryvalue=implode('',$entryvalue_array); + + $this->currentEntry->setField($fieldkey,$entryvalue); + } + + function setEntryType($entrytype) { + $this->currentEntry->setType($entrytype); + } + + function setEntryKey($entrykey) { + //echo "new entry:".$entrykey."\n"; + $this->currentEntry->setKey($entrykey); + } + + function beginEntry() { + $this->currentEntry = createBibEntry(); + $this->currentEntry->setFile($this->filename); + } + + function endEntry($entrysource) { + + // we add a timestamp + $this->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($entrysource)); + } + + // 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')) { + $this->currentEntry->setField(Q_INNER_AUTHOR,$this->currentEntry->getFormattedAuthorsString()); + + foreach($this->currentEntry->getCanonicalAuthors() as $author) { + $homepage_key = $this->currentEntry->getHomePageKey($author); + if (isset($this->stringdb[$homepage_key])) { + $this->currentEntry->homepages[$homepage_key] = $this->stringdb[$homepage_key]->value; + } + } + } + + // 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; + } + } + +} // end class BibDBBuilder diff --git a/src/Definitions.php b/src/Definitions.php index 46506a5..65d8c9d 100644 --- a/src/Definitions.php +++ b/src/Definitions.php @@ -2,188 +2,194 @@ namespace Monperrus\BibtexBrowser; -// the encoding of your bibtex file -@define('BIBTEX_INPUT_ENCODING','UTF-8');//@define('BIBTEX_INPUT_ENCODING','iso-8859-1');//define('BIBTEX_INPUT_ENCODING','windows-1252'); -// the encoding of the HTML output -@define('OUTPUT_ENCODING','UTF-8'); - -// print a warning if deprecated variable is used -if (defined('ENCODING')) { - echo 'ENCODING has been replaced by BIBTEX_INPUT_ENCODING and OUTPUT_ENCODING'; +class Definitions +{ + public function __construct() + { + // the encoding of your bibtex file + @define('BIBTEX_INPUT_ENCODING','UTF-8');//@define('BIBTEX_INPUT_ENCODING','iso-8859-1');//define('BIBTEX_INPUT_ENCODING','windows-1252'); + // the encoding of the HTML output + @define('OUTPUT_ENCODING','UTF-8'); + + // print a warning if deprecated variable is used + if (defined('ENCODING')) { + echo 'ENCODING has been replaced by BIBTEX_INPUT_ENCODING and OUTPUT_ENCODING'; + } + + // number of bib items per page + // 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 + // @define('BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT',false); + @define('BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT',true); + @define('BIBLIOGRAPHYSTYLE','DefaultBibliographyStyle');// this is the name of a function + @define('BIBLIOGRAPHYSECTIONS','DefaultBibliographySections');// this is the name of a function + @define('BIBLIOGRAPHYTITLE','DefaultBibliographyTitle');// this is the name of a function + + // shall we load MathJax to render math in $…$ in HTML? + @define('BIBTEXBROWSER_RENDER_MATH', true); + @define('MATHJAX_URI', '//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML.js'); + + // the default jquery URI + @define('JQUERY_URI', '//code.jquery.com/jquery-1.5.1.min.js'); + + // 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 default template + @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('ABBRV_TYPE','index');// may be year/x-abbrv/key/none/index/keys-index + + // are robots allowed to crawl and index bibtexbrowser generated pages? + @define('BIBTEXBROWSER_ROBOTS_NOINDEX',false); + + //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 + @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. + // can be @define('ORDER_FUNCTION','compare_bib_entry_by_title'); + // can be @define('ORDER_FUNCTION','compare_bib_entry_by_bibtex_order'); + @define('ORDER_FUNCTION','compare_bib_entry_by_year'); + @define('ORDER_FUNCTION_FINE','compare_bib_entry_by_month'); + + // only displaying the n newest entries + @define('BIBTEXBROWSER_NEWEST',5); + + @define('BIBTEXBROWSER_NO_DEFAULT', false); + + // BIBTEXBROWSER_LINK_STYLE defines which function to use to display the links of a bibtex entry + @define('BIBTEXBROWSER_LINK_STYLE','bib2links_default'); // can be 'nothing' (a function that does nothing) + + // do we add [bibtex] links ? + @define('BIBTEXBROWSER_BIBTEX_LINKS',true); + // do we add [pdf] links ? + @define('BIBTEXBROWSER_PDF_LINKS',true); + // do we add [doi] links ? + @define('BIBTEXBROWSER_DOI_LINKS',true); + // do we add [gsid] links (Google Scholar)? + @define('BIBTEXBROWSER_GSID_LINKS',true); + + // should pdf, doi, url, gsid links be opened in a new window? + @define('BIBTEXBROWSER_LINKS_TARGET','_self');// can be _blank (new window), _top (with frames) + + // should authors be linked to [none/homepage/resultpage] + // none: nothing + // their homepage if defined as @strings + // their publication lists according to this bibtex + @define('BIBTEXBROWSER_AUTHOR_LINKS','homepage'); + + // BIBTEXBROWSER_LAYOUT defines the HTML rendering layout of the produced HTML + // may be table/list/ordered_list/definition/none (for ,
    ,
    , nothing resp.). + // for list/ordered_list, the abbrevations are not taken into account (see ABBRV_TYPE) + // for ordered_list, the index is given by HTML directly (in increasing order) + @define('BIBTEXBROWSER_LAYOUT','table'); + + // should the original bibtex be displayed or a reconstructed one with filtering + // values: original/reconstructed + // warning, with reconstructed, the latex markup for accents/diacritics is lost + @define('BIBTEXBROWSER_BIBTEX_VIEW','original'); + // a list of fields that will not be shown in the bibtex view if BIBTEXBROWSER_BIBTEX_VIEW=reconstructed + @define('BIBTEXBROWSER_BIBTEX_VIEW_FILTEREDOUT','comment|note|file'); + + // should Latex macros be executed (e.g. \'e -> é + @define('BIBTEXBROWSER_USE_LATEX2HTML',true); + + // Which is the first html level that should be used in embedded mode? + @define('BIBTEXBROWSER_HTMLHEADINGLEVEL', 2); + + @define('BIBTEXBROWSER_ACADEMIC_TOC', false); + + @define('BIBTEXBROWSER_DEBUG',false); + + // how to print authors names? + // default => as in the bibtex file + // USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT = true => "Meyer, Herbert" + // USE_INITIALS_FOR_NAMES = true => "Meyer H" + // USE_FIRST_THEN_LAST => Herbert Meyer + @define('USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT',false);// output authors in a comma separated form, e.g. "Meyer, H"? + @define('USE_INITIALS_FOR_NAMES',false); // use only initials for all first names? + @define('USE_FIRST_THEN_LAST',false); // use only initials for all first names? + @define('FORCE_NAMELIST_SEPARATOR', ''); // if non-empty, use this to separate multiple names regardless of USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT + @define('LAST_AUTHOR_SEPARATOR',' and '); + + @define('TYPES_SIZE',10); // number of entry types per table + @define('YEAR_SIZE',20); // number of years per table + @define('AUTHORS_SIZE',30); // number of authors per table + @define('TAGS_SIZE',30); // number of keywords per table + @define('READLINE_LIMIT',1024); + @define('Q_YEAR', 'year'); + @define('Q_YEAR_PAGE', 'year_page'); + @define('Q_YEAR_INPRESS', 'in press'); + @define('Q_YEAR_ACCEPTED', 'accepted'); + @define('Q_YEAR_SUBMITTED', 'submitted'); + @define('Q_FILE', 'bib'); + @define('Q_AUTHOR', 'author'); + @define('Q_AUTHOR_PAGE', 'author_page'); + @define('Q_TAG', 'keywords'); + @define('Q_TAG_PAGE', 'keywords_page'); + @define('Q_TYPE', 'type');// used for queries + @define('Q_TYPE_PAGE', 'type_page'); + @define('Q_ALL', 'all'); + @define('Q_ENTRY', 'entry'); + @define('Q_KEY', 'key'); + @define('Q_KEYS', 'keys'); // filter entries using a url-encoded, JSON-encoded array of bibtex keys + @define('Q_SEARCH', 'search'); + @define('Q_EXCLUDE', 'exclude'); + @define('Q_RESULT', 'result'); + @define('Q_ACADEMIC', 'academic'); + @define('Q_DB', 'bibdb'); + @define('Q_LATEST', 'latest'); + @define('Q_RANGE', 'range'); + @define('AUTHOR', 'author'); + @define('EDITOR', 'editor'); + @define('SCHOOL', 'school'); + @define('TITLE', 'title'); + @define('BOOKTITLE', 'booktitle'); + @define('YEAR', 'year'); + @define('BUFFERSIZE',100000); + @define('MULTIPLE_BIB_SEPARATOR',';'); + @define('METADATA_GS',true); + @define('METADATA_DC',true); + @define('METADATA_OPENGRAPH',true); + @define('METADATA_EPRINTS',false); + + // define sort order for special values in 'year' field + // highest number is sorted first + // don't exceed 0 though, since the values are added to PHP_INT_MAX + @define('ORDER_YEAR_INPRESS', -0); + @define('ORDER_YEAR_ACCEPTED', -1); + @define('ORDER_YEAR_SUBMITTED', -2); + @define('ORDER_YEAR_OTHERNONINT', -3); + + + // 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 + // for instance with @define('BIBTEXBROWSER_URL',''); // links to the current page with ? + //@define('BIBTEXBROWSER_URL',basename(__FILE__)); + @define('BIBTEXBROWSER_URL',parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)); + + // *************** END CONFIGURATION + + define('Q_INNER_AUTHOR', '_author');// internally used for representing the author + define('Q_INNER_TYPE', 'x-bibtex-type');// used for representing the type of the bibtex entry internally + @define('Q_INNER_KEYS_INDEX', '_keys-index');// used for storing indices in $_GET[Q_KEYS] array + } } - -// number of bib items per page -// 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 -// @define('BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT',false); -@define('BIBTEXBROWSER_USE_PROGRESSIVE_ENHANCEMENT',true); -@define('BIBLIOGRAPHYSTYLE','DefaultBibliographyStyle');// this is the name of a function -@define('BIBLIOGRAPHYSECTIONS','DefaultBibliographySections');// this is the name of a function -@define('BIBLIOGRAPHYTITLE','DefaultBibliographyTitle');// this is the name of a function - -// shall we load MathJax to render math in $…$ in HTML? -@define('BIBTEXBROWSER_RENDER_MATH', true); -@define('MATHJAX_URI', '//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML.js'); - -// the default jquery URI -@define('JQUERY_URI', '//code.jquery.com/jquery-1.5.1.min.js'); - -// 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 default template -@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('ABBRV_TYPE','index');// may be year/x-abbrv/key/none/index/keys-index - -// are robots allowed to crawl and index bibtexbrowser generated pages? -@define('BIBTEXBROWSER_ROBOTS_NOINDEX',false); - -//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 -@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. -// can be @define('ORDER_FUNCTION','compare_bib_entry_by_title'); -// can be @define('ORDER_FUNCTION','compare_bib_entry_by_bibtex_order'); -@define('ORDER_FUNCTION','compare_bib_entry_by_year'); -@define('ORDER_FUNCTION_FINE','compare_bib_entry_by_month'); - -// only displaying the n newest entries -@define('BIBTEXBROWSER_NEWEST',5); - -@define('BIBTEXBROWSER_NO_DEFAULT', false); - -// BIBTEXBROWSER_LINK_STYLE defines which function to use to display the links of a bibtex entry -@define('BIBTEXBROWSER_LINK_STYLE','bib2links_default'); // can be 'nothing' (a function that does nothing) - -// do we add [bibtex] links ? -@define('BIBTEXBROWSER_BIBTEX_LINKS',true); -// do we add [pdf] links ? -@define('BIBTEXBROWSER_PDF_LINKS',true); -// do we add [doi] links ? -@define('BIBTEXBROWSER_DOI_LINKS',true); -// do we add [gsid] links (Google Scholar)? -@define('BIBTEXBROWSER_GSID_LINKS',true); - -// should pdf, doi, url, gsid links be opened in a new window? -@define('BIBTEXBROWSER_LINKS_TARGET','_self');// can be _blank (new window), _top (with frames) - -// should authors be linked to [none/homepage/resultpage] -// none: nothing -// their homepage if defined as @strings -// their publication lists according to this bibtex -@define('BIBTEXBROWSER_AUTHOR_LINKS','homepage'); - -// BIBTEXBROWSER_LAYOUT defines the HTML rendering layout of the produced HTML -// may be table/list/ordered_list/definition/none (for
,
    ,
    , nothing resp.). -// for list/ordered_list, the abbrevations are not taken into account (see ABBRV_TYPE) -// for ordered_list, the index is given by HTML directly (in increasing order) -@define('BIBTEXBROWSER_LAYOUT','table'); - -// should the original bibtex be displayed or a reconstructed one with filtering -// values: original/reconstructed -// warning, with reconstructed, the latex markup for accents/diacritics is lost -@define('BIBTEXBROWSER_BIBTEX_VIEW','original'); -// a list of fields that will not be shown in the bibtex view if BIBTEXBROWSER_BIBTEX_VIEW=reconstructed -@define('BIBTEXBROWSER_BIBTEX_VIEW_FILTEREDOUT','comment|note|file'); - -// should Latex macros be executed (e.g. \'e -> é -@define('BIBTEXBROWSER_USE_LATEX2HTML',true); - -// Which is the first html level that should be used in embedded mode? -@define('BIBTEXBROWSER_HTMLHEADINGLEVEL', 2); - -@define('BIBTEXBROWSER_ACADEMIC_TOC', false); - -@define('BIBTEXBROWSER_DEBUG',false); - -// how to print authors names? -// default => as in the bibtex file -// USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT = true => "Meyer, Herbert" -// USE_INITIALS_FOR_NAMES = true => "Meyer H" -// USE_FIRST_THEN_LAST => Herbert Meyer -@define('USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT',false);// output authors in a comma separated form, e.g. "Meyer, H"? -@define('USE_INITIALS_FOR_NAMES',false); // use only initials for all first names? -@define('USE_FIRST_THEN_LAST',false); // use only initials for all first names? -@define('FORCE_NAMELIST_SEPARATOR', ''); // if non-empty, use this to separate multiple names regardless of USE_COMMA_AS_NAME_SEPARATOR_IN_OUTPUT -@define('LAST_AUTHOR_SEPARATOR',' and '); - -@define('TYPES_SIZE',10); // number of entry types per table -@define('YEAR_SIZE',20); // number of years per table -@define('AUTHORS_SIZE',30); // number of authors per table -@define('TAGS_SIZE',30); // number of keywords per table -@define('READLINE_LIMIT',1024); -@define('Q_YEAR', 'year'); -@define('Q_YEAR_PAGE', 'year_page'); -@define('Q_YEAR_INPRESS', 'in press'); -@define('Q_YEAR_ACCEPTED', 'accepted'); -@define('Q_YEAR_SUBMITTED', 'submitted'); -@define('Q_FILE', 'bib'); -@define('Q_AUTHOR', 'author'); -@define('Q_AUTHOR_PAGE', 'author_page'); -@define('Q_TAG', 'keywords'); -@define('Q_TAG_PAGE', 'keywords_page'); -@define('Q_TYPE', 'type');// used for queries -@define('Q_TYPE_PAGE', 'type_page'); -@define('Q_ALL', 'all'); -@define('Q_ENTRY', 'entry'); -@define('Q_KEY', 'key'); -@define('Q_KEYS', 'keys'); // filter entries using a url-encoded, JSON-encoded array of bibtex keys -@define('Q_SEARCH', 'search'); -@define('Q_EXCLUDE', 'exclude'); -@define('Q_RESULT', 'result'); -@define('Q_ACADEMIC', 'academic'); -@define('Q_DB', 'bibdb'); -@define('Q_LATEST', 'latest'); -@define('Q_RANGE', 'range'); -@define('AUTHOR', 'author'); -@define('EDITOR', 'editor'); -@define('SCHOOL', 'school'); -@define('TITLE', 'title'); -@define('BOOKTITLE', 'booktitle'); -@define('YEAR', 'year'); -@define('BUFFERSIZE',100000); -@define('MULTIPLE_BIB_SEPARATOR',';'); -@define('METADATA_GS',true); -@define('METADATA_DC',true); -@define('METADATA_OPENGRAPH',true); -@define('METADATA_EPRINTS',false); - -// define sort order for special values in 'year' field -// highest number is sorted first -// don't exceed 0 though, since the values are added to PHP_INT_MAX -@define('ORDER_YEAR_INPRESS', -0); -@define('ORDER_YEAR_ACCEPTED', -1); -@define('ORDER_YEAR_SUBMITTED', -2); -@define('ORDER_YEAR_OTHERNONINT', -3); - - -// 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 -// for instance with @define('BIBTEXBROWSER_URL',''); // links to the current page with ? -//@define('BIBTEXBROWSER_URL',basename(__FILE__)); -@define('BIBTEXBROWSER_URL',parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)); - -// *************** END CONFIGURATION - -define('Q_INNER_AUTHOR', '_author');// internally used for representing the author -define('Q_INNER_TYPE', 'x-bibtex-type');// used for representing the type of the bibtex entry internally -@define('Q_INNER_KEYS_INDEX', '_keys-index');// used for storing indices in $_GET[Q_KEYS] array diff --git a/src/ParserDelegate.php b/src/ParserDelegate.php new file mode 100644 index 0000000..629af5d --- /dev/null +++ b/src/ParserDelegate.php @@ -0,0 +1,27 @@ +delegate = $delegate; + } + + public function parse($handle) { + if (gettype($handle) == 'string') { throw new Exception('oops'); } + $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=''; + $fieldvaluepart=''; + $finalkey=''; + $entrysource=''; + + // metastate + $isinentry = false; + + $delegate->beginFile(); + + // 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; + $fieldvaluepart=''; + $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($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($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; + $delegate->entryValuePart($finalkey,$fieldvaluepart,'CURLYTOP'); + $fieldvaluepart=''; + } + else if ($s=='}') { // end entry + $state = GETVALUE; + $delegate->entryValuePart($finalkey,$fieldvaluepart,'CURLYTOP'); + } + else { + $entryvalue=$entryvalue.$s; + $fieldvaluepart=$fieldvaluepart.$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; + $delegate->entryValuePart($finalkey,$fieldvaluepart,'CURLYONE'); + $fieldvaluepart=''; + $entryvalue=$entryvalue.$s; + } + else { + $entryvalue=$entryvalue.$s; + $fieldvaluepart=$fieldvaluepart.$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(); + //$d = $this->delegate;print_r($d); + } // end function +} // end class diff --git a/src/StringEntry.php b/src/StringEntry.php new file mode 100644 index 0000000..0f54186 --- /dev/null +++ b/src/StringEntry.php @@ -0,0 +1,19 @@ +name=$key; + $this->value=$value; + $this->filename=$filename; + } + + public function toString() + { + return '@string{'.$this->name.'={'.$this->value.'}}'; + } +} // end class StringEntry diff --git a/src/XMLPrettyPrinter.php b/src/XMLPrettyPrinter.php new file mode 100644 index 0000000..ce414f3 --- /dev/null +++ b/src/XMLPrettyPrinter.php @@ -0,0 +1,40 @@ +'; + print ''; + } + + public function endFile() { + print ''; + } + + public function setEntryField($finalkey,$entryvalue) { + print "\n".$finalkey."\n".$entryvalue."\n\n"; + } + + public function setEntryType($entrytype) { + print ''.$entrytype.''; + } + + public function setEntryKey($entrykey) { + print ''.$entrykey.''; + } + + public function beginEntry() { + print "\n"; + } + + public function endEntry($entrysource) { + print "\n"; + } +} // end class XMLPrettyPrinter diff --git a/src/bibtexbrowser.php b/src/bibtexbrowser.php old mode 100755 new mode 100644 index e3aae03..681d260 --- a/src/bibtexbrowser.php +++ b/src/bibtexbrowser.php @@ -15,6 +15,12 @@ License, or (at your option) any later version. */ +use Monperrus\BibtexBrowser\StateBasedBibtexParser; +use Monperrus\BibtexBrowser\ParserDelegate; +use Monperrus\BibtexBrowser\XMLPrettyPrinter; +use Monperrus\BibtexBrowser\StringEntry; +use Monperrus\BibtexBrowser\BibDBBuilder; + // 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')) { @@ -483,471 +489,10 @@ 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 __construct($delegate) { - $this->delegate = $delegate; - } - - function parse($handle) { - if (gettype($handle) == 'string') { throw new Exception('oops'); } - $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=''; - $fieldvaluepart=''; - $finalkey=''; - $entrysource=''; - - // metastate - $isinentry = false; - - $delegate->beginFile(); - - // 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; - $fieldvaluepart=''; - $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($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($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; - $delegate->entryValuePart($finalkey,$fieldvaluepart,'CURLYTOP'); - $fieldvaluepart=''; - } - else if ($s=='}') { // end entry - $state = GETVALUE; - $delegate->entryValuePart($finalkey,$fieldvaluepart,'CURLYTOP'); - } - else { - $entryvalue=$entryvalue.$s; - $fieldvaluepart=$fieldvaluepart.$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; - $delegate->entryValuePart($finalkey,$fieldvaluepart,'CURLYONE'); - $fieldvaluepart=''; - $entryvalue=$entryvalue.$s; - } - else { - $entryvalue=$entryvalue.$s; - $fieldvaluepart=$fieldvaluepart.$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(); - //$d = $this->delegate;print_r($d); - } // end function -} // end class - -/** a default empty implementation of a delegate for StateBasedBibtexParser */ -class ParserDelegate { - - function beginFile() {} - - function endFile() {} - - function setEntryField($finalkey,$entryvalue) {} - - function setEntryType($entrytype) {} - - function setEntryKey($entrykey) {} - - function beginEntry() {} - - function endEntry($entrysource) {} - - /** called for each sub parts of type {part} of a field value - * for now, only CURLYTOP and CURLYONE events - */ - function entryValuePart($key, $value, $type) {} - -} // end class ParserDelegate - - -/** is a possible delegate for StateBasedBibParser. -usage: -see snippet of [[#StateBasedBibParser]] -*/ -class XMLPrettyPrinter extends ParserDelegate { - function beginFile() { - header('Content-type: text/xml;'); - print ''; - print ''; - } - - - function endFile() { - print ''; - } - function setEntryField($finalkey,$entryvalue) { - print "\n".$finalkey."\n".$entryvalue."\n\n"; - } - - function setEntryType($entrytype) { - print ''.$entrytype.''; - } - function setEntryKey($entrykey) { - print ''.$entrykey.''; - } - - function beginEntry() { - print "\n"; - } - - function endEntry($entrysource) { - print "\n"; - } -} // end class XMLPrettyPrinter - -/** represents @string{k=v} */ -class StringEntry { - function __construct($k, $v, $filename) { - $this->name=$k; - $this->value=$v; - $this->filename=$filename; - } - - function toString() { - return '@string{'.$this->name.'={'.$this->value.'}}'; - } -} // end class StringEntry - - - - -/** builds arrays of BibEntry objects from a bibtex file. -usage: -
    -  $empty_array = array();
    -  $db = new BibDBBuilder(); // see also factory method createBibDBBuilder
    -  $db->build('bibacid-utf8.bib'); // parses bib file
    -  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 extends ParserDelegate { - - /** A hashtable from keys to bib entries (BibEntry). */ - var $builtdb = array(); - - /** A hashtable of constant strings */ - var $stringdb = array(); - - var $filename; - - var $currentEntry; - - function build($bibfilename, $handle = NULL) { - - $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); - return $this->builtdb; - } - - function beginFile() { - } - - function endFile() { - // resolving crossrefs - // we are careful with PHP 4 semantics - foreach (array_keys($this->builtdb) as $key) { - $bib = $this->builtdb[$key]; - if ($bib->hasField('crossref')) { - if (isset($this->builtdb[$bib->getField('crossref')])) { - $crossrefEntry = $this->builtdb[$bib->getField('crossref')]; - $bib->crossref = $crossrefEntry; - foreach($crossrefEntry->getFields() as $k => $v) { - // copying the fields of the cross ref - // only if they don't exist yet - if (!$bib->hasField($k)) { - $bib->setField($k,$v); - } - } - } - } - } - //print_r($this->builtdb); - } - - function setEntryField($fieldkey,$entryvalue) { - $fieldkey=trim($fieldkey); - // support for Bibtex concatenation - // see http://newton.ex.ac.uk/tex/pack/bibtex/btxdoc/node3.html - // (?$v) { - // spaces are allowed when using # and they are not taken into account - // however # is not itself replaced by a space - // warning: @strings are not case sensitive - // see http://newton.ex.ac.uk/tex/pack/bibtex/btxdoc/node3.html - $stringKey=strtolower(trim($v)); - if (isset($this->stringdb[$stringKey])) - { - // this field will be formated later by xtrim and latex2html - $entryvalue_array[$k]=$this->stringdb[$stringKey]->value; - - // we keep a trace of this replacement - // so as to produce correct bibtex snippets - $this->currentEntry->constants[$stringKey]=$this->stringdb[$stringKey]->value; - } - } - $entryvalue=implode('',$entryvalue_array); - - $this->currentEntry->setField($fieldkey,$entryvalue); - } - - function setEntryType($entrytype) { - $this->currentEntry->setType($entrytype); - } - - function setEntryKey($entrykey) { - //echo "new entry:".$entrykey."\n"; - $this->currentEntry->setKey($entrykey); - } - - function beginEntry() { - $this->currentEntry = createBibEntry(); - $this->currentEntry->setFile($this->filename); - } - function endEntry($entrysource) { - // we add a timestamp - $this->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($entrysource)); - } - - // 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')) { - $this->currentEntry->setField(Q_INNER_AUTHOR,$this->currentEntry->getFormattedAuthorsString()); - - foreach($this->currentEntry->getCanonicalAuthors() as $author) { - $homepage_key = $this->currentEntry->getHomePageKey($author); - if (isset($this->stringdb[$homepage_key])) { - $this->currentEntry->homepages[$homepage_key] = $this->stringdb[$homepage_key]->value; - } - } - } - - // 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; - } - } -} // end class BibDBBuilder