lib/dnote/notes.rb in mvz-dnote-1.8.0 vs lib/dnote/notes.rb in mvz-dnote-1.9.0
- old
+ new
@@ -1,9 +1,10 @@
# frozen_string_literal: true
-require 'pathname'
-require 'dnote/note'
+require "pathname"
+require "dnote/note"
+require "dnote/notes_collection"
module DNote
# = Developer Notes
#
# This class goes through you source files and compiles a list
@@ -16,117 +17,97 @@
#--
# TODO: Add ability to read header notes. They often
# have a outline format, rather then the single line.
#++
class Notes
- include Enumerable
-
# Default paths (all ruby scripts).
- DEFAULT_PATHS = ['**/*.rb'].freeze
+ DEFAULT_PATHS = ["**/*.rb"].freeze
# Default note labels to look for in source code. (NOT CURRENTLY USED!)
DEFAULT_LABELS = %w(TODO FIXME OPTIMIZE THINK DEPRECATE).freeze
# Files to search for notes.
- attr_accessor :files
+ attr_reader :files
# Labels to document. Defaults are: +TODO+, +FIXME+, +OPTIMIZE+ and +DEPRECATE+.
- attr_accessor :labels
+ attr_reader :labels
# Require label colon? Default is +true+.
- attr_accessor :colon
+ attr_reader :colon
# Specific remark marker (+nil+ for auto).
- attr_accessor :marker
+ attr_reader :marker
# Link template.
- attr_accessor :url
+ attr_reader :url
# Number of lines of context to show.
- attr_accessor :context
+ attr_reader :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]
@url = options[:url]
@context = options[:context] || 0
-
@remark = {}
parse
end
- # Array of notes.
- attr_reader :notes
-
- # Notes counts by label.
- def counts
- @counts ||= begin
- h = {}
- by_label.each do |label, notes|
- h[label] = notes.size
- end
- h
- end
+ def notes_collection
+ @notes_collection ||= NotesCollection.new(@notes)
end
- # Iterate through notes.
- def each(&block)
- notes.each(&block)
- end
-
- # No notes?
- def empty?
- notes.empty?
- end
-
# Gather notes.
#--
# TODO: Play golf with Notes#parse.
#++
def parse
records = []
files.each do |fname|
- next unless File.file?(fname)
+ records += parse_file(fname)
+ end
- 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
+ @notes = records.sort
+ end
+
+ def parse_file(fname)
+ return [] unless File.file?(fname)
+
+ records = []
+ 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}/
+ text << "\n" unless text[-1, 1] == "\n"
+ text << line.gsub(/^\s*#{mark}\s*/, "")
+ else
+ text.strip!
+ text = nil
end
+ elsif !/^\s*#{mark}/.match?(line)
+ capt << line if capt && capt.size < context
end
end
-
- @notes = records.sort
+ records
end
# Is this line a note?
def match(line, lineno, file)
if labels.empty?
@@ -146,19 +127,17 @@
end
end
rec
end
- #--
- # TODO: ruby-1.9.1-p378 reports: `match': invalid byte sequence in UTF-8
- #++
def match_special_regex(label, file)
mark = remark(file)
+ label = Regexp.escape(label)
if colon
- /#{mark}\s*#{Regexp.escape(label)}[:]\s+(.*?)$/
+ /#{mark}\s*#{label}:\s+(.*?)$/
else
- /#{mark}\s*#{Regexp.escape(label)}[:]?\s+(.*?)$/
+ /#{mark}\s*#{label}:?\s+(.*?)$/
end
end
# Match notes that are labeled with a colon.
def match_general(line, lineno, file)
@@ -174,106 +153,41 @@
# 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+(.*?)$/
+ /#{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
- @by_label ||= begin
- list = {}
- notes.each do |note|
- list[note.label] ||= []
- list[note.label] << note
- list[note.label].sort
+ def remark(file)
+ @remark[File.extname(file)] ||=
+ begin
+ mark = guess_marker(file)
+ Regexp.escape(mark)
end
- list
- end
end
- # Organize notes into a hash with filename for keys.
- 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
-
- # Organize notes into a hash with labels for keys, followed
- # by a hash with filename for keys.
- 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
-
- # Organize notes into a hash with filenames for keys, followed
- # by a hash with labels for keys.
- 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
-
- # Convert to an array of hashes.
- def to_a
- notes.map(&:to_h)
- end
-
- # Same as #by_label.
- def to_h
- by_label
- end
-
- def remark(file)
- @remark[File.extname(file)] ||= begin
- mark = guess_marker(file)
- Regexp.escape(mark)
- end
- 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 ".js", ".c", "cpp", ".css"
+ "//"
+ when ".bas"
"'"
- when '.sql', '.ada'
- '--'
- when '.asm'
- ';'
+ when ".sql", ".ada"
+ "--"
+ when ".asm"
+ ";"
else
- '#'
+ "#"
end
end
end
end