| --- |
| interface Props { |
| citationText: string; |
| bibtex: string; |
| licence?: string; |
| doi?: string; |
| } |
| const { citationText, bibtex, licence, doi } = Astro.props as Props; |
| --- |
|
|
| <footer class="footer"> |
| <div class="footer-inner"> |
| <section class="citation-block"> |
| <h3>Citation</h3> |
| <p>For attribution in academic contexts, please cite this work as</p> |
| <pre class="citation short">{citationText}</pre> |
|
|
| <p>BibTeX citation</p> |
| <pre class="citation long">{bibtex}</pre> |
| </section> |
| { |
| doi && ( |
| <section class="doi-block"> |
| <h3>DOI</h3> |
| <p> |
| <a |
| href={`https://doi.org/${doi}`} |
| target="_blank" |
| rel="noopener noreferrer" |
| > |
| {doi} |
| </a> |
| </p> |
| </section> |
| ) |
| } |
| { |
| licence && ( |
| <section class="reuse-block"> |
| <h3>Reuse</h3> |
| <p set:html={licence} /> |
| </section> |
| ) |
| } |
| <section class="references-block"> |
| <slot /> |
| </section> |
| <div class="template-credit"> |
| <p> |
| made with ❤️ with <a |
| href="https://huggingface.co/spaces/tfrere/research-article-template" |
| target="_blank" |
| rel="noopener noreferrer">research article template</a |
| > |
| </p> |
| </div> |
| </div> |
| </footer> |
|
|
| <script is:inline> |
| (() => { |
| const getFooter = () => |
| document.currentScript?.closest("footer") || |
| document.querySelector("footer.footer"); |
| const footer = getFooter(); |
| if (!footer) return; |
| const target = footer.querySelector(".references-block"); |
| if (!target) return; |
| |
| const contentRoot = |
| document.querySelector("section.content-grid main") || |
| document.querySelector("main") || |
| document.body; |
| |
| const ensureHeading = (text) => { |
| const exists = Array.from(target.children).some( |
| (c) => |
| c.tagName === "H3" && |
| c.textContent.trim().toLowerCase() === text.toLowerCase(), |
| ); |
| if (!exists) { |
| const h = document.createElement("h3"); |
| h.textContent = text; |
| target.appendChild(h); |
| } |
| }; |
| |
| const moveIntoFooter = (element, headingText) => { |
| if (!element) return false; |
| |
| |
| const firstHeading = element.querySelector( |
| ":scope > h1, :scope > h2, :scope > h3", |
| ); |
| if (firstHeading) { |
| const txt = (firstHeading.textContent || "").trim().toLowerCase(); |
| const targetTxt = headingText.trim().toLowerCase(); |
| if ( |
| txt === targetTxt || |
| txt.includes("reference") || |
| txt.includes("bibliograph") |
| ) { |
| firstHeading.remove(); |
| } |
| } |
| |
| ensureHeading(headingText); |
| |
| |
| |
| target.appendChild(element); |
| |
| return true; |
| }; |
| const run = () => { |
| |
| if (footer.dataset.processed === "true") return false; |
| |
| const findFirstOutsideFooter = (selectors) => { |
| |
| const searchRoots = [contentRoot, document.body].filter(Boolean); |
| |
| for (const root of searchRoots) { |
| for (const sel of selectors) { |
| const el = root.querySelector(sel); |
| if (el && !footer.contains(el)) return el; |
| } |
| } |
| return null; |
| }; |
| |
| const referencesEl = findFirstOutsideFooter([ |
| "#references", |
| ".references", |
| ".bibliography", |
| ]); |
| |
| |
| const footnotesEl = findFirstOutsideFooter([ |
| "[data-built-footnotes]", |
| ".footnotes", |
| "section.footnotes", |
| "div.footnotes", |
| ]); |
| |
| const movedRefs = moveIntoFooter(referencesEl, "References"); |
| const movedNotes = moveIntoFooter(footnotesEl, "Footnotes"); |
| |
| if (movedRefs || movedNotes) { |
| footer.dataset.processed = "true"; |
| } |
| |
| return movedRefs || movedNotes; |
| }; |
| |
| |
| const attemptMove = () => { |
| run(); |
| }; |
| |
| |
| attemptMove(); |
| |
| |
| if (document.readyState === "loading") { |
| document.addEventListener("DOMContentLoaded", attemptMove, { once: true }); |
| } |
| |
| |
| window.addEventListener("load", () => { |
| setTimeout(attemptMove, 100); |
| }, { once: true }); |
| |
| |
| setTimeout(attemptMove, 300); |
| |
| |
| |
| })(); |
| </script> |
|
|
| <style is:global> |
| .footer { |
| contain: layout style; |
| font-size: 0.8em; |
| line-height: 1.7em; |
| margin-top: 60px; |
| margin-bottom: 0; |
| border-top: 1px solid rgba(0, 0, 0, 0.1); |
| color: rgba(0, 0, 0, 0.5); |
| } |
| |
| .footer-inner { |
| max-width: 1280px; |
| margin: 0 auto; |
| padding: 60px 16px 48px; |
| display: grid; |
| grid-template-columns: 220px minmax(0, 680px) 260px; |
| gap: 32px; |
| align-items: start; |
| } |
| |
| |
| .citation-block, |
| .references-block, |
| .reuse-block, |
| .doi-block { |
| display: contents; |
| } |
| |
| .citation-block > h3, |
| .references-block > h3, |
| .reuse-block > h3, |
| .doi-block > h3 { |
| grid-column: 1; |
| font-size: 15px; |
| margin: 0; |
| text-align: right; |
| padding-right: 30px; |
| } |
| |
| .citation-block > :not(h3), |
| .references-block > :not(h3), |
| .reuse-block > :not(h3), |
| .doi-block > :not(h3) { |
| grid-column: 2; |
| } |
| |
| .citation-block h3 { |
| margin: 0 0 8px; |
| } |
| |
| .citation-block h4 { |
| margin: 16px 0 8px; |
| font-size: 14px; |
| text-transform: uppercase; |
| color: var(--muted-color); |
| } |
| |
| .citation-block p, |
| .reuse-block p, |
| .doi-block p, |
| .footnotes ol, |
| .footnotes ol p, |
| .references { |
| margin-top: 0; |
| } |
| |
| |
| |
| .footer .footnotes .katex { |
| font-size: 1.25em; |
| line-height: 1.21; |
| } |
| |
| .footer .footnotes .katex-display { |
| margin: 1em 0; |
| text-align: center; |
| display: block; |
| overflow-x: auto; |
| overflow-y: hidden; |
| } |
| |
| .footer .footnotes .katex-display > .katex { |
| display: block; |
| text-align: center; |
| } |
| |
| |
| .footer .footnotes .katex .katex-html { |
| display: inline-block; |
| } |
| |
| .footer .footnotes .katex .base { |
| display: inline-block; |
| } |
| |
| |
| .citation { |
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, |
| "Liberation Mono", "Courier New", monospace; |
| font-size: 11px; |
| line-height: 15px; |
| border-left: 1px solid rgba(0, 0, 0, 0.1); |
| padding-left: 18px; |
| border: 1px solid rgba(0, 0, 0, 0.1); |
| background: rgba(0, 0, 0, 0.02); |
| padding: 10px 18px; |
| border-radius: 3px; |
| color: rgba(150, 150, 150, 1); |
| overflow: hidden; |
| margin-top: -12px; |
| white-space: pre-wrap; |
| word-wrap: break-word; |
| } |
| |
| .citation a { |
| color: rgba(0, 0, 0, 0.6); |
| text-decoration: underline; |
| } |
| |
| .citation.short { |
| margin-top: -4px; |
| } |
| |
| .references-block h3 { |
| margin: 0; |
| } |
| |
| |
| .references-block ol { |
| padding: 0 0 0 15px; |
| } |
| |
| @media (min-width: 768px) { |
| .references-block ol { |
| padding: 0 0 0 30px; |
| margin-left: -30px; |
| } |
| } |
| |
| .references-block li { |
| margin-bottom: 1em; |
| } |
| |
| .references-block a { |
| color: var(--text-color); |
| } |
| |
| [data-theme="dark"] .footer { |
| border-top-color: rgba(255, 255, 255, 0.15); |
| color: rgba(200, 200, 200, 0.8); |
| } |
| [data-theme="dark"] .citation { |
| background: rgba(255, 255, 255, 0.04); |
| border-color: rgba(255, 255, 255, 0.15); |
| color: rgba(200, 200, 200, 1); |
| } |
| [data-theme="dark"] .citation a { |
| color: rgba(255, 255, 255, 0.75); |
| } |
| |
| |
| .footer a { |
| color: var(--primary-color); |
| border-bottom: 1px solid var(--link-underline); |
| text-decoration: none; |
| } |
| .footer a:hover { |
| color: var(--primary-color-hover); |
| border-bottom-color: var(--link-underline-hover); |
| } |
| [data-theme="dark"] .footer a { |
| color: var(--primary-color); |
| } |
| |
| |
| .template-credit { |
| display: contents; |
| } |
| |
| .template-credit p { |
| grid-column: 2; |
| margin: 24px 0 0 0; |
| font-size: 0.85em; |
| color: rgba(0, 0, 0, 0.5); |
| } |
| |
| .template-credit a { |
| color: rgba(0, 0, 0, 0.6); |
| border-bottom: 1px solid rgba(0, 0, 0, 0.15); |
| } |
| |
| .template-credit a:hover { |
| color: rgba(0, 0, 0, 0.8); |
| border-bottom-color: rgba(0, 0, 0, 0.3); |
| } |
| |
| [data-theme="dark"] .template-credit p { |
| color: rgba(200, 200, 200, 0.6); |
| } |
| |
| [data-theme="dark"] .template-credit a { |
| color: rgba(200, 200, 200, 0.7); |
| border-bottom-color: rgba(255, 255, 255, 0.2); |
| } |
| |
| [data-theme="dark"] .template-credit a:hover { |
| color: rgba(200, 200, 200, 0.9); |
| border-bottom-color: rgba(255, 255, 255, 0.35); |
| } |
| </style> |
|
|