Citation generator added

This commit is contained in:
2024-10-28 19:08:33 -07:00
parent 9e55ba90e1
commit 2f26afb36f
3 changed files with 72 additions and 14 deletions

View File

@@ -2,7 +2,7 @@
abstract = {Human-robot interaction (HRI) research plays a pivotal role in shaping how robots communicate and collaborate with humans. However, conducting HRI studies, particularly those employing the Wizard-of-Oz (WoZ) technique, can be challenging. WoZ user studies can have complexities at the technical and methodological levels that may render the results irreproducible. We propose to address these challenges with HRIStudio, a novel web-based platform designed to streamline the design, execution, and analysis of WoZ experiments. HRIStudio offers an intuitive interface for experiment creation, real-time control and monitoring during experimental runs, and comprehensive data logging and playback tools for analysis and reproducibility. By lowering technical barriers, promoting collaboration, and offering methodological guidelines, HRIStudio aims to make human-centered robotics research easier, and at the same time, empower researchers to develop scientifically rigorous user studies.},
author = {O'Connor, Sean and Perrone, L. Felipe},
title = {HRIStudio: A Framework for Wizard-of-Oz Experiments in Human-Robot Interaction Studies (Late Breaking Report)},
booktitle={33rd IEEE International Conference on Robot and Human Interactive Communication (RO-MAN)},
booktitle={33rd IEEE International Conference on Robot and Human Interactive Communication},
year = {2024}
url = {https://soconnor.dev/publications/hristudio-lbr.pdf},
paperUrl = {/publications/hristudio-lbr.pdf},

View File

@@ -1,17 +1,18 @@
'use client';
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "~/components/ui/card";
import { Badge } from "~/components/ui/badge";
import { ArrowUpRight, FileText, Presentation } from "lucide-react";
import { ArrowUpRight, BookOpenText, FileText, Presentation } from "lucide-react";
import Link from "next/link";
import { parseBibtex } from "~/lib/bibtex";
import { useEffect, useState } from "react";
import type { Publication } from "~/lib/bibtex";
import { Badge } from "~/components/ui/badge";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "~/components/ui/card";
import { Skeleton } from "~/components/ui/skeleton";
import type { Publication } from "~/lib/bibtex";
import { parseBibtex } from "~/lib/bibtex";
export default function PublicationsPage() {
const [publications, setPublications] = useState<Publication[]>([]);
const [loading, setLoading] = useState(true);
const tagsToStrip = ['paperUrl', 'posterUrl'];
useEffect(() => {
fetch('/publications.bib')
@@ -23,6 +24,38 @@ export default function PublicationsPage() {
});
}, []);
const downloadBibtex = (pub: Publication) => {
const { title, authors, venue, year, doi, abstract, type, citationType, citationKey } = pub;
let bibtexEntry = `@${citationType}{${citationKey},\n`;
bibtexEntry += ` title = {${title}},\n`;
bibtexEntry += ` author = {${authors.join(' and ')}},\n`;
bibtexEntry += ` year = {${year}},\n`;
if (type === 'conference' || type === 'workshop') {
bibtexEntry += ` organization = {${venue}},\n`;
} else if (type === 'journal') {
bibtexEntry += ` journal = {${venue}},\n`;
} else if (type === 'thesis') {
bibtexEntry += ` school = {${venue}},\n`;
}
if (doi) {
bibtexEntry += ` doi = {${doi}},\n`;
}
if (abstract) {
bibtexEntry += ` abstract = {${abstract}},\n`;
}
bibtexEntry += `}\n`;
const blob = new Blob([bibtexEntry], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `refs.bib`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
};
return (
<div className="space-y-8">
<section className="prose prose-zinc dark:prose-invert max-w-none">
@@ -49,9 +82,9 @@ export default function PublicationsPage() {
<CardHeader className="pb-2">
<div className="flex items-center justify-between">
<CardTitle>{pub.title}</CardTitle>
{pub.url && (
{pub.paperUrl && (
<Link
href={pub.url}
href={pub.paperUrl}
target="_blank"
rel="noopener noreferrer"
className="text-muted-foreground hover:text-primary"
@@ -113,6 +146,14 @@ export default function PublicationsPage() {
</Badge>
</Link>
)}
<Badge
onClick={() => downloadBibtex(pub)}
className="cursor-pointer capitalize"
variant="outline"
>
<BookOpenText className="h-4 w-4" />
BibTeX
</Badge>
</div>
</CardContent>
</Card>

View File

@@ -8,12 +8,15 @@ export type Publication = {
paperUrl?: string;
posterUrl?: string;
abstract?: string;
citationType?: string;
citationKey?: string;
type: 'conference' | 'journal' | 'workshop' | 'thesis';
};
type BibTeXEntry = {
type: string;
fields: Record<string, string>;
citationKey: string;
};
function parseAuthors(authorString: string): string[] {
@@ -31,10 +34,11 @@ function parseAuthors(authorString: string): string[] {
function parseBibTeXEntry(entry: string): BibTeXEntry | null {
// Match the entry type and content
const typeMatch = entry.match(/^(\w+)\s*{\s*[\w\d-_]+\s*,/);
const typeMatch = entry.match(/^(\w+)\s*{\s*([\w\d-_]+)\s*,/);
if (!typeMatch) return null;
const type = typeMatch[1]!.toLowerCase();
const citationKey = typeMatch[2];
const content = entry.slice(typeMatch[0].length);
const fields: Record<string, string> = {};
@@ -68,7 +72,7 @@ function parseBibTeXEntry(entry: string): BibTeXEntry | null {
fields[currentField] = buffer.trim();
}
return { type, fields };
return { type, fields, citationKey: citationKey! };
}
export function parseBibtex(bibtex: string): Publication[] {
@@ -79,10 +83,21 @@ export function parseBibtex(bibtex: string): Publication[] {
.filter((entry): entry is BibTeXEntry => entry !== null);
return entries.map(entry => {
const publicationType =
entry.type === 'inproceedings' ? 'conference' :
entry.type === 'article' ? 'journal' :
entry.type === 'mastersthesis' ? 'thesis' : 'workshop';
const publicationType = (() => {
switch (entry.type) {
case 'inproceedings':
case 'conference':
return 'conference';
case 'article':
return 'journal';
case 'mastersthesis':
return 'thesis';
case 'workshop':
return 'workshop';
default:
return 'journal';
}
})();
return {
title: entry.fields.title?.replace(/[{}]/g, '') || '',
@@ -94,6 +109,8 @@ export function parseBibtex(bibtex: string): Publication[] {
paperUrl: entry.fields.paperurl,
posterUrl: entry.fields.posterurl,
abstract: entry.fields.abstract,
citationType: entry.type,
citationKey: entry.citationKey,
type: publicationType
};
});