org_mode 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ gemspec
6
6
  gem "commander"
7
7
  gem "facets"
8
8
  gem "mustache"
9
+ gem "colorize"
9
10
 
10
11
  group :development do
11
12
  if RUBY_VERSION =~ /^1\.9/
@@ -21,6 +22,7 @@ group :test do
21
22
  gem "timecop"
22
23
  gem "guard-cucumber"
23
24
  gem "popen4"
25
+ gem "pry"
24
26
  end
25
27
 
26
28
 
data/bin/org-mode CHANGED
@@ -11,22 +11,20 @@ program :description, 'Formats and extracts information out of org-mode files'
11
11
  program :help_formatter, :compact
12
12
 
13
13
  command :agenda do |c|
14
- c.syntax = 'org-mode agenda [options]'
15
- c.summary = ''
16
- c.description = ''
17
- c.example 'description', 'command example'
18
- c.option '--some-switch', 'Some switch that does something'
14
+ c.syntax = 'org-mode agenda [options] *org-mode-files'
15
+ c.summary = 'Displays information on scheduled items'
16
+ c.description = nil
17
+ c.example 'extract information on scheduled items out of files', 'org-mode agenda an-org-file.org'
18
+ c.option '--no-color', 'Do not use color in output'
19
19
  c.when_called OrgMode::Commands::Agenda, :execute
20
20
  end
21
21
 
22
22
  command :update do |c|
23
- c.syntax = 'Orgy update [options]'
24
- c.summary = ''
25
- c.description = ''
23
+ c.syntax = 'org-mode update [options]'
24
+ c.summary = 'Reformats an org-file'
25
+ c.description = 'Reformat and update the org-file. Converting the org-file to a standard format'
26
26
  c.example 'description', 'command example'
27
- c.option '--some-switch', 'Some switch that does something'
28
- c.action do |args, options|
29
- # Do something or c.when_called Orgy::Commands::Update
30
- end
27
+ c.option '--archive-done', 'Archives done items'
28
+ c.when_called OrgMode::Commands::Update, :execute
31
29
  end
32
30
 
@@ -11,12 +11,11 @@ Feature: agenda
11
11
  """
12
12
  When the script is executed on the org-file
13
13
  When the script is called with "agenda"
14
- Then the output should be
15
- """
16
- Agenda ()
17
- 2012-01-01
18
- TODO Scheduled task
19
- """
14
+ Then the output should contain "Agenda"
15
+ And the output should contain "2012-01-01"
16
+ And the output should contain "15:15"
17
+ And the output should contain "TODO"
18
+ And the output should contain "Scheduled task"
20
19
 
21
20
  # @focus
22
21
  # Scenario: should limit restults in a day view
@@ -0,0 +1,42 @@
1
+ Feature: org-mode update <orgfile>
2
+ org-mode script should reformat a file correctly
3
+ to a user can easily reformat an org-file in a
4
+ standarized way. This also enables certain
5
+ filters to be applied.
6
+
7
+ Scenario: should present meaningfull agenda information
8
+ Given we have an org-file with the following content
9
+ """
10
+ a header
11
+ * TODO Scheduled task <1-1-2012 Wed 15:15>
12
+ content that will be indented
13
+ multiline that is
14
+ ** TODO Scheduled task <1-1-2012 Wed 15:15-16:15>
15
+ some other content that will be indented
16
+ """
17
+ When the script is called with "update"
18
+ Then the output should be
19
+ """
20
+ a header
21
+
22
+ * TODO <2012-01-01 Sun 15:15> Scheduled task
23
+ content that will be indented
24
+ multiline that is
25
+ ** TODO <2012-01-01 Sun 15:15-16:15> Scheduled task
26
+ some other content that will be indented
27
+ """
28
+
29
+ # @focus
30
+ # Scenario: should limit restults in a day view
31
+ # Given date is "1-1-2012 15:00"
32
+ # And we have an org-file with the following content
33
+ # """
34
+ # * TODO Todays task <1-1-2012 Wed 15:15>
35
+ # * TODO Tommorrows task <2-1-2012 Wed 15:15>
36
+ # """
37
+ # When the script is called with "agenda today"
38
+ # Then the output should be
39
+ # """
40
+ # Todays activities:
41
+ # TODO Todays task
42
+ # """
data/features/steps.rb CHANGED
@@ -30,6 +30,10 @@ end
30
30
  Then /^the output should be$/ do |string|
31
31
  @stdout.should == string
32
32
  end
