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