Module: Todo::Syntax

Included in:
Task
Defined in:
lib/todo/syntax.rb

Overview

Supports parsing and extracting core syntax fragments from todo.txt lines.

Constant Summary collapse

CONTEXTS_PATTERN =

The regex used to match contexts.

/(?:\s+|^)@[^\s]+/
PROJECTS_PATTERN =

The regex used to match projects.

/(?:\s+|^)\+[^\s]+/
PRIORITY_PATTERN =

The regex used to match priorities.

/(?:^|\s+)\(([A-Za-z])\)\s+/
CREATED_ON_PATTERN =

The regex used to match creation date.

/(?:^|-\d{2}\s|\)\s)(\d{4}-\d{2}-\d{2})\s/
COMPLETED_ON_PATTERN =

The regex used to match completion.

/^x\s+(\d{4}-\d{2}-\d{2})\s+/
DUE_ON_PATTERN =

The regex used to match due date.

/(?:due:)(\d{4}-\d{2}-\d{2})(?:\s+|$)/i
TAGS_PATTERN =

The regex used to match generic tags.

/([a-z]+):([a-z0-9_-]+)/i
COMPLETED_FLAG =
'x'.freeze
SINGLE_SPACE =
' '.freeze

Instance Method Summary collapse

Instance Method Details

#check_completed_flag(line) ⇒ Boolean

Checks whether the given todo item has a completion flag set.

This provides support for ad-hoc handwritten lists where the completed flag is set but there is no completed date.

Parameters:

  • line (String)

    the todo item to be processed

Returns:

  • (Boolean)


87
88
89
# File 'lib/todo/syntax.rb', line 87

def check_completed_flag(line)
  line[0] == COMPLETED_FLAG && line[1] == SINGLE_SPACE
end

#extract_completed_date(line) ⇒ Date

Extracts the completion date for the given todo item. Returns nil if a valid date is not found.

Parameters:

  • line (String)

    the todo item to be processed

Returns:

  • (Date)

    the completed date of the line



68
69
70
71
72
73
74
75
# File 'lib/todo/syntax.rb', line 68

def extract_completed_date(line)
  date = COMPLETED_ON_PATTERN.match(line)
  begin
    Date.parse(date[1]) if date
  rescue ArgumentError
    return nil # The given date is not valid
  end
end

#extract_contexts(line) ⇒ Array<String>

Extract the list of ‘@context` tags out of the task line.

Parameters:

  • line (String)

    Line of text encoding a single task

Returns:

  • (Array<String>)

    List of context tags



104
105
106
# File 'lib/todo/syntax.rb', line 104

def extract_contexts(line)
  line.scan(CONTEXTS_PATTERN).map(&:strip)
end

#extract_created_on(line) ⇒ Date

Extracts the creation date for the given todo item. Returns nil if a valid date is not found.

Parameters:

  • line (String)

    the todo item to be processed

Returns:

  • (Date)

    the created date of the line



54
55
56
57
58
59
60
61
# File 'lib/todo/syntax.rb', line 54

def extract_created_on(line)
  date = line.match CREATED_ON_PATTERN
  begin
    Date.parse(date[1]) if date
  rescue ArgumentError
    return nil # The given date is not valid
  end
end

#extract_item_text(line) ⇒ String

Extracts the readable text content of a task line, stripping out all the discrete pieces of metadata (priority, dates, completion flag, projects, contexts, etc).

Parameters:

  • line (String)

    the todo item to be processed

Returns:

  • (String)

    the text content of the item



31
32
33
34
35
36
37
38
39
# File 'lib/todo/syntax.rb', line 31

def extract_item_text(line)
  line.gsub(COMPLETED_ON_PATTERN, '')
      .gsub(PRIORITY_PATTERN, '')
      .gsub(CREATED_ON_PATTERN, '')
      .gsub(CONTEXTS_PATTERN, '')
      .gsub(PROJECTS_PATTERN, '')
      .gsub(DUE_ON_PATTERN, '')
      .strip
end

#extract_priority(line) ⇒ String

Extracts the priority indicator from the task line.

Parameters:

  • line (String)

    the todo item to be processed

Returns:

  • (String)

    the character (from A-Z) representing the priority



45
46
47
# File 'lib/todo/syntax.rb', line 45

def extract_priority(line)
  line.match(PRIORITY_PATTERN)[1] if line =~ PRIORITY_PATTERN
end

#extract_projects(line) ⇒ Array<String>

Extract the list of ‘+project` tags out of the task line.

Parameters:

  • line (String)

    Line of text encoding a single task

Returns:

  • (Array<String>)

    List of project tags



112
113
114
# File 'lib/todo/syntax.rb', line 112

def extract_projects(line)
  line.scan(PROJECTS_PATTERN).map(&:strip)
end

#extract_tags(line) ⇒ Hash<Symbol,String>

Extracts the collection of tag annotations for the given todo item. Returns an empty hash if no tags are found.

Parameters:

  • line (String)

    the todo item to be processed

Returns:

  • (Hash<Symbol,String>)

    the collection of tag annotations



96
97
98
# File 'lib/todo/syntax.rb', line 96

def extract_tags(line)
  line.scan(TAGS_PATTERN).map { |tag, val| [tag.downcase.to_sym, val] }.to_h
end