allow to use pygments.appspot.com instead of pygmentize(1)

This commit is contained in:
Simon Rozet 2010-03-19 15:53:51 -07:00
parent 545fd53b88
commit bc8bdccb7d
2 changed files with 57 additions and 24 deletions

View File

@ -7,6 +7,9 @@
#/ -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
#/ -w Highlight code using http://pygments.appspot.com
#/ instead of pygmentize(1)
#/
#/ #/
#/ --help Show this help message #/ --help Show this help message
@ -37,10 +40,19 @@ ARGV.options { |o|
o.on("-o", "--output=DIR") { |dir| output_dir = dir } o.on("-o", "--output=DIR") { |dir| output_dir = dir }
o.on("-l", "--language=LANG") { |lang| options[:language] = lang } o.on("-l", "--language=LANG") { |lang| options[:language] = lang }
o.on("-c", "--comment-chars=CHARS") { |chars| options[:comment_chars] = Regexp.escape(chars) } o.on("-c", "--comment-chars=CHARS") { |chars| options[:comment_chars] = Regexp.escape(chars) }
o.on("-w") { |v| options[:webservice] = v }
o.on_tail("-h", "--help") { usage($stdout, 0) } o.on_tail("-h", "--help") { usage($stdout, 0) }
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?

View File

@ -47,12 +47,8 @@ end
# HTML templating. # HTML templating.
require 'mustache' require 'mustache'
# Code is run through [Pygments](http://pygments.org/) for syntax # We use `Net::HTTP` to highlight code via <http://pygments.appspot.com>
# highlighting. Fail fast right here if we can't find the `pygmentize` require 'net/http'
# program on PATH.
if ! ENV['PATH'].split(':').any? { |dir| File.exist?("#{dir}/pygmentize") }
fail "Pygments is required for syntax highlighting"
end
#### Public Interface #### Public Interface
@ -76,7 +72,11 @@ class Rocco
else else
File.read(filename) File.read(filename)
end end
defaults = { :language => 'ruby', :comment_chars => '#' } defaults = {
:language => 'ruby',
:comment_chars => '#',
:webservice => false
}
@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,22 +157,15 @@ 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# DIVIDER\n\n")
code_html = nil
open("|pygmentize -l #{@options[:language]} -f html", 'r+') do |fd| code_html =
pid = if @options[:webservice]
fork { highlight_webservice(code_stream)
fd.close_read else
fd.write code_blocks.join("\n\n# DIVIDER\n\n") highlight_pygmentize(code_stream)
fd.close_write
exit!
}
fd.close_write
code_html = fd.read
fd.close_read
Process.wait(pid)
end end
# Do some post-processing on the pygments output to split things back # Do some post-processing on the pygments output to split things back
@ -185,6 +178,34 @@ class Rocco
# Lastly, combine the docs and code lists back into a list of two-tuples. # Lastly, combine the docs and code lists back into a list of two-tuples.
docs_html.zip(code_html) docs_html.zip(code_html)
end 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
open("|pygmentize -l #{@options[:language]} -f html", 'r+') do |fd|
pid =
fork {
fd.close_read
fd.write code
fd.close_write
exit!
}
fd.close_write
code_html = fd.read
fd.close_read
Process.wait(pid)
end
code_html
end
def highlight_webservice(code)
Net::HTTP.post_form(
URI.parse('http://pygments.appspot.com/'),
{'lang' => 'ruby', 'code' => code}
).body
end
end end
# And that's it. # And that's it.