Skip to content

Instantly share code, notes, and snippets.

@phette23
Last active October 30, 2023 15:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phette23/affa231c5ae28a0bad54d687a614efa2 to your computer and use it in GitHub Desktop.
Save phette23/affa231c5ae28a0bad54d687a614efa2 to your computer and use it in GitHub Desktop.
todo.txt extension - count finished tasks by project references
#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const readline = require('readline')
const todo_dir = process.env.TODO_DIR
// TODO we could make this optionally count todo.txt too e.g. with a CLI flag
const done_file = path.join(todo_dir, 'done.txt')
const projregex = /(\+[A-Za-z0-9]+)(\s|$)/g
const ctxregex = /(@[A-Za-z0-9]+)(\s|$)/g
let counts = {}
if (process.argv.includes('usage')) {
console.log(
` projectcount
Counts the number of times each project ("+project") was mentioned in a
completed task i.e. in done.txt.
-c, --ctx, --context flag: count @contexts instead of +projects.`)
process.exit(0)
}
let regex = null
if (process.argv.includes('-c') || process.argv.includes('--ctx') || process.argv.includes('--context')) {
regex = ctxregex
} else {
regex = projregex
}
const rl = readline.createInterface({
input: fs.createReadStream(done_file),
crlfDelay: Infinity // treate CRLF as line ending
})
rl.on('line', (line) => {
let matches = line.match(regex)
matches && matches.forEach(match => {
let project = match.trim().substring(1).toLowerCase()
counts.hasOwnProperty(project) ? counts[project]++ : counts[project] = 1
})
}).on('close', () => {
// we want column width to be _at least_ the longest project name + 1
let width = Object.keys(counts).reduce((acc, val) => {
if (acc > val.length) return acc
return val.length
}, 0) + 1
console.log(`${'Project'.padEnd(width)} Tasks`)
// Object.entries returns an array of [key, value] arrays
Object.entries(counts).sort((a, b) => {
return b[1] - a[1]
}).forEach(p => {
console.log(`${p[0].padEnd(width)} ${p[1]}`)
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment