Class: DNote::Notes
Overview
Developer Notes
This class goes through you source files and compiles a list of any labeled comments. Labels are all-cap single word prefixes to a comment ending in a colon.
Special labels do not require the colon. By default these are TODO
, FIXME
, OPTIMIZE
, THINK
and DEPRECATE
.
–
TODO: Add ability to read header notes. They often
have a outline format, rather then the single line.
++
Constant Summary collapse
- DEFAULT_PATHS =
Default paths (all ruby scripts).
['**/*.rb'].freeze
- DEFAULT_LABELS =
Default note labels to look for in source code. (NOT CURRENTLY USED!)
%w(TODO FIXME OPTIMIZE THINK DEPRECATE).freeze
Instance Attribute Summary collapse
-
#colon ⇒ Object
Require label colon? Default is
true
. -
#context ⇒ Object
Number of lines of context to show.
-
#files ⇒ Object
Files to search for notes.
-
#labels ⇒ Object
Labels to document.
-
#marker ⇒ Object
Specific remark marker (
nil
for auto). -
#notes ⇒ Object
readonly
Array of notes.
-
#url ⇒ Object
Link template.
Instance Method Summary collapse
-
#by_file ⇒ Object
Organize notes into a hash with filename for keys.
-
#by_file_label ⇒ Object
Organize notes into a hash with filenames for keys, followed by a hash with labels for keys.
-
#by_label ⇒ Object
Organize notes into a hash with labels for keys.
-
#by_label_file ⇒ Object
Organize notes into a hash with labels for keys, followed by a hash with filename for keys.
-
#counts ⇒ Object
Notes counts by label.
-
#each(&block) ⇒ Object
Iterate through notes.
-
#empty? ⇒ Boolean
No notes?.
-
#guess_marker(file) ⇒ Object
Guess marker based on file extension.
-
#initialize(files, options = {}) ⇒ Notes
constructor
New set of notes for give
files
and optional special labels. -
#match(line, lineno, file) ⇒ Object
Is this line a note?.
-
#match_general(line, lineno, file) ⇒ Object
Match notes that are labeled with a colon.
-
#match_general_regex(file) ⇒ Object
Keep in mind that general non-colon matches have a higher potential of false positives.
-
#match_special(line, lineno, file) ⇒ Object
Match special notes.
-
#match_special_regex(label, file) ⇒ Object
– TODO: ruby-1.9.1-p378 reports: ‘match’: invalid byte sequence in UTF-8 ++.
-
#parse ⇒ Object
Gather notes.
- #remark(file) ⇒ Object
-
#to_a ⇒ Object
Convert to an array of hashes.
-
#to_h ⇒ Object
Same as #by_label.
Constructor Details
#initialize(files, options = {}) ⇒ Notes
New set of notes for give files
and optional special labels.
48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/dnote/notes.rb', line 48 def initialize(files, = {}) @files = [files].flatten @labels = [[:labels] || DEFAULT_LABELS].flatten.compact @colon = [:colon].nil? ? true : [:colon] @marker = [:marker] @url = [:url] @context = [:context] || 0 @remark = {} parse end |
Instance Attribute Details
#colon ⇒ Object
Require label colon? Default is true
.
36 37 38 |
# File 'lib/dnote/notes.rb', line 36 def colon @colon end |
#context ⇒ Object
Number of lines of context to show.
45 46 47 |
# File 'lib/dnote/notes.rb', line 45 def context @context end |
#files ⇒ Object
Files to search for notes.
30 31 32 |
# File 'lib/dnote/notes.rb', line 30 def files @files end |
#labels ⇒ Object
Labels to document. Defaults are: TODO
, FIXME
, OPTIMIZE
and DEPRECATE
.
33 34 35 |
# File 'lib/dnote/notes.rb', line 33 def labels @labels end |
#marker ⇒ Object
Specific remark marker (nil
for auto).
39 40 41 |
# File 'lib/dnote/notes.rb', line 39 def marker @marker end |
#notes ⇒ Object (readonly)
Array of notes.
62 63 64 |
# File 'lib/dnote/notes.rb', line 62 def notes @notes end |
#url ⇒ Object
Link template.
42 43 44 |
# File 'lib/dnote/notes.rb', line 42 def url @url end |
Instance Method Details
#by_file ⇒ Object
Organize notes into a hash with filename for keys.
199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/dnote/notes.rb', line 199 def by_file @by_file ||= begin list = {} notes.each do |note| list[note.file] ||= [] list[note.file] << note list[note.file].sort! end list end end |
#by_file_label ⇒ Object
Organize notes into a hash with filenames for keys, followed by a hash with labels for keys.
228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/dnote/notes.rb', line 228 def by_file_label @by_file_label ||= begin list = {} notes.each do |note| list[note.file] ||= {} list[note.file][note.label] ||= [] list[note.file][note.label] << note list[note.file][note.label].sort! end list end end |
#by_label ⇒ Object
Organize notes into a hash with labels for keys.
186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/dnote/notes.rb', line 186 def by_label @by_label ||= begin list = {} notes.each do |note| list[note.label] ||= [] list[note.label] << note list[note.label].sort end list end end |
#by_label_file ⇒ Object
Organize notes into a hash with labels for keys, followed by a hash with filename for keys.
213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/dnote/notes.rb', line 213 def by_label_file @by_label_file ||= begin list = {} notes.each do |note| list[note.label] ||= {} list[note.label][note.file] ||= [] list[note.label][note.file] << note list[note.label][note.file].sort! end list end end |
#counts ⇒ Object
Notes counts by label.
65 66 67 68 69 70 71 72 73 |
# File 'lib/dnote/notes.rb', line 65 def counts @counts ||= begin h = {} by_label.each do |label, notes| h[label] = notes.size end h end end |
#each(&block) ⇒ Object
Iterate through notes.
76 77 78 |
# File 'lib/dnote/notes.rb', line 76 def each(&block) notes.each(&block) end |
#empty? ⇒ Boolean
No notes?
81 82 83 |
# File 'lib/dnote/notes.rb', line 81 def empty? notes.empty? end |
#guess_marker(file) ⇒ Object
Guess marker based on file extension. Fallsback to ‘#’ if the extension is unknown.
TODO: Continue to add comment types.
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/dnote/notes.rb', line 262 def guess_marker(file) return @marker if @marker # forced marker case File.extname(file) when '.js', '.c', 'cpp', '.css' '//' when '.bas' "'" when '.sql', '.ada' '--' when '.asm' ';' else '#' end end |
#match(line, lineno, file) ⇒ Object
Is this line a note?
131 132 133 134 135 136 137 |
# File 'lib/dnote/notes.rb', line 131 def match(line, lineno, file) if labels.empty? match_general(line, lineno, file) else match_special(line, lineno, file) end end |
#match_general(line, lineno, file) ⇒ Object
Match notes that are labeled with a colon.
164 165 166 167 168 169 170 171 172 |
# File 'lib/dnote/notes.rb', line 164 def match_general(line, lineno, file) rec = nil if (md = match_general_regex(file).match(line)) label = md[1] text = md[2] rec = Note.new(self, file, label, lineno, text, remark(file)) end rec end |
#match_general_regex(file) ⇒ Object
Keep in mind that general non-colon matches have a higher potential of false positives.
176 177 178 179 180 181 182 183 |
# File 'lib/dnote/notes.rb', line 176 def match_general_regex(file) mark = remark(file) if colon /#{mark}\s*([A-Z]+)[:]\s+(.*?)$/ else /#{mark}\s*([A-Z]+)\s+(.*?)$/ end end |
#match_special(line, lineno, file) ⇒ Object
Match special notes.
140 141 142 143 144 145 146 147 148 149 |
# File 'lib/dnote/notes.rb', line 140 def match_special(line, lineno, file) rec = nil labels.each do |label| if (md = match_special_regex(label, file).match(line)) text = md[1] rec = Note.new(self, file, label, lineno, text, remark(file)) end end rec end |
#match_special_regex(label, file) ⇒ Object
– TODO: ruby-1.9.1-p378 reports: ‘match’: invalid byte sequence in UTF-8 ++
154 155 156 157 158 159 160 161 |
# File 'lib/dnote/notes.rb', line 154 def match_special_regex(label, file) mark = remark(file) if colon /#{mark}\s*#{Regexp.escape(label)}[:]\s+(.*?)$/ else /#{mark}\s*#{Regexp.escape(label)}[:]?\s+(.*?)$/ end end |
#parse ⇒ Object
Gather notes. – TODO: Play golf with Notes#parse. ++
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/dnote/notes.rb', line 89 def parse records = [] files.each do |fname| next unless File.file?(fname) mark = remark(fname) lineno = 0 note = nil text = nil capt = nil File.readlines(fname).each do |line| lineno += 1 note = match(line, lineno, fname) if note text = note.text capt = note.capture records << note elsif text case line when /^\s*#{mark}+\s*$/, /^\s*#{mark}\-\-/, /^\s*#{mark}\+\+/ text.strip! text = nil when /^\s*#{mark}/ if text[-1, 1] == "\n" text << line.gsub(/^\s*#{mark}\s*/, '') else text << "\n" << line.gsub(/^\s*#{mark}\s*/, '') end else text.strip! text = nil end elsif line !~ /^\s*#{mark}/ capt << line if capt && capt.size < context end end end @notes = records.sort end |
#remark(file) ⇒ Object
251 252 253 254 255 256 |
# File 'lib/dnote/notes.rb', line 251 def remark(file) @remark[File.extname(file)] ||= begin mark = guess_marker(file) Regexp.escape(mark) end end |
#to_a ⇒ Object
Convert to an array of hashes.
242 243 244 |
# File 'lib/dnote/notes.rb', line 242 def to_a notes.map(&:to_h) end |
#to_h ⇒ Object
Same as #by_label.
247 248 249 |
# File 'lib/dnote/notes.rb', line 247 def to_h by_label end |