docfolio 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99d2c5789c65b55841fd11b71cfb29448e1ea722
4
- data.tar.gz: d4221138fa97f72c806a8aaabd04f3881f0e4c76
3
+ metadata.gz: e45dbe3f14a1a7135af5c0172af46430bd17a683
4
+ data.tar.gz: 33c879f96cc800b3b1e7a264cb1903b08536d408
5
5
  SHA512:
6
- metadata.gz: f6afcea04d4231186c8ac92f138637f75fa447073668603d83fbc9f285771d68e5fb83b7872d3466710a742751018063e52d8c4cfe389d69cd9a84fadb3e8bea
7
- data.tar.gz: 27134b0e2c0d9151a33716307325fc8076a8994056776bef3c4abd197ce355e0e4d6e769a1d1d0373e7c61ed37bca1f2eb71062525ca1dddef86bb266c8e9a6b
6
+ metadata.gz: eef722b2f0ed517071307ed25ded7fa97faba77242cde022ad4681dcf90a8e27d628be498c902e8b62ef50a9abcc0e8370cc4c721bf2626e1466488cd9d8d52d
7
+ data.tar.gz: 208e402157fc17576d3578160afce37edeca054db9a6687ad01a1a008cb6b3f931476af32e85e494c5db96c59f15ca6fd359386290c987e1fc645ade1fb04900
@@ -41,6 +41,7 @@ module DateFormat
41
41
  [day, month, year]
42
42
  end
43
43
 
44
+ # A hash of text months and their corresponding month number
44
45
  MONTHS = {
45
46
  'jan' => 1,
46
47
  'feb' => 2,
@@ -68,6 +69,9 @@ module DateFormat
68
69
  'sept' => 9
69
70
  }
70
71
 
72
+ # Takes a text month to its corresponding number, case insensitive
73
+ # @param [String] month Month of year in text
74
+ # @return [Integer] Number of month in calander e.g. Feb is 2
71
75
  def convert_month_to_number(month)
72
76
  return month.to_i if month.to_i > 0 # already a number
73
77
  month = month.downcase
@@ -75,6 +79,9 @@ module DateFormat
75
79
  end
76
80
  end
77
81
 
82
+ # Extracts a date in seconds past UNIX epoc from a string date. The result
83
+ # can be used for other date operations. Converts from dd-mmm-yy and similar
84
+ # formats as commonly found in csv files
78
85
  def format_date(date)
79
86
  DateExtractor.new.format_date(date)
80
87
  end
@@ -1,5 +1,4 @@
1
1
  require_relative 'learning_diary.rb'
2
- # require 'stringio'
3
2
  require_relative 'views/collater_console_view.rb'
4
3
 
5
4
  # collection class for Learning Diarys / logs
@@ -25,6 +24,7 @@ class Logs
25
24
  log_file(file_or_directory) if File.file?(file_or_directory)
26
25
  end
27
26
 
27
+ # Implements Enumerable by iterating through each learning diary
28
28
  def each(&block)
29
29
  @logs.each { |p| block.call(p) }
30
30
  end
@@ -68,6 +68,7 @@ class Docfolio
68
68
  true
69
69
  end
70
70
 
71
+ # print all parsed logs to the console
71
72
  def print_logs
72
73
  @view.print_logs(@logs)
73
74
  end
@@ -7,16 +7,27 @@ require_relative 'views/diary_console_view.rb'
7
7
  class LearningDiary
8
8
  include Enumerable
9
9
 
10
+ # Array of paragraphs representing the parsed DSL from one file
10
11
  attr_reader :paragraphs
11
12
 
12
- # @param [String] file name of a text file containing text in docfile DSL
13
+ # @param [String] file name of a text file containing text in docfolio DSL
13
14
  def initialize(file)
14
15
  # preparation
15
16
  # @todo extract to an initialize_vars function, as in the paragraph class
16
17
  Paragraph.reset
17
18
  @console_view = DiaryConsoleView.new
