<?php
	// Project:    Web Reference Database (refbase) <http://www.refbase.net>
	// Copyright:  Matthias Steffens <mailto:refbase@extracts.de> and the file's
	//             original author(s).
	//
	//             This code is distributed in the hope that it will be useful,
	//             but WITHOUT ANY WARRANTY. Please see the GNU General Public
	//             License for more details.
	//
	// File:       ./cite/formats/cite_latex_bbl.php
	// Repository: $HeadURL$
	// Author(s):  Matthias Steffens <mailto:refbase@extracts.de>
	//
	// Created:    20-Jul-07, 19:42
	// Modified:   $Date: 2017-04-13 02:00:18 +0000 (Thu, 13 Apr 2017) $
	//             $Author$
	//             $Revision: 1416 $

	// This is a citation format file (which must reside within the 'cite/formats/' sub-directory of your refbase root directory). It contains a version of
	// the 'citeRecords()' function that outputs a reference list from selected records in LateX .bbl format, to be used with LaTeX/BibTeX. The .bbl file
	// generated by refbase can be used as a replacement of the BibTeX-generated .bbl file. Make sure to use "citeOrder=author" when generating the .bbl file.

	// NOTE: In its current incarnation, this script outputs a .bbl variant that is intended to be used with the natbib package.
	//       You may want to adopt the style-specific settings below if necessary. The natbib package is available at:
	//       <http://www.ctan.org/tex-archive/macros/latex/contrib/natbib/>

	// --------------------------------------------------------------------

	// --- BEGIN CITATION FORMAT ---

	function citeRecords($result, $rowsFound, $query, $queryURL, $showQuery, $showLinks, $rowOffset, $showRows, $previousOffset, $nextOffset, $wrapResults, $citeStyle, $citeOrder, $citeType, $orderBy, $headerMsg, $userID, $viewType)
	{
		global $contentTypeCharset; // defined in 'ini.inc.php'

		global $client;

		// The array '$transtab_refbase_latex' contains search & replace patterns for conversion from refbase markup to LaTeX markup & entities.
		// Converts refbase fontshape markup (italic, bold) into LaTeX commands of the 'textcomp' package, super- and subscript as well as greek
		// symbols get converted into the respective commands in math mode. You may need to adopt the LaTeX markup to suit your individual needs.
		global $transtab_refbase_latex; // defined in 'transtab_refbase_latex.inc.php'

		// The arrays '$transtab_latin1_latex' and '$transtab_unicode_latex' provide translation tables for best-effort conversion of higher ASCII
		// characters from ISO-8859-1 (or Unicode, respectively) to LaTeX entities.
		global $transtab_latin1_latex; // defined in 'transtab_latin1_latex.inc.php'
		global $transtab_unicode_latex; // defined in 'transtab_unicode_latex.inc.php'


		// --- Begin style-specific settings ----------------------------------

		// NOTE: the given settings are meant to be used with the natbib package;
		//       you'll have to adopt these settings if you'd like to generate a
		//       .bbl file for another style/package

		// 1) Define header with .bst style-specific declarations:
		// NOTE: since this header is normally inserted by BibTeX from the used .bst style, I'm not sure if there's a variant of this header that's
		//       universally accepted by natbib. So, if necessary adopt it to your needs.
		// -- by default, we use this header (as inserted by a .bst style that was generated from 'merlin.mbs' via the docstrip utility):
		$bblHeader = "\\providecommand{\\natexlab}[1]{#1}" . "\n"
		           . "\\providecommand{\\url}[1]{\\texttt{#1}}" . "\n"
		           . "\\providecommand{\\urlprefix}{URL }" . "\n"
		           . "\\providecommand{\\eprint}[2][]{\\url{#2}}" . "\n\n";

		// -- here's another header example (as inserted by 'elsart-harv.bst'):
//		$bblHeader = "\\expandafter\\ifx\\csname natexlab\\endcsname\\relax\\def\\natexlab#1{#1}\\fi" . "\n"
//		           . "\\expandafter\\ifx\\csname url\\endcsname\\relax" . "\n"
//		           . "  \\def\\url#1{\\texttt{#1}}\\fi" . "\n"
//		           . "\\expandafter\\ifx\\csname urlprefix\\endcsname\\relax\\def\\urlprefix{URL }\\fi" . "\n\n";

		// 2) Define name of \bibitem command:
		$bibItemCommand = "\\bibitem"; // use "\\harvarditem" for the Harvard family of styles

		// 3) Define variables and placeholder strings which together will form the \bibitem option string:

		// -- variables:
		$betweenShortAuthorsDelim = " & "; // used to connect individual author names in the short author list
		$betweenFullAuthorsDelim = ", "; // used to connect multiple authors in the full author list
		$betweenLastAuthorsDelim = " & "; // used to connect the second-to-last author with the last author in the full author list
		$etalIdentifierString = " et~al."; // appended to the first author's last name if the record's number of authors exceeds the number given in '$maxAuthorCountInShortAuthorList'
		$maxAuthorCountInShortAuthorList = 2; // maximum number of authors to be used in the short author list

		// -- placeholder strings:
		// (please see the refbase online documentation for more info about placeholders and their syntax: <http://placeholders.refbase.net/>)
		$year = "<:year[4]:>"; // year format, e.g. "1990"
		$shortAuthorList = "<:authors[" . $maxAuthorCountInShortAuthorList . "|" . $betweenShortAuthorsDelim . "|" . $etalIdentifierString .  "]:>"; // format of the short author list which is used as text citation, e.g. "Jones", "Jones and Baker" or "Jones et al."
		$fullAuthorList = "<:authors[0|_#_§_~_|]:>"; // format of the full author list, e.g. "Jones, Baker, and Williams"
		// NOTE: in the above placeholder string, we use the string "_#_§_~_" as author delimiter which allows us to uniquely identify that delimiter again below, and replace it with the contents of either '$betweenFullAuthorsDelim' or '$betweenLastAuthorsDelim' (depending on its position)

		// 4) Define \bibitem option format:

		// -- extended natbib 5.3 style:
		$bibItemOptionShort = "[{" . $shortAuthorList . "}(" . $year . ")" . "]"; // e.g.: \bibitem[{Jones et al.}(1990)]{key}...
		$bibItemOptionFull = "[{" . $shortAuthorList . "}(" . $year . "){" . $fullAuthorList . "}]"; // e.g.: \bibitem[{Jones et al.}(1990){Jones, Baker, and Williams}]{key}...
		// NOTE: since the author lists may contain parentheses, we need to enclose them in curly brackets to work around a natbib limitation

		// -- native natbib style:
//		$bibItemOptionShort = "[" . $shortAuthorList . "(" . $year . ")" . "]"; // e.g.: \bibitem[Jones et al.(1990)]{key}...
//		$bibItemOptionFull = "";

		// -- apalike style:
//		$bibItemOptionShort = "[" . $shortAuthorList . ", " . $year . "]"; // e.g.: \bibitem[Jones et al., 1990]{key}...
//		$bibItemOptionFull = "";

		// -- newapa or chicago styles:
//		$bibItemOptionShort = "[\\protect\\citeauthoryear{" . $fullAuthorList . "}{" . $shortAuthorList . "}{" . $year . "}" . "]"; // this assumes that it's not allowed to omit the full author list, though I dunno)
//		$bibItemOptionFull = "[\\protect\\citeauthoryear{" . $fullAuthorList . "}{" . $shortAuthorList . "}{" . $year . "}" . "]"; // e.g.: \bibitem[\protect\citeauthoryear{Jones, Baker, and Williams}{Jones et al.}{1990}]{key}...

		// -- named style:
//		$bibItemOptionShort = "[\\protect\\citeauthoryear{" . $shortAuthorList . "}{" . $year . "}" . "]"; // e.g.: \bibitem[\protect\citeauthoryear{Jones et al.}{1990}]{key}...
//		$bibItemOptionFull = "";

		// -- astron style:
//		$bibItemOptionShort = "[\\protect\\astroncite{" . $shortAuthorList . "}{" . $year . "}" . "]"; // e.g.: \bibitem[\protect\astroncite{Jones et al.}{1990}]{key}...
//		$bibItemOptionFull = "";

		// -- authordate style:
//		$bibItemOptionShort = "[\\protect\\citename{" . $shortAuthorList . ", }" . $year . "]"; // e.g.: \bibitem[\protect\citename{Jones et al., }1990]{key}...
//		$bibItemOptionFull = "";

		// -- harvard style:
//		$bibItemOptionShort = "[" . $shortAuthorList . "]{" . $fullAuthorList . "}{" . $year . "}"; // this assumes that it's not allowed to omit the full author list, though I dunno)
//		$bibItemOptionFull = "[" . $shortAuthorList . "]{" . $fullAuthorList . "}{" . $year . "}"; // e.g.: \harvarditem[Jones et al.]{Jones, Baker, and Williams}{1990}{key}...

		// 5) Define deduplication prefix and suffix strings:
		//    Identical text citation strings get uniquified by appending letters to the year, e.g. duplicate occurrences
		//    of "Jones et al. 1990" should become "Jones et al. 1990a" and "Jones et al. 1990b" in the final output.
		//    These prefix/suffix strings will be inserted before/after the deduplication letter:
		$dedupPrefix = "{\\natexlab{"; // these prefix/suffix strings are required by natbib; if any custom command (such as '\natexlab') is used, make sure that the command is also defined above in variable '$bblHeader'
		$dedupSuffix = "}}";

		// --- End style-specific settings ------------------------------------


		// Initialize array variables:
		$yearsArray = array();
		$typeTitlesArray = array();
		$bibItemsArray = array();

		// Define inline text markup to be used by the 'citeRecord()' function:
		$markupPatternsArray = array("bold-prefix"        => "\\textbf{",
		                             "bold-suffix"        => "}",
		                             "italic-prefix"      => "\\textit{",
		                             "italic-suffix"      => "}",
		                             "underline-prefix"   => "\\ul{", // the '\ul' command requires '\usepackage{soul}'
		                             "underline-suffix"   => "}",
		                             "endash"             => "--", // or use '{\\textendash}'
		                             "emdash"             => "---", // or use '{\\textemdash}'
		                             "ampersand"          => "&", // conversion of ampersands is done below, after the citation has been generated
		                             "double-quote"       => '"',
		                             "double-quote-left"  => "{\\textquotedblleft}",
		                             "double-quote-right" => "{\\textquotedblright}",
		                             "single-quote"       => "'", // same as for ampersands
		                             "single-quote-left"  => "{\\textquoteleft}",
		                             "single-quote-right" => "{\\textquoteright}",
		                             "less-than"          => "<",
		                             "greater-than"       => ">",
		                             "newline"            => "\n\n"
		                            );

		// Defines search & replace 'actions' that will be applied upon LaTeX output to all those refbase fields that are listed
		// in the corresponding 'fields' element:
		$latexSearchReplaceActionsArray = array(
		                                        array('fields'  => array("title", "publication", "abbrev_journal", "address", "keywords", "abstract", "orig_title", "series_title", "abbrev_series_title", "notes"),
		                                              'actions' => $transtab_refbase_latex
		                                             )
		                                       );

		// For CLI queries, we'll allow paging thru the result set, i.e. we honour the values of the CLI options '-S|--start' ('$rowOffset')
		// and '-R|--rows' ('$showRows') ('$rowOffset' and '$showRows' are re-assigned in function 'seekInMySQLResultsToOffset()' in 'include.inc.php')
		if (preg_match("/^cli/i", $client)) // if the query originated from a command line client such as the "refbase" CLI client ("cli-refbase-1.0")
			$showMaxRows = $showRows; // show only rows up to the value given in '$showRows'
		else
			$showMaxRows = $rowsFound; // otherwise show all rows


		// Setup the basic .bbl document structure:
		$latexData = "\\begin{thebibliography}{" . $showMaxRows . "}\n\n";

		// Add header with .bst style-specific declarations:
		$latexData .= $bblHeader;


		// LOOP OVER EACH RECORD:
		// Fetch one page of results (or less if on the last page)
		// (i.e., upto the limit specified in $showMaxRows) fetch a row into the $row array and ...
		for ($rowCounter=0; (($rowCounter < $showMaxRows) && ($row = @ mysqli_fetch_array($result))); $rowCounter++)
		{
			foreach ($row as $rowFieldName => $rowFieldValue)
				// Apply search & replace 'actions' to all fields that are listed in the 'fields' element of the arrays contained in '$latexSearchReplaceActionsArray':
				foreach ($latexSearchReplaceActionsArray as $fieldActionsArray)
					if (in_array($rowFieldName, $fieldActionsArray['fields']))
						$row[$rowFieldName] = searchReplaceText($fieldActionsArray['actions'], $row[$rowFieldName], true); // function 'searchReplaceText()' is defined in 'include.inc.php'


			// Order attributes according to the chosen output style & record type:
			$record = citeRecord($row, $citeStyle, $citeType, $markupPatternsArray, false); // function 'citeRecord()' is defined in the citation style file given in '$citeStyleFile' (which, in turn, must reside in the 'cite' directory of the refbase root directory), see function 'generateCitations()'


			// Print out the current record:
			if (!empty($record)) // unless the record buffer is empty...
			{
				// This is a stupid hack that maps the names of the '$row' array keys to those used
				// by the '$formVars' array (which is required by function 'generateCiteKey()')
				// (eventually, the '$formVars' array should use the MySQL field names as names for its array keys)
				$formVars = buildFormVarsArray($row); // function 'buildFormVarsArray()' is defined in 'include.inc.php'

				// Generate or extract the cite key for this record:
				// NOTE: currently, the following placeholders are not available for citation output:
				//       <:keywords:>, <:issn:>, <:area:>, <:notes:>, <:userKeys:>
				//       if the cite key specification uses one of these placeholders, it will get ignored
				$citeKey = generateCiteKey($formVars); // function 'generateCiteKey()' is defined in 'include.inc.php'

				// The '\bibitem' command requires a cite key, which is why we'll include the record's serial number
				// even when the user's export options specify 'export_cite_keys=no' or 'autogenerate_cite_keys=no':
				// NOTE: maybe we should always generate a cite key here, even if 'export_cite_keys=no' or 'autogenerate_cite_keys=no'??
				if (empty($citeKey))
					$citeKey = $row['serial'];

				// Generate the \bibitem option string that's used to build the proper text citation:
				$bibItemOptionShortString = parsePlaceholderString($formVars, $bibItemOptionShort, "<:authors[2| and | et~al.]:><(:year:)>"); // function 'parsePlaceholderString()' is defined in 'include.inc.php'

				if (!empty($bibItemOptionFull) AND preg_match("/^[^;]+(;[^;]+){" . $maxAuthorCountInShortAuthorList . "}/", $row['author'])) // if the 'author' field does contain more authors as specified in '$maxAuthorCountInShortAuthorList'
				{
					// include full author list:
					$bibItemOptionString = parsePlaceholderString($formVars, $bibItemOptionFull, "<:authors[2| and | et~al.]:><(:year:)><:authors[0|, |]:>");
					$bibItemOptionString = preg_replace("/_#_§_~_(?!.*?_#_§_~_)/", $betweenLastAuthorsDelim, $bibItemOptionString); // replace last occurrence of "_#_§_~_"
					$bibItemOptionString = preg_replace("/_#_§_~_/", $betweenFullAuthorsDelim, $bibItemOptionString); // replace all other occurrences of "_#_§_~_"
				}
				else // only include short author list:
					$bibItemOptionString = $bibItemOptionShortString;

				// In case of duplicate text citation strings, append a letter to the year in the \bibitem option string as well as in the formatted reference:
				// NOTE: - this is not fool proof and currently only works if there are no more than 26 duplicate text citations (letters a-z)
				//       - the below replace actions get triggered on the first four-digit number that happens to be identical to the record's year, but depending on the reference format, this may not be the actual year of the reference but some other number!
				for ($i=0; isset($bibItemsArray[$bibItemOptionShortString]); $i++)
				{
					// Update the existing \bibitem entry (that has an identical text citation string) and append an "a" to it's year items:
					if ($i == 0)
					{
						$dedupPrefixQuoted = preg_quote($dedupPrefix, "/"); // escape meta characters (including '/' that is used as delimiter for the PCRE replace functions below and which gets passed as second argument)
						$dedupSuffixQuoted = preg_quote($dedupSuffix, "/");

						$oldBibItemOptionShortString = preg_replace("/^\[(.+)\]$/", "\\1", $bibItemOptionShortString); // remove square brackets from short \bibitem option string (which is required for the subsequent 'str_replace()' action to work with short and full option strings)
						$newBibItemOptionShortString = preg_replace("/(" . $row['year'] . ")(" . $dedupPrefixQuoted . "[a-z]*" . $dedupSuffixQuoted . ")*/", "\\1" . $dedupPrefix . "a" . $dedupSuffix, $oldBibItemOptionShortString, 1);
						$bibItemsArray[$bibItemOptionShortString] = str_replace($oldBibItemOptionShortString, $newBibItemOptionShortString, $bibItemsArray[$bibItemOptionShortString]);
						$bibItemsArray[$bibItemOptionShortString] = preg_replace("/(" . $row['year'] . ")(" . $dedupPrefixQuoted . "[a-z]*" . $dedupSuffixQuoted . ")*(?!.*?" . $row['year'] . ")/", "\\1" . $dedupPrefix . "a" . $dedupSuffix, $bibItemsArray[$bibItemOptionShortString], 1); // note that this will fail if the formatted reference contains a number after the year that is identical to the year!
					}

					// Append a letter to the year items of the current \bibitem entry:
					$bibItemOptionShortString = preg_replace("/(" . $row['year'] . ")(" . $dedupPrefixQuoted . "[a-z]*" . $dedupSuffixQuoted . ")*/e", "'\\1$dedupPrefix'.chr(98 + $i).'$dedupSuffix'", $bibItemOptionShortString, 1); // the 'e' modifier allows to execute PHP code within the replacement pattern
					$bibItemOptionString = preg_replace("/(" . $row['year'] . ")(" . $dedupPrefixQuoted . "[a-z]*" . $dedupSuffixQuoted . ")*/e", "'\\1$dedupPrefix'.chr(98 + $i).'$dedupSuffix'", $bibItemOptionString, 1);
					$record = preg_replace("/(" . $row['year'] . ")(" . $dedupPrefixQuoted . "[a-z]*" . $dedupSuffixQuoted . ")*/e", "'\\1$dedupPrefix'.chr(98 + $i).'$dedupSuffix'", $record, 1);
				}


				// Attempt to convert higher ASCII chars (i.e., characters with an ASCII value of >= 128) to their corresponding LaTeX entities:
				if ($contentTypeCharset == "UTF-8")
					$recordEncoded = searchReplaceText($transtab_unicode_latex, $record, false); // function 'searchReplaceText()' is defined in 'include.inc.php'
				else
					$recordEncoded = searchReplaceText($transtab_latin1_latex, $record, false);

				// We have to make sure that the \bibitem option string also contains proper LaTeX entities:
				if ($contentTypeCharset == "UTF-8")
					$bibItemOptionStringEncoded = searchReplaceText($transtab_unicode_latex, $bibItemOptionString, false);
				else
					$bibItemOptionStringEncoded = searchReplaceText($transtab_latin1_latex, $bibItemOptionString, false);


				// Copy the current \bibitem entry to the array of generated \bibitem entries:
				$bibItemsArray[$bibItemOptionShortString] = $bibItemCommand . $bibItemOptionStringEncoded . "{" . $citeKey . "} " . $recordEncoded;
			}
		}

		$latexData .= implode("\n\n", $bibItemsArray) . "\n\n";

		$latexData .= "\\end{thebibliography}\n\n";

		return $latexData;
	}

	// --- END CITATION FORMAT ---
?>
