import of my markdown bullet journal summary util; README doc; logo
This commit is contained in:
parent
dcf02880a9
commit
c746b547ba
|
@ -12,3 +12,4 @@
|
||||||
|
|
||||||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||||
.glide/
|
.glide/
|
||||||
|
.idea/
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
Binary file not shown.
After Width: | Height: | Size: 890 KiB |
|
@ -0,0 +1,54 @@
|
||||||
|
# Markdown Bullet Journal
|
||||||
|
|
||||||
|
![Markdown Bullet Journal Logo](https://github.com/dballard/markdown-bullet-journal/raw/master/src/Markdown-Bullet-Journal.png "Markdown Bullet Journal Logo")
|
||||||
|
|
||||||
|
Markdown Bullet Journal is a digital adaptation of analog tech. I found having a running todo list with daily migrations dropping done items worked best for my workflow. Add a simple summary app to show you all you have accomplished and I'm happy.
|
||||||
|
|
||||||
|
These are a simple set of utilities that work for me. Nothing fancy
|
||||||
|
|
||||||
|
## mdbj-migrate
|
||||||
|
|
||||||
|
When run in a directory, takes the last dated .md file, copies it to a new file with today's date, and dropes all lines marked completed (with a '[x]').
|
||||||
|
|
||||||
|
## mdbj-summary
|
||||||
|
|
||||||
|
Consumes all dated .md files in the directory and prints out all done tasks (lines with '[x]'). Properly collapses nested items into one line names like
|
||||||
|
|
||||||
|
- Complex task
|
||||||
|
- [ ] Subpart A
|
||||||
|
- [x] Task 1
|
||||||
|
|
||||||
|
into
|
||||||
|
|
||||||
|
"Complex task / Subpart A / Task 1"
|
||||||
|
|
||||||
|
## Markdown supported
|
||||||
|
|
||||||
|
The basics of headers with '#'
|
||||||
|
|
||||||
|
Nested lists with '-' and indentation
|
||||||
|
|
||||||
|
Todo and done with '[ ]' and '[x]'
|
||||||
|
|
||||||
|
Obviously you can use other markdown features such as **bold**, *italics* and [Links](https://guides.github.com/features/mastering-markdown/) but none of these trigger any special treatment with regards to Markdown Bullet Journal.
|
||||||
|
|
||||||
|
See the included demo file for a better idea.
|
||||||
|
|
||||||
|
### Extra Markdown Bullet Journal 'modules'
|
||||||
|
|
||||||
|
#### Daily Repetitive Tasks
|
||||||
|
|
||||||
|
These are tasks you might want to do a subset of on any given day, and possibly several times. You would like it tracked, but on migration you would like it 'reset to 0' not dropped. In my case I use it with a list of exercises I pick one to do a few times a day.
|
||||||
|
|
||||||
|
- [x] 4x10 - Pushups
|
||||||
|
- [ ] 0x10 - Crunches
|
||||||
|
- [ ] 0x10 - Lunges
|
||||||
|
- [x] 1x5 - minutes of meditation
|
||||||
|
|
||||||
|
Will get output as:
|
||||||
|
|
||||||
|
- 40 pushups
|
||||||
|
- 5 minutes of meditation
|
||||||
|
|
||||||
|
And then on migration the '4' and '1' will get reset to 0 and the tasks will not get dropped
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"bufio"
|
||||||
|
"strings"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
files, err := ioutil.ReadDir("./")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
if file.Name()[len(file.Name())-3:] == ".md" {
|
||||||
|
genReport(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func genReport(fileInfo os.FileInfo) {
|
||||||
|
file, err := os.Open(fileInfo.Name())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
fmt.Println("")
|
||||||
|
fmt.Println(fileInfo.Name())
|
||||||
|
|
||||||
|
header := ""
|
||||||
|
headerPrinted := false
|
||||||
|
stack := make([]string, 0)
|
||||||
|
|
||||||
|
total := 0
|
||||||
|
doneCount := 0
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
if scanner.Text() == "# Daily Health" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if strings.Trim(scanner.Text(), " \t\n\r") == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if scanner.Text()[0] == '#' {
|
||||||
|
header = scanner.Text()[2:]
|
||||||
|
headerPrinted = false;
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
startSpaces := regexp.MustCompile("^ *")
|
||||||
|
indentLevel := len(startSpaces.Find([]byte(scanner.Text())))/4
|
||||||
|
todo := false
|
||||||
|
done := false
|
||||||
|
if indentLevel < len(stack)-1 {
|
||||||
|
stack = stack[: indentLevel+1]
|
||||||
|
}
|
||||||
|
if indentLevel == len(stack)-1 {
|
||||||
|
stack[len(stack)-1], todo, done = getText(scanner.Text(), indentLevel)
|
||||||
|
}
|
||||||
|
if indentLevel >= len(stack) {
|
||||||
|
line := ""
|
||||||
|
line, todo, done = getText(scanner.Text(), indentLevel)
|
||||||
|
stack = append(stack, line)
|
||||||
|
}
|
||||||
|
|
||||||
|
if todo {
|
||||||
|
total += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if done {
|
||||||
|
if !headerPrinted {
|
||||||
|
fmt.Println(" # " + header)
|
||||||
|
headerPrinted = true
|
||||||
|
}
|
||||||
|
doneCount += 1
|
||||||
|
fmt.Println(" " + strings.Join(stack, " / "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(doneCount, "/", total)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getText(str string, indentLevel int) (text string, todo bool, done bool) {
|
||||||
|
//fmt.Printf("indentLevel: %v str: '%s'\n", indentLevel, str )
|
||||||
|
if len(str) < (indentLevel*4 +2) {
|
||||||
|
return "", false, false
|
||||||
|
}
|
||||||
|
text = str[indentLevel*4 +2:]
|
||||||
|
done = false
|
||||||
|
todo = false
|
||||||
|
if text[0] == '[' {
|
||||||
|
todo = true
|
||||||
|
if text[1] == 'x' || text[1] == 'X' {
|
||||||
|
done = true
|
||||||
|
}
|
||||||
|
if len(text) > 4 {
|
||||||
|
text = text[4:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in New Issue