diff --git a/_plugins/talk.rb b/_plugins/talk.rb
new file mode 100644
index 0000000..a37dab0
--- /dev/null
+++ b/_plugins/talk.rb
@@ -0,0 +1,82 @@
+# _plugins/bibtex_tag.rb
+module Jekyll
+ class TalkTag < Liquid::Block
+ def initialize(tag_name, markup, tokens)
+ super
+ @thumbnail_url, @pdf_url, @thumbnail_caption, @caption_url = markup.split(" ").map(&:strip)
+ end
+
+ # Generate a unique ID for this entry
+ unique_id = "bibtex-" + Random.hex(4)
+
+ def render(context)
+ text = super
+ site = context.registers[:site]
+ converter = site.find_converter_instance(Jekyll::Converters::Markdown)
+
+ # Set thumbnail string, distinguishing between videos and images
+ if @thumbnail_url.end_with?(".mp4")
+ thumbnail_string = "
"
+ else
+ thumbnail_string = "

"
+ end
+
+ # Set PDF string, if one is provided
+ pdf_string = ""
+ if @pdf_url && @pdf_url != ""
+ pdf_string = "
PDF"
+ end
+
+ # Set thumbnail caption, if one is provided
+ thumbnail_caption = ""
+ if @thumbnail_caption && @thumbnail_caption != ""
+ if @caption_url && @caption_url != ""
+ thumbnail_caption = "
"
+ else
+ thumbnail_caption = "
Credit: #{@thumbnail_caption}
"
+ end
+ end
+
+ # Wrap the BibTeX code in triple backticks and specify the language
+ bibtex_code = "```bibtex\n#{text.strip}\n```"
+
+ # Convert the BibTeX block using the Markdown converter
+ processed_bibtex = converter.convert(bibtex_code)
+
+ # Generate a unique ID for this entry
+ unique_id = "bibtex-" + Random.hex(4)
+
+ # Create the HTML structure
+ html = <<~HTML
+
+
+ #{thumbnail_string}
+ #{thumbnail_caption}
+
+
+
+
+
+
+
+
+ #{processed_bibtex}
+
+
+ #{text}
+
+
+
+ HTML
+
+ html
+ end
+ end
+end
+
+Liquid::Template.register_tag('talk', Jekyll::TalkTag)
diff --git a/_research/talks.md b/_research/talks.md
deleted file mode 100644
index 81665a7..0000000
--- a/_research/talks.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-title: Talks
-permalink: /research/talks/
----
-
-# 2024
-* **Invited talk**, _From Microspheres to Supermassive Stars: An overview of the University of Idaho’s Numerical Relativity group’s research_, Idaho National Laboratory, ID, USA.
-* **Invited talk**, North American Einstein Toolkit Summer School, _Direct-Collapse Black Holes: Gravitational-Wave Signatures of Massive Black Hole Formation_, Louisiana State University, LA, USA.
-* **Selected talk**, APS April Meeting, _Binary Neutron Star Mergers on a Moving Mesh_, SAFE Credit Union Convention Center, Sacramento, CA, USA.
-
-# 2023
-* **Invited talk**, INT 23-2: Astrophysical Neutrinos and the Origin of the Elements, _GRHayL: An Open-source, Modular, Extensible GRMHD Library_, Institute for Nuclear Theory, Seattle, WA, USA.
-* **Invited talk**, North American Einstein Toolkit Summer School, _Tutorial: Einstein Toolkit Simulation Analysis_, Rochester Institute of Technology, NY, USA.
-* **Selected talk**, APS April Meeting, _IllinoisGRMHD: Recent Developments and Future Plans_, Hilton Minneapolis, Minneapolis, MN, USA.
-
-# 2022
-* **Invited talk**, North American Einstein Toolkit Working Workshop, _An introduction to NRPy+_, University of Illinois at Urbana-Champaign, IL, USA.
-* **Invited talk**, North American Einstein Toolkit Summer School, _Accurate, long-term binary neutron stars simulations with IllinoisGRMHD and HARM+NUC_, University of Idaho, ID, USA.
-* **Selected talk**, APS April Meeting, _Accurate, long-term binary neutron stars simulations with IllinoisGRMHD and HARM+NUC_, New York Marriott Marquis, NY, USA.
-
-# 2021
-* **Poster presentation**, Midwest Relativity Meeting, _IllinoisGRMHD+HARM3D: Next-generation binary neutron stars simulations_, University of Illinois at Urbana-Champaign, IL, USA.
-* **Invited talk**, North American Einstein Toolkit Summer School, _NRPy+ tutorial: Maxwell’s equations in flat space & ET thorn generation_, University of Illinois at Urbana-Champaign, IL, USA (online event).
-* **Invited talk**, TCAN on BNS Workshop, _IllinoisGRMHD progress update --- advanced, tabulated equation of state support_, Rochester Institute of Technology, NY, USA (online event).
-* **Selected talk**, APS April Meeting, _New, user-friendly codes to study critical collapse_, online event.
-
-# 2020
-* **Invited talk**, TCAN on BNS Workshop, _IllinoisGRMHD progress update --- piecewise polytropic equation of state support_, Rochester Institute of Technology, NY, USA (online event).
-
diff --git a/_sass/minimal-mistakes/_buttons.scss b/_sass/minimal-mistakes/_buttons.scss
index e07b507..8cec7ca 100644
--- a/_sass/minimal-mistakes/_buttons.scss
+++ b/_sass/minimal-mistakes/_buttons.scss
@@ -42,6 +42,8 @@
(linkedin, $linkedin-color),
(journal, $facebook-color),
(arxiv, $danger-color),
+ (slides, #f5bf17),
+ (github, #000),
(bib, $info-color);
@each $buttoncolor, $color in $buttoncolors {
diff --git a/_sass/minimal-mistakes/_navigation.scss b/_sass/minimal-mistakes/_navigation.scss
index b400fd5..d4ab7e7 100644
--- a/_sass/minimal-mistakes/_navigation.scss
+++ b/_sass/minimal-mistakes/_navigation.scss
@@ -241,7 +241,7 @@
position: absolute;
inset-inline-start: 0;
bottom: 0;
- height: 4px;
+ height: 2px;
background: $primary-color;
width: 100%;
-webkit-transition: $global-transition;
diff --git a/assets/css/bibtex.css b/assets/css/bibtex.css
index 3877070..e8dcb60 100644
--- a/assets/css/bibtex.css
+++ b/assets/css/bibtex.css
@@ -5,19 +5,41 @@
width: calc(100% - 60px);
}
-.bibtex-image {
+.bibtex-thumbnail {
flex-shrink: 0;
width: 150px;
height: 150px;
border: 1px solid #ccc;
+ position: relative;
+ display: inline-block;
}
-.bibtex-image img {
+.bibtex-thumbnail img,
+.bibtex-thumbnail video {
+ display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
+.bibtex-thumbnail .caption {
+ position: absolute;
+ bottom: 0;
+ inset-inline-end: 0;
+ margin: 0 auto;
+ padding: 2px 5px;
+ font-family: Georgia, Times, serif !default;
+ font-size: 7pt;
+ background-color: rgba(0, 0, 0, 0.5);
+ text-align: end;
+ z-index: 5;
+ border-radius: $border-radius 0 0 0;
+ a {
+ color: #fff;
+ text-decoration: none;
+ }
+}
+
.bibtex-contents {
flex-grow: 1;
display: flex;
@@ -26,8 +48,11 @@
}
.paper-title {
- font-size: 1.1em;
text-align: justify;
+}
+
+.paper-title, .talk-title {
+ font-size: 1.1em;
padding-bottom: 8px;
border-bottom: 1px solid #bbb;
}
@@ -58,3 +83,9 @@
.btn--bib {
cursor: pointer;
}
+
+.talk-event {
+ padding-top: 8px;
+ color: #666;
+}
+
diff --git a/assets/docs/posters/2021-11-12-LRW-Poster-MWRM.pdf b/assets/docs/posters/2021-11-12-LRW-Poster-MWRM.pdf
new file mode 100644
index 0000000..aea921f
Binary files /dev/null and b/assets/docs/posters/2021-11-12-LRW-Poster-MWRM.pdf differ
diff --git a/assets/docs/talks/2020-07-07-LRW-Talk-TCAN.pdf b/assets/docs/talks/2020-07-07-LRW-Talk-TCAN.pdf
new file mode 100644
index 0000000..d0e9bba
Binary files /dev/null and b/assets/docs/talks/2020-07-07-LRW-Talk-TCAN.pdf differ
diff --git a/assets/docs/talks/2021-04-19-LRW-Talk-APS.pdf b/assets/docs/talks/2021-04-19-LRW-Talk-APS.pdf
new file mode 100644
index 0000000..d118649
Binary files /dev/null and b/assets/docs/talks/2021-04-19-LRW-Talk-APS.pdf differ
diff --git a/assets/docs/talks/2021-07-12-LRW-Talk-TCAN.pdf b/assets/docs/talks/2021-07-12-LRW-Talk-TCAN.pdf
new file mode 100644
index 0000000..82b9990
Binary files /dev/null and b/assets/docs/talks/2021-07-12-LRW-Talk-TCAN.pdf differ
diff --git a/assets/docs/talks/2022-04-10-LRW-Talk-APS.pdf b/assets/docs/talks/2022-04-10-LRW-Talk-APS.pdf
new file mode 100644
index 0000000..461ced7
Binary files /dev/null and b/assets/docs/talks/2022-04-10-LRW-Talk-APS.pdf differ
diff --git a/assets/docs/talks/2022-06-17-LRW-Talk-NAET.pdf b/assets/docs/talks/2022-06-17-LRW-Talk-NAET.pdf
new file mode 100644
index 0000000..8e62306
Binary files /dev/null and b/assets/docs/talks/2022-06-17-LRW-Talk-NAET.pdf differ
diff --git a/assets/docs/talks/2022-07-20-LRW-Talk-ETWW.pdf b/assets/docs/talks/2022-07-20-LRW-Talk-ETWW.pdf
new file mode 100644
index 0000000..be46b4f
Binary files /dev/null and b/assets/docs/talks/2022-07-20-LRW-Talk-ETWW.pdf differ
diff --git a/assets/docs/talks/2023-08-03-LRW-Talk-INT.pdf b/assets/docs/talks/2023-08-03-LRW-Talk-INT.pdf
new file mode 100644
index 0000000..205ed10
Binary files /dev/null and b/assets/docs/talks/2023-08-03-LRW-Talk-INT.pdf differ
diff --git a/assets/docs/talks/2024-06-21-LRW-Talk-INL.pdf b/assets/docs/talks/2024-06-21-LRW-Talk-INL.pdf
new file mode 100644
index 0000000..75f30bd
Binary files /dev/null and b/assets/docs/talks/2024-06-21-LRW-Talk-INL.pdf differ
diff --git a/assets/images/talks/2021_APS.png b/assets/images/talks/2021_APS.png
new file mode 100644
index 0000000..dfe2f30
Binary files /dev/null and b/assets/images/talks/2021_APS.png differ
diff --git a/assets/images/talks/2021_MWRM.png b/assets/images/talks/2021_MWRM.png
new file mode 100644
index 0000000..bf33b7f
Binary files /dev/null and b/assets/images/talks/2021_MWRM.png differ
diff --git a/assets/images/talks/2022_ETWW.png b/assets/images/talks/2022_ETWW.png
new file mode 100644
index 0000000..1664261
Binary files /dev/null and b/assets/images/talks/2022_ETWW.png differ
diff --git a/assets/images/talks/2023_APS.png b/assets/images/talks/2023_APS.png
new file mode 100644
index 0000000..106bfab
Binary files /dev/null and b/assets/images/talks/2023_APS.png differ
diff --git a/assets/images/talks/generic.png b/assets/images/talks/generic.png
new file mode 120000
index 0000000..07e704f
--- /dev/null
+++ b/assets/images/talks/generic.png
@@ -0,0 +1 @@
+../web-app-manifest-192x192.png
\ No newline at end of file
diff --git a/assets/js/bibtex-paper.js b/assets/js/bibtex-paper.js
new file mode 100644
index 0000000..db1a47d
--- /dev/null
+++ b/assets/js/bibtex-paper.js
@@ -0,0 +1,149 @@
+import { parseBibTeX, formatTitle } from './bibtex-utils.js';
+
+function formatAuthorName(authorStr) {
+ // Split at comma to separate last name from first/middle names
+ const [lastName, firstNames] = authorStr.trim().split(',').map(s => s.trim());
+
+ if (!firstNames) return lastName; // Handle case with no comma
+
+ // Get first initial and any middle initials
+ const names = firstNames.split(' ').filter(n => n);
+ const initials = names.map(name => name.charAt(0)).join('.');
+
+ // Return in "F.M. Last" format
+ return `${initials}. ${lastName}`;
+}
+
+function formatAuthors(authorStr, myName = "L.R. Werneck") {
+ // Split authors into array
+ const authors = authorStr.split(' and ').map(a => a.trim());
+
+ // Find my position in the author list
+ const myIndex = authors.findIndex(author => formatAuthorName(author) === myName);
+
+ // If there are 5 or fewer authors, handle normally
+ if (authors.length <= 5) {
+ if (myIndex === -1) {
+ return authors.map(author => formatAuthorName(author)).join(', ');
+ }
+
+ let formattedAuthors = authors
+ .map((author, index) => {
+ if (index === myIndex) {
+ return `
${myName}`;
+ }
+ return formatAuthorName(author);
+ });
+
+ // Add "and" before the last author if needed
+ if (formattedAuthors.length > 1) {
+ formattedAuthors[formattedAuthors.length - 1] = 'and ' + formattedAuthors[formattedAuthors.length - 1];
+ }
+
+ return formattedAuthors.join(', ');
+ }
+
+ // More than 5 authors
+ if (myIndex === -1 || myIndex >= 5) {
+ // Show first 5 authors and et al.
+ const firstFive = authors.slice(0, 5).map(author => formatAuthorName(author));
+ if (myIndex > 5) {
+ return firstFive.join(', ') + ', ' + `
${myName}` + ' et al.';
+ }
+ return firstFive.join(', ') + ' et al.';
+ }
+
+ // I'm among the first 5 authors
+ let formattedAuthors = authors.slice(0, 5).map((author, index) => {
+ if (index === myIndex) {
+ return `
${myName}`;
+ }
+ return formatAuthorName(author);
+ });
+
+ return formattedAuthors.join(', ') + ' et al.';
+}
+
+function formatCitation(bibData) {
+ if (!bibData) return '';
+ const { fields } = bibData;
+
+ // Create separate elements for each part
+ const titleElement = document.createElement('div');
+ const authorsElement = document.createElement('div');
+ const journalElement = document.createElement('div');
+
+ // Format title
+ if (fields.title) {
+ titleElement.innerHTML = formatTitle(fields.title);
+ }
+
+ // Format authors
+ if (fields.author) {
+ authorsElement.innerHTML = formatAuthors(fields.author);
+ }
+
+ // Format journal info
+ if (fields.journal) {
+ journalElement.innerHTML = `${fields.journal}, ${fields.volume} (${fields.number}) ${fields.pages} (${fields.year})`;
+ } else if (fields.eprint && fields.archiveprefix === "arXiv") {
+ journalElement.innerHTML = `arXiv:${fields.eprint} [${fields.primaryclass}] (${fields.year}),
${fields.misc}`;
+ }
+
+ return {
+ title: titleElement.innerHTML,
+ authors: authorsElement.innerHTML,
+ journal: journalElement.innerHTML
+ };
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+ document.querySelectorAll('.bibtex-entry').forEach(container => {
+ const bibtexData = container.querySelector('.bibtex-data');
+ const titleElement = container.querySelector('.paper-title');
+ const authorsElement = container.querySelector('.paper-authors');
+ const journalElement = container.querySelector('.paper-journal');
+
+ if (bibtexData) {
+ const parsed = parseBibTeX(bibtexData.textContent);
+ const formatted = formatCitation(parsed);
+
+ // Set the content for each section
+ if (titleElement) titleElement.innerHTML = formatted.title;
+ if (authorsElement) authorsElement.innerHTML = formatted.authors;
+ if (journalElement) journalElement.innerHTML = formatted.journal;
+
+ // Set up the button links
+ if (parsed && parsed.fields) {
+ const journalButton = container.querySelector('.btn--journal');
+ if (journalButton && parsed.fields.doi) {
+ journalButton.href = `https://doi.org/${parsed.fields.doi}`;
+ } else if (journalButton) {
+ journalButton.style.display = 'none';
+ }
+
+ const arxivButton = container.querySelector('.btn--arxiv');
+ if (arxivButton && parsed.fields.eprint) {
+ arxivButton.href = `https://arxiv.org/abs/${parsed.fields.eprint}`;
+ } else if (arxivButton) {
+ arxivButton.style.display = 'none';
+ }
+ }
+
+ bibtexData.style.display = 'none';
+ }
+ });
+
+ document.querySelectorAll('.btn--bib').forEach(button => {
+ button.addEventListener('click', function() {
+ const targetId = this.getAttribute('data-target');
+ const bibtexContent = document.querySelector(targetId);
+
+ if (bibtexContent) {
+ const isVisible = bibtexContent.style.display !== 'none';
+ bibtexContent.style.display = isVisible ? 'none' : 'block';
+ this.textContent = isVisible ? 'BibTeX' : 'Hide';
+ }
+ });
+ });
+});
diff --git a/assets/js/bibtex-parser.js b/assets/js/bibtex-parser.js
deleted file mode 100644
index 411c33d..0000000
--- a/assets/js/bibtex-parser.js
+++ /dev/null
@@ -1,224 +0,0 @@
-// Save this as assets/js/bibtex-parser.js
-function parseBibTeX(bibtexStr) {
- // Extract entry type and key
- const typeMatch = bibtexStr.match(/@(\w+)\s*{\s*([^,]*),/);
- if (!typeMatch) return null;
-
- const type = typeMatch[1];
- const key = typeMatch[2];
-
- // Extract fields with improved handling of quoted content
- const fields = {};
- const fieldRegex = /(\w+)\s*=\s*(?:"([^"]*)"|{([^}]*)})/g;
- let match;
-
- while ((match = fieldRegex.exec(bibtexStr)) !== null) {
- fields[match[1].toLowerCase()] = match[2] || match[3];
- }
-
- return { type, key, fields };
-}
-
-function formatAuthorName(authorStr) {
- // Split at comma to separate last name from first/middle names
- const [lastName, firstNames] = authorStr.trim().split(',').map(s => s.trim());
-
- if (!firstNames) return lastName; // Handle case with no comma
-
- // Get first initial and any middle initials
- const names = firstNames.split(' ').filter(n => n);
- const initials = names.map(name => name.charAt(0)).join('.');
-
- // Return in "F.M. Last" format
- return `${initials}. ${lastName}`;
-}
-
-function formatAuthors(authorStr, myName = "L.R. Werneck") {
- // Split authors into array
- const authors = authorStr.split(' and ').map(a => a.trim());
-
- // Find my position in the author list
- const myIndex = authors.findIndex(author => formatAuthorName(author) === myName);
-
- // If there are 5 or fewer authors, handle normally
- if (authors.length <= 5) {
- if (myIndex === -1) {
- return authors.map(author => formatAuthorName(author)).join(', ');
- }
-
- let formattedAuthors = authors
- .map((author, index) => {
- if (index === myIndex) {
- return `
${myName}`;
- }
- return formatAuthorName(author);
- });
-
- // Add "and" before the last author if needed
- if (formattedAuthors.length > 1) {
- formattedAuthors[formattedAuthors.length - 1] = 'and ' + formattedAuthors[formattedAuthors.length - 1];
- }
-
- return formattedAuthors.join(', ');
- }
-
- // More than 5 authors
- if (myIndex === -1 || myIndex >= 5) {
- // Show first 5 authors and et al.
- const firstFive = authors.slice(0, 5).map(author => formatAuthorName(author));
- if (myIndex > 5) {
- return firstFive.join(', ') + ', ' + `
${myName}` + ' et al.';
- }
- return firstFive.join(', ') + ' et al.';
- }
-
- // I'm among the first 5 authors
- let formattedAuthors = authors.slice(0, 5).map((author, index) => {
- if (index === myIndex) {
- return `
${myName}`;
- }
- return formatAuthorName(author);
- });
-
- return formattedAuthors.join(', ') + ' et al.';
-}
-
-function formatTitle(title) {
- // List of words to keep lowercase
- const lowercaseWords = new Set([
- 'a', 'an', 'the', 'and', 'but', 'or', 'for', 'nor', 'on', 'at',
- 'to', 'by', 'in', 'of', 'with', 'as'
- ]);
-
- // List of special terms to preserve exact capitalization
- const preserveTerms = new Map([
- ['illinoisgrmhd', 'IllinoisGRMHD'],
- ['nrpy+', 'NRPy+'],
- ['retinas', 'RETINAS'],
- ['nrpycritcol', 'NRPyCritCol'],
- ['sfcollapse1d', 'SFcollapse1D'],
- ['groovy', 'GRoovy'],
- ['grhayl', 'GRHayL'],
- ['harm3d+nuc', 'HARM3D+NUC'],
- ['1d', '1D'],
- ['2d', '2D'],
- ['3d', '3D'],
- ]);
-
- // Remove any remaining braces and split into words
- const cleanTitle = title.replace(/[{}]/g, '');
- const words = cleanTitle.split(/\s+/);
-
- // Capitalize words according to rules
- const titleCase = words.map((word, index) => {
- // Remove punctuation from the word for comparison
- const match = word.match(/^([a-zA-Z0-9+]+)([.,:;!?]*)$/);
- const baseWord = match ? match[1] : word;
- const punctuation = match ? match[2] : '';
-
- // Convert base word to lowercase for comparison
- const lowercaseWord = baseWord.toLowerCase();
-
- // Check if word is a special term that needs preservation
- if (preserveTerms.has(lowercaseWord)) {
- return preserveTerms.get(lowercaseWord) + punctuation;
- }
-
- // Always capitalize first and last word
- if (index === 0 || index === words.length - 1) {
- return baseWord.charAt(0).toUpperCase() + baseWord.slice(1).toLowerCase() + punctuation;
- }
- // Check if word should remain lowercase
- if (lowercaseWords.has(lowercaseWord)) {
- return baseWord.toLowerCase() + punctuation;
- }
- // Capitalize first letter of other words
- return baseWord.charAt(0).toUpperCase() + baseWord.slice(1).toLowerCase() + punctuation;
- });
-
- return `
${titleCase.join(' ')}`;
-}
-
-function formatCitation(bibData) {
- if (!bibData) return '';
- const { fields } = bibData;
-
- // Create separate elements for each part
- const titleElement = document.createElement('div');
- const authorsElement = document.createElement('div');
- const journalElement = document.createElement('div');
-
- // Format title
- if (fields.title) {
- titleElement.innerHTML = formatTitle(fields.title);
- }
-
- // Format authors
- if (fields.author) {
- authorsElement.innerHTML = formatAuthors(fields.author);
- }
-
- // Format journal info
- if (fields.journal) {
- journalElement.innerHTML = `${fields.journal}, ${fields.volume} (${fields.number}) ${fields.pages} (${fields.year})`;
- } else if (fields.eprint && fields.archiveprefix === "arXiv") {
- journalElement.innerHTML = `arXiv:${fields.eprint} [${fields.primaryclass}] (${fields.year}),
${fields.misc}`;
- }
-
- return {
- title: titleElement.innerHTML,
- authors: authorsElement.innerHTML,
- journal: journalElement.innerHTML
- };
-}
-
-document.addEventListener('DOMContentLoaded', function() {
- document.querySelectorAll('.bibtex-entry').forEach(container => {
- const bibtexData = container.querySelector('.bibtex-data');
- const titleElement = container.querySelector('.paper-title');
- const authorsElement = container.querySelector('.paper-authors');
- const journalElement = container.querySelector('.paper-journal');
-
- if (bibtexData) {
- const parsed = parseBibTeX(bibtexData.textContent);
- const formatted = formatCitation(parsed);
-
- // Set the content for each section
- if (titleElement) titleElement.innerHTML = formatted.title;
- if (authorsElement) authorsElement.innerHTML = formatted.authors;
- if (journalElement) journalElement.innerHTML = formatted.journal;
-
- // Set up the button links
- if (parsed && parsed.fields) {
- const journalButton = container.querySelector('.btn--journal');
- if (journalButton && parsed.fields.doi) {
- journalButton.href = `https://doi.org/${parsed.fields.doi}`;
- } else if (journalButton) {
- journalButton.style.display = 'none';
- }
-
- const arxivButton = container.querySelector('.btn--arxiv');
- if (arxivButton && parsed.fields.eprint) {
- arxivButton.href = `https://arxiv.org/abs/${parsed.fields.eprint}`;
- } else if (arxivButton) {
- arxivButton.style.display = 'none';
- }
- }
-
- bibtexData.style.display = 'none';
- }
- });
-
- document.querySelectorAll('.btn--bib').forEach(button => {
- button.addEventListener('click', function() {
- const targetId = this.getAttribute('data-target');
- const bibtexContent = document.querySelector(targetId);
-
- if (bibtexContent) {
- const isVisible = bibtexContent.style.display !== 'none';
- bibtexContent.style.display = isVisible ? 'none' : 'block';
- this.textContent = isVisible ? 'BibTeX' : 'Hide';
- }
- });
- });
-});
diff --git a/assets/js/bibtex-talk.js b/assets/js/bibtex-talk.js
new file mode 100644
index 0000000..023ba5f
--- /dev/null
+++ b/assets/js/bibtex-talk.js
@@ -0,0 +1,99 @@
+import { parseBibTeX, formatTitle } from './bibtex-utils.js';
+
+function formatTalk(bibData) {
+ if (!bibData) return '';
+ const { fields } = bibData;
+
+ // Create separate elements for each part
+ const titleElement = document.createElement('div');
+ const typeElement = document.createElement('div');
+ const eventnameElement = document.createElement('div');
+ const addressElement = document.createElement('div');
+
+ // Format title
+ if (fields.title) {
+ titleElement.innerHTML = formatTitle(fields.title);
+ }
+
+ // Format note
+ if (fields.note) {
+ typeElement.innerHTML = `
${fields.note.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ')}`;
+ }
+
+ // Format booktitle (event name)
+ if (fields.booktitle) {
+ eventnameElement.innerHTML = `
${fields.booktitle}`
+ }
+
+ // Format address (journal) info
+ if (fields.address) {
+ addressElement.innerHTML = `${fields.address} (${fields.year})`;
+ }
+
+ return {
+ title: titleElement.innerHTML,
+ type: typeElement.innerHTML,
+ eventname: eventnameElement.innerHTML,
+ address: addressElement.innerHTML
+ };
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+ document.querySelectorAll('.bibtex-entry').forEach(container => {
+ const bibtexData = container.querySelector('.bibtex-data');
+ const titleElement = container.querySelector('.talk-title');
+ const typeElement = container.querySelector('.talk-type');
+ const eventElement = container.querySelector('.talk-event');
+ const addressElement = container.querySelector('.talk-address');
+
+
+ if (bibtexData) {
+ const parsed = parseBibTeX(bibtexData.textContent);
+ const formatted = formatTalk(parsed);
+
+ // Set the content for each section
+ if (titleElement) titleElement.innerHTML = formatted.title;
+ if (typeElement) typeElement.innerHTML = formatted.type;
+ if (eventElement) eventElement.innerHTML = formatted.eventname;
+ if (addressElement) addressElement.innerHTML = formatted.address;
+
+ // Set up the button links
+ if (parsed && parsed.fields) {
+ const slidesButton = container.querySelector('.btn--slides');
+ if (slidesButton && parsed.fields.publishedat) {
+ slidesButton.href = `${parsed.fields.publishedat}`;
+ } else if (slidesButton) {
+ slidesButton.style.display = 'none';
+ }
+
+ const githubButton = container.querySelector('.btn--github');
+ if (githubButton && parsed.fields.url) {
+ githubButton.href = `${parsed.fields.url}`;
+ } else if (githubButton) {
+ githubButton.style.display = 'none';
+ }
+ }
+
+ bibtexData.style.display = 'none';
+ }
+ });
+
+ document.querySelectorAll('.btn--bib').forEach(button => {
+ button.addEventListener('click', function() {
+ const targetId = this.getAttribute('data-target');
+ const bibtexContent = document.querySelector(targetId);
+
+ if (bibtexContent) {
+ const isVisible = bibtexContent.style.display !== 'none';
+ bibtexContent.style.display = isVisible ? 'none' : 'block';
+ this.textContent = isVisible ? 'BibTeX' : 'Hide';
+ }
+ });
+ });
+
+ document.querySelectorAll('.bibtex-thumbnail video').forEach(video => {
+ video.autoplay = true;
+ video.loop = true;
+ video.muted = true;
+ });
+});
diff --git a/assets/js/bibtex-utils.js b/assets/js/bibtex-utils.js
new file mode 100644
index 0000000..bc40e02
--- /dev/null
+++ b/assets/js/bibtex-utils.js
@@ -0,0 +1,89 @@
+export function parseBibTeX(bibtexStr) {
+ // Extract entry type and key
+ const typeMatch = bibtexStr.match(/@(\w+)\s*{\s*([^,]*),/);
+ if (!typeMatch) return null;
+
+ const type = typeMatch[1];
+ const key = typeMatch[2];
+
+ // Extract fields with improved handling of quoted content
+ const fields = {};
+ const fieldRegex = /(\w+)\s*=\s*(?:"([^"]*)"|{([^}]*)})/g;
+ let match;
+
+ while ((match = fieldRegex.exec(bibtexStr)) !== null) {
+ fields[match[1].toLowerCase()] = match[2] || match[3];
+ }
+
+ return { type, key, fields };
+}
+
+export function formatTitle(title) {
+ // List of words to keep lowercase
+ const lowercaseWords = new Set([
+ 'a', 'an', 'the', 'and', 'but', 'or', 'for', 'nor', 'on', 'at',
+ 'to', 'by', 'in', 'of', 'with', 'as'
+ ]);
+
+ // List of special terms to preserve exact capitalization
+ const preserveTerms = new Map([
+ ['--', '–'],
+ ['---', '—'],
+ ['ns', 'NS'],
+ ['nss', 'NSs'],
+ ['bns', 'BNS'],
+ ['bh', 'BH'],
+ ['bhs', 'BHs'],
+ ['bbh', 'BBH'],
+ ['illinoisgrmhd', 'IllinoisGRMHD'],
+ ['illinoisgrmhd+harm3d', 'IllinoisGRMHD+HARM3D'],
+ ['grmhd', 'GRMHD'],
+ ['nrpy+', 'NRPy+'],
+ ['retinas', 'RETINAS'],
+ ['nrpycritcol', 'NRPyCritCol'],
+ ['gravitational-wave', 'Gravitational-Wave'],
+ ['sfcollapse1d', 'SFcollapse1D'],
+ ['groovy', 'GRoovy'],
+ ['grhayl', 'GRHayL'],
+ ['harm', 'HARM'],
+ ['harm3d', 'HARM3D'],
+ ['harm+nuc', 'HARM+NUC'],
+ ['harm3d+nuc', 'HARM3D+NUC'],
+ ['1d', '1D'],
+ ['2d', '2D'],
+ ['3d', '3D'],
+ ]);
+
+ // Remove any remaining braces and split into words
+ const cleanTitle = title.replace(/[{}]/g, '').replace(/\\&/g, '&');
+ const words = cleanTitle.split(/\s+/);
+
+ // Capitalize words according to rules
+ const titleCase = words.map((word, index) => {
+ // Remove punctuation from the word for comparison
+ const match = word.match(/^([a-zA-Z0-9+]+)([.,:;!?]*)$/);
+ const baseWord = match ? match[1] : word;
+ const punctuation = match ? match[2] : '';
+
+ // Convert base word to lowercase for comparison
+ const lowercaseWord = baseWord.toLowerCase();
+
+ // Check if word is a special term that needs preservation
+ if (preserveTerms.has(lowercaseWord)) {
+ return preserveTerms.get(lowercaseWord) + punctuation;
+ }
+
+ // Always capitalize first and last word
+ if (index === 0 || index === words.length - 1) {
+ return baseWord.charAt(0).toUpperCase() + baseWord.slice(1).toLowerCase() + punctuation;
+ }
+ // Check if word should remain lowercase
+ if (lowercaseWords.has(lowercaseWord)) {
+ return baseWord.toLowerCase() + punctuation;
+ }
+ // Capitalize first letter of other words
+ return baseWord.split('-').map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join('-') + punctuation;
+ });
+
+ return `
${titleCase.join(' ')}`;
+}
diff --git a/assets/videos/igm_bns_ls220_density.mp4 b/assets/videos/igm_bns_ls220_density.mp4
new file mode 100644
index 0000000..ad46a75
Binary files /dev/null and b/assets/videos/igm_bns_ls220_density.mp4 differ
diff --git a/assets/videos/igm_bns_ls220_temperature.mp4 b/assets/videos/igm_bns_ls220_temperature.mp4
new file mode 100644
index 0000000..3480011
Binary files /dev/null and b/assets/videos/igm_bns_ls220_temperature.mp4 differ
diff --git a/assets/videos/igm_bns_sly_ppeos.mp4 b/assets/videos/igm_bns_sly_ppeos.mp4
new file mode 100644
index 0000000..4ac4a2a
Binary files /dev/null and b/assets/videos/igm_bns_sly_ppeos.mp4 differ
diff --git a/assets/videos/moving_mesh.mp4 b/assets/videos/moving_mesh.mp4
new file mode 100644
index 0000000..d2a02ac
Binary files /dev/null and b/assets/videos/moving_mesh.mp4 differ