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'