tomdoc 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ require File.dirname(__FILE__) + '/lib/tomdoc/version'
2
+
1
3
  require 'rake/testtask'
2
4
 
3
5
  def command?(command)
@@ -33,18 +35,18 @@ end
33
35
  task :default => :test
34
36
 
35
37
  if command? :turn
36
- desc "Run tests"
37
- task :test do
38
+ desc "Run tests with turn"
39
+ task :turn do
38
40
  suffix = "-n #{ENV['TEST']}" if ENV['TEST']
39
41
  sh "turn -Ilib:. test/*.rb #{suffix}"
40
42
  end
41
- else
42
- Rake::TestTask.new do |t|
43
- t.libs << 'lib'
44
- t.libs << '.'
45
- t.pattern = 'test/**/*_test.rb'
46
- t.verbose = false
47
- end
43
+ end
44
+
45
+ Rake::TestTask.new do |t|
46
+ t.libs << 'lib'
47
+ t.libs << '.'
48
+ t.pattern = 'test/**/*_test.rb'
49
+ t.verbose = false
48
50
  end
49
51
 
50
52
 
@@ -62,20 +64,25 @@ end
62
64
  # Gems
63
65
  #
64
66
 
65
- begin
66
- require 'tomdoc/version'
67
- require 'mg'
68
- MG.new("tomdoc.gemspec")
67
+ desc "Build gem."
68
+ task :gem do
69
+ sh "gem build tomdoc.gemspec"
70
+ end
71
+
72
+ task :push => [:gem] do
73
+ file = Dir["*-#{TomDoc::VERSION}.gem"].first
74
+ sh "gem push #{file}"
75
+ end
69
76
 
70
- desc "Push a new version to Gemcutter and publish docs."
71
- task :publish => "gem:publish" do
72
- require File.dirname(__FILE__) + '/lib/tomdoc/version'
77
+ desc "tag version"
78
+ task :tag do
79
+ sh "git tag v#{TomDoc::VERSION}"
80
+ sh "git push origin master --tags"
81
+ sh "git clean -fd"
82
+ end
73
83
 
74
- sh "git tag v#{TomDoc::VERSION}"
75
- sh "git push origin master --tags"
76
- sh "git clean -fd"
77
- end
78
- rescue LoadError
79
- warn "mg not available."
80
- warn "Install it with: gem i mg"
84
+ desc "tag version and push gem to server"
85
+ task :release => [:push, :tag] do
86
+ puts "And away she goes!"
81
87
  end
88
+
@@ -31,62 +31,283 @@ module TomDoc
31
31
  end
32
32
  end
33
33
 
34
+ #
35
+ # TODO: Instead of having TomDoc::TomDoc, lets consider renaming this
36
+ # class TomDoc::Comment or something.
37
+ #
34
38
  class TomDoc
35
39
  attr_accessor :raw
36
40
 
37
- def initialize(text)
41
+ # Public: Initialize a TomDoc object.
42
+ #
43
+ # text - The raw text of a method or class/module comment.
44
+ #
45
+ # Returns new TomDoc instance.
46
+ def initialize(text, options={})
38
47
  @raw = text.to_s.strip
48
+
49
+ @arguments = []
50
+ @examples = []
51
+ @returns = []
52
+ @raises = []
53
+ @signatures = []
54
+ @signature_fields = []
55
+
56
+ parse unless @raw.empty?
39
57
  end
40
58
 
41
59
  def to_s
42
60
  @raw
43
61
  end
44
62
 
63
+ # Validate given comment text.
64
+ #
65
+ # Returns true if comment is valid, otherwise false.
45
66
  def self.valid?(text)
46
67
  new(text).valid?
47
68
  end
48
69
 
70
+ # Validate raw comment.
71
+ #
72
+ # Returns true if comment is valid, otherwise false.
49
73
  def valid?
50
- validate
51
- rescue InvalidTomDoc
52
- false
74
+ return false if !raw.include?('Returns')
75
+ return false if sections.size < 2
76
+ true
53
77
  end
54
78
 
79
+ # Validate raw comment.
80
+ #
81
+ # Returns true if comment is valid.
82
+ # Raises InvalidTomDoc if comment is not valid.
55
83
  def validate
56
84
  if !raw.include?('Returns')
