import { normalizePath , TFolder , TFile , FileSystemAdapter } from "obsidian" ; import { getAllDailyNotes , getDailyNoteSettings , getDateFromFile } from "obsidian-daily-notes-interface" ; export class DailyNotesFolderMissingError extends Error { } export async function getRemainingTasks ( note ) { if ( ! note ) { return 0 ; } const { vault } = window . app ; let fileContents = await vault . cachedRead ( note ) ; const matchLength = ( fileContents . match ( /(-|\*) (\[(\s|x|X|\\|\-|\>|D|\?|\/|\+|R|\!|i|B|P|C)\]\s)?((\<time\>)?\d{1,2}\:\d{2})?/g ) || [ ] ) . length ; fileContents = null ; return matchLength ; } export async function getTasksForDailyNote ( dailyNote , dailyEvents ) { if ( ! dailyNote ) { return [ ] ; } const { vault } = window . app ; const Tasks = await getRemainingTasks ( dailyNote ) ; if ( Tasks ) { let fileContents = await vault . cachedRead ( dailyNote ) ; let fileLines = getAllLinesFromFile ( fileContents ) ; const startDate = getDateFromFile ( dailyNote , "day" ) ; const endDate = getDateFromFile ( dailyNote , "day" ) ; for ( let i = 0 ; i < fileLines . length ; i ++ ) { const line = fileLines [ i ] ; const rawText = extractTextFromTodoLine ( line ) ; if ( line . length === 0 ) continue ; if ( lineIsNotTasksTodo ( line ) ) continue ; if ( lineIsValidTodo ( line ) || lineContainsTime ( line ) ) { if ( lineContainsTime ( line ) ) { startDate . hours ( parseInt ( extractHourFromBulletLine ( line ) ) ) ; startDate . minutes ( parseInt ( extractMinFromBulletLine ( line ) ) ) ; endDate . hours ( parseInt ( extractHourFromBulletLine ( line ) ) ) ; if ( parseInt ( extractHourFromBulletLine ( line ) ) > 22 ) { endDate . minutes ( parseInt ( extractMinFromBulletLine ( line ) ) ) ; } else { endDate . minutes ( parseInt ( extractMinFromBulletLine ( line ) ) + 59 ) ; } } else { startDate . hours ( 0 ) ; startDate . minutes ( 0 ) ; endDate . minutes ( 0 ) ; endDate . hours ( 0 ) ; } if ( lineIsValidTodoEvent ( line ) ) { dailyEvents . push ( { id : i , title : rawText , start : startDate . toDate ( ) , end : endDate . toDate ( ) , resourceId : i , status : 'TODO' , file : dailyNote , originalText : line , lineNum : i , } ) ; } else if ( lineIsValidDoneEvent ( line ) ) { dailyEvents . push ( { id : i , title : rawText , start : startDate . toDate ( ) , end : endDate . toDate ( ) , resourceId : i , status : 'DONE' , file : dailyNote , originalText : line , lineNum : i , } ) ; } else if ( lineIsValidAnotherEvent ( line ) ) { dailyEvents . push ( { id : i , title : rawText , start : startDate . toDate ( ) , end : endDate . toDate ( ) , resourceId : i , status : 'ANOTHER' , file : dailyNote , originalText : line , lineNum : i , } ) ; } else if ( lineContainsTime ( line ) ) { dailyEvents . push ( { id : i , title : rawText , start : startDate . toDate ( ) , end : endDate . toDate ( ) , resourceId : i , status : 'JOURNAL' , file : dailyNote , originalText : line , lineNum : i , } ) ; } } } fileLines = null ; fileContents = null ; } } export function getPath ( filePath ) { const { vault } = window . app ; if ( vault . adapter instanceof FileSystemAdapter ) { return ( vault . adapter as FileSystemAdapter ) . getFullPath ( filePath ) ; } throw new Error ( 'cannot determine base path' ) ; } export async function outputResults ( ) { const events = [ ] ; const { vault } = window . app ; const { folder } = getDailyNoteSettings ( ) ; const dailyNotesFolder = vault . getAbstractFileByPath ( normalizePath ( folder ) ) as TFolder ; if ( ! dailyNotesFolder ) { throw new DailyNotesFolderMissingError ( "Failed to find daily notes folder" ) ; } const dailyNotes = getAllDailyNotes ( ) ; for ( const string in dailyNotes ) { if ( dailyNotes [ string ] instanceof TFile ) { await getTasksForDailyNote ( dailyNotes [ string ] , events ) ; } } return events ; } const getAllLinesFromFile = ( cache ) => cache . split ( /\r?\n/ ) ; const lineIsValidTodo = ( line ) => { return /^\s*[\-\*]\s\[(\s|x|X|\\|\-|\>|D|\?|\/|\+|R|\!|i|B|P|C)\]\s?\s*\S/ . test ( line ) ; } ; const lineIsNotTasksTodo = ( line ) => { return /(⏫|🛫|📅|📆|(@{)|⏳|⌛|(\[due\:\:)|(\[created\:\:)|(\[completion\:\:)) ?(\d{4}-\d{2}-\d{2})(\])?/ . test ( line ) ; } ; const lineIsValidTodoEvent = ( line ) => { return /^\s*[\-\*]\s\[ \]\s?\s*\S/ . test ( line ) ; } ; const lineIsValidDoneEvent = ( line ) => { return /^\s*[\-\*]\s\[x\]\s?\s*\S/ . test ( line ) ; } ; const lineIsValidAnotherEvent = ( line ) => { return /^\s*[\-\*]\s\[(X|\\|\-|\>|D|\?|\/|\+|R|\!|i|B|P|C)\]\s?\s*\S/ . test ( line ) ; } ; const lineContainsTime = ( line ) => { return /^\s*[\-\*]\s(\[(\s|x|X|\\|\-|\>|D|\?|\/|\+|R|\!|i|B|P|C)\]\s)?(\<time\>)?\d{1,2}\:\d{2}(.*)$/ . test ( line ) ; } ; const extractTextFromTodoLine = ( line ) => /^\s*[\-\*]\s(\[(\s|x|X|\\|\-|\>|D|\?|\/|\+|R|\!|i|B|P|C)\]\s?)?(\<time\>)?((\d{1,2})\:(\d{2}))?(\<\/time\>)?(.*)$/ . exec ( line ) ?. [ 8 ] ; const extractHourFromBulletLine = ( line ) => /^\s*[\-\*]\s(\[(\s|x|X|\\|\-|\>|D|\?|\/|\+|R|\!|i|B|P|C)\]\s?)?(\<time\>)?(\d{1,2})\:(\d{2})(.*)$/ . exec ( line ) ?. [ 4 ] ; const extractMinFromBulletLine = ( line ) => /^\s*[\-\*]\s(\[(\s|x|X|\\|\-|\>|D|\?|\/|\+|R|\!|i|B|P|C)\]\s?)?(\<time\>)?(\d{1,2})\:(\d{2})(.*)$/ . exec ( line ) ?. [ 5 ] ; const tagFromLine = ( line ) => /\s(#\S{0,})\s/ ;