diff --git a/lib/rocco.rb b/lib/rocco.rb
index 2debdee..7bd1ca0 100644
--- a/lib/rocco.rb
+++ b/lib/rocco.rb
@@ -9,8 +9,8 @@
require 'rdiscount'
class Rocco
- # `Rocco.new` takes a `filename` and an optional `block` used to read
- # the file's contents. When `block` is given, it must read the contents
+ # `Rocco.new` takes a source `filename` and an optional `block` used to
+ # read the file's contents. When `block` is given, it must read the contents
# of the file using whatever means necessary and return it as a string.
# With no `block`, the file is read to retrieve data.
def initialize(filename, &block)
@@ -26,100 +26,98 @@ class Rocco
@sections = highlight(parse(@data))
end
-# Internal Parsing and Highlighting
-# ---------------------------------
+ # The source filename.
+ attr_reader :file
-protected
+ # A list of two-tuples representing each *section* of the source file. Each
+ # item in the list has the form `[docs_html, code_html]` and represents a
+ # single section.
+ #
+ # Both `docs_html` and `code_html` are strings containing the
+ # documentation and source code HTML, respectively.
+ attr_reader :sections
- # Parse the raw file data into a list of two-tuples.
- def parse(data)
- sections = []
- docs, code = [], []
- data.split("\n").each do |line|
- case line
- when /^\s*#/
- if code.any?
- sections << [docs, code]
- docs, code = [], []
- end
- docs << line
- when /^\s*$/
- if code.any?
- code << line
- else
+ # Internal Parsing and Highlighting
+ # ---------------------------------
+ protected
+
+ # Parse the raw file data into a list of two-tuples.
+ def parse(data)
+ sections = []
+ docs, code = [], []
+ data.split("\n").each do |line|
+ case line
+ when /^\s*#/
+ if code.any?
+ sections << [docs, code]
+ docs, code = [], []
+ end
docs << line
+ when /^\s*$/
+ if code.any?
+ code << line
+ else
+ docs << line
+ end
+ else
+ code << line
end
- else
- code << line
end
- end
- sections << [docs, code] if docs.any? || code.any?
- sections
- end
-
- # Take the raw section data and apply markdown formatting and syntax
- # highlighting.
- def highlight(sections)
- # Start by splitting the docs and codes blocks into two separate lists.
- docs_blocks, code_blocks = [], []
- sections.each do |docs,code|
- docs_blocks << docs.map { |line| line.sub(/^\s*#\s?/, '') }.join("\n")
- code_blocks << code.join("\n")
+ sections << [docs, code] if docs.any? || code.any?
+ sections
end
- # Combine all docs blocks into a single big markdown document and run
- # through RDiscount. Then split it back out into separate sections.
- markdown = docs_blocks.join("\n##### DIVIDER\n")
- docs_html = Markdown.new(markdown, :smart).
- to_html.
- split("\n
DIVIDER
\n")
+ # Take the raw section data and apply markdown formatting and syntax
+ # highlighting.
+ def highlight(sections)
+ # Start by splitting the docs and codes blocks into two separate lists.
+ docs_blocks, code_blocks = [], []
+ sections.each do |docs,code|
+ docs_blocks << docs.map { |line| line.sub(/^\s*#\s?/, '') }.join("\n")
+ code_blocks << code.join("\n")
+ end
+
+ # Combine all docs blocks into a single big markdown document and run
+ # through RDiscount. Then split it back out into separate sections.
+ markdown = docs_blocks.join("\n##### DIVIDER\n")
+ docs_html = Markdown.new(markdown, :smart).
+ to_html.
+ split("\n
DIVIDER
\n")
+
+ # Combine all code blocks into a single big stream and run through
+ # pygments. We `popen` a pygmentize process and then fork off a
+ # writer process.
+ code_html = nil
+ open("|pygmentize -l ruby -f html", 'r+') do |fd|
+ fork {
+ fd.close_read
+ fd.write code_blocks.join("\n# DIVIDER\n")
+ fd.close_write
+ exit!
+ }
- # Combine all code blocks into a single big stream and run through
- # pygments. We `popen` a pygmentize process and then fork off a
- # writer process.
- code_html = nil
- open("|pygmentize -l ruby -f html", 'r+') do |fd|
- fork {
- fd.close_read
- fd.write code_blocks.join("\n# DIVIDER\n")
fd.close_write
- exit!
- }
+ code_html = fd.read
+ fd.close_read
+ end
- fd.close_write
- code_html = fd.read
- fd.close_read
+ # Do some post-processing on the pygments output to remove
+ # partial `
` blocks. We'll add these back when we build to main
+ # document.
+ code_html = code_html.
+ split(/\n*# DIVIDER<\/span>\n*/m).
+ map { |code| code.sub(/\n?
/m, '') }.
+ map { |code| code.sub(/\n?<\/pre><\/div>\n/m, '') }
+
+ # Combine the docs and code lists into the same sections style list we
+ # started with.
+ docs_html.zip(code_html)
end
- # Do some post-processing on the pygments output to remove
- # partial `
` blocks. We'll add these back when we build to main
- # document.
- code_html = code_html.
- split(/\n*# DIVIDER<\/span>\n*/m).
- map { |code| code.sub(/\n?
/m, '') }.
- map { |code| code.sub(/\n?<\/pre><\/div>\n/m, '') }
-
- # Combine the docs and code lists into the same sections style list we
- # started with.
- docs_html.zip(code_html)
- end
-
public
+ require 'rocco/layout'
+
def to_html
- buf = []
- buf << ""
- buf << ""
- buf << ""
- buf << ""
- buf << ""
- buf << "
"
- @sections.each do |docs,code|
- buf << "
"
- buf << "
#{docs}
"
- buf << "
#{code}
"
- buf << "
"
- end
- buf << "
"
- buf.join("\n")
+ Rocco::Layout.new(self).render
end
end
diff --git a/lib/rocco/layout.mustache b/lib/rocco/layout.mustache
new file mode 100644
index 0000000..999f33b
--- /dev/null
+++ b/lib/rocco/layout.mustache
@@ -0,0 +1,28 @@
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
{{ title }}
+
+
+
+
+ {{#sections}}
+
+
{{{ docs }}}
+
+
{{{ code }}}
+
+
+ {{/sections}}
+
+
+
diff --git a/lib/rocco/layout.rb b/lib/rocco/layout.rb
new file mode 100644
index 0000000..9711ee4
--- /dev/null
+++ b/lib/rocco/layout.rb
@@ -0,0 +1,24 @@
+require 'mustache'
+
+class Rocco::Layout < Mustache
+ self.template_path = File.dirname(__FILE__)
+
+ def initialize(doc)
+ @doc = doc
+ end
+
+ def title
+ @doc.file
+ end
+
+ def sections
+ num = 0
+ @doc.sections.map do |docs,code|
+ {
+ :docs => docs,
+ :code => code,
+ :num => (num += 1)
+ }
+ end
+ end
+end