from enum import Enum import re import os # Assigning numbers to types of data class tokenTypes (Enum): HEADING = 1 DATE = 2 TODO = 3 BULLETPOINT = 4 class date: day = 0 month = 0 year = 0 def __init__(self, dateString: str): dateString = dateString.split(".") self.year = int(dateString[0]) self.month = int(dateString[1]) self.day = int(dateString[2]) def asString(self): return f"{str(self.year)}.{str(self.month):{'0'}>2}.{str(self.day):{'0'}>2}" def tokenize(file: str): headingRe = r"\s*\*\s*([A-z0-9 ]+)\s*\*\s*\[(\d\d\d\d[.]\d\d[.]\d\d)\]\s*{(TO[.]DO|DONE)}\s*" bulletPointRe = r"-\s*((\s|[A-z0-9])+)\s*" unprocessed = [] end = False while not end: heading = re.match(headingRe, file) bulletPoint = re.match(bulletPointRe, file) if heading != None: unprocessed.append(heading.group()) file = file[heading.span()[1]:] elif bulletPoint != None: unprocessed.append(bulletPoint.group()) file = file[bulletPoint.span()[1]:] else: end = True values = [] types = [] for i in unprocessed: heading = re.findall(headingRe, i) bulletPoint = re.findall(bulletPointRe, i) if heading != []: heading = heading[0] values.append(heading[0]) types.append(tokenTypes.HEADING) values.append(date(heading[1])) types.append(tokenTypes.DATE) if heading[2] == "TO.DO": values.append(True) else: values.append(False) types.append(tokenTypes.TODO) elif bulletPoint != []: values.append(bulletPoint[0]) types.append(tokenTypes.BULLETPOINT) return values, types def printHeading(values, i): if values[i + 2]: toDoString = "DONE" else: toDoString = "TO.DO" print(f"{values[i]:{" "}<30}| {values[i+1].asString()} | {toDoString}") def view(values, types): output = "" for i in range(len(values)): if types[i] == tokenTypes.HEADING: output += values[i] + "|" if types[i] == tokenTypes.DATE: output += values[i].asString() + "|" if types[i] == tokenTypes.TODO: if not values[i]: output += "DONE\n" else: output += "TO.DO\n" if types[i] == tokenTypes.BULLETPOINT: output += str(values[i][0]) return output def outputGoatNote(values, types): output = "" for i in range(len(values)): if types[i] == tokenTypes.HEADING: output += "* " + values[i] + " * " if types[i] == tokenTypes.DATE: output += "[" + values[i].asString() + "] " if types[i] == tokenTypes.TODO: if not values[i]: output += "{DONE}\n" else: output += "{TO.DO}\n" if types[i] == tokenTypes.BULLETPOINT: output += "- " + str(values[i][0]) return output # MAIN CODE STARTS HERE Put user into shell then ask for which file to read from fileName = input("Which GOATED file do you wanna read?? \n") if fileName == "": fileName = f"{os.environ["HOME"]}/.global.gn" if ".gn" not in fileName: print("That's not a goatNote file! Silly goose! Automatically putting you into the global file!") fileName = f"{os.environ["HOME"]}/.global.gn" try: file = open(fileName, "r") except: print("ABORT MISSION (couldn't open file)", fileName, "does not exist") exit(1) values, types = tokenize(file.read()) file.close() file = open(fileName, "w") # Drop user into a shell print("enter one of the following commands: list, toggle, view, help, save, or type close (make sure to save first!!) to exit program") line = input(": ").lower().split(" ") while line[0] != "close": if line[0] == "list": for i in range(len(types)): if types[i] == tokenTypes.HEADING: printHeading(values, i) elif line[0] == "toggle": for i in range(len(types)): if types[i] == tokenTypes.HEADING: if values[i] == line[1]: values[i+2] = not values[i+2] break elif line[0] == "view": print(view(values, types)) elif line[0] == "help": if len(line) == 1: print("enter one of the following commands following the word \"help\": list, toggle, view, formatting, save, or type close (make sure to save first!!) to exit program") elif line[1] == "list": print("This command allows you to view a list of all the headings you have in one file.") elif line[1] == "toggle": print("This command allows you to change any specific goatNote from to-do to done. To use this command, type \"toggle (header you want to change)\"") elif line[1] == "view": print("This command allows you to view and read every goatNote you have in your selected file.") elif line[1] == "formatting": print("The formatting style for goatNote files is as follows: \n * heading * [yyyy.mm.dd] {TO.TO/DONE} \n - note body") else: print("enter one of the following commands following the word \"help\": list, toggle, view, formatting, or type close to exit program") elif line[0] == "save": file.write(outputGoatNote(values, types)) file.flush() #save file else: print("Invalid command :(") line = input(": ").lower().split(" ") print("byee(closing program)") file.close()