>[!citation]
><%*
/**
* Chicago Author–Date (Adapted) — Bibliography-only formatter for Obsidian
*
* Frontmatter properties:
* type (text)
* author(s) (list) e.g. ["Doe, John", "Hanford, Alice"]
* year (text) year, or fuller date e.g. "2020-03-15"
* title (text)
* edition (text)
* editor(s) (list)
* publication (text) journal / container title
* issue (text) combined volume(issue), e.g. "5(13)"
* location (text) page, page range, or article locator
* publisher (text)
* city (text)
* url (text)
*
* Key adaptations:
* - Full given names (as provided, "Family, Given")
* - Year shown parenthesized in the author–date slot
* - Stable URL as locator
* - Publisher rendered as "City: Publisher" when city is present
*/
function norm(s) { return (s ?? "").toString().trim(); }
function getYear(fm) {
return norm(fm.year);
}
function authorsFromFrontmatter(fm) {
const a = fm["author(s)"];
if (!Array.isArray(a)) return [];
return a.map(norm).filter(Boolean);
}
function editorsFromFrontmatter(fm) {
const e = fm["editor(s)"];
if (!Array.isArray(e)) return [];
return e.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, " ") // collapse runs of whitespace
.replace(/\s+([:;,.])/g, "$1") // no space before : ; , .
.replace(/\.{2,}/g, ".") // no doubled periods
.trim();
}
function chooseLocator(fm) {
return norm(fm.url);
}
// "City: Publisher." / "Publisher." / "City." (whichever parts exist)
function publisherClause(fm) {
const city = norm(fm.city);
const publisher = norm(fm.publisher);
if (city && publisher) return `${city}: ${publisher}.`;
if (publisher) return `${publisher}.`;
if (city) return `${city}.`;
return "";
}
function bibEntry(fm) {
const type = norm(fm.type);
const title = norm(fm.title);
const year = getYear(fm);
const yearClause = `(${year || "n. d."}).`;
const authors = authorsFromFrontmatter(fm);
const authorStr = authorListChicago(authors);
const container = norm(fm.publication);
const issue = norm(fm.issue); // combined, e.g. "5(13)"
const location = norm(fm.location); // page/range or locator
const edition = norm(fm.edition);
const locator = chooseLocator(fm);
const pubClause = publisherClause(fm);
// ---- Book chapter
if (type.startsWith("reference/book/chapter")) {
// Author. (Year). Chapter. In *Book Title*, edited by X, Pages nn–nn. City: Publisher. URL.
const editors = editorsFromFrontmatter(fm);
const editedBy = editors.length ? `Edited by ${editors.join(", ")}.` : "";
const pp = location ? `Pages ${location}.` : "";
const ed = edition ? `${edition} edition.` : "";
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
yearClause,
quoteTitle(title),
container ? `In ${italics(container)},` : "",
editedBy,
pp,
ed,
pubClause,
loc
]);
}
// ---- Book
if (type.startsWith("reference/book")) {
// Author. (Year). *Title*. Edition. City: Publisher. URL.
const ed = edition ? `${edition} edition.` : "";
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
yearClause,
title ? `${italics(title)}.` : "",
ed,
pubClause,
loc
]);
}
// ---- 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* 5(13): location. URL.
const vp = issue + (location ? `: ${location}` : "");
const vpClause = vp ? `${vp}.` : "";
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
yearClause,
quoteTitle(title),
container ? `${italics(container)}.` : "",
vpClause,
loc
]);
}
// ---- Magazine / newspaper
if (type.startsWith("reference/article/magazine") || type.startsWith("reference/article/newspaper")) {
// Author. (Year). Title. *Outlet*. URL.
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
yearClause,
quoteTitle(title),
container ? `${italics(container)}.` : "",
loc
]);
}
// ---- Web page / post / thread
if (type.startsWith("reference/web/page") || type.startsWith("reference/web/post") || type.startsWith("reference/web/thread")) {
// Author. (Year). Title. *Site*. URL.
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
yearClause,
quoteTitle(title),
container ? `${italics(container)}.` : "",
loc
]);
}
// ---- Software
if (type.startsWith("reference/software")) {
// Author/Org. (Year). *Software Name*. URL.
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
yearClause,
title ? `${italics(title)}.` : "",
loc
]);
}
// ---- Dataset
if (type.startsWith("reference/dataset")) {
// Author/Org. (Year). *Dataset Title* [Data set]. URL.
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
yearClause,
title ? `${italics(title)} [Data set].` : "",
loc
]);
}
// ---- Media
if (type.startsWith("reference/podcast") || type.startsWith("reference/video") || type.startsWith("reference/film")) {
// Creator. (Year). *Title* [Medium]. Site/Distributor. URL.
const medium = type.endsWith("podcast") ? "[Podcast]" : type.endsWith("video") ? "[Video]" : "[Film]";
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
yearClause,
title ? `${italics(title)} ${medium}.` : "",
container ? `${container}.` : "",
loc
]);
}
// ---- Reference entries
if (type.startsWith("reference/entry/dictionary") || type.startsWith("reference/entry/encyclopedia")) {
// Entry. (Year). In *Reference Work*. URL.
const loc = locator ? `${locator}.` : "";
return join([
yearClause,
quoteTitle(title),
container ? `In ${italics(container)}.` : "",
loc
]);
}
// ---- Fallback
const loc = locator ? `${locator}.` : "";
return join([
authorStr ? `${authorStr}.` : "",
yearClause,
title ? quoteTitle(title) : "",
container ? `${italics(container)}.` : "",
loc
]);
}
const fm = tp.frontmatter;
tR += bibEntry(fm);
%>
>![[Index of references.base#citation|no-toolbar]]