|
|
--- |
|
|
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(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (element.classList && element.classList.contains("footnotes")) { |
|
|
const footnoteItems = element.querySelectorAll("li"); |
|
|
footnoteItems.forEach((item) => { |
|
|
const backrefContainer = item.querySelector("small.backrefs"); |
|
|
const lastP = item.querySelector("p:last-of-type"); |
|
|
if (backrefContainer && lastP && !lastP.contains(backrefContainer)) { |
|
|
lastP.appendChild(document.createTextNode(" ")); |
|
|
lastP.appendChild(backrefContainer); |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
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([ |
|
|
"#bibliography-references-list", |
|
|
"[data-bibliography-block]", |
|
|
"#references", |
|
|
"#refs", |
|
|
".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> |
|
|
|