#!/usr/bin/awk -f BEGIN { RS="---\n" # set ---\n as record separator FS="\n\n" # set \n\n as field separator secs_per_day = 86400 "date +%s" | getline now # get current unix seconds timestamp "mktemp" | getline file # create a temporary file close("date +%s") close ("mktemp") gsub("\n", "", file) # remove trailing newline from 'file' string } NF <= 1 { next } # skip invalid lines quit == 1 { print $0 > file } { q = $1 # first field is the question a = $2 # seconf field is the answer # the third field represents our metadata. # for a newly created flashcard file, it does not exist fn = 0 # how many subfields the metadata field has if (NF == 3) { gsub("\n", "", $3) fn = split($3, data, ":") } g = (fn > 0) ? data[1] : 0 # user grade n = (fn > 1) ? data[2] : 0 # repetion number ef = (fn > 2) ? data[3] : 2.5 # easiness factor i = (fn > 3) ? data[4] : 0 # number of days before review then = (fn > 4) ? data[5] : now # last access unix second timestamp date = then sm2() write() } # before exiting, replace flash card file with our temporary file END { system("[ -s " file " ] && mv " file " " FILENAME) } # supermemo2 spaced repetion algorithm function sm2() { if (i == 0) # new card, display and update i to 1 i = 1 else if ( (now - then) / secs_per_day < i) { return 0 } display() # show the user the card # correct values in case of bad input ef = (g == 0) ? 2.5 : ef if (g == "q") { # if the user types 'q' instead of grade (0-5), exit g = 0 quit == 1 return 1 } if (g >= 3) { if (n == 0) i = 1 else if ( n == 1) i = 6 else i = int(i * ef) n++ } else { n = 0 i = 1 } ef += 0.1 - (5-g) * (0.08 + (5-g) * 0.02) date = now return 1 } # writes a record to the flashcard file function write() { printf("%s\n\n", q) > file printf("%s\n\n", a) >> file printf("%d:", g) >> file printf("%d:", n) >> file printf("%f:", ef) >> file printf("%d:", i) >> file printf("%d\n", date)>> file printf("---\n") >> file } # displays a flashcard and reacts to user input function display() { col_g = "\033[0;32m" col_def= "\033[0m" col_y= "\033[0;33m" printf("%s[question]:%s %s", col_y, col_def, q); input() printf("%s[answer]:%s %s\n", col_y, col_def, a) printf("%s[grade]%s (0 -> 5): ", col_y, col_def) g = input() } # fetches user input function input( tmp) { read = "i=; read i; echo $i" read | getline tmp close(read) return tmp }