33
+ Then /^the output should contain "([^""]*)"$/ do |pattern|
34
+ @stdout.should match(pattern)
35
+ end
36
+
33
37
  Then /^the error should be$/ do |string|
34
38
  @script_error.stderr.chomp.should == string
35
39
  end
@@ -0,0 +1,13 @@
1
+ require 'stringio'
2
+
3
+ def capture_stdout
4
+ out = StringIO.new
5
+ old_stdout = $stdout
6
+ $stdout = out
7
+ yield
8
+ out.rewind
9
+ return out.read
10
+ ensure
11
+ $stdout = old_stdout
12
+ end
13
+
@@ -1,9 +1,9 @@
1
1
  require 'org_mode/parser'
2
2
  require 'org_mode/loader'
3
3
  require 'org_mode/reporters/agenda'
4
+ require 'org_mode/presenters/console'
4
5
 
5
6
  require 'core_ext/string'
6
- require 'mustache'
7
7
 
8
8
  module OrgMode::Commands
9
9
  class Agenda
@@ -18,19 +18,9 @@ module OrgMode::Commands
18
18
 
19
19
  file_collection = OrgMode::Loader.load_and_parse_files(*args)
20
20
  agenda_reporter = OrgMode::Reporters::Agenda.new(file_collection)
21
+ text_presenter = OrgMode::Presenters::Agenda::Console.new(agenda_reporter)
21
22
 
