Newer
Older
import React, { useState, useEffect } from "react";
import bibtexParse from 'bibtex-parser-js';
interface BibEntry {
ENTRYTYPE: string;
journal?: string;
volume?: string;
pages?: string;
year?: string;
doi?: string;
[key: string]: any;
interface BibtexParserProps {
bibtexSources: string[]; // Accept an array of BibTeX strings
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
function formatPages(pages: string | undefined): JSX.Element | null {
// Check if pages is provided and is a non-empty string
if (pages && pages.length > 0) {
// Check for common page range separators
const pageRangeRegex = /--|-|–|–/; // RegEx to match various dash types
if (pageRangeRegex.test(pages)) {
const pag = pages.split(pageRangeRegex).map(p => p.trim());
const begin = pag[0];
const end = pag[1];
// Return formatted JSX
return (
<>
, <span property="schema:pageBegin">{begin}</span>-<span property="schema:pageEnd">{end}</span>
</>
);
} else if (/^\d+(-\d+)?$/.test(pages)) {
// If pages is a single numeric range, return it directly
return (
<>
, <span property="schema:pageBegin">{pages}</span>
</>
);
} else {
// Handle non-numeric page info
console.warn(`Non-numeric page information detected ('${pages}'). Treating as missing.`);
return null; // Return null if invalid
}
} else {
console.warn("Sorry, no page information.");
return null; // Return null if no page info
}
}
export const BibtexParser: React.FC<BibtexParserProps> = ({ bibtexSources , special, start}) => {
const [parsedEntries, setParsedEntries] = useState<BibEntry[]>([]);
//console.log("Parsing BibTeX sources: ", bibtexSources);
try {
const allEntries: BibEntry[] = [];
bibtexSources.forEach((bibtex) => {
// console.log(`Parsing BibTeX entry #${index + 1}: `, bibtex);
allEntries.push(...parsed);
});
setParsedEntries(allEntries);
//console.log("All parsed entries: ", allEntries);
alert("An error occurred while parsing the BibTeX entries. Please check the format." + bibtexSources);
// Helper function to render AUTHORS
const formatAuthors = (authors: string): string => {
//console.log("Original input:", authors);
// Bereinigen des Eingabestrings und Ersetzen von "and" durch "|"
const cleanedAuthors = authors
.replace(/\s*and\s*/g, "|") // "and" durch "|" ersetzen
.replace(/\{|\}/g, "") // geschweifte Klammern entfernen
.trim();
//console.log("Cleaned authors string:", cleanedAuthors);
// Autoren in ein Array aufteilen
const authorList = cleanedAuthors.split("|").map(author => author.trim());
//console.log("Split author list:", authorList);
// Maximale Anzahl der anzuzeigenden Autoren
const maxAuthors = 7;
// Formatiere jeden Autor
const formattedAuthors = authorList.map((author, _index) => {
//console.log(`Processing author #${index + 1}:`, author);
// Nachname und Vornamen aufteilen
const [last, firstNames] = author.includes(",") ?
author.split(",").map(part => part.trim()) :
['', author]; // Wenn kein Komma vorhanden ist, wird der gesamte Name als Vorname behandelt
// console.log(`Last name: "${last}", First names: "${firstNames}"`);
// Initialen für Vornamen erstellen
const initials = firstNames.split(' ').map(n => n[0] + '.').join(' ');
//console.log(`Initials for "${firstNames}": "${initials}"`);
const formattedName = `${last}, ${initials}`.trim(); // Rückgabe des formatierten Namens
//console.log(`Formatted name: "${formattedName}"`);
//console.log("Formatted authors before adding et al.:", formattedAuthors);
// Kombiniere die formatierten Autoren mit korrekter Interpunktion
const output = formattedAuthors.slice(0, maxAuthors).join('; ') +
(formattedAuthors.length > maxAuthors ? ' et al.' : '');
//console.log("Final output:", output);
// Helper function to render individual citations based on their type
const renderCitation = (entry: BibEntry, index: number) => {
// console.log(`Rendering citation for entry #${index + 1}: `, entry);
// Use the index as citation number
let citationNumber = index +1;
if(start){
citationNumber += start -1;
}
const entryType = entry.entryType.toLowerCase(); // Convert to lowercase for consistent comparison
const entryTags = entry.entryTags; // Adjust based on your data structure
// console.log("Entry Tags: ", entryTags);
switch (entryType) {
<li key={index} typeof="schema:ScholarlyArticle" role="doc-biblioentry" property="schema:citation" id={`desc-${citationNumber}${specialthing}`}>
{/* Citation number as comment */}
{/*<!-- Citation num ${citationNumber} --> */}
{formatAuthors(entryTags.AUTHOR || entryTags.EDITOR || "")}
<span property="schema:name">{entryTags.TITLE.replace(/[?!.]/g, '').replace(/\n/g, ' ').trim()}.</span>
<i property="schema:publisher" typeof="schema:Organization">{entryTags.JOURNAL}</i>
<b property="issueNumber" typeof="PublicationIssue">{entryTags.VOLUME}</b>
{formatPages(entryTags.PAGES) && <span>{formatPages(entryTags.PAGES)}</span>}
{entryTags.YEAR && (
<span> (<time property="schema:datePublished" datatype="xsd:gYear" dateTime={entryTags.YEAR}>{entryTags.YEAR}</time>).</span>
)}
{entryTags.DOI && (
<span> <a className="doi" href={`https://doi.org/${entryTags.DOI}`}>doi: {entryTags.DOI}</a></span>
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<li key={index} typeof="schema:Book" role="doc-biblioentry" property="schema:citation" id={`desc-${citationNumber}`}>
{/* Render authors */}
{formatAuthors(entryTags.AUTHOR || entryTags.EDITOR || "")}
{/* Render title or booktitle */}
{entryTags.TITLE ? (
<span property="schema:name"> {entryTags.TITLE.replace(/[?!.]/g, '').replace(/\n/g, ' ').trim()}.</span>
) : entryTags.BOOKTITLE ? (
<span property="schema:name"> {entryTags.BOOKTITLE.replace(/[?!.]/g, '').replace(/\n/g, ' ').trim()}.</span>
) : (
console.warn(`No title or booktitle found for entry ${citationNumber}`)
)}
{/* Render publisher */}
{entryTags.PUBLISHER && (
<i property="schema:publisher" typeof="schema:Organization">
{entryTags.PUBLISHER}
</i>
)}
{/* Render year */}
{entryTags.YEAR && (
<span>
(<time property="schema:datePublished" datatype="xsd:gYear" dateTime={entryTags.YEAR}>
{entryTags.YEAR}
</time>).
</span>
)}
{entryTags.ISBN && (
<span property="isbn"> {entryTags.ISBN}</span>
)
}
<li key={index} typeof="schema:WebPage" role="doc-biblioentry" property="schema:citation" id={`desc-${citationNumber}`}>
{/* Render authors */}
<span property="schema:name">. {entryTags.TITLE.replace(/[?!.]/g, '').replace(/\n/g, ' ').trim()}.</span>
)}
{/* Render howpublished */}
{entryTags.HOWPUBLISHED && (
<i property="schema:publisher" typeof="schema:Organization"> {entryTags.HOWPUBLISHED}</i>
)}
{/* Render year */}
{entryTags.YEAR && (
<span> (<time property="schema:datePublished" datatype="xsd:gYear" dateTime={entryTags.YEAR}>{entryTags.YEAR}</time>).</span>
)}
// Handle additional entry types here
case "inproceedings":
return (
<li key={index}>
<span>{formatAuthors(entryTags.AUTHOR || "")}</span>
<span>{entryTags.TITLE}</span>. In <i>{entryTags.BOOKTITLE}</i>,
<b>{entryTags.editor}</b>, {entryTags.YEAR}.
<span>{formatAuthors(entryTags.AUTHOR || "")}</span>
<span>{entryTags.TITLE}</span>, PhD thesis, {entryTags.SCHOOL}, {entryTags.YEAR}.
console.warn(`Unknown entry type: ${entryType}`);
return <li key={index}>Unknown entry type: {entryType}</li>;
let startnumber = 1;
if(start) {
startnumber = start;
}
{parsedEntries.length === 0 ? (
<p>No citations available.</p>
) : (
{parsedEntries.map((entry, index) => renderCitation(entry, index))}
</ol>
)}