Skip to content

Instantly share code, notes, and snippets.

@uroybd
Last active December 31, 2022 05:10
Show Gist options
  • Save uroybd/fdc908b72eccd77c893a35e7719d1227 to your computer and use it in GitHub Desktop.
Save uroybd/fdc908b72eccd77c893a35e7719d1227 to your computer and use it in GitHub Desktop.
Obsidian yearly goals
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),
];
})
);
}
}
title created updated reading_goal journal_goal
2023
2022-12-27 12:32:29 +0600
2022-12-28 10:40:47 +0600
52
26

Journal and Musings

const {Formatters} = customJS;
Formatters.yearly_journal_stats(dv);

Reading

const {Formatters} = customJS;
Formatters.yearly_reading_stats(dv);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment