Class: TodoDay
- Inherits:
-
Object
- Object
- TodoDay
- Defined in:
- lib/rodo/rodolib.rb
Overview
Encapsulate a single date of todo information
Instance Attribute Summary collapse
-
#date ⇒ Object
Returns the value of attribute date.
-
#lines ⇒ Object
Returns the value of attribute lines.
Class Method Summary collapse
-
.merge_structures(target, source) ⇒ Object
Merge alls entries from source into target.
-
.structure_reindex(structure, index = 0) ⇒ Object
Will traverse the given structure and update all indices to be in increasing order.
- .structure_to_a(structure) ⇒ Object
Instance Method Summary collapse
- #close ⇒ Object
- #date_name ⇒ Object
-
#indent_depth(line_index) ⇒ Object
Returns the number of leading spaces of the given line.
-
#initialize(lines) ⇒ TodoDay
constructor
A new instance of TodoDay.
- #line_prototype(line_index) ⇒ Object
- #merge_lines(lines_to_append) ⇒ Object
-
#parent_index(line_index) ⇒ Object
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.
-
#structure ⇒ Object
Turns the linear list of lines of this TodoDay into a nested structure of the form [“text”, children: […], …] where …
- #to_s ⇒ Object
Constructor Details
#initialize(lines) ⇒ TodoDay
Returns a new instance of TodoDay.
252 253 254 255 256 257 258 259 |
# 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 |
Instance Attribute Details
#date ⇒ Object
Returns the value of attribute date.
249 250 251 |
# File 'lib/rodo/rodolib.rb', line 249 def date @date end |
#lines ⇒ Object
Returns the value of attribute lines.
250 251 252 |
# File 'lib/rodo/rodolib.rb', line 250 def lines @lines end |
Class Method Details
.merge_structures(target, source) ⇒ Object
Merge alls entries from source into target
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
# 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 |
.structure_reindex(structure, index = 0) ⇒ Object
Will traverse the given structure and update all indices to be in increasing order
413 414 415 416 417 418 419 |
# 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) ⇒ Object
403 404 405 406 407 408 409 410 |
# 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 |
Instance Method Details
#close ⇒ Object
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# 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 ⇒ Object
261 262 263 264 |
# 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) ⇒ Object
Returns the number of leading spaces of the given line
286 287 288 289 290 |
# 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) ⇒ Object
270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
# 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) ⇒ Object
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# 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) ⇒ Object
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
294 295 296 297 298 299 300 301 302 303 304 305 306 |
# 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 ⇒ Object
Turns the linear list of lines of this TodoDay into a nested structure of the form
- “text”, children: […], …
-
where … is the same hash structure “text”, children: […]
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# 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 ⇒ Object
266 267 268 |
# File 'lib/rodo/rodolib.rb', line 266 def to_s lines.join("\n").rstrip end |