<!-- index.php -->
<?php
  
require "bibtex2html.php";
  
$bibtex = new BibTeX();
  
// Several bib-files can be added in sequence
  
$bibtex->addBibFile("xmartin.bib");
  
$header = @file_get_contents("header.html");
  
$footer = @file_get_contents("footer.html");
  
$bibtex->outputHTML($header$footer);
?>
<!-- bibtex2html.php -->
<?php
  
# BibTeX to HTML class by Martin Hassel.
  # http://nlp.lacasahassel.net/publications
  #
  # 2008-??-??: First version of the code inspired and adapted from various
  #             other implementations in Perl etc.
  # 2009-10-23: Sorting by date added by Sumithra Velupillai.
  # 2011-04-12: Correct handling of editor(s) in InBook and InCollection.
  # 2011-08-17: Stylesheet support for odd and even rows in the table.
  #
  # This program is free software; you can redistribute it and/or modify it
  # under the terms of the GNU General Public License as published by the
  # Free Software Foundation; either version 2 of the License,
  # or (at your option) any later version.
  #
  # This program is distributed in the hope that it will be useful,
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  # GNU General Public License for more details.
  #
  # A full copy of the GNU General Public License can be retrieved from
  # http://www.gnu.org/copyleft/gpl.html

  // Turn off error reporting to the browser
  
error_reporting(E_ALL & ~E_NOTICE);

  class 
