7 Commits
Author SHA1 Message Date
Frederik Möllers 3f104a22b9 Ignore MacOS .DS* files 2025-08-14 01:05:42 +02:00
Frederik Möllers 63dc0d58bb Use self-hosted JavaScript libraries
Add iFrameResizer for when the publication lists are included via an
iframe.
Add self-hosted copies of jQuery and MathJax.
Fix some styling in the code and in the HTML via CSS
2025-08-14 01:03:54 +02:00
Frederik Möllers c0e8d54438 Slight improvements
1. Ignore /temp in git
2. Use bibtexbrowser_configure instead of DEFINE in ...local.php
3. In makehtml.sh, adapt to Mac OS if it is detected
2025-08-01 00:56:14 +02:00
Frederik Möllers e259e5e131 Build custom URLs to point to our static files 2025-07-30 02:36:11 +02:00
Frederik Möllers 52b67afd92 ZRD-specific changes and generation of first draft 2025-07-30 02:10:54 +02:00
Martin Monperrus 7248783ff4 add support for venue pagination 2025-05-02 21:50:14 +02:00
Martin Monperrus 3a08ff063e add test for multisearch 2025-03-21 20:36:46 +01:00
25 changed files with 544 additions and 15 deletions
+6
View File
@@ -0,0 +1,6 @@
# ignore generated artifacts
/artifacts
# ignore temporary directory if it remains after testing or so
/temp
# ignore Mac OS hidden files
/**/.DS_Store
+117
View File
@@ -1403,6 +1403,123 @@ class BibtexbrowserTest extends PHPUnit_Framework_TestCase {
$this->assertFalse($entry1->hasPhrase('')); // Empty phrase should not match $this->assertFalse($entry1->hasPhrase('')); // Empty phrase should not match
} }
function testMultiSearchWithSpecialChars() {
// Create test entries with C/C++ related content
$bibtex = "@article{cpp2023,
title={Advances in C/C++ Programming Language},
author={Jane Programmer},
journal={Journal of Programming Languages},
year=2023,
keywords={C/C++, programming languages, compilers}
}
@inproceedings{java2023,
title={Java vs Python: Performance Comparison},
author={John Coder},
booktitle={International Conference on Software Engineering},
year=2023,
keywords={Java, Python, performance}
}";
$test_data = fopen('php://memory','x+');
fwrite($test_data, $bibtex);
fseek($test_data, 0);
$db = new BibDataBase();
$db->update_internal("inline", $test_data);
// Test searching for C/C++ (which contains special characters / and +)
$q = array(Q_SEARCH => 'C/C++');
$results = $db->multisearch($q);
// Should match only the first entry
$this->assertEquals(1, count($results));
$this->assertEquals('Advances in C/C++ Programming Language', $results[0]->getTitle());
// Test searching with escaped slashes
$q = array(Q_SEARCH => 'C/C\+\+');
$results = $db->multisearch($q);
$this->assertEquals(1, count($results));
// Test with partial match
$q = array(Q_SEARCH => 'C/C');
$results = $db->multisearch($q);
$this->assertEquals(1, count($results));
// Test with keywords field specifically
$q = array(Q_TAG => 'C/C++');
$results = $db->multisearch($q);
$this->assertEquals(1, count($results));
// Test searching for something that doesn't exist
$q = array(Q_SEARCH => 'Rust');
$results = $db->multisearch($q);
$this->assertEquals(0, count($results));
}
function test_venuevc_pagination() {
// Define the page size for pagination
bibtexbrowser_configure('VENUE_SIZE', 2);
// Create a test BibTeX database with multiple entries
$bibtex = "@article{paper1,title={Paper One},journal={Journal A},year=2020}
@article{paper2,title={Paper Two},journal={Journal A},year=2020}
@article{paper3,title={Paper Three},journal={Journal B},year=2020}
@article{paper4,title={Paper Four},journal={Journal B},year=2020}
@article{paper5,title={Paper Five},journal={Journal C},year=2020}
@article{paper6,title={Paper Six},journal={Journal C},year=2020}";
$test_data = fopen('php://memory','r+');
fwrite($test_data, $bibtex);
fseek($test_data, 0);
$db = new BibDataBase();
$db->update_internal("inline", $test_data);
// Create VenueVC display
$display = new MenuManager();
$display->setDB($db);
// First, test without pagination parameter
$_GET["venue_page"] = '1';
ob_start();
$display->display();
$output = ob_get_clean();
// Verify all entries are shown when no pagination is specified
$this->assertStringContainsString('Journal A', $output);
$this->assertStringContainsString('Journal B', $output);
// Test with pagination parameter
$_GET["venue_page"] = '1';
ob_start();
$display->display();
$output1 = ob_get_clean();
// Create XML parser to properly analyze the HTML structure
$xml = new SimpleXMLElement("<doc>".$output1."</doc>");
// Count number of entries displayed on first page
//$result = $xml->xpath('//tr[contains(@class, "btb-menu-items")]');
//$this->assertEquals($PAGE_SIZE, count($result));
// Verify pagination links existence
$this->assertStringContainsString('venue_page=2', $output1);
// Test second page
$_GET["venue_page"] = '2';
ob_start();
$display->display();
$output2 = ob_get_clean();
// Verify navigation links
$this->assertStringContainsString('venue_page=1', $output2); // Link to previous page
// Verify different entries on second page
$this->assertStringContainsString('Journal C', $output2);
// Clean up
unset($_GET["venue_page"]);
}
} // end class } // end class
// Test implementation that records events // Test implementation that records events
+48
View File
@@ -0,0 +1,48 @@
<?php
/**
* A helper Display class that is just like SimpleDisplay but just never
* outputs section headers (i.e. year numbers). Used by YearCatDisplay.
**/
class NoHeaderDisplay extends SimpleDisplay {
function changeSection($pred, $bib) {
return false;
}
}
/**
* A modified "Academic" display, with reversed grouping. First grouping is by
* year, then by category. Uses NoHeaderDisplay to not have year numbers within
* categories.
*/
class YearCatDisplay extends AcademicDisplay {
/** an array of strings representing years */
var $yearIndex;
/** transforms a query to HTML
* $ query is an array (e.g. array(Q_YEAR=>'2005'))
* $title is a string, the title of the section
*/
function search2html($query, $title) {
$entries = $this->db->multisearch($query);
if (count($entries)>0) {
echo "\n".'<div class="theader">'.$title.'</div>'."\n";
}
$display = new NoHeaderDisplay();
$display->setEntries($entries);
$display->display();
}
function display() {
$this->db = createBibDataBase();
$this->db->bibdb = $this->entries;
$this->yearIndex = $this->db->yearIndex();
foreach($this->yearIndex as $year) {
echo "\n".'<div class="sheader">'.$year.'</div>'."\n";
foreach (_DefaultBibliographySections() as $section) {
$this->search2html(array_merge(array(Q_YEAR=>$year), $section['query']),$section['title']);
}
}
}
}
?>
+39
View File
@@ -0,0 +1,39 @@
@import url("/static/fonts/manrope.css");
body {
color: rgba(0, 0, 0, 0.8);
font-family: "Manrope",Arial,sans-serif;
font-weight: 500;
line-height: 1.8;
margin: 0;
}
.rheader {
display: none;
}
.sheader {
font-size: 1.5rem;
font-weight: 600;
padding-top: 1.5em;
padding-bottom: .5em;
}
.theader {
display: block;
font-size: 1.25rem;
font-weight: 600;
padding-top: .5em;
padding-bottom: .5em;
}
td.bibref {
display: none;
}
td.bibitem {
padding-left: 1.5rem;
display: block;
}
a {
color: #C01632;
text-decoration: underline;
outline: none;
}
a:hover {
text-decoration: none;
}
+19
View File
@@ -0,0 +1,19 @@
<?php
global $BIBTEXBROWSER_LANG;
$BIBTEXBROWSER_LANG=array();
$BIBTEXBROWSER_LANG['Bachelor\'s thesis'] = "Bachelorarbeit";
$BIBTEXBROWSER_LANG['Books'] = 'Bücher';
$BIBTEXBROWSER_LANG['Book Chapters'] = "Buchbeiträge";
$BIBTEXBROWSER_LANG['Chapter in'] = "Kapitel in";
$BIBTEXBROWSER_LANG['In'] = "In";
$BIBTEXBROWSER_LANG['Master\'s thesis'] = "Masterarbeit";
$BIBTEXBROWSER_LANG['No date'] = "Kein Datum";
$BIBTEXBROWSER_LANG['No publications present'] = "Keine Publikationen vorhanden";
$BIBTEXBROWSER_LANG['Other Publications'] = "Andere Veröffentlichungen";
$BIBTEXBROWSER_LANG['PhD thesis'] = "Dissertation";
$BIBTEXBROWSER_LANG['Refereed Articles'] = "Zeitschriftenbeiträge";
$BIBTEXBROWSER_LANG['Refereed Conference Papers'] = "Konferenzbeiträge";
$BIBTEXBROWSER_LANG['Refereed Workshop Papers'] = "Workshopbeiträge";
$BIBTEXBROWSER_LANG['Technical report'] = "Technischer Bericht";
@define('LAST_AUTHOR_SEPARATOR',' und ');
?>
+63
View File
@@ -0,0 +1,63 @@
<?php
bibtexbrowser_configure('ABBRV_TYPE','key');
// use tabular layout (HTML tables)
bibtexbrowser_configure('BIBTEXBROWSER_LAYOUT','table');
// URL to individual files
bibtexbrowser_configure('BIBTEXBROWSER_URL',"https://publications.zrd-saar.de/");
// URL to jQuery
bibtexbrowser_configure('JQUERY_URI', '/static/jquery-3.6.4.min.js');
// URL to MathJax
bibtexbrowser_configure('MATHJAX_URI', '/static/TeX-AMS_HTML.V2.7.1.js');
// target for links
bibtexbrowser_configure('BIBTEXBROWSER_LINKS_TARGET','_blank');
// use IEEE Transactions-like style, e.g. puts authors in front of title
bibtexbrowser_configure('BIBLIOGRAPHYSTYLE', 'JanosBibliographyStyle');
//bibtexbrowser_configure('BIBLIOGRAPHYSECTIONS','AGSorgeBibliographySections');
// Allow "Firstname Lastname" as well as "Lastname, Firstname" for authors
bibtexbrowser_configure('USE_FIRST_THEN_LAST',true);
// Enable all metadata generation
bibtexbrowser_configure('METADATA_COINS',true); // see https://en.wikipedia.org/wiki/COinS
bibtexbrowser_configure('METADATA_GS',true); // metadata google scholar
bibtexbrowser_configure('METADATA_DC',true); // see http://dublincore.org/
bibtexbrowser_configure('METADATA_OPENGRAPH',true); // see http://ogp.me/
bibtexbrowser_configure('METADATA_EPRINTS',true); // see https://wiki.eprints.org/w/Category:EPrints_Metadata_Fields
// include language config
if(isset($_GET['language']))
{
include(preg_replace('/local\.php$/',$_GET['language'].'.php',__FILE__));
}
// Order entries by year, but reverse the order (newest on top)
bibtexbrowser_configure('ORDER_FUNCTION','compare_bib_entry_by_year_reverse');
function compare_bib_entry_by_year_reverse($a, $b)
{
return 0 - compare_bib_entry_by_year($a, $b);
}
// A custom URL builder for the static files we create
bibtexbrowser_configure('BIBTEXBROWSER_URL_BUILDER', 'url_builder_static');
function url_builder_static($bibentry) {
return BIBTEXBROWSER_URL.'keys/'.$bibentry->getKey().'.html';
}
// A custom function for the MathJax footer to use the static URL instead of the CDN one
// Also include iframeResizer JS
function javascript_math() {
?>
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
}
};
</script>
<script type="text/javascript" id="MathJax-script" async src="/static/tex-mml-chtml.js">
</script>
<script type="text/javascript" id="iFrameResizer" src="/static/iframe-resizer.child.js">
</script>
<?php
}
?>
+15 -13
View File
@@ -181,6 +181,7 @@ if (defined('ENCODING')) {
@define('YEAR_SIZE',20); // number of years per table @define('YEAR_SIZE',20); // number of years per table
@define('AUTHORS_SIZE',30); // number of authors per table @define('AUTHORS_SIZE',30); // number of authors per table
@define('TAGS_SIZE',30); // number of keywords per table @define('TAGS_SIZE',30); // number of keywords per table
@define('VENUE_SIZE',30); // number of venues per table
@define('READLINE_LIMIT',1024); @define('READLINE_LIMIT',1024);
@define('Q_YEAR', 'year'); @define('Q_YEAR', 'year');
@define('Q_YEAR_PAGE', 'year_page'); @define('Q_YEAR_PAGE', 'year_page');
@@ -2874,7 +2875,6 @@ usage:
$db = zetDB('bibacid-utf8.bib'); $db = zetDB('bibacid-utf8.bib');
$menu = new MenuManager(); $menu = new MenuManager();
$menu->setDB($db); $menu->setDB($db);
$menu->year_size=100;// should display all years :)
$menu->display(); $menu->display();
</pre> </pre>
*/ */
@@ -2883,11 +2883,6 @@ class MenuManager {
/** The bibliographic database, an instance of class BibDataBase. */ /** The bibliographic database, an instance of class BibDataBase. */
var $db; var $db;
var $type_size = TYPES_SIZE;
var $year_size = YEAR_SIZE;
var $author_size = AUTHORS_SIZE;
var $tag_size = TAGS_SIZE;
function __construct() { function __construct() {
} }
@@ -2952,18 +2947,25 @@ class MenuManager {
} }
else $page = 1; else $page = 1;
$this->displayMenu('Types', $types, $page, $this->type_size, Q_TYPE_PAGE, Q_INNER_TYPE); $this->displayMenu('Types', $types, $page, bibtexbrowser_configuration("TYPES_SIZE"), Q_TYPE_PAGE, Q_INNER_TYPE);
} }
/** Displays and controls the venues. */ /** Displays and controls the venues. */
function venueVC() { function venueVC() {
// retrieve authors list to display // retrieve venues list to display
$data = $this->db->venueIndex(); $venues = $this->db->venueIndex();
$this->displayMenu('Venues', $data, 1, 100000, Q_SEARCH, // determine the venues page to display
if (isset($_GET['venue_page'])) {
$page = $_GET['venue_page'];
} else $page = 1;
if (count($venues) > 0) {
$this->displayMenu('Venues', $venues, $page, bibtexbrowser_configuration("VENUE_SIZE"), 'venue_page',
Q_SEARCH); Q_SEARCH);
} }
}
/** Displays and controls the authors menu in a table. */ /** Displays and controls the authors menu in a table. */
function authorVC() { function authorVC() {
@@ -2977,7 +2979,7 @@ class MenuManager {
else $page = 1; else $page = 1;
$this->displayMenu('Authors', $authors, $page, $this->author_size, Q_AUTHOR_PAGE, $this->displayMenu('Authors', $authors, $page, bibtexbrowser_configuration("AUTHORS_SIZE"), Q_AUTHOR_PAGE,
Q_AUTHOR); Q_AUTHOR);
} }
@@ -2992,7 +2994,7 @@ class MenuManager {
} else $page = 1; } else $page = 1;
if (count($tags)>0) $this->displayMenu('Keywords', $tags, $page, $this->tag_size, Q_TAG_PAGE, if (count($tags)>0) $this->displayMenu('Keywords', $tags, $page, bibtexbrowser_configuration("MENU_SIZE"), Q_TAG_PAGE,
Q_TAG); Q_TAG);
} }
@@ -3008,7 +3010,7 @@ class MenuManager {
else $page = 1; else $page = 1;
$this->displayMenu('Years', $years, $page, $this->year_size, Q_YEAR_PAGE, $this->displayMenu('Years', $years, $page, bibtexbrowser_configuration("YEAR_SIZE"), Q_YEAR_PAGE,
Q_YEAR); Q_YEAR);
} }
Executable
+57
View File
@@ -0,0 +1,57 @@
#!/bin/bash
# set some paths/binary names depending on the OS
case "$(uname -s)" in
"Darwin")
PHP="php83"
;;
# "Linux" is Linux
*)
PHP="php"
;;
esac
# URL of the Bibtex file
BIBTEX_URL="https://cloud.hiz-saarland.de/public.php/dav/files/Yj8FtZsTS9TkFWG"
# command to run BibtexBrowser
BIBTEXBROWSER="${PHP} -c \"php_cli.ini\" -f \"bibtexbrowser.php\""
# remove any remaining artifacts and temporary files
rm -rf "artifacts" "temp"
# create output directories and download bibtex file
mkdir -p "artifacts/keys" "temp"
wget -O "temp/zrd.bib" "$BIBTEX_URL"
# if `bibtool` is available, sanitize the bibtex file
if which bibtool >/dev/null 2>&1
then
bibtool "temp/zrd.bib" > "temp/zrd.new.bib"
echo "Bibtool successful!"
mv -f "temp/zrd.new.bib" "temp/zrd.bib"
fi
# copy static files
cp -fR "static" "artifacts/"
for WEBSITE_LANGUAGE in german
do :
# generate full index
eval "$BIBTEXBROWSER \"bib=temp/zrd.bib\" all display=YearCatDisplay language=$WEBSITE_LANGUAGE > \"artifacts/all.${WEBSITE_LANGUAGE}.html\""
# generate index for each person
while read LINE
do :
ALIAS="$(echo "$LINE" | cut -d ':' -f 1)"
SEARCHSTRING="$(echo "$LINE" | cut -d ':' -f 2)"
eval "$BIBTEXBROWSER \"bib=temp/zrd.bib\" \"author=$SEARCHSTRING\" academic=1 language=$WEBSITE_LANGUAGE > \"artifacts/${ALIAS}.${WEBSITE_LANGUAGE}.html\""
done < "persons.txt"
done
# generate page for each key
egrep '^@' "temp/zrd.bib" | sed -e 's/.*\t \(.*\),/\1/' | while read KEY
do :
eval "$BIBTEXBROWSER \"bib=temp/zrd.bib\" \"key=$KEY\" > \"artifacts/keys/${KEY}.html\""
done
# Clean up
rm -rf "temp"
rm bibtexbrowser_*.dat
+16
View File
@@ -0,0 +1,16 @@
ajla:Ajla Hajric
anastasiia:Anastasiia Babych
andreas:Andreas Rebmann
anna:Anna Zichler
frederik:Frederik Möllers
greta:Greta Böttcher
jochen:Jochen Krüger
lina:Lina Nauerz
max:Maximilian Eichacker
natascha:Natascha Schliwinski
niklas:Niklas Dahlem
piotr:Piotr Rataj
simone:Simone Salemi
stephanie:Stephanie Vogelgesang
theresa:Theresa Moll
tim:Tim Schneider
+1
View File
@@ -0,0 +1 @@
auto_prepend_file = "prepend.php"
+3
View File
@@ -0,0 +1,3 @@
<?php
parse_str(implode('&', array_slice($argv, 1)), $_GET);
?>
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+62
View File
@@ -0,0 +1,62 @@
/* manrope-200 - latin_latin-ext */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Manrope';
font-style: normal;
font-weight: 200;
src: url('/static/fonts/manrope-v19-latin_latin-ext-200.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* manrope-300 - latin_latin-ext */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Manrope';
font-style: normal;
font-weight: 300;
src: url('/static/fonts/manrope-v19-latin_latin-ext-300.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* manrope-regular - latin_latin-ext */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Manrope';
font-style: normal;
font-weight: 400;
src: url('/static/fonts/manrope-v19-latin_latin-ext-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* manrope-500 - latin_latin-ext */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Manrope';
font-style: normal;
font-weight: 500;
src: url('/static/fonts/manrope-v19-latin_latin-ext-500.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* manrope-600 - latin_latin-ext */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Manrope';
font-style: normal;
font-weight: 600;
src: url('/static/fonts/manrope-v19-latin_latin-ext-600.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* manrope-700 - latin_latin-ext */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Manrope';
font-style: normal;
font-weight: 700;
src: url('/static/fonts/manrope-v19-latin_latin-ext-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* manrope-800 - latin_latin-ext */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Manrope';
font-style: normal;
font-weight: 800;
src: url('/static/fonts/manrope-v19-latin_latin-ext-800.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2
View File
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

File diff suppressed because one or more lines are too long