From 76f3a63391864449b3dd6b937fdd614f7a379cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A8r=20Kessels?= Date: Mon, 4 Nov 2019 14:14:44 +0100 Subject: [PATCH] Make due-date follow the todotxt convention: don't abuse the creation date Currently, todotxt gem is incompatible with todo.txt as it uses the space for 'creation date' to store a 'due date'. https://github.com/todotxt/todo.txt#todotxt-format-rules This patch changes that to use the key:value format as place to hold due: dates. https://github.com/todotxt/todo.txt#additional-file-format-definitions This makes it compatible with e.g. simpletask app and gnome-todo. --- features/due.feature | 26 ++++++++++++------------- features/step_definitions/list_steps.rb | 2 ++ lib/todotxt/regex.rb | 2 +- lib/todotxt/todo.rb | 2 +- spec/todo_spec.rb | 9 +++++---- spec/todolist_spec.rb | 6 +++--- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/features/due.feature b/features/due.feature index e7b529d..b91ecf0 100644 --- a/features/due.feature +++ b/features/due.feature @@ -15,35 +15,35 @@ Feature: Due Scenario: List due items Given the date is "2012-12-12" And a todofile with the following items exists: - | todo | - | 2012-12-17 Install todotxt @cli +todotxt | - | Read documentation +todotxt | - | 2012-12-12 Buy GTD book @amazon +wishlist | - | 2012-12-19 Evaluate installation +todotxt | + | todo | + | 2012-11-17 Install todotxt due:2012-12-17 @cli +todotxt | + | Read documentation +todotxt | + | Buy GTD book due:2012-12-12 @amazon +wishlist | + | Evaluate installation due:2012-12-19 +todotxt | When I run `todotxt due` interactively Then it should pass with exactly: """ Due today (2012-12-12) - 3. 2012-12-12 Buy GTD book @amazon +wishlist + 3. Buy GTD book due:2012-12-12 @amazon +wishlist Past-due items Due 7 days in advance - 1. 2012-12-17 Install todotxt @cli +todotxt - 4. 2012-12-19 Evaluate installation +todotxt + 1. 2012-11-17 Install todotxt due:2012-12-17 @cli +todotxt + 4. Evaluate installation due:2012-12-19 +todotxt """ Scenario: list overdue items Given the date is "2012-12-12" And a todofile with the following items exists: - | todo | - | 2012-12-17 Install todotxt @cli +todotxt | - | Read documentation +todotxt | - | 2012-11-11 Buy GTD book @amazon +wishlist | + | todo | + | Install todotxt due:2012-12-17 @cli +todotxt | + | Read documentation +todotxt | + | 2012-10-11 Buy GTD book due:2012-11-11 @amazon +wishlist | When I run `todotxt due` interactively Then it should pass with: """ Past-due items - 3. 2012-11-11 Buy GTD book @amazon +wishlist + 3. 2012-10-11 Buy GTD book due:2012-11-11 @amazon +wishlist """ diff --git a/features/step_definitions/list_steps.rb b/features/step_definitions/list_steps.rb index 64544f1..7e1c452 100644 --- a/features/step_definitions/list_steps.rb +++ b/features/step_definitions/list_steps.rb @@ -1,3 +1,5 @@ +require "date" + Then /^I should see all entries from the todofile with numbers$/ do step %{I should see all entries from the todofile named "todo.txt" with numbers} end diff --git a/lib/todotxt/regex.rb b/lib/todotxt/regex.rb index 1665b71..f35f485 100644 --- a/lib/todotxt/regex.rb +++ b/lib/todotxt/regex.rb @@ -2,6 +2,6 @@ module Todotxt PRIORITY_REGEX = /^\(([A-Z])\) /.freeze PROJECT_REGEX = /(\+\w+)/.freeze CONTEXT_REGEX = /(@\w+)/.freeze - DATE_REGEX = /^(\([A-Z]\) )?(x )?((\d{4}-)(\d{1,2}-)(\d{1,2}))\s?/.freeze + DATE_REGEX = /(\s+due:((\d{4}-)(\d{1,2}-)(\d{1,2})))/.freeze DONE_REGEX = /^(\([A-Z]\) )?x /.freeze end diff --git a/lib/todotxt/todo.rb b/lib/todotxt/todo.rb index f0b3bd4..e17b32a 100644 --- a/lib/todotxt/todo.rb +++ b/lib/todotxt/todo.rb @@ -28,7 +28,7 @@ def initialize(text, line = nil) # Get due date if set # @return [Date|Nil] def due - date = Chronic.parse(text.scan(DATE_REGEX).flatten[2]) + date = Chronic.parse(text.scan(DATE_REGEX).flatten[1]) date.nil? ? nil : date.to_date end diff --git a/spec/todo_spec.rb b/spec/todo_spec.rb index 213bfb2..b0e6211 100644 --- a/spec/todo_spec.rb +++ b/spec/todo_spec.rb @@ -25,14 +25,15 @@ expect(todo.done).to be_truthy end - it 'parses a due date' do - todo = Todotxt::Todo.new '(A) x 2012-12-12 an item +project1 +project2 @context1 @context2' + it 'parses a due: date' do + # prio state completion-date creation-date description ... key:value + todo = Todotxt::Todo.new '(A) x 2012-11-22 2011-11-12 an item due:2012-12-12 +project1 +project2 @context1 @context2' expect(todo.due).to eql(Chronic.parse('12 December 2012').to_date) - todo = Todotxt::Todo.new '2012-1-2 an item +project1 +project2 @context1 @context2' + todo = Todotxt::Todo.new 'item due:2012-1-2 +project1 +project2 @context1 @context2' expect(todo.due).to eql(Chronic.parse('2 January 2012').to_date) - todo = Todotxt::Todo.new '42 folders' + todo = Todotxt::Todo.new '2011-31-1 42 folders' expect(todo.due).to be_nil end diff --git a/spec/todolist_spec.rb b/spec/todolist_spec.rb index bfa8b6f..d2173d6 100644 --- a/spec/todolist_spec.rb +++ b/spec/todolist_spec.rb @@ -48,15 +48,15 @@ end it 'fetches items for a certain date' do - @list.add '2012-12-12 item' + @list.add 'item due:2012-12-12' date = DateTime.parse('2012-12-12') expect(@list.on_date(date).count).to eql 1 expect(@list.on_date(date)).to match([@list.todos.last]) end it 'fetchs items before a cereain date' do - @list.add '2012-11-11 item' - @list.add '2012-12-12 item' + @list.add 'item due:2012-11-11' + @list.add 'item due:2012-12-12' date = DateTime.parse('2012-12-12') expect(@list.before_date(date).count).to eql 1 end