|
class Formatters { |
|
format_book_collections(collections, dv) { |
|
if (collections) { |
|
const keys = Object.keys(collections); |
|
const links = dv |
|
.pages('"Personal/Reading/Collections"') |
|
.where( |
|
(p) => |
|
p.handle != undefined && |
|
keys.indexOf(p.handle) > -1 |
|
) |
|
.map((p) => { |
|
return `[[${p.file.path}|${p.title} ${ |
|
"#" + collections[p.handle] |
|
}]]`; |
|
}); |
|
|
|
return links.join("\n"); |
|
} |
|
} |
|
|
|
format_book_count(handle, dv) { |
|
const books = dv |
|
.pages('"Personal/Reading/Books"') |
|
.where( |
|
(p) => |
|
p.collections != undefined && |
|
Object.keys(p.collections).indexOf(handle) > -1 |
|
); |
|
return books.length; |
|
} |
|
|
|
format_image(url, width) { |
|
if (!url) { |
|
return ""; |
|
} |
|
if (width == undefined) { |
|
width = "150px"; |
|
} |
|
return `<img src="${url}" width="${width}" />`; |
|
} |
|
|
|
format_list(value, separator) { |
|
if (separator == undefined) { |
|
separator = "\n"; |
|
} |
|
return value.join(separator); |
|
} |
|
|
|
format_mood(value) { |
|
switch (value) { |
|
case "good": |
|
return "🙂"; |
|
case "angry": |
|
return "😠"; |
|
case "confident": |
|
return "😎"; |
|
case "sad": |
|
return "😔"; |
|
case "amused": |
|
return "😌"; |
|
case "unamused": |
|
return "😑"; |
|
case "moody": |
|
return "🙃"; |
|
case "indifferent": |
|
return "🫥"; |
|
default: |
|
return "∅"; |
|
} |
|
} |
|
|
|
format_weather(value) { |
|
switch (value) { |
|
case "sunny": |
|
return "☀"; |
|
case "cloudy": |
|
return "☁"; |
|
case "rainy": |
|
return "⛆"; |
|
case "thunderstorm": |
|
return "⛈"; |
|
case "cold": |
|
return "⛇"; |
|
case "night": |
|
return "🌙"; |
|
default: |
|
return "∅"; |
|
} |
|
} |
|
format_path(value, vault, level = 2) { |
|
if (typeof value != "string") { |
|
return ""; |
|
} |
|
|
|
const parts = value.split("/"); |
|
const name = parts.length <= level ? parts[parts.length - 1] : parts[level]; |
|
return `<a href="obsidian://search?vault=${encodeURIComponent( |
|
vault |
|
)}&query=path:${encodeURIComponent(value)}">${name}</a>`; |
|
} |
|
|
|
format_compact_date(date) { |
|
if (!date) { |
|
return ""; |
|
} else { |
|
return date.toFormat("'<small>'MMM dd, yyyy'<hr/>'hh:mm a'</small>'"); |
|
} |
|
} |
|
|
|
format_collapsed_list(data, keep = 1) { |
|
if (data.length > keep) { |
|
return `<details> |
|
<summary style="list-style-type: none;">${data |
|
.slice(0, keep) |
|
.join(", ")}...</summary> |
|
<div>${data.slice(keep).join(", ")}</div> |
|
</details>`; |
|
} else { |
|
return `${data.join(", ")}`; |
|
} |
|
} |
|
|
|
format_rating(value) { |
|
if (value == null || value == "N/A") { |
|
return "∅"; |
|
} |
|
let full = Math.floor(value); |
|
let fraction = value - full; |
|
let empty = 5 - Math.ceil(value); |
|
let result = |
|
"●".repeat(full) + |
|
(fraction != 0 ? "◐" : "") + |
|
(empty != 0 ? "○".repeat(empty) : ""); |
|
// do something |
|
// You can use another functions defined in the file |
|
return result; |
|
} |
|
|
|
format_progress(value, max, dv, hide_track) { |
|
let track = ""; |
|
if (value < max && !hide_track) { |
|
const per_week = max / 52; |
|
const now_week = dv.luxon.DateTime.now().weekNumber; |
|
const optimal_progress = per_week * now_week; |
|
track = '<div style="color: green;">On track</div>'; |
|
if (optimal_progress > value) { |
|
track = `<div style="color: red;">Due: ${ |
|
optimal_progress - value |
|
}</div>`; |
|
} |
|
} |
|
return `<div style="width: 100%; display: flex; align-items: center;"><progress style="width: 80%; margin-right: 10px; flex: 1;" max="${max}" value="${value}"></progress>${Math.round( |
|
(value / max) * 100 |
|
)}% (${value}/${max})</div>${track}`; |
|
} |
|
|
|
format_title_link(value, fobj_name = "file") { |
|
return `[[${value[fobj_name].path}|${value.title}]]`; |
|
} |
|
|
|
yearly_journal_stats(dv) { |
|
const now = dv.luxon.DateTime.now(); |
|
const current = dv.current(); |
|
const year = parseInt(current.title); |
|
const journal = dv |
|
.pages('"Personal/Journal" or "Personal/Musings"') |
|
.where((j) => j.created && dv.date(j.created).year == year); |
|
const journal_count = journal.length; |
|
dv.paragraph( |
|
this.format_progress( |
|
journal_count, |
|
current.journal_goal || journal_count, |
|
dv, |
|
now.year != year |
|
) |
|
); |
|
dv.table( |
|
["Title", "Mood", "Weather", "Tags"], |
|
journal.map((b) => { |
|
return [ |
|
this.format_title_link(b), |
|
this.format_mood(b.mood), |
|
this.format_weather(b.weather), |
|
b.tags ? b.tags.join(", ") : "", |
|
]; |
|
}) |
|
); |
|
} |
|
|
|
yearly_reading_stats(dv) { |
|
const now = dv.luxon.DateTime.now(); |
|
const current = dv.current(); |
|
const year = parseInt(current.title); |
|
const read_this_year = dv |
|
.pages('"Personal/Reading/Books/Read"') |
|
.where( |
|
(book) => |
|
book.status == "Read" && |
|
book.read_at && |
|
book.read_at.find((d) => dv.date(d).year == year) |
|
); |
|
const read_count = read_this_year.length; |
|
dv.paragraph( |
|
this.format_progress( |
|
read_count, |
|
current.reading_goal || read_count, |
|
dv, |
|
now.year != year |
|
) |
|
); |
|
dv.table( |
|
["Title", "Authors", "Rating"], |
|
read_this_year.map((b) => { |
|
return [ |
|
this.format_title_link(b), |
|
this.format_collapsed_list(b.authors), |
|
this.format_rating(b.rating), |
|
]; |
|
}) |
|
); |
|
} |
|
} |