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"]
- DEFAULT_LABELS =
Default note labels to look for in source code. (NOT CURRENTLY USED!)
['TODO', 'FIXME', 'OPTIMIZE', 'THINK', 'DEPRECATE']
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). -
#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 ++.
-
#notes ⇒ Object
Array of notes.
-
#parse ⇒ Object
Gather notes.
- #remark(file) ⇒ Object
-
#to_a ⇒ Object
Convert to an array of hashes.
-
#to_h ⇒ Object
Same as #by_label.
Methods included from Enumerable
Constructor Details
#initialize(files, options = {}) ⇒ Notes
New set of notes for give files
and optional special labels.
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/dnote/notes.rb', line 47 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
.
35 36 37 |
# File 'lib/dnote/notes.rb', line 35 def colon @colon end |
#context ⇒ Object
Number of lines of context to show.
44 45 46 |
# File 'lib/dnote/notes.rb', line 44 def context @context end |
#files ⇒ Object
Files to search for notes.
29 30 31 |
# File 'lib/dnote/notes.rb', line 29 def files @files end |
#labels ⇒ Object
Labels to document. Defaults are: TODO
, FIXME
, OPTIMIZE
and DEPRECATE
.
32 33 34 |
# File 'lib/dnote/notes.rb', line 32 def labels @labels end |
#marker ⇒ Object
Specific remark marker (nil
for auto).
38 39 40 |
# File 'lib/dnote/notes.rb', line 38 def marker @marker end |
#url ⇒ Object
Link template.
41 42 43 |
# File 'lib/dnote/notes.rb', line 41 def url @url end |
Instance Method Details
#by_file ⇒ Object
Organize notes into a hash with filename for keys.
206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/dnote/notes.rb', line 206 def by_file @by_file ||= ( list = {} notes.each do |note| list[note.file] ||= [] list[note.file] << note list[note.file].sort! #!{ |a,b| a.line <=> b.line } end list ) end |
#by_file_label ⇒ Object
Organize notes into a hash with filenames for keys, followed by a hash with labels for keys.
235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/dnote/notes.rb', line 235 def by_file_label @by_file ||= ( 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! #{ |a,b| a.line <=> b.line } end list ) end |
#by_label ⇒ Object
Organize notes into a hash with labels for keys.
193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/dnote/notes.rb', line 193 def by_label @by_label ||= ( list = {} notes.each do |note| list[note.label] ||= [] list[note.label] << note list[note.label].sort #!{ |a,b| a.line <=> b.line } end list ) end |
#by_label_file ⇒ Object
Organize notes into a hash with labels for keys, followed by a hash with filename for keys.
220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/dnote/notes.rb', line 220 def by_label_file @by_label ||= ( 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! #{ |a,b| a.line <=> b.line } end list ) end |
#counts ⇒ Object
Notes counts by label.
66 67 68 69 70 71 72 73 74 |
# File 'lib/dnote/notes.rb', line 66 def counts @counts ||= ( h = {} by_label.each do |label, notes| h[label] = notes.size end h ) end |
#each(&block) ⇒ Object
Iterate through notes.
77 78 79 |
# File 'lib/dnote/notes.rb', line 77 def each(&block) notes.each(&block) end |
#empty? ⇒ Boolean
No notes?
82 83 84 |
# File 'lib/dnote/notes.rb', line 82 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.
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/dnote/notes.rb', line 270 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?
137 138 139 140 141 142 143 |
# File 'lib/dnote/notes.rb', line 137 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.
171 172 173 174 175 176 177 178 179 |
# File 'lib/dnote/notes.rb', line 171 def match_general(line, lineno, file) rec = nil if md = match_general_regex(file).match(line) label, text = md[1], md[2] #rec = {'label'=>label,'file'=>file,'line'=>lineno,'note'=>text} rec = Note.new(self, file, label, lineno, text, remark(file)) end return rec end |
#match_general_regex(file) ⇒ Object
Keep in mind that general non-colon matches have a higher potential of false positives.
183 184 185 186 187 188 189 190 |
# File 'lib/dnote/notes.rb', line 183 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.
146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/dnote/notes.rb', line 146 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 = {'label'=>label,'file'=>file,'line'=>lineno,'note'=>text} 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 ++
161 162 163 164 165 166 167 168 |
# File 'lib/dnote/notes.rb', line 161 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 |
#notes ⇒ Object
Array of notes.
61 62 63 |
# File 'lib/dnote/notes.rb', line 61 def notes @notes end |
#parse ⇒ Object
Gather notes. – TODO: Play golf with Notes#parse. ++
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 129 130 131 132 133 134 |
# File 'lib/dnote/notes.rb', line 90 def parse records = [] files.each do |fname| next unless File.file?(fname) #next unless fname =~ /\.rb$/ # TODO: should this be done? mark = remark(fname) lineno, note, text, capt = 0, nil, nil, nil File.readlines(fname).each do |line| #while line = f.gets lineno += 1 note = match(line, lineno, fname) if note #file = fname text = note.text capt = note.capture #note = {'label'=>label,'file'=>file,'line'=>line_no,'note'=>text} records << note else if 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 else if line !~ /^\s*#{mark}/ capt << line if capt && capt.size < context end end end #end end end @notes = records.sort end |
#remark(file) ⇒ Object
259 260 261 262 263 264 |
# File 'lib/dnote/notes.rb', line 259 def remark(file) @remark[File.extname(file)] ||= ( mark = guess_marker(file) Regexp.escape(mark) ) end |
#to_a ⇒ Object
Convert to an array of hashes.
249 250 251 |
# File 'lib/dnote/notes.rb', line 249 def to_a notes.map{ |n| n.to_h } end |
#to_h ⇒ Object
Same as #by_label.
254 255 256 |
# File 'lib/dnote/notes.rb', line 254 def to_h by_label end |