1#!/usr/bin/env ruby 2# $originalId: ruby2html.rb,v 1.2 2005/09/23 22:53:47 aamine Exp $ 3 4TEMPLATE_LINE = __LINE__ + 2 5TEMPLATE = <<-EndTemplate 6<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 7<html> 8<head> 9 <meta http-equiv="Content-Type" content="text/html; charset=<%= encoding %>"> 10<% if css %> 11 <link rel="stylesheet" type="text/css" href="<%= css %>"> 12<% end %> 13 <title><%= File.basename(f.path) %></title> 14</head> 15<body> 16<pre> 17<% 18 if print_line_number 19 Ruby2HTML.compile(f).each_with_index do |line, idx| 20%><%= sprintf('%4d %s', idx+1, line) %><% 21 end 22 else 23%><%= Ruby2HTML.compile(f) %><% 24 end 25%> 26</pre> 27</body> 28</html> 29EndTemplate 30 31require 'ripper' 32require 'stringio' 33require 'cgi' 34require 'erb' 35require 'optparse' 36 37def main 38 encoding = 'us-ascii' 39 css = nil 40 print_line_number = false 41 parser = OptionParser.new 42 parser.banner = "Usage: #{File.basename($0)} [-l] [<file>...]" 43 parser.on('--encoding=NAME', 'Character encoding [us-ascii].') {|name| 44 encoding = name 45 } 46 parser.on('--css=URL', 'Set a link to CSS.') {|url| 47 css = url 48 } 49 parser.on('-l', '--line-number', 'Show line number.') { 50 print_line_number = true 51 } 52 parser.on('--help', 'Prints this message and quit.') { 53 puts parser.help 54 exit 0 55 } 56 begin 57 parser.parse! 58 rescue OptionParser::ParseError => err 59 $stderr.puts err 60 $stderr.puts parser.help 61 exit 1 62 end 63 puts ruby2html(ARGF, encoding, css, print_line_number) 64end 65 66class ERB 67 attr_accessor :lineno 68 69 remove_method :result 70 def result(b) 71 eval(@src, b, (@filename || '(erb)'), (@lineno || 1)) 72 end 73end 74 75def ruby2html(f, encoding, css, print_line_number) 76 erb = ERB.new(TEMPLATE, nil, '>') 77 erb.filename = __FILE__ 78 erb.lineno = TEMPLATE_LINE 79 erb.result(binding()) 80end 81 82class Ruby2HTML < Ripper::Filter 83 def Ruby2HTML.compile(f) 84 buf = StringIO.new 85 Ruby2HTML.new(f).parse(buf) 86 buf.string 87 end 88 89 def on_default(event, tok, f) 90 f << CGI.escapeHTML(tok) 91 end 92 93 def on_kw(tok, f) 94 f << %Q[<span class="resword">#{CGI.escapeHTML(tok)}</span>] 95 end 96 97 def on_comment(tok, f) 98 f << %Q[<span class="comment">#{CGI.escapeHTML(tok.rstrip)}</span>\n] 99 end 100 101 def on_tstring_beg(tok, f) 102 f << %Q[<span class="string">#{CGI.escapeHTML(tok)}] 103 end 104 105 def on_tstring_end(tok, f) 106 f << %Q[#{CGI.escapeHTML(tok)}</span>] 107 end 108end 109 110if $0 == __FILE__ 111 main 112end 113