class TodoDay
Encapsulate a single date of todo information
Attributes
date[RW]
lines[RW]
Public Class Methods
merge_structures(target, source)
click to toggle source
Merge alls entries from source into target
# File lib/rodo/rodolib.rb, line 365 def self.merge_structures(target, source) # Attempt 1.3: to_prepend = [] source.each { |new_block| existing_block_index = target.find_index { |existing_block| new_block != nil && existing_block != nil && new_block[:text] != "" && new_block[:text] == existing_block[:text] } if existing_block_index existing_block = target[existing_block_index] # Insert everything in the to_prepend queue at the given position... # ... but merge whitespace now whitespace_check_index = existing_block_index - 1 while whitespace_check_index >=0 && to_prepend.size > 0 && to_prepend[0][:text] == "" && target[whitespace_check_index][:text] = "" to_prepend.shift whitespace_check_index -= 1 end target.insert(existing_block_index, *to_prepend) # Start queue from scratch to_prepend = [] merge_structures(existing_block[:children], new_block[:children]) else to_prepend << new_block.dup end } # Everything that couldn't be matched, goes to the end # TODO Whitespace merging target.concat(to_prepend) TodoDay::structure_reindex(target) return target end
new(lines)
click to toggle source
# File lib/rodo/rodolib.rb, line 252 def initialize(lines) self.lines = lines if lines.size > 0 && lines[0] =~ /^\s*\#\s*(\d\d\d\d-\d\d-\d\d)/ self.date = Date.parse($1) raise "Date couldn't be parsed on line #{lines[0]}" if self.date == nil end end
structure_reindex(structure, index = 0)
click to toggle source
Will traverse the given structure and update all indices to be in increasing order
# File lib/rodo/rodolib.rb, line 413 def self.structure_reindex(structure, index = 0) structure.each { |block| block[:index] = index index = structure_reindex(block[:children], index + 1) } return index end
structure_to_a(structure)
click to toggle source
# File lib/rodo/rodolib.rb, line 403 def self.structure_to_a(structure) result = [] structure.each { |block| result << block[:text] result.concat(structure_to_a(block[:children])) } return result end
Public Instance Methods
close()
click to toggle source
# File lib/rodo/rodolib.rb, line 332 def close unfinished_lines = [] lines.each { |line| if line =~ /^\s*(-\s+)?\[(.)\]/ if $2 == " " unfinished_lines << line.dup line.sub!(/\[\s\]/, "[>]") end # Copy structure: elsif !(line =~ /^\s*[-*]\s+/ || line =~ /^\s*#\s/) unfinished_lines << line.dup end } if unfinished_lines[0] =~ /^\s*\#\s*(\d\d\d\d-\d\d-\d\d)/ unfinished_lines.shift end # When closing on the same day: append hour and minutes newDate = "# #{Time.now.strftime("%Y-%m-%d %a")}" if lines.size > 0 && lines[0].start_with?(newDate) newDate = "# #{Time.now.strftime("%Y-%m-%d %a %H:%M")}" end return TodoDay.new([newDate, *unfinished_lines]) end
date_name()
click to toggle source
# File lib/rodo/rodolib.rb, line 261 def date_name return date.strftime("%Y-%m-%d") if date return "undefined" end
indent_depth(line_index)
click to toggle source
Returns the number of leading spaces of the given line
# File lib/rodo/rodolib.rb, line 286 def indent_depth(line_index) return nil if !lines[line_index] || lines[line_index].strip.length == 0 lines[line_index][/\A\s*/].length end
line_prototype(line_index)
click to toggle source
# File lib/rodo/rodolib.rb, line 270 def line_prototype(line_index) line = lines[line_index] if /^(?<lead>\s+[*-])(?<option>\s\[.\]\s?)?(?<rest>.*?)$/ =~ line if option =~ /^\s\[.\]/ option = " [ ]" end else lead = " -" option = " [ ]" end option = "" if !option return lead + option.rstrip + " " end
merge_lines(lines_to_append)
click to toggle source
# File lib/rodo/rodolib.rb, line 421 def merge_lines(lines_to_append) return if lines_to_append.empty? end_lines = [] end_lines << lines.pop while lines.last.strip.size == 0 my_structure = structure ap_structure = TodoDay.new(lines_to_append).structure TodoDay::merge_structures(my_structure, ap_structure) @lines = TodoDay::structure_to_a(my_structure) lines.concat(end_lines) end
parent_index(line_index)
click to toggle source
Returns the line index of the parent line if any or nil The parent line is the line with a reduced indentation or the section header in case there no reduced indented line
# File lib/rodo/rodolib.rb, line 294 def parent_index(line_index) j = line_index - 1 my_indent = indent_depth(line_index) return nil if !my_indent while j > 0 # Day header does not count as parent other_indent = indent_depth(j) if other_indent && other_indent < my_indent return j end j -= 1 end return nil end
structure()
click to toggle source
Turns the linear list of lines of this TodoDay
into a nested structure of the form
- {text: “text”, children: […]}, …
-
where … is the same hash structure {text: “text”, children: […]}
# File lib/rodo/rodolib.rb, line 311 def structure indents = [nil] * lines.size (lines.size - 1).downto(0).each { |i| indents[i] = indent_depth(i) || (i+1 < indents.size ? indents[i+1] : 0) } stack = [{depth: -1, children: []}] lines.each_with_index { |s, i| indent = indents[i] new_child = {depth: indent, text: s, index: i, children: []} while indent <= stack.last[:depth] stack.pop end stack.last[:children] << new_child stack << new_child } return stack.first[:children] end
to_s()
click to toggle source
# File lib/rodo/rodolib.rb, line 266 def to_s lines.join("\n").rstrip end