19
+
20
+ # Array of paragraphs representing the parsed DSL from one file
18
21
  @paragraphs = []
19
- @standard_credits_array = []
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
20
31
  @impact_credits_array = []
21
32
 
22
33
  # read the whole txt file in one go
@@ -31,36 +42,52 @@ class LearningDiary
31
42
  calc_impact_credits
32
43
  end
33
44
 
45
+ # Implements Enuemerable module by iterating through each paragraph in the
46
+ # learning diary
34
47
  def each(&block)
35
48
  @paragraphs.each { |p| block.call(p) }
36
49
  end
37
50
 
51
+ # Implements [] by indexing the @paragraphs instance variable
38
52
  def [](index)
39
53
  @paragraphs[index]
40
54
  end
41
55
 
56
+ # @return [Integer] The sum of the standard credits in minutes
42
57
  def standard_credits_total
43
58
  @standard_credits_array.reduce(0) { |a, e| a + e[2] }
44
59
  end
45
60
 
61
+ # @return [Array] The array of standard credits, each element of
62
+ # type [start_time, end_time, duration]
46
63
  def standard_credits
47
64
  @standard_credits_array
48
65
  end
49
66
 
67
+ # @return [Integer] The sum of the impact credits in minutes
50
68
  def impact_credits_total
51
69
  @impact_credits_array.reduce(0) { |a, e| a + e[2] }
52
70
  end
53
71
 
54
- def credits_total
55
- impact_credits_total + standard_credits_total
56
- end
57
-
72
+ # @return [Array] The array of impact credits, each element of
73
+ # type [start_time, end_time, duration]
58
74
  def impact_credits
59
75
  @impact_credits_array
60
76
  end
61
77
 
78
+ # @return [Integer] The sum of the impact and standard credits in minutes
79
+ def credits_total
80
+ impact_credits_total + standard_credits_total
81
+ end
82
+
62
83
  private
63
84
 
85
+ # @todo Deal with edge case where the start and end times of different
86
+ # elements overlap to avoid claiming credit for the same moments in
87
+ # time more than once
88
+ # @return [Array] Array of elements of type
89
+ # [start_time, end_time, duration], one for each tag in all the paragraphs
90
+ # that earns standard credit
64
91
  def calc_standard_credits
65
92
  @paragraphs.each do |p|
66
93
  next unless p.creditable?
@@ -72,11 +99,12 @@ class LearningDiary
72
99
  @standard_credits_array.uniq!
73
100
  end
74
101
 
102
+ # @return [Array] Array of elements of type
103
+ # [start_time, end_time, duration], one for each tag in all the paragraphs
104
+ # that earns impact credit
75
105
  def calc_impact_credits
76
-
77
106
  @paragraphs.each do |p|
78
107
  next unless p.impact_creditable?
79
- # p p
80
108
  start = p.start_time
81
109
  finish = p.end_time
82
110
  duration = p.period
@@ -29,7 +29,6 @@ module MyTime
29
29
  end
30
30
 
31
31
  private
32
-
33
32
 
34
33
  # @param [Number] f_hour From hours
35
34
  # @param [Number] f_min From minutes
@@ -41,6 +40,11 @@ module MyTime
41
40
  has(@start_time) && (!has @end_time) ? true : start_t(f_hour, f_min)
42
41
  end
43
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
44
48
  def to_end_time(t_hour, t_min)
45
49
  # extract_time_object simply adds hours and mins to date
46
50
  @end_time = extract_time_object(t_hour, t_min, @date)
@@ -108,10 +112,19 @@ class Paragraph
108
112
 
109
113
  # initialize class date, start and class end time class instance variables
110
114
  @cst = @cet = @date = nil
111
- @section = @id = 0 # :TITLE
112
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
113
125
  class << self
114
- # class starttime and class end time
126
+ # class starttime and class end time, date, section
127
+ # @todo find out what id is and does!
115
128
  attr_accessor :st, :et, :date, :section, :id
116
129
  end
117
130
 
