lazydoc 0.9.0 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +17 -0
- data/MIT-LICENSE +16 -15
- data/README +51 -30
- data/lib/lazydoc.rb +49 -17
- data/lib/lazydoc/attributes.rb +227 -72
- data/lib/lazydoc/document.rb +13 -11
- data/lib/lazydoc/version.rb +7 -0
- metadata +7 -4
data/History
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
== 1.0.0 / 2009-12-05
|
2
|
+
|
3
|
+
* optimized regexps
|
4
|
+
* updated Lazydoc::Attributes to automatically set source_file
|
5
|
+
when inherited
|
6
|
+
* added document method to Lazydoc to look up document for
|
7
|
+
source_file without automatically creating the document (as
|
8
|
+
is the case with Lazydoc[])
|
9
|
+
* register_file now guesses a default constant name based on
|
10
|
+
the path relative to a matching LOAD_PATH
|
11
|
+
* updated Lazydoc::Attributes to allow manually registered
|
12
|
+
comments across multiple source files
|
13
|
+
* added inheritance for lazy attributes
|
14
|
+
* changed registered_methods to return an array of the methods
|
15
|
+
whose documentation will be registered (no longer a hash by
|
16
|
+
default)
|
17
|
+
|
1
18
|
== 0.9.0 / 2009-05-25
|
2
19
|
|
3
20
|
* lazy attributes can now be accessed without auto-resolve
|
data/MIT-LICENSE
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
Copyright (c) 2008-2009, Regents of the University of Colorado.
|
2
|
+
Copyright (c) 2009, Simon Chiang.
|
2
3
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
software and associated documentation files (the "Software"), to deal
|
5
|
-
without restriction, including without limitation the rights
|
6
|
-
publish, distribute, sublicense, and/or sell
|
7
|
-
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
6
|
+
in the Software without restriction, including without limitation the rights
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
8
10
|
|
9
|
-
The above copyright notice and this permission notice shall be included in all
|
10
|
-
substantial portions of the Software.
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
12
|
+
copies or substantial portions of the Software.
|
11
13
|
|
12
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
OTHER DEALINGS IN THE SOFTWARE.
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
SOFTWARE.
|
data/README
CHANGED
@@ -6,9 +6,8 @@ Tap[http://tap.rubyforge.org] framework.
|
|
6
6
|
|
7
7
|
== Description
|
8
8
|
|
9
|
-
Lazydoc allows you to define lazy attributes that
|
10
|
-
|
11
|
-
Lazydoc pulls out the documentation:
|
9
|
+
Lazydoc allows you to define lazy attributes that access documentation in a
|
10
|
+
source file.
|
12
11
|
|
13
12
|
# Sample::key <value>
|
14
13
|
# This is the comment content. A content
|
@@ -35,8 +34,7 @@ Comments support wrapping, allowing for easy presentation:
|
|
35
34
|
# ..............................
|
36
35
|
# }
|
37
36
|
|
38
|
-
|
39
|
-
particularly method definitions:
|
37
|
+
Lazydoc also provides helpers to register method documentation:
|
40
38
|
|
41
39
|
class Helpers
|
42
40
|
extend Lazydoc::Attributes
|
@@ -49,7 +47,7 @@ particularly method definitions:
|
|
49
47
|
end
|
50
48
|
|
51
49
|
# register_caller will register the line
|
52
|
-
# that *calls* method_two
|
50
|
+
# that *calls* method_two (see below)
|
53
51
|
def method_two
|
54
52
|
Lazydoc.register_caller
|
55
53
|
end
|
@@ -59,19 +57,18 @@ particularly method definitions:
|
|
59
57
|
# registered by method_two
|
60
58
|
Helpers.const_attrs[:method_two] = Helpers.new.method_two
|
61
59
|
|
62
|
-
doc = Helpers.lazydoc
|
63
|
-
doc.resolve
|
64
|
-
|
65
60
|
one = Helpers.const_attrs[:method_one]
|
61
|
+
one.resolve
|
66
62
|
one.method_name # => "method_one"
|
67
63
|
one.arguments # => ["a", "b='str'", "&c"]
|
68
64
|
one.to_s # => "method_one is registered whenever it gets defined"
|
69
65
|
|
70
66
|
two = Helpers.const_attrs[:method_two]
|
67
|
+
two.resolve
|
71
68
|
two.subject # => "Helpers.const_attrs[:method_two] = Helpers.new.method_two"
|
72
69
|
two.to_s # => "*THIS* is the line that gets registered by method_two"
|
73
70
|
|
74
|
-
Lazy accessors may be defined to
|
71
|
+
Lazy accessors may be defined to access the registered lines more easily:
|
75
72
|
|
76
73
|
class Helpers
|
77
74
|
lazy_attr(:one, :method_one)
|
@@ -81,11 +78,10 @@ Lazy accessors may be defined to map the registered lines as well:
|
|
81
78
|
Helpers.one.method_name # => "method_one"
|
82
79
|
Helpers.two.subject # => "Helpers.const_attrs[:method_two] = Helpers.new.method_two"
|
83
80
|
|
84
|
-
Check out these links for
|
81
|
+
Check out these links for developments and bug tracking.
|
85
82
|
|
86
83
|
* Website[http://tap.rubyforge.org/lazydoc]
|
87
84
|
* Github[http://github.com/bahuvrihi/lazydoc/tree/master]
|
88
|
-
* Lighthouse[http://bahuvrihi.lighthouseapp.com/projects/19948-lazydoc/tickets?q=all]
|
89
85
|
* {Google Group}[http://groups.google.com/group/ruby-on-tap]
|
90
86
|
|
91
87
|
== Usage
|
@@ -96,9 +92,9 @@ are represented by Comment objects.
|
|
96
92
|
|
97
93
|
=== Constant Attributes
|
98
94
|
|
99
|
-
Constant attributes are
|
100
|
-
that must consist of only lowercase letters and/or
|
101
|
-
example, these are constant attributes:
|
95
|
+
Constant attributes are defined in the documentation to look like constants,
|
96
|
+
but with an extra 'key' that must consist of only lowercase letters and/or
|
97
|
+
underscores. For example, these are constant attributes:
|
102
98
|
|
103
99
|
# Const::Name::key
|
104
100
|
# Const::Name::key_with_underscores
|
@@ -111,7 +107,7 @@ While these are not:
|
|
111
107
|
# Const::Name::k@y
|
112
108
|
|
113
109
|
Lazydoc parses a Lazydoc::Comment for each constant attribute by using the
|
114
|
-
remainder of the line as a value (ie subject) and
|
110
|
+
remainder of the line as a value (ie subject) and trailing lines as content.
|
115
111
|
Parsing continues until a non-comment line, an end key, or a new attribute
|
116
112
|
is reached; the comment is then stored by constant name and key.
|
117
113
|
|
@@ -139,8 +135,8 @@ is reached; the comment is then stored by constant name and key.
|
|
139
135
|
# 'another' => ['value for another', 'comment for another parsed to an end key']}
|
140
136
|
# }
|
141
137
|
|
142
|
-
Constant attributes are only parsed from
|
143
|
-
|
138
|
+
Constant attributes are only parsed from comment lines. To turn off attribute
|
139
|
+
parsing for a section of documentation, use start/stop keys:
|
144
140
|
|
145
141
|
str = %Q{
|
146
142
|
Const::Name::not_parsed
|
@@ -155,9 +151,9 @@ attribute parsing for a section of documentation, use start/stop keys:
|
|
155
151
|
doc.resolve(str)
|
156
152
|
doc.summarize {|comment| comment.value } # => {'Const::Name' => {'parsed' => 'value'}}
|
157
153
|
|
158
|
-
To hide attributes from RDoc, make use of the RDoc <tt>:startdoc:</tt>
|
159
|
-
document modifier like this (note
|
160
|
-
from hiding the example):
|
154
|
+
To hide attributes from RDoc, make use of the RDoc <tt>:startdoc:</tt>
|
155
|
+
document modifier like this (note the modifiers have an extra space in them to
|
156
|
+
prevent RDoc from hiding the example):
|
161
157
|
|
162
158
|
# :start doc::Const::Name::one hidden in RDoc
|
163
159
|
# * This line is visible in RDoc.
|
@@ -171,16 +167,17 @@ from hiding the example):
|
|
171
167
|
#
|
172
168
|
# * This line is also visible in RDoc.
|
173
169
|
|
174
|
-
As a side note,
|
175
|
-
|
176
|
-
'Const::Name::key' is equivalent to the method call
|
170
|
+
As a side note, the constant attribute syntax is designed to echo how the
|
171
|
+
Lazydoc::Attributes module makes comments accessible in code. In *very*
|
172
|
+
idiomatic Ruby 'Const::Name::key' is equivalent to the method call
|
173
|
+
'Const::Name.key'.
|
177
174
|
|
178
175
|
=== Code Comments
|
179
176
|
|
180
|
-
Code comments are lines registered for parsing if and when a Lazydoc gets
|
177
|
+
Code comments are lines registered for parsing if and when a Lazydoc gets
|
181
178
|
resolved. Unlike constant attributes, the registered line is the comment
|
182
|
-
subject (ie value) and
|
183
|
-
the behavior of RDoc).
|
179
|
+
subject (ie value) and the content consists of the preceding documentation
|
180
|
+
(basically mimicking the behavior of RDoc).
|
184
181
|
|
185
182
|
str = %Q{
|
186
183
|
# comment lines for
|
@@ -211,6 +208,31 @@ of a Regexp, the first matching line is used; Procs receive an array of
|
|
211
208
|
lines and should return the line number that should be used. See
|
212
209
|
{Comment#parse_up}[link://classes/Lazydoc/Comment.html] for more details.
|
213
210
|
|
211
|
+
Manually registering lines for documentation can be quite cumbersome. The
|
212
|
+
Lazydoc::Attributes module provides helpers to register method documentation
|
213
|
+
on classes with method-like inheritance.
|
214
|
+
|
215
|
+
class A
|
216
|
+
extend Lazydoc::Attributes
|
217
|
+
lazy_attr(:one, :method_one)
|
218
|
+
lazy_register(:method_one)
|
219
|
+
|
220
|
+
# documentation for method one
|
221
|
+
def method_one; end
|
222
|
+
end
|
223
|
+
|
224
|
+
class B < A
|
225
|
+
end
|
226
|
+
|
227
|
+
class C < B
|
228
|
+
# overriding documentation for method one
|
229
|
+
def method_one; end
|
230
|
+
end
|
231
|
+
|
232
|
+
A::one.comment # => "documentation for method one"
|
233
|
+
B::one.comment # => "documentation for method one"
|
234
|
+
C::one.comment # => "overriding documentation for method one"
|
235
|
+
|
214
236
|
== Installation
|
215
237
|
|
216
238
|
Lazydoc is available as a gem on RubyForge[http://rubyforge.org/projects/tap]. Use:
|
@@ -219,7 +241,6 @@ Lazydoc is available as a gem on RubyForge[http://rubyforge.org/projects/tap].
|
|
219
241
|
|
220
242
|
== Info
|
221
243
|
|
222
|
-
Copyright (c)
|
223
|
-
Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com]
|
224
|
-
Support:: CU Denver School of Medicine Deans Academic Enrichment Fund
|
244
|
+
Copyright (c) 2009, Simon Chiang.
|
245
|
+
Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com]
|
225
246
|
License:: {MIT-Style}[link:files/MIT-LICENSE.html]
|
data/lib/lazydoc.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'lazydoc/version'
|
1
2
|
require 'lazydoc/document'
|
2
3
|
|
3
4
|
module Lazydoc
|
@@ -8,22 +9,54 @@ module Lazydoc
|
|
8
9
|
@registry ||= []
|
9
10
|
end
|
10
11
|
|
11
|
-
# Returns the
|
12
|
-
#
|
12
|
+
# Returns the document registered to the source file, or nil if no such
|
13
|
+
# document exists.
|
14
|
+
def document(source_file)
|
15
|
+
source_file = File.expand_path(source_file.to_s)
|
16
|
+
registry.find {|doc| doc.source_file == source_file }
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the document registered to the source file. If no such document
|
20
|
+
# exists, one will be created for it.
|
13
21
|
def [](source_file)
|
22
|
+
document(source_file) || register_file(source_file)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Guesses the default constant name for the source file by camelizing the
|
26
|
+
# shortest relative path from a matching $LOAD_PATH to the source file.
|
27
|
+
# Returns nil if the source file is not relative to any load path.
|
28
|
+
#
|
29
|
+
# ==== Code Credit
|
30
|
+
#
|
31
|
+
# The camelize algorithm is taken from the ActiveSupport {Inflections}[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
32
|
+
# module. See the {Tap::Env::StringExt}[http://tap.rubyforge.org/rdoc/classes/Tap/Env/StringExt.html]
|
33
|
+
# module (which uses the same) for a proper credit and license.
|
34
|
+
#
|
35
|
+
def guess_const_name(source_file)
|
14
36
|
source_file = File.expand_path(source_file.to_s)
|
15
|
-
|
37
|
+
|
38
|
+
load_paths = []
|
39
|
+
$LOAD_PATH.each do |load_path|
|
40
|
+
load_path = File.expand_path(load_path)
|
41
|
+
if source_file.rindex(load_path, 0) == 0
|
42
|
+
load_paths << load_path
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
return nil if load_paths.empty?
|
47
|
+
|
48
|
+
load_path = load_paths.sort_by {|load_path| load_path.length}.pop
|
49
|
+
extname = File.extname(source_file)
|
50
|
+
relative_path = source_file[(load_path.length + 1)..(-1 - extname.length)]
|
51
|
+
relative_path.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
16
52
|
end
|
17
53
|
|
18
|
-
# Generates a
|
19
|
-
# registry, or returns the document already registered to
|
54
|
+
# Generates a document for the source_file and default_const_name and adds it to
|
55
|
+
# registry, or returns the document already registered to the source file. An
|
20
56
|
# error is raised if you try to re-register a source_file with an inconsistent
|
21
57
|
# default_const_name.
|
22
|
-
def register_file(source_file, default_const_name=
|
23
|
-
|
24
|
-
lazydoc = registry.find {|doc| doc.source_file == source_file }
|
25
|
-
|
26
|
-
unless lazydoc
|
58
|
+
def register_file(source_file, default_const_name=guess_const_name(source_file))
|
59
|
+
unless lazydoc = document(source_file)
|
27
60
|
lazydoc = Document.new(source_file)
|
28
61
|
registry << lazydoc
|
29
62
|
end
|
@@ -32,16 +65,15 @@ module Lazydoc
|
|
32
65
|
lazydoc
|
33
66
|
end
|
34
67
|
|
35
|
-
# Registers the line number to the document for source_file and
|
36
|
-
#
|
68
|
+
# Registers the line number to the document for source_file and returns the
|
69
|
+
# new comment.
|
37
70
|
def register(source_file, line_number, comment_class=Comment)
|
38
71
|
Lazydoc[source_file].register(line_number, comment_class)
|
39
72
|
end
|
40
73
|
|
41
|
-
# Registers the method
|
42
|
-
#
|
43
|
-
#
|
44
|
-
# register_caller is called (whew!). For instance:
|
74
|
+
# Registers the method to the line where it was called. To do so,
|
75
|
+
# register_caller examines the specified index in the call stack
|
76
|
+
# and extracts a file and line number. For instance:
|
45
77
|
#
|
46
78
|
# module Sample
|
47
79
|
# module_function
|
@@ -59,7 +91,7 @@ module Lazydoc
|
|
59
91
|
#
|
60
92
|
def register_caller(comment_class=Comment, caller_index=1)
|
61
93
|
caller[caller_index] =~ CALLER_REGEXP
|
62
|
-
Lazydoc[$1].register($
|
94
|
+
Lazydoc[$1].register($2.to_i - 1, comment_class)
|
63
95
|
end
|
64
96
|
|
65
97
|
# Parses the usage for a file (ie the first comment in the file
|
data/lib/lazydoc/attributes.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Lazydoc
|
2
2
|
|
3
3
|
# Attributes adds methods to declare class-level accessors for constant
|
4
|
-
# attributes.
|
4
|
+
# attributes associated with the class.
|
5
5
|
#
|
6
6
|
# # ConstName::key value
|
7
7
|
# class ConstName
|
@@ -9,132 +9,287 @@ module Lazydoc
|
|
9
9
|
# lazy_attr :key
|
10
10
|
# end
|
11
11
|
#
|
12
|
-
# ConstName.
|
13
|
-
#
|
12
|
+
# ConstName::key.subject # => 'value'
|
13
|
+
#
|
14
|
+
# Lazy attributes are inherited, but can be overridden.
|
15
|
+
#
|
16
|
+
# class SubclassA < ConstName; end
|
17
|
+
# SubclassA::key.subject # => 'value'
|
18
|
+
#
|
19
|
+
# # SubclassB::key overridden value
|
20
|
+
# class SubclassB < ConstName; end
|
21
|
+
# SubclassB::key.subject # => 'overridden value'
|
22
|
+
#
|
23
|
+
# You can use Attributes to register methods on modules, but currently the
|
24
|
+
# inheritance is a bit wonky; the accessors are methods on the extended
|
25
|
+
# class/module and so standard module inclusion will not pass them on.
|
26
|
+
# To work around you need to extend and redefine the accessors. Note,
|
27
|
+
# however, that methods do not need to be re-registered.
|
28
|
+
#
|
29
|
+
# module A
|
30
|
+
# extend Lazydoc::Attributes
|
31
|
+
# lazy_attr(:one, :method_one)
|
32
|
+
# lazy_register(:method_one)
|
33
|
+
#
|
34
|
+
# # documentation for method one
|
35
|
+
# def method_one; end
|
36
|
+
# end
|
14
37
|
#
|
38
|
+
# class B
|
39
|
+
# include A
|
40
|
+
# extend Lazydoc::Attributes
|
41
|
+
# lazy_attr(:one, :method_one)
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# class C < B
|
45
|
+
# # overriding documentation for method one
|
46
|
+
# def method_one; end
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# A::one.comment # => "documentation for method one"
|
50
|
+
# B::one.comment # => "documentation for method one"
|
51
|
+
# C::one.comment # => "overriding documentation for method one"
|
52
|
+
#
|
15
53
|
# ==== Keys and Register
|
16
54
|
#
|
17
|
-
#
|
18
|
-
# const_attrs
|
19
|
-
#
|
55
|
+
# Constant attributes parsed from a source file will ALWAYS be stored in
|
56
|
+
# const_attrs using a string (since the 'ConstName::key' syntax always
|
57
|
+
# results in a string key). A lazy_attr is basically shorthand for either
|
58
|
+
# of these statements:
|
59
|
+
#
|
60
|
+
# ConstName.const_attrs['key'].subject # => 'value'
|
61
|
+
# Lazydoc::Document['ConstName']['key'].subject # => 'value'
|
62
|
+
#
|
63
|
+
# By default a lazy_attr maps to the constant attribute with the same name
|
64
|
+
# as the accessor, but this can be overridden by specifying the string key
|
65
|
+
# for another attribute.
|
66
|
+
#
|
67
|
+
# class ConstName
|
68
|
+
# lazy_attr :alt, 'key'
|
69
|
+
# end
|
20
70
|
#
|
21
|
-
# ConstName.
|
71
|
+
# ConstName::alt.subject # => 'value'
|
72
|
+
# ConstName.const_attrs['alt'] # => nil
|
22
73
|
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
74
|
+
# Comments specified by non-string keys may also be stored in const_attrs;
|
75
|
+
# these will not conflict with constant attributes parsed from a source
|
76
|
+
# file. For instance you could manually register a comment to a symbol key
|
77
|
+
# using lazy_register:
|
26
78
|
#
|
27
79
|
# class Sample
|
28
80
|
# extend Lazydoc::Attributes
|
29
81
|
#
|
30
|
-
#
|
82
|
+
# lazy_register(:method_one)
|
83
|
+
#
|
31
84
|
# # this is the method one comment
|
32
85
|
# def method_one
|
33
86
|
# end
|
34
87
|
# end
|
35
88
|
#
|
36
|
-
# Sample.
|
37
|
-
# Sample.const_attrs[:method_one].comment # => "this is the method one comment"
|
89
|
+
# Sample.const_attrs[:method_one].comment # => "this is the method one comment"
|
38
90
|
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
# lazy_attr.
|
91
|
+
# Manually-registered comments may then be paired with a lazy_attr. As
|
92
|
+
# before the key for the comment is provided in the definition.
|
42
93
|
#
|
43
94
|
# class Paired
|
44
95
|
# extend Lazydoc::Attributes
|
45
96
|
#
|
46
97
|
# lazy_attr(:one, :method_one)
|
47
|
-
#
|
48
|
-
# lazy_register(:method_two)
|
98
|
+
# lazy_register(:method_one)
|
49
99
|
#
|
50
|
-
#
|
51
|
-
# # this is the manually-registered method one comment
|
100
|
+
# # this is the method one comment
|
52
101
|
# def method_one
|
53
102
|
# end
|
54
|
-
#
|
55
|
-
# # this is the lazyily-registered method two comment
|
56
|
-
# def method_two
|
57
|
-
# end
|
58
103
|
# end
|
59
104
|
#
|
60
|
-
# Paired.
|
61
|
-
#
|
62
|
-
#
|
105
|
+
# Paired::one.comment # => "this is the method one comment"
|
106
|
+
#
|
107
|
+
# ==== Troubleshooting
|
63
108
|
#
|
109
|
+
# Under most circumstances Attributes will register all the necessary files
|
110
|
+
# to make constant attributes available. These include:
|
111
|
+
#
|
112
|
+
# * the file where the class is extended
|
113
|
+
# * the file where a subclass inherits from an extended class
|
114
|
+
# * files that declare a lazy_attr
|
115
|
+
#
|
116
|
+
# Be sure to call register_lazydoc in files that are not covered by one of
|
117
|
+
# these cases but nonetheless contain constant attributes that should be
|
118
|
+
# available to a lazy_attr.
|
64
119
|
module Attributes
|
65
|
-
|
66
|
-
# The source file for the extended class. By default source_file
|
67
|
-
# is set to the file where Attributes extends the class (if you
|
68
|
-
# include Attributes, you must set source_file manually).
|
69
|
-
attr_accessor :source_file
|
70
120
|
|
71
|
-
|
121
|
+
# Sets source_file as the file where Attributes first extends the class.
|
122
|
+
def self.extended(base)
|
72
123
|
caller[1] =~ CALLER_REGEXP
|
73
|
-
base.
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
124
|
+
unless base.instance_variable_defined?(:@lazydocs)
|
125
|
+
base.instance_variable_set(:@lazydocs, [Lazydoc[$1]])
|
126
|
+
end
|
127
|
+
|
128
|
+
unless base.instance_variable_defined?(:@lazy_registry)
|
129
|
+
base.instance_variable_set(:@lazy_registry, {})
|
130
|
+
end
|
131
|
+
|
79
132
|
super
|
80
133
|
end
|
81
134
|
|
82
|
-
#
|
83
|
-
|
84
|
-
|
85
|
-
|
135
|
+
# Returns the documents registered to the extending class.
|
136
|
+
#
|
137
|
+
# By default lazydocs contains a Document for the file where Attributes
|
138
|
+
# extends the class, or where a subclass first inherits from an extended
|
139
|
+
# class (if you include Attributes, you must set lazydocs manually).
|
140
|
+
#
|
141
|
+
# Additional documents may be added by calling register_lazydoc.
|
142
|
+
attr_reader :lazydocs
|
143
|
+
|
144
|
+
# Returns an array of the methods whose documentation will be automatically
|
145
|
+
# registered by Attributes. Set as_registry to true to return a hash of
|
146
|
+
# of (method_name, [comment_class, caller_index]) pairs where the
|
147
|
+
# registration arguments are the hash values.
|
148
|
+
def registered_methods(as_registry=false)
|
149
|
+
methods = {}
|
150
|
+
ancestors.reverse.each do |ancestor|
|
151
|
+
if ancestor.kind_of?(Attributes)
|
152
|
+
methods.merge!(ancestor.lazy_registry)
|
153
|
+
end
|
86
154
|
end
|
87
155
|
|
88
|
-
|
156
|
+
as_registry ? methods : methods.keys
|
89
157
|
end
|
90
158
|
|
91
159
|
# Returns the constant attributes resolved for the extended class.
|
92
160
|
def const_attrs
|
93
161
|
Document[to_s]
|
94
162
|
end
|
95
|
-
|
96
|
-
|
97
|
-
def lazydoc
|
98
|
-
Lazydoc[source_file]
|
99
|
-
end
|
163
|
+
|
164
|
+
protected
|
100
165
|
|
101
166
|
# A hash of (method_name, [comment_class, caller_index]) pairs indicating
|
102
|
-
# methods to lazily register, and the inputs to
|
103
|
-
#
|
104
|
-
|
105
|
-
|
167
|
+
# methods to lazily register, and the inputs used to register the method.
|
168
|
+
#
|
169
|
+
# The lazy_registry only contains methods lazily registered within the
|
170
|
+
# current class or module. To return methods registered throughout the
|
171
|
+
# inheritance hierarchy, use registered_methods(true)
|
172
|
+
attr_reader :lazy_registry
|
173
|
+
|
174
|
+
# Registers the calling file into lazydocs. Registration occurs by
|
175
|
+
# examining the call stack at the specified index.
|
176
|
+
def register_lazydoc(caller_index=0)
|
177
|
+
caller[caller_index] =~ CALLER_REGEXP
|
178
|
+
lazydocs << Lazydoc[File.expand_path($1)]
|
179
|
+
lazydocs.uniq!
|
180
|
+
self
|
106
181
|
end
|
107
182
|
|
108
183
|
# Creates a method that reads and resolves the constant attribute specified
|
109
|
-
# by key
|
110
|
-
#
|
184
|
+
# by key. The method has a signature like:
|
185
|
+
#
|
186
|
+
# def method(resolve=true)
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# To return the constant attribute without resolving, call the method with
|
190
|
+
# resolve == false. If writable is true, a corresponding writer is also
|
191
|
+
# created.
|
111
192
|
def lazy_attr(symbol, key=symbol.to_s, writable=true)
|
112
|
-
key
|
113
|
-
|
114
|
-
else "YAML.load(\'#{YAML.dump(key)}\')"
|
193
|
+
unless key.kind_of?(String) || key.kind_of?(Symbol)
|
194
|
+
raise "invalid lazy_attr key: #{key.inspect} (#{key.class})"
|
115
195
|
end
|
116
196
|
|
117
|
-
|
118
|
-
def #{symbol}(resolve=true)
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
instance_eval(%Q{
|
124
|
-
def #{symbol}=(comment)
|
125
|
-
const_attrs[#{key}] = comment
|
126
|
-
end}) if writable
|
197
|
+
key = key.inspect
|
198
|
+
instance_eval %Q{def #{symbol}(resolve=true); get_const_attr(#{key}, resolve); end}
|
199
|
+
instance_eval(%Q{def #{symbol}=(comment); const_attrs[#{key}] = comment; end}) if writable
|
200
|
+
|
201
|
+
register_lazydoc(1)
|
127
202
|
end
|
128
203
|
|
129
204
|
# Marks the method for lazy registration. When the method is registered,
|
130
205
|
# it will be stored in const_attrs by method_name.
|
131
206
|
def lazy_register(method_name, comment_class=Method, caller_index=1)
|
132
|
-
|
207
|
+
lazy_registry[method_name.to_sym] = [comment_class, caller_index]
|
133
208
|
end
|
134
209
|
|
135
|
-
#
|
136
|
-
|
137
|
-
|
210
|
+
# Manually registers the next comment into const_attrs. Note a lazy_attr
|
211
|
+
# will still need to be defined to access this comment as an attribute.
|
212
|
+
def register___(key, comment_class=Method)
|
213
|
+
caller[0] =~ CALLER_REGEXP
|
214
|
+
source_file = File.expand_path($1)
|
215
|
+
const_attrs[key] = Lazydoc[source_file].register___(comment_class, 1)
|
216
|
+
end
|
217
|
+
|
218
|
+
private
|
219
|
+
|
220
|
+
# Inherits lazy_registry from parent to child. Also registers the
|
221
|
+
# source_file for the child as the file where the inheritance first
|
222
|
+
# occurs.
|
223
|
+
def inherited(child)
|
224
|
+
unless child.instance_variable_defined?(:@lazydocs)
|
225
|
+
caller.each do |call|
|
226
|
+
next if call =~ /in `inherited'$/
|
227
|
+
|
228
|
+
call =~ CALLER_REGEXP
|
229
|
+
child.instance_variable_set(:@lazydocs, [Lazydoc[$1]])
|
230
|
+
break
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
unless child.instance_variable_defined?(:@lazy_registry)
|
235
|
+
child.instance_variable_set(:@lazy_registry, {})
|
236
|
+
end
|
237
|
+
|
238
|
+
super
|
239
|
+
end
|
240
|
+
|
241
|
+
# Helper to traverse the inheritance hierarchy. The logic of this method
|
242
|
+
# is described in the dsl pattern: http://gist.github.com/181961
|
243
|
+
def each_ancestor # :nodoc:
|
244
|
+
yield(self)
|
245
|
+
|
246
|
+
blank, *ancestors = self.ancestors
|
247
|
+
ancestors.each do |ancestor|
|
248
|
+
yield(ancestor) if ancestor.kind_of?(Attributes)
|
249
|
+
end
|
250
|
+
|
251
|
+
nil
|
252
|
+
end
|
253
|
+
|
254
|
+
# Lazily registers the added method if marked for lazy registration.
|
255
|
+
def method_added(sym)
|
256
|
+
current = nil
|
257
|
+
each_ancestor do |ancestor|
|
258
|
+
if ancestor.lazy_registry.has_key?(sym)
|
259
|
+
current = ancestor
|
260
|
+
break
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
if current
|
265
|
+
args = current.lazy_registry[sym]
|
266
|
+
const_attrs[sym] ||= Lazydoc.register_caller(*args)
|
267
|
+
end
|
268
|
+
|
269
|
+
super
|
270
|
+
end
|
271
|
+
|
272
|
+
# helper to traverse up the inheritance hierarchy looking for the first
|
273
|
+
# const_attr assigned to key. the lazydocs for each class will be
|
274
|
+
# resolved along the way, if specified.
|
275
|
+
def get_const_attr(key, resolve) # :nodoc:
|
276
|
+
each_ancestor do |ancestor|
|
277
|
+
const_attrs = ancestor.const_attrs
|
278
|
+
|
279
|
+
unless const_attrs.has_key?(key)
|
280
|
+
next unless resolve
|
281
|
+
|
282
|
+
ancestor.lazydocs.each {|doc| doc.resolve }
|
283
|
+
next unless const_attrs.has_key?(key)
|
284
|
+
end
|
285
|
+
|
286
|
+
const_attr = const_attrs[key]
|
287
|
+
if resolve && const_attr.kind_of?(Comment)
|
288
|
+
const_attr.resolve
|
289
|
+
end
|
290
|
+
|
291
|
+
return const_attr
|
292
|
+
end
|
138
293
|
end
|
139
294
|
end
|
140
295
|
end
|
data/lib/lazydoc/document.rb
CHANGED
@@ -10,22 +10,22 @@ module Lazydoc
|
|
10
10
|
# A regexp matching an attribute start or end. After a match:
|
11
11
|
#
|
12
12
|
# $1:: const_name
|
13
|
-
# $
|
14
|
-
# $
|
13
|
+
# $2:: key
|
14
|
+
# $3:: end flag
|
15
15
|
#
|
16
|
-
ATTRIBUTE_REGEXP = /([A-Z][A-z]*(
|
16
|
+
ATTRIBUTE_REGEXP = /([A-Z][A-z]*(?:::[A-Z][A-z]*)*)?::([a-z_]+)(-?)/
|
17
17
|
|
18
18
|
# A regexp matching constants from the ATTRIBUTE_REGEXP leader
|
19
|
-
CONSTANT_REGEXP = /#.*?([A-Z][A-z]*(
|
19
|
+
CONSTANT_REGEXP = /#.*?([A-Z][A-z]*(?:::[A-Z][A-z]*)*)?$/
|
20
20
|
|
21
21
|
# A regexp matching a caller line, to extract the calling file
|
22
22
|
# and line number. After a match:
|
23
23
|
#
|
24
24
|
# $1:: file
|
25
|
-
# $
|
25
|
+
# $2:: line number (as a string, obviously)
|
26
26
|
#
|
27
27
|
# Note that line numbers in caller start at 1, not 0.
|
28
|
-
CALLER_REGEXP = /^(([A-z]:)?[^:]+):(\d+)/
|
28
|
+
CALLER_REGEXP = /^((?:[A-z]:)?[^:]+):(\d+)/
|
29
29
|
|
30
30
|
# A Document resolves constant attributes and code comments for a particular
|
31
31
|
# source file. Documents may be assigned a default_const_name to be used
|
@@ -40,9 +40,8 @@ module Lazydoc
|
|
40
40
|
# Document['Const::Name']['key'].value # => 'value a'
|
41
41
|
# Document['Default']['key'].value # => 'value b'
|
42
42
|
#
|
43
|
-
# As
|
44
|
-
#
|
45
|
-
# itself.
|
43
|
+
# As in the example, constant attibutes for all documents may be accessed
|
44
|
+
# from Document[].
|
46
45
|
class Document
|
47
46
|
class << self
|
48
47
|
|
@@ -136,6 +135,9 @@ module Lazydoc
|
|
136
135
|
# Returns the attributes for the specified const_name. If an empty
|
137
136
|
# const_name ('') is specified, and a default_const_name is set,
|
138
137
|
# the default_const_name will be used instead.
|
138
|
+
#
|
139
|
+
# Note this method will return ALL attributes associated with const_name,
|
140
|
+
# not just attributes associated with self.
|
139
141
|
def [](const_name)
|
140
142
|
const_name = default_const_name if default_const_name && const_name == ''
|
141
143
|
Document[const_name]
|
@@ -184,7 +186,7 @@ module Lazydoc
|
|
184
186
|
def register___(comment_class=Comment, caller_index=0)
|
185
187
|
caller[caller_index] =~ CALLER_REGEXP
|
186
188
|
block = lambda do |scanner, lines|
|
187
|
-
n = $
|
189
|
+
n = $2.to_i
|
188
190
|
n += 1 while lines[n] =~ /^\s*(#.*)?$/
|
189
191
|
n
|
190
192
|
end
|
@@ -216,7 +218,7 @@ module Lazydoc
|
|
216
218
|
comment.parse_down(scanner, lines) do |line|
|
217
219
|
if line =~ ATTRIBUTE_REGEXP
|
218
220
|
# rewind to capture the next attribute unless an end is specified.
|
219
|
-
scanner.unscan unless $
|
221
|
+
scanner.unscan unless $3 == '-' && $2 == key && $1.to_s == const_name
|
220
222
|
true
|
221
223
|
else false
|
222
224
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lazydoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: "1.0"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Chiang
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-05
|
12
|
+
date: 2009-12-05 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -33,11 +33,14 @@ files:
|
|
33
33
|
- lib/lazydoc/subject.rb
|
34
34
|
- lib/lazydoc/trailer.rb
|
35
35
|
- lib/lazydoc/utils.rb
|
36
|
+
- lib/lazydoc/version.rb
|
36
37
|
- README
|
37
38
|
- MIT-LICENSE
|
38
39
|
- History
|
39
40
|
has_rdoc: true
|
40
41
|
homepage: http://tap.rubyforge.org/lazydoc
|
42
|
+
licenses: []
|
43
|
+
|
41
44
|
post_install_message:
|
42
45
|
rdoc_options:
|
43
46
|
- --title
|
@@ -63,9 +66,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
66
|
requirements: []
|
64
67
|
|
65
68
|
rubyforge_project: tap
|
66
|
-
rubygems_version: 1.3.
|
69
|
+
rubygems_version: 1.3.5
|
67
70
|
signing_key:
|
68
|
-
specification_version:
|
71
|
+
specification_version: 3
|
69
72
|
summary: Lazily pull documentation out of source files.
|
70
73
|
test_files: []
|
71
74
|
|