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 +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
|