22
- tmpl_vars = {}
23
- tmpl_vars[:noi_per_date] = agenda_reporter.open_nodes_grouped_by_day
24
-
25
- puts Mustache.render <<-eos.strip_indent(8), tmpl_vars
26
- Agenda ()
27
- {{#noi_per_date}}
28
- {{date}}
29
- {{#nodes}}
30
- {{todo_state}}{{title}}
31
- {{/nodes}}
32
- {{/noi_per_date}}
33
- eos
23
+ puts text_presenter.open_items_per_day_colorized
34
24
 
35
25
  rescue SystemCallError => e
36
26
  puts "Encountered a little problem: #{e}"
@@ -1,4 +1,23 @@
1
+ require 'org_mode/parser'
2
+ require 'org_mode/loader'
3
+ require 'org_mode/formatters/textual'
4
+ require 'org_mode/processors/archive_done'
5
+
1
6
  module OrgMode::Commands
2
7
  class Update
8
+ def execute(args, options)
9
+ org_file = OrgMode::Loader.load_and_parse_file(args[0])
10
+
11
+ if options.archive_done
12
+ org_file = OrgMode::Processors::ArchiveDone.new(org_file).process
13
+ end
14
+
15
+ org_formatter = OrgMode::Formatters::Textual.new(org_file)
16
+
17
+ puts org_formatter.format
18
+
19
+ rescue StandardError => e
20
+ puts "Encountered a little problem: #{e}"
21
+ end
3
22
  end
4
23
  end
@@ -0,0 +1,48 @@
1
+ require 'org_mode'
2
+ require 'facets/kernel/blank'
3
+
4
+ module OrgMode
5
+ module Formatters
6
+ class Textual
7
+ def initialize(org_file)
8
+ @org_file = org_file
9
+ end
10
+
11
+ def format
12
+ [ @org_file.header,
13
+ @org_file.nodes.map {|n| format_node(n)} * "\n",
14
+ @org_file.footer ].reject(&:blank?) * "\n\n"
15
+ end
16
+
17
+ def format_node(node)
18
+ [format_title(node), format_content(node)].reject(&:blank?) * "\n"
19
+ end
20
+
21
+ def format_title(node)
22
+ stars = "*" * node.stars
23
+ [stars, node.todo_state, format_date(node), node.title].reject(&:blank?) * ' '
24
+ end
25
+
26
+ def format_content(node)
27
+ node.content.lines.map do |l|
28
+ [" " * node.indent, l].join
29
+ end.join
30
+ end
31
+
32
+ def format_date(node)
33
+ date = if node.date_end_time
34
+ "#{node.date_start_time.strftime('%Y-%m-%d %a %H:%M')}-#{node.date_end_time.strftime('%H:%M')}"
35
+ elsif node.date_start_time
36
+ "#{node.date_start_time.strftime('%Y-%m-%d %a %H:%M')}"
37
+ elsif node.date
38
+ "#{node.date.strftime('%Y-%m-%d %a')}"
39
+ else
40
+ nil
41
+ end
42
+
43
+ date ? "<#{date}>" : nil
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,20 @@
1
+ module OrgMode
2
+ class NodeUtils
3
+ # Public: transforms a sequental list of
4
+ # nodes into a tree structure setting
5
+ # parents and children on the nodes
6
+ def self.convert_sequential_nodelist_into_tree(nodes)
7
+ parent_stack = []
8
+ nodes.map! do |node|
9
+ node.parent = parent_stack[node.stars - 1]
10
+ if node.parent
11
+ node.parent.children << node
12
+ end
13
+ parent_stack[node.stars] = node
14
+ end
15
+
16
+ # filter out all non root nodes
17
+ nodes.select(&:root_node?)
18
+ end
19
+ end
20
+ end
@@ -7,6 +7,7 @@
7
7
  # Parser is decoupled from object model to make it easy to write updated
8
8
  # parsers or use a database to serialize an org-mode file out of.
9
9
  require 'org_mode'
10
+ require 'org_mode/node_utils'
10
11
  require 'date'
11
12
 
12
13
  module OrgMode
@@ -29,18 +30,18 @@ module OrgMode
29
30
  # Returns OrgMode::File object containing all
30
31
  # information of the file.
31
32
  def parse(buffer)
32
- b, nodes, e = parse_buffer(buffer)
33
-
34
- parent_stack = []
35
- nodes.map! do |title, content|
36
- node = NodeParser.parse(title,content)
37
- node.parent = parent_stack[node.stars - 1]
38
- if node.parent
39
- node.parent.children << node
40
- end
41
- parent_stack[node.stars] = node
33
+ b, nodes, e = parse_buffer(buffer)
34
+
35
+ parsed_nodes = parse_nodes(nodes)
36
+ root_nodes = NodeUtils.convert_sequential_nodelist_into_tree(parsed_nodes)
37
+
38
+ return File.new(b,root_nodes,e)
39
+ end
40
+
41
+ def parse_nodes(nodes)
42
+ nodes.map do |title,content|
43
+ NodeParser.parse(title,content)
42
44
  end
43
- return File.new(b,nodes,e)
44
45
  end
45
46
 
46
47
  def parse_buffer(buffer)
@@ -110,11 +111,11 @@ module OrgMode
110
111
  def parse_extract_dates(node)
111
112
  _, extracted_date, start_time, end_time = node.title.match(RxDateRegexp).to_a
112
113
  node.title = node.title.gsub(RxDateRegexp, '')
114
+ node.title.strip!
113
115
 
114
- if extracted_date
115
- node.date_start_time = DateTime.parse("#{extracted_date} #{start_time}")
116
- node.date_end_time = DateTime.parse("#{extracted_date} #{end_time}")
117
- end
116
+ node.date = DateTime.parse(extracted_date) if extracted_date
117
+ node.date_start_time = DateTime.parse("#{extracted_date} #{start_time}") if start_time
118
+ node.date_end_time = DateTime.parse("#{extracted_date} #{end_time}") if end_time
118
119
  end
119
120
 
120
121
  RxEmptyLine = /^\s*$/
@@ -0,0 +1,51 @@
1
+ require 'colorize'
2
+ require 'capture_stdout'
3
+
4
+ module OrgMode
5
+ module Presenters
6
+ module Agenda
7
+
8
+ class Console
9
+ def initialize reporter
10
+ @agenda_reporter = reporter
11
+ end
12
+
13
+ def open_items_per_day_colorized
14
+ capture_stdout do
15
+ now = DateTime.now
16
+ puts "Agenda: open items grouped by day [#{now.strftime('%Y-%m-%d %H:%M')}]".yellow.underline
17
+ puts
18
+ ongbd = @agenda_reporter.open_nodes_grouped_by_day
19
+ ongbd.each do |e|
20
+ puts "#{e.date}".blue.underline
21
+ e.nodes.each do |n|
22
+ color = :green
23
+ color = :red if n.date_start_time && n.node.date_start_time < now
24
+ color = :red if n.date && n.node.date < now
25
+
26
+ puts " " + node_line(n).send(color)
27
+ end
28
+ puts
29
+ end
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def node_line(n)
36
+ title = [n.todo_state, n.title].reject(&:nil?) * ' '
37
+ if n.appointment?
38
+ if n.date_end_time
39
+ "%s-%s %s" % [n.date_start_time, n.date_end_time, title]
40
+ else
41
+ "%s %s" % [n.date_start_time, title]
42
+ end
43
+ else
44
+ "ALL-DAY %s" % [title]
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,69 @@
1
+ require 'org_mode'
2
+ require 'core_ext/string'
3
+ require 'delegate'
4
+
5
+ module OrgMode
6
+ module Processors
7
+ class ArchiveDoneOrgFile < SimpleDelegator
8
+ def initialize(org_file)
9
+ super(org_file)
10
+ end
11
+
12
+ def archived_root_node
13
+ select_by_title(/^Archived$/, :stars => 1).first
14
+ end
15
+
16
+ def create_archived_root_node
17
+ self.root_nodes << OrgMode::Node.new.tap do |n|
18
+ n.title = "Archived"
19
+ n.content = <<-eos.strip_indent(10)
20
+ This node contains archived items. Appended
21
+ due to calling the script with update --archive-done
22
+ eos
23
+ n.stars = 1
24
+ end
25
+ end
26
+
27
+ def move_done_trees_to_archived_root_node
28
+ processed_nodes = []
29
+ self.nodes.each do |n|
30
+ # if not done move to processed nodes
31
+ # if done append to archived_root_node
32
+ end
33
+ end
34
+ end
35
+
36
+ class ArchiveDone
37
+ def initialize(org_file)
38
+ @org_file = ArchiveDoneOrgFile.new(org_file)
39
+ end
40
+
41
+ def process
42
+ @org_file.create_archived_root_node unless @org_file.archived_root_node
43
+
44
+ to_be_archived_trees = []
45
+ walk_and_update_node_children @org_file do |children|
46
+ to_be_archived_trees << children.select(&:done?)
47
+ children.reject(&:done?)
48
+ end
49
+
50
+ @org_file.archived_root_node.children.concat( to_be_archived_trees.flatten )
51
+
52
+ @org_file
53
+ end
54
+
55
+ # Private: walks all nodes
56
+ # but updates children array with
57
+ # return value of called function.
58
+ #
59
+ # Can be used to extract nodes from
60
+ # tree
61
+ def walk_and_update_node_children(node, &block)
62
+ node.children = block.call(node.children)
63
+ node.children.map do |n|
64
+ walk_and_update_node_children(n, &block)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,4 +1,5 @@
1
1
  require 'facets/to_hash'
2
+ require 'facets/ostruct'
2
3
 
3
4
  module OrgMode
4
5
  module Reporters
@@ -26,17 +27,21 @@ module OrgMode
26
27
  # build a nice orderd struct
27
28
  noi_per_day.keys.sort.map do |date|
28
29
  { :date => date, :nodes => noi_per_day[date].map { |n| node_to_hash(n) } }
29
- end
30
+ end.map(&:to_ostruct)
31
+
30
32
  end
31
33
 
32
34
  private
33
35
 
34
36
  def node_to_hash(node)
35
- rv = [:title, :content, :todo_state, :date, :stars].
37
+ rv = [:title, :content, :todo_state, :date, :date_start_time, :date_end_time, :stars, :appointment?].
36
38
  map { |k| [ k, node.send(k) ] }.to_h
37
39
 
38
40
  rv[:date] = rv[:date].strftime('%Y-%m-%d %H:%M') if rv[:date]
39
- rv
41
+ rv[:date_start_time] = rv[:date_start_time].strftime('%H:%M') if rv[:date_start_time]
42
+ rv[:date_end_time] = rv[:date_end_time].strftime('%H:%M') if rv[:date_end_time]
43
+ rv[:node] = node
44
+ rv.to_ostruct
40
45
  end
41
46
 
42
47
  end
@@ -1,3 +1,3 @@
1
1
  module OrgMode
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/org_mode.rb CHANGED
@@ -14,9 +14,8 @@ require "org_mode/version"
14
14
 
15
15
  module OrgMode
16
16
 
17
-
18
17
  class Node
19
- attr_accessor :title, :content, :stars, :date_start_time, :date_end_time, :todo_state
18
+ attr_accessor :title, :content, :stars, :date, :date_start_time, :date_end_time, :todo_state
20
19
  attr_accessor :parent, :children
21
20
 
22
21
  def initialize
@@ -24,9 +23,6 @@ module OrgMode
24
23
  @children = []
25
24
  end
26
25
 
27
- alias :date :date_start_time
28
- alias :date= :date_start_time=
29
-
30
26
  def indent
31
27
  stars + 1
32
28
  end
@@ -39,6 +35,10 @@ module OrgMode
39
35
  !date.nil?
40
36
  end
41
37
 
38
+ def appointment?
39
+ !!( date_start_time || date_end_time )
40
+ end
41
+
42
42
  def open?
43
43
  not done?
44
44
  end
@@ -50,24 +50,47 @@ module OrgMode
50
50
  end
51
51
 
52
52
  module FileInterface
53
- def root_nodes
54
- nodes.select(&:root_node?)
55
- end
56
-
57
53
  def scheduled_nodes
58
54
  nodes.select(&:scheduled?)
59
55
  end
56
+
57
+ def select_by_title(pattern, props={})
58
+ result = nodes
59
+ props.each do |k,v|
60
+ result = result.select {|n| n.send(k) == v }
61
+ end
62
+ result.select {|n| n.title =~ pattern}
63
+ end
60
64
  end
61
65
 
62
66
  class File
63
- attr_accessor :header, :nodes, :footer
67
+ attr_accessor :header, :root_nodes, :footer
64
68
 
65
69
  include FileInterface
66
70
 
67
- def initialize(header, nodes, footer)
71
+ # For universial children accessor
72
+ # file is just a node
73
+ alias :children :root_nodes
74
+ alias :children= :root_nodes=
75
+
76
+ def initialize(header, root_nodes, footer)
68
77
  @header = header
69
78
  @footer = footer
70
- @nodes = nodes
79
+ @root_nodes = root_nodes
80
+ end
81
+
82
+ def nodes
83
+ serialize_nodes(root_nodes)
84
+ end
85
+
86
+ private
87
+
88
+ # recusively serializes
89
+ # the nodes
90
+ def serialize_nodes(nodes)
91
+ nodes.map do |n|
92
+ [n] + serialize_nodes(n.children)
93
+ end.flatten
71
94
  end
72
95
  end
73
96
 
@@ -83,5 +106,10 @@ module OrgMode
83
106
  def nodes
84
107
  files.map(&:nodes).flatten
85
108
  end
109
+
110
+ def root_nodes
111
+ nodes.select(&:root_node?)
112
+ end
113
+
86
114
  end
87
115
  end
data/org_mode.gemspec CHANGED
@@ -25,4 +25,5 @@ Gem::Specification.new do |s|
25
25
  s.add_runtime_dependency "commander", ["~> 4.0"]
26
26
  s.add_runtime_dependency "facets", ["~> 2.9"]
27
27
  s.add_runtime_dependency "mustache", ["~> 0.99"]
28
+ s.add_runtime_dependency "colorize", ["~> 0.5"]
28
29
  end
@@ -1,23 +1,13 @@
1
1
  require 'org_mode/commands/agenda'
2
- require 'tempfile'
3
- require 'core_ext/string'
4
- require 'support/capture_stdout'
5
- require 'support/write_into_tempfile'
6
2
  require 'timecop'
7
3
 
8
- # Helper to execute agenda and compare the output
9
- def execute_and_compare_stdout_with args, options, expected_output
10
- output = capture_stdout do
11
- @org_mode_commands_agenda.execute(args, options)
12
- end
13
- output.should == expected_output
14
- end
4
+ require 'lib/org_mode/commands/helpers'
15
5
 
16
6
  describe OrgMode::Commands::Agenda do
17
7
  before do
18
8
  Timecop.freeze('2012-01-01 15:00')
19
9
 
20
- @org_mode_commands_agenda = OrgMode::Commands::Agenda.new
10
+ @cmd = @org_mode_commands_agenda = OrgMode::Commands::Agenda.new
21
11
  end
22
12
 
23
13
  context '#execute' do
@@ -26,11 +16,8 @@ describe OrgMode::Commands::Agenda do
26
16
  org_file = write_into_tempfile <<-eos.strip_indent(10)
27
17
  * TODO Scheduled task <1-1-2012 Wed 15:15>
28
18
  eos
29
- execute_and_compare_stdout_with [org_file.path], stub, <<-eos.strip_indent(10)
30
- Agenda ()
31
- 2012-01-01
32
- TODO Scheduled task
33
- eos
19
+ execute_and_output_should_contain @cmd, [org_file.path], stub,
20
+ /TODO/, /2012-01-01/, /15:15/ ,/Scheduled task/
34
21
  end
35
22
  end
36
23
  context 'when loaded with two files' do
@@ -41,14 +28,8 @@ describe OrgMode::Commands::Agenda do
41
28
  org_file2 = write_into_tempfile <<-eos.strip_indent(10)
42
29
  * TODO Scheduled task on the 1th <1-1-2012 Wed 15:15>
43
30
  eos
44
- execute_and_compare_stdout_with [org_file, org_file2].map(&:path), stub,
45
- <<-eos.strip_indent(10)
46
- Agenda ()
47
- 2012-01-01
48
- TODO Scheduled task on the 1th
49
- 2012-01-05
50
- TODO Scheduled task on the 5th
51
- eos
31
+ execute_and_output_should_contain @cmd, [org_file, org_file2].map(&:path), stub,
32
+ /TODO/, /2012-01-01/, /15:15/ ,/Scheduled task/, /on the 1th/, /on the 5th/
52
33
  end
53
34
  end
54
35
  end
@@ -0,0 +1,20 @@
1
+ require 'tempfile'
2
+ require 'core_ext/string'
3
+ require 'support/write_into_tempfile'
4
+ require 'capture_stdout'
5
+
6
+ # Helper to execute agenda and compare the output
7
+ def execute_and_compare_stdout_with cmd, args, options, expected_output
8
+ output = capture_stdout do
9
+ cmd.execute(args, options)
10
+ end
11
+ output.should == expected_output
12
+ end
13
+ def execute_and_output_should_contain cmd, args, options, *expected_output
14
+ output = capture_stdout do
15
+ cmd.execute(args, options)
16
+ end
17
+ expected_output.each do |pattern|
18
+ output.should match( pattern )
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ require 'org_mode/commands/update'
2
+ require 'lib/org_mode/commands/helpers'
3
+
4
+ describe OrgMode::Commands::Update do
5
+ before do
6
+ @cmd = OrgMode::Commands::Update.new
7
+ end
8
+
9
+ context '#execute' do
10
+ context 'without options' do
11
+ it 'reformats a file correctly' do
12
+ org_file = write_into_tempfile <<-eos.strip_indent(10)
13
+ * TODO Scheduled task <1-1-2012 Wed 15:15>
14
+ eos
15
+ execute_and_compare_stdout_with @cmd, [org_file.path], stub(:archive_done => false), <<-eos.strip_indent(10)
16
+ * TODO <2012-01-01 Sun 15:15> Scheduled task
17
+ eos
18
+ end
19
+ end
20
+ context 'option --archive-done' do
21
+ it 'archives the subtree as expected' do
22
+ org_file = write_into_tempfile <<-eos.strip_indent(10)
23
+ * TODO Scheduled task <1-1-2012 Wed 15:15>
24
+ ** DONE Scheduled child task <1-1-2012 Wed 12:15>
25
+ *** TODO Scheduled child of child
26
+ eos
27
+ execute_and_compare_stdout_with @cmd, [org_file.path], stub(:archive_done => true), <<-eos.strip_indent(10)
28
+ * TODO <2012-01-01 Sun 15:15> Scheduled task
29
+ * Archived
30
+ This node contains archived items. Appended
31
+ due to calling the script with update --archive-done
32
+
33
+ ** DONE <2012-01-01 Sun 12:15> Scheduled child task
34
+ *** TODO Scheduled child of child
35
+ eos
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,46 @@
1
+ require 'org_mode/formatters/textual'
2
+ require 'support/blueprints'
3
+
4
+ describe OrgMode::Formatters::Textual do
5
+ let(:org_file) do
6
+ nodes = []
7
+ files = []
8
+ nodes << OrgMode::Node.make(:stars => 1,
9
+ :todo_state => 'DONE',
10
+ :date => Date.parse('2012-06-01'))
11
+
12
+ # make helper for this
13
+ date = DateTime.parse('2012-02-01')
14
+ date_start = DateTime.parse('2012-02-01 15:00')
15
+ date_end = DateTime.parse('2012-02-01 16:00')
16
+ nodes << OrgMode::Node.make(:stars => 2, :date=>Date.parse('2012-02-03'))
17
+ nodes << OrgMode::Node.make(:stars => 3, :date=>date_start,
18
+ :date_end_time=>date_end,
19
+ :date_start_time=>date_start)
20
+ OrgMode::File.make(:nodes => nodes)
21
+ end
22
+
23
+
24
+ context '#format' do
25
+ before do
26
+ formatter = OrgMode::Formatters::Textual.new(org_file)
27
+ @output = formatter.format
28
+ end
29
+
30
+ it "is formatted as expected" do
31
+ @output.should == <<-eos.gsub(/^ {1,8}/,'').chomp
32
+ aheader
33
+
34
+ * DONE <2012-06-01 Fri> org-node
35
+ org-node content
36
+ ** TODO <2012-02-03 Fri> org-node
37
+ org-node content
38
+ *** TODO <2012-02-01 Wed 15:00-16:00> org-node
39
+ org-node content
40
+
41
+ afooter
42
+ eos
43
+ end
44
+ end
45
+
46
+ end
@@ -180,14 +180,20 @@ describe OrgMode::NodeParser do
180
180
  end
181
181
  context "node title with date time" do
182
182
  let(:node) {OrgMode::NodeParser.parse('** Date node title <2012-02-03 Wed 15:15>', nil)}
183
- it "parses the date-time from the title correcty" do
184
- node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
183
+ it "parses the date from the title correcty" do
184
+ node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 00:00'
185
+ end
186
+ it "parses the date_start_time from the title correcty" do
187
+ node.date_start_time.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
188
+ end
189
+ it "parses the date_end_time from the title correcty" do
190
+ node.date_end_time.should be_nil
185
191
  end
186
192
  end
187
193
  context "node title with date-range" do
188
194
  let(:node) {OrgMode::NodeParser.parse('** Date node title <2012-02-03 Wed 15:15-16:15>', nil)}
189
195
  it "parses the date from the title correcty" do
190
- node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
196
+ node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 00:00'
191
197
  end
192
198
  it "parses the start_tiem correctly" do
193
199
  node.date_start_time.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
@@ -0,0 +1,44 @@
1
+ require 'org_mode/processors/archive_done'
2
+ require 'support/blueprints'
3
+ require 'support/include_hash'
4
+ require 'timecop'
5
+
6
+ # When can we archive a tree
7
+ #
8
+ # we can archive a tree when all dones
9
+ # of a tree are done. Or the root-tree is done
10
+
11
+ describe OrgMode::Processors::ArchiveDone do
12
+
13
+ let(:org_file) do
14
+ nodes = []
15
+ nodes << OrgMode::Node.make(:stars => 1,
16
+ :todo_state => 'DONE',
17
+ :date => Date.parse('2012-06-01'))
18
+ nodes << OrgMode::Node.make(:stars => 2, :date=>Date.parse('2012-02-03'))
19
+ nodes << OrgMode::Node.make(:stars => 3, :date=>DateTime.parse('2012-02-01 15:00'))
20
+ OrgMode::File.make(:nodes => nodes)
21
+ end
22
+
23
+ context '#process' do
24
+ let(:processed_org_file) do
25
+ processor = OrgMode::Processors::ArchiveDone.new(org_file)
26
+ processor.process
27
+ end
28
+
29
+ context 'archived_node' do
30
+ let(:archived_nodes) do
31
+ processed_org_file.select_by_title(/^Archived$/, :stars => 1)
32
+ end
33
+
34
+ it 'should have created a node "Archived"' do
35
+ archived_nodes.length.should == 1
36
+ end
37
+
38
+ it 'should have added the DONE tree to the archived ones' do
39
+ #archived_nodes[0].children.length.should == 1
40
+ end
41
+ end
42
+ end
43
+
44
+ end
@@ -36,35 +36,6 @@ describe OrgMode::Reporters::Agenda do
36
36
  nodecount_per_date = reported.map { |e| [e[:date], e[:nodes].length] }
37
37
  nodecount_per_date.should == [["2012-02-01", 2], ["2012-02-03", 1], ["2012-02-05", 1]]
38
38
  end
39
- it "should result in the following subhashes" do
40
- reported.should ==
41
- [{:date=>"2012-02-01",
42
- :nodes=>
43
- [{:title=>"org-node",
44
- :content=>"org-node content",
45
- :todo_state=>"TODO",
46
- :date=>"2012-02-01 00:00",
47
- :stars=>1},
48
- {:title=>"org-node",
49
- :content=>"org-node content",
50
- :todo_state=>"TODO",
51
- :date=>"2012-02-01 15:00",
52
- :stars=>3}]},
53
- {:date=>"2012-02-03",
54
- :nodes=>
55
- [{:title=>"org-node",
56
- :content=>"org-node content",
57
- :todo_state=>"TODO",
58
- :date=>"2012-02-03 00:00",
59
- :stars=>2}]},
60
- {:date=>"2012-02-05",
61
- :nodes=>
62
- [{:title=>"org-node",
63
- :content=>"org-node content",
64
- :todo_state=>"TODO",
65
- :date=>"2012-02-05 00:00",
66
- :stars=>2}]}]
67
- end
68
39
  it "it ignores the DONE task" do
69
40
  dates = reported.map {|e| e[:date] }
70
41
  dates.should_not include("2012-06-01")
@@ -1,4 +1,5 @@
1
1
  require 'org_mode'
2
+ require 'org_mode/node_utils'
2
3
  require 'support/blueprints'
3
4
 
4
5
  describe OrgMode::File do
@@ -1,4 +1,5 @@
1
1
  require 'org_mode'
2
+ require 'org_mode/node_utils'
2
3
 
3
4
  class OrgMode::Node
4
5
  def self.make(attrs={})
@@ -7,6 +8,8 @@ class OrgMode::Node
7
8
  n.stars = attrs[:stars] || rand(4)
8
9
  n.content = attrs[:content] || "org-node content"
9
10
  n.date = attrs[:date]
11
+ n.date_start_time = attrs[:date_start_time]
12
+ n.date_end_time = attrs[:date_end_time]
10
13
  n.todo_state = attrs[:todo_state] || 'TODO'
11
14
  end
12
15
  end
@@ -15,7 +18,8 @@ end
15
18
  class OrgMode::File
16
19
  def self.make(attrs={})
17
20
  nodes = attrs[:nodes] || Array.new(2) { OrgMode::Node.make }
18
- self.new("aheader", nodes , "afooter")
21
+ root_nodes = OrgMode::NodeUtils.convert_sequential_nodelist_into_tree(nodes)
22
+ self.new("aheader", root_nodes , "afooter")
19
23
  end
20
24
  end
21
25
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: org_mode
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Boy Maas
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-02-10 00:00:00 Z
18
+ date: 2012-02-12 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rake
@@ -77,6 +77,21 @@ dependencies:
77
77
  version: "0.99"
78
78
  type: :runtime
79
79
  version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ name: colorize
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ hash: 1
89
+ segments:
90
+ - 0
91
+ - 5
92
+ version: "0.5"
93
+ type: :runtime
94
+ version_requirements: *id005
80
95
  description: Org-mode parser, presenter, and reformatter. Read more about it on the github pages.
81
96
  email:
82
97
  - boy.maas@gmail.com
@@ -96,22 +111,32 @@ files:
96
111
  - features/cmdline_handles_errors_cracefully.feature
97
112
  - features/cmdline_noparams.feature
98
113
  - features/cmdline_todos.feature
114
+ - features/cmdline_update.feature
99
115
  - features/steps.rb
100
116
  - features/support/env.rb
101
117
  - features/support/org_mode_script.rb
118
+ - lib/capture_stdout.rb
102
119
  - lib/core_ext/string.rb
103
120
  - lib/org_mode.rb
104
121
  - lib/org_mode/commands.rb
105
122
  - lib/org_mode/commands/agenda.rb
106
123
  - lib/org_mode/commands/update.rb
124
+ - lib/org_mode/formatters/textual.rb
107
125
  - lib/org_mode/loader.rb
126
+ - lib/org_mode/node_utils.rb
108
127
  - lib/org_mode/parser.rb
128
+ - lib/org_mode/presenters/console.rb
129
+ - lib/org_mode/processors/archive_done.rb
109
130
  - lib/org_mode/reporters/agenda.rb
110
131
  - lib/org_mode/version.rb
111
132
  - org_mode.gemspec
112
133
  - spec/data/org-file-01-simple-node-structure.org
113
134
  - spec/lib/org_mode/commands/agenda_spec.rb
135
+ - spec/lib/org_mode/commands/helpers.rb
136
+ - spec/lib/org_mode/commands/update_spec.rb
137
+ - spec/lib/org_mode/formatters/textual_spec.rb
114
138
  - spec/lib/org_mode/parser_spec.rb
139
+ - spec/lib/org_mode/processors/archive_done_spec.rb
115
140
  - spec/lib/org_mode/reporters/agenda_spec.rb
116
141
  - spec/lib/org_mode_spec.rb
117
142
  - spec/support/blueprints.rb
@@ -156,12 +181,17 @@ test_files:
156
181
  - features/cmdline_handles_errors_cracefully.feature
157
182
  - features/cmdline_noparams.feature
158
183
  - features/cmdline_todos.feature
184
+ - features/cmdline_update.feature
159
185
  - features/steps.rb
160
186
  - features/support/env.rb
161
187
  - features/support/org_mode_script.rb
162
188
  - spec/data/org-file-01-simple-node-structure.org
163
189
  - spec/lib/org_mode/commands/agenda_spec.rb
190
+ - spec/lib/org_mode/commands/helpers.rb
191
+ - spec/lib/org_mode/commands/update_spec.rb
192
+ - spec/lib/org_mode/formatters/textual_spec.rb
164
193
  - spec/lib/org_mode/parser_spec.rb
194
+ - spec/lib/org_mode/processors/archive_done_spec.rb
165
195
  - spec/lib/org_mode/reporters/agenda_spec.rb
166
196
  - spec/lib/org_mode_spec.rb
167
197
  - spec/support/blueprints.rb