rocco 0.3 → 0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -22,7 +22,7 @@ end
22
22
 
23
23
  # Bring in Rocco tasks
24
24
  require 'rocco/tasks'
25
- Rocco::make 'docs/', FileList['lib/**/*.rb', 'bin/rocco']
25
+ Rocco::make 'docs/'
26
26
 
27
27
  desc 'Build rocco docs'
28
28
  task :docs => :rocco
data/bin/rocco CHANGED
@@ -1,15 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
- # The `rocco(1)` executable.
3
- #
4
- # This isn't documented yet.
5
- #
6
- #/ Usage: rocco [-o <dir>] <file>...
2
+ #/ Usage: rocco [-l <lang>] [-c <chars>] [-o <dir>] <file>...
7
3
  #/ Generate literate-programming-style documentation for Ruby source <file>s.
8
4
  #/
9
5
  #/ Options:
10
- #/ -o, --output=<dir> Directory where generated HTML files are written
6
+ #/ -l, --language=<lang> The Pygments lexer to use to highlight code
7
+ #/ -c, --comment-chars=<chars>
8
+ #/ The string to recognize as a comment marker
9
+ #/ -o, --output=<dir> Directory where generated HTML files are written
11
10
  #/
12
- #/ --help Show this help message
11
+ #/ --help Show this help message
13
12
 
14
13
  require 'optparse'
15
14
 
@@ -32,9 +31,12 @@ end
32
31
  # Parse command line options, aborting if anything goes wrong.
33
32
  output_dir = '.'
34
33
  sources = []
34
+ options = {}
35
35
  ARGV.options { |o|
36
36
  o.program_name = File.basename($0)
37
37
  o.on("-o", "--output=DIR") { |dir| output_dir = dir }
38
+ o.on("-l", "--language=LANG") { |lang| options[:language] = lang }
39
+ o.on("-c", "--comment-chars=CHARS") { |chars| options[:comment_chars] = Regexp.escape(chars) }
38
40
  o.on_tail("-h", "--help") { usage($stdout, 0) }
39
41
  o.parse!
40
42
  } or abort_with_note
@@ -80,8 +82,8 @@ Dir.mkdir output_dir if !File.directory?(output_dir)
80
82
 
81
83
  # Run each file through Rocco and write output.
82
84
  sources.each do |filename|
83
- rocco = Rocco.new(filename, sources)
84
- dest = File.join(output_dir, File.basename(filename, '.rb') + '.html')
85
+ rocco = Rocco.new(filename, sources, options)
86
+ dest = filename.split('.')[0..-2].join('.') + '.html'
85
87
  puts "rocco: #{filename} -> #{dest}"
86
88
  File.open(dest, 'wb') { |fd| fd.write(rocco.to_html) }
87
89
  end
@@ -57,13 +57,18 @@ end
57
57
  #### Public Interface
58
58
 
59
59
  # `Rocco.new` takes a source `filename`, an optional list of source filenames
60
- # for other documentation sources, and an optional `block`. When `block` is
61
- # given, it must read the contents of the file using whatever means necessary
62
- # and return it as a string. With no `block`, the file is read to retrieve data.
60
+ # for other documentation sources, an `options` hash, and an optional `block`.
61
+ # The `options` hash respects two members: `:language`, which specifies which
62
+ # Pygments lexer to use; and `:comment_chars`, which specifies the comment
63
+ # characters of the target language. The options default to `'ruby'` and `'#'`,
64
+ # respectively.
65
+ # When `block` is given, it must read the contents of the file using whatever
66
+ # means necessary and return it as a string. With no `block`, the file is read
67
+ # to retrieve data.
63
68
  class Rocco
64
- VERSION = '0.3'
69
+ VERSION = '0.4'
65
70
 
66
- def initialize(filename, sources=[], &block)
71
+ def initialize(filename, sources=[], options={}, &block)
67
72
  @file = filename
68
73
  @data =
69
74
  if block_given?
@@ -71,7 +76,10 @@ class Rocco
71
76
  else
72
77
  File.read(filename)
73
78
  end
79
+ defaults = { :language => 'ruby', :comment_chars => '#' }
80
+ @options = defaults.merge(options)
74
81
  @sources = sources
82
+ @comment_pattern = Regexp.new("^\\s*#{@options[:comment_chars]}")
75
83
  @sections = highlight(split(parse(@data)))
76
84
  end
77
85
 
@@ -98,13 +106,16 @@ class Rocco
98
106
 
99
107
  # Parse the raw file data into a list of two-tuples. Each tuple has the
100
108
  # form `[docs, code]` where both elements are arrays containing the
101
- # raw lines parsed from the input file.
109
+ # raw lines parsed from the input file. The first line is ignored if it
110
+ # is a shebang line.
102
111
  def parse(data)
103
112
  sections = []
104
113
  docs, code = [], []
105
- data.split("\n").each do |line|
114
+ lines = data.split("\n")
115
+ lines.shift if lines[0] =~ /^\#\!/
116
+ lines.each do |line|
106
117
  case line
107
- when /^\s*#(?:\s+|$)/
118
+ when @comment_pattern
108
119
  if code.any?
109
120
  sections << [docs, code]
