>[!citation]
><%*
/**
* Chicago Author–Date (Adapted) — Bibliography-only formatter for Obsidian
*
* Frontmatter expects:
* authors:
* - Doe, John
* - Hanford, Alice
*
* Key adaptations:
* - Full given names (as provided)
* - DOI preferred; else stable URL
* - Book city omitted by default
* - Access date only if you set `accessed` (recommended for mutable web sources)
*/
function norm(s) { return (s ?? "").toString().trim(); }
function getYear(fm) {
const y = norm(fm.year);
if (y) return y;
const issued = norm(fm.issued);
if (/^\d{4}/.test(issued)) return issued.slice(0,4);
return "";
}
function formatDateHuman(iso) {
const s = norm(iso);
if (!s) return "";
if (/^\d{4}$/.test(s)) return s;
const d = new Date(s);
if (isNaN(d.getTime())) return s;
const months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
return `${months[d.getUTCMonth()]} ${d.getUTCDate()}, ${d.getUTCFullYear()}`;
}
function authorsFromFrontmatter(fm) {
const a = fm.authors;
if (!Array.isArray(a)) return [];
return a.map(norm).filter(Boolean);
}
function authorListChicago(authors) {
// Input already "Family, Given"
if (authors.length === 0) return "";
if (authors.length === 1) return authors[0];
if (authors.length === 2) return `${authors[0]} and ${authors[1]}`;
return `${authors.slice(0,-1).join(", ")}, and ${authors[authors.length-1]}`;
}
function italics(s) { s = norm(s); return s ? `*${s}*` : ""; }
function quoteTitle(s) { s = norm(s); return s ? `“${s}.”` : ""; }
function join(parts) {
return parts.map(norm).filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
}
function chooseLocator(fm) {
const doi = norm(fm.doi);
const url = norm(fm.url);
if (doi) {
if (doi.startsWith("http")) return doi;
return `https://doi.org/${doi.replace(/^doi:\s*/i,"")}`;
}
return url;
}
function accessedClause(fm) {
const a = norm(fm.accessed);
if (!a) return "";
return ` Accessed ${formatDateHuman(a)}.`;
}
function bibEntry(fm) {
const type = norm(fm.type);
const title = norm(fm.title);
const year = getYear(fm);
const issuedHuman = fm.issued ? formatDateHuman(fm.issued) : "";
const authors = authorsFromFrontmatter(fm);
const authorStr = authorListChicago(authors);
const container = norm(fm.container_title);
const publisher = norm(fm.publisher);
const volume = norm(fm.volume);
const issue = norm(fm.issue);
const pages = norm(fm.pages);
const edition = norm(fm.edition);
const version = norm(fm.version);
const locator = chooseLocator(fm);
// ---- Book chapter
if (type.startsWith("reference/book/chapter")) {
// Author. Year. "Chapter." In *Book Title*, edited by X, Pages nn–nn. Publisher. DOI/URL. Accessed...
const editors = Array.isArray(fm.editors) ? fm.editors.map(norm).filter(Boolean) : [];
const editedBy = editors.length ? `Edited by ${editors.join(", ")}.` : "";
const pp = pages ? `Pages ${pages}.` : "";
const ed = edition ? `${edition} edition.` : "";
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
year ? `${year}.` : "",
quoteTitle(title),
container ? `In ${italics(container)},` : "",
editedBy,
pp,
ed,
publisher ? `${publisher}.` : "",
loc,
accessedClause(fm).trim()
]);
}
// ---- Book
if (type.startsWith("reference/book")) {
// Author. Year. *Title*. Edition. Publisher. DOI/URL. Accessed...
const ed = edition ? `${edition} edition.` : "";
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
year ? `${year}.` : "",
title ? `${italics(title)}.` : "",
ed,
publisher ? `${publisher}.` : "",
loc,
accessedClause(fm).trim()
]);
}
// ---- Scholarly article / preprint / report / thesis / conference paper
if (
type.startsWith("reference/article/journal") ||
type.startsWith("reference/article/preprint") ||
type.startsWith("reference/report") ||
type.startsWith("reference/thesis") ||
type.startsWith("reference/conference/paper")
) {
// Author. Year. "Title." *Journal* volume (issue): pages. DOI/URL. [Accessed if set]
const volIssue = join([volume, issue ? `(${issue})` : ""]).replace(/\s+/g,"").trim(); // e.g., 12(3)
const vp = join([volIssue, pages ? `: ${pages}` : ""]);
const vpClause = vp ? `${vp}.` : "";
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
year ? `${year}.` : "",
quoteTitle(title),
container ? `${italics(container)}.` : "",
vpClause,
loc,
accessedClause(fm).trim()
]);
}
// ---- Magazine / newspaper
if (type.startsWith("reference/article/magazine") || type.startsWith("reference/article/newspaper")) {
// Author. Year. "Title." *Outlet*, Month D, Year. URL. Accessed...
const datePart = issuedHuman || year;
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
year ? `${year}.` : "",
quoteTitle(title),
container ? `${italics(container)},` : "",
datePart ? `${datePart}.` : "",
loc,
accessedClause(fm).trim()
]);
}
// ---- Web page / post / thread
if (type.startsWith("reference/web/page") || type.startsWith("reference/web/post") || type.startsWith("reference/web/thread")) {
// Author. Year. "Title." *Site*, Month D, Year. URL. Accessed...
const datePart = issuedHuman || year;
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
year ? `${year}.` : "",
quoteTitle(title),
container ? `${italics(container)},` : "",
datePart ? `${datePart}.` : "",
loc,
accessedClause(fm).trim()
]);
}
// ---- Software
if (type.startsWith("reference/software")) {
// Author/Org. Year. *Software Name*. (Version x). DOI/URL. Accessed...
const v = version ? `(Version ${version}).` : "";
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
year ? `${year}.` : "",
title ? `${italics(title)}.` : "",
v,
loc,
accessedClause(fm).trim()
]);
}
// ---- Dataset
if (type.startsWith("reference/dataset")) {
// Author/Org. Year. *Dataset Title* [Data set]. DOI/URL. Accessed...
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
year ? `${year}.` : "",
title ? `${italics(title)} [Data set].` : "",
loc,
accessedClause(fm).trim()
]);
}
// ---- Media
if (type.startsWith("reference/podcast") || type.startsWith("reference/video") || type.startsWith("reference/film")) {
// Creator. Year. *Title* [Medium]. Site/Distributor, Month D, Year. URL. Accessed...
const medium = type.endsWith("podcast") ? "[Podcast]" : type.endsWith("video") ? "[Video]" : "[Film]";
const datePart = issuedHuman || year;
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
year ? `${year}.` : "",
title ? `${italics(title)} ${medium}.` : "",
container ? `${container},` : "",
datePart ? `${datePart}.` : "",
loc,
accessedClause(fm).trim()
]);
}
// ---- Reference entries
if (type.startsWith("reference/entry/dictionary") || type.startsWith("reference/entry/encyclopedia")) {
// "Entry." Year. In *Reference Work*. URL. Accessed...
const loc = locator ? `${locator}.` : "";
return join([
year ? `${year}.` : "",
quoteTitle(title),
container ? `In ${italics(container)}.` : "",
loc,
accessedClause(fm).trim()
]);
}
// ---- Fallback
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
year ? `${year}.` : "",
title ? quoteTitle(title) : "",
container ? `${italics(container)}.` : "",
loc,
accessedClause(fm).trim()
]);
}
const fm = tp.frontmatter;
tR += bibEntry(fm);
%>