lib/dnote/notes.rb in dnote-1.4.0 vs lib/dnote/notes.rb in dnote-1.6.0

- old
+ new

@@ -32,20 +32,30 @@ attr_accessor :labels # Require label colon? Default is +true+. attr_accessor :colon - # Alternate remark marker. Default is '#'. + # Specific remark marker (+nil+ for auto). attr_accessor :marker + # Link template. + attr_accessor :url + + # Number of lines of context to show. + attr_accessor :context + # New set of notes for give +files+ and optional special labels. def initialize(files, options={}) - @files = [files].flatten - @labels = [options[:labels] || DEFAULT_LABELS].flatten.compact - @colon = options[:colon].nil? ? true : options[:colon] - @marker = options[:marker] #|| '#' - @remark = {} + @files = [files].flatten + @labels = [options[:labels] || DEFAULT_LABELS].flatten.compact + @colon = options[:colon].nil? ? true : options[:colon] + @marker = options[:marker] #|| '#' + @url = options[:url] + @context = options[:context] || 0 + + @remark = {} + parse end # Array of notes. def notes @@ -73,51 +83,59 @@ notes.empty? end # Gather notes. #-- - # TODO: Play gold with Notes#parse. + # TODO: Play golf with Notes#parse. #++ def parse records = [] files.each do |fname| next unless File.file?(fname) #next unless fname =~ /\.rb$/ # TODO: should this be done? mark = remark(fname) - File.open(fname) do |f| - lineno, save, text = 0, nil, nil - while line = f.gets + lineno, note, text, capt = 0, nil, nil, nil + File.readlines(fname).each do |line| + #while line = f.gets lineno += 1 - save = match(line, lineno, fname) - if save + note = match(line, lineno, fname) + if note #file = fname - text = save.text - #save = {'label'=>label,'file'=>file,'line'=>line_no,'note'=>text} - records << save + 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}[+][+]/ + when /^\s*#{mark}+\s*$/, /^\s*#{mark}\-\-/, /^\s*#{mark}\+\+/ text.strip! text = nil - else + 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 end @notes = records.sort end - # + # Is this line a note? def match(line, lineno, file) if labels.empty? match_general(line, lineno, file) else match_special(line, lineno, file) @@ -129,11 +147,11 @@ 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(file, label, lineno, text) + rec = Note.new(self, file, label, lineno, text, remark(file)) end end rec end @@ -141,33 +159,34 @@ # TODO: ruby-1.9.1-p378 reports: `match': invalid byte sequence in UTF-8 #++ def match_special_regex(label, file) mark = remark(file) if colon - /#{mark}\s*#{Regexp.escape(label)}[:]\s*(.*?)$/ + /#{mark}\s*#{Regexp.escape(label)}[:]\s+(.*?)$/ else - /#{mark}\s*#{Regexp.escape(label)}[:]?\s*(.*?)$/ + /#{mark}\s*#{Regexp.escape(label)}[:]?\s+(.*?)$/ end end # Match notes that are labeled with a colon. 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(file, label, lineno, text) + rec = Note.new(self, file, label, lineno, text, remark(file)) end return rec end - # + # Keep in mind that general non-colon matches have a higher potential + # of false positives. def match_general_regex(file) mark = remark(file) if colon /#{mark}\s*([A-Z]+)[:]\s+(.*?)$/ - else - /#{mark}\s*([A-Z]+)[:]?\s+(.*?)$/ + else + /#{mark}\s*([A-Z]+)\s+(.*?)$/ end end # Organize notes into a hash with labels for keys. def by_label