Skip to content

Instantly share code, notes, and snippets.

@basilioss
Last active September 12, 2024 02:18
Show Gist options
  • Save basilioss/b0d1e608781d0457004debccf213163b to your computer and use it in GitHub Desktop.
Save basilioss/b0d1e608781d0457004debccf213163b to your computer and use it in GitHub Desktop.
Obsidian template to rollover incomplete todo items from the previous daily note
<%*
// v1.1: Fixed the error when inserting the template, when a note for the previous day does not exist
const previousDay = moment(tp.file.title, "YYYY-MM-DD").subtract(1, "days").format("YYYY-MM-DD")
const nextDay = moment(tp.file.title, "YYYY-MM-DD").add(1, "days").format("YYYY-MM-DD")
tR += "# " + tp.file.title + "\n"
%>
<< [[<% previousDay %>]] | [[<% nextDay %>]] >>
<%*
// Insert tasks from a previous day
try {
// Define checkboxes to move (https://minimal.guide/Block+types/Checklists)
const checkboxes = ["- [ ]", "- [/]", "- [>]"]
// Get array of tasks
const file = await tp.file.include("[[" + previousDay + "]]")
const array = file.split('\n')
const tasks = array.filter(a => checkboxes.some(c => a.includes(c)))
// [/], [>] => [ ]
for (i = 0; i < tasks.length; i++)
tR += tasks[i].replace(/\[\/\]/, '[ ]').replace(/\[>\]/, '[ ]') + "\n"
} catch (error) {
new Notice(error, 5000)
}
// Move file to "journal" folder
await tp.file.move('journal/'+tp.file.title)
%>
@lordkekz
Copy link

lordkekz commented Nov 12, 2022

This is really nice!
I made an adapted version that works as a user script, can look behind for previous daily notes in case a day is skipped, and is able to filter out tasks that match the format used by the day planner plugin.
What do you think?

rolloverTodo.js

// Modeled after: https://gist.github.com/basilioss/b0d1e608781d0457004debccf213163b

// Function will try to find the closest preceding day which has a daily note.
// maxSkippedDays: Maximum number of days without a daily note before giving up.
// ignoreDayPlanner: Whether to ignore tasks that match the format for the day planner plugin.
async function rolloverTodo(tp, maxSkippedDays, ignoreDayPlanner) {
	var result = "";
	
	try {
		// Argument checks
		if (!Number.isInteger(maxSkippedDays)) {
			// Notice if invalid value was given
			if (maxSkippedDays != undefined)
				new Notice("rolloverTodo: maxSkippedDays should be an integer!", 5000);
			
			// Use default value
			maxSkippedDays = 3; // default value
		}
		if (typeof ignoreDayPlanner != "boolean") {
			// Notice if invalid value was given
			if (ignoreDayPlanner != undefined)
				new Notice("rolloverTodo: ignoreDayPlanner should be a boolean!", 5000);
			
			// Use default value
			ignoreDayPlanner = true;
		}
		
		// ### INSERT TASKS FROM A PREVIOUS DAY ###
		
		// Define checkboxes to move (https://minimal.guide/Block+types/Checklists)
		const checkboxes = ["- [ ]", "- [/]", "- [>]"];

		// Find closest daily note
		var lastDailyNote = moment(tp.file.title, "YYYY-MM-DD").subtract(1, "days").format("YYYY-MM-DD");
		var file = null;
		for (i = 0; i <= maxSkippedDays && file==null; i++) {
			try {
				// Look for previous daily note
				file = await tp.file.include("[[" + lastDailyNote + "]]");
			} catch (error) {
				// Daily note wasn't found; go back by one day.
				lastDailyNote = moment(lastDailyNote, "YYYY-MM-DD").subtract(1, "days").format("YYYY-MM-DD");
			}
		}
		if (file==null)
			throw new Error("Couldn't find a note to rollover todos from within the past " + maxSkippedDays + " days!");

		// Get tasks from closest daily note
		const array = file.split('\n');
		const tasks = array.filter(a =>
			// Starts with one of the checkboxes
			checkboxes.some(c => a.includes(c))
			// Isn't a day planner event (or those are allowed)
			&& (!ignoreDayPlanner || a.match(/- \[[ \/>]\] \d\d:\d\d .*/)==null));

		// If todos are from before original previous day, print the date.
		if (i>1)
			result += "> Todos rolled over from " + lastDailyNote  + "\n";

		// [/], [>] => [ ]
		for (i = 0; i < tasks.length; i++)
			result += tasks[i].replace(/\[\/\]/, '[ ]').replace(/\[>\]/, '[ ]') + "\n";
	} catch (error) {
		new Notice(error, 5000);
	}
	return result;
}

module.exports = rolloverTodo;

In your daily note template:

For default behavior (up to 3 days skipped and with ignoring of day planner): <% tp.user.rolloverTodo(tp) %>
For behavior like the original (0 skipped days and no filter for day planner): <% tp.user.rolloverTodo(tp, 0, false) %>
Note that I removed the automatic file title and linking of yesterday/tomorrow, since I'm putting them somewhere else in my personal tempate.

@basilioss
Copy link
Author

@lordkekz That's much better, thanks for sharing!

@buiax
Copy link

buiax commented Jan 16, 2023

How do you get the checkbox to display like the video?

@basilioss
Copy link
Author

I use Minimal theme

@Sean-Shmulevich
Copy link

this is exactly what i was looking for <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment