REBOL [ Title: "To Do Script" File-name: %to-do-guru.r Date: 10-June-2008 Author: "Ed O'Connor" License: "MIT" ] cmds: [ ['add | 'create ] set str string! (add-task str) | ['replace | 'swap ] set id integer! set str string! (replace-task id str) | ['append | 'affix ] set id integer! set str string! (append-task id str) | ['pri | 'rank ] set id integer! set str string! (prioritize) | ['done | 'do ] set id integer! (mark-complete id) | ['find | 'search ] set str string! (find-tasks str) | ['listpri | 'lspri ] (print-tasks/pri) | ['listhab | 'lshab ] (print-tasks/hab) | ['list | 'ls ] (print-tasks) | ['help | '? ] (print "help tbd") | ['editor | 'gui ] (launch-editor) | ['archive | 'arch ] (archive) | ['restore | 'rs ] (restore) | ['quit | 'q ] (print "Session ended." halt) ] read-tasks: func [/local id][ tasks: any [attempt [read/lines %todo.txt] copy []] id: 0 forskip tasks 2 [ id: id + 1 insert tasks id ] sort/skip/compare tasks 2 2 ] save-tasks: func [/local task-write output out][ task-write: copy tasks sort/skip task-write 2 output: extract/index task-write 2 2 out: make string! 100 foreach item output [repend out [item newline]] write %todo.txt out ] add-task: func [task [string!]][ either not empty? trim task [ next-id: add 1 (length? tasks) / 2 repend tasks [next-id task] save-tasks ][ print "Error: Missing task description." ] ] append-task: func [index [integer!] fragm [string!] /local task][ either find tasks index [ task: select tasks index append task rejoin [" " fragm] save-tasks ][ print "Task number not found." ] ] replace-task: func [index [integer!] newstr [string!] /local task][ either find tasks index [ task: select tasks index task: newstr save-tasks ][ print "Task number not found." ] ] mark-complete: func [index [integer!] /local task][ either > length? tasks 0 [ task: select tasks index insert task "X " save-tasks ][ print "Task number does not exist." ] ] archive: does [ either > length? tasks 0 [ foreach [i t] tasks [ if #"X" = first t [write/append %done.txt rejoin [t newline]] ] remove-each [i t] tasks [#"X" = first t] save-tasks read-tasks ][ print "No tasks currently marked for archiving." ] ] restore: does [ done: any [attempt [read/lines %done.txt] copy []] either all [ > length? done 0 exists %todo.txt ][ foreach task done [ unless #"X" = first t [write/append %todo.txt rejoin [task newline]] ] remove-each [i t] done [#"X" <> first task] write/lines %done.txt done save-tasks read-tasks ][ print "Unable to restore tasks: Missing todo.txt and/or done.txt." ] ] alpha: charset [#"A" - #"Z" #"a" - #"z"] pri-format: ["(" some alpha ")"] print-tasks: func [/pri /hab /local output] [ output: copy [] print "CURRENT TASKS" foreach [i t] tasks [ if pri [parse/all t [some [pri-format (repend output [i t]) break | skip]]] if hab [parse/all t [any ["~recur" (repend output [i t]) break | skip]]] unless any [pri hab][repend output [i t]] ] foreach [i t] output [print rejoin [i ": " t]] print [(length? output) / 2 "tasks listed." newline] ] find-tasks: func [params [string!] /local criteria ][ criteria: parse/all params " " rule: copy [skip] foreach param criteria [ insert rule [(print rejoin [i ": " t]) break |] insert rule compose [(param)] ] foreach [i t] tasks [bind rule 'i parse/all t [some rule]] ] launch-editor: does [ either system/product = 'view [ editor %todo.txt ][ print "Sorry, REBOL/View is required to launch the GUI editor". ] ] read-tasks forever [ unless parse load/all ask "to-do >> " [cmds] [print "? Input not recognized."] ]