@@ -172,19 +185,37 @@ class Paragraph
172
185
  end
173
186
 
174
187
  # @todo should this be private?
188
+ # Initialize the paragraph variables.
175
189
  def initialize_vars
176
190
  @date_specified = @end_time_specified = @start_time_specified = false
177
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']
178
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
179
204
  @id = Paragraph.id
180
205
  Paragraph.id += 1
181
206
  end
182
207
 
183
- # each on paragraph iterates through the tags
208
+ # Iterates through the instance tags
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
184
212
  def each(&block)
185
213
  @tags.each { |t| block.call(t) }
186
214
  end
187
215
 
216
+ # Implements [] for paragraph
217
+ # @return [Array] an element of the tags array, itself an element
218
+ # of type [:tag, 'content']
188
219
  def [](index)
189
220
  tags[index]
190
221
  end
@@ -195,17 +226,20 @@ class Paragraph
195
226
  false
196
227
  end
197
228
 
198
- # true is the paragraph contains a tag that can earn impact credit
229
+ # true if the paragraph contains a tag that can earn impact credit
199
230
  def impact_creditable?
200
231
  @tags.each { |t| return true if t[0] == :I }
201
232
  false
202
233
  end
203
234
 
235
+ # @return [Integer] the interval in minutes between start and end times
204
236
  def period
205
237
  return 0 if @end_time.nil? || @start_time.nil?
206
238
  (@end_time - @start_time).to_i / 60
207
239
  end
208
240
 
241
+ # @return end time if exists or failing that the start time if exists
242
+ # or failing that nil
209
243
  def latest_time
210
244
  return @end_time unless @end_time.nil?
211
245
  return @start_time unless @start_time.nil?
@@ -214,9 +248,15 @@ class Paragraph
214
248
 
215
249
  private
216
250
 
251
+ # Indexes for the elements of a tabbed array. Elements are of
252
+ # type [:tag, 'content']
217
253
  TAG = 0
254
+
255
+ # Content index number
218
256
  CONTENT = 1
219
257
 
258
+ # Setter for the class instance variables for the start time, end time
259
+ # and date
220
260
  def assign_class_dates(array)
221
261
  Paragraph.st, Paragraph.et, Paragraph.date = array
222
262
  end
@@ -227,28 +267,54 @@ class Paragraph
227
267
  [Paragraph.st, Paragraph.et, Paragraph.date]
228
268
  end
229
269
 
270
+ # @todo split/rename the actions of this function
271
+ # Extracts all the tag for the paragraph
272
+ # @param [String] str Paragraph from which tags are to be extracted
273
+ # @return [Boolean] True if any tags have been extracted
230
274
  def tags_extracted?(str)
231
275
  (@tags.count) < (@tags += extract_tags(str)).count
232
276
  end
233
277
 
278
+ # Add a single tagged content element of type
279
+ # [:symbol (tag), String (content)] to the @tags instance instance variable
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
234
283
  def tag_section(str)
235
284
  tag_it(SECTIONS[Paragraph.section], str)
236
285
  end
237
286
 
287
+ # Joins all content in @tags of with a tag of type tag
288
+ # @param [Symbol] tag The tag for which content that should be selected.
289
+ # @param [String] str An optional string that can be passed to the function
290
+ # to which selected content will be appended.
238
291
  def content(tag, str = '')
239
292
  @tags.each { |t| str << t[CONTENT] + ' ' if t[TAG] == tag }
240
293
  str
241
294
  end
242
295
 
296
+ # Safely increments the class instance section invariable
243
297
  def next_section
244
298
  Paragraph.section += 1 unless Paragraph.section == (SECTIONS.count - 1)
245
299
  end
246
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
247
307
  def tag_it(tag, p)
248
308
  @tags << [tag, p]
249
309
  next_section if Paragraph.section == 0 # :TITLE
250
310
  end
251
311
 