57
85
  raise InvalidTomDoc.new("No `Returns' statement.")
58
86
  end
59
87
 
60
- if tomdoc.split("\n\n").size < 2
88
+ if sections.size < 2
61
89
  raise InvalidTomDoc.new("No description section found.")
62
90
  end
63
91
 
64
92
  true
65
93
  end
66
94
 
95
+ # The raw comment text cleaned-up and ready for section parsing.
96
+ #
97
+ # Returns cleaned-up comment String.
67
98
  def tomdoc
68
- #raw
69
- clean = raw.split("\n").map do |line|
70
- line =~ /^(\s*# ?)/ ? line.sub($1, '') : nil
71
- end.compact.join("\n")
72
- clean
99
+ lines = raw.split("\n")
100
+
101
+ # remove remark symbol
102
+ if lines.all?{ |line| /^\s*#/ =~ line }
103
+ lines = lines.map do |line|
104
+ line =~ /^(\s*#)/ ? line.sub($1, '') : nil
105
+ end
106
+ end
107
+
108
+ # for some reason the first line is coming in without indention
109
+ # regardless.
110
+ first = lines.shift
111
+
112
+ # remove indention
113
+ spaces = lines.map do |line|
114
+ next if line.strip.empty?
115
+ md = /^(\s*)/.match(line)
116
+ md ? md[1].size : nil
117
+ end.compact
118
+
119
+ space = spaces.min
120
+ lines = lines.map do |line|
121
+ if line.empty?
122
+ line.strip
123
+ else
124
+ line[space..-1]
125
+ end
126
+ end
127
+
128
+ # put first line back
129
+ lines.unshift(first.sub(/^\s*/,''))
130
+
131
+ lines.compact.join("\n")
73
132
  end
74
133
 
134
+ # List of comment sections. These are divided simply on "\n\n".
135
+ #
136
+ # Returns Array of comment sections.
75
137
  def sections
76
- tomdoc.split("\n\n")
138
+ parsed {
139
+ @sections
140
+ }
77
141
  end
78
142
 
143
+ # Description of method or class/module.
144
+ #
145
+ # Returns description String.
79
146
  def description
80
- sections.first
147
+ parsed {
148
+ @description
149
+ }
150
+ end
151
+
152
+ # Description of method or class/module.
153
+ #
154
+ # Returns description String.
155
+ def arguments
156
+ parsed {
157
+ @arguments
158
+ }
159
+ end
160
+ alias args arguments
161
+
162
+ # List of use examples of a method or class/module.
163
+ #
164
+ # Returns String of examples.
165
+ def examples
166
+ parsed {
167
+ @examples
168
+ }
169
+ end
170
+
171
+ # Description of a methods yield procedure.
172
+ #
173
+ # Returns String decription of yield procedure.
174
+ def yields
175
+ parsed {
176
+ @yields
177
+ }
178
+ end
179
+
180
+ # The list of retrun values a method can return.
181
+ #
182
+ # Returns Array of method return descriptions.
183
+ def returns
184
+ parsed {
185
+ @returns
186
+ }
187
+ end
188
+
189
+ # A list of errors a method might raise.
190
+ #
191
+ # Returns Array of method raises descriptions.
192
+ def raises
193
+ parsed {
194
+ @raises
195
+ }
196
+ end
197
+
198
+ # A list of alternate method signatures.
199
+ #
200
+ # Returns Array of signatures.
201
+ def signatures
202
+ parsed {
203
+ @signatures
204
+ }
205
+ end
206
+
207
+ # A list of signature fields.
208
+ #
209
+ # Returns Array of field definitions.
210
+ def signature_fields
211
+ parsed {
212
+ @signature_fields
213
+ }
214
+ end
215
+
216
+ # Check if method is public.
217
+ #
218
+ # Returns true if method is public.
219
+ def public?
220
+ parsed {
221
+ @status == 'Public'
222
+ }
223
+ end
224
+
225
+ # Check if method is internal.
226
+ #
227
+ # Returns true if method is internal.
228
+ def internal?
229
+ parsed {
230
+ @status == 'Internal'
231
+ }
232
+ end
233
+
234
+ # Check if method is deprecated.
235
+ #
236
+ # Returns true if method is deprecated.
237
+ def deprecated?
238
+ parsed {
239
+ @status == 'Deprecated'
240
+ }
241
+ end
242
+
243
+ private
244
+
245
+ # Has the comment been parsed yet?
246
+ def parsed(&block)
247
+ parse unless @parsed
248
+ block.call
249
+ end
250
+
251
+ # Internal: Parse the Tomdoc formatted comment.
252
+ #
253
+ # Returns true if there was a comment to parse.
254
+ def parse
255
+ @parsed = true
256
+
257
+ @sections = tomdoc.split("\n\n")
258
+ sections = @sections.dup
259
+
260
+ return false if sections.empty?
261
+
262
+ parse_description(sections.shift)
263
+
264
+ if sections.first && sections.first =~ /^\w+\s+\-/m
265
+ parse_arguments(sections.shift)
266
+ end
267
+
268
+ current = sections.shift
269
+ while current
270
+ case current
271
+ when /^Examples/
272
+ parse_examples(current, sections)
273
+ when /^Yields/
274
+ parse_yields(current)
275
+ when /^(Returns|Raises)/
276
+ parse_returns(current)
277
+ when /^Signature/
278
+ parse_signature(current, sections)
279
+ end
280
+ current = sections.shift
281
+ end
282
+
283
+ return @parsed
81
284
  end
82
285
 
83
- def args
286
+ # Parse description.
287
+ #
288
+ # section - String containig description.
289
+ #
290
+ # Returns nothing.
291
+ def parse_description(section)
292
+ if md = /^([A-Z]\w+\:)/.match(section)
293
+ @status = md[1].chomp(':')
294
+ @description = md.post_match.strip
295
+ else
296
+ @description = section.strip
297
+ end
298
+ end
299
+
300
+ # Parse arguments section. Arguments occur subsequent to
301
+ # the description.
302
+ #
303
+ # section - String contaning agument definitions.
304
+ #
305
+ # Returns nothing.
306
+ def parse_arguments(section)
84
307
  args = []
85
308
  last_indent = nil
86
309
 
87
- return args unless sections[1]
88
-
89
- sections[1].split("\n").each do |line|
310
+ section.split("\n").each do |line|
90
311
  next if line.strip.empty?
91
312
  indent = line.scan(/^\s*/)[0].to_s.size
92
313
 
@@ -100,54 +321,117 @@ module TomDoc
100
321
  last_indent = indent
101
322
  end
102
323
 
103
- args
324
+ @arguments = args
104
325
  end
105
326
 
106
- def examples
107
- if tomdoc =~ /(\s*Examples\s*(.+?)\s*(?:Returns|Raises))/m
108
- $2.split("\n\n")
109
- else
110
- []
327
+ # Parse examples.
328
+ #
329
+ # section - String starting with `Examples`.
330
+ # sections - All sections subsequent to section.
331
+ #
332
+ # Returns nothing.
333
+ def parse_examples(section, sections)
334
+ examples = []
335
+
336
+ section = section.sub('Examples', '').strip
337
+
338
+ examples << section unless section.empty?
339
+ while sections.first && sections.first !~ /^\S/
340
+ examples << sections.shift.strip
111
341
  end
342
+
343
+ @examples = examples
112
344
  end
113
345
 
114
- def returns
115
- if tomdoc =~ /^\s*(Returns.+)/m
116
- lines = $1.split("\n")
117
- statements = []
118
-
119
- lines.each do |line|
120
- next if line =~ /^\s*Raises/
121
- if line =~ /^\s+/
122
- statements.last << line.squeeze(' ')
123
- else
124
- statements << line
125
- end
346
+ # Parse yields section.
347
+ #
348
+ # section - String contaning Yields line.
349
+ #
350
+ # Returns nothing.
351
+ def parse_yields(section)
352
+ @yields = section.strip
353
+ end
354
+
355
+ # Parse returns section.
356
+ #
357
+ # section - String contaning Returns and/or Raises lines.
358
+ #
359
+ # Returns nothing.
360
+ def parse_returns(section)
361
+ returns, raises, current = [], [], []
362
+
363
+ lines = section.split("\n")
364
+ lines.each do |line|
365
+ case line
366
+ when /^Returns/
367
+ returns << line
368
+ current = returns
369
+ when /^Raises/
370
+ raises << line
371
+ current = raises
372
+ when /^\s+/
373
+ current.last << line.squeeze(' ')
374
+ else
375
+ current << line # TODO: What to do with non-compliant line?
126
376
  end
377
+ end
127
378
 
128
- statements
129
- else
130
- []
379
+ @returns, @raises = returns, raises
380
+ end
381
+
382
+ # Parse signature section.
383
+ #
384
+ # section - String starting with `Signature`.
385
+ # sections - All sections subsequent to section.
386
+ #
387
+ # Returns nothing.
388
+ def parse_signature(section, sections=[])
389
+ signatures = []
390
+
391
+ section = section.sub('Signature', '').strip
392
+
393
+ signatures << section unless section.empty?
394
+
395
+ while sections.first && sections.first !~ /^\S/
396
+ sigs = sections.shift
397
+ sigs.split("\n").each do |s|
398
+ signatures << s.strip
399
+ end
400
+ end
401
+
402
+ @signatures = signatures
403
+
404
+ if sections.first && sections.first =~ /^\w+\s*\-/m
405
+ parse_signature_fields(sections.shift)
131
406
  end
132
407
  end
133
408
 
134
- def raises
135
- if tomdoc =~ /^\s*(Raises.+)/m
136
- lines = $1.split("\n")
137
- statements = []
138
-
139
- lines.each do |line|
140
- if line =~ /^\s+/
141
- statements.last << line.squeeze(' ')
142
- else
143
- statements << line
144
- end
409
+ # Subsequent to Signature section there can be field
410
+ # definitions.
411
+ #
412
+ # section - String subsequent to signatures.
413
+ #
414
+ # Returns nothing.
415
+ def parse_signature_fields(section)
416
+ args = []
417
+ last_indent = nil
418
+
419
+ section.split("\n").each do |line|
420
+ next if line.strip.empty?
421
+ indent = line.scan(/^\s*/)[0].to_s.size
422
+
423
+ if last_indent && indent > last_indent
424
+ args.last.description += line.squeeze(" ")
425
+ else
426
+ param, desc = line.split(" - ")
427
+ args << Arg.new(param.strip, desc.strip) if param && desc
145
428
  end
146
429
 
147
- statements
148
- else
149
- []
430
+ last_indent = indent
150
431
  end
432
+
433
+ @signature_fields = args
151
434
  end
435
+
152
436
  end
153
437
  end
@@ -1,3 +1,3 @@
1
1
  module TomDoc
2
- VERSION = '0.2.3'
2
+ VERSION = '0.2.4'
3
3
  end
@@ -46,6 +46,31 @@ comment2
46
46
  # multiplex('Bo', 2)
47
47
  # # => 'BoBo'
48
48
  comment3
49
+
50
+ @comment4 = TomDoc::TomDoc.new(<<comment4)
51
+ # Duplicate some text an abitrary number of times.
52
+ #
53
+ # Yields the Integer index of the iteration.
54
+ #
55
+ # Signature
56
+ #
57
+ # find_by_<field>[_and_<field>...](args)
58
+ #
59
+ # field - A field name.
60
+ comment4
61
+
62
+ @comment5 = TomDoc::TomDoc.new(<<comment5)
63
+ Duplicate some text an abitrary number of times.
64
+
65
+ Yields the Integer index of the iteration.
66
+
67
+ Signature
68
+
69
+ find_by_<field>[_and_<field>...](args)
70
+
71
+ field - A field name.
72
+ comment5
73
+
49
74
  end
50
75
 
51
76
  test "knows when TomDoc is invalid" do
@@ -92,7 +117,7 @@ comment3
92
117
  end
93
118
 
94
119
  test "knows each example" do
95
- assert_equal " multiplex('Bo', 2)\n # => 'BoBo'",
120
+ assert_equal "multiplex('Bo', 2)\n # => 'BoBo'",
96
121
  @comment.examples[1].to_s
97
122
  end
98
123
 
@@ -124,4 +149,26 @@ comment3
124
149
  test "knows what to do when there are no return examples" do
125
150
  assert_equal 0, @comment2.examples.size
126
151
  end
152
+
153
+ test "knows what the method yields" do
154
+ assert_equal "Yields the Integer index of the iteration.", @comment4.yields
155
+ end
156
+
157
+ test "knows if the method has alternate signatures" do
158
+ assert_equal 1, @comment4.signatures.size
159
+ assert_equal "find_by_<field>[_and_<field>...](args)", @comment4.signatures.first
160
+ end
161
+
162
+ test "knows the fields associated with signatures" do
163
+ assert_equal 1, @comment4.signature_fields.size
164
+
165
+ arg = @comment4.signature_fields.first
166
+ assert_equal :field, arg.name
167
+ assert_equal "A field name.", arg.description
168
+ end
169
+
170
+ test "can hande comments without comment marker" do
171
+ assert_equal "Duplicate some text an abitrary number of times.",
172
+ @comment5.description
173
+ end
127
174
  end
metadata CHANGED
@@ -1,62 +1,51 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: tomdoc
3
- version: !ruby/object:Gem::Version
4
- hash: 17
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.4
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 2
9
- - 3
10
- version: 0.2.3
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Tom Preston-Werner
14
9
  - Chris Wanstrath
15
10
  autorequire:
16
11
  bindir: bin
17
12
  cert_chain: []
18
-
19
- date: 2011-06-10 00:00:00 Z
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
13
+ date: 2012-02-22 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
22
16
  name: ruby_parser
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &18375600 !ruby/object:Gem::Requirement
25
18
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 7
30
- segments:
31
- - 2
32
- - 0
33
- - 4
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
34
22
  version: 2.0.4
35
23
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: colored
39
24
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ version_requirements: *18375600
26
+ - !ruby/object:Gem::Dependency
27
+ name: colored
28
+ requirement: &18375180 !ruby/object:Gem::Requirement
41
29
  none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- hash: 3
46
- segments:
47
- - 0
48
- version: "0"
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
49
34
  type: :runtime
50
- version_requirements: *id002
51
- description: " TomDoc is flexible code documentation with human readers in\n mind. The tomdoc gem is a Ruby library to discover and display\n TomDoc'd methods and classes.\n\n Given a Ruby file with TomDoc'd methods, tomdoc can generate HTML or\n print to the console. You can use it to query up a single method or\n a group of methods, and it's usable from irb.\n\n If you're using TomDoc, tomdoc is for you.\n"
35
+ prerelease: false
36
+ version_requirements: *18375180
37
+ description: ! " TomDoc is flexible code documentation with human readers in\n mind.
38
+ The tomdoc gem is a Ruby library to discover and display\n TomDoc'd methods and
39
+ classes.\n\n Given a Ruby file with TomDoc'd methods, tomdoc can generate HTML
40
+ or\n print to the console. You can use it to query up a single method or\n a group
41
+ of methods, and it's usable from irb.\n\n If you're using TomDoc, tomdoc is for
42
+ you.\n"
52
43
  email: chris@ozmm.org
53
- executables:
44
+ executables:
54
45
  - tomdoc
55
46
  extensions: []
56
-
57
47
  extra_rdoc_files: []
58
-
59
- files:
48
+ files:
60
49
  - README.md
61
50
  - Rakefile
62
51
  - LICENSE
@@ -86,36 +75,27 @@ files:
86
75
  - test/fixtures/simple.rb
87
76
  homepage: http://github.com/defunkt/tomdoc
88
77
  licenses: []
89
-
90
78
  post_install_message:
91
79
  rdoc_options: []
92
-
93
- require_paths:
80
+ require_paths:
94
81
  - lib
95
- required_ruby_version: !ruby/object:Gem::Requirement
82
+ required_ruby_version: !ruby/object:Gem::Requirement
96
83
  none: false
97
- requirements:
98
- - - ">="
99
- - !ruby/object:Gem::Version
100
- hash: 3
101
- segments:
102
- - 0
103
- version: "0"
104
- required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
89
  none: false
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- hash: 3
110
- segments:
111
- - 0
112
- version: "0"
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
113
94
  requirements: []
114
-
115
95
  rubyforge_project:
116
- rubygems_version: 1.8.2
96
+ rubygems_version: 1.8.11
117
97
  signing_key:
118
98
  specification_version: 3
119
99
  summary: A TomDoc library for Ruby.
120
100
  test_files: []
121
-
101
+ has_rdoc: false