rocco 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/bin/rocco +11 -9
- data/lib/rocco.rb +25 -11
- data/lib/rocco/layout.rb +1 -1
- data/lib/rocco/tasks.rb +15 -5
- data/rocco.gemspec +2 -2
- metadata +3 -3
data/Rakefile
CHANGED
data/bin/rocco
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
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
|
-
#/ -
|
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
|
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 =
|
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
|
data/lib/rocco.rb
CHANGED
@@ -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`.
|
61
|
-
#
|
62
|
-
#
|
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.
|
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")
|
114
|
+
lines = data.split("\n")
|
115
|
+
lines.shift if lines[0] =~ /^\#\!/
|
116
|
+
lines.each do |line|
|
106
117
|
case line
|
107
|
-
when
|
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(
|
128
|
-
code_blocks << code.
|
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
|
164
|
+
open("|pygmentize -l #{@options[:language]} -f html", 'r+') do |fd|
|
151
165
|
pid =
|
152
166
|
fork {
|
153
167
|
fd.close_read
|
data/lib/rocco/layout.rb
CHANGED
data/lib/rocco/tasks.rb
CHANGED
@@ -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
|
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
|
data/rocco.gemspec
CHANGED
@@ -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.
|
7
|
-
s.date = '2010-03-
|
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
|
-
-
|
8
|
-
version: "0.
|
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
|
+
date: 2010-03-19 00:00:00 -07:00
|
17
17
|
default_executable:
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|