312
+ # Acts and a getter and setter for tagged content. Adds a getter and setter
313
+ # methods for each tag with the name of the tag. For example:
314
+ # paragraph.intro('my intro')
315
+ # Would and an :INTRO tag with the text content of 'my intro'
316
+ # paragraph.intro
317
+ # Returns all content with a tag of :INTRO
252
318
  def method_missing(n, *args, &block)
253
319
  if args[0].nil? # tag getter
254
320
  ALL_TAGS.include?(n) ? content(n) : super(n, *args, &block)
data/lib/docfolio/tags.rb CHANGED
@@ -1,13 +1,24 @@
1
1
  require_relative 'date_format.rb'
2
2
  require 'English'
3
3
 
4
- # handles extraction of tagged or other significant content
4
+ # handles extraction of tagged or other significant content.
5
+ # Interface: extract_date, extract_tags
5
6
  module Tags
6
- # interface: extract_date, extract_tags
7
- TAGS = [:LP, :R, :DEN, :NOTE, :I] # recognized in text
8
- CREDITABLE = [:LP, :R, :I] # can earn cpd credit
9
- SECTIONS = [:TITLE, :INTRO, :NOTE] # assumed from position in document
7
+
8
+ # Tags that are part of the DSL and are recognized in text
9
+ TAGS = [:LP, :R, :DEN, :NOTE, :I]
10
+
11
+ # Tags that can earn CPD credit
12
+ CREDITABLE = [:LP, :R, :I]
13
+
14
+ # Tags that are applied to content based on the position in the document
15
+ SECTIONS = [:TITLE, :INTRO, :NOTE]
16
+
17
+ # Tags that are internal and which have no meaning derived from the DSL or
18
+ # the position in the document.
10
19
  SPECIAL = [:DATE] # internal tags with no meaning from content or position
20
+
21
+ # A combined array of all tags
11
22
  ALL_TAGS = SECTIONS + TAGS + SPECIAL
12
23
 
13
24
  # extracts and formats tags and pertaining text from a plain text paragraph
@@ -19,7 +30,9 @@ module Tags
19
30
  # returns a MatchData object. This can be used as an array, where indices
20
31
  # 1 - n are the matched backreferences of the last successful match
21
32
  # @param [String] paragraph_text a paragraph from a DSL text file
22
- # @param [Time] date of this paragraph. May be nil if not known.
33
+ # @param [Time] date Date of this paragraph. May be nil if not known.
34
+ # This date is taken from the Date class instance variable of the
35
+ # paragraph class.
23
36
  # @return [Array<String, Array, Time>] Array of values to be returned
24
37
  # [String return value] 'paragraph_text' the same paragraph that was passed to the function but without the matched date character if there were any.
25
38
  # [Array return value] 'time_array' array of 4 integer representing the hours and minutes of the from and to times
@@ -45,6 +58,12 @@ module Tags
45
58
  [paragraph_text, time_array, date]
46
59
  end
47
60
 
61
+ # Extracts a paragraph string to a tagged array with elements of type
62
+ # [:tag, 'content']. Called after the date/time info has been removed. If
63
+ # called before, will result in date info at the start being tagged as
64
+ # a :NOTE
65
+ # @param [String] paragraph_text Paragraph string after date info removed
66
+ # @return [Array] Tagged array
48
67
  def extract_tags(paragraph_text)
49
68
  tag_regex =~ paragraph_text ? extract_tag(paragraph_text) : []
50
69
  end
@@ -117,11 +136,25 @@ module Tags
117
136
  nil
118
137
  end
119
138
 
139
+ # Paragraphs are broken down into a tagged array, with elements of type
140
+ # [:tag, 'text']. The first element of an array is of type string. If the
141
+ # paragraph begins with text before any tags, then this first element will
142
+ # contain this text, otherwise it will be an empty string. This function
143
+ # tests this string and returns it tagged as :NOTE unless empty in which
144
+ # case it returns an empty array []
145
+ # @param [Array] a An array of tagged content of the paragraph
146
+ # @return [Array] Another tagged array which is either empty, or just
147
+ # contains a single tagged content of the text at the beginning if there
148
+ # was any.
120
149
  def preface_with_note(a)
