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

- old
+ new

@@ -7,12 +7,12 @@ # # 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 require the colon. By default these are +TODO+, - # +FIXME+, +OPTIMIZE+ and +DEPRECATE+. + # 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. #++ @@ -21,11 +21,11 @@ # Default paths (all ruby scripts). DEFAULT_PATHS = ["**/*.rb"] # Default note labels to look for in source code. (NOT CURRENTLY USED!) - DEFAULT_LABELS = ['TODO', 'FIXME', 'OPTIMIZE', 'DEPRECATE'] + DEFAULT_LABELS = ['TODO', 'FIXME', 'OPTIMIZE', 'THINK', 'DEPRECATE'] # Files to search for notes. attr_accessor :files # Labels to document. Defaults are: +TODO+, +FIXME+, +OPTIMIZE+ and +DEPRECATE+. @@ -40,11 +40,12 @@ # 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] || '#' + @marker = options[:marker] #|| '#' + @remark = {} parse end # Array of notes. def notes @@ -79,10 +80,11 @@ 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 += 1 save = match(line, lineno, fname) @@ -92,18 +94,18 @@ #save = {'label'=>label,'file'=>file,'line'=>line_no,'note'=>text} records << save else if text case line - when /^\s*#{remark}+\s*$/, /(?!^\s*#{remark})/, /^\s*#{remark}[+][+]/ + when /^\s*#{mark}+\s*$/, /(?!^\s*#{mark})/, /^\s*#{mark}[+][+]/ text.strip! text = nil else if text[-1,1] == "\n" - text << line.gsub(/^\s*#{remark}\s*/,'') + text << line.gsub(/^\s*#{mark}\s*/,'') else - text << "\n" << line.gsub(/^\s*#{remark}\s*/,'') + text << "\n" << line.gsub(/^\s*#{mark}\s*/,'') end end end end end @@ -124,11 +126,11 @@ # Match special notes. def match_special(line, lineno, file) rec = nil labels.each do |label| - if md = match_special_regex(label).match(line) + 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) end end @@ -136,35 +138,37 @@ end #-- # TODO: ruby-1.9.1-p378 reports: `match': invalid byte sequence in UTF-8 #++ - def match_special_regex(label) + def match_special_regex(label, file) + mark = remark(file) if colon - /#{remark}\s*#{Regexp.escape(label)}[:]\s*(.*?)$/ + /#{mark}\s*#{Regexp.escape(label)}[:]\s*(.*?)$/ else - /#{remark}\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.match(line) + 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) end return rec end # - def match_general_regex + def match_general_regex(file) + mark = remark(file) if colon - /#{remark}\s*([A-Z]+)[:]\s+(.*?)$/ + /#{mark}\s*([A-Z]+)[:]\s+(.*?)$/ else - /#{remark}\s*([A-Z]+)[:]?\s+(.*?)$/ + /#{mark}\s*([A-Z]+)[:]?\s+(.*?)$/ end end # Organize notes into a hash with labels for keys. def by_label @@ -231,11 +235,34 @@ def to_h by_label end # - def remark - @remark ||= Regexp.escape(marker) + def remark(file) + @remark[File.extname(file)] ||= ( + mark = guess_marker(file) + Regexp.escape(mark) + ) + end + + # Guess marker based on file extension. Fallsback to '#' + # if the extension is unknown. + # + # TODO: Continue to add comment types. + 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 # Convert to array of hashes then to YAML. #def to_yaml # require 'yaml'