Skip to content

Instantly share code, notes, and snippets.

@melborne
Created September 12, 2008 01:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save melborne/10357 to your computer and use it in GitHub Desktop.
Save melborne/10357 to your computer and use it in GitHub Desktop.
Ruby methods list html generator. place dat file to same dir for ruby code.
# rb_meth_list2html.rb -- generate Ruby method list html file
# Author:: keyes
require "rbutils"
require "erb"
RUBY_REF = "http://doc.okkez.net/#{RUBY_VERSION.delete('.')}/view/"
USEFUL_LINKS =
{"Standard Library" => "#{RUBY_REF}library",
"RAA" => "http://raa.ruby-lang.org/",
"Regular Expression" => "#{RUBY_REF}spec/regexp",
"M17N" => "#{RUBY_REF}spec/m17n",
"Ruby Official" => "http://www.ruby-lang.org/ja/",
"Ruby-list" => "http://blade.nagaokaut.ac.jp/ruby/ruby-list/index.shtml",
"Ruby-talk" => "http://blade.nagaokaut.ac.jp/ruby/ruby-talk/index.shtml",
"old Ruby Ref" => "http://www.ruby-lang.org/ja/man/html/",
"RHG" => "http://i.loveruby.net/ja/rhg/book/"
}
RUBY_DESC = RUBY_VERSION >= '1.8.7' ? RUBY_DESCRIPTION : "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}]"
def method_list(klass)
methods = klass.methods_by_type
methods.keys.each do |key|
methods[key].reject!{ |m| m =~ /method_list|class_link|method_link|enum_class_check|ruby_man_method_link/} if klass == Object
end
return methods.reject{ |k,v| v.empty? }
end
def class_link(klass)
begin
unless RUBY186_METHODS.keys.to_s.include?(klass.to_s)
'class19_link'
else
'top_class_link'
end
rescue Exception => e
'class19_link'
end
end
def method_link(klass, meth_type, meth)
begin
unless RUBY186_METHODS[klass.to_s][meth_type].include?(meth.to_s)
'meth19_link'
else
"meth_link"
end
rescue Exception => e
"meth19_link"
end
end
# correct links for Enumerator Class
def enum_class_check(klass)
if klass.to_s =~ /Enumerator/ and RUBY_VERSION <= "1.9.0"
'Enumerable=Enumerator'
else
klass
end
end
def ruby_man_method_link(klass, meth_type, meth)
end_symbol = { "*" => "=2a", "+" => "=2b", "\\-" => "=2d", "/" => "=2f", "<" => "=3c", "=" => "=3d", ">" => "=3e", "?" => "=3f", "\\[" => "=5b", "\\]" => "=5d", "\\^" => "=5e", "~" => "=7e", "|" => "=7c", "@" => "=40", "!" => "=21", "%" => "=25", "&" => "=26" }
case
when klass == Kernel && meth_type == "public_instance_methods"
klass = Object
mtype = "i"
when klass.class == Module
if meth_type !~ /instance/
klass = Module
mtype = "i"
elsif meth_type == 'private_instance_methods'
mtype = "m"
else #'public_instance_methods'
mtype = "i"
end
when meth_type == 'public_methods'
if meth =~ /allocate|new|superclass/
klass = Class
mtype = "i"
else
mtype = "s"
end
when meth_type =~ /private/
klass = Object
mtype = "i"
else # public_instance_methods
mtype = "i"
end
meth = meth.to_s.gsub(/["#{end_symbol.keys.join}"]/)do |s|
s.sub!(/[\[\]\^\-]/) { |i| "\\#{i}" }
end_symbol[s]
end
RUBY_REF + "method/#{enum_class_check(klass)}" + "/#{mtype}/#{meth}"
end
klasses = RbUtils.classes.sort_by{ |k| k.to_s } - [ERB]#, StringScanner, StringScanner::Error]
modules = RbUtils.modules.sort_by{ |k| k.to_s } - [RbUtils]
if RUBY_VERSION >= "1.9.0"
klasses -= [Complex, RubyVM]
modules -= [Gem]
end
klasses, errors = klasses.partition{ |k| k.to_s !~ /Error/ }
# ordered by class hierarchy
sclass = RUBY_VERSION >= '1.9' ? BasicObject : Object
klasses = klasses.class_tree([sclass]).flatten.reverse
errors = errors.class_tree([Exception]).flatten.reverse
klass_and_module = klasses + modules + errors
constants = RbUtils.constants - ['RUBY_REF','RUBY186_METHODS','RUBY_DESC','USEFUL_LINKS']
libraries = RbUtils.libraries.reject { |lib| lib =~ /^tk.+|-tk$/ }
RUBY186_METHODS = RbUtils.ruby186_methods
file_name = "ruby#{RUBY_VERSION.delete('.')}_class_list.html"
File.open(file_name, "w") do |f|
f.puts ERB.new(DATA.read).result(binding)
end
__END__
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Ruby <%= RUBY_VERSION %> Methods List</title>
<style type="text/css" media="screen">
* {margin: 0; padding: 0;}
h1.class_title {color:#eed; background:#149; padding-left:10px; margin:7px 0 5px 0;}
h3.meth_type, h3.top_subtitle {color:#833;}
h2#ruby_title {padding:5px 0 0 15px; margin:0 0 5px 0;}
form#search {margin:5px 0 0 15px;}
div.meths, div.top_list {padding:0 10px 0 15px;}
span.superclass {font-size:16pt; color:#888; margin-left:5px;}
span#top_link {font-size:14pt; float:right; width:30px; height:20px; padding-top:10px; margin:0px 20px;}
span.counter {color:#833;}
a#top_title_link:link, a#top_title_link:visited {color:#149;}
a.top_class_link:link, a.top_class_link:visited {color:blue;}
a.class19_link:link, a.class19_link:visited {color:#030;}
a.class_link, a#top_title_link, a.top_class_link, a.meth_link, a.meth19_link, a.class19_link {text-decoration:none;}
a.class_link:link, a.class_link:visited {color:#eed;}
a.meth_link:link, a.meth_link:visited {color:blue;}
a.meth19_link:link, a.meth19_link:visited {color:#030;}
a#top_title_link:hover {color:#833; font-weight:bolder; font-style:italic;}
a.class_link:hover, a.top_class_link:hover, a.class19_link:hover, a.meth_link:hover, a.meth19_link:hover {color:#833; font-weight:bolder; font-style:italic;}
</style>
</head>
<body id="main" style='background:#eed'>
<p id='top'>
<h2 id="ruby_title"><a id="top_title_link" href="<%= RUBY_REF %>index"> <%= RUBY_DESC.capitalize %></a></h2>
<form id='search' method="get" action="<%= RUBY_REF %>search" name="f" id="top_search">
<input value="" name="q" size="20">
<input value="Method Search" type="submit">
</form>
</p>
<div class='top_list'>
<h3 class='top_subtitle'>Class</h3>
<% klasses.each do |klass| %>
<span><a class=<%= class_link(klass) %> href="#<%= klass %>"><%= klass %></a> | </span>
<% end %>
<span class="counter"><%= klasses.length %></span>
</div>
<div class='top_list'>
<h3 class='top_subtitle'>Module</h3>
<% modules.each do |mod| %>
<span><a class=<%= class_link(mod) %> href="#<%= mod %>"><%= mod %></a> | </span>
<% end %>
<span class="counter"><%= modules.length %></span>
</div>
<div class='top_list'>
<h3 class='top_subtitle'>Exception Class</h3>
<% errors.each do |error| %>
<span><a class=<%= class_link(error) %> href="#<%= error %>"><%= error %></a> | </span>
<% end %>
<span class="counter"><%= errors.length %></span>
</div>
<div class='top_list'>
<h3 class='top_subtitle'>Standard Library</h3>
<% libraries.each do |lib| %>
<span><a class="top_class_link" href="<%= RUBY_REF %>library/<%= lib %>"><%= lib %></a> | </span>
<% end %>
<span class="counter"><%= libraries.length %></span>
</div>
<div class='top_list'>
<h3 class='top_subtitle'>Links</h3>
<% USEFUL_LINKS.each do |name, site| %>
<span><a class="top_class_link" href=<%= site %>><%= name %></a> | </span>
<% end %>
</div>
<% klass_and_module.each do |klass| %>
<% super_classes = klass.class == Class ? klass.hierarchy-[klass] : [klass.class] %>
<% if RUBY_VERSION >= '1.9' %>
<% super_classes -= [BasicObject] unless klass == Object %>
<% end %>
<% mod = klass.included_modules %>
<span id="top_link">
<a href="" style="color:#883">top</a>
</span>
<h1 class='class_title' id="<%= klass %>">
<a class="class_link" href="<%= RUBY_REF %>class/<%= enum_class_check(klass) %>"><%= klass %> <span style='font-size:18pt'><%= klass.class %></span></a>
<span class="superclass">
<% unless super_classes.empty? %>
<% super_classes.each do |sc| %>
< <a class="class_link" href="#<%= sc %>"><%= sc %></a>
<% end %>
<% end %>
<span>
<% unless mod.empty? %>
[<% mod.each do |m| %>
<a class='class_link' href='#<%= m %>'><%= m %> </a>
<% end %>]
<% end %>
</span>
</span>
</h1>
<div class='meths'>
<% method_list(klass).each do |meth_type, meths| %>
<h3 class='meth_type'><%= meth_type %></h3>
<% meths.sort.each_with_index do |meth, i| %>
<span>
<a class=<%= method_link(klass,meth_type,meth) %> href=<%= ruby_man_method_link(klass,meth_type,meth) %>><%= meth %></a>
<%= i+1 < meths.length ? " | " : "" %>
</span>
<% end %>
<% if meths.length >= 10 %>
<span class="counter"> | <%= meths.length %></span>
<% end %>
<% end %>
<% if klass == Kernel %>
<h3 class='meth_type'>Constants</h3>
<% constants.each do |const| %>
<span><a class='meth_link' href="<%= RUBY_REF %>method/Kernel/c/<%= const %>"><%= const %></a> | </span>
<% end %>
<% end %>
</div>
<% end %>
</body>
</html>
# = RbUtils -- Ruby Utility to get classes, methods, class hierarchy, libraries
#
# rbutils.rb -
# Author:: keyes
#require "find"
module RbUtils
Libraries = %w(abbrev benchmark bigdecimal cgi cmath complex continuation csv curses date dbm debug delegate digest dl drb e2mmap English erb etc expect fcntl fiber fileutils find forwardable gdbm getoptlong gserver iconv io/nonblock io/wait ipaddr irb json kconv logger mathn matrix minitest/unit mkmf monitor mutex_m net/ftp net/http net/https net/imap net/pop net/smtp net/telnet nkf observer open3 open-uri openssl optparse ostruct pathname pp prettyprint profile profiler pstore pty racc/parser rake rational rbconfig readline resolv resolv-replace rexml rinda/rinda rinda/tuplespace ripper rss rubygems scanf sdbm securerandom set shell shellwords singleton socket stringio strscan sync syslog tempfile test/unit thread thwait time timeout tk tmpdir tracer tsort un uri weakref webrick win32/registry Win32API win32ole xmlrpc yaml zlib)
def self.classes
klasses = constants_plus.map{ |const| eval(const.to_s)}.select{ |k| k.class == Class }
klasses << Enumerable::Enumerator if RUBY_VERSION == '1.8.7'
klasses
end
def self.modules
constants_plus.map{ |const| eval(const.to_s)}.select{ |m| m.class == Module }
end
def self.constants
Module.constants.map{ |c| c.to_s}.select{ |c| eval(c).class.to_s !~ /Class|Module/ }
end
# depends on library paths
def self.libraries
lib_path = if RUBY_VERSION >= '1.9'
"/usr/local/lib/ruby/1.9.0/"
else
"/opt/local/lib/ruby/1.8/"
end
# result = []
# Find.find(lib_path) do |f|
# if f = f.sub!(/#{lib_path}(.*)\.rb/, '\1')
# result << f
# end
# end
# result
# Dir.entries(lib_path).map { |f| f.gsub("\.rb", "") }.reject { |f| f =~ /\.\.*/ }.uniq
Libraries
end
def self.ruby186_methods
begin
# set your ruby 1.8.6 path for execution
meths = %x(ruby186 -rrbutils -e "#{<<CODE}")
meths = {}
klass_and_module = RbUtils.classes + RbUtils.modules - [RbUtils]
klass_and_module.each do |klass|
meths[klass.to_s] = klass.methods_by_type
end
p meths
CODE
eval(meths)
rescue Exception => e
end
end
private
def self.constants_plus
Module.constants + [File::Constants, File::Stat, Process::GID, Process::Status, Process::Sys, Process::UID, Struct::Tms]
end
end
class Module
def hierarchy
(self.superclass ? self.superclass.hierarchy : []).unshift(self)
end
def methods_by_type(*args)
meths = {}
args = ['pu','pt','pr','pui','pti','pri'] if args.empty?
meth_types = {'pu' => 'public_methods', 'pt' => 'protected_methods', 'pr' => 'private_methods', 'pui' => 'public_instance_methods', 'pti' => 'protected_instance_methods', 'pri' => 'private_instance_methods'}
args.map!{ |arg| meth_types[arg] }.compact!
args.each do |mtype|
meths[mtype] = self.send(mtype, false)
#match with string or symbol
meths[mtype].reject!{ |m| m =~ /hierarchy|methods_by_type|class_tree/ }
end
meths
end
end
class Array
def class_tree(parents)
result = []
parents.each do |parent|
s_class = select{ |this| this.superclass == parent }
result << (parents.empty? ? [] : class_tree(s_class.reverse)) << parent
end
result
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment