lib/tap/support/lazydoc.rb in bahuvrihi-tap-0.10.0 vs lib/tap/support/lazydoc.rb in bahuvrihi-tap-0.10.1
- old
+ new
@@ -8,12 +8,11 @@
#
# === Constant Attributes
#
# Constant attributes are designated the same as constants in Ruby, but with
# an extra 'key' constant that must consist of only lowercase letters and/or
- # underscores. This format assures that attributes are sytactically invalid
- # outside of comments.
+ # underscores. Attributes are only parsed from comment lines.
#
# When Lazydoc finds an attribute it parses a Comment value where the subject
# is the remainder of the line, and comment lines are parsed down until a
# non-comment line, an end key, or a new attribute is reached.
#
@@ -47,10 +46,12 @@
# str = %Q{
# # :::-
# # Const::Name::not_parsed
# # :::+
#
+ # Const::Name::not_parsed
+ #
# # Const::Name::parsed subject
# }
#
# lazydoc = Lazydoc.new
# lazydoc.resolve(str)
@@ -125,15 +126,15 @@
#
# $1:: const_name
# $3:: key
# $4:: end flag
#
- ATTRIBUTE_REGEXP = /(::|([A-Z][A-z]*::)+)([a-z_]+)(-?)/
+ ATTRIBUTE_REGEXP = /([A-Z][A-z]*(::[A-Z][A-z]*)*)?::([a-z_]+)(-?)/
+
+ # A regexp matching constants from the ATTRIBUTE_REGEXP leader
+ CONSTANT_REGEXP = /#.*?([A-Z][A-z]*(::[A-Z][A-z]*)*)?$/
- # A regexp matching constants.
- CONSTANT_REGEXP = /(::|([A-Z][A-z]*::)+)/
-
class << self
# A hash of (source_file, lazydoc) pairs tracking the
# Lazydoc instance for the given source file.
def registry
@@ -157,11 +158,11 @@
def register(source_file, line_number)
Lazydoc[source_file].register(line_number)
end
# Resolves all lazydocs which include the specified code comments.
- def resolve(code_comments)
+ def resolve_comments(code_comments)
registry.each do |doc|
next if (code_comments & doc.code_comments).empty?
doc.resolve
end
end
@@ -183,18 +184,20 @@
# each (const_name, key, value) triplet to the mandatory block and
# skips regions delimited by the stop and start keys <tt>:-</tt>
# and <tt>:+</tt>.
#
# str = %Q{
- # Const::Name::key value
- # ::alt alt_value
+ # # Const::Name::key value
+ # # ::alt alt_value
+ # #
+ # # Ignored::Attribute::not_matched value
+ # # :::-
+ # # Also::Ignored::key value
+ # # :::+
+ # # Another::key another value
#
- # Ignored::Attribute::not_matched value
- # :::-
- # Also::Ignored::key value
- # :::+
- # Another::key another value
+ # Ignored::key value
# }
#
# results = []
# Lazydoc.scan(str, 'key|alt') do |const_name, key, value|
# results << [const_name, key, value]
@@ -211,21 +214,21 @@
scanner = case str
when StringScanner then str
when String then StringScanner.new(str)
else raise TypeError, "can't convert #{str.class} into StringScanner or String"
end
-
- regexp = /(#{key})([ \r\t-].*$|$)/
+
+ regexp = /^(.*?)::(:-|#{key})/
while !scanner.eos?
- break if scanner.skip_until(CONSTANT_REGEXP) == nil
- const_name = scanner[1]
-
- case
- when scanner.scan(regexp)
- yield(const_name.chomp('::'), scanner[1], scanner[2].strip)
- when scanner.scan(/:-/)
- scanner.skip_until(/:\+/)
+ break if scanner.skip_until(regexp) == nil
+
+ if scanner[2] == ":-"
+ scanner.skip_until(/:::\+/)
+ else
+ next unless scanner[1] =~ CONSTANT_REGEXP
+ key = scanner[2]
+ yield($1.to_s, key, scanner.matched.strip) if scanner.scan(/[ \r\t].*$|$/)
end
end
scanner
end
@@ -265,13 +268,13 @@
else raise TypeError, "can't convert #{str.class} into StringScanner or String"
end
scan(scanner, '[a-z_]+') do |const_name, key, value|
comment = Comment.parse(scanner, false) do |line|
- if line =~ /::/ && line =~ ATTRIBUTE_REGEXP
+ if line =~ ATTRIBUTE_REGEXP
# rewind to capture the next attribute unless an end is specified.
- scanner.unscan unless !$4.empty? && $1.chomp("::") == const_name && $3 == key
+ scanner.unscan unless $4 == '-' && $3 == key && $1.to_s == const_name
true
else false
end
end
comment.subject = value
@@ -292,14 +295,17 @@
# A hash of (const_name, attributes) pairs tracking the constant
# attributes resolved or to-be-resolved for self. Attributes
# are hashes of (key, comment) pairs.
attr_reader :const_attrs
-
+
+ attr_reader :patterns
+
def initialize(source_file=nil)
self.source_file = source_file
@code_comments = []
+ @patterns = {}
@const_attrs = {}
@resolved = false
end
# Sets the source file for self. Expands the source file path if necessary.
@@ -362,18 +368,37 @@
end
comment
end
+ def register_pattern(key, regexp, &block) # :yields: comment, match
+ patterns[key] = [regexp, block]
+ end
+
+ def register_method_pattern(key, method, range=0..-1)
+ register_pattern(key, /^\s*def\s+#{method}(\((.*?)\))?/) do |comment, match|
+ args = match[2].to_s.split(',').collect do |arg|
+ arg = arg.strip.upcase
+ case arg
+ when /^&/ then nil
+ when /^\*/ then arg[1..-1] + "..."
+ else arg
+ end
+ end
+
+ comment.subject = args[range].join(', ')
+ end
+ end
+
# Returns true if the code_comments for source_file are frozen.
def resolved?
@resolved
end
attr_writer :resolved
- def resolve(str=nil, comment_regexp=nil) # :yields: comment, match
+ def resolve(str=nil)
return(false) if resolved?
if str == nil
raise ArgumentError, "no source file specified" unless source_file && File.exists?(source_file)
str = File.read(source_file)
@@ -382,14 +407,21 @@
Lazydoc.parse(str) do |const_name, key, comment|
attributes(const_name)[key] = comment
end
lines = str.split(/\r?\n/)
- lines.each_with_index do |line, line_number|
- next unless line =~ comment_regexp
- comment = register(line_number)
- yield(comment, $~) if block_given?
- end unless comment_regexp == nil
+
+ patterns.each_pair do |key, (regexp, block)|
+ next if default_attributes.has_key?(key)
+
+ lines.each_with_index do |line, line_number|
+ next unless line =~ regexp
+
+ comment = register(line_number)
+ default_attributes[key] = comment
+ break if block.call(comment, $~)
+ end
+ end unless patterns.empty?
code_comments.collect! do |comment|
line_number = comment.line_number
comment.subject = lines[line_number] if comment.subject == nil
\ No newline at end of file