Lazydoc
Lazydoc lazily pulls documentation out of source files and makes it available in code through lazy attributes. Lazydoc is used by the Tap framework.
Description
Lazydoc allows you to define lazy attributes that act as markers for documentation in a source file. When you call the lazy attribute, Lazydoc pulls out the documentation:
# Sample::key <value>
# This is the comment content. A content
# string can span multiple lines...
class Sample
extend Lazydoc::Attributes
lazy_attr :key
end
comment = Sample::key
comment.value # => "<value>"
comment.comment # => "This is the comment content. A content string can span multiple lines..."
Comments support wrapping, allowing for easy presentation:
thirtydots = "\n#{'.' * 30}\n"
"#{thirtydots}#{comment.wrap(30)}#{thirtydots}"
# => %q{
# ..............................
# This is the comment content.
# A content string can span
# multiple lines...
# ..............................
# }
In addition, Lazydoc provides helpers to register individual lines of code, particularly method definitions:
class Helpers
extend Lazydoc::Attributes
lazy_register(:method_one)
# method_one is registered whenever it
# gets defined
def method_one(a, b='str', &c)
end
# register_caller will register the line
# that *calls* method_two
def method_two
Lazydoc.register_caller
end
end
# *THIS* is the line that gets
# registered by method_two
Helpers.const_attrs[:method_two] = Helpers.new.method_two
doc = Helpers.lazydoc
doc.resolve
one = Helpers.const_attrs[:method_one]
one.method_name # => "method_one"
one.arguments # => ["a", "b='str'", "&c"]
one.to_s # => "method_one is registered whenever it gets defined"
two = Helpers.const_attrs[:method_two]
two.subject # => "Helpers.const_attrs[:method_two] = Helpers.new.method_two"
two.to_s # => "*THIS* is the line that gets registered by method_two"
Lazy accessors may be defined to map the registered lines as well:
class Helpers
lazy_attr(:one, :method_one)
lazy_attr(:two, :method_two)
end
Helpers.one.method_name # => "method_one"
Helpers.two.subject # => "Helpers.const_attrs[:method_two] = Helpers.new.method_two"
Check out these links for development, and bug tracking.
Usage
Lazydoc can find two types of documentation, constant attributes and code comments. The distinction is primarily how they are found and parsed; both are represented by Comment objects.
Constant Attributes
Constant attributes are like constants in Ruby, but with an extra ‘key’ that must consist of only lowercase letters and/or underscores. For example, these are constant attributes:
# Const::Name::key
# Const::Name::key_with_underscores
# ::key
While these are not:
# Const::Name::Key
# Const::Name::key2
# Const::Name::k@y
Lazydoc parses a Lazydoc::Comment for each constant attribute by using the remainder of the line as a value (ie subject) and parsing down for content. Parsing continues until a non-comment line, an end key, or a new attribute is reached; the comment is then stored by constant name and key.
str = %Q{
# Const::Name::key value for key
# comment for key
# parsed until a
# non-comment line
# Const::Name::another value for another
# comment for another
# parsed to an end key
# Const::Name::another-
#
# ignored comment
}
doc = Lazydoc::Document.new
doc.resolve(str)
doc.summarize {|c| [c.value, c.comment] }
# => {
# 'Const::Name' => {
# 'key' => ['value for key', 'comment for key parsed until a non-comment line'],
# 'another' => ['value for another', 'comment for another parsed to an end key']}
# }
Constant attributes are only parsed from commented lines. To turn off attribute parsing for a section of documentation, use start/stop keys:
str = %Q{
Const::Name::not_parsed
# :::-
# Const::Name::not_parsed
# :::+
# Const::Name::parsed value
}
doc = Lazydoc::Document.new
doc.resolve(str)
doc.summarize {|comment| comment.value } # => {'Const::Name' => {'parsed' => 'value'}}
To hide attributes from RDoc, make use of the RDoc :startdoc:
document modifier like this (note that spaces are added to prevent RDoc from hiding the example):
# :start doc::Const::Name::one hidden in RDoc
# * This line is visible in RDoc.
# :start doc::Const::Name::one-
#
#--
# Const::Name::two
# You can hide attribute comments like this.
# Const::Name::two-
#++
#
# * This line is also visible in RDoc.
As a side note, ‘Const::Name::key’ is not a reference to the ‘key’ constant (that would be invalid). In very idiomatic ruby ‘Const::Name::key’ is equivalent to the method call ‘Const::Name.key’.
Code Comments
Code comments are lines registered for parsing if and when a Lazydoc gets resolved. Unlike constant attributes, the registered line is the comment subject (ie value) and contents are parsed up from it (basically mimicking the behavior of RDoc).
str = %Q{
# comment lines for
# the method
def method
end
# as in RDoc, the comment can be
# separated from the method
def another_method
end
}
doc = Lazydoc::Document.new
doc.register(3)
doc.register(9)
doc.resolve(str)
doc.comments.collect {|c| [c.subject, c.comment] }
# => [
# ['def method', 'comment lines for the method'],
# ['def another_method', 'as in RDoc, the comment can be separated from the method']]
Comments may be registered to specific line numbers, or with a Proc or Regexp that will determine the line number during resolution. In the case of a Regexp, the first matching line is used; Procs receive an array of lines and should return the line number that should be used. See Comment#parse_up for more details.
Installation
Lazydoc is available as a gem on RubyForge. Use:
% gem install lazydoc
Info
Copyright © 2008, Regents of the University of Colorado.
- Developer
- Support
-
CU Denver School of Medicine Deans Academic Enrichment Fund
- Licence