BibTeX {

    function 
BibTeX() {
      
$this->version "BibTeX to HTML by Martin Hassel (2011-08-17)";
      
$this->files = array();
      
$this->entries = array();
    }

    function 
addBibFile($bibfile$publishurls=true) {
      
$this->publishurls[$bibfile] = $publishurls;
      
$this->files[] = $bibfile;
    }

    function 
parse() {
      
$this->count = -1;
      foreach(
$this->files as $filename) {
        
$lineindex 0;
        
$fieldcount = -1;
        
$lines = @file($filename);
        if(!
$lines) return;
        foreach(
$lines as $line) {
          
$lineindex++;
          
$line trim($line);
          
$seg $line str_replace("'","`",$line);
          
$ps strpos($seg,'=');
          
$segtest strtolower($seg);
          
// Some funny comment string
          
if(strpos($segtest,'@string')!==false) continue;
          
// Pybliographer comments
          
if(strpos($segtest,'@comment')!==false) continue;
          
// Normal TeX style comment
          
if(strpos($seg,'%%')!==false) continue;
          
// Ok when there is nothing to see, skip it!
          
if(!strlen($seg)) continue;
          if(
"@" == $seg[0]) {
            
$this->count++;
            
$this->items['raw'][$this->count] = $line "\r\n";
            
$ps strpos($seg,'@');
            
$pe strpos($seg,'{');
            
$this->types[$this->count] = trim(substr($seg,1,$pe-1));
            
$fieldcount=-1;
            
$this->items['linebegin'][$this->count] = $lineindex;
          } 
// # of item increase
          
elseif($ps !== false) { // One field begins
            
$this->items['raw'][$this->count] .= $line "\r\n";
            
$ps strpos($seg,'=');
            
$fieldcount++;
            
$var[$fieldcount] = strtolower(trim(substr($seg,0,$ps)));
            if(
$var[$fieldcount]=='pages') {
              
$ps strpos($seg,'=');
              
$pm strpos($seg,'--');
              
$pe strpos($seg,'},');
              
$pagefrom[$this->count] = substr($seg,$ps,$pm-$ps);
              
$pageto[$this->count] = substr($seg,$pm,$pe-$pm);
              
$bp str_replace('=','',$pagefrom[$this->count]);
              
$bp str_replace('{','',$bp);
              
$bp str_replace('}','',$bp);
              
$bp trim(str_replace('-','',$bp));
              
$ep str_replace('=','',$pageto[$this->count]);
              
$bp str_replace('{','',$bp);
              
$bp str_replace('}','',$bp);
              
$ep trim(str_replace('-','',$ep));
            }
            
$pe strpos($seg,'},');
            if(
$pe === false) {
              
$value[$fieldcount] = strstr($seg,'=');
            } else {
              
$value[$fieldcount] = substr($seg,$ps,$pe);
            }
          } else {
            
$this->items['raw'][$this->count] .= $line "\r\n";
            
$pe strpos($seg,'},');
            if(
$fieldcount > -1) {
              if(
$pe === false) {
                
$value[$fieldcount] .=' '.strstr($seg,' ');
              } else {
                
$value[$fieldcount] .=' '.substr($seg,$ps,$pe);
              }
            }
          }
          if(
$fieldcount >= 0) {
            
$v $value[$fieldcount];
            
// Cleanup entry
            
$v ltrim($v,' ={(');
            
$v rtrim($v,' ,})');
            
// Convert LaTeX special chars to HTML dito
            // More can be added below as needed
            
$from = array(
              
'\&',
              
'{\AA}',
              
'{\aa}',
              
'\AA',
              
'\aa',
              
'\"{A}',
              
'\"{a}',
              
'\"A',
              
'\"a',
              
'\"{O}',
              
'\"{o}',
              
'\"O',
              
'\"o',
              
'$\sim$',
              
'{',
              
'}'
              
);
            
$to = array(
              
'&amp;',
              
'&Aring;',
              
'&aring;',
              
'&Aring;',
              
'&aring;',
              
'&Auml;',
              
'&auml;',
              
'&Auml;',
              
'&auml;',
              
'&Ouml;',
              
'&ouml;',
              
'&Ouml;',
              
'&ouml;',
              
'~',
              
'',
              
''
              
);
            
$v str_replace($from,$to,$v);
            
// Convert author field to last names only and et al in case of more than two authors
            
if($var[$fieldcount]=="author" || $var[$fieldcount]=="editor")
              
// If written as: Family name, First name (and Family name, First name)*
              
if(substr_count($v,", ") > 2)
                
$v preg_replace("/, .*/"," et al",$v);
              elseif(
substr_count($v,", ") == 2)
                
$v preg_replace("/(.*?), .*? and (.*?), .*/","$1 &amp; $2",$v);
              elseif(
substr_count($v,", ") == 1)
                
$v preg_replace("/, .*/","",$v);
              
// If written as: First name Family name (and First name Family name)*
              // This is more difficult to match and might need some refinement
              
elseif(substr_count($v," and ") > 1)
                
$v preg_replace("/.*? (\w*?) and .*/","$1 et al",$v);
              elseif(
substr_count($v," and ") == 1)
                
$v preg_replace("/.*? (\w*?) and .*? (.*)/","$1 &amp; $2",$v);
              else
                
$v preg_replace("/.*? (\w*)/","$1",$v);
            if(
$var[$fieldcount]=="url" && $this->publishurls[$filename]==false)
              
$v "";
            
$this->items[$var[$fieldcount]][$this->count] = trim($v);
          }
        }
      }
    }

    function 
outputHTML($header=""$footer=""$exposebibfile=true$exposesourcecode=true) {
      if(
$exposesourcecode && $_GET["show"]) {
        echo 
"&lt;!-- index.php --&gt;<br/>\n";
        
highlight_file($_SERVER['SCRIPT_FILENAME']);
        echo 
"&lt;!-- bibtex2html.php --&gt;<br/>\n";
        
highlight_file("bibtex2html.php");
        exit;
      }
      
$this->parse();
      
$entries = array();
      
$bibtex = (array)$this;
      for(
$i=0$i<=$bibtex['count']; $i++) {
        
// Add fields here as you need them
        
$raw          $bibtex['items']['raw'][$i];
        
$year         $bibtex['items']['year'][$i];
        
$month        get_month($bibtex['items']['month'][$i]);
        
$date         get_date($bibtex['items']['month'][$i]);
        
$author       $bibtex['items']['author'][$i];
        
$editor       $bibtex['items']['editor'][$i];
        
$title        $bibtex['items']['title'][$i];
        
$chapter      $bibtex['items']['chapter'][$i];
        
$url          $bibtex['items']['url'][$i];
        
$booktitle    $bibtex['items']['booktitle'][$i];
        
$type         $bibtex['items']['type'][$i];
        
$howpublished $bibtex['items']['howpublished'][$i];
        
$journal      $bibtex['items']['journal'][$i];
        
$publisher    $bibtex['items']['publisher'][$i];
        
$volume       $bibtex['items']['volume'][$i];
        
$number       $bibtex['items']['number'][$i];
        
$pages        $bibtex['items']['pages'][$i];
        
$institution  $bibtex['items']['institution'][$i];
        
$school       $bibtex['items']['school'][$i];
        
$address      $bibtex['items']['address'][$i];
        
$note         $bibtex['items']['note'][$i];
        
// checking for broken urls is mighty slow
        
if($_GET["checkurls"]) {
          
$urlok true;
          
$fp = @fopen($url,'r');
          if(
$fp) @fclose($fp);
          else 
$urlok false;
        } else
          
$urlok true;
        
// HTML formatted or "raw" entry
        
if($_GET["bibtexentry"])
          
$entries["$year$month$date$author$title"] = $raw;
        else
          
// Add more fields here and/or change order as you like
          // Chapter and Booktitle now handles Editor/Editors correctly for one and two editor(s)
          // Note: In the case of three editors or more a plural s still is not added to "editor"
          
$entries["$year$month$date$type$author$title"] = rtrim(
            (
$author?"<span id='author'>$author</span>":"<span id='editor1'>$editor, editor".(strstr($editor," &amp; ")?"s":"")."</span>") .
            
", <span id='year'>$year</span>.\n" .
            (
$title?($url&&$urlok?"<a href='$url'>$title</a>":"<span id='title'>$title</span>"):"") .
            (
$chapter?($author&&$editor?"":", chapter ").($url&&$urlok?"<a href='$url'>$chapter</a>":($author&&$editor?"":", chapter ")."<span id='chapter'>$chapter</span>"):"") .
            
".<br/>\n" .
            (
$booktitle?"In ".($author&&$editor?"<span id='editor2'>$editor, editor".(strstr($editor," &amp; ")?"s, ":", ")."</span>":"")."<span id='booktitle'>$booktitle</span>, ":"") .
            (
$type?"<span id='type'>$type</span>, ":"") .
            (
$howpublished?"<span id='howpublished'>$howpublished</span>, ":"") .
            (
$journal?"<span id='journal'>$journal</span>, ":"") .
            (
$volume?"Volume <span id='volume'>$volume</span>, ":"") .
            (
$number?"Issue <span id='number'>$number</span>, ":"") .
            (
$publisher?"<span id='publisher'>$publisher</span>, ":"") .
            (
$pages?"pp <span id='pages'>$pages</span>, ":"") .
            (
$institution?"<span id='institution'>$institution</span>, ":"") .
            (
$school?"<span id='school'>$school</span>, ":"") .
            (
$address?"<span id='address'>$address</span>":"") .
            (
$note?". <span id='note'>$note</span>":""),
          
" ,").".\n";
      }
      
// To ensure that no caching of generated pages is done
      
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
      
header("Last-Modified: " gmdate("D, d M Y H:i:s") . " GMT");
      
header("Cache-Control: no-store, no-cache, must-revalidate");
      
header("Cache-Control: post-check=0, pre-check=0"false);
      
header("Pragma: no-cache");
      
// Start HTML output
      
if(!$_GET["bibtexentry"]) {
        
header('Content-Type: text/html; charset='.$GLOBALS['charset']);
        echo 
"$header\n<!-- $this->version Begin -->\n<table id='bibtable'>\n";
      }
      
krsort($entries);
      foreach(
$entries as $key => $entry) {
        
$j++;
        
// Output chosen "raw" BibTeX entry and exit
        
if($_GET["bibtexentry"]==$j) {
          
header('Content-Type: text/plain; charset='.$GLOBALS['charset']);
          echo 
$entry;
          exit;
        }
        
// Output HTML formatted entry with link to corresponding "raw" BibTeX entry
        
elseif(!$_GET["bibtexentry"])
          echo 
"<tr>\n<td id='biblink'>\n",
            
"[<a href='",$_SERVER['PHP_SELF'],"?bibtexentry=$j'>$j</a>]</td>\n",
            
"<td id='bibentry-",(($j&1)?"odd":"even"),"'>\n$entry</td>\n</tr>\n";
      }
      echo 
"</table>\n<br/>\n";
      
// Set to false if you don't want to expose your bib-file(s), but why wouldn't you?
      
if($exposebibfile) {
        
$bibfiles "All references are also available as BibTeX file(s): ";
        foreach(
$bibtex['files'] as $filename) {
          
$bibfiles .= "<a href='$filename'>$filename</a>, ";
        }
        echo 
rtrim($bibfiles,", "), "<br/>\n";
      }
      
// Set to false if you don't want to expose this code, but please do :-)
      
if($exposesourcecode)
        echo 
"The <a href='",$_SERVER['PHP_SELF'],"?show=code'>PHP code</a> used to generate this page can be used freely.\n";
      echo 
"<!-- $this->version End -->\n$footer";
    }
  }

function 
get_month($month){
  switch (
substr($month03)) {
  case 
"Jan"$month_nr "01"; break;
  case 
"Feb"$month_nr "02"; break;
  case 
"Mar"$month_nr "03"; break;
  case 
"Apr"$month_nr "04"; break;
  case 
"May"$month_nr "05"; break;
  case 
"Jun"$month_nr "06"; break;
  case 
"Jul"$month_nr "07"; break;
  case 
"Aug"$month_nr "08"; break;
  case 
"Sep"$month_nr "09"; break;
  case 
"Oct"$month_nr "10"; break;
  case 
"Nov"$month_nr "11"; break;
  case 
"Dec"$month_nr "12"; break;
  case 
""$month_nr "00"; break;
  }
  return 
$month_nr;
}

function 
get_date($month){
  return (int) 
preg_replace("/.*?(\d+).*/""$1"$month);
}
?>