use mustache for layout
This commit is contained in:
parent
7b0f7d31fd
commit
5eca6cdc9b
164
lib/rocco.rb
164
lib/rocco.rb
@ -9,8 +9,8 @@
|
|||||||
require 'rdiscount'
|
require 'rdiscount'
|
||||||
|
|
||||||
class Rocco
|
class Rocco
|
||||||
# `Rocco.new` takes a `filename` and an optional `block` used to read
|
# `Rocco.new` takes a source `filename` and an optional `block` used to
|
||||||
# the file's contents. When `block` is given, it must read the contents
|
# 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.
|
# of the file using whatever means necessary and return it as a string.
|
||||||
# With no `block`, the file is read to retrieve data.
|
# With no `block`, the file is read to retrieve data.
|
||||||
def initialize(filename, &block)
|
def initialize(filename, &block)
|
||||||
@ -26,100 +26,98 @@ class Rocco
|
|||||||
@sections = highlight(parse(@data))
|
@sections = highlight(parse(@data))
|
||||||
end
|
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.
|
# Internal Parsing and Highlighting
|
||||||
def parse(data)
|
# ---------------------------------
|
||||||
sections = []
|
protected
|
||||||
docs, code = [], []
|
|
||||||
data.split("\n").each do |line|
|
# Parse the raw file data into a list of two-tuples.
|
||||||
case line
|
def parse(data)
|
||||||
when /^\s*#/
|
sections = []
|
||||||
if code.any?
|
docs, code = [], []
|
||||||
sections << [docs, code]
|
data.split("\n").each do |line|
|
||||||
docs, code = [], []
|
case line
|
||||||
end
|
when /^\s*#/
|
||||||
docs << line
|
if code.any?
|
||||||
when /^\s*$/
|
sections << [docs, code]
|
||||||
if code.any?
|
docs, code = [], []
|
||||||
code << line
|
end
|
||||||
else
|
|
||||||
docs << line
|
docs << line
|
||||||
|
when /^\s*$/
|
||||||
|
if code.any?
|
||||||
|
code << line
|
||||||
|
else
|
||||||
|
docs << line
|
||||||
|
end
|
||||||
|
else
|
||||||
|
code << line
|
||||||
end
|
end
|
||||||
else
|
|
||||||
code << line
|
|
||||||
end
|
end
|
||||||
end
|
sections << [docs, code] if docs.any? || code.any?
|
||||||
sections << [docs, code] if docs.any? || code.any?
|
sections
|
||||||
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")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Combine all docs blocks into a single big markdown document and run
|
# Take the raw section data and apply markdown formatting and syntax
|
||||||
# through RDiscount. Then split it back out into separate sections.
|
# highlighting.
|
||||||
markdown = docs_blocks.join("\n##### DIVIDER\n")
|
def highlight(sections)
|
||||||
docs_html = Markdown.new(markdown, :smart).
|
# Start by splitting the docs and codes blocks into two separate lists.
|
||||||
to_html.
|
docs_blocks, code_blocks = [], []
|
||||||
split("\n<h5>DIVIDER</h5>\n")
|
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<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.
|
||||||
|
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
|
fd.close_write
|
||||||
exit!
|
code_html = fd.read
|
||||||
}
|
fd.close_read
|
||||||
|
end
|
||||||
|
|
||||||
fd.close_write
|
# Do some post-processing on the pygments output to remove
|
||||||
code_html = fd.read
|
# partial `<pre>` blocks. We'll add these back when we build to main
|
||||||
fd.close_read
|
# 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.
|
||||||
|
docs_html.zip(code_html)
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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.
|
|
||||||
docs_html.zip(code_html)
|
|
||||||
end
|
|
||||||
|
|
||||||
public
|
public
|
||||||
|
require 'rocco/layout'
|
||||||
|
|
||||||
def to_html
|
def to_html
|
||||||
buf = []
|
Rocco::Layout.new(self).render
|
||||||
buf << "<!DOCTYPE html>"
|
|
||||||
buf << "<head>"
|
|
||||||
buf << "<style>table td{vertical-align:top;padding:10px;}\npre{background:#fff;overflow-x:auto}</style>"
|
|
||||||
buf << "<link rel=stylesheet href='http://github.com/richleland/pygments-css/raw/master/default.css'>"
|
|
||||||
buf << "</head>"
|
|
||||||
buf << "<table width=100%>"
|
|
||||||
@sections.each do |docs,code|
|
|
||||||
buf << "<tr>"
|
|
||||||
buf << "<td width=50%>#{docs}</td>"
|
|
||||||
buf << "<td width=50%><div class='highlight codehilite'><pre>#{code}</pre></div></td>"
|
|
||||||
buf << "</tr>"
|
|
||||||
end
|
|
||||||
buf << "</table>"
|
|
||||||
buf.join("\n")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
28
lib/rocco/layout.mustache
Normal file
28
lib/rocco/layout.mustache
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
||||||
|
<title>{{ title }}</title>
|
||||||
|
<link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='container'>
|
||||||
|
<table cellspacing=0 cellpadding=0>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class=docs><h1>{{ title }}</h1></th>
|
||||||
|
<th class=code></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#sections}}
|
||||||
|
<tr id='section-{{ num }}'>
|
||||||
|
<td class=docs>{{{ docs }}}</td>
|
||||||
|
<td class=code>
|
||||||
|
<div class='highlight'><pre>{{{ code }}}</pre></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/sections}}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
24
lib/rocco/layout.rb
Normal file
24
lib/rocco/layout.rb
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user