From 2250694c32faf98abe846958382126b02eb453cd Mon Sep 17 00:00:00 2001 From: Ryan Tomayko Date: Tue, 9 Mar 2010 09:17:19 -0800 Subject: [PATCH] update generated doc --- index.html | 218 ++++++++++++++++++++++------------------------------- 1 file changed, 90 insertions(+), 128 deletions(-) diff --git a/index.html b/index.html index ced0938..8ec3ac0 100644 --- a/index.html +++ b/index.html @@ -41,67 +41,58 @@ for a set of Ruby source files:

rocco lib/*.rb
 
-

The HTML files are written to the current working directory.

- +

The HTML files are written to the current working directory.

- -

Prerequisites

- +

Prerequisites

- -

The rdiscount library is -required for Markdown processing.

- +

We’ll need a Markdown library. RDiscount, if we’re lucky. Otherwise, +issue a warning and fall back on using BlueCloth.

-
require 'rdiscount'
-
+
begin
+  require 'rdiscount'
+rescue LoadError => boom
+  warn "warn: #{boom}. trying bluecloth"
+  require 'bluecloth'
+  Markdown = BlueCloth
+end
- -

We use {{ mustache }} for -templating.

- +

We use {{ mustache }} for +HTML templating.

-
require 'mustache'
-
+
require 'mustache'
- -

Code is run through Pygments for syntax -highlighting. Fail fast if we can’t find the pygmentize program.

- +

Code is run through Pygments for syntax +highlighting. Fail fast right here if we can’t find the pygmentize +program on PATH.

if ! ENV['PATH'].split(':').any? { |dir| File.exist?("#{dir}/pygmentize") }
   fail "Pygments is required for syntax highlighting"
-end
-
+end - -

Public Interface

- +

Public Interface

- -

Rocco.new takes a source filename and an optional block. +

Rocco.new takes a source filename and an optional block. 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.

- +file is read to retrieve data.

class Rocco
   VERSION = '0.1'
@@ -113,64 +104,45 @@ file is read to retrieve data.

yield else File.read(filename) - end
+ end + @sections = highlight(split(parse(@data))) + end - -

Parsing and highlighting

- +

The filename as given to Rocco.new.

-
    @sections = highlight(parse(@data))
-  end
-
+
  attr_reader :file
- -

The filename as given to Rocco.new.

- +

A list of two-tuples representing each section of the source file. Each +item in the list has the form: [docs_html, code_html], where both +elements are strings containing the documentation and source code HTML, +respectively.

-
  attr_reader :file
-
+
  attr_reader :sections
- -

A list of two-tuples representing each section of the source file. Each -item in the list has the form: [docs_html, code_html], where both -elements are strings containing the documentation and source code HTML, -respectively.

- - -
  attr_reader :sections
-
- - - - -

Generate HTML output for the entire document.

- +

Generate HTML output for the entire document.

  require 'rocco/layout'
   def to_html
     Rocco::Layout.new(self).render
-  end
-
+ end - - -

Internal Parsing and Highlighting

- + +

Internal Parsing and Highlighting

- - -

Parse the raw file data into a list of two-tuples.

- + +

Parse the raw file data into a list of two-tuples. Each tuple has the +form [docs, code] where both elements are arrays containing the +raw lines parsed from the input file.

  def parse(data)
     sections = []
@@ -189,86 +161,76 @@ respectively.

end sections << [docs, code] if docs.any? || code.any? sections - end -
+ end - - -

Take the raw section data and apply markdown formatting and syntax -highlighting.

- + +

Take the list of paired sections two-tuples and split into two +separate lists: one holding the comments with leaders removed and +one with the code blocks.

-
  def highlight(sections)
- - - - -

Start by splitting the docs and codes blocks into two separate lists.

- - -
    docs_blocks, code_blocks = [], []
+        
  def split(sections)
+    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
-
+ [docs_blocks, code_blocks] + end
+ + + +

Take the result of split and apply Markdown formatting to comments and +syntax highlighting to source code.

+ +
  def highlight(blocks)
+    docs_blocks, code_blocks = blocks
+ + + +

Combine all docs blocks into a single big markdown document with section +dividers and run through the Markdown processor. Then split it back out +into separate sections.

+ +
    markdown = docs_blocks.join("\n\n##### DIVIDER\n\n")
+    docs_html = Markdown.new(markdown, :smart).
+      to_html.
+      split(/\n*<h5>DIVIDER<\/h5>\n*/m)
- -

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<h5>DIVIDER</h5>\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.

- +

Combine all code blocks into a single big stream and run through +Pygments. We popen a read/write pygmentize process in the parent and +then fork off a child process to write the input.

    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!
-      }
-
+      pid =
+        fork {
+          fd.close_read
+          fd.write code_blocks.join("\n\n# DIVIDER\n\n")
+          fd.close_write
+          exit!
+        }
       fd.close_write
       code_html = fd.read
       fd.close_read
-    end
-
+ Process.wait(pid) + end + + + +

Do some post-processing on the pygments output to split things back +into sections and remove partial <pre> blocks.

+ +
    code_html = code_html.
+      split(/\n*<span class="c1"># DIVIDER<\/span>\n*/m).
+      map { |code| code.sub(/\n?<div class="highlight"><pre>/m, '') }.
+      map { |code| code.sub(/\n?<\/pre><\/div>\n/m, '') }
- -

Do some post-processing on the pygments output to remove -partial <pre> blocks. We’ll add these back when we build to main -document.

- - -
    code_html = code_html.
-      split(/\n?<span class="c1"># DIVIDER<\/span>\n?/m).
-      map { |code| code.sub(/\n?<div class="highlight"><pre>/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.

+

Lastly, combine the docs and code lists back into a list of two-tuples.

    docs_html.zip(code_html)