121
150
  str = a[0].strip
122
151
  str == '' ? [] : [[:NOTE, str]]
123
152
  end
124
153
 
154
+ # Turns an array of strings into a tagged array. Ignores the string variable at position [0]. This first string is turned into a tagged array by the function #preface_with_note and appended in #extract_tag
155
+ # @param [Array] a Array of strings from splitting the paragraph
156
+ # @return [Array] A tagged array with elements of the form
157
+ # [:tag, 'content']
125
158
  def tags_array(a)
126
159
  tags = []
127
160
  tag_count = (a.count - 1) / 2
@@ -133,12 +166,18 @@ module Tags
133
166
  tags
134
167
  end
135
168
 
169
+ # Splits the paragraph into an array of tags of type [:tag, 'content']
170
+ # @param [String] paragraph_text String text of the paragraph with any
171
+ # date and time info at the beginning, removed
172
+ # @return [Array] Tagged array of content with elements of type
173
+ # [:tag, 'content']
136
174
  def extract_tag(paragraph_text)
137
175
  a = paragraph_text.split(tag_regex)
138
176
  preface_with_note(a) + tags_array(a)
139
177
  end
140
178
  end
141
179
 
180
+ # Adds a given number and hours and minutes to a Time object
142
181
  # @param [Time] from time to which hours and minutes are added
143
182
  # @param [Number] hour hours to add to from
144
183
  # @param [Number] min minutes to add to from
@@ -148,10 +187,29 @@ module Tags
148
187
  Time.at(from.to_i + seconds)
149
188
  end
150
189
 
190
+ # Extracts a paragraph string to a tagged array with elements of type
191
+ # [:tag, 'content']. Called after the date/time info has been removed. If
192
+ # called before, will result in date info at the start being tagged as
193
+ # a :NOTE
194
+ # @param [String] paragraph_text Paragraph string after date info removed
195
+ # @return [Array] Tagged array
151
196
  def extract_tags(paragraph_text)
152
197
  TagFriend.new.extract_tags(paragraph_text)
153
198
  end
154
199
 
200
+ # Defined in the Tags module
201
+ # @todo move function to one of the date or time handling classes
202
+ # The $LAST_MATCH_INFO global is equivalent to Rexexp.last_match and
203
+ # returns a MatchData object. This can be used as an array, where indices
204
+ # 1 - n are the matched backreferences of the last successful match
205
+ # @param [String] paragraph_text a paragraph from a DSL text file
206
+ # @param [Time] date Date of this paragraph. May be nil if not known.
207
+ # This date is taken from the Date class instance variable of the
208
+ # paragraph class.
209
+ # @return [Array<String, Array, Time>] Array of values to be returned
210
+ # [String return value] 'paragraph_text' the same paragraph that was passed to the function but without the matched date character if there were any.
211
+ # [Array return value] 'time_array' array of 4 integer representing the hours and minutes of the from and to times
212
+ # [Time return value] 'date' the date in (day month year) of this paragraph taken from the matched date_regex if there was one. Will be nil if there was no match and if the date passed to the function was also nil.
155
213
  def extract_date(paragraph_text, date)
156
214
  TagFriend.new.extract_date(paragraph_text, date)
157
215
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docfolio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Bulmer
@@ -9,7 +9,21 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2015-12-10 00:00:00.000000000 Z
12
- dependencies: []
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.7.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.7.7
13
27
  description: A domain specific language to aid recording of a personal learning portfolio
14
28
  for UK General Practitioners.
15
29
  email: n.bulmer@live.co.uk
@@ -38,7 +52,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
38
52
  requirements:
39
53
  - - ">="
40
54
  - !ruby/object:Gem::Version
41
- version: '0'
55
+ version: 2.1.5
42
56
  required_rubygems_version: !ruby/object:Gem::Requirement
43
57
  requirements:
44
58
  - - ">="