docfolio 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/docfolio +3 -0
- data/lib/docfolio/docfolio.rb +1 -75
- data/lib/docfolio/learning_diary.rb +113 -64
- data/lib/docfolio/logs.rb +63 -0
- data/lib/docfolio/paragraph.rb +63 -271
- data/lib/docfolio/paragraph_modules/date_times.rb +10 -0
- data/lib/docfolio/paragraph_modules/dates.rb +169 -0
- data/lib/docfolio/paragraph_modules/tags.rb +194 -0
- data/lib/docfolio/paragraph_modules/times.rb +74 -0
- data/lib/docfolio/views/diary_console_view.rb +13 -1
- data/lib/docfolio/views/view.rb +2 -2
- metadata +10 -6
- data/lib/docfolio.rb +0 -2
- data/lib/docfolio/date_format.rb +0 -88
- data/lib/docfolio/tags.rb +0 -216
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b800d02e4519f49588fb902a96dbe6be8cc4225
|
4
|
+
data.tar.gz: d8aca2ddac0c36710c5259fbdf5ffd0265e7d0d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e97db1cbbe80b2a96e1a8cecaa55b715287506b9897a4349c225d37ab29f8aba2c72fc65ea5cfe206240650a2cce53b073d5bbed319909e297dbffaecb07fbc
|
7
|
+
data.tar.gz: 12e28cf7aa59b8ef0a2259e7cd34831bce8e288dd1f32c0c562a4e10a22062d3bb685371f43178e8817efd0fa203eb41c87a5d51391821121bf54dcaa2d301ba
|
data/bin/docfolio
ADDED
data/lib/docfolio/docfolio.rb
CHANGED
@@ -1,75 +1 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative 'views/collater_console_view.rb'
|
3
|
-
|
4
|
-
# collection class for Learning Diarys / logs
|
5
|
-
class Logs
|
6
|
-
include Enumerable
|
7
|
-
|
8
|
-
# iterates through every file in the data directory and parses with
|
9
|
-
# LearningDiary
|
10
|
-
def initialize(loading_logs = true)
|
11
|
-
@logs = []
|
12
|
-
if loading_logs
|
13
|
-
log_files_dir.each do |log_file_name|
|
14
|
-
@logs << LearningDiary.new(log_file_name)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Adds either a file to logs or a directory to logs
|
20
|
-
# @param [String] file_or_directory A string containing the name of a
|
21
|
-
# file or directory
|
22
|
-
def add(file_or_directory)
|
23
|
-
log_directory(file_or_directory) if File.directory?(file_or_directory)
|
24
|
-
log_file(file_or_directory) if File.file?(file_or_directory)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Implements Enumerable by iterating through each learning diary
|
28
|
-
def each(&block)
|
29
|
-
@logs.each { |p| block.call(p) }
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
# Adds a file to logs
|
35
|
-
# @param [String] file A string containing the name of a file
|
36
|
-
def log_file(file)
|
37
|
-
@logs << LearningDiary.new(file)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Adds a directory to logs
|
41
|
-
# @param [String] dir A string containing the name of a directory
|
42
|
-
def log_directory(dir)
|
43
|
-
Dir[dir + '/**/*.txt'].each { |file| log_file(file) }
|
44
|
-
end
|
45
|
-
|
46
|
-
# @return [Array] An array of strings. Each string is a
|
47
|
-
# relative file path for every .txt file under the data directory
|
48
|
-
def log_files_dir
|
49
|
-
Dir['./docfolio/data/**/*.txt']
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# controller class for the diaries/logs collection
|
54
|
-
class Docfolio
|
55
|
-
def initialize
|
56
|
-
@logs = Logs.new
|
57
|
-
@view = CollaterConsoleView.new
|
58
|
-
end
|
59
|
-
|
60
|
-
# Creates a portfolio
|
61
|
-
# @param [String] portfolio_file_or_directory A portfolio file or a
|
62
|
-
# name of a directory containing portfolio files including files
|
63
|
-
# within subdirectories.
|
64
|
-
def self.create(portfolio_file_or_directory)
|
65
|
-
logs = Logs.new(false)
|
66
|
-
logs.add(portfolio_file_or_directory)
|
67
|
-
CollaterConsoleView.new.print_logs(logs)
|
68
|
-
true
|
69
|
-
end
|
70
|
-
|
71
|
-
# print all parsed logs to the console
|
72
|
-
def print_logs
|
73
|
-
@view.print_logs(@logs)
|
74
|
-
end
|
75
|
-
end
|
1
|
+
require_relative 'logs.rb'
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require_relative 'date_format.rb'
|
2
1
|
require_relative 'paragraph.rb'
|
3
2
|
require_relative 'views/diary_console_view.rb'
|
4
3
|
|
@@ -7,39 +6,19 @@ require_relative 'views/diary_console_view.rb'
|
|
7
6
|
class LearningDiary
|
8
7
|
include Enumerable
|
9
8
|
|
10
|
-
#
|
9
|
+
# Paragraphs is an array representing the parsed DSL from one file
|
11
10
|
attr_reader :paragraphs
|
12
11
|
|
12
|
+
# The credit arrays are arrays of elements of type
|
13
|
+
# [start_time, end_time, duration], one for each tag in all the paragraphs
|
14
|
+
# that earns credit
|
15
|
+
attr_reader :standard_credits, :impact_credits
|
16
|
+
|
13
17
|
# @param [String] file name of a text file containing text in docfolio DSL
|
14
18
|
def initialize(file)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@console_view = DiaryConsoleView.new
|
19
|
-
|
20
|
-
# Array of paragraphs representing the parsed DSL from one file
|
21
|
-
@paragraphs = []
|
22
|
-
|
23
|
-
# Array of elements of type [start_time, end_time, duration], one for
|
24
|
-
# each tag in all the paragraphs that earns standard credit
|
25
|
-
# @todo this perhaps would be better as a ||= in the corresponding function
|
26
|
-
@standard_credits_array = []
|
27
|
-
|
28
|
-
# Array of elements of type [start_time, end_time, duration], one for
|
29
|
-
# each tag in all the paragraphs that earns impact credit
|
30
|
-
# @todo this perhaps would be better as a ||= in the corresponding function
|
31
|
-
@impact_credits_array = []
|
32
|
-
|
33
|
-
# read the whole txt file in one go
|
34
|
-
f = File.read(file, encoding: 'UTF-8')
|
35
|
-
|
36
|
-
# iterates through each paragraph
|
37
|
-
f.split(/\n/).each do |p|
|
38
|
-
next if p == '' # ignore if paragraph empty
|
39
|
-
@paragraphs << Paragraph.new(p) #
|
40
|
-
end
|
41
|
-
calc_standard_credits
|
42
|
-
calc_impact_credits
|
19
|
+
initialize_vars
|
20
|
+
parse(file)
|
21
|
+
calculate_credits
|
43
22
|
end
|
44
23
|
|
45
24
|
# Implements Enuemerable module by iterating through each paragraph in the
|
@@ -55,24 +34,12 @@ class LearningDiary
|
|
55
34
|
|
56
35
|
# @return [Integer] The sum of the standard credits in minutes
|
57
36
|
def standard_credits_total
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
# @return [Array] The array of standard credits, each element of
|
62
|
-
# type [start_time, end_time, duration]
|
63
|
-
def standard_credits
|
64
|
-
@standard_credits_array
|
37
|
+
standard_credits.reduce(0) { |a, e| a + e[2] }
|
65
38
|
end
|
66
39
|
|
67
40
|
# @return [Integer] The sum of the impact credits in minutes
|
68
41
|
def impact_credits_total
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
# @return [Array] The array of impact credits, each element of
|
73
|
-
# type [start_time, end_time, duration]
|
74
|
-
def impact_credits
|
75
|
-
@impact_credits_array
|
42
|
+
impact_credits.reduce(0) { |a, e| a + e[2] }
|
76
43
|
end
|
77
44
|
|
78
45
|
# @return [Integer] The sum of the impact and standard credits in minutes
|
@@ -80,36 +47,118 @@ class LearningDiary
|
|
80
47
|
impact_credits_total + standard_credits_total
|
81
48
|
end
|
82
49
|
|
50
|
+
def significant_event?
|
51
|
+
paragraphs.each { |p| return true if p.significant_event? }
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
83
55
|
private
|
84
56
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
57
|
+
def initialize_vars
|
58
|
+
Paragraph.reset
|
59
|
+
@console_view = DiaryConsoleView.new
|
60
|
+
@paragraphs = []
|
61
|
+
@standard_credits = []
|
62
|
+
@impact_credits = []
|
63
|
+
end
|
64
|
+
|
65
|
+
def calculate_credits
|
66
|
+
calc_standard_credits
|
67
|
+
calc_impact_credits
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse(file)
|
71
|
+
# read the whole txt file in one go
|
72
|
+
f = File.read(file, encoding: 'UTF-8')
|
73
|
+
|
74
|
+
# iterates through each paragraph, extracting tagged content and time info
|
75
|
+
f.split(/\n/).each do |p|
|
76
|
+
p.strip!
|
77
|
+
next if p == '' # ignore if paragraph empty
|
78
|
+
previous_paragraph = @paragraphs.last
|
79
|
+
current_paragraph = Paragraph.new(p)
|
80
|
+
@paragraphs << current_paragraph
|
81
|
+
post_process(previous_paragraph, current_paragraph)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# if the prev/current times are of the form:
|
86
|
+
#
|
87
|
+
# 19:00-nil [[:LP, "By entering information
|
88
|
+
# 19:00-19:35
|
89
|
+
#
|
90
|
+
# then make it...
|
91
|
+
#
|
92
|
+
# 19:00-19:35 [[:LP, "By entering information
|
93
|
+
# 19:35-nil
|
94
|
+
def move_end_time_back(previous_paragraph, current_paragraph)
|
95
|
+
if previous_paragraph.end_time.nil? &&
|
96
|
+
( ! current_paragraph.end_time.nil? ) &&
|
97
|
+
( previous_paragraph.start_time == current_paragraph.start_time )
|
98
|
+
previous_paragraph.end_time = current_paragraph.end_time
|
99
|
+
current_paragraph.start_time = current_paragraph.end_time
|
100
|
+
current_paragraph.end_time = nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# if the prev/current times are of the form:
|
105
|
+
#
|
106
|
+
# 19:00-nil [[:LP, "By entering information
|
107
|
+
# 19:35-nil
|
108
|
+
#
|
109
|
+
# then make it...
|
110
|
+
#
|
111
|
+
# 19:00-19:35 [[:LP, "By entering information
|
112
|
+
# 19:35-nil
|
113
|
+
def assume_last_end_time_from_st_time(previous_paragraph, current_paragraph)
|
114
|
+
if ( previous_paragraph.end_time.nil? ) &&
|
115
|
+
( ! current_paragraph.start_time.nil? ) &&
|
116
|
+
( ! previous_paragraph.start_time.nil? ) &&
|
117
|
+
( previous_paragraph.start_time < current_paragraph.start_time )
|
118
|
+
previous_paragraph.end_time = current_paragraph.start_time
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def post_process(previous_paragraph, current_paragraph)
|
123
|
+
return if previous_paragraph.nil?
|
124
|
+
move_end_time_back(previous_paragraph, current_paragraph)
|
125
|
+
assume_last_end_time_from_st_time(previous_paragraph, current_paragraph)
|
126
|
+
end
|
127
|
+
|
128
|
+
# @param [Symbol] is_creditable Name of the function to call on the
|
129
|
+
# paragraphs to assertain if the paragraph times are to be counted
|
130
|
+
# towards a particular type of credit
|
131
|
+
# @param [Array] credits Array of elements of type
|
132
|
+
# [start_time, end_time, duration], one for each tag in all the paragraphs
|
90
133
|
# that earns standard credit
|
91
|
-
|
134
|
+
# @return [Array] Array of elements of type
|
135
|
+
# [start_time, end_time, duration], one for each tag in all the paragraphs
|
136
|
+
# that earns credit of type credits
|
137
|
+
def calc_credits(is_creditable, credits)
|
92
138
|
@paragraphs.each do |p|
|
93
|
-
next unless p.
|
139
|
+
next unless p.public_send(is_creditable)
|
94
140
|
start = p.start_time
|
95
141
|
finish = p.end_time
|
96
|
-
duration = p.
|
97
|
-
|
142
|
+
duration = p.duration
|
143
|
+
credits << [start, finish, duration] unless duration == 0
|
98
144
|
end
|
99
|
-
|
145
|
+
credits.uniq!
|
146
|
+
end
|
147
|
+
|
148
|
+
# @todo Deal with edge case where the start and end times of different
|
149
|
+
# elements overlap to avoid claiming credit for the same moments in
|
150
|
+
# time more than once
|
151
|
+
# @return [Array] Array of elements of type
|
152
|
+
# [start_time, end_time, duration], one for each tag in all the paragraphs
|
153
|
+
# that earns standard credit
|
154
|
+
def calc_standard_credits
|
155
|
+
calc_credits(:creditable?, standard_credits)
|
100
156
|
end
|
101
157
|
|
102
|
-
# @return [Array] Array of elements of type
|
103
|
-
# [start_time, end_time, duration], one for each tag in all the paragraphs
|
158
|
+
# @return [Array] Array of elements of type
|
159
|
+
# [start_time, end_time, duration], one for each tag in all the paragraphs
|
104
160
|
# that earns impact credit
|
105
161
|
def calc_impact_credits
|
106
|
-
|
107
|
-
next unless p.impact_creditable?
|
108
|
-
start = p.start_time
|
109
|
-
finish = p.end_time
|
110
|
-
duration = p.period
|
111
|
-
@impact_credits_array << [start, finish, duration] unless duration == 0
|
112
|
-
end
|
113
|
-
@impact_credits_array.uniq!
|
162
|
+
calc_credits(:impact_creditable?, impact_credits)
|
114
163
|
end
|
115
164
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative 'learning_diary.rb'
|
2
|
+
require_relative 'views/collater_console_view.rb'
|
3
|
+
|
4
|
+
# collection class for Learning Diarys / logs
|
5
|
+
class Logs
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
# iterates through every file in the data directory and parses with
|
9
|
+
# LearningDiary
|
10
|
+
def initialize
|
11
|
+
@logs = []
|
12
|
+
end
|
13
|
+
|
14
|
+
# Adds either a file to logs or a directory to logs
|
15
|
+
# @param [String] file_or_directory A string containing the name of a
|
16
|
+
# file or directory
|
17
|
+
def add(file_or_directory)
|
18
|
+
log_directory(file_or_directory) if File.directory?(file_or_directory)
|
19
|
+
log_file(file_or_directory) if File.file?(file_or_directory)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Implements Enumerable by iterating through each learning diary
|
23
|
+
def each(&block)
|
24
|
+
@logs.each { |p| block.call(p) }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Adds a file to logs
|
30
|
+
# @param [String] file A string containing the name of a file
|
31
|
+
def log_file(file)
|
32
|
+
@logs << LearningDiary.new(file)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Adds a directory to logs
|
36
|
+
# @param [String] dir A string containing the name of a directory
|
37
|
+
def log_directory(dir)
|
38
|
+
Dir[dir + '/**/*.txt'].each { |file| log_file(file) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# controller class for the diaries/logs collection
|
43
|
+
class Docfolio
|
44
|
+
def initialize
|
45
|
+
@logs = Logs.new
|
46
|
+
@view = CollaterConsoleView.new
|
47
|
+
end
|
48
|
+
|
49
|
+
# Creates a portfolio
|
50
|
+
# @param [String] portfolio_file_or_directory A portfolio file or a
|
51
|
+
# name of a directory containing portfolio files including files
|
52
|
+
# within subdirectories.
|
53
|
+
def self.create(portfolio_file_or_directory)
|
54
|
+
logs = Logs.new
|
55
|
+
logs.add(portfolio_file_or_directory)
|
56
|
+
CollaterConsoleView.new.print_logs(logs)
|
57
|
+
end
|
58
|
+
|
59
|
+
# print all parsed logs to the console
|
60
|
+
def print_logs
|
61
|
+
@view.print_logs(@logs)
|
62
|
+
end
|
63
|
+
end
|
data/lib/docfolio/paragraph.rb
CHANGED
@@ -1,312 +1,118 @@
|
|
1
|
-
require_relative 'tags.rb'
|
2
|
-
|
3
|
-
# @param [Array] time_array updated start and end times in hours and minutes
|
4
|
-
# @param [Array] times_and_dates current start and end times and date
|
5
|
-
# @return [Array] returns the new times_and_dates array for use going forwards
|
6
|
-
module MyTime
|
7
|
-
# processes new times and dates with current times and dates
|
8
|
-
class TimeProcesser
|
9
|
-
include Tags
|
10
|
-
|
11
|
-
# Takes class start end times and dates as Time objects and amends the
|
12
|
-
# times, advancing the date if the start time has crossed midnight.
|
13
|
-
# @param [Array] current_times_and_dates An array containing the
|
14
|
-
# Paragraph class instance variables for the start time, end time
|
15
|
-
# and date (day)
|
16
|
-
# @param [Array] new_times An array containing the from hour, from min,
|
17
|
-
# to hour, to min
|
18
|
-
# @return [Array] The updated Paragraph class instance variables for the
|
19
|
-
# start time, end time and date.
|
20
|
-
def process_times(new_times, current_times_and_dates)
|
21
|
-
@start_time, @end_time, @date = current_times_and_dates
|
22
|
-
f_hour, f_min, t_hour, t_min = new_times
|
23
|
-
if (has f_hour) && to_st_tme(f_hour, f_min)
|
24
|
-
t_hour = f_hour
|
25
|
-
t_min = f_min
|
26
|
-
end
|
27
|
-
to_end_time(t_hour, t_min) if has t_hour
|
28
|
-
[@start_time, @end_time, @date]
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
# @param [Number] f_hour From hours
|
34
|
-
# @param [Number] f_min From minutes
|
35
|
-
# @return [Boolean] if has a start time and no end time return true else
|
36
|
-
# set start time and return false (the nil for the last assignment of
|
37
|
-
# start_t)
|
38
|
-
def to_st_tme(f_hour, f_min)
|
39
|
-
# treat the time as an end time if there is a start time and no end time
|
40
|
-
has(@start_time) && (!has @end_time) ? true : start_t(f_hour, f_min)
|
41
|
-
end
|
42
|
-
|
43
|
-
# Set the end time to the current paragraph date at t_hour and t_min.
|
44
|
-
# If the end time is before the start time, assume the end time is for the
|
45
|
-
# next day and add a day.
|
46
|
-
# @param [Number] t_hour To hours
|
47
|
-
# @param [Number] t_min To minutes
|
48
|
-
def to_end_time(t_hour, t_min)
|
49
|
-
# extract_time_object simply adds hours and mins to date
|
50
|
-
@end_time = extract_time_object(t_hour, t_min, @date)
|
51
|
-
# if end_time before start_time, assume it is the following day
|
52
|
-
@end_time += a_day if @end_time < @start_time
|
53
|
-
end
|
54
|
-
|
55
|
-
# Adds hours and mins to date (Time). Then adds a day if the start time is
|
56
|
-
# before the end time. Finally, makes end time nil
|
57
|
-
# @todo why advance the start time by a day if before the end time?
|
58
|
-
# @todo why make end_time nil?
|
59
|
-
def start_t(hour, min)
|
60
|
-
# extract_time_object simply adds hours and mins to date
|
61
|
-
@start_time = extract_time_object(hour, min, @date)
|
62
|
-
|
63
|
-
# advance start time by one day if the start time is before the end_time
|
64
|
-
@start_time += a_day if (has @end_time) && @start_time < @end_time
|
65
|
-
@end_time = nil
|
66
|
-
end
|
67
|
-
|
68
|
-
# Improves readability of boolean condition statements. Is used from Time
|
69
|
-
# objects and integer hour component, but it works for any object
|
70
|
-
# @param [Object] time_date_component Any object
|
71
|
-
# @return [Boolean] true if the parameter is not nil
|
72
|
-
def has(time_date_component)
|
73
|
-
!time_date_component.nil?
|
74
|
-
end
|
75
|
-
|
76
|
-
# returns one day in seconds and adds a day to the @date
|
77
|
-
def a_day
|
78
|
-
@date.nil? ? fail('needs date') : @date += 86_400
|
79
|
-
86_400
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# Takes class start end times and dates as Time objects and amends the
|
84
|
-
# times, advancing the date if the start time has crossed midnight.
|
85
|
-
# @param [Array] times_and_dates An array containing the Paragraph class
|
86
|
-
# instance variables for the start time, end time and date (day)
|
87
|
-
# @param [Array] time_array An array containing the from hour, from min,
|
88
|
-
# to hour, to min
|
89
|
-
def process_times(time_array, times_and_dates)
|
90
|
-
TimeProcesser.new.process_times(time_array, times_and_dates)
|
91
|
-
end
|
92
|
-
end
|
1
|
+
require_relative './paragraph_modules/tags.rb'
|
2
|
+
require_relative './paragraph_modules/date_times.rb'
|
93
3
|
|
94
4
|
# Used by LearningDiary
|
95
5
|
# Initialized with plain text, will parse and hold tagged content
|
96
6
|
# Can keep track of time, section and id information from previous paragraphs
|
97
7
|
# using class instance variables
|
98
8
|
class Paragraph
|
99
|
-
include
|
100
|
-
include
|
101
|
-
|
102
|
-
private
|
9
|
+
include TaggedContent
|
10
|
+
include DateTimes
|
103
11
|
|
104
|
-
|
12
|
+
attr_reader :id
|
105
13
|
|
106
|
-
|
107
|
-
|
108
|
-
attr_reader :id, :tags
|
109
|
-
|
110
|
-
# instance start time and instance end time
|
14
|
+
# instance start time and instance end time.
|
111
15
|
attr_accessor :start_time, :end_time
|
112
16
|
|
113
|
-
#
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
# initialize the section class instance variable. The section is an integer
|
118
|
-
# that is an index to the array of tags called SECTIONS declared in the
|
119
|
-
# module Tags
|
120
|
-
@section = 0 # :TITLE
|
121
|
-
|
122
|
-
@id = 0
|
123
|
-
|
124
|
-
# Declaration of class instance variables
|
125
|
-
class << self
|
126
|
-
# class starttime and class end time, date, section
|
127
|
-
# @todo find out what id is and does!
|
128
|
-
attr_accessor :st, :et, :date, :section, :id
|
129
|
-
end
|
130
|
-
|
131
|
-
# @param [String] p a single paragraph from a text file.
|
132
|
-
def initialize(p)
|
133
|
-
# preparation
|
134
|
-
initialize_vars
|
135
|
-
|
136
|
-
# Extract the date and time from a paragraph if it contains date and time
|
137
|
-
# info. Removes the date and time from the paragraph puts whats left into
|
138
|
-
# rest_of_str. Puts the to hour, to min, from hour and from min into the
|
139
|
-
# time array. Puts the date into Paragraph.date as a Time object.
|
140
|
-
#
|
141
|
-
# Paragraph.date is a class instance variable that holds the date to apply
|
142
|
-
# to this and subsequent paragraphs. It is initialized to nil when the
|
143
|
-
# program starts and reset to nil when reset is called (which it is called
|
144
|
-
# by the LearningDiary when initializing to parse a new file, called by
|
145
|
-
# the Collater when iterating through each text file)
|
146
|
-
#
|
147
|
-
# The extract_date function is from the Tag module
|
148
|
-
rest_of_str, time_array, Paragraph.date = extract_date(p, Paragraph.date)
|
149
|
-
|
150
|
-
# if a date or time has been found (and extracted)
|
151
|
-
if rest_of_str != p
|
152
|
-
# transer class start and end times to those of this paragraph, reset
|
153
|
-
# section to :NOTE
|
154
|
-
note_time
|
155
|
-
|
156
|
-
# Takes the current class instance times and dates and newly extracted
|
157
|
-
# paragraph dates from this paragraph, follows a set of rules to
|
158
|
-
# determine what the class instant times and dates should become
|
159
|
-
assign_class_dates process_times(time_array, class_dates)
|
160
|
-
|
161
|
-
# tranfser class start and end times to those of this paragraph, reset
|
162
|
-
# section to :NOTE
|
163
|
-
note_time
|
164
|
-
end
|
17
|
+
# @param [String] raw_paragraph_string a single paragraph from a text file.
|
18
|
+
def initialize(raw_paragraph_string)
|
19
|
+
@tag_extractor = TagExtractor.new
|
165
20
|
|
166
|
-
|
167
|
-
# @todo should this be in an else statement?
|
168
|
-
return if rest_of_str == ''
|
21
|
+
extract_content(extract_time(raw_paragraph_string))
|
169
22
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
# @param [Array] tag An array of tags
|
175
|
-
def tag?(tag)
|
176
|
-
@tags.each { |t| return true if t[0] == tag }
|
177
|
-
false
|
23
|
+
@start_time = TimeProcesser.st
|
24
|
+
@end_time = TimeProcesser.et
|
25
|
+
@id = Paragraph.id
|
26
|
+
Paragraph.id += 1
|
178
27
|
end
|
179
28
|
|
180
29
|
# resets the class variables so that a new file can be parsed
|
181
30
|
# is called by LearningDiary when preparing to parse a new txt file
|
182
31
|
def self.reset
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
# @todo should this be private?
|
188
|
-
# Initialize the paragraph variables.
|
189
|
-
def initialize_vars
|
190
|
-
@date_specified = @end_time_specified = @start_time_specified = false
|
191
|
-
@start_time = @end_time = nil
|
192
|
-
|
193
|
-
# Array of tagged content. e.g.
|
194
|
-
# @tags
|
195
|
-
# => [:TITLE, 'My Title']
|
196
|
-
# @tags
|
197
|
-
# => [:INTRO, 'My introduction.']
|
198
|
-
# @tags
|
199
|
-
# => [:LP, 'Something I have learnt']
|
200
|
-
@tags = []
|
201
|
-
|
202
|
-
# Give the instance instance an id number that is kept track of by a
|
203
|
-
# class instance id, then increment the class instance id
|
204
|
-
@id = Paragraph.id
|
205
|
-
Paragraph.id += 1
|
32
|
+
TagExtractor.reset
|
33
|
+
TimeProcesser.reset
|
34
|
+
Paragraph.id = 0
|
206
35
|
end
|
207
36
|
|
208
|
-
# Iterates through the
|
209
|
-
# @todo Find out if this is the tags for the paragraph or the whole
|
210
|
-
# document. Common sense says just the paragraph as this is just an
|
211
|
-
# instance instance variable
|
37
|
+
# Iterates through the tags of this paragraph
|
212
38
|
def each(&block)
|
213
|
-
|
39
|
+
tags.each { |t| block.call(t) }
|
214
40
|
end
|
215
41
|
|
216
42
|
# Implements [] for paragraph
|
217
|
-
# @return [Array] an element of the tags array, itself an element
|
43
|
+
# @return [Array] an element of the tags array, itself an element
|
218
44
|
# of type [:tag, 'content']
|
219
45
|
def [](index)
|
220
46
|
tags[index]
|
221
47
|
end
|
222
48
|
|
223
|
-
# true
|
49
|
+
# true if the paragraph contains a tag that can earn credit
|
224
50
|
def creditable?
|
225
|
-
@
|
226
|
-
false
|
51
|
+
@tag_extractor.creditable?
|
227
52
|
end
|
228
53
|
|
229
54
|
# true if the paragraph contains a tag that can earn impact credit
|
230
55
|
def impact_creditable?
|
231
|
-
@
|
232
|
-
|
56
|
+
@tag_extractor.impact_creditable?
|
57
|
+
end
|
58
|
+
|
59
|
+
def tag?(tag)
|
60
|
+
@tag_extractor.tag?(tag)
|
233
61
|
end
|
234
62
|
|
63
|
+
def significant_event?
|
64
|
+
@tag_extractor.significant_event?
|
65
|
+
end
|
66
|
+
|
67
|
+
# public
|
235
68
|
# @return [Integer] the interval in minutes between start and end times
|
236
|
-
def
|
69
|
+
def duration
|
237
70
|
return 0 if @end_time.nil? || @start_time.nil?
|
238
71
|
(@end_time - @start_time).to_i / 60
|
239
72
|
end
|
240
73
|
|
241
|
-
# @return end time if exists or failing that the start time if exists
|
242
|
-
# or failing that nil
|
243
|
-
def latest_time
|
244
|
-
return @end_time unless @end_time.nil?
|
245
|
-
return @start_time unless @start_time.nil?
|
246
|
-
nil
|
247
|
-
end
|
248
|
-
|
249
74
|
private
|
250
75
|
|
251
|
-
#
|
252
|
-
#
|
253
|
-
|
76
|
+
# TimeProcesser.date is a class instance variable that holds the date to
|
77
|
+
# apply to this and subsequent paragraphs. It is initialized to nil when the
|
78
|
+
# program starts and reset to nil when reset is called (which it is called
|
79
|
+
# by the LearningDiary when initializing to parse a new file, called by
|
80
|
+
# the Collater when iterating through each text file)
|
81
|
+
def extract_time(p)
|
82
|
+
# The extract_date function is from the DateExtractor class in the
|
83
|
+
# date module
|
84
|
+
array = DateExtractor.new.extract_date(p, TimeProcesser.date)
|
85
|
+
rest_of_str, time_array, TimeProcesser.date = array
|
254
86
|
|
255
|
-
|
256
|
-
|
87
|
+
# Takes the current class instance times and dates and any newly extracted
|
88
|
+
# paragraph dates from this paragraph, follows a set of rules to
|
89
|
+
# determine what the class instant times and dates should become
|
90
|
+
TimeProcesser.new.process_times(time_array)
|
257
91
|
|
258
|
-
|
259
|
-
# and date
|
260
|
-
def assign_class_dates(array)
|
261
|
-
Paragraph.st, Paragraph.et, Paragraph.date = array
|
92
|
+
rest_of_str
|
262
93
|
end
|
263
94
|
|
264
|
-
|
265
|
-
|
266
|
-
def class_dates
|
267
|
-
[Paragraph.st, Paragraph.et, Paragraph.date]
|
95
|
+
def extract_content(rest_of_str)
|
96
|
+
@tag_extractor.extract_content(rest_of_str)
|
268
97
|
end
|
269
98
|
|
270
|
-
|
271
|
-
|
272
|
-
# @param [String] str Paragraph from which tags are to be extracted
|
273
|
-
# @return [Boolean] True if any tags have been extracted
|
274
|
-
def tags_extracted?(str)
|
275
|
-
(@tags.count) < (@tags += extract_tags(str)).count
|
99
|
+
def content(tag, str = '')
|
100
|
+
@tag_extractor.content(tag, str = '')
|
276
101
|
end
|
277
102
|
|
278
|
-
|
279
|
-
|
280
|
-
# using the current value of the section class instance variable as an
|
281
|
-
# index to reference the correct section tag symbol from the SECTIONS array
|
282
|
-
# @param [String] str the content to tag
|
283
|
-
def tag_section(str)
|
284
|
-
tag_it(SECTIONS[Paragraph.section], str)
|
103
|
+
def tags
|
104
|
+
@tag_extractor.tags
|
285
105
|
end
|
286
106
|
|
287
|
-
|
288
|
-
|
289
|
-
# @param [String] str An optional string that can be passed to the function
|
290
|
-
# to which selected content will be appended.
|
291
|
-
def content(tag, str = '')
|
292
|
-
@tags.each { |t| str << t[CONTENT] + ' ' if t[TAG] == tag }
|
293
|
-
str
|
107
|
+
def all_tags
|
108
|
+
TagExtractor.all_tags
|
294
109
|
end
|
295
110
|
|
296
|
-
#
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
# Add a single tagged content element of type
|
302
|
-
# [:symbol (tag), String (content)] to the @tags instance instance variable.
|
303
|
-
# Move the section class instance variable up one (to current :INTRO) if
|
304
|
-
# it is at position 0 (currently :TITLE)
|
305
|
-
# @param [String] p the content to tag
|
306
|
-
# @param [Symbol] tag the tag to use
|
307
|
-
def tag_it(tag, p)
|
308
|
-
@tags << [tag, p]
|
309
|
-
next_section if Paragraph.section == 0 # :TITLE
|
111
|
+
# Declaration of class instance variables
|
112
|
+
class << self
|
113
|
+
# The number of paragraph instances instantiated since last reset. Used to
|
114
|
+
# seqentially number the instances in a learning diary
|
115
|
+
attr_accessor :id
|
310
116
|
end
|
311
117
|
|
312
118
|
# Acts and a getter and setter for tagged content. Adds a getter and setter
|
@@ -316,21 +122,7 @@ class Paragraph
|
|
316
122
|
# paragraph.intro
|
317
123
|
# Returns all content with a tag of :INTRO
|
318
124
|
def method_missing(n, *args, &block)
|
319
|
-
|
320
|
-
|
321
|
-
else # section setter
|
322
|
-
SECTIONS.include?(n) ? tag_it(n, args[0]) : super(n, *args, &block)
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
|
327
|
-
# @todo this function does two things, split it up
|
328
|
-
# Sets the section to a simple :NOTE and transfers the class times to the
|
329
|
-
# instance times.
|
330
|
-
# new untagged sections should be of :NOTE (2)
|
331
|
-
def note_time
|
332
|
-
Paragraph.section = 2 #:NOTE
|
333
|
-
@start_time = Paragraph.st
|
334
|
-
@end_time = Paragraph.et
|
125
|
+
# tag getter
|
126
|
+
args[0].nil? && all_tags.include?(n) ? content(n) : super(n, *args, &block)
|
335
127
|
end
|
336
128
|
end
|