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 << ""
-      buf << ""
-      buf << ""
-    end
-    buf << "
#{docs}
#{code}
" - 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 }} + + + +
+ + + + + + + + + {{#sections}} + + + + + {{/sections}} +

{{ title }}

{{{ docs }}} +
{{{ code }}}
+
+
+ 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