110
121
  docs, code = [], []
@@ -124,8 +135,11 @@ class Rocco
124
135
  def split(sections)
125
136
  docs_blocks, code_blocks = [], []
126
137
  sections.each do |docs,code|
127
- docs_blocks << docs.map { |line| line.sub(/^\s*#\s?/, '') }.join("\n")
128
- code_blocks << code.join("\n")
138
+ docs_blocks << docs.map { |line| line.sub(@comment_pattern, '') }.join("\n")
139
+ code_blocks << code.map do |line|
140
+ tabs = line.match(/^(\t+)/)
141
+ tabs ? line.sub(/^\t+/, ' ' * tabs.captures[0].length) : line
142
+ end.join("\n")
129
143
  end
130
144
  [docs_blocks, code_blocks]
131
145
  end
@@ -147,7 +161,7 @@ class Rocco
147
161
  # Pygments. We `popen` a read/write pygmentize process in the parent and
148
162
  # then fork off a child process to write the input.
149
163
  code_html = nil
150
- open("|pygmentize -l ruby -f html", 'r+') do |fd|
164
+ open("|pygmentize -l #{@options[:language]} -f html", 'r+') do |fd|
151
165
  pid =
152
166
  fork {
153
167
  fd.close_read
@@ -31,7 +31,7 @@ class Rocco::Layout < Mustache
31
31
  {
32
32
  :path => source,
33
33
  :basename => File.basename(source),
34
- :url => File.basename(source, '.rb') + '.html'
34
+ :url => File.basename(source).split('.')[0..-2].join('.') + '.html'
35
35
  }
36
36
  end
37
37
  end
@@ -33,6 +33,15 @@
33
33
  #
34
34
  # Rocco::make 'html/', ['lib/thing.rb', 'lib/thing/*.rb']
35
35
  #
36
+ # Finally, it is also possible to specify which Pygments language you would
37
+ # like to use to highlight the code, as well as the comment characters for the
38
+ # language in the `options` hash:
39
+ #
40
+ # Rocco::make 'html/', 'lib/thing/**/*.rb', {
41
+ # :language => 'io',
42
+ # :comment_chars => '#'
43
+ # }
44
+ #
36
45
 
37
46
  # Might be nice to defer this until we actually need to build docs but this
38
47
  # will have to do for now.
@@ -42,17 +51,18 @@ require 'rocco'
42
51
  # of sugar over `Rocco::Task.new`. If you want your Rake task to be named
43
52
  # something other than `:rocco`, you can use `Rocco::Task` directly.
44
53
  class Rocco
45
- def self.make(dest='docs/', source_files='lib/**/*.rb')
46
- Task.new(:rocco, dest, source_files)
54
+ def self.make(dest='docs/', source_files='lib/**/*.rb', options={})
55
+ Task.new(:rocco, dest, source_files, options)
47
56
  end
48
57
 
49
58
  # `Rocco::Task.new` takes a task name, the destination directory docs
50
59
  # should be built under, and a source file pattern or file list.
51
60
  class Task
52
- def initialize(task_name, dest='docs/', sources='lib/**/*.rb')
61
+ def initialize(task_name, dest='docs/', sources='lib/**/*.rb', options={})
53
62
  @name = task_name
54
63
  @dest = dest[-1] == ?/ ? dest : "#{dest}/"
55
64
  @sources = FileList[sources]
65
+ @options = options
56
66
 
57
67
  # Make sure there's a `directory` task defined for our destination.
58
68
  define_directory_task @dest
@@ -60,7 +70,7 @@ class Rocco
60
70
  # Run over the source file list, constructing destination filenames
61
71
  # and defining file tasks.
62
72
  @sources.each do |source_file|
63
- dest_file = File.basename(source_file, '.rb') + '.html'
73
+ dest_file = File.basename(source_file).split('.')[0..-2].join('.') + '.html'
64
74
  define_file_task source_file, "#{@dest}#{dest_file}"
65
75
 
66
76
  # If `rake/clean` was required, add the generated files to the list.
@@ -92,7 +102,7 @@ class Rocco
92
102
  prerequisites = [@dest, source_file] + rocco_source_files
93
103
  file dest_file => prerequisites do |f|
94
104
  verbose { puts "rocco: #{source_file} -> #{dest_file}" }
95
- rocco = Rocco.new(source_file, @sources.to_a)
105
+ rocco = Rocco.new(source_file, @sources.to_a, @options)
96
106
  File.open(dest_file, 'wb') { |fd| fd.write(rocco.to_html) }
97
107
  end
98
108
  task @name => dest_file
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'rocco'
6
- s.version = '0.3'
7
- s.date = '2010-03-16'
6
+ s.version = '0.4'
7
+ s.date = '2010-03-19'
8
8
 
9
9
  s.description = "Docco in Ruby"
10
10
  s.summary = s.description
metadata CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 3
8
- version: "0.3"
7
+ - 4
8
+ version: "0.4"
9
9
  platform: ruby
10
10
  authors:
11
11
  - Ryan Tomayko
@@ -13,7 +13,7 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2010-03-16 00:00:00 -07:00
16
+ date: 2010-03-19 00:00:00 -07:00
17
17
  default_executable:
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency