go-todotxt/todotxt.go

146 lines
4.2 KiB
Go

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Package todotxt is a Go client library for Gina Trapani's todo.txt files.
// It allows for parsing and manipulating of task lists and tasks in the todo.txt format.
//
// Source code and project home: https://github.com/JamesClonk/go-todotxt
package todotxt
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"strings"
)
// TaskList represents a list of todo.txt task entries.
// It is usually loaded from a whole todo.txt file.
type TaskList []Task
// IgnoreComments can be set to 'false', in order to revert to a more standard todo.txt behaviour.
// The todo.txt format does not define comments.
var (
// IgnoreComments is used to switch ignoring of comments (lines starting with "#").
// If this is set to 'false', then lines starting with "#" will be parsed as tasks.
IgnoreComments = true
)
// String returns a complete tasklist string in todo.txt format.
func (tasklist TaskList) String() (text string) {
for _, task := range tasklist {
text += fmt.Sprintf("%s\n", task.String())
}
return text
}
// AddTask appends a task to the current TaskList, and takes care to set the Task.Id correctly, modifying the Task by the given pointer!
func (tasklist *TaskList) AddTask(task *Task) (err error) {
task.Id = 0
for _, t := range *tasklist {
if t.Id > task.Id {
task.Id = t.Id
}
}
task.Id += 1
*tasklist = append(*tasklist, *task)
return
}
// LoadFromFile loads a TaskList from *os.File.
//
// Using *os.File instead of a filename allows to also use os.Stdin.
//
// Note: This will clear the current TaskList and overwrite it's contents with whatever is in *os.File.
func (tasklist *TaskList) LoadFromFile(file *os.File) error {
*tasklist = []Task{} // Empty tasklist
taskId := 1
scanner := bufio.NewScanner(file)
for scanner.Scan() {
text := strings.Trim(scanner.Text(), "\t\n\r ") // Read line
// Ignore blank or comment lines
if text == "" || (IgnoreComments && strings.HasPrefix(text, "#")) {
continue
}
task, err := ParseTask(text)
if err != nil {
return err
}
task.Id = taskId
*tasklist = append(*tasklist, *task)
taskId++
}
if err := scanner.Err(); err != nil {
return err
}
return nil
}
// WriteToFile writes a TaskList to *os.File.
//
// Using *os.File instead of a filename allows to also use os.Stdout.
func (tasklist *TaskList) WriteToFile(file *os.File) error {
writer := bufio.NewWriter(file)
_, err := writer.WriteString(tasklist.String())
writer.Flush()
return err
}
// LoadFromFilename loads a TaskList from a file (most likely called "todo.txt").
//
// Note: This will clear the current TaskList and overwrite it's contents with whatever is in the file.
func (tasklist *TaskList) LoadFromFilename(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
return tasklist.LoadFromFile(file)
}
// WriteToFilename writes a TaskList to the specified file (most likely called "todo.txt").
func (tasklist *TaskList) WriteToFilename(filename string) error {
return ioutil.WriteFile(filename, []byte(tasklist.String()), 0640)
}
// LoadFromFile loads and returns a TaskList from *os.File.
//
// Using *os.File instead of a filename allows to also use os.Stdin.
func LoadFromFile(file *os.File) (TaskList, error) {
tasklist := TaskList{}
if err := tasklist.LoadFromFile(file); err != nil {
return nil, err
}
return tasklist, nil
}
// WriteToFile writes a TaskList to *os.File.
//
// Using *os.File instead of a filename allows to also use os.Stdout.
func WriteToFile(tasklist *TaskList, file *os.File) error {
return tasklist.WriteToFile(file)
}
// LoadFromFilename loads and returns a TaskList from a file (most likely called "todo.txt").
func LoadFromFilename(filename string) (TaskList, error) {
tasklist := TaskList{}
if err := tasklist.LoadFromFilename(filename); err != nil {
return nil, err
}
return tasklist, nil
}
// WriteToFilename writes a TaskList to the specified file (most likely called "todo.txt").
func WriteToFilename(tasklist *TaskList, filename string) error {
return tasklist.WriteToFilename(filename)
}