Module: Lazydoc

Defined in:
lib/lazydoc.rb,
lib/lazydoc/utils.rb,
lib/lazydoc/method.rb,
lib/lazydoc/comment.rb,
lib/lazydoc/subject.rb,
lib/lazydoc/trailer.rb,
lib/lazydoc/version.rb,
lib/lazydoc/document.rb,
lib/lazydoc/arguments.rb,
lib/lazydoc/attributes.rb

Defined Under Namespace

Modules: Attributes, Utils Classes: Arguments, Comment, Document, Method, Subject, Trailer

Constant Summary collapse

MAJOR =
1
MINOR =
0
TINY =
0
VERSION =
"#{MAJOR}.#{MINOR}.#{TINY}"
ATTRIBUTE_REGEXP =

A regexp matching an attribute start or end. After a match:

$1:: const_name
$2:: key
$3:: end flag
/([A-Z][A-z]*(?:::[A-Z][A-z]*)*)?::([a-z_]+)(-?)/
CONSTANT_REGEXP =

A regexp matching constants from the ATTRIBUTE_REGEXP leader

/#.*?([A-Z][A-z]*(?:::[A-Z][A-z]*)*)?$/
CALLER_REGEXP =

A regexp matching a caller line, to extract the calling file and line number. After a match:

$1:: file
$2:: line number (as a string, obviously)

Note that line numbers in caller start at 1, not 0.

/^((?:[A-z]:)?[^:]+):(\d+)/

Class Method Summary collapse

Class Method Details

.[](source_file) ⇒ Object

Returns the document registered to the source file. If no such document exists, one will be created for it.



21
22
23
# File 'lib/lazydoc.rb', line 21

def [](source_file)
  document(source_file) || register_file(source_file)
end

.document(source_file) ⇒ Object

Returns the document registered to the source file, or nil if no such document exists.



14
15
16
17
# File 'lib/lazydoc.rb', line 14

def document(source_file)
  source_file = File.expand_path(source_file.to_s)
  registry.find {|doc| doc.source_file == source_file }
end

.guess_const_name(source_file) ⇒ Object

Guesses the default constant name for the source file by camelizing the shortest relative path from a matching $LOAD_PATH to the source file. Returns nil if the source file is not relative to any load path.

Code Credit

The camelize algorithm is taken from the ActiveSupport Inflections module. See the Tap::Env::StringExt module (which uses the same) for a proper credit and license.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/lazydoc.rb', line 35

def guess_const_name(source_file)
  source_file = File.expand_path(source_file.to_s)
  
  load_paths = []
  $LOAD_PATH.each do |load_path|
    load_path = File.expand_path(load_path)
    if source_file.rindex(load_path, 0) == 0
      load_paths << load_path
    end
  end
  
  return nil if load_paths.empty?
  
  load_path = load_paths.sort_by {|load_path| load_path.length}.pop
  extname = File.extname(source_file)
  relative_path = source_file[(load_path.length + 1)..(-1 - extname.length)]
  relative_path.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
end

.register(source_file, line_number, comment_class = Comment) ⇒ Object

Registers the line number to the document for source_file and returns the new comment.



70
71
72
# File 'lib/lazydoc.rb', line 70

def register(source_file, line_number, comment_class=Comment)
  Lazydoc[source_file].register(line_number, comment_class)
end

.register_caller(comment_class = Comment, caller_index = 1) ⇒ Object

Registers the method to the line where it was called. To do so, register_caller examines the specified index in the call stack and extracts a file and line number. For instance:

module Sample
  module_function
  def method
    Lazydoc.register_caller
  end
end

# this is the line that gets registered
c = Sample.method

c.resolve
c.subject   # => "c = Sample.method"
c.comment   # => "this is the line that gets registered"


92
93
94
95
# File 'lib/lazydoc.rb', line 92

def register_caller(comment_class=Comment, caller_index=1)
  caller[caller_index] =~ CALLER_REGEXP
  Lazydoc[$1].register($2.to_i - 1, comment_class)
end

.register_file(source_file, default_const_name = guess_const_name(source_file)) ⇒ Object

Generates a document for the source_file and default_const_name and adds it to registry, or returns the document already registered to the source file. An error is raised if you try to re-register a source_file with an inconsistent default_const_name.



58
59
60
61
62
63
64
65
66
# File 'lib/lazydoc.rb', line 58

def register_file(source_file, default_const_name=guess_const_name(source_file))
  unless lazydoc = document(source_file)
    lazydoc = Document.new(source_file)
    registry << lazydoc
  end
  
  lazydoc.default_const_name = default_const_name
  lazydoc
end

.registryObject

An array of documents registered with Lazydoc.



8
9
10
# File 'lib/lazydoc.rb', line 8

def registry
  @registry ||= []
end

.usage(path, cols = 80) ⇒ Object

Parses the usage for a file (ie the first comment in the file following an optional bang line), wrapped to n cols. For example, with this:

[hello_world.rb]
#!/usr/bin/env ruby
# This is your basic hello world
# script:
#
#   % ruby hello_world.rb

puts 'hello world'

You get this:

"\n" + Lazydoc.usage('hello_world.rb')  
# => %Q{
# This is your basic hello world script:
#
#   % ruby hello_world.rb}


118
119
120
121
122
123
# File 'lib/lazydoc.rb', line 118

def usage(path, cols=80)
  scanner = StringScanner.new(File.read(path))
  scanner.scan(/#!.*?\r?\n/)
  scanner.scan(/\s*#/m)
  Comment.new.parse_down(scanner, nil, false).wrap(cols, 2).strip
end