Merge a bunch of stuff from burke/master
This commit is contained in:
commit
957e5cf197
@ -7,7 +7,6 @@
|
|||||||
#/ -c, --comment-chars=<chars>
|
#/ -c, --comment-chars=<chars>
|
||||||
#/ The string to recognize as a comment marker
|
#/ The string to recognize as a comment marker
|
||||||
#/ -o, --output=<dir> Directory where generated HTML files are written
|
#/ -o, --output=<dir> Directory where generated HTML files are written
|
||||||
#/
|
|
||||||
#/ --help Show this help message
|
#/ --help Show this help message
|
||||||
|
|
||||||
require 'optparse'
|
require 'optparse'
|
||||||
@ -42,6 +41,14 @@ ARGV.options { |o|
|
|||||||
o.parse!
|
o.parse!
|
||||||
} or abort_with_note
|
} or abort_with_note
|
||||||
|
|
||||||
|
# Use http://pygments.appspot.com in case `pygmentize(1)` isn't available.
|
||||||
|
if ! ENV['PATH'].split(':').any? { |dir| File.exist?("#{dir}/pygmentize") }
|
||||||
|
unless options[:webservice]
|
||||||
|
$stderr.puts "pygmentize not in PATH; using pygments.appspot.com instead"
|
||||||
|
options[:webservice] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Eat sources from ARGV.
|
# Eat sources from ARGV.
|
||||||
sources << ARGV.shift while ARGV.any?
|
sources << ARGV.shift while ARGV.any?
|
||||||
|
|
||||||
|
65
lib/rocco.rb
65
lib/rocco.rb
@ -38,7 +38,7 @@
|
|||||||
begin
|
begin
|
||||||
require 'rdiscount'
|
require 'rdiscount'
|
||||||
rescue LoadError => boom
|
rescue LoadError => boom
|
||||||
warn "warn: #{boom}. trying bluecloth"
|
warn "WARNING: #{boom}. Trying bluecloth."
|
||||||
require 'bluecloth'
|
require 'bluecloth'
|
||||||
Markdown = BlueCloth
|
Markdown = BlueCloth
|
||||||
end
|
end
|
||||||
@ -47,11 +47,13 @@ end
|
|||||||
# HTML templating.
|
# HTML templating.
|
||||||
require 'mustache'
|
require 'mustache'
|
||||||
|
|
||||||
|
# We use `Net::HTTP` to highlight code via <http://pygments.appspot.com>
|
||||||
|
require 'net/http'
|
||||||
|
|
||||||
# Code is run through [Pygments](http://pygments.org/) for syntax
|
# Code is run through [Pygments](http://pygments.org/) for syntax
|
||||||
# highlighting. Fail fast right here if we can't find the `pygmentize`
|
# highlighting. If it's not installed, locally, use a webservice.
|
||||||
# program on PATH.
|
if `which pygmentize`.blank?
|
||||||
if ! ENV['PATH'].split(':').any? { |dir| File.exist?("#{dir}/pygmentize") }
|
warn "WARNING: Pygments not found. Using webservice."
|
||||||
fail "Pygments is required for syntax highlighting"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#### Public Interface
|
#### Public Interface
|
||||||
@ -76,7 +78,10 @@ class Rocco
|
|||||||
else
|
else
|
||||||
File.read(filename)
|
File.read(filename)
|
||||||
end
|
end
|
||||||
defaults = { :language => 'ruby', :comment_chars => '#' }
|
defaults = {
|
||||||
|
:language => 'ruby',
|
||||||
|
:comment_chars => '#',
|
||||||
|
}
|
||||||
@options = defaults.merge(options)
|
@options = defaults.merge(options)
|
||||||
@sources = sources
|
@sources = sources
|
||||||
@comment_pattern = Regexp.new("^\\s*#{@options[:comment_chars]}")
|
@comment_pattern = Regexp.new("^\\s*#{@options[:comment_chars]}")
|
||||||
@ -157,15 +162,36 @@ class Rocco
|
|||||||
to_html.
|
to_html.
|
||||||
split(/\n*<h5>DIVIDER<\/h5>\n*/m)
|
split(/\n*<h5>DIVIDER<\/h5>\n*/m)
|
||||||
|
|
||||||
# Combine all code blocks into a single big stream and run through
|
# Combine all code blocks into a single big stream and run through either
|
||||||
# Pygments. We `popen` a read/write pygmentize process in the parent and
|
# `pygmentize(1)` or <http://pygments.appspot.com>
|
||||||
# then fork off a child process to write the input.
|
code_stream = code_blocks.join("\n\n#{@options[:comment_chars]} DIVIDER\n\n")
|
||||||
|
|
||||||
|
if `which pygmentize`.blank?
|
||||||
|
code_html = highlight_webservice(code_stream)
|
||||||
|
else
|
||||||
|
code_html = highlight_pygmentize(code_stream)
|
||||||
|
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="c.">#{@options[:comment_chars]} DIVIDER<\/span>\n*/m).
|
||||||
|
map { |code| code.sub(/\n?<div class="highlight"><pre>/m, '') }.
|
||||||
|
map { |code| code.sub(/\n?<\/pre><\/div>\n/m, '') }
|
||||||
|
|
||||||
|
# Lastly, combine the docs and code lists back into a list of two-tuples.
|
||||||
|
docs_html.zip(code_html)
|
||||||
|
end
|
||||||
|
|
||||||
|
# We `popen` a read/write pygmentize process in the parent and
|
||||||
|
# then fork off a child process to write the input.
|
||||||
|
def highlight_pygmentize(code)
|
||||||
code_html = nil
|
code_html = nil
|
||||||
open("|pygmentize -l #{@options[:language]} -f html", 'r+') do |fd|
|
open("|pygmentize -l #{@options[:language]} -f html", 'r+') do |fd|
|
||||||
pid =
|
pid =
|
||||||
fork {
|
fork {
|
||||||
fd.close_read
|
fd.close_read
|
||||||
fd.write code_blocks.join("\n\n# DIVIDER\n\n")
|
fd.write code
|
||||||
fd.close_write
|
fd.close_write
|
||||||
exit!
|
exit!
|
||||||
}
|
}
|
||||||
@ -175,15 +201,16 @@ class Rocco
|
|||||||
Process.wait(pid)
|
Process.wait(pid)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Do some post-processing on the pygments output to split things back
|
code_html
|
||||||
# into sections and remove partial `<pre>` blocks.
|
end
|
||||||
code_html = code_html.
|
|
||||||
split(/\n*<span class="c1"># DIVIDER<\/span>\n*/m).
|
# Pygments is not one of those things that's trivial for a ruby user to install,
|
||||||
map { |code| code.sub(/\n?<div class="highlight"><pre>/m, '') }.
|
# so we'll fall back on a webservice to highlight the code if it isn't available.
|
||||||
map { |code| code.sub(/\n?<\/pre><\/div>\n/m, '') }
|
def highlight_webservice(code)
|
||||||
|
Net::HTTP.post_form(
|
||||||
# Lastly, combine the docs and code lists back into a list of two-tuples.
|
URI.parse('http://pygments.appspot.com/'),
|
||||||
docs_html.zip(code_html)
|
{'lang' => @options['language'], 'code' => code}
|
||||||
|
).body
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user