diff --git a/deps.rip b/deps.rip deleted file mode 100755 index 33d75a7b..00000000 --- a/deps.rip +++ /dev/null @@ -1,7 +0,0 @@ -git://github.com/jnicklas/templater.git -git://github.com/sstephenson/sprockets.git -git://github.com/sinatra/sinatra.git -git://github.com/nex3/haml.git -git://github.com/chriseppstein/compass.git -git://github.com/foca/sinatra-content-for.git -git://github.com/brynary/rack-test.git \ No newline at end of file diff --git a/middleman.gemspec b/middleman.gemspec index 0d2a47bd..3675cb60 100755 --- a/middleman.gemspec +++ b/middleman.gemspec @@ -27,7 +27,6 @@ Gem::Specification.new do |s| "bin/mm-build", "bin/mm-init", "bin/mm-server", - "deps.rip", "lib/middleman.rb", "lib/middleman/base.rb", "lib/middleman/builder.rb", @@ -42,7 +41,6 @@ Gem::Specification.new do |s| "lib/middleman/features/relative_assets.rb", "lib/middleman/features/slickmap.rb", "lib/middleman/features/smush_pngs.rb", - "lib/middleman/features/sprockets.rb", "lib/middleman/haml.rb", "lib/middleman/helpers.rb", "lib/middleman/rack/sprockets+ruby19.rb", diff --git a/vendor/gems/gems/cucumber-0.4.4/examples/self_test/tmp/features/step_definitions/steps.rb b/vendor/gems/gems/cucumber-0.4.4/examples/self_test/tmp/features/step_definitions/steps.rb new file mode 100755 index 00000000..6cbe5d65 --- /dev/null +++ b/vendor/gems/gems/cucumber-0.4.4/examples/self_test/tmp/features/step_definitions/steps.rb @@ -0,0 +1,10 @@ +Given /^a failing step$/ do + raise "I fail" +end + +Given /^a passing step$/ do +end + +Given /^a pending step$/ do + pending +end \ No newline at end of file diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/Makefile b/vendor/gems/gems/eventmachine-0.12.10/ext/Makefile new file mode 100755 index 00000000..f33cdcec --- /dev/null +++ b/vendor/gems/gems/eventmachine-0.12.10/ext/Makefile @@ -0,0 +1,157 @@ + +SHELL = /bin/sh + +#### Start of system configuration section. #### + +srcdir = . +topdir = /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 +hdrdir = $(topdir) +VPATH = $(srcdir):$(topdir):$(hdrdir) +exec_prefix = $(prefix) +prefix = $(DESTDIR)/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr +sharedstatedir = $(prefix)/com +mandir = $(DESTDIR)/usr/share/man +psdir = $(docdir) +oldincludedir = $(DESTDIR)/usr/include +localedir = $(datarootdir)/locale +bindir = $(exec_prefix)/bin +libexecdir = $(exec_prefix)/libexec +sitedir = $(DESTDIR)/Library/Ruby/Site +htmldir = $(docdir) +vendorarchdir = $(vendorlibdir)/$(sitearch) +includedir = $(prefix)/include +infodir = $(DESTDIR)/usr/share/info +vendorlibdir = $(vendordir)/$(ruby_version) +sysconfdir = $(prefix)/etc +libdir = $(exec_prefix)/lib +sbindir = $(exec_prefix)/sbin +rubylibdir = $(libdir)/ruby/$(ruby_version) +docdir = $(datarootdir)/doc/$(PACKAGE) +dvidir = $(docdir) +vendordir = $(libdir)/ruby/vendor_ruby +datarootdir = $(prefix)/share +pdfdir = $(docdir) +archdir = $(rubylibdir)/$(arch) +sitearchdir = $(sitelibdir)/$(sitearch) +datadir = $(datarootdir) +localstatedir = $(prefix)/var +sitelibdir = $(sitedir)/$(ruby_version) + +CC = gcc +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME) + +RUBY_EXTCONF_H = +CFLAGS = -fno-common -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common $(cflags) +INCFLAGS = -I. -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. +DEFS = +CPPFLAGS = -DBUILD_FOR_RUBY -DHAVE_RB_TRAP_IMMEDIATE -DHAVE_RBTRAP -DHAVE_WRITEV -DHAVE_WRITEV -DHAVE_RB_TIME_NEW -DOS_UNIX -DHAVE_SYS_EVENT_H -DHAVE_SYS_QUEUE_H -DHAVE_KQUEUE -DHAVE_OPENSSL_SSL_H -DHAVE_OPENSSL_ERR_H -DWITH_SSL -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE +CXXFLAGS = $(CFLAGS) +ldflags = -L. -arch i386 -arch x86_64 +dldflags = +archflag = +DLDFLAGS = $(ldflags) $(dldflags) $(archflag) +LDSHARED = $(CXX) -arch i386 -arch x86_64 -pipe -bundle -undefined dynamic_lookup +AR = ar +EXEEXT = + +RUBY_INSTALL_NAME = ruby +RUBY_SO_NAME = ruby +arch = universal-darwin10.0 +sitearch = universal-darwin10.0 +ruby_version = 1.8 +ruby = /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby +RUBY = $(ruby) +RM = rm -f +MAKEDIRS = mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp + +#### End of system configuration section. #### + +preload = + +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lC -lcrypto -lssl -lpthread -ldl +SRCS = binder.cpp cmain.cpp cplusplus.cpp ed.cpp em.cpp emwin.cpp epoll.cpp files.cpp kb.cpp page.cpp pipe.cpp rubymain.cpp sigs.cpp ssl.cpp +OBJS = binder.o cmain.o cplusplus.o ed.o em.o emwin.o epoll.o files.o kb.o page.o pipe.o rubymain.o sigs.o ssl.o +TARGET = rubyeventmachine +DLLIB = $(TARGET).bundle +EXTSTATIC = +STATIC_LIB = + +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = /Users/tdreyno/Dropbox/Sites/middleman/vendor/gems/gems/eventmachine-0.12.10/lib$(target_prefix) +RUBYARCHDIR = /Users/tdreyno/Dropbox/Sites/middleman/vendor/gems/gems/eventmachine-0.12.10/lib$(target_prefix) + +TARGET_SO = $(DLLIB) +CLEANLIBS = $(TARGET).bundle $(TARGET).il? $(TARGET).tds $(TARGET).map +CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak + +all: $(DLLIB) +static: $(STATIC_LIB) + +clean: + @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) + +distclean: clean + @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + +realclean: distclean +install: install-so install-rb + +install-so: $(RUBYARCHDIR) +install-so: $(RUBYARCHDIR)/$(DLLIB) +$(RUBYARCHDIR)/$(DLLIB): $(DLLIB) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +install-rb: pre-install-rb install-rb-default +install-rb-default: pre-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +$(RUBYARCHDIR): + $(MAKEDIRS) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .cxx .cpp .C .o + +.cc.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.cxx.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.cpp.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.C.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.c.o: + $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $< + +$(DLLIB): $(OBJS) + @-$(RM) $@ + $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + + + +$(OBJS): ruby.h defines.h diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/binder.o b/vendor/gems/gems/eventmachine-0.12.10/ext/binder.o new file mode 100755 index 00000000..c0f95c71 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/binder.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/cmain.o b/vendor/gems/gems/eventmachine-0.12.10/ext/cmain.o new file mode 100755 index 00000000..d1242d4c Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/cmain.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/cplusplus.o b/vendor/gems/gems/eventmachine-0.12.10/ext/cplusplus.o new file mode 100755 index 00000000..fb93f870 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/cplusplus.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/ed.o b/vendor/gems/gems/eventmachine-0.12.10/ext/ed.o new file mode 100755 index 00000000..59a80f24 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/ed.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/em.o b/vendor/gems/gems/eventmachine-0.12.10/ext/em.o new file mode 100755 index 00000000..45b7dbad Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/em.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/emwin.o b/vendor/gems/gems/eventmachine-0.12.10/ext/emwin.o new file mode 100755 index 00000000..9ba44520 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/emwin.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/epoll.o b/vendor/gems/gems/eventmachine-0.12.10/ext/epoll.o new file mode 100755 index 00000000..ae801d0e Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/epoll.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/Makefile b/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/Makefile new file mode 100755 index 00000000..1cbf27ae --- /dev/null +++ b/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/Makefile @@ -0,0 +1,157 @@ + +SHELL = /bin/sh + +#### Start of system configuration section. #### + +srcdir = . +topdir = /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 +hdrdir = $(topdir) +VPATH = $(srcdir):$(topdir):$(hdrdir) +exec_prefix = $(prefix) +prefix = $(DESTDIR)/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr +sharedstatedir = $(prefix)/com +mandir = $(DESTDIR)/usr/share/man +psdir = $(docdir) +oldincludedir = $(DESTDIR)/usr/include +localedir = $(datarootdir)/locale +bindir = $(exec_prefix)/bin +libexecdir = $(exec_prefix)/libexec +sitedir = $(DESTDIR)/Library/Ruby/Site +htmldir = $(docdir) +vendorarchdir = $(vendorlibdir)/$(sitearch) +includedir = $(prefix)/include +infodir = $(DESTDIR)/usr/share/info +vendorlibdir = $(vendordir)/$(ruby_version) +sysconfdir = $(prefix)/etc +libdir = $(exec_prefix)/lib +sbindir = $(exec_prefix)/sbin +rubylibdir = $(libdir)/ruby/$(ruby_version) +docdir = $(datarootdir)/doc/$(PACKAGE) +dvidir = $(docdir) +vendordir = $(libdir)/ruby/vendor_ruby +datarootdir = $(prefix)/share +pdfdir = $(docdir) +archdir = $(rubylibdir)/$(arch) +sitearchdir = $(sitelibdir)/$(sitearch) +datadir = $(datarootdir) +localstatedir = $(prefix)/var +sitelibdir = $(sitedir)/$(ruby_version) + +CC = gcc +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME) + +RUBY_EXTCONF_H = +CFLAGS = -fno-common -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common $(cflags) +INCFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DBUILD_FOR_RUBY -DOS_UNIX -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags) +CXXFLAGS = $(CFLAGS) +ldflags = -L. -arch i386 -arch x86_64 +dldflags = +archflag = +DLDFLAGS = $(ldflags) $(dldflags) $(archflag) +LDSHARED = $(CXX) -arch i386 -arch x86_64 -pipe -bundle -undefined dynamic_lookup +AR = ar +EXEEXT = + +RUBY_INSTALL_NAME = ruby +RUBY_SO_NAME = ruby +arch = universal-darwin10.0 +sitearch = universal-darwin10.0 +ruby_version = 1.8 +ruby = /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby +RUBY = $(ruby) +RM = rm -f +MAKEDIRS = mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp + +#### End of system configuration section. #### + +preload = + +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl +SRCS = mapper.cpp rubymain.cpp +OBJS = mapper.o rubymain.o +TARGET = fastfilereaderext +DLLIB = $(TARGET).bundle +EXTSTATIC = +STATIC_LIB = + +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = /Users/tdreyno/Dropbox/Sites/middleman/vendor/gems/gems/eventmachine-0.12.10/lib$(target_prefix) +RUBYARCHDIR = /Users/tdreyno/Dropbox/Sites/middleman/vendor/gems/gems/eventmachine-0.12.10/lib$(target_prefix) + +TARGET_SO = $(DLLIB) +CLEANLIBS = $(TARGET).bundle $(TARGET).il? $(TARGET).tds $(TARGET).map +CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak + +all: $(DLLIB) +static: $(STATIC_LIB) + +clean: + @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) + +distclean: clean + @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + +realclean: distclean +install: install-so install-rb + +install-so: $(RUBYARCHDIR) +install-so: $(RUBYARCHDIR)/$(DLLIB) +$(RUBYARCHDIR)/$(DLLIB): $(DLLIB) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +install-rb: pre-install-rb install-rb-default +install-rb-default: pre-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +$(RUBYARCHDIR): + $(MAKEDIRS) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .cxx .cpp .C .o + +.cc.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.cxx.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.cpp.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.C.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.c.o: + $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $< + +$(DLLIB): $(OBJS) + @-$(RM) $@ + $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + + + +$(OBJS): ruby.h defines.h diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/fastfilereaderext.bundle b/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/fastfilereaderext.bundle new file mode 100755 index 00000000..1e31b425 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/fastfilereaderext.bundle differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/mapper.o b/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/mapper.o new file mode 100755 index 00000000..e601c1b4 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/mapper.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/rubymain.o b/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/rubymain.o new file mode 100755 index 00000000..a6ca1c53 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/fastfilereader/rubymain.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/files.o b/vendor/gems/gems/eventmachine-0.12.10/ext/files.o new file mode 100755 index 00000000..09e541c4 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/files.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/kb.o b/vendor/gems/gems/eventmachine-0.12.10/ext/kb.o new file mode 100755 index 00000000..7ab0ba57 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/kb.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/mkmf.log b/vendor/gems/gems/eventmachine-0.12.10/ext/mkmf.log new file mode 100755 index 00000000..f869db69 --- /dev/null +++ b/vendor/gems/gems/eventmachine-0.12.10/ext/mkmf.log @@ -0,0 +1,281 @@ +have_var: checking for rb_trap_immediate in ruby.h,rubysig.h... -------------------- yes + +"gcc -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common -c conftest.c" +checked program was: +/* begin */ +1: #include +2: #include +3: +4: /*top*/ +5: int main() { return 0; } +6: int t() { const volatile void *volatile p; p = &(&rb_trap_immediate)[0]; return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_thread_blocking_region()... -------------------- no + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lpthread -ldl " +conftest.c: In function ‘t’: +conftest.c:3: error: ‘rb_thread_blocking_region’ undeclared (first use in this function) +conftest.c:3: error: (Each undeclared identifier is reported only once +conftest.c:3: error: for each function it appears in.) +conftest.c: In function ‘t’: +conftest.c:3: error: ‘rb_thread_blocking_region’ undeclared (first use in this function) +conftest.c:3: error: (Each undeclared identifier is reported only once +conftest.c:3: error: for each function it appears in.) +lipo: can't figure out the architecture type of: /var/folders/f-/f-fz+8IRHg8gx0qhO9ZpxU+++TI/-Tmp-//cccEYdM5.out +checked program was: +/* begin */ +1: /*top*/ +2: int main() { return 0; } +3: int t() { void ((*volatile p)()); p = (void ((*)()))rb_thread_blocking_region; return 0; } +/* end */ + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lpthread -ldl " +Undefined symbols for architecture i386: + "_rb_thread_blocking_region", referenced from: + _t in ccz9fwnI.o +ld: symbol(s) not found for architecture i386 +collect2: ld returned 1 exit status +Undefined symbols for architecture x86_64: + "_rb_thread_blocking_region", referenced from: + _t in ccDQtliL.o +ld: symbol(s) not found for architecture x86_64 +collect2: ld returned 1 exit status +lipo: can't open input file: /var/folders/f-/f-fz+8IRHg8gx0qhO9ZpxU+++TI/-Tmp-//ccNtcUAe.out (No such file or directory) +checked program was: +/* begin */ +1: /*top*/ +2: int main() { return 0; } +3: int t() { rb_thread_blocking_region(); return 0; } +/* end */ + +-------------------- + +have_func: checking for inotify_init() in sys/inotify.h... -------------------- no + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lpthread -ldl " +conftest.c:1:25: error: sys/inotify.h: No such file or directory +conftest.c: In function ‘t’: +conftest.c:5: error: ‘inotify_init’ undeclared (first use in this function) +conftest.c:5: error: (Each undeclared identifier is reported only once +conftest.c:5: error: for each function it appears in.) +conftest.c:1:25: error: sys/inotify.h: No such file or directory +conftest.c: In function ‘t’: +conftest.c:5: error: ‘inotify_init’ undeclared (first use in this function) +conftest.c:5: error: (Each undeclared identifier is reported only once +conftest.c:5: error: for each function it appears in.) +lipo: can't figure out the architecture type of: /var/folders/f-/f-fz+8IRHg8gx0qhO9ZpxU+++TI/-Tmp-//ccUG0Q0r.out +checked program was: +/* begin */ +1: #include +2: +3: /*top*/ +4: int main() { return 0; } +5: int t() { void ((*volatile p)()); p = (void ((*)()))inotify_init; return 0; } +/* end */ + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lpthread -ldl " +conftest.c:1:25: error: sys/inotify.h: No such file or directory +conftest.c:1:25: error: sys/inotify.h: No such file or directory +lipo: can't figure out the architecture type of: /var/folders/f-/f-fz+8IRHg8gx0qhO9ZpxU+++TI/-Tmp-//cc5C3qNQ.out +checked program was: +/* begin */ +1: #include +2: +3: /*top*/ +4: int main() { return 0; } +5: int t() { inotify_init(); return 0; } +/* end */ + +-------------------- + +have_macro: checking for __NR_inotify_init in sys/syscall.h... -------------------- no + +"gcc -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common -c conftest.c" +conftest.c:4:3: error: #error +conftest.c:5: error: expected identifier or ‘(’ before ‘>>’ token +conftest.c:4:3: error: #error +conftest.c:5: error: expected identifier or ‘(’ before ‘>>’ token +lipo: can't open input file: /var/folders/f-/f-fz+8IRHg8gx0qhO9ZpxU+++TI/-Tmp-//ccbXD11s.out (No such file or directory) +checked program was: +/* begin */ +1: #include +2: /*top*/ +3: #ifndef __NR_inotify_init +4: # error +5: >>>>>> __NR_inotify_init undefined <<<<<< +6: #endif +/* end */ + +-------------------- + +have_func: checking for writev() in sys/uio.h... -------------------- yes + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lpthread -ldl " +checked program was: +/* begin */ +1: #include +2: +3: /*top*/ +4: int main() { return 0; } +5: int t() { void ((*volatile p)()); p = (void ((*)()))writev; return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_thread_check_ints()... -------------------- no + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lpthread -ldl " +conftest.c: In function ‘t’: +conftest.c:3: error: ‘rb_thread_check_ints’ undeclared (first use in this function) +conftest.c:3: error: (Each undeclared identifier is reported only once +conftest.c:3: error: for each function it appears in.) +conftest.c: In function ‘t’: +conftest.c:3: error: ‘rb_thread_check_ints’ undeclared (first use in this function) +conftest.c:3: error: (Each undeclared identifier is reported only once +conftest.c:3: error: for each function it appears in.) +lipo: can't figure out the architecture type of: /var/folders/f-/f-fz+8IRHg8gx0qhO9ZpxU+++TI/-Tmp-//cc2APTbR.out +checked program was: +/* begin */ +1: /*top*/ +2: int main() { return 0; } +3: int t() { void ((*volatile p)()); p = (void ((*)()))rb_thread_check_ints; return 0; } +/* end */ + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lpthread -ldl " +Undefined symbols for architecture i386: + "_rb_thread_check_ints", referenced from: + _t in cc62yllm.o +ld: symbol(s) not found for architecture i386 +collect2: ld returned 1 exit status +Undefined symbols for architecture x86_64: + "_rb_thread_check_ints", referenced from: + _t in ccvcprgK.o +ld: symbol(s) not found for architecture x86_64 +collect2: ld returned 1 exit status +lipo: can't open input file: /var/folders/f-/f-fz+8IRHg8gx0qhO9ZpxU+++TI/-Tmp-//cc3Nkwrn.out (No such file or directory) +checked program was: +/* begin */ +1: /*top*/ +2: int main() { return 0; } +3: int t() { rb_thread_check_ints(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_time_new()... -------------------- yes + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lpthread -ldl " +conftest.c: In function ‘t’: +conftest.c:3: error: ‘rb_time_new’ undeclared (first use in this function) +conftest.c:3: error: (Each undeclared identifier is reported only once +conftest.c:3: error: for each function it appears in.) +conftest.c: In function ‘t’: +conftest.c:3: error: ‘rb_time_new’ undeclared (first use in this function) +conftest.c:3: error: (Each undeclared identifier is reported only once +conftest.c:3: error: for each function it appears in.) +lipo: can't figure out the architecture type of: /var/folders/f-/f-fz+8IRHg8gx0qhO9ZpxU+++TI/-Tmp-//ccOLS696.out +checked program was: +/* begin */ +1: /*top*/ +2: int main() { return 0; } +3: int t() { void ((*volatile p)()); p = (void ((*)()))rb_time_new; return 0; } +/* end */ + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lpthread -ldl " +checked program was: +/* begin */ +1: /*top*/ +2: int main() { return 0; } +3: int t() { rb_time_new(); return 0; } +/* end */ + +-------------------- + +have_header: checking for sys/event.h... -------------------- yes + +"gcc -E -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include +/* end */ + +-------------------- + +have_header: checking for sys/queue.h... -------------------- yes + +"gcc -E -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include +/* end */ + +-------------------- + +package configuration for openssl is not found +have_library: checking for main() in -lssl... -------------------- yes + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lruby -lssl -lpthread -ldl " +checked program was: +/* begin */ +1: /*top*/ +2: int main() { return 0; } +3: int t() { void ((*volatile p)()); p = (void ((*)()))main; return 0; } +/* end */ + +-------------------- + +have_library: checking for main() in -lcrypto... -------------------- yes + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lssl -lruby -lcrypto -lssl -lpthread -ldl " +checked program was: +/* begin */ +1: /*top*/ +2: int main() { return 0; } +3: int t() { void ((*volatile p)()); p = (void ((*)()))main; return 0; } +/* end */ + +-------------------- + +have_library: checking for main() in -lC... -------------------- yes + +"gcc -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lcrypto -lssl -lruby -lC -lcrypto -lssl -lpthread -ldl " +checked program was: +/* begin */ +1: /*top*/ +2: int main() { return 0; } +3: int t() { void ((*volatile p)()); p = (void ((*)()))main; return 0; } +/* end */ + +-------------------- + +have_header: checking for openssl/ssl.h... -------------------- yes + +"gcc -E -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include +/* end */ + +-------------------- + +have_header: checking for openssl/err.h... -------------------- yes + +"gcc -E -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include +/* end */ + +-------------------- + +" -o conftest -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0 -I. -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common conftest.c -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L. -arch i386 -arch x86_64 -lC -lcrypto -lssl -lruby -lstdc++ -lpthread -ldl " +checked program was: +/* begin */ +1: #include +2: using namespace std; +3: int main(){ pair tuple = make_pair(1,2); } +/* end */ + diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/page.o b/vendor/gems/gems/eventmachine-0.12.10/ext/page.o new file mode 100755 index 00000000..8c3154e3 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/page.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/pipe.o b/vendor/gems/gems/eventmachine-0.12.10/ext/pipe.o new file mode 100755 index 00000000..e30887e2 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/pipe.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/rubyeventmachine.bundle b/vendor/gems/gems/eventmachine-0.12.10/ext/rubyeventmachine.bundle new file mode 100755 index 00000000..0e0c374a Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/rubyeventmachine.bundle differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/rubymain.o b/vendor/gems/gems/eventmachine-0.12.10/ext/rubymain.o new file mode 100755 index 00000000..e3aebe2c Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/rubymain.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/sigs.o b/vendor/gems/gems/eventmachine-0.12.10/ext/sigs.o new file mode 100755 index 00000000..d73ffb3f Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/sigs.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/ext/ssl.o b/vendor/gems/gems/eventmachine-0.12.10/ext/ssl.o new file mode 100755 index 00000000..925fbba0 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/ext/ssl.o differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/lib/fastfilereaderext.bundle b/vendor/gems/gems/eventmachine-0.12.10/lib/fastfilereaderext.bundle new file mode 100755 index 00000000..1e31b425 Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/lib/fastfilereaderext.bundle differ diff --git a/vendor/gems/gems/eventmachine-0.12.10/lib/rubyeventmachine.bundle b/vendor/gems/gems/eventmachine-0.12.10/lib/rubyeventmachine.bundle new file mode 100755 index 00000000..0e0c374a Binary files /dev/null and b/vendor/gems/gems/eventmachine-0.12.10/lib/rubyeventmachine.bundle differ diff --git a/vendor/gems/gems/rdoc-2.4.3/bin/rdoc b/vendor/gems/gems/rdoc-2.4.3/bin/rdoc new file mode 100755 index 00000000..a94f4232 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/bin/rdoc @@ -0,0 +1,35 @@ +#!/usr/bin/env ruby +# +# RDoc: Documentation tool for source code +# (see lib/rdoc/rdoc.rb for more information) +# +# Copyright (c) 2003 Dave Thomas +# Released under the same terms as Ruby +# +# $Revision: 15033 $ + +require 'rdoc/rdoc' + +begin + r = RDoc::RDoc.new + r.document ARGV +rescue Interrupt + $stderr.puts + $stderr.puts "Interrupted" + exit 1 +rescue SystemExit + raise +rescue Exception => e + if $DEBUG_RDOC then + $stderr.puts e.message + $stderr.puts "#{e.backtrace.join "\n\t"}" + $stderr.puts + else + $stderr.puts "uh-oh! RDoc had a problem:" + $stderr.puts e.message + $stderr.puts + $stderr.puts "run with --debug for full backtrace" + end + exit 1 +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/alias.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/alias.rb new file mode 100755 index 00000000..74a8d4e7 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/alias.rb @@ -0,0 +1,54 @@ +require 'rdoc/code_object' + +## +# Represent an alias, which is an old_name/new_name pair associated with a +# particular context + +class RDoc::Alias < RDoc::CodeObject + + ## + # Allow comments to be overridden + + attr_writer :comment + + ## + # Aliased name + + attr_accessor :new_name + + ## + # Aliasee's name + + attr_accessor :old_name + + ## + # Source file token stream + + attr_accessor :text + + ## + # Creates a new Alias with a token stream of +text+ that aliases +old_name+ + # to +new_name+ and has +comment+ + + def initialize(text, old_name, new_name, comment) + super() + @text = text + @old_name = old_name + @new_name = new_name + self.comment = comment + end + + def inspect # :nodoc: + "#<%s:0x%x %s.alias_method %s, %s>" % [ + self.class, object_id, + parent.name, @old_name, @new_name, + ] + end + + def to_s # :nodoc: + "alias: #{self.old_name} -> #{self.new_name}\n#{self.comment}" + end + +end + + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/anon_class.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/anon_class.rb new file mode 100755 index 00000000..0a684f2d --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/anon_class.rb @@ -0,0 +1,10 @@ +require 'rdoc/class_module' + +## +# An anonymous class like: +# +# c = Class.new do end + +class RDoc::AnonClass < RDoc::ClassModule +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/any_method.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/any_method.rb new file mode 100755 index 00000000..b65fd9ab --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/any_method.rb @@ -0,0 +1,190 @@ +require 'rdoc/code_object' +require 'rdoc/tokenstream' + +## +# AnyMethod is the base class for objects representing methods + +class RDoc::AnyMethod < RDoc::CodeObject + + ## + # Method name + + attr_writer :name + + ## + # public, protected, private + + attr_accessor :visibility + + ## + # Parameters yielded by the called block + + attr_accessor :block_params + + ## + # Don't rename \#initialize to \::new + + attr_accessor :dont_rename_initialize + + ## + # Is this a singleton method? + + attr_accessor :singleton + + ## + # Source file token stream + + attr_reader :text + + ## + # Array of other names for this method + + attr_reader :aliases + + ## + # Fragment reference for this method + + attr_reader :aref + + ## + # The method we're aliasing + + attr_accessor :is_alias_for + + ## + # Parameters for this method + + attr_overridable :params, :param, :parameters, :parameter + + ## + # Different ways to call this method + + attr_accessor :call_seq + + include RDoc::TokenStream + + ## + # Resets method fragment reference counter + + def self.reset + @@aref = 'M000000' + end + + reset + + def initialize(text, name) + super() + @text = text + @name = name + @token_stream = nil + @visibility = :public + @dont_rename_initialize = false + @block_params = nil + @aliases = [] + @is_alias_for = nil + @call_seq = nil + + @aref = @@aref + @@aref = @@aref.succ + end + + ## + # Order by #singleton then #name + + def <=>(other) + [@singleton ? 0 : 1, @name] <=> [other.singleton ? 0 : 1, other.name] + end + + ## + # Adds +method+ as an alias for this method + + def add_alias(method) + @aliases << method + end + + ## + # HTML id-friendly method name + + def html_name + @name.gsub(/[^a-z]+/, '-') + end + + def inspect # :nodoc: + alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil + "#<%s:0x%x %s%s%s (%s)%s>" % [ + self.class, object_id, + parent_name, + singleton ? '::' : '#', + name, + visibility, + alias_for, + ] + end + + ## + # Full method name including namespace + + def full_name + "#{@parent.full_name}#{pretty_name}" + end + + ## + # Method name + + def name + return @name if @name + + @name = @call_seq[/^.*?\.(\w+)/, 1] || @call_seq + end + + ## + # Pretty parameter list for this method + + def param_seq + params = params.gsub(/\s*\#.*/, '') + params = params.tr("\n", " ").squeeze(" ") + params = "(#{params})" unless p[0] == ?( + + if block = block_params then # yes, = + # If this method has explicit block parameters, remove any explicit + # &block + params.sub!(/,?\s*&\w+/) + + block.gsub!(/\s*\#.*/, '') + block = block.tr("\n", " ").squeeze(" ") + if block[0] == ?( + block.sub!(/^\(/, '').sub!(/\)/, '') + end + params << " { |#{block}| ... }" + end + + params + end + + ## + # Path to this method + + def path + "#{@parent.path}##{@aref}" + end + + ## + # Method name with class/instance indicator + + def pretty_name + "#{singleton ? '::' : '#'}#{@name}" + end + + def to_s # :nodoc: + "#{self.class.name}: #{full_name} (#{@text})\n#{@comment}" + end + + ## + # Type of method (class or instance) + + def type + singleton ? 'class' : 'instance' + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/attr.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/attr.rb new file mode 100755 index 00000000..235a5ab2 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/attr.rb @@ -0,0 +1,79 @@ +require 'rdoc/code_object' + +## +# An attribute created by \#attr, \#attr_reader, \#attr_writer or +# \#attr_accessor + +class RDoc::Attr < RDoc::CodeObject + + ## + # Name of the attribute + + attr_accessor :name + + ## + # Is the attribute readable, writable or both? + + attr_accessor :rw + + ## + # Source file token stream + + attr_accessor :text + + ## + # public, protected, private + + attr_accessor :visibility + + def initialize(text, name, rw, comment) + super() + @text = text + @name = name + @rw = rw + @visibility = :public + self.comment = comment + end + + ## + # Attributes are ordered by name + + def <=>(other) + self.name <=> other.name + end + + ## + # An HTML id-friendly representation of #name + + def html_name + @name.gsub(/[^a-z]+/, '-') + end + + def inspect # :nodoc: + attr = case rw + when 'RW' then :attr_accessor + when 'R' then :attr_reader + when 'W' then :attr_writer + else + " (#{rw})" + end + + "#<%s:0x%x %s.%s :%s>" % [ + self.class, object_id, + parent_name, attr, @name, + ] + end + + ## + # URL path for this attribute + + def path + "#{@parent.path}##{@name}" + end + + def to_s # :nodoc: + "attr: #{self.name} #{self.rw}\n#{self.comment}" + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/cache.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/cache.rb new file mode 100755 index 00000000..bdd830a1 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/cache.rb @@ -0,0 +1,41 @@ +require 'thread' +require 'singleton' + +## +# A generic, thread-safe in-memory cache. It's used for caching +# RDoc::TemplatePage objects when generating RDoc output. + +class RDoc::Cache + + include Singleton + + ## + # Creates a new, empty cache + + def initialize + @contents = {} + @lock = Mutex.new + end + + ## + # Checks whether there's a value in the cache with key +key+. If so, then + # that value will be returned. Otherwise, the given block will be run, and + # its return value will be put into the cache, and returned. + + def cache(key) + @lock.synchronize do + @contents[key] ||= yield + end + end + + ## + # Clears the contents of the cache + + def clear + @lock.synchronize do + @contents.clear + end + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/class_module.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/class_module.rb new file mode 100755 index 00000000..dc8874f9 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/class_module.rb @@ -0,0 +1,87 @@ +require 'rdoc/context' + +## +# ClassModule is the base class for objects representing either a class or a +# module. + +class RDoc::ClassModule < RDoc::Context + + attr_accessor :diagram + + ## + # Creates a new ClassModule with +name+ with optional +superclass+ + + def initialize(name, superclass = 'Object') + @diagram = nil + @full_name = nil + @name = name + @superclass = superclass + super() + end + + ## + # Finds a class or module with +name+ in this namespace or its descendents + + def find_class_named(name) + return self if full_name == name + @classes.each_value {|c| return c if c.find_class_named(name) } + nil + end + + ## + # Return the fully qualified name of this class or module + + def full_name + @full_name ||= if RDoc::ClassModule === @parent then + "#{@parent.full_name}::#{@name}" + else + @name + end + end + + ## + # 'module' or 'class' + + def type + module? ? 'module' : 'class' + end + + ## + # Does this object represent a module? + + def module? + false + end + + ## + # Path to this class or module + + def path + http_url RDoc::RDoc.current.generator.class_dir + end + + ## + # Get the superclass of this class. Attempts to retrieve the superclass + # object, returns the name if it is not known. + + def superclass + raise NoMethodError, "#{full_name} is a module" if module? + + RDoc::TopLevel.find_class_named(@superclass) || @superclass + end + + ## + # Set the superclass of this class to +superclass+ + + def superclass=(superclass) + raise NoMethodError, "#{full_name} is a module" if module? + + @superclass = superclass if @superclass.nil? or @superclass == 'Object' + end + + def to_s # :nodoc: + "#{self.class}: #{full_name} #{@comment} #{super}" + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/code_object.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/code_object.rb new file mode 100755 index 00000000..2b7d9cde --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/code_object.rb @@ -0,0 +1,152 @@ +require 'rdoc' + +## +# We contain the common stuff for contexts (which are containers) and other +# elements (methods, attributes and so on) + +class RDoc::CodeObject + + ## + # Our comment + + attr_reader :comment + + ## + # Do we document our children? + + attr_reader :document_children + + ## + # Do we document ourselves? + + attr_reader :document_self + + ## + # Are we done documenting (ie, did we come across a :enddoc:)? + + attr_accessor :done_documenting + + ## + # Force documentation of this CodeObject + + attr_accessor :force_documentation + + ## + # Our parent CodeObject + + attr_accessor :parent + + ## + # Which section are we in + + attr_accessor :section + + ## + # We are the model of the code, but we know that at some point we will be + # worked on by viewers. By implementing the Viewable protocol, viewers can + # associated themselves with these objects. + + attr_accessor :viewer + + ## + # There's a wee trick we pull. Comment blocks can have directives that + # override the stuff we extract during the parse. So, we have a special + # class method, attr_overridable, that lets code objects list those + # directives. When a comment is assigned, we then extract out any matching + # directives and update our object + + def self.attr_overridable(name, *aliases) + @overridables ||= {} + + attr_accessor name + + aliases.unshift name + + aliases.each do |directive_name| + @overridables[directive_name.to_s] = name + end + end + + ## + # Creates a new CodeObject that will document itself and its children + + def initialize + @comment = nil + @document_children = true + @document_self = true + @done_documenting = false + @force_documentation = false + @parent = nil + end + + ## + # Replaces our comment with +comment+, unless it is empty. + + def comment=(comment) + @comment = comment unless comment.empty? + end + + ## + # Enables or disables documentation of this CodeObject's children. Calls + # remove_classes_and_modules when disabling. + + def document_children=(document_children) + @document_children = document_children + remove_classes_and_modules unless document_children + end + + ## + # Enables or disables documentation of this CodeObject. Calls + # remove_methods_etc when disabling. + + def document_self=(document_self) + @document_self = document_self + remove_methods_etc unless document_self + end + + ## + # File name of our parent + + def parent_file_name + @parent ? @parent.base_name : '(unknown)' + end + + ## + # Name of our parent + + def parent_name + @parent ? @parent.full_name : '(unknown)' + end + + ## + # Callback called upon disabling documentation of children. See + # #document_children= + + def remove_classes_and_modules + end + + ## + # Callback called upon disabling documentation of ourself. See + # #document_self= + + def remove_methods_etc + end + + ## + # Enable capture of documentation + + def start_doc + @document_self = true + @document_children = true + end + + ## + # Disable capture of documentation + + def stop_doc + @document_self = false + @document_children = false + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/code_objects.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/code_objects.rb new file mode 100755 index 00000000..c60dad92 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/code_objects.rb @@ -0,0 +1,23 @@ +# We represent the various high-level code constructs that appear in Ruby +# programs: classes, modules, methods, and so on. + +require 'rdoc/code_object' +require 'rdoc/context' +require 'rdoc/top_level' + +require 'rdoc/class_module' +require 'rdoc/normal_class' +require 'rdoc/normal_module' +require 'rdoc/anon_class' +require 'rdoc/single_class' + +require 'rdoc/any_method' +require 'rdoc/alias' +require 'rdoc/ghost_method' +require 'rdoc/meta_method' + +require 'rdoc/attr' +require 'rdoc/constant' +require 'rdoc/require' +require 'rdoc/include' + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/constant.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/constant.rb new file mode 100755 index 00000000..56566da8 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/constant.rb @@ -0,0 +1,36 @@ +require 'rdoc/code_object' + +## +# A constant + +class RDoc::Constant < RDoc::CodeObject + + ## + # The constant's name + + attr_accessor :name + + ## + # The constant's value + + attr_accessor :value + + ## + # Creates a new constant with +name+, +value+ and +comment+ + + def initialize(name, value, comment) + super() + @name = name + @value = value + self.comment = comment + end + + ## + # Path to this constant + + def path + "#{@parent.path}##{@name}" + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/context.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/context.rb new file mode 100755 index 00000000..b6763991 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/context.rb @@ -0,0 +1,712 @@ +require 'thread' +require 'rdoc/code_object' + +## +# A Context is something that can hold modules, classes, methods, attributes, +# aliases, requires, and includes. Classes, modules, and files are all +# Contexts. + +class RDoc::Context < RDoc::CodeObject + + ## + # Types of methods + + TYPES = %w[class instance] + + ## + # Method visibilities + + VISIBILITIES = [:public, :protected, :private] + + ## + # Aliased methods + + attr_reader :aliases + + ## + # attr* methods + + attr_reader :attributes + + ## + # Constants defined + + attr_reader :constants + + ## + # Current section of documentation + + attr_reader :current_section + + ## + # Files this context is found in + + attr_reader :in_files + + ## + # Modules this context includes + + attr_reader :includes + + ## + # Methods defined in this context + + attr_reader :method_list + + ## + # Name of this class excluding namespace. See also full_name + + attr_reader :name + + ## + # Files this context requires + + attr_reader :requires + + ## + # Sections in this context + + attr_reader :sections + + ## + # Aliases that haven't been resolved to a method + + attr_accessor :unmatched_alias_lists + + ## + # Current visibility of this context + + attr_reader :visibility + + ## + # A per-comment section of documentation like: + # + # # :SECTION: The title + # # The body + + class Section + + ## + # Section comment + + attr_reader :comment + + ## + # Context this Section lives in + + attr_reader :parent + + ## + # Section sequence number (for linking) + + attr_reader :sequence + + ## + # Section title + + attr_reader :title + + @@sequence = "SEC00000" + @@sequence_lock = Mutex.new + + ## + # Creates a new section with +title+ and +comment+ + + def initialize(parent, title, comment) + @parent = parent + @title = title + + @@sequence_lock.synchronize do + @@sequence.succ! + @sequence = @@sequence.dup + end + + set_comment comment + end + + ## + # Sections are equal when they have the same #sequence + + def ==(other) + self.class === other and @sequence == other.sequence + end + + def inspect # :nodoc: + "#<%s:0x%x %s %p>" % [ + self.class, object_id, + @sequence, title + ] + end + + ## + # Set the comment for this section from the original comment block If + # the first line contains :section:, strip it and use the rest. + # Otherwise remove lines up to the line containing :section:, and look + # for those lines again at the end and remove them. This lets us write + # + # # blah blah blah + # # + # # :SECTION: The title + # # The body + + def set_comment(comment) + return unless comment + + if comment =~ /^#[ \t]*:section:.*\n/ then + start = $` + rest = $' + + if start.empty? + @comment = rest + else + @comment = rest.sub(/#{start.chomp}\Z/, '') + end + else + @comment = comment + end + + @comment = nil if @comment.empty? + end + + end + + ## + # Creates an unnamed empty context with public visibility + + def initialize + super + + @in_files = [] + + @name ||= "unknown" + @comment ||= "" + @parent = nil + @visibility = :public + + @current_section = Section.new self, nil, nil + @sections = [@current_section] + + initialize_methods_etc + initialize_classes_and_modules + end + + ## + # Sets the defaults for classes and modules + + def initialize_classes_and_modules + @classes = {} + @modules = {} + end + + ## + # Sets the defaults for methods and so-forth + + def initialize_methods_etc + @method_list = [] + @attributes = [] + @aliases = [] + @requires = [] + @includes = [] + @constants = [] + + # This Hash maps a method name to a list of unmatched aliases (aliases of + # a method not yet encountered). + @unmatched_alias_lists = {} + end + + ## + # Contexts are sorted by full_name + + def <=>(other) + full_name <=> other.full_name + end + + ## + # Adds +an_alias+ that is automatically resolved + + def add_alias(an_alias) + meth = find_instance_method_named(an_alias.old_name) + + if meth then + add_alias_impl an_alias, meth + else + add_to @aliases, an_alias + unmatched_alias_list = @unmatched_alias_lists[an_alias.old_name] ||= [] + unmatched_alias_list.push an_alias + end + + an_alias + end + + ## + # Adds +an_alias+ pointing to +meth+ + + def add_alias_impl(an_alias, meth) + new_meth = RDoc::AnyMethod.new an_alias.text, an_alias.new_name + new_meth.is_alias_for = meth + new_meth.singleton = meth.singleton + new_meth.params = meth.params + new_meth.comment = "Alias for \##{meth.name}" + meth.add_alias new_meth + add_method new_meth + end + + ## + # Adds +attribute+ + + def add_attribute(attribute) + add_to @attributes, attribute + end + + ## + # Adds a class named +name+ with +superclass+. + # + # Given class Container::Item RDoc assumes +Container+ is a module + # unless it later sees class Container. add_class automatically + # upgrades +name+ to a class in this case. + + def add_class(class_type, name, superclass = 'Object') + klass = add_class_or_module @classes, class_type, name, superclass + + # If the parser encounters Container::Item before encountering + # Container, then it assumes that Container is a module. This may not + # be the case, so remove Container from the module list if present and + # transfer any contained classes and modules to the new class. + + RDoc::TopLevel.lock.synchronize do + mod = RDoc::TopLevel.modules_hash.delete klass.full_name + + if mod then + klass.classes_hash.update mod.classes_hash + klass.modules_hash.update mod.modules_hash + klass.method_list.concat mod.method_list + + @modules.delete klass.name + end + + RDoc::TopLevel.classes_hash[klass.full_name] = klass + end + + klass + end + + ## + # Instantiates a +class_type+ named +name+ and adds it the modules or + # classes Hash +collection+. + + def add_class_or_module(collection, class_type, name, superclass = nil) + full_name = if RDoc::TopLevel === self then # HACK + name + else + "#{self.full_name}::#{name}" + end + mod = collection[name] + + if mod then + mod.superclass = superclass unless mod.module? + else + all = nil + + RDoc::TopLevel.lock.synchronize do + all = if class_type == RDoc::NormalModule then + RDoc::TopLevel.modules_hash + else + RDoc::TopLevel.classes_hash + end + + mod = all[full_name] + end + + unless mod then + mod = class_type.new name, superclass + else + # If the class has been encountered already, check that its + # superclass has been set (it may not have been, depending on the + # context in which it was encountered). + if class_type == RDoc::NormalClass then + mod.superclass = superclass unless mod.superclass + end + end + + unless @done_documenting then + RDoc::TopLevel.lock.synchronize do + all[full_name] = mod + end + collection[name] = mod + end + + mod.section = @current_section + mod.parent = self + end + + mod + end + + ## + # Adds +constant+ + + def add_constant(constant) + add_to @constants, constant + end + + ## + # Adds included module +include+ + + def add_include(include) + add_to @includes, include + end + + ## + # Adds +method+ + + def add_method(method) + method.visibility = @visibility + add_to @method_list, method + + unmatched_alias_list = @unmatched_alias_lists[method.name] + if unmatched_alias_list then + unmatched_alias_list.each do |unmatched_alias| + add_alias_impl unmatched_alias, method + @aliases.delete unmatched_alias + end + + @unmatched_alias_lists.delete method.name + end + end + + ## + # Adds a module named +name+. If RDoc already knows +name+ is a class then + # that class is returned instead. See also #add_class + + def add_module(class_type, name) + return @classes[name] if @classes.key? name + + add_class_or_module @modules, class_type, name, nil + end + + ## + # Adds +require+ to this context's top level + + def add_require(require) + if RDoc::TopLevel === self then + add_to @requires, require + else + parent.add_require require + end + end + + ## + # Adds +thing+ to the collection +array+ + + def add_to(array, thing) + array << thing if @document_self and not @done_documenting + thing.parent = self + thing.section = @current_section + end + + ## + # Array of classes in this context + + def classes + @classes.values + end + + ## + # All classes and modules in this namespace + + def classes_and_modules + classes + modules + end + + ## + # Hash of classes keyed by class name + + def classes_hash + @classes + end + + ## + # Is part of this thing was defined in +file+? + + def defined_in?(file) + @in_files.include?(file) + end + + ## + # Iterator for attributes + + def each_attribute # :yields: attribute + @attributes.each {|a| yield a} + end + + ## + # Iterator for classes and modules + + def each_classmodule(&block) # :yields: module + classes_and_modules.sort.each(&block) + end + + ## + # Iterator for constants + + def each_constant # :yields: constant + @constants.each {|c| yield c} + end + + ## + # Iterator for included modules + + def each_include # :yields: include + @includes.each do |i| yield i end + end + + ## + # Iterator for methods + + def each_method # :yields: method + @method_list.sort.each {|m| yield m} + end + + ## + # Finds an attribute with +name+ in this context + + def find_attribute_named(name) + @attributes.find { |m| m.name == name } + end + + ## + # Finds a constant with +name+ in this context + + def find_constant_named(name) + @constants.find {|m| m.name == name} + end + + ## + # Find a module at a higher scope + + def find_enclosing_module_named(name) + parent && parent.find_module_named(name) + end + + ## + # Finds a file with +name+ in this context + + def find_file_named(name) + top_level.class.find_file_named(name) + end + + ## + # Finds an instance method with +name+ in this context + + def find_instance_method_named(name) + @method_list.find { |meth| meth.name == name && !meth.singleton } + end + + ## + # Finds a method, constant, attribute, module or files named +symbol+ in + # this context + + def find_local_symbol(symbol) + find_method_named(symbol) or + find_constant_named(symbol) or + find_attribute_named(symbol) or + find_module_named(symbol) or + find_file_named(symbol) + end + + ## + # Finds a instance or module method with +name+ in this context + + def find_method_named(name) + @method_list.find { |meth| meth.name == name } + end + + ## + # Find a module with +name+ using ruby's scoping rules + + def find_module_named(name) + res = @modules[name] || @classes[name] + return res if res + return self if self.name == name + find_enclosing_module_named name + end + + ## + # Look up +symbol+. If +method+ is non-nil, then we assume the symbol + # references a module that contains that method. + + def find_symbol(symbol, method = nil) + result = nil + + case symbol + when /^::(.*)/ then + result = top_level.find_symbol($1) + when /::/ then + modules = symbol.split(/::/) + + unless modules.empty? then + module_name = modules.shift + result = find_module_named(module_name) + + if result then + modules.each do |name| + result = result.find_module_named name + break unless result + end + end + end + + else + # if a method is specified, then we're definitely looking for + # a module, otherwise it could be any symbol + if method then + result = find_module_named symbol + else + result = find_local_symbol symbol + if result.nil? then + if symbol =~ /^[A-Z]/ then + result = parent + while result && result.name != symbol do + result = result.parent + end + end + end + end + end + + if result and method then + fail unless result.respond_to? :find_local_symbol + result = result.find_local_symbol(method) + end + + result + end + + ## + # URL for this with a +prefix+ + + def http_url(prefix) + path = full_name + path = path.gsub(/<<\s*(\w*)/, 'from-\1') if path =~ /< 'TopLevel', + 'fontname' => FONT, + 'fontsize' => '8', + 'bgcolor' => 'lightcyan1', + 'compound' => 'true') + + # it's a little hack %) i'm too lazy to create a separate class + # for default node + graph << DOT::Node.new('name' => 'node', + 'fontname' => FONT, + 'color' => 'black', + 'fontsize' => 8) + + i.modules.each do |mod| + draw_module(mod, graph, true, i.relative_name) + end + add_classes(i, graph, i.relative_name) + + i.diagram = convert_to_png("f_#{file_count}", graph) + + # now go through and document each top level class and + # module independently + i.modules.each_with_index do |mod, count| + @done_modules = {} + @local_names = find_names(mod) + @global_names = [] + + @global_graph = graph = DOT::Digraph.new('name' => 'TopLevel', + 'fontname' => FONT, + 'fontsize' => '8', + 'bgcolor' => 'lightcyan1', + 'compound' => 'true') + + graph << DOT::Node.new('name' => 'node', + 'fontname' => FONT, + 'color' => 'black', + 'fontsize' => 8) + draw_module(mod, graph, true) + mod.diagram = convert_to_png("m_#{file_count}_#{count}", + graph) + end + end + $stderr.puts unless @options.quiet + end + + private + + def find_names(mod) + return [mod.full_name] + mod.classes.collect{|cl| cl.full_name} + + mod.modules.collect{|m| find_names(m)}.flatten + end + + def find_full_name(name, mod) + full_name = name.dup + return full_name if @local_names.include?(full_name) + mod_path = mod.full_name.split('::')[0..-2] + unless mod_path.nil? + until mod_path.empty? + full_name = mod_path.pop + '::' + full_name + return full_name if @local_names.include?(full_name) + end + end + return name + end + + def draw_module(mod, graph, top_level = false, file = nil) + return if @done_modules[mod.full_name] and not top_level + + @counter += 1 + url = mod.http_url("classes") + m = DOT::Subgraph.new('name' => "cluster_#{mod.full_name.gsub( /:/,'_' )}", + 'label' => mod.name, + 'fontname' => FONT, + 'color' => 'blue', + 'style' => 'filled', + 'URL' => %{"#{url}"}, + 'fillcolor' => top_level ? 'palegreen1' : 'palegreen3') + + @done_modules[mod.full_name] = m + add_classes(mod, m, file) + graph << m + + unless mod.includes.empty? + mod.includes.each do |inc| + m_full_name = find_full_name(inc.name, mod) + if @local_names.include?(m_full_name) + @global_graph << DOT::Edge.new('from' => "#{m_full_name.gsub( /:/,'_' )}", + 'to' => "#{mod.full_name.gsub( /:/,'_' )}", + 'ltail' => "cluster_#{m_full_name.gsub( /:/,'_' )}", + 'lhead' => "cluster_#{mod.full_name.gsub( /:/,'_' )}") + else + unless @global_names.include?(m_full_name) + path = m_full_name.split("::") + url = File.join('classes', *path) + ".html" + @global_graph << DOT::Node.new('name' => "#{m_full_name.gsub( /:/,'_' )}", + 'shape' => 'box', + 'label' => "#{m_full_name}", + 'URL' => %{"#{url}"}) + @global_names << m_full_name + end + @global_graph << DOT::Edge.new('from' => "#{m_full_name.gsub( /:/,'_' )}", + 'to' => "#{mod.full_name.gsub( /:/,'_' )}", + 'lhead' => "cluster_#{mod.full_name.gsub( /:/,'_' )}") + end + end + end + end + + def add_classes(container, graph, file = nil ) + + use_fileboxes = @options.fileboxes + + files = {} + + # create dummy node (needed if empty and for module includes) + if container.full_name + graph << DOT::Node.new('name' => "#{container.full_name.gsub( /:/,'_' )}", + 'label' => "", + 'width' => (container.classes.empty? and + container.modules.empty?) ? + '0.75' : '0.01', + 'height' => '0.01', + 'shape' => 'plaintext') + end + + container.classes.each_with_index do |cl, cl_index| + last_file = cl.in_files[-1].relative_name + + if use_fileboxes && !files.include?(last_file) + @counter += 1 + files[last_file] = + DOT::Subgraph.new('name' => "cluster_#{@counter}", + 'label' => "#{last_file}", + 'fontname' => FONT, + 'color'=> + last_file == file ? 'red' : 'black') + end + + next if cl.name == 'Object' || cl.name[0,2] == "<<" + + url = cl.http_url("classes") + + label = cl.name.dup + if use_fileboxes && cl.in_files.length > 1 + label << '\n[' + + cl.in_files.collect {|i| + i.relative_name + }.sort.join( '\n' ) + + ']' + end + + attrs = { + 'name' => "#{cl.full_name.gsub( /:/, '_' )}", + 'fontcolor' => 'black', + 'style'=>'filled', + 'color'=>'palegoldenrod', + 'label' => label, + 'shape' => 'ellipse', + 'URL' => %{"#{url}"} + } + + c = DOT::Node.new(attrs) + + if use_fileboxes + files[last_file].push c + else + graph << c + end + end + + if use_fileboxes + files.each_value do |val| + graph << val + end + end + + unless container.classes.empty? + container.classes.each_with_index do |cl, cl_index| + cl.includes.each do |m| + m_full_name = find_full_name(m.name, cl) + if @local_names.include?(m_full_name) + @global_graph << DOT::Edge.new('from' => "#{m_full_name.gsub( /:/,'_' )}", + 'to' => "#{cl.full_name.gsub( /:/,'_' )}", + 'ltail' => "cluster_#{m_full_name.gsub( /:/,'_' )}") + else + unless @global_names.include?(m_full_name) + path = m_full_name.split("::") + url = File.join('classes', *path) + ".html" + @global_graph << DOT::Node.new('name' => "#{m_full_name.gsub( /:/,'_' )}", + 'shape' => 'box', + 'label' => "#{m_full_name}", + 'URL' => %{"#{url}"}) + @global_names << m_full_name + end + @global_graph << DOT::Edge.new('from' => "#{m_full_name.gsub( /:/,'_' )}", + 'to' => "#{cl.full_name.gsub( /:/, '_')}") + end + end + + sclass = cl.superclass + next if sclass.nil? || sclass == 'Object' + sclass_full_name = find_full_name(sclass,cl) + unless @local_names.include?(sclass_full_name) or @global_names.include?(sclass_full_name) + path = sclass_full_name.split("::") + url = File.join('classes', *path) + ".html" + @global_graph << DOT::Node.new('name' => "#{sclass_full_name.gsub( /:/, '_' )}", + 'label' => sclass_full_name, + 'URL' => %{"#{url}"}) + @global_names << sclass_full_name + end + @global_graph << DOT::Edge.new('from' => "#{sclass_full_name.gsub( /:/,'_' )}", + 'to' => "#{cl.full_name.gsub( /:/, '_')}") + end + end + + container.modules.each do |submod| + draw_module(submod, graph) + end + + end + + def convert_to_png(file_base, graph) + str = graph.to_s + return @diagram_cache[str] if @diagram_cache[str] + op_type = @options.image_format + dotfile = File.join(DOT_PATH, file_base) + src = dotfile + ".dot" + dot = dotfile + "." + op_type + + unless @options.quiet + $stderr.print "." + $stderr.flush + end + + File.open(src, 'w+' ) do |f| + f << str << "\n" + end + + system "dot", "-T#{op_type}", src, "-o", dot + + # Now construct the imagemap wrapper around + # that png + + ret = wrap_in_image_map(src, dot) + @diagram_cache[str] = ret + return ret + end + + ## + # Extract the client-side image map from dot, and use it to generate the + # imagemap proper. Return the whole .. combination, suitable for + # inclusion on the page + + def wrap_in_image_map(src, dot) + res = "" + dot_map = `dot -Tismap #{src}` + + if(!dot_map.empty?) + res << %{\n} + dot_map.split($/).each do |area| + unless area =~ /^rectangle \((\d+),(\d+)\) \((\d+),(\d+)\) ([\/\w.]+)\s*(.*)/ + $stderr.puts "Unexpected output from dot:\n#{area}" + return nil + end + + xs, ys = [$1.to_i, $3.to_i], [$2.to_i, $4.to_i] + url, area_name = $5, $6 + + res << %{ #{area_name}\n} + end + res << "\n" + end + + res << %{#{dot}} + return res + end + + end + +end diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/dot.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/dot.rb new file mode 100755 index 00000000..fbd2cfba --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/dot.rb @@ -0,0 +1,249 @@ +module RDoc; end + +module RDoc::DOT + + TAB = ' ' + TAB2 = TAB * 2 + + # options for node declaration + NODE_OPTS = [ + 'bgcolor', + 'color', + 'fontcolor', + 'fontname', + 'fontsize', + 'height', + 'width', + 'label', + 'layer', + 'rank', + 'shape', + 'shapefile', + 'style', + 'URL', + ] + + # options for edge declaration + EDGE_OPTS = [ + 'color', + 'decorate', + 'dir', + 'fontcolor', + 'fontname', + 'fontsize', + 'id', + 'label', + 'layer', + 'lhead', + 'ltail', + 'minlen', + 'style', + 'weight' + ] + + # options for graph declaration + GRAPH_OPTS = [ + 'bgcolor', + 'center', + 'clusterrank', + 'color', + 'compound', + 'concentrate', + 'fillcolor', + 'fontcolor', + 'fontname', + 'fontsize', + 'label', + 'layerseq', + 'margin', + 'mclimit', + 'nodesep', + 'nslimit', + 'ordering', + 'orientation', + 'page', + 'rank', + 'rankdir', + 'ranksep', + 'ratio', + 'size', + 'style', + 'URL' + ] + + # a root class for any element in dot notation + class SimpleElement + attr_accessor :name + + def initialize( params = {} ) + @label = params['name'] ? params['name'] : '' + end + + def to_s + @name + end + end + + # an element that has options ( node, edge or graph ) + class Element < SimpleElement + #attr_reader :parent + attr_accessor :name, :options + + def initialize( params = {}, option_list = [] ) + super( params ) + @name = params['name'] ? params['name'] : nil + @parent = params['parent'] ? params['parent'] : nil + @options = {} + option_list.each{ |i| + @options[i] = params[i] if params[i] + } + @options['label'] ||= @name if @name != 'node' + end + + def each_option + @options.each{ |i| yield i } + end + + def each_option_pair + @options.each_pair{ |key, val| yield key, val } + end + + #def parent=( thing ) + # @parent.delete( self ) if defined?( @parent ) and @parent + # @parent = thing + #end + end + + + # this is used when we build nodes that have shape=record + # ports don't have options :) + class Port < SimpleElement + attr_accessor :label + + def initialize( params = {} ) + super( params ) + @name = params['label'] ? params['label'] : '' + end + def to_s + ( @name && @name != "" ? "<#{@name}>" : "" ) + "#{@label}" + end + end + + # node element + class Node < Element + + def initialize( params = {}, option_list = NODE_OPTS ) + super( params, option_list ) + @ports = params['ports'] ? params['ports'] : [] + end + + def each_port + @ports.each{ |i| yield i } + end + + def << ( thing ) + @ports << thing + end + + def push ( thing ) + @ports.push( thing ) + end + + def pop + @ports.pop + end + + def to_s( t = '' ) + + label = @options['shape'] != 'record' && @ports.length == 0 ? + @options['label'] ? + t + TAB + "label = \"#{@options['label']}\"\n" : + '' : + t + TAB + 'label = "' + " \\\n" + + t + TAB2 + "#{@options['label']}| \\\n" + + @ports.collect{ |i| + t + TAB2 + i.to_s + }.join( "| \\\n" ) + " \\\n" + + t + TAB + '"' + "\n" + + t + "#{@name} [\n" + + @options.to_a.collect{ |i| + i[1] && i[0] != 'label' ? + t + TAB + "#{i[0]} = #{i[1]}" : nil + }.compact.join( ",\n" ) + ( label != '' ? ",\n" : "\n" ) + + label + + t + "]\n" + end + end + + # subgraph element is the same to graph, but has another header in dot + # notation + class Subgraph < Element + + def initialize( params = {}, option_list = GRAPH_OPTS ) + super( params, option_list ) + @nodes = params['nodes'] ? params['nodes'] : [] + @dot_string = 'subgraph' + end + + def each_node + @nodes.each{ |i| yield i } + end + + def << ( thing ) + @nodes << thing + end + + def push( thing ) + @nodes.push( thing ) + end + + def pop + @nodes.pop + end + + def to_s( t = '' ) + hdr = t + "#{@dot_string} #{@name} {\n" + + options = @options.to_a.collect{ |name, val| + val && name != 'label' ? + t + TAB + "#{name} = #{val}" : + name ? t + TAB + "#{name} = \"#{val}\"" : nil + }.compact.join( "\n" ) + "\n" + + nodes = @nodes.collect{ |i| + i.to_s( t + TAB ) + }.join( "\n" ) + "\n" + hdr + options + nodes + t + "}\n" + end + end + + # this is graph + class Digraph < Subgraph + def initialize( params = {}, option_list = GRAPH_OPTS ) + super( params, option_list ) + @dot_string = 'digraph' + end + end + + # this is edge + class Edge < Element + attr_accessor :from, :to + def initialize( params = {}, option_list = EDGE_OPTS ) + super( params, option_list ) + @from = params['from'] ? params['from'] : nil + @to = params['to'] ? params['to'] : nil + end + + def to_s( t = '' ) + t + "#{@from} -> #{to} [\n" + + @options.to_a.collect{ |i| + i[1] && i[0] != 'label' ? + t + TAB + "#{i[0]} = #{i[1]}" : + i[1] ? t + TAB + "#{i[0]} = \"#{i[1]}\"" : nil + }.compact.join( "\n" ) + "\n" + t + "]\n" + end + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator.rb new file mode 100755 index 00000000..b6500297 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator.rb @@ -0,0 +1,8 @@ +require 'rdoc' + +## +# Namespace for generators + +module RDoc::Generator +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/darkfish.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/darkfish.rb new file mode 100755 index 00000000..4e5791cd --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/darkfish.rb @@ -0,0 +1,455 @@ +#!ruby +# vim: noet ts=2 sts=8 sw=2 + +require 'rubygems' +gem 'rdoc', '>= 2.4' unless defined? $rdoc_rakefile + +require 'pp' +require 'pathname' +require 'fileutils' +require 'erb' +require 'yaml' + +require 'rdoc/rdoc' +require 'rdoc/generator' +require 'rdoc/generator/markup' + +# +# Darkfish RDoc HTML Generator +# +# $Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $ +# +# == Author/s +# * Michael Granger (ged@FaerieMUD.org) +# +# == Contributors +# * Mahlon E. Smith (mahlon@martini.nu) +# * Eric Hodel (drbrain@segment7.net) +# +# == License +# +# Copyright (c) 2007, 2008, Michael Granger. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the author/s, nor the names of the project's +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +class RDoc::Generator::Darkfish + + RDoc::RDoc.add_generator( self ) + + include ERB::Util + + # Subversion rev + SVNRev = %$Rev: 52 $ + + # Subversion ID + SVNId = %$Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $ + + # Path to this file's parent directory. Used to find templates and other + # resources. + GENERATOR_DIR = File.join 'rdoc', 'generator' + + # Release Version + VERSION = '1.1.6' + + # Directory where generated classes live relative to the root + CLASS_DIR = nil + + # Directory where generated files live relative to the root + FILE_DIR = nil + + + ################################################################# + ### C L A S S M E T H O D S + ################################################################# + + ### Standard generator factory method + def self::for( options ) + new( options ) + end + + + ################################################################# + ### I N S T A N C E M E T H O D S + ################################################################# + + ### Initialize a few instance variables before we start + def initialize( options ) + @options = options + @options.diagram = false + + template = @options.template || 'darkfish' + + template_dir = $LOAD_PATH.map do |path| + File.join path, GENERATOR_DIR, 'template', template + end.find do |dir| + File.directory? dir + end + + raise RDoc::Error, "could not find template #{template.inspect}" unless + template_dir + + @template_dir = Pathname.new File.expand_path(template_dir) + + @files = nil + @classes = nil + + @basedir = Pathname.pwd.expand_path + end + + ###### + public + ###### + + # The output directory + attr_reader :outputdir + + + ### Output progress information if debugging is enabled + def debug_msg( *msg ) + return unless $DEBUG_RDOC + $stderr.puts( *msg ) + end + + def class_dir + CLASS_DIR + end + + def file_dir + FILE_DIR + end + + ### Create the directories the generated docs will live in if + ### they don't already exist. + def gen_sub_directories + @outputdir.mkpath + end + + ### Copy over the stylesheet into the appropriate place in the output + ### directory. + def write_style_sheet + debug_msg "Copying static files" + options = { :verbose => $DEBUG_RDOC, :noop => $dryrun } + + FileUtils.cp @template_dir + 'rdoc.css', '.', options + + Dir[(@template_dir + "{js,images}/**/*").to_s].each do |path| + next if File.directory? path + next if path =~ /#{File::SEPARATOR}\./ + + dst = Pathname.new(path).relative_path_from @template_dir + + # I suck at glob + dst_dir = dst.dirname + FileUtils.mkdir_p dst_dir, options unless File.exist? dst_dir + + FileUtils.cp @template_dir + path, dst, options + end + end + + ### Build the initial indices and output objects + ### based on an array of TopLevel objects containing + ### the extracted information. + def generate( top_levels ) + @outputdir = Pathname.new( @options.op_dir ).expand_path( @basedir ) + + @files = top_levels.sort + @classes = RDoc::TopLevel.all_classes_and_modules.sort + @methods = @classes.map { |m| m.method_list }.flatten.sort + @modsort = get_sorted_module_list( @classes ) + + # Now actually write the output + write_style_sheet + generate_index + generate_class_files + generate_file_files + + rescue StandardError => err + debug_msg "%s: %s\n %s" % [ err.class.name, err.message, err.backtrace.join("\n ") ] + raise + end + + ######### + protected + ######### + + ### Return a list of the documented modules sorted by salience first, then + ### by name. + def get_sorted_module_list( classes ) + nscounts = classes.inject({}) do |counthash, klass| + top_level = klass.full_name.gsub( /::.*/, '' ) + counthash[top_level] ||= 0 + counthash[top_level] += 1 + + counthash + end + + # Sort based on how often the top level namespace occurs, and then on the + # name of the module -- this works for projects that put their stuff into + # a namespace, of course, but doesn't hurt if they don't. + classes.sort_by do |klass| + top_level = klass.full_name.gsub( /::.*/, '' ) + [ + nscounts[ top_level ] * -1, + klass.full_name + ] + end.select do |klass| + klass.document_self + end + end + + ### Generate an index page which lists all the classes which + ### are documented. + def generate_index + debug_msg "Rendering the index page..." + + templatefile = @template_dir + 'index.rhtml' + template_src = templatefile.read + template = ERB.new( template_src, nil, '<>' ) + template.filename = templatefile.to_s + context = binding() + + output = nil + + begin + output = template.result( context ) + rescue NoMethodError => err + raise RDoc::Error, "Error while evaluating %s: %s (at %p)" % [ + templatefile, + err.message, + eval( "_erbout[-50,50]", context ) + ], err.backtrace + end + + outfile = @basedir + @options.op_dir + 'index.html' + unless $dryrun + debug_msg "Outputting to %s" % [outfile.expand_path] + outfile.open( 'w', 0644 ) do |fh| + fh.print( output ) + end + else + debug_msg "Would have output to %s" % [outfile.expand_path] + end + end + + ### Generate a documentation file for each class + def generate_class_files + debug_msg "Generating class documentation in #@outputdir" + templatefile = @template_dir + 'classpage.rhtml' + + @classes.each do |klass| + debug_msg " working on %s (%s)" % [ klass.full_name, klass.path ] + outfile = @outputdir + klass.path + rel_prefix = @outputdir.relative_path_from( outfile.dirname ) + svninfo = self.get_svninfo( klass ) + + debug_msg " rendering #{outfile}" + self.render_template( templatefile, binding(), outfile ) + end + end + + ### Generate a documentation file for each file + def generate_file_files + debug_msg "Generating file documentation in #@outputdir" + templatefile = @template_dir + 'filepage.rhtml' + + @files.each do |file| + outfile = @outputdir + file.path + debug_msg " working on %s (%s)" % [ file.full_name, outfile ] + rel_prefix = @outputdir.relative_path_from( outfile.dirname ) + context = binding() + + debug_msg " rendering #{outfile}" + self.render_template( templatefile, binding(), outfile ) + end + end + + + ### Return a string describing the amount of time in the given number of + ### seconds in terms a human can understand easily. + def time_delta_string( seconds ) + return 'less than a minute' if seconds < 1.minute + return (seconds / 1.minute).to_s + ' minute' + (seconds/60 == 1 ? '' : 's') if seconds < 50.minutes + return 'about one hour' if seconds < 90.minutes + return (seconds / 1.hour).to_s + ' hours' if seconds < 18.hours + return 'one day' if seconds < 1.day + return 'about one day' if seconds < 2.days + return (seconds / 1.day).to_s + ' days' if seconds < 1.week + return 'about one week' if seconds < 2.week + return (seconds / 1.week).to_s + ' weeks' if seconds < 3.months + return (seconds / 1.month).to_s + ' months' if seconds < 1.year + return (seconds / 1.year).to_s + ' years' + end + + + # %q$Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $" + SVNID_PATTERN = / + \$Id:\s + (\S+)\s # filename + (\d+)\s # rev + (\d{4}-\d{2}-\d{2})\s # Date (YYYY-MM-DD) + (\d{2}:\d{2}:\d{2}Z)\s # Time (HH:MM:SSZ) + (\w+)\s # committer + \$$ + /x + + ### Try to extract Subversion information out of the first constant whose value looks like + ### a subversion Id tag. If no matching constant is found, and empty hash is returned. + def get_svninfo( klass ) + constants = klass.constants or return {} + + constants.find {|c| c.value =~ SVNID_PATTERN } or return {} + + filename, rev, date, time, committer = $~.captures + commitdate = Time.parse( date + ' ' + time ) + + return { + :filename => filename, + :rev => Integer( rev ), + :commitdate => commitdate, + :commitdelta => time_delta_string( Time.now.to_i - commitdate.to_i ), + :committer => committer, + } + end + + + ### Load and render the erb template in the given +templatefile+ within the + ### specified +context+ (a Binding object) and write it out to +outfile+. + ### Both +templatefile+ and +outfile+ should be Pathname-like objects. + + def render_template( templatefile, context, outfile ) + template_src = templatefile.read + template = ERB.new( template_src, nil, '<>' ) + template.filename = templatefile.to_s + + output = begin + template.result( context ) + rescue NoMethodError => err + raise RDoc::Error, "Error while evaluating %s: %s (at %p)" % [ + templatefile.to_s, + err.message, + eval( "_erbout[-50,50]", context ) + ], err.backtrace + end + + unless $dryrun + outfile.dirname.mkpath + outfile.open( 'w', 0644 ) do |ofh| + ofh.print( output ) + end + else + debug_msg " would have written %d bytes to %s" % + [ output.length, outfile ] + end + end + +end # Roc::Generator::Darkfish + +# :stopdoc: + +### Time constants +module TimeConstantMethods # :nodoc: + + ### Number of seconds (returns receiver unmodified) + def seconds + return self + end + alias_method :second, :seconds + + ### Returns number of seconds in minutes + def minutes + return self * 60 + end + alias_method :minute, :minutes + + ### Returns the number of seconds in hours + def hours + return self * 60.minutes + end + alias_method :hour, :hours + + ### Returns the number of seconds in days + def days + return self * 24.hours + end + alias_method :day, :days + + ### Return the number of seconds in weeks + def weeks + return self * 7.days + end + alias_method :week, :weeks + + ### Returns the number of seconds in fortnights + def fortnights + return self * 2.weeks + end + alias_method :fortnight, :fortnights + + ### Returns the number of seconds in months (approximate) + def months + return self * 30.days + end + alias_method :month, :months + + ### Returns the number of seconds in years (approximate) + def years + return (self * 365.25.days).to_i + end + alias_method :year, :years + + + ### Returns the Time number of seconds before the + ### specified +time+. E.g., 2.hours.before( header.expiration ) + def before( time ) + return time - self + end + + + ### Returns the Time number of seconds ago. (e.g., + ### expiration > 2.hours.ago ) + def ago + return self.before( ::Time.now ) + end + + + ### Returns the Time number of seconds after the given +time+. + ### E.g., 10.minutes.after( header.expiration ) + def after( time ) + return time + self + end + + # Reads best without arguments: 10.minutes.from_now + def from_now + return self.after( ::Time.now ) + end +end # module TimeConstantMethods + + +# Extend Numeric with time constants +class Numeric # :nodoc: + include TimeConstantMethods +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/markup.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/markup.rb new file mode 100755 index 00000000..c492483b --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/markup.rb @@ -0,0 +1,194 @@ +require 'rdoc/code_objects' +require 'rdoc/generator' +require 'rdoc/markup/to_html_crossref' + +## +# Handle common HTML markup tasks for various CodeObjects + +module RDoc::Generator::Markup + + ## + # Generates a relative URL from this object's path to +target_path+ + + def aref_to(target_path) + RDoc::Markup::ToHtml.gen_relative_url path, target_path + end + + ## + # Generates a relative URL from +from_path+ to this object's path + + def as_href(from_path) + RDoc::Markup::ToHtml.gen_relative_url from_path, path + end + + ## + # Handy wrapper for marking up this object's comment + + def description + markup @comment + end + + ## + # RDoc::Markup formatter object + + def formatter + return @formatter if defined? @formatter + + show_hash = RDoc::RDoc.current.options.show_hash + this = RDoc::Context === self ? self : @parent + @formatter = RDoc::Markup::ToHtmlCrossref.new this.path, this, show_hash + end + + ## + # Convert a string in markup format into HTML. + + def markup(str, remove_para = false) + return '' unless str + + # Convert leading comment markers to spaces, but only if all non-blank + # lines have them + if str =~ /^(?>\s*)[^\#]/ then + content = str + else + content = str.gsub(/^\s*(#+)/) { $1.tr '#', ' ' } + end + + res = formatter.convert content + + if remove_para then + res.sub!(/^

/, '') + res.sub!(/<\/p>$/, '') + end + + res + end + + ## + # Build a webcvs URL starting for the given +url+ with +full_path+ appended + # as the destination path. If +url+ contains '%s' +full_path+ will be + # sprintf'd into +url+ instead. + + def cvs_url(url, full_path) + if /%s/ =~ url then + sprintf url, full_path + else + url + full_path + end + end + +end + +class RDoc::AnyMethod + + include RDoc::Generator::Markup + + ## + # Prepend +src+ with line numbers. Relies on the first line of a source + # code listing having: + # + # # File xxxxx, line dddd + + def add_line_numbers(src) + if src =~ /\A.*, line (\d+)/ then + first = $1.to_i - 1 + last = first + src.count("\n") + size = last.to_s.length + + line = first + src.gsub!(/^/) do + res = if line == first then + " " * (size + 2) + else + "%#{size}d: " % line + end + + line += 1 + res + end + end + end + + ## + # Turns the method's token stream into HTML + + def markup_code + return '' unless @token_stream + + src = "" + + @token_stream.each do |t| + next unless t + # style = STYLE_MAP[t.class] + style = case t + when RDoc::RubyToken::TkCONSTANT then "ruby-constant" + when RDoc::RubyToken::TkKW then "ruby-keyword kw" + when RDoc::RubyToken::TkIVAR then "ruby-ivar" + when RDoc::RubyToken::TkOp then "ruby-operator" + when RDoc::RubyToken::TkId then "ruby-identifier" + when RDoc::RubyToken::TkNode then "ruby-node" + when RDoc::RubyToken::TkCOMMENT then "ruby-comment cmt" + when RDoc::RubyToken::TkREGEXP then "ruby-regexp re" + when RDoc::RubyToken::TkSTRING then "ruby-value str" + when RDoc::RubyToken::TkVal then "ruby-value" + else + nil + end + + text = CGI.escapeHTML(t.text) + + if style + src << "#{text}" + else + src << text + end + end + + add_line_numbers src if RDoc::RDoc.current.options.include_line_numbers + + src + end + +end + +class RDoc::Attr + + include RDoc::Generator::Markup + +end + +class RDoc::Constant + + include RDoc::Generator::Markup + +end + +class RDoc::Context + + include RDoc::Generator::Markup + +end + +class RDoc::Context::Section + + include RDoc::Generator::Markup + +end + +class RDoc::TopLevel + + ## + # Returns a URL for this source file on some web repository. Use the -W + # command line option to set. + + def cvs_url + url = RDoc::RDoc.current.options.webcvs + + if /%s/ =~ url then + url % @absolute_name + else + url + @absolute_name + end + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/ri.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/ri.rb new file mode 100755 index 00000000..44fc97d7 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/ri.rb @@ -0,0 +1,230 @@ +require 'rdoc/generator' +require 'rdoc/markup/to_flow' + +require 'rdoc/ri/cache' +require 'rdoc/ri/reader' +require 'rdoc/ri/writer' +require 'rdoc/ri/descriptions' + +class RDoc::Generator::RI + + RDoc::RDoc.add_generator self + + ## + # Generator may need to return specific subclasses depending on the + # options they are passed. Because of this we create them using a factory + + def self.for(options) + new(options) + end + + ## + # Set up a new ri generator + + def initialize(options) #:not-new: + @options = options + @ri_writer = RDoc::RI::Writer.new "." + @markup = RDoc::Markup.new + @to_flow = RDoc::Markup::ToFlow.new + + @generated = {} + end + + ## + # Build the initial indices and output objects based on an array of + # TopLevel objects containing the extracted information. + + def generate(top_levels) + RDoc::TopLevel.all_classes_and_modules.each do |cls| + process_class cls + end + end + + def process_class(from_class) + generate_class_info(from_class) + + # now recurse into this class' constituent classes + from_class.each_classmodule do |mod| + process_class(mod) + end + end + + def generate_class_info(cls) + case cls + when RDoc::NormalModule then + cls_desc = RDoc::RI::ModuleDescription.new + else + cls_desc = RDoc::RI::ClassDescription.new + superclass = cls.superclass + superclass = superclass.full_name unless String === superclass + cls_desc.superclass = superclass + end + + cls_desc.name = cls.name + cls_desc.full_name = cls.full_name + cls_desc.comment = markup(cls.comment) + + cls_desc.attributes = cls.attributes.sort.map do |a| + RDoc::RI::Attribute.new(a.name, a.rw, markup(a.comment)) + end + + cls_desc.constants = cls.constants.map do |c| + RDoc::RI::Constant.new(c.name, c.value, markup(c.comment)) + end + + cls_desc.includes = cls.includes.map do |i| + RDoc::RI::IncludedModule.new(i.name) + end + + class_methods, instance_methods = method_list(cls) + + cls_desc.class_methods = class_methods.map do |m| + RDoc::RI::MethodSummary.new(m.name) + end + + cls_desc.instance_methods = instance_methods.map do |m| + RDoc::RI::MethodSummary.new(m.name) + end + + update_or_replace(cls_desc) + + class_methods.each do |m| + generate_method_info(cls_desc, m) + end + + instance_methods.each do |m| + generate_method_info(cls_desc, m) + end + end + + def generate_method_info(cls_desc, method) + meth_desc = RDoc::RI::MethodDescription.new + meth_desc.name = method.name + meth_desc.full_name = cls_desc.full_name + if method.singleton + meth_desc.full_name += "::" + else + meth_desc.full_name += "#" + end + meth_desc.full_name << method.name + + meth_desc.comment = markup(method.comment) + meth_desc.params = params_of(method) + meth_desc.visibility = method.visibility.to_s + meth_desc.is_singleton = method.singleton + meth_desc.block_params = method.block_params + + meth_desc.aliases = method.aliases.map do |a| + RDoc::RI::AliasName.new(a.name) + end + + @ri_writer.add_method(cls_desc, meth_desc) + end + + private + + ## + # Returns a list of class and instance methods that we'll be documenting + + def method_list(cls) + list = cls.method_list + unless @options.show_all + list = list.find_all do |m| + m.visibility == :public || m.visibility == :protected || m.force_documentation + end + end + + c = [] + i = [] + list.sort.each do |m| + if m.singleton + c << m + else + i << m + end + end + return c,i + end + + def params_of(method) + if method.call_seq + method.call_seq + else + params = method.params || "" + + p = params.gsub(/\s*\#.*/, '') + p = p.tr("\n", " ").squeeze(" ") + p = "(" + p + ")" unless p[0] == ?( + + if (block = method.block_params) + block.gsub!(/\s*\#.*/, '') + block = block.tr("\n", " ").squeeze(" ") + if block[0] == ?( + block.sub!(/^\(/, '').sub!(/\)/, '') + end + p << " {|#{block.strip}| ...}" + end + p + end + end + + def markup(comment) + return nil if !comment || comment.empty? + + # Convert leading comment markers to spaces, but only + # if all non-blank lines have them + + if comment =~ /^(?>\s*)[^\#]/ + content = comment + else + content = comment.gsub(/^\s*(#+)/) { $1.tr('#',' ') } + end + @markup.convert(content, @to_flow) + end + + ## + # By default we replace existing classes with the same name. If the + # --merge option was given, we instead merge this definition into an + # existing class. We add our methods, aliases, etc to that class, but do + # not change the class's description. + + def update_or_replace(cls_desc) + old_cls = nil + + if @options.merge + rdr = RDoc::RI::Reader.new RDoc::RI::Cache.new(@options.op_dir) + + namespace = rdr.top_level_namespace + namespace = rdr.lookup_namespace_in(cls_desc.name, namespace) + if namespace.empty? + $stderr.puts "You asked me to merge this source into existing " + $stderr.puts "documentation. This file references a class or " + $stderr.puts "module called #{cls_desc.name} which I don't" + $stderr.puts "have existing documentation for." + $stderr.puts + $stderr.puts "Perhaps you need to generate its documentation first" + exit 1 + else + old_cls = namespace[0] + end + end + + prev_cls = @generated[cls_desc.full_name] + + if old_cls and not prev_cls then + old_desc = rdr.get_class old_cls + cls_desc.merge_in old_desc + end + + if prev_cls then + cls_desc.merge_in prev_cls + end + + @generated[cls_desc.full_name] = cls_desc + + @ri_writer.remove_class cls_desc + @ri_writer.add_class cls_desc + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/.document b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/.document new file mode 100755 index 00000000..e69de29b diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/classpage.rhtml b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/classpage.rhtml new file mode 100755 index 00000000..921fcef7 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/classpage.rhtml @@ -0,0 +1,281 @@ + + + + + + + <%= klass.type.capitalize %>: <%= klass.full_name %> + + + + + + + + + + + +

+
+
+

In Files

+
+ +
+
+ + <% if !svninfo.empty? %> +
+

Subversion Info

+
+
+
Rev
+
<%= svninfo[:rev] %>
+ +
Last Checked In
+
<%= svninfo[:commitdate].strftime('%Y-%m-%d %H:%M:%S') %> + (<%= svninfo[:commitdelta] %> ago)
+ +
Checked in by
+
<%= svninfo[:committer] %>
+
+
+
+ <% end %> +
+ +
+ + + <% if klass.type == 'class' %> +
+

Parent

+ <% unless String === klass.superclass %> + + <% else %> + + <% end %> +
+ <% end %> + + + <% unless klass.classes_and_modules.empty? %> +
+

Namespace

+ +
+ <% end %> + + + <% unless klass.method_list.empty? %> +
+

Methods

+ +
+ <% end %> + + + <% unless klass.includes.empty? %> +
+

Included Modules

+ +
+ <% end %> +
+ +
+ <% simple_files = @files.select {|tl| tl.parser == RDoc::Parser::Simple } %> + <% unless simple_files.empty? then %> +
+

Files

+ +
+ <% end %> + +
+

Class Index + [+]

+
+
+ Quicksearch + +
+
+ + + +
+ + <% if $DEBUG_RDOC %> +
toggle debugging
+ <% end %> +
+
+ +
+

<%= klass.full_name %>

+ +
+ <%= klass.description %> +
+ + + <% unless klass.constants.empty? %> +
+

Constants

+
+ <% klass.each_constant do |const| %> +
<%= const.name %>
+ <% if const.comment %> +
<%= const.description.strip %>
+ <% else %> +
(Not documented)
+ <% end %> + <% end %> +
+
+ <% end %> + + + <% unless klass.attributes.empty? %> +
+

Attributes

+ + <% klass.each_attribute do |attrib| %> +
+ + <% if attrib.rw =~ /w/i %> + + <% end %> +
+ <%= h attrib.name %>[<%= attrib.rw %>] +
+ +
+ <% if attrib.comment %> + <%= attrib.description.strip %> + <% else %> +

(Not documented)

+ <% end %> +
+
+ <% end %> +
+ <% end %> + + + <% klass.methods_by_type.each do |type, visibilities| + next if visibilities.empty? + visibilities.each do |visibility, methods| + next if methods.empty? %> +
+

<%= visibility.to_s.capitalize %> <%= type.capitalize %> Methods

+ + <% methods.each do |method| %> +
"> + + +
+ <% if method.call_seq %> + <%= method.call_seq.strip.gsub(/->/, '→').gsub( /^\w.*?\./m, '') %> + click to toggle source + <% else %> + <%= h method.name %><%= method.params %> + click to toggle source + <% end %> +
+ +
+ <% if method.comment %> + <%= method.description.strip %> + <% else %> +

(Not documented)

+ <% end %> + + <% if method.token_stream %> +
+
+<%= method.markup_code %>
+
+
+ <% end %> +
+ + <% unless method.aliases.empty? %> +
+ Also aliased as: <%= method.aliases.map do |aka| + %{#{h aka.name}} + end.join(", ") %> +
+ <% end %> +
+ + <% end %> +
+ <% end + end %> + +
+ + +
+ <% if $DEBUG_RDOC + require 'pp' %> +
<%= h PP.pp(klass, _erbout) %>
+
+ <% else %> +

Disabled; run with --debug to generate this.

+ <% end %> + + +
+

[Validate]

+

Generated with the Darkfish + Rdoc Generator <%= RDoc::Generator::Darkfish::VERSION %>.

+
+ + + + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/filepage.rhtml b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/filepage.rhtml new file mode 100755 index 00000000..2627e896 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/filepage.rhtml @@ -0,0 +1,114 @@ + + + + + + + + File: <%= file.base_name %> [<%= @options.title %>] + + + + + + + + + +<% if file.parser == RDoc::Parser::Simple %> + +
+
+ <% simple_files = @files.select { |f| f.parser == RDoc::Parser::Simple } %> + <% unless simple_files.empty? then %> +
+

Files

+ +
+ <% end %> + +
+

Class Index + [+]

+
+
+ Quicksearch + +
+
+ + + +
+ + <% if $DEBUG_RDOC %> +
toggle debugging
+ <% end %> +
+
+ +
+ <%= file.description %> +
+ +
+

[Validate]

+

Generated with the Darkfish + Rdoc Generator <%= RDoc::Generator::Darkfish::VERSION %>.

+
+ +<% else %> + +
+
+
Last Modified
+
<%= file.last_modified %>
+ + <% if file.requires %> +
Requires
+
+
    + <% file.requires.each do |require| %> +
  • <%= require.name %>
  • + <% end %> +
+
+ <% end %> + + <% if @options.webcvs %> +
Trac URL
+
<%= file.cvs_url %>
+ <% end %> +
+
+ +
+ <% if file.comment %> +
+

Description

+ <%= file.description %> +
+ <% end %> +
+ +<% end %> + + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/brick.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/brick.png new file mode 100755 index 00000000..7851cf34 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/brick.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/brick_link.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/brick_link.png new file mode 100755 index 00000000..9ebf013a Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/brick_link.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bug.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bug.png new file mode 100755 index 00000000..2d5fb90e Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bug.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bullet_black.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bullet_black.png new file mode 100755 index 00000000..57619706 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bullet_black.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png new file mode 100755 index 00000000..b47ce55f Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png new file mode 100755 index 00000000..9ab4a896 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/date.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/date.png new file mode 100755 index 00000000..783c8335 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/date.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/find.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/find.png new file mode 100755 index 00000000..15474796 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/find.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif new file mode 100755 index 00000000..82290f48 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png new file mode 100755 index 00000000..c6473b32 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/package.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/package.png new file mode 100755 index 00000000..da3c2a2d Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/package.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/page_green.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/page_green.png new file mode 100755 index 00000000..de8e003f Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/page_green.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/page_white_text.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/page_white_text.png new file mode 100755 index 00000000..813f712f Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/page_white_text.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/page_white_width.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/page_white_width.png new file mode 100755 index 00000000..1eb88094 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/page_white_width.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/plugin.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/plugin.png new file mode 100755 index 00000000..6187b15a Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/plugin.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/ruby.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/ruby.png new file mode 100755 index 00000000..f763a168 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/ruby.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/tag_green.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/tag_green.png new file mode 100755 index 00000000..83ec984b Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/tag_green.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/wrench.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/wrench.png new file mode 100755 index 00000000..5c8213fe Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/wrench.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/wrench_orange.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/wrench_orange.png new file mode 100755 index 00000000..565a9330 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/wrench_orange.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/zoom.png b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/zoom.png new file mode 100755 index 00000000..908612e3 Binary files /dev/null and b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/images/zoom.png differ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/index.rhtml b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/index.rhtml new file mode 100755 index 00000000..21c06760 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/index.rhtml @@ -0,0 +1,64 @@ + + + + + + + + <%= h @options.title %> + + + + + + + + + + + + <% $stderr.sync = true %> +

<%= h @options.title %>

+ + <% if @options.main_page && main_page = @files.find { |f| f.full_name == @options.main_page } %> +
+ <%= main_page.description.sub(%r{^\s*}i, '') %> +
+ <% else %> +

This is the API documentation for '<%= @options.title %>'.

+ <% end %> + + <% simple_files = @files.select {|tl| tl.parser == RDoc::Parser::Simple } %> + <% unless simple_files.empty? then %> +

Files

+ + <% end %> + +

Classes/Modules

+ + +

Methods

+ + +
+

[Validate]

+

Generated with the Darkfish + Rdoc Generator <%= RDoc::Generator::Darkfish::VERSION %>.

+
+ + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/darkfish.js b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/darkfish.js new file mode 100755 index 00000000..43528fdd --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/darkfish.js @@ -0,0 +1,116 @@ +/** + * + * Darkfish Page Functions + * $Id: darkfish.js 53 2009-01-07 02:52:03Z deveiant $ + * + * Author: Michael Granger + * + */ + +/* Provide console simulation for firebug-less environments */ +if (!("console" in window) || !("firebug" in console)) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", + "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; + + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +}; + + +/** + * Unwrap the first element that matches the given @expr@ from the targets and return them. + */ +$.fn.unwrap = function( expr ) { + return this.each( function() { + $(this).parents( expr ).eq( 0 ).after( this ).remove(); + }); +}; + + +function showSource( e ) { + var target = e.target; + var codeSections = $(target). + parents('.method-detail'). + find('.method-source-code'); + + $(target). + parents('.method-detail'). + find('.method-source-code'). + slideToggle(); +}; + +function hookSourceViews() { + $('.method-description,.method-heading').click( showSource ); +}; + +function toggleDebuggingSection() { + $('.debugging-section').slideToggle(); +}; + +function hookDebuggingToggle() { + $('#debugging-toggle img').click( toggleDebuggingSection ); +}; + +function hookQuickSearch() { + $('.quicksearch-field').each( function() { + var searchElems = $(this).parents('.section').find( 'li' ); + var toggle = $(this).parents('.section').find('h3 .search-toggle'); + // console.debug( "Toggle is: %o", toggle ); + var qsbox = $(this).parents('form').get( 0 ); + + $(this).quicksearch( this, searchElems, { + noSearchResultsIndicator: 'no-class-search-results', + focusOnLoad: false + }); + $(toggle).click( function() { + // console.debug( "Toggling qsbox: %o", qsbox ); + $(qsbox).toggle(); + }); + }); +}; + +function highlightTarget( anchor ) { + console.debug( "Highlighting target '%s'.", anchor ); + + $("a[name=" + anchor + "]").each( function() { + if ( !$(this).parent().parent().hasClass('target-section') ) { + console.debug( "Wrapping the target-section" ); + $('div.method-detail').unwrap( 'div.target-section' ); + $(this).parent().wrap( '
' ); + } else { + console.debug( "Already wrapped." ); + } + }); +}; + +function highlightLocationTarget() { + console.debug( "Location hash: %s", window.location.hash ); + if ( ! window.location.hash || window.location.hash.length == 0 ) return; + + var anchor = window.location.hash.substring(1); + console.debug( "Found anchor: %s; matching %s", anchor, "a[name=" + anchor + "]" ); + + highlightTarget( anchor ); +}; + +function highlightClickTarget( event ) { + console.debug( "Highlighting click target for event %o", event.target ); + try { + var anchor = $(event.target).attr( 'href' ).substring(1); + console.debug( "Found target anchor: %s", anchor ); + highlightTarget( anchor ); + } catch ( err ) { + console.error( "Exception while highlighting: %o", err ); + }; +}; + + +$(document).ready( function() { + hookSourceViews(); + hookDebuggingToggle(); + hookQuickSearch(); + highlightLocationTarget(); + + $('ul.link-list a').bind( "click", highlightClickTarget ); +}); diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/jquery.js b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/jquery.js new file mode 100755 index 00000000..afe9e74c --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/jquery.js @@ -0,0 +1,32 @@ +/* + * jQuery 1.2.6 - New Wave Javascript + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2008-09-25 09:50:52 -0700 (Thu, 25 Sep 2008) $ + * $Rev: 38 $ + */ +(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else +return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else +return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else +selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else +this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else +return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else +jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
","
"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else +ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&¬xml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else +while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else +for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else +xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else +jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else +s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})(); \ No newline at end of file diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/quicksearch.js b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/quicksearch.js new file mode 100755 index 00000000..332772ac --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/quicksearch.js @@ -0,0 +1,114 @@ +/** + * + * JQuery QuickSearch - Hook up a form field to hide non-matching elements. + * $Id: quicksearch.js 53 2009-01-07 02:52:03Z deveiant $ + * + * Author: Michael Granger + * + */ +jQuery.fn.quicksearch = function( target, searchElems, options ) { + // console.debug( "Quicksearch fn" ); + + var settings = { + delay: 250, + clearButton: false, + highlightMatches: false, + focusOnLoad: false, + noSearchResultsIndicator: null + }; + if ( options ) $.extend( settings, options ); + + return jQuery(this).each( function() { + // console.debug( "Creating a new quicksearch on %o for %o", this, searchElems ); + new jQuery.quicksearch( this, searchElems, settings ); + }); +}; + + +jQuery.quicksearch = function( searchBox, searchElems, settings ) { + var timeout; + var boxdiv = $(searchBox).parents('div').eq(0); + + function init() { + setupKeyEventHandlers(); + focusOnLoad(); + }; + + function setupKeyEventHandlers() { + // console.debug( "Hooking up the 'keypress' event to %o", searchBox ); + $(searchBox). + unbind( 'keyup' ). + keyup( function(e) { return onSearchKey( e.keyCode ); }); + $(searchBox). + unbind( 'keypress' ). + keypress( function(e) { + switch( e.which ) { + // Execute the search on Enter, Tab, or Newline + case 9: + case 13: + case 10: + clearTimeout( timeout ); + e.preventDefault(); + doQuickSearch(); + break; + + // Allow backspace + case 8: + return true; + break; + + // Only allow valid search characters + default: + return validQSChar( e.charCode ); + } + }); + }; + + function focusOnLoad() { + if ( !settings.focusOnLoad ) return false; + $(searchBox).focus(); + }; + + function onSearchKey ( code ) { + clearTimeout( timeout ); + // console.debug( "...scheduling search." ); + timeout = setTimeout( doQuickSearch, settings.delay ); + }; + + function validQSChar( code ) { + var c = String.fromCharCode( code ); + return ( + (c == ':') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') + ); + }; + + function doQuickSearch() { + var searchText = searchBox.value; + var pat = new RegExp( searchText, "im" ); + var shownCount = 0; + + if ( settings.noSearchResultsIndicator ) { + $('#' + settings.noSearchResultsIndicator).hide(); + } + + // All elements start out hidden + $(searchElems).each( function(index) { + var str = $(this).text(); + + if ( pat.test(str) ) { + shownCount += 1; + $(this).fadeIn(); + } else { + $(this).hide(); + } + }); + + if ( shownCount == 0 && settings.noSearchResultsIndicator ) { + $('#' + settings.noSearchResultsIndicator).slideDown(); + } + }; + + init(); +}; diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/thickbox-compressed.js b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/thickbox-compressed.js new file mode 100755 index 00000000..3a3fdae1 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/generator/template/darkfish/js/thickbox-compressed.js @@ -0,0 +1,10 @@ +/* + * Thickbox 3 - One Box To Rule Them All. + * By Cody Lindley (http://www.codylindley.com) + * Copyright (c) 2007 cody lindley + * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php +*/ + +var tb_pathToImage = "../images/loadingAnimation.gif"; + +eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('$(o).2S(9(){1u(\'a.18, 3n.18, 3i.18\');1w=1p 1t();1w.L=2H});9 1u(b){$(b).s(9(){6 t=X.Q||X.1v||M;6 a=X.u||X.23;6 g=X.1N||P;19(t,a,g);X.2E();H P})}9 19(d,f,g){3m{3(2t o.v.J.2i==="2g"){$("v","11").r({A:"28%",z:"28%"});$("11").r("22","2Z");3(o.1Y("1F")===M){$("v").q("<4 5=\'B\'><4 5=\'8\'>");$("#B").s(G)}}n{3(o.1Y("B")===M){$("v").q("<4 5=\'B\'><4 5=\'8\'>");$("#B").s(G)}}3(1K()){$("#B").1J("2B")}n{$("#B").1J("2z")}3(d===M){d=""}$("v").q("<4 5=\'K\'><1I L=\'"+1w.L+"\' />");$(\'#K\').2y();6 h;3(f.O("?")!==-1){h=f.3l(0,f.O("?"))}n{h=f}6 i=/\\.2s$|\\.2q$|\\.2m$|\\.2l$|\\.2k$/;6 j=h.1C().2h(i);3(j==\'.2s\'||j==\'.2q\'||j==\'.2m\'||j==\'.2l\'||j==\'.2k\'){1D="";1G="";14="";1z="";1x="";R="";1n="";1r=P;3(g){E=$("a[@1N="+g+"]").36();25(D=0;((D&1d;&1d;2T &2R;"}n{1D=E[D].Q;1G=E[D].u;14="<1e 5=\'1U\'>&1d;&1d;&2O; 2N"}}n{1r=1b;1n="1t "+(D+1)+" 2L "+(E.1c)}}}S=1p 1t();S.1g=9(){S.1g=M;6 a=2x();6 x=a[0]-1M;6 y=a[1]-1M;6 b=S.z;6 c=S.A;3(b>x){c=c*(x/b);b=x;3(c>y){b=b*(y/c);c=y}}n 3(c>y){b=b*(y/c);c=y;3(b>x){c=c*(x/b);b=x}}13=b+30;1a=c+2G;$("#8").q("<1I 5=\'2F\' L=\'"+f+"\' z=\'"+b+"\' A=\'"+c+"\' 23=\'"+d+"\'/>"+"<4 5=\'2D\'>"+d+"<4 5=\'2C\'>"+1n+14+R+"<4 5=\'2A\'>1l 1k 1j 1s");$("#Z").s(G);3(!(14==="")){9 12(){3($(o).N("s",12)){$(o).N("s",12)}$("#8").C();$("v").q("<4 5=\'8\'>");19(1D,1G,g);H P}$("#1U").s(12)}3(!(R==="")){9 1i(){$("#8").C();$("v").q("<4 5=\'8\'>");19(1z,1x,g);H P}$("#1X").s(1i)}o.1h=9(e){3(e==M){I=2w.2v}n{I=e.2u}3(I==27){G()}n 3(I==3k){3(!(R=="")){o.1h="";1i()}}n 3(I==3j){3(!(14=="")){o.1h="";12()}}};16();$("#K").C();$("#1L").s(G);$("#8").r({Y:"T"})};S.L=f}n{6 l=f.2r(/^[^\\?]+\\??/,\'\');6 m=2p(l);13=(m[\'z\']*1)+30||3h;1a=(m[\'A\']*1)+3g||3f;W=13-30;V=1a-3e;3(f.O(\'2j\')!=-1){1E=f.1B(\'3d\');$("#15").C();3(m[\'1A\']!="1b"){$("#8").q("<4 5=\'2f\'><4 5=\'1H\'>"+d+"<4 5=\'2e\'>1l 1k 1j 1s ")}n{$("#B").N();$("#8").q(" ")}}n{3($("#8").r("Y")!="T"){3(m[\'1A\']!="1b"){$("#8").q("<4 5=\'2f\'><4 5=\'1H\'>"+d+"<4 5=\'2e\'>1l 1k 1j 1s<4 5=\'F\' J=\'z:"+W+"p;A:"+V+"p\'>")}n{$("#B").N();$("#8").q("<4 5=\'F\' 3c=\'3b\' J=\'z:"+W+"p;A:"+V+"p;\'>")}}n{$("#F")[0].J.z=W+"p";$("#F")[0].J.A=V+"p";$("#F")[0].3a=0;$("#1H").11(d)}}$("#Z").s(G);3(f.O(\'37\')!=-1){$("#F").q($(\'#\'+m[\'26\']).1T());$("#8").24(9(){$(\'#\'+m[\'26\']).q($("#F").1T())});16();$("#K").C();$("#8").r({Y:"T"})}n 3(f.O(\'2j\')!=-1){16();3($.1q.35){$("#K").C();$("#8").r({Y:"T"})}}n{$("#F").34(f+="&1y="+(1p 33().32()),9(){16();$("#K").C();1u("#F a.18");$("#8").r({Y:"T"})})}}3(!m[\'1A\']){o.21=9(e){3(e==M){I=2w.2v}n{I=e.2u}3(I==27){G()}}}}31(e){}}9 1m(){$("#K").C();$("#8").r({Y:"T"})}9 G(){$("#2Y").N("s");$("#Z").N("s");$("#8").2X("2W",9(){$(\'#8,#B,#1F\').2V("24").N().C()});$("#K").C();3(2t o.v.J.2i=="2g"){$("v","11").r({A:"1Z",z:"1Z"});$("11").r("22","")}o.1h="";o.21="";H P}9 16(){$("#8").r({2U:\'-\'+20((13/2),10)+\'p\',z:13+\'p\'});3(!(1V.1q.2Q&&1V.1q.2P<7)){$("#8").r({38:\'-\'+20((1a/2),10)+\'p\'})}}9 2p(a){6 b={};3(!a){H b}6 c=a.1B(/[;&]/);25(6 i=0;i + * + */ + +/* Base Green is: #6C8C22 */ + +*{ padding: 0; margin: 0; } + +body { + background: #efefef; + font: 14px "Helvetica Neue", Helvetica, Tahoma, sans-serif; +} +body.class, body.module, body.file { + margin-left: 40px; +} +body.file-popup { + font-size: 90%; + margin-left: 0; +} + +h1 { + font-size: 300%; + text-shadow: rgba(135,145,135,0.65) 2px 2px 3px; + color: #6C8C22; +} +h2,h3,h4 { margin-top: 1.5em; } + +a { + color: #6C8C22; + text-decoration: none; +} +a:hover { + border-bottom: 1px dotted #6C8C22; +} + +pre { + background: #ddd; + padding: 0.5em 0; +} + + +/* @group Generic Classes */ + +.initially-hidden { + display: none; +} + +.quicksearch-field { + width: 98%; + background: #ddd; + border: 1px solid #aaa; + height: 1.5em; + -webkit-border-radius: 4px; +} +.quicksearch-field:focus { + background: #f1edba; +} + +.missing-docs { + font-size: 120%; + background: white url(images/wrench_orange.png) no-repeat 4px center; + color: #ccc; + line-height: 2em; + border: 1px solid #d00; + opacity: 1; + padding-left: 20px; + text-indent: 24px; + letter-spacing: 3px; + font-weight: bold; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; +} + +.target-section { + border: 2px solid #dcce90; + border-left-width: 8px; + padding: 0 1em; + background: #fff3c2; +} + +/* @end */ + + +/* @group Index Page, Standalone file pages */ +body.indexpage { + margin: 1em 3em; +} +body.indexpage p, +body.indexpage div, +body.file p { + margin: 1em 0; +} + +.indexpage ul, +.file #documentation ul { + line-height: 160%; + list-style: none; +} +.indexpage ul a, +.file #documentation ul a { + font-size: 16px; +} + +.indexpage li, +.file #documentation li { + padding-left: 20px; + background: url(images/bullet_black.png) no-repeat left 4px; +} +.indexpage li.module { + background: url(images/package.png) no-repeat left 4px; +} +.indexpage li.class { + background: url(images/ruby.png) no-repeat left 4px; +} +.indexpage li.file { + background: url(images/page_white_text.png) no-repeat left 4px; +} + +/* @end */ + +/* @group Top-Level Structure */ + +.class #metadata, +.file #metadata, +.module #metadata { + float: left; + width: 260px; +} + +.class #documentation, +.file #documentation, +.module #documentation { + margin: 2em 1em 5em 300px; + min-width: 340px; +} + +.file #metadata { + margin: 0.8em; +} + +#validator-badges { + clear: both; + margin: 1em 1em 2em; +} + +/* @end */ + +/* @group Metadata Section */ +#metadata .section { + background-color: #dedede; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border: 1px solid #aaa; + margin: 0 8px 16px; + font-size: 90%; + overflow: hidden; +} +#metadata h3.section-header { + margin: 0; + padding: 2px 8px; + background: #ccc; + color: #666; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-bottom: 1px solid #aaa; +} +#metadata ul, +#metadata dl, +#metadata p { + padding: 8px; + list-style: none; +} + +#file-metadata ul { + padding-left: 28px; + list-style-image: url(images/page_green.png); +} + +dl.svninfo { + color: #666; + margin: 0; +} +dl.svninfo dt { + font-weight: bold; +} + +ul.link-list li { + white-space: nowrap; +} +ul.link-list .type { + font-size: 8px; + text-transform: uppercase; + color: white; + background: #969696; + padding: 2px 4px; + -webkit-border-radius: 5px; +} + +/* @end */ + + +/* @group Project Metadata Section */ +#project-metadata { + margin-top: 3em; +} + +.file #project-metadata { + margin-top: 0em; +} + +#project-metadata .section { + border: 1px solid #aaa; +} +#project-metadata h3.section-header { + border-bottom: 1px solid #aaa; + position: relative; +} +#project-metadata h3.section-header .search-toggle { + position: absolute; + right: 5px; +} + + +#project-metadata form { + color: #777; + background: #ccc; + padding: 8px 8px 16px; + border-bottom: 1px solid #bbb; +} +#project-metadata fieldset { + border: 0; +} + +#no-class-search-results { + margin: 0 auto 1em; + text-align: center; + font-size: 14px; + font-weight: bold; + color: #aaa; +} + +/* @end */ + + +/* @group Documentation Section */ +#description { + font-size: 100%; + color: #333; +} + +#description p { + margin: 1em 0.4em; +} + +#description ul { + margin-left: 2em; +} +#description ul li { + line-height: 1.4em; +} + +#description dl, +#documentation dl { + margin: 8px 1.5em; + border: 1px solid #ccc; +} +#description dl { + font-size: 14px; +} + +#description dt, +#documentation dt { + padding: 2px 4px; + font-weight: bold; + background: #ddd; +} +#description dd, +#documentation dd { + padding: 2px 12px; +} +#description dd + dt, +#documentation dd + dt { + margin-top: 0.7em; +} + +#documentation .section { + font-size: 90%; +} +#documentation h3.section-header { + margin-top: 2em; + padding: 0.75em 0.5em; + background-color: #dedede; + color: #333; + font-size: 150%; + border: 1px solid #bbb; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} + +#constants-list > dl, +#attributes-list > dl { + margin: 1em 0 2em; + border: 0; +} +#constants-list > dl dt, +#attributes-list > dl dt { + padding-left: 0; + font-weight: bold; + font-family: Monaco, "Andale Mono"; + background: inherit; +} +#constants-list > dl dt a, +#attributes-list > dl dt a { + color: inherit; +} +#constants-list > dl dd, +#attributes-list > dl dd { + margin: 0 0 1em 0; + padding: 0; + color: #666; +} + +/* @group Method Details */ + +#documentation .method-source-code { + display: none; +} + +#documentation .method-detail { + margin: 0.5em 0; + padding: 0.5em 0; + cursor: pointer; +} +#documentation .method-detail:hover { + background-color: #f1edba; +} +#documentation .method-alias { + font-style: oblique; +} +#documentation .method-heading { + position: relative; + padding: 2px 4px 0 20px; + font-size: 125%; + font-weight: bold; + color: #333; + background: url(images/brick.png) no-repeat left bottom; +} +#documentation .method-heading a { + color: inherit; +} +#documentation .method-click-advice { + position: absolute; + top: 2px; + right: 5px; + font-size: 10px; + color: #9b9877; + visibility: hidden; + padding-right: 20px; + line-height: 20px; + background: url(images/zoom.png) no-repeat right top; +} +#documentation .method-detail:hover .method-click-advice { + visibility: visible; +} + +#documentation .method-alias .method-heading { + color: #666; + background: url(images/brick_link.png) no-repeat left bottom; +} + +#documentation .method-description, +#documentation .aliases { + margin: 0 20px; + line-height: 1.2em; + color: #666; +} +#documentation .aliases { + padding-top: 4px; + font-style: italic; + cursor: default; +} +#documentation .method-description p { + padding: 0; +} +#documentation .method-description p + p { + margin-bottom: 0.5em; +} + +#documentation .attribute-method-heading { + background: url(images/tag_green.png) no-repeat left bottom; +} +#documentation #attribute-method-details .method-detail:hover { + background-color: transparent; + cursor: default; +} +#documentation .attribute-access-type { + font-size: 60%; + text-transform: uppercase; + vertical-align: super; + padding: 0 2px; +} +/* @end */ + +/* @end */ + + + +/* @group Source Code */ + +a.source-toggle { + font-size: 90%; +} +a.source-toggle img { + +} + +div.method-source-code { + background: #262626; + color: #efefef; + margin: 1em; + padding: 0.5em; + border: 1px dashed #999; + overflow: hidden; +} + +div.method-source-code pre { + background: inherit; + padding: 0; + color: white; + overflow: hidden; +} + +/* @group Ruby keyword styles */ + +.standalone-code { background: #221111; color: #ffdead; overflow: hidden; } + +.ruby-constant { color: #7fffd4; background: transparent; } +.ruby-keyword { color: #00ffff; background: transparent; } +.ruby-ivar { color: #eedd82; background: transparent; } +.ruby-operator { color: #00ffee; background: transparent; } +.ruby-identifier { color: #ffdead; background: transparent; } +.ruby-node { color: #ffa07a; background: transparent; } +.ruby-comment { color: #b22222; font-weight: bold; background: transparent; } +.ruby-regexp { color: #ffa07a; background: transparent; } +.ruby-value { color: #7fffd4; background: transparent; } + +/* @end */ +/* @end */ + + +/* @group File Popup Contents */ + +.file #metadata, +.file-popup #metadata { +} + +.file-popup dl { + font-size: 80%; + padding: 0.75em; + background-color: #dedede; + color: #333; + border: 1px solid #bbb; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} +.file dt { + font-weight: bold; + padding-left: 22px; + line-height: 20px; + background: url(images/page_white_width.png) no-repeat left top; +} +.file dt.modified-date { + background: url(images/date.png) no-repeat left top; +} +.file dt.requires { + background: url(images/plugin.png) no-repeat left top; +} +.file dt.scs-url { + background: url(images/wrench.png) no-repeat left top; +} + +.file dl dd { + margin: 0 0 1em 0; +} +.file #metadata dl dd ul { + list-style: circle; + margin-left: 20px; + padding-top: 0; +} +.file #metadata dl dd ul li { +} + + +.file h2 { + margin-top: 2em; + padding: 0.75em 0.5em; + background-color: #dedede; + color: #333; + font-size: 120%; + border: 1px solid #bbb; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} + +/* @end */ + + + + +/* @group ThickBox Styles */ +#TB_window { + font: 12px Arial, Helvetica, sans-serif; + color: #333333; +} + +#TB_secondLine { + font: 10px Arial, Helvetica, sans-serif; + color:#666666; +} + +#TB_window a:link {color: #666666;} +#TB_window a:visited {color: #666666;} +#TB_window a:hover {color: #000;} +#TB_window a:active {color: #666666;} +#TB_window a:focus{color: #666666;} + +#TB_overlay { + position: fixed; + z-index:100; + top: 0px; + left: 0px; + height:100%; + width:100%; +} + +.TB_overlayMacFFBGHack {background: url(images/macFFBgHack.png) repeat;} +.TB_overlayBG { + background-color:#000; + filter:alpha(opacity=75); + -moz-opacity: 0.75; + opacity: 0.75; +} + +* html #TB_overlay { /* ie6 hack */ + position: absolute; + height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); +} + +#TB_window { + position: fixed; + background: #ffffff; + z-index: 102; + color:#000000; + display:none; + border: 4px solid #525252; + text-align:left; + top:50%; + left:50%; +} + +* html #TB_window { /* ie6 hack */ +position: absolute; +margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); +} + +#TB_window img#TB_Image { + display:block; + margin: 15px 0 0 15px; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + border-top: 1px solid #666; + border-left: 1px solid #666; +} + +#TB_caption{ + height:25px; + padding:7px 30px 10px 25px; + float:left; +} + +#TB_closeWindow{ + height:25px; + padding:11px 25px 10px 0; + float:right; +} + +#TB_closeAjaxWindow{ + padding:7px 10px 5px 0; + margin-bottom:1px; + text-align:right; + float:right; +} + +#TB_ajaxWindowTitle{ + float:left; + padding:7px 0 5px 10px; + margin-bottom:1px; + font-size: 22px; +} + +#TB_title{ + background-color: #6C8C22; + color: #dedede; + height:40px; +} +#TB_title a { + color: white !important; + border-bottom: 1px dotted #dedede; +} + +#TB_ajaxContent{ + clear:both; + padding:2px 15px 15px 15px; + overflow:auto; + text-align:left; + line-height:1.4em; +} + +#TB_ajaxContent.TB_modal{ + padding:15px; +} + +#TB_ajaxContent p{ + padding:5px 0px 5px 0px; +} + +#TB_load{ + position: fixed; + display:none; + height:13px; + width:208px; + z-index:103; + top: 50%; + left: 50%; + margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */ +} + +* html #TB_load { /* ie6 hack */ +position: absolute; +margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); +} + +#TB_HideSelect{ + z-index:99; + position:fixed; + top: 0; + left: 0; + background-color:#fff; + border:none; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; + height:100%; + width:100%; +} + +* html #TB_HideSelect { /* ie6 hack */ + position: absolute; + height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); +} + +#TB_iframeContent{ + clear:both; + border:none; + margin-bottom:-1px; + margin-top:1px; + _margin-bottom:1px; +} + +/* @end */ + +/* @group Debugging Section */ + +#debugging-toggle { + text-align: center; +} +#debugging-toggle img { + cursor: pointer; +} + +#rdoc-debugging-section-dump { + display: none; + margin: 0 2em 2em; + background: #ccc; + border: 1px solid #999; +} + + + +/* @end */ diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ghost_method.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ghost_method.rb new file mode 100755 index 00000000..192b46f5 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ghost_method.rb @@ -0,0 +1,8 @@ +require 'rdoc/any_method' + +## +# GhostMethod represents a method referenced only by a comment + +class RDoc::GhostMethod < RDoc::AnyMethod +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/include.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/include.rb new file mode 100755 index 00000000..9be90615 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/include.rb @@ -0,0 +1,39 @@ +require 'rdoc/code_object' + +## +# A Module include in a class with \#include + +class RDoc::Include < RDoc::CodeObject + + ## + # Name of included module + + attr_accessor :name + + ## + # Creates a new Include for +name+ with +comment+ + + def initialize(name, comment) + super() + @name = name + self.comment = comment + end + + def inspect # :nodoc: + "#<%s:0x%x %s.include %s>" % [ + self.class, + object_id, + parent_name, @name, + ] + end + + ## + # Attempts to locate the included module object. Returns the name if not + # known. + + def module + RDoc::TopLevel.find_module_named(@name) || @name + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/known_classes.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/known_classes.rb new file mode 100755 index 00000000..dbb1802f --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/known_classes.rb @@ -0,0 +1,68 @@ +module RDoc + + ## + # Ruby's built-in classes, modules and exceptions + + KNOWN_CLASSES = { + "rb_cArray" => "Array", + "rb_cBignum" => "Bignum", + "rb_cClass" => "Class", + "rb_cData" => "Data", + "rb_cDir" => "Dir", + "rb_cFalseClass" => "FalseClass", + "rb_cFile" => "File", + "rb_cFixnum" => "Fixnum", + "rb_cFloat" => "Float", + "rb_cHash" => "Hash", + "rb_cIO" => "IO", + "rb_cInteger" => "Integer", + "rb_cModule" => "Module", + "rb_cNilClass" => "NilClass", + "rb_cNumeric" => "Numeric", + "rb_cObject" => "Object", + "rb_cProc" => "Proc", + "rb_cRange" => "Range", + "rb_cRegexp" => "Regexp", + "rb_cRubyVM" => "RubyVM", + "rb_cString" => "String", + "rb_cStruct" => "Struct", + "rb_cSymbol" => "Symbol", + "rb_cThread" => "Thread", + "rb_cTime" => "Time", + "rb_cTrueClass" => "TrueClass", + + "rb_eArgError" => "ArgError", + "rb_eEOFError" => "EOFError", + "rb_eException" => "Exception", + "rb_eFatal" => "Fatal", + "rb_eFloatDomainError" => "FloatDomainError", + "rb_eIOError" => "IOError", + "rb_eIndexError" => "IndexError", + "rb_eInterrupt" => "Interrupt", + "rb_eLoadError" => "LoadError", + "rb_eNameError" => "NameError", + "rb_eNoMemError" => "NoMemError", + "rb_eNotImpError" => "NotImpError", + "rb_eRangeError" => "RangeError", + "rb_eRuntimeError" => "RuntimeError", + "rb_eScriptError" => "ScriptError", + "rb_eSecurityError" => "SecurityError", + "rb_eSignal" => "Signal", + "rb_eStandardError" => "StandardError", + "rb_eSyntaxError" => "SyntaxError", + "rb_eSystemCallError" => "SystemCallError", + "rb_eSystemExit" => "SystemExit", + "rb_eTypeError" => "TypeError", + "rb_eZeroDivError" => "ZeroDivError", + + "rb_mComparable" => "Comparable", + "rb_mEnumerable" => "Enumerable", + "rb_mErrno" => "Errno", + "rb_mFileTest" => "FileTest", + "rb_mGC" => "GC", + "rb_mKernel" => "Kernel", + "rb_mMath" => "Math", + "rb_mProcess" => "Process" + } + +end diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup.rb new file mode 100755 index 00000000..9d22b389 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup.rb @@ -0,0 +1,378 @@ +require 'rdoc' + +## +# RDoc::Markup parses plain text documents and attempts to decompose them into +# their constituent parts. Some of these parts are high-level: paragraphs, +# chunks of verbatim text, list entries and the like. Other parts happen at +# the character level: a piece of bold text, a word in code font. This markup +# is similar in spirit to that used on WikiWiki webs, where folks create web +# pages using a simple set of formatting rules. +# +# RDoc::Markup itself does no output formatting: this is left to a different +# set of classes. +# +# RDoc::Markup is extendable at runtime: you can add \new markup elements to +# be recognised in the documents that RDoc::Markup parses. +# +# RDoc::Markup is intended to be the basis for a family of tools which share +# the common requirement that simple, plain-text should be rendered in a +# variety of different output formats and media. It is envisaged that +# RDoc::Markup could be the basis for formatting RDoc style comment blocks, +# Wiki entries, and online FAQs. +# +# == Synopsis +# +# This code converts +input_string+ to HTML. The conversion takes place in +# the +convert+ method, so you can use the same RDoc::Markup converter to +# convert multiple input strings. +# +# require 'rdoc/markup/to_html' +# +# h = RDoc::Markup::ToHtml.new +# +# puts h.convert(input_string) +# +# You can extend the RDoc::Markup parser to recognise new markup +# sequences, and to add special processing for text that matches a +# regular expression. Here we make WikiWords significant to the parser, +# and also make the sequences {word} and \text... signify +# strike-through text. When then subclass the HTML output class to deal +# with these: +# +# require 'rdoc/markup' +# require 'rdoc/markup/to_html' +# +# class WikiHtml < RDoc::Markup::ToHtml +# def handle_special_WIKIWORD(special) +# "" + special.text + "" +# end +# end +# +# m = RDoc::Markup.new +# m.add_word_pair("{", "}", :STRIKE) +# m.add_html("no", :STRIKE) +# +# m.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD) +# +# wh = WikiHtml.new +# wh.add_tag(:STRIKE, "", "") +# +# puts "#{wh.convert ARGF.read}" +# +#-- +# Author:: Dave Thomas, dave@pragmaticprogrammer.com +# License:: Ruby license + +class RDoc::Markup + + SPACE = ?\s + + # List entries look like: + # * text + # 1. text + # [label] text + # label:: text + # + # Flag it as a list entry, and work out the indent for subsequent lines + + SIMPLE_LIST_RE = /^( + ( \* (?# bullet) + |- (?# bullet) + |\d+\. (?# numbered ) + |[A-Za-z]\. (?# alphabetically numbered ) + ) + \s+ + )\S/x + + LABEL_LIST_RE = /^( + ( \[.*?\] (?# labeled ) + |\S.*:: (?# note ) + )(?:\s+|$) + )/x + + ## + # Take a block of text and use various heuristics to determine it's + # structure (paragraphs, lists, and so on). Invoke an event handler as we + # identify significant chunks. + + def initialize + @am = RDoc::Markup::AttributeManager.new + @output = nil + end + + ## + # Add to the sequences used to add formatting to an individual word (such + # as *bold*). Matching entries will generate attributes that the output + # formatters can recognize by their +name+. + + def add_word_pair(start, stop, name) + @am.add_word_pair(start, stop, name) + end + + ## + # Add to the sequences recognized as general markup. + + def add_html(tag, name) + @am.add_html(tag, name) + end + + ## + # Add to other inline sequences. For example, we could add WikiWords using + # something like: + # + # parser.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD) + # + # Each wiki word will be presented to the output formatter via the + # accept_special method. + + def add_special(pattern, name) + @am.add_special(pattern, name) + end + + ## + # We take a string, split it into lines, work out the type of each line, + # and from there deduce groups of lines (for example all lines in a + # paragraph). We then invoke the output formatter using a Visitor to + # display the result. + + def convert(str, op) + lines = str.split(/\r?\n/).map { |line| Line.new line } + @lines = Lines.new lines + + return "" if @lines.empty? + @lines.normalize + assign_types_to_lines + group = group_lines + # call the output formatter to handle the result + #group.each { |line| p line } + group.accept @am, op + end + + private + + ## + # Look through the text at line indentation. We flag each line as being + # Blank, a paragraph, a list element, or verbatim text. + + def assign_types_to_lines(margin = 0, level = 0) + while line = @lines.next + if line.blank? then + line.stamp :BLANK, level + next + end + + # if a line contains non-blanks before the margin, then it must belong + # to an outer level + + text = line.text + + for i in 0...margin + if text[i] != SPACE + @lines.unget + return + end + end + + active_line = text[margin..-1] + + # Rules (horizontal lines) look like + # + # --- (three or more hyphens) + # + # The more hyphens, the thicker the rule + # + + if /^(---+)\s*$/ =~ active_line + line.stamp :RULE, level, $1.length-2 + next + end + + # Then look for list entries. First the ones that have to have + # text following them (* xxx, - xxx, and dd. xxx) + + if SIMPLE_LIST_RE =~ active_line + offset = margin + $1.length + prefix = $2 + prefix_length = prefix.length + + flag = case prefix + when "*","-" then :BULLET + when /^\d/ then :NUMBER + when /^[A-Z]/ then :UPPERALPHA + when /^[a-z]/ then :LOWERALPHA + else raise "Invalid List Type: #{self.inspect}" + end + + line.stamp :LIST, level+1, prefix, flag + text[margin, prefix_length] = " " * prefix_length + assign_types_to_lines(offset, level + 1) + next + end + + if LABEL_LIST_RE =~ active_line + offset = margin + $1.length + prefix = $2 + prefix_length = prefix.length + + next if handled_labeled_list(line, level, margin, offset, prefix) + end + + # Headings look like + # = Main heading + # == Second level + # === Third + # + # Headings reset the level to 0 + + if active_line[0] == ?= and active_line =~ /^(=+)\s*(.*)/ + prefix_length = $1.length + prefix_length = 6 if prefix_length > 6 + line.stamp :HEADING, 0, prefix_length + line.strip_leading(margin + prefix_length) + next + end + + # If the character's a space, then we have verbatim text, + # otherwise + + if active_line[0] == SPACE + line.strip_leading(margin) if margin > 0 + line.stamp :VERBATIM, level + else + line.stamp :PARAGRAPH, level + end + end + end + + ## + # Handle labeled list entries, We have a special case to deal with. + # Because the labels can be long, they force the remaining block of text + # over the to right: + # + # this is a long label that I wrote:: and here is the + # block of text with + # a silly margin + # + # So we allow the special case. If the label is followed by nothing, and + # if the following line is indented, then we take the indent of that line + # as the new margin. + # + # this is a long label that I wrote:: + # here is a more reasonably indented block which + # will be attached to the label. + # + + def handled_labeled_list(line, level, margin, offset, prefix) + prefix_length = prefix.length + text = line.text + flag = nil + + case prefix + when /^\[/ then + flag = :LABELED + prefix = prefix[1, prefix.length-2] + when /:$/ then + flag = :NOTE + prefix.chop! + else + raise "Invalid List Type: #{self.inspect}" + end + + # body is on the next line + if text.length <= offset then + original_line = line + line = @lines.next + return false unless line + text = line.text + + for i in 0..margin + if text[i] != SPACE + @lines.unget + return false + end + end + + i = margin + i += 1 while text[i] == SPACE + + if i >= text.length then + @lines.unget + return false + else + offset = i + prefix_length = 0 + + if text[offset..-1] =~ SIMPLE_LIST_RE then + @lines.unget + line = original_line + line.text = '' + else + @lines.delete original_line + end + end + end + + line.stamp :LIST, level+1, prefix, flag + text[margin, prefix_length] = " " * prefix_length + assign_types_to_lines(offset, level + 1) + return true + end + + ## + # Return a block consisting of fragments which are paragraphs, list + # entries or verbatim text. We merge consecutive lines of the same type + # and level together. We are also slightly tricky with lists: the lines + # following a list introduction look like paragraph lines at the next + # level, and we remap them into list entries instead. + + def group_lines + @lines.rewind + + in_list = false + wanted_type = wanted_level = nil + + block = LineCollection.new + group = nil + + while line = @lines.next + if line.level == wanted_level and line.type == wanted_type + group.add_text(line.text) + else + group = block.fragment_for(line) + block.add(group) + + if line.type == :LIST + wanted_type = :PARAGRAPH + else + wanted_type = line.type + end + + wanted_level = line.type == :HEADING ? line.param : line.level + end + end + + block.normalize + block + end + + ## + # For debugging, we allow access to our line contents as text. + + def content + @lines.as_text + end + public :content + + ## + # For debugging, return the list of line types. + + def get_line_types + @lines.line_types + end + public :get_line_types + +end + +require 'rdoc/markup/fragments' +require 'rdoc/markup/inline' +require 'rdoc/markup/lines' diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/attribute_manager.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/attribute_manager.rb new file mode 100755 index 00000000..5c253b10 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/attribute_manager.rb @@ -0,0 +1,311 @@ +require 'rdoc/markup/inline' + +## +# Manages changes of attributes in a block of text + +class RDoc::Markup::AttributeManager + + ## + # The NUL character + + NULL = "\000".freeze + + ## + # We work by substituting non-printing characters in to the text. For now + # I'm assuming that I can substitute a character in the range 0..8 for a 7 + # bit character without damaging the encoded string, but this might be + # optimistic + + A_PROTECT = 004 + PROTECT_ATTR = A_PROTECT.chr + + ## + # This maps delimiters that occur around words (such as *bold* or +tt+) + # where the start and end delimiters and the same. This lets us optimize + # the regexp + + MATCHING_WORD_PAIRS = {} + + ## + # And this is used when the delimiters aren't the same. In this case the + # hash maps a pattern to the attribute character + + WORD_PAIR_MAP = {} + + ## + # This maps HTML tags to the corresponding attribute char + + HTML_TAGS = {} + + ## + # And this maps _special_ sequences to a name. A special sequence is + # something like a WikiWord + + SPECIAL = {} + + ## + # Return an attribute object with the given turn_on and turn_off bits set + + def attribute(turn_on, turn_off) + RDoc::Markup::AttrChanger.new turn_on, turn_off + end + + def change_attribute(current, new) + diff = current ^ new + attribute(new & diff, current & diff) + end + + def changed_attribute_by_name(current_set, new_set) + current = new = 0 + current_set.each do |name| + current |= RDoc::Markup::Attribute.bitmap_for(name) + end + + new_set.each do |name| + new |= RDoc::Markup::Attribute.bitmap_for(name) + end + + change_attribute(current, new) + end + + def copy_string(start_pos, end_pos) + res = @str[start_pos...end_pos] + res.gsub!(/\000/, '') + res + end + + ## + # Map attributes like textto the sequence + # \001\002\001\003, where is a per-attribute specific + # character + + def convert_attrs(str, attrs) + # first do matching ones + tags = MATCHING_WORD_PAIRS.keys.join("") + + re = /(^|\W)([#{tags}])([#:\\]?[\w.\/-]+?\S?)\2(\W|$)/ + + 1 while str.gsub!(re) do + attr = MATCHING_WORD_PAIRS[$2] + attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr) + $1 + NULL * $2.length + $3 + NULL * $2.length + $4 + end + + # then non-matching + unless WORD_PAIR_MAP.empty? then + WORD_PAIR_MAP.each do |regexp, attr| + str.gsub!(regexp) { + attrs.set_attrs($`.length + $1.length, $2.length, attr) + NULL * $1.length + $2 + NULL * $3.length + } + end + end + end + + ## + # Converts HTML tags to RDoc attributes + + def convert_html(str, attrs) + tags = HTML_TAGS.keys.join '|' + + 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) { + attr = HTML_TAGS[$1.downcase] + html_length = $1.length + 2 + seq = NULL * html_length + attrs.set_attrs($`.length + html_length, $2.length, attr) + seq + $2 + seq + NULL + } + end + + ## + # Converts special sequences to RDoc attributes + + def convert_specials(str, attrs) + unless SPECIAL.empty? + SPECIAL.each do |regexp, attr| + str.scan(regexp) do + attrs.set_attrs($`.length, $&.length, + attr | RDoc::Markup::Attribute::SPECIAL) + end + end + end + end + + ## + # A \ in front of a character that would normally be processed turns off + # processing. We do this by turning \< into <#{PROTECT} + + PROTECTABLE = %w[<\\] + + ## + # Escapes special sequences of text to prevent conversion to RDoc + + def mask_protected_sequences + protect_pattern = Regexp.new("\\\\([#{Regexp.escape(PROTECTABLE.join(''))}])") + @str.gsub!(protect_pattern, "\\1#{PROTECT_ATTR}") + end + + ## + # Unescapes special sequences of text + + def unmask_protected_sequences + @str.gsub!(/(.)#{PROTECT_ATTR}/, "\\1\000") + end + + ## + # Creates a new attribute manager that understands bold, emphasized and + # teletype text. + + def initialize + add_word_pair("*", "*", :BOLD) + add_word_pair("_", "_", :EM) + add_word_pair("+", "+", :TT) + + add_html("em", :EM) + add_html("i", :EM) + add_html("b", :BOLD) + add_html("tt", :TT) + add_html("code", :TT) + end + + ## + # Adds a markup class with +name+ for words wrapped in the +start+ and + # +stop+ character. To make words wrapped with "*" bold: + # + # am.add_word_pair '*', '*', :BOLD + + def add_word_pair(start, stop, name) + raise ArgumentError, "Word flags may not start with '<'" if + start[0,1] == '<' + + bitmap = RDoc::Markup::Attribute.bitmap_for name + + if start == stop then + MATCHING_WORD_PAIRS[start] = bitmap + else + pattern = /(#{Regexp.escape start})(\S+)(#{Regexp.escape stop})/ + WORD_PAIR_MAP[pattern] = bitmap + end + + PROTECTABLE << start[0,1] + PROTECTABLE.uniq! + end + + ## + # Adds a markup class with +name+ for words surrounded by HTML tag +tag+. + # To process emphasis tags: + # + # am.add_html 'em', :EM + + def add_html(tag, name) + HTML_TAGS[tag.downcase] = RDoc::Markup::Attribute.bitmap_for name + end + + ## + # Adds a special handler for +pattern+ with +name+. A simple URL handler + # would be: + # + # @am.add_special(/((https?:)\S+\w)/, :HYPERLINK) + + def add_special(pattern, name) + SPECIAL[pattern] = RDoc::Markup::Attribute.bitmap_for name + end + + ## + # Processes +str+ converting attributes, HTML and specials + + def flow(str) + @str = str + + mask_protected_sequences + + @attrs = RDoc::Markup::AttrSpan.new @str.length + + convert_attrs(@str, @attrs) + convert_html(@str, @attrs) + convert_specials(str, @attrs) + + unmask_protected_sequences + + split_into_flow + end + + ## + # Debug method that prints a string along with its attributes + + def display_attributes + puts + puts @str.tr(NULL, "!") + bit = 1 + 16.times do |bno| + line = "" + @str.length.times do |i| + if (@attrs[i] & bit) == 0 + line << " " + else + if bno.zero? + line << "S" + else + line << ("%d" % (bno+1)) + end + end + end + puts(line) unless line =~ /^ *$/ + bit <<= 1 + end + end + + def split_into_flow + res = [] + current_attr = 0 + str = "" + + str_len = @str.length + + # skip leading invisible text + i = 0 + i += 1 while i < str_len and @str[i].chr == "\0" + start_pos = i + + # then scan the string, chunking it on attribute changes + while i < str_len + new_attr = @attrs[i] + if new_attr != current_attr + if i > start_pos + res << copy_string(start_pos, i) + start_pos = i + end + + res << change_attribute(current_attr, new_attr) + current_attr = new_attr + + if (current_attr & RDoc::Markup::Attribute::SPECIAL) != 0 then + i += 1 while + i < str_len and (@attrs[i] & RDoc::Markup::Attribute::SPECIAL) != 0 + + res << RDoc::Markup::Special.new(current_attr, + copy_string(start_pos, i)) + start_pos = i + next + end + end + + # move on, skipping any invisible characters + begin + i += 1 + end while i < str_len and @str[i].chr == "\0" + end + + # tidy up trailing text + if start_pos < str_len + res << copy_string(start_pos, str_len) + end + + # and reset to all attributes off + res << change_attribute(current_attr, 0) if current_attr != 0 + + res + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/formatter.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/formatter.rb new file mode 100755 index 00000000..a499d12e --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/formatter.rb @@ -0,0 +1,25 @@ +require 'rdoc/markup' + +## +# Base class for RDoc markup formatters +# +# Formatters use a visitor pattern to convert content into output. + +class RDoc::Markup::Formatter + + ## + # Creates a new Formatter + + def initialize + @markup = RDoc::Markup.new + end + + ## + # Marks up +content+ + + def convert(content) + @markup.convert content, self + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/fragments.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/fragments.rb new file mode 100755 index 00000000..bbe0bced --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/fragments.rb @@ -0,0 +1,377 @@ +require 'rdoc/markup' +require 'rdoc/markup/lines' + +class RDoc::Markup + + ## + # A Fragment is a chunk of text, subclassed as a paragraph, a list + # entry, or verbatim text. + + class Fragment + attr_reader :level, :param, :txt + attr_accessor :type + + ## + # This is a simple factory system that lets us associate fragement + # types (a string) with a subclass of fragment + + TYPE_MAP = {} + + def self.type_name(name) + TYPE_MAP[name] = self + end + + def self.for(line) + klass = TYPE_MAP[line.type] || + raise("Unknown line type: '#{line.type.inspect}:' '#{line.text}'") + return klass.new(line.level, line.param, line.flag, line.text) + end + + def initialize(level, param, type, txt) + @level = level + @param = param + @type = type + @txt = "" + add_text(txt) if txt + end + + def add_text(txt) + @txt << " " if @txt.length > 0 + @txt << txt.tr_s("\n ", " ").strip + end + + def to_s + "L#@level: #{self.class.name.split('::')[-1]}\n#@txt" + end + + end + + ## + # A paragraph is a fragment which gets wrapped to fit. We remove all + # newlines when we're created, and have them put back on output. + + class Paragraph < Fragment + type_name :PARAGRAPH + end + + ## + # An empty line + + class BlankLine < Paragraph + type_name :BLANK + end + + ## + # A heading + + class Heading < Paragraph + type_name :HEADING + + ## + # Level of heading, smaller is more important + + def head_level + @param.to_i + end + + end + + ## + # A List is a fragment with some kind of label + + class ListBase < Paragraph + LIST_TYPES = [ + :BULLET, + :NUMBER, + :UPPERALPHA, + :LOWERALPHA, + :LABELED, + :NOTE, + ] + end + + ## + # An item in a list + + class ListItem < ListBase + type_name :LIST + + def to_s # :nodoc: + text = if [:NOTE, :LABELED].include? type then + "#{@param}: #{@txt}" + else + @txt + end + + "L#@level: #{type} #{self.class.name.split('::')[-1]}\n#{text}" + end + + end + + ## + # Start of a list + + class ListStart < ListBase + + ## + # Creates a ListStart with nesting +level+ + + def initialize(level, param, type) + super(level, param, type, nil) + end + end + + ## + # End of a list + + class ListEnd < ListBase + + ## + # Creates a ListEnd with nesting +level+ + + def initialize(level, type) + super(level, "", type, nil) + end + end + + ## + # Verbatim code contains lines that don't get wrapped. + + class Verbatim < Fragment + type_name :VERBATIM + + ## + # Adds +txt+ to this verbatim + + def add_text(txt) + @txt << txt.chomp << "\n" + end + + end + + ## + # A horizontal rule + + class Rule < Fragment + type_name :RULE + end + + ## + # Collect groups of lines together. Each group will end up containing a flow + # of text. + + class LineCollection + + ## + # Creates a new collection of lines + + def initialize + @fragments = [] + end + + ## + # Adds +fragment+ to the collection + + def add(fragment) + @fragments << fragment + end + + ## + # Iterates over the lines in the collection + + def each(&b) + @fragments.each(&b) + end + + def to_a # :nodoc: + @fragments.map {|fragment| fragment.to_s} + end + + ## + # Factory for different fragment types + + def fragment_for(*args) + Fragment.for(*args) + end + + ## + # Tidy up at the end + + def normalize + change_verbatim_blank_lines + add_list_start_and_ends + add_list_breaks + tidy_blank_lines + end + + def to_s # :nodoc: + @fragments.join("\n----\n") + end + + def accept(am, visitor) + visitor.start_accepting + + @fragments.each do |fragment| + case fragment + when Verbatim + visitor.accept_verbatim(am, fragment) + when Rule + visitor.accept_rule(am, fragment) + when ListStart + visitor.accept_list_start(am, fragment) + when ListEnd + visitor.accept_list_end(am, fragment) + when ListItem + visitor.accept_list_item(am, fragment) + when BlankLine + visitor.accept_blank_line(am, fragment) + when Heading + visitor.accept_heading(am, fragment) + when Paragraph + visitor.accept_paragraph(am, fragment) + end + end + + visitor.end_accepting + end + + private + + ## + # If you have: + # + # normal paragraph text. + # + # this is code + # + # and more code + # + # You'll end up with the fragments Paragraph, BlankLine, Verbatim, + # BlankLine, Verbatim, BlankLine, etc. + # + # The BlankLine in the middle of the verbatim chunk needs to be changed to + # a real verbatim newline, and the two verbatim blocks merged + + def change_verbatim_blank_lines + frag_block = nil + blank_count = 0 + @fragments.each_with_index do |frag, i| + if frag_block.nil? + frag_block = frag if Verbatim === frag + else + case frag + when Verbatim + blank_count.times { frag_block.add_text("\n") } + blank_count = 0 + frag_block.add_text(frag.txt) + @fragments[i] = nil # remove out current fragment + when BlankLine + if frag_block + blank_count += 1 + @fragments[i] = nil + end + else + frag_block = nil + blank_count = 0 + end + end + end + @fragments.compact! + end + + ## + # List nesting is implicit given the level of indentation. Make it + # explicit, just to make life a tad easier for the output processors + + def add_list_start_and_ends + level = 0 + res = [] + type_stack = [] + + @fragments.each do |fragment| + # $stderr.puts "#{level} : #{fragment.class.name} : #{fragment.level}" + new_level = fragment.level + while (level < new_level) + level += 1 + type = fragment.type + res << ListStart.new(level, fragment.param, type) if type + type_stack.push type + # $stderr.puts "Start: #{level}" + end + + while level > new_level + type = type_stack.pop + res << ListEnd.new(level, type) if type + level -= 1 + # $stderr.puts "End: #{level}, #{type}" + end + + res << fragment + level = fragment.level + end + level.downto(1) do |i| + type = type_stack.pop + res << ListEnd.new(i, type) if type + end + + @fragments = res + end + + ## + # Inserts start/ends between list entries at the same level that have + # different element types + + def add_list_breaks + res = @fragments + + @fragments = [] + list_stack = [] + + res.each do |fragment| + case fragment + when ListStart + list_stack.push fragment + when ListEnd + start = list_stack.pop + fragment.type = start.type + when ListItem + l = list_stack.last + if fragment.type != l.type + @fragments << ListEnd.new(l.level, l.type) + start = ListStart.new(l.level, fragment.param, fragment.type) + @fragments << start + list_stack.pop + list_stack.push start + end + else + ; + end + @fragments << fragment + end + end + + ## + # Tidy up the blank lines: + # * change Blank/ListEnd into ListEnd/Blank + # * remove blank lines at the front + + def tidy_blank_lines + (@fragments.size - 1).times do |i| + if BlankLine === @fragments[i] and ListEnd === @fragments[i+1] then + @fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i] + end + end + + # remove leading blanks + @fragments.each_with_index do |f, i| + break unless f.kind_of? BlankLine + @fragments[i] = nil + end + + @fragments.compact! + end + + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/inline.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/inline.rb new file mode 100755 index 00000000..ce091aab --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/inline.rb @@ -0,0 +1,126 @@ +require 'rdoc/markup' + +class RDoc::Markup + + ## + # We manage a set of attributes. Each attribute has a symbol name and a bit + # value. + + class Attribute + SPECIAL = 1 + + @@name_to_bitmap = { :_SPECIAL_ => SPECIAL } + @@next_bitmap = 2 + + def self.bitmap_for(name) + bitmap = @@name_to_bitmap[name] + unless bitmap then + bitmap = @@next_bitmap + @@next_bitmap <<= 1 + @@name_to_bitmap[name] = bitmap + end + bitmap + end + + def self.as_string(bitmap) + return "none" if bitmap.zero? + res = [] + @@name_to_bitmap.each do |name, bit| + res << name if (bitmap & bit) != 0 + end + res.join(",") + end + + def self.each_name_of(bitmap) + @@name_to_bitmap.each do |name, bit| + next if bit == SPECIAL + yield name.to_s if (bitmap & bit) != 0 + end + end + + end + + AttrChanger = Struct.new :turn_on, :turn_off + + ## + # An AttrChanger records a change in attributes. It contains a bitmap of the + # attributes to turn on, and a bitmap of those to turn off. + + class AttrChanger + def to_s # :nodoc: + "Attr: +#{Attribute.as_string(turn_on)}/-#{Attribute.as_string(turn_on)}" + end + end + + ## + # An array of attributes which parallels the characters in a string. + + class AttrSpan + + ## + # Creates a new AttrSpan for +length+ characters + + def initialize(length) + @attrs = Array.new(length, 0) + end + + ## + # Toggles +bits+ from +start+ to +length+ + def set_attrs(start, length, bits) + for i in start ... (start+length) + @attrs[i] |= bits + end + end + + ## + # Acccesses flags for character +n+ + + def [](n) + @attrs[n] + end + + end + + ## + # Hold details of a special sequence + + class Special + + ## + # Special type + + attr_reader :type + + ## + # Special text + + attr_accessor :text + + ## + # Creates a new special sequence of +type+ with +text+ + + def initialize(type, text) + @type, @text = type, text + end + + ## + # Specials are equal when the have the same text and type + + def ==(o) + self.text == o.text && self.type == o.type + end + + def inspect # :nodoc: + "#" % [ + object_id, @type, RDoc::Markup::Attribute.as_string(type), text.dump] + end + + def to_s # :nodoc: + "Special: type=#{type}, name=#{RDoc::Markup::Attribute.as_string type}, text=#{text.dump}" + end + + end + +end + +require 'rdoc/markup/attribute_manager' diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/lines.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/lines.rb new file mode 100755 index 00000000..6ec8e093 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/lines.rb @@ -0,0 +1,156 @@ +class RDoc::Markup + + ## + # We store the lines we're working on as objects of class Line. These + # contain the text of the line, along with a flag indicating the line type, + # and an indentation level. + + class Line + + ## + # Not really + + INFINITY = 9999 + + LINE_TYPES = [ + :BLANK, + :HEADING, + :LIST, + :PARAGRAPH, + :RULE, + :VERBATIM, + ] + + # line type + attr_accessor :type + + # The indentation nesting level + attr_accessor :level + + # The contents + attr_accessor :text + + # A prefix or parameter. For LIST lines, this is + # the text that introduced the list item (the label) + attr_accessor :param + + # A flag. For list lines, this is the type of the list + attr_accessor :flag + + # the number of leading spaces + attr_accessor :leading_spaces + + # true if this line has been deleted from the list of lines + attr_accessor :deleted + + def initialize(text) + @text = text.dup + @deleted = false + + # expand tabs + 1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)} && $~ #` + + # Strip trailing whitespace + @text.sub!(/\s+$/, '') + + # and look for leading whitespace + if @text.length > 0 + @text =~ /^(\s*)/ + @leading_spaces = $1.length + else + @leading_spaces = INFINITY + end + end + + # Return true if this line is blank + def blank? + @text.empty? + end + + # stamp a line with a type, a level, a prefix, and a flag + def stamp(type, level, param="", flag=nil) + @type, @level, @param, @flag = type, level, param, flag + end + + ## + # Strip off the leading margin + + def strip_leading(size) + if @text.size > size + @text[0,size] = "" + else + @text = "" + end + end + + def to_s + "#@type#@level: #@text" + end + end + + ## + # A container for all the lines. + + class Lines + + include Enumerable + + attr_reader :lines # :nodoc: + + def initialize(lines) + @lines = lines + rewind + end + + def empty? + @lines.size.zero? + end + + def each + @lines.each do |line| + yield line unless line.deleted + end + end + +# def [](index) +# @lines[index] +# end + + def rewind + @nextline = 0 + end + + def next + begin + res = @lines[@nextline] + @nextline += 1 if @nextline < @lines.size + end while res and res.deleted and @nextline < @lines.size + res + end + + def unget + @nextline -= 1 + end + + def delete(a_line) + a_line.deleted = true + end + + def normalize + margin = @lines.collect{|l| l.leading_spaces}.min + margin = 0 if margin == :INFINITY + @lines.each {|line| line.strip_leading(margin) } if margin > 0 + end + + def as_text + @lines.map {|l| l.text}.join("\n") + end + + def line_types + @lines.map {|l| l.type } + end + + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/preprocess.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/preprocess.rb new file mode 100755 index 00000000..a175d179 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/preprocess.rb @@ -0,0 +1,80 @@ +require 'rdoc/markup' + +## +# Handle common directives that can occur in a block of text: +# +# : include : filename + +class RDoc::Markup::PreProcess + + ## + # Creates a new pre-processor for +input_file_name+ that will look for + # included files in +include_path+ + + def initialize(input_file_name, include_path) + @input_file_name = input_file_name + @include_path = include_path + end + + ## + # Look for common options in a chunk of text. Options that we don't handle + # are yielded to the caller. + + def handle(text) + text.gsub!(/^([ \t]*#?[ \t]*):(\w+):([ \t]*)(.+)?\n/) do + next $& if $3.empty? and $4 and $4[0, 1] == ':' + + prefix = $1 + directive = $2.downcase + param = $4 + + case directive + when 'include' then + filename = param.split[0] + include_file filename, prefix + + else + result = yield directive, param + result = "#{prefix}:#{directive}: #{param}\n" unless result + result + end + end + end + + private + + ## + # Include a file, indenting it correctly. + + def include_file(name, indent) + if full_name = find_include_file(name) then + content = File.read full_name + + # strip leading '#'s, but only if all lines start with them + if content =~ /^[^#]/ then + content.gsub(/^/, indent) + else + content.gsub(/^#?/, indent) + end + else + $stderr.puts "Couldn't find file to include '#{name}' from #{@input_file_name}" + '' + end + end + + ## + # Look for the given file in the directory containing the current file, + # and then in each of the directories specified in the RDOC_INCLUDE path + + def find_include_file(name) + to_search = [ File.dirname(@input_file_name) ].concat @include_path + to_search.each do |dir| + full_name = File.join(dir, name) + stat = File.stat(full_name) rescue next + return full_name if stat.readable? + end + nil + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_flow.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_flow.rb new file mode 100755 index 00000000..3556a4fa --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_flow.rb @@ -0,0 +1,211 @@ +require 'rdoc/markup/formatter' +require 'rdoc/markup/fragments' +require 'rdoc/markup/inline' +require 'cgi' + +class RDoc::Markup + + module Flow + + ## + # Paragraph + + P = Struct.new(:body) + + ## + # Verbatim + + VERB = Struct.new(:body) + + ## + # Horizontal rule + + RULE = Struct.new(:width) + + ## + # List + + class LIST + attr_reader :type, :contents + def initialize(type) + @type = type + @contents = [] + end + def <<(stuff) + @contents << stuff + end + end + + ## + # List item + + LI = Struct.new(:label, :body) + + ## + # Heading + + H = Struct.new(:level, :text) + + end + + class ToFlow < RDoc::Markup::Formatter + + LIST_TYPE_TO_HTML = { + :BULLET => [ "
    ", "
" ], + :NUMBER => [ "
    ", "
" ], + :UPPERALPHA => [ "
    ", "
" ], + :LOWERALPHA => [ "
    ", "
" ], + :LABELED => [ "
", "
" ], + :NOTE => [ "", "
" ], + } + + InlineTag = Struct.new(:bit, :on, :off) + + def initialize + super + + init_tags + end + + ## + # Set up the standard mapping of attributes to HTML tags + + def init_tags + @attr_tags = [ + InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:BOLD), "", ""), + InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:TT), "", ""), + InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:EM), "", ""), + ] + end + + ## + # Add a new set of HTML tags for an attribute. We allow separate start and + # end tags for flexibility + + def add_tag(name, start, stop) + @attr_tags << InlineTag.new(RDoc::Markup::Attribute.bitmap_for(name), start, stop) + end + + ## + # Given an HTML tag, decorate it with class information and the like if + # required. This is a no-op in the base class, but is overridden in HTML + # output classes that implement style sheets + + def annotate(tag) + tag + end + + ## + # :section: Visitor + + def start_accepting + @res = [] + @list_stack = [] + end + + def end_accepting + @res + end + + def accept_paragraph(am, fragment) + @res << Flow::P.new((convert_flow(am.flow(fragment.txt)))) + end + + def accept_verbatim(am, fragment) + @res << Flow::VERB.new((convert_flow(am.flow(fragment.txt)))) + end + + def accept_rule(am, fragment) + size = fragment.param + size = 10 if size > 10 + @res << Flow::RULE.new(size) + end + + def accept_list_start(am, fragment) + @list_stack.push(@res) + list = Flow::LIST.new(fragment.type) + @res << list + @res = list + end + + def accept_list_end(am, fragment) + @res = @list_stack.pop + end + + def accept_list_item(am, fragment) + @res << Flow::LI.new(fragment.param, convert_flow(am.flow(fragment.txt))) + end + + def accept_blank_line(am, fragment) + # @res << annotate("

") << "\n" + end + + def accept_heading(am, fragment) + @res << Flow::H.new(fragment.head_level, convert_flow(am.flow(fragment.txt))) + end + + private + + def on_tags(res, item) + attr_mask = item.turn_on + return if attr_mask.zero? + + @attr_tags.each do |tag| + if attr_mask & tag.bit != 0 + res << annotate(tag.on) + end + end + end + + def off_tags(res, item) + attr_mask = item.turn_off + return if attr_mask.zero? + + @attr_tags.reverse_each do |tag| + if attr_mask & tag.bit != 0 + res << annotate(tag.off) + end + end + end + + def convert_flow(flow) + res = "" + flow.each do |item| + case item + when String + res << convert_string(item) + when AttrChanger + off_tags(res, item) + on_tags(res, item) + when Special + res << convert_special(item) + else + raise "Unknown flow element: #{item.inspect}" + end + end + res + end + + def convert_string(item) + CGI.escapeHTML(item) + end + + def convert_special(special) + handled = false + Attribute.each_name_of(special.type) do |name| + method_name = "handle_special_#{name}" + if self.respond_to? method_name + special.text = send(method_name, special) + handled = true + end + end + + raise "Unhandled special: #{special}" unless handled + + special.text + end + + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_html.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_html.rb new file mode 100755 index 00000000..9e431502 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_html.rb @@ -0,0 +1,406 @@ +require 'rdoc/markup/formatter' +require 'rdoc/markup/fragments' +require 'rdoc/markup/inline' + +require 'cgi' + +class RDoc::Markup::ToHtml < RDoc::Markup::Formatter + + LIST_TYPE_TO_HTML = { + :BULLET => %w[

], + :NUMBER => %w[
], + :UPPERALPHA => %w[
], + :LOWERALPHA => %w[
], + :LABELED => %w[
], + :NOTE => %w[
], + } + + InlineTag = Struct.new(:bit, :on, :off) + + def initialize + super + + # @in_tt - tt nested levels count + # @tt_bit - cache + @in_tt = 0 + @tt_bit = RDoc::Markup::Attribute.bitmap_for :TT + + # external hyperlinks + @markup.add_special(/((link:|https?:|mailto:|ftp:|www\.)\S+\w)/, :HYPERLINK) + + # and links of the form [] + @markup.add_special(/(((\{.*?\})|\b\S+?)\[\S+?\.\S+?\])/, :TIDYLINK) + + init_tags + end + + ## + # Converts a target url to one that is relative to a given path + + def self.gen_relative_url(path, target) + from = File.dirname path + to, to_file = File.split target + + from = from.split "/" + to = to.split "/" + + from.delete '.' + to.delete '.' + + while from.size > 0 and to.size > 0 and from[0] == to[0] do + from.shift + to.shift + end + + from.fill ".." + from.concat to + from << to_file + File.join(*from) + end + + ## + # Generate a hyperlink for url, labeled with text. Handle the + # special cases for img: and link: described under handle_special_HYPERLINK + + def gen_url(url, text) + if url =~ /([A-Za-z]+):(.*)/ then + type = $1 + path = $2 + else + type = "http" + path = url + url = "http://#{url}" + end + + if type == "link" then + url = if path[0, 1] == '#' then # is this meaningful? + path + else + self.class.gen_relative_url @from_path, path + end + end + + if (type == "http" or type == "link") and + url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then + "" + else + "#{text.sub(%r{^#{type}:/*}, '')}" + end + end + + ## + # And we're invoked with a potential external hyperlink mailto: + # just gets inserted. http: links are checked to see if they + # reference an image. If so, that image gets inserted using an + # tag. Otherwise a conventional is used. We also + # support a special type of hyperlink, link:, which is a reference + # to a local file whose path is relative to the --op directory. + + def handle_special_HYPERLINK(special) + url = special.text + gen_url url, url + end + + ## + # Here's a hypedlink where the label is different to the URL + # #{name}" + else + name + end + + @seen[name] = out + + out + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_latex.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_latex.rb new file mode 100755 index 00000000..aac5c495 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_latex.rb @@ -0,0 +1,328 @@ +require 'rdoc/markup/formatter' +require 'rdoc/markup/fragments' +require 'rdoc/markup/inline' + +require 'cgi' + +## +# Convert SimpleMarkup to basic LaTeX report format. + +class RDoc::Markup::ToLaTeX < RDoc::Markup::Formatter + + BS = "\020" # \ + OB = "\021" # { + CB = "\022" # } + DL = "\023" # Dollar + + BACKSLASH = "#{BS}symbol#{OB}92#{CB}" + HAT = "#{BS}symbol#{OB}94#{CB}" + BACKQUOTE = "#{BS}symbol#{OB}0#{CB}" + TILDE = "#{DL}#{BS}sim#{DL}" + LESSTHAN = "#{DL}<#{DL}" + GREATERTHAN = "#{DL}>#{DL}" + + def self.l(str) + str.tr('\\', BS).tr('{', OB).tr('}', CB).tr('$', DL) + end + + def l(arg) + RDoc::Markup::ToLaTeX.l(arg) + end + + LIST_TYPE_TO_LATEX = { + :BULLET => [ l("\\begin{itemize}"), l("\\end{itemize}") ], + :NUMBER => [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\arabic" ], + :UPPERALPHA => [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\Alph" ], + :LOWERALPHA => [ l("\\begin{enumerate}"), l("\\end{enumerate}"), "\\alph" ], + :LABELED => [ l("\\begin{description}"), l("\\end{description}") ], + :NOTE => [ + l("\\begin{tabularx}{\\linewidth}{@{} l X @{}}"), + l("\\end{tabularx}") ], + } + + InlineTag = Struct.new(:bit, :on, :off) + + def initialize + init_tags + @list_depth = 0 + @prev_list_types = [] + end + + ## + # Set up the standard mapping of attributes to LaTeX + + def init_tags + @attr_tags = [ + InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:BOLD), l("\\textbf{"), l("}")), + InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:TT), l("\\texttt{"), l("}")), + InlineTag.new(RDoc::Markup::Attribute.bitmap_for(:EM), l("\\emph{"), l("}")), + ] + end + + ## + # Escape a LaTeX string + + def escape(str) + $stderr.print "FE: ", str if $DEBUG_RDOC + s = str. + sub(/\s+$/, ''). + gsub(/([_\${}&%#])/, "#{BS}\\1"). + gsub(/\\/, BACKSLASH). + gsub(/\^/, HAT). + gsub(/~/, TILDE). + gsub(//, GREATERTHAN). + gsub(/,,/, ",{},"). + gsub(/\`/, BACKQUOTE) + $stderr.print "-> ", s, "\n" if $DEBUG_RDOC + s + end + + ## + # Add a new set of LaTeX tags for an attribute. We allow + # separate start and end tags for flexibility + + def add_tag(name, start, stop) + @attr_tags << InlineTag.new(RDoc::Markup::Attribute.bitmap_for(name), start, stop) + end + + ## + # This is a higher speed (if messier) version of wrap + + def wrap(txt, line_len = 76) + res = "" + sp = 0 + ep = txt.length + while sp < ep + # scan back for a space + p = sp + line_len - 1 + if p >= ep + p = ep + else + while p > sp and txt[p] != ?\s + p -= 1 + end + if p <= sp + p = sp + line_len + while p < ep and txt[p] != ?\s + p += 1 + end + end + end + res << txt[sp...p] << "\n" + sp = p + sp += 1 while sp < ep and txt[sp] == ?\s + end + res + end + + ## + # :section: Visitor + + def start_accepting + @res = "" + @in_list_entry = [] + end + + def end_accepting + @res.tr(BS, '\\').tr(OB, '{').tr(CB, '}').tr(DL, '$') + end + + def accept_paragraph(am, fragment) + @res << wrap(convert_flow(am.flow(fragment.txt))) + @res << "\n" + end + + def accept_verbatim(am, fragment) + @res << "\n\\begin{code}\n" + @res << fragment.txt.sub(/[\n\s]+\Z/, '') + @res << "\n\\end{code}\n\n" + end + + def accept_rule(am, fragment) + size = fragment.param + size = 10 if size > 10 + @res << "\n\n\\rule{\\linewidth}{#{size}pt}\n\n" + end + + def accept_list_start(am, fragment) + @res << list_name(fragment.type, true) << "\n" + @in_list_entry.push false + end + + def accept_list_end(am, fragment) + if tag = @in_list_entry.pop + @res << tag << "\n" + end + @res << list_name(fragment.type, false) << "\n" + end + + def accept_list_item(am, fragment) + if tag = @in_list_entry.last + @res << tag << "\n" + end + @res << list_item_start(am, fragment) + @res << wrap(convert_flow(am.flow(fragment.txt))) << "\n" + @in_list_entry[-1] = list_end_for(fragment.type) + end + + def accept_blank_line(am, fragment) + # @res << "\n" + end + + def accept_heading(am, fragment) + @res << convert_heading(fragment.head_level, am.flow(fragment.txt)) + end + + private + + def on_tags(res, item) + attr_mask = item.turn_on + return if attr_mask.zero? + + @attr_tags.each do |tag| + if attr_mask & tag.bit != 0 + res << tag.on + end + end + end + + def off_tags(res, item) + attr_mask = item.turn_off + return if attr_mask.zero? + + @attr_tags.reverse_each do |tag| + if attr_mask & tag.bit != 0 + res << tag.off + end + end + end + + def convert_flow(flow) + res = "" + flow.each do |item| + case item + when String + $stderr.puts "Converting '#{item}'" if $DEBUG_RDOC + res << convert_string(item) + when AttrChanger + off_tags(res, item) + on_tags(res, item) + when Special + res << convert_special(item) + else + raise "Unknown flow element: #{item.inspect}" + end + end + res + end + + ## + # some of these patterns are taken from SmartyPants... + + def convert_string(item) + escape(item). + + # convert ... to elipsis (and make sure .... becomes .) + gsub(/\.\.\.\./, '.\ldots{}').gsub(/\.\.\./, '\ldots{}'). + + # convert single closing quote + gsub(%r{([^ \t\r\n\[\{\(])\'}, '\1\''). + gsub(%r{\'(?=\W|s\b)}, "'" ). + + # convert single opening quote + gsub(/'/, '`'). + + # convert double closing quote + gsub(%r{([^ \t\r\n\[\{\(])\"(?=\W)}, "\\1''"). + + # convert double opening quote + gsub(/"/, "``"). + + # convert copyright + gsub(/\(c\)/, '\copyright{}') + + end + + def convert_special(special) + handled = false + Attribute.each_name_of(special.type) do |name| + method_name = "handle_special_#{name}" + if self.respond_to? method_name + special.text = send(method_name, special) + handled = true + end + end + raise "Unhandled special: #{special}" unless handled + special.text + end + + def convert_heading(level, flow) + res = + case level + when 1 then "\\chapter{" + when 2 then "\\section{" + when 3 then "\\subsection{" + when 4 then "\\subsubsection{" + else "\\paragraph{" + end + + convert_flow(flow) + + "}\n" + end + + def list_name(list_type, is_open_tag) + tags = LIST_TYPE_TO_LATEX[list_type] || raise("Invalid list type: #{list_type.inspect}") + if tags[2] # enumerate + if is_open_tag + @list_depth += 1 + if @prev_list_types[@list_depth] != tags[2] + case @list_depth + when 1 + roman = "i" + when 2 + roman = "ii" + when 3 + roman = "iii" + when 4 + roman = "iv" + else + raise("Too deep list: level #{@list_depth}") + end + @prev_list_types[@list_depth] = tags[2] + return l("\\renewcommand{\\labelenum#{roman}}{#{tags[2]}{enum#{roman}}}") + "\n" + tags[0] + end + else + @list_depth -= 1 + end + end + tags[ is_open_tag ? 0 : 1] + end + + def list_item_start(am, fragment) + case fragment.type + when :BULLET, :NUMBER, :UPPERALPHA, :LOWERALPHA then + "\\item " + + when :LABELED then + "\\item[" + convert_flow(am.flow(fragment.param)) + "] " + + when :NOTE then + convert_flow(am.flow(fragment.param)) + " & " + else + raise "Invalid list type" + end + end + + def list_end_for(fragment_type) + case fragment_type + when :BULLET, :NUMBER, :UPPERALPHA, :LOWERALPHA, :LABELED then + "" + when :NOTE + "\\\\\n" + else + raise "Invalid list type" + end + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_test.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_test.rb new file mode 100755 index 00000000..b55a0cce --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_test.rb @@ -0,0 +1,53 @@ +require 'rdoc/markup' +require 'rdoc/markup/formatter' + +## +# This Markup outputter is used for testing purposes. + +class RDoc::Markup::ToTest < RDoc::Markup::Formatter + + ## + # :section: Visitor + + def start_accepting + @res = [] + end + + def end_accepting + @res + end + + def accept_paragraph(am, fragment) + @res << fragment.to_s + end + + def accept_verbatim(am, fragment) + @res << fragment.to_s + end + + def accept_list_start(am, fragment) + @res << fragment.to_s + end + + def accept_list_end(am, fragment) + @res << fragment.to_s + end + + def accept_list_item(am, fragment) + @res << fragment.to_s + end + + def accept_blank_line(am, fragment) + @res << fragment.to_s + end + + def accept_heading(am, fragment) + @res << fragment.to_s + end + + def accept_rule(am, fragment) + @res << fragment.to_s + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_texinfo.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_texinfo.rb new file mode 100755 index 00000000..2b75e00b --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/markup/to_texinfo.rb @@ -0,0 +1,73 @@ +require 'rdoc/markup/formatter' +require 'rdoc/markup/fragments' +require 'rdoc/markup/inline' + +require 'rdoc/markup' +require 'rdoc/markup/formatter' + +## +# Convert SimpleMarkup to basic TexInfo format +# +# TODO: WTF is AttributeManager for? + +class RDoc::Markup::ToTexInfo < RDoc::Markup::Formatter + + def format(text) + text.txt. + gsub(/@/, "@@"). + gsub(/\{/, "@{"). + gsub(/\}/, "@}"). + # gsub(/,/, "@,"). # technically only required in cross-refs + gsub(/\+([\w]+)\+/, "@code{\\1}"). + gsub(/\([^<]+)\<\/tt\>/, "@code{\\1}"). + gsub(/\*([\w]+)\*/, "@strong{\\1}"). + gsub(/\([^<]+)\<\/b\>/, "@strong{\\1}"). + gsub(/_([\w]+)_/, "@emph{\\1}"). + gsub(/\([^<]+)\<\/em\>/, "@emph{\\1}") + end + + # :section: Visitor + + def start_accepting + @text = [] + end + + def end_accepting + @text.join("\n") + end + + def accept_paragraph(attributes, text) + @text << format(text) + end + + def accept_verbatim(attributes, text) + @text << "@verb{|#{format(text)}|}" + end + + def accept_heading(attributes, text) + heading = ['@majorheading', '@chapheading'][text.head_level - 1] || '@heading' + @text << "#{heading} #{format(text)}" + end + + def accept_list_start(attributes, text) + @text << '@itemize @bullet' + end + + def accept_list_end(attributes, text) + @text << '@end itemize' + end + + def accept_list_item(attributes, text) + @text << "@item\n#{format(text)}" + end + + def accept_blank_line(attributes, text) + @text << "\n" + end + + def accept_rule(attributes, text) + @text << '-----' + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/meta_method.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/meta_method.rb new file mode 100755 index 00000000..e0c065c2 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/meta_method.rb @@ -0,0 +1,8 @@ +require 'rdoc/any_method' + +## +# MetaMethod represents a meta-programmed method + +class RDoc::MetaMethod < RDoc::AnyMethod +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/normal_class.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/normal_class.rb new file mode 100755 index 00000000..9a5c5e33 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/normal_class.rb @@ -0,0 +1,18 @@ +require 'rdoc/class_module' + +## +# A normal class, neither singleton nor anonymous + +class RDoc::NormalClass < RDoc::ClassModule + + def inspect # :nodoc: + superclass = @superclass ? " < #{@superclass}" : nil + "<%s:0x%x class %s%s includes: %p attributes: %p methods: %p aliases: %p>" % [ + self.class, object_id, + full_name, superclass, @includes, @attributes, @method_list, @aliases + ] + end + +end + + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/normal_module.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/normal_module.rb new file mode 100755 index 00000000..6f561c7b --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/normal_module.rb @@ -0,0 +1,34 @@ +require 'rdoc/class_module' + +## +# A normal module, like NormalClass + +class RDoc::NormalModule < RDoc::ClassModule + + ## + # Appends +comment+ to the current comment, but separated by a rule + + def comment=(comment) + return if comment.empty? + comment = @comment << "\n# ---\n" << comment unless @comment.empty? + + super + end + + def inspect # :nodoc: + "#<%s:0x%x module %s includes: %p attributes: %p methods: %p aliases: %p>" % [ + self.class, object_id, + full_name, @includes, @attributes, @method_list, @aliases + ] + end + + ## + # This is a module, returns true + + def module? + true + end + +end + + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/options.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/options.rb new file mode 100755 index 00000000..40f1bfcc --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/options.rb @@ -0,0 +1,542 @@ +require 'optparse' + +require 'rdoc/ri/paths' + +## +# RDoc::Options handles the parsing and storage of options + +class RDoc::Options + + ## + # Character-set + + attr_reader :charset + + ## + # Should diagrams be drawn? + + attr_accessor :diagram + + ## + # Files matching this pattern will be excluded + + attr_accessor :exclude + + ## + # Should we draw fileboxes in diagrams? + + attr_reader :fileboxes + + ## + # The list of files to be processed + + attr_accessor :files + + ## + # Scan newer sources than the flag file if true. + + attr_reader :force_update + + ## + # Description of the output generator (set with the -fmt option) + + attr_accessor :generator + + ## + # Formatter to mark up text with + + attr_accessor :formatter + + ## + # Image format for diagrams + + attr_reader :image_format + + ## + # Include line numbers in the source listings? + + attr_reader :include_line_numbers + + ## + # Name of the file, class or module to display in the initial index page (if + # not specified the first file we encounter is used) + + attr_accessor :main_page + + ## + # Merge into classes of the same name when generating ri + + attr_reader :merge + + ## + # The name of the output directory + + attr_accessor :op_dir + + ## + # Is RDoc in pipe mode? + + attr_accessor :pipe + + ## + # Array of directories to search for files to satisfy an :include: + + attr_reader :rdoc_include + + ## + # Include private and protected methods in the output? + + attr_accessor :show_all + + ## + # Include the '#' at the front of hyperlinked instance method names + + attr_reader :show_hash + + ## + # The number of columns in a tab + + attr_reader :tab_width + + ## + # Template to be used when generating output + + attr_reader :template + + ## + # Number of threads to parse with + + attr_accessor :threads + + ## + # Documentation title + + attr_reader :title + + ## + # Verbosity, zero means quiet + + attr_accessor :verbosity + + ## + # URL of web cvs frontend + + attr_reader :webcvs + + def initialize # :nodoc: + require 'rdoc/rdoc' + @op_dir = 'doc' + @show_all = false + @main_page = nil + @merge = false + @exclude = [] + @generators = RDoc::RDoc::GENERATORS + @generator = RDoc::Generator::Darkfish + @generator_name = nil + @rdoc_include = [] + @title = nil + @template = nil + @threads = if RUBY_PLATFORM == 'java' then + Java::java::lang::Runtime.getRuntime.availableProcessors * 2 + else + 2 + end + @diagram = false + @fileboxes = false + @show_hash = false + @image_format = 'png' + @tab_width = 8 + @include_line_numbers = false + @force_update = true + @verbosity = 1 + @pipe = false + + @webcvs = nil + + @charset = 'utf-8' + end + + ## + # Parse command line options. + + def parse(argv) + opts = OptionParser.new do |opt| + opt.program_name = File.basename $0 + opt.version = RDoc::VERSION + opt.release = nil + opt.summary_indent = ' ' * 4 + opt.banner = <<-EOF +Usage: #{opt.program_name} [options] [names...] + + Files are parsed, and the information they contain collected, before any + output is produced. This allows cross references between all files to be + resolved. If a name is a directory, it is traversed. If no names are + specified, all Ruby files in the current directory (and subdirectories) are + processed. + + How RDoc generates output depends on the output formatter being used, and on + the options you give. + + - Darkfish creates frameless HTML output by Michael Granger. + + - ri creates ri data files + EOF + + opt.separator nil + opt.separator "Parsing Options:" + opt.separator nil + + opt.on("--all", "-a", + "Include all methods (not just public) in", + "the output.") do |value| + @show_all = value + end + + opt.separator nil + + opt.on("--exclude=PATTERN", "-x", Regexp, + "Do not process files or directories", + "matching PATTERN.") do |value| + @exclude << value + end + + opt.separator nil + + opt.on("--extension=NEW=OLD", "-E", + "Treat files ending with .new as if they", + "ended with .old. Using '-E cgi=rb' will", + "cause xxx.cgi to be parsed as a Ruby file.") do |value| + new, old = value.split(/=/, 2) + + unless new and old then + raise OptionParser::InvalidArgument, "Invalid parameter to '-E'" + end + + unless RDoc::ParserFactory.alias_extension old, new then + raise OptionParser::InvalidArgument, "Unknown extension .#{old} to -E" + end + end + + opt.separator nil + + opt.on("--force-update", "-U", + "Forces rdoc to scan all sources even if", + "newer than the flag file.") do |value| + @force_update = value + end + + opt.separator nil + + opt.on("--pipe", + "Convert RDoc on stdin to HTML") do + @pipe = true + end + + opt.separator nil + + opt.on("--threads=THREADS", Integer, + "Number of threads to parse with.") do |threads| + @threads = threads + end + + opt.separator nil + opt.separator "Generator Options:" + opt.separator nil + + opt.on("--charset=CHARSET", "-c", + "Specifies the output HTML character-set.") do |value| + @charset = value + end + + opt.separator nil + + generator_text = @generators.keys.map { |name| " #{name}" }.sort + + opt.on("--fmt=FORMAT", "--format=FORMAT", "-f", @generators.keys, + "Set the output formatter. One of:", *generator_text) do |value| + @generator_name = value.downcase + setup_generator + end + + opt.separator nil + + opt.on("--include=DIRECTORIES", "-i", Array, + "Set (or add to) the list of directories to", + "be searched when satisfying :include:", + "requests. Can be used more than once.") do |value| + @rdoc_include.concat value.map { |dir| dir.strip } + end + + opt.separator nil + + opt.on("--line-numbers", "-N", + "Include line numbers in the source code.") do |value| + @include_line_numbers = value + end + + opt.separator nil + + opt.on("--main=NAME", "-m", + "NAME will be the initial page displayed.") do |value| + @main_page = value + end + + opt.separator nil + + opt.on("--output=DIR", "--op", "-o", + "Set the output directory.") do |value| + @op_dir = value + end + + opt.separator nil + + opt.on("--show-hash", "-H", + "A name of the form #name in a comment is a", + "possible hyperlink to an instance method", + "name. When displayed, the '#' is removed", + "unless this option is specified.") do |value| + @show_hash = value + end + + opt.separator nil + + opt.on("--tab-width=WIDTH", "-w", OptionParser::DecimalInteger, + "Set the width of tab characters.") do |value| + @tab_width = value + end + + opt.separator nil + + opt.on("--template=NAME", "-T", + "Set the template used when generating", + "output.") do |value| + @template = value + end + + opt.separator nil + + opt.on("--title=TITLE", "-t", + "Set TITLE as the title for HTML output.") do |value| + @title = value + end + + opt.separator nil + + opt.on("--webcvs=URL", "-W", + "Specify a URL for linking to a web frontend", + "to CVS. If the URL contains a '\%s', the", + "name of the current file will be", + "substituted; if the URL doesn't contain a", + "'\%s', the filename will be appended to it.") do |value| + @webcvs = value + end + + opt.separator nil + opt.separator "Diagram Options:" + opt.separator nil + + image_formats = %w[gif png jpg jpeg] + opt.on("--image-format=FORMAT", "-I", image_formats, + "Sets output image format for diagrams. Can", + "be #{image_formats.join ', '}. If this option", + "is omitted, png is used. Requires", + "diagrams.") do |value| + @image_format = value + end + + opt.separator nil + + opt.on("--diagram", "-d", + "Generate diagrams showing modules and", + "classes. You need dot V1.8.6 or later to", + "use the --diagram option correctly. Dot is", + "available from http://graphviz.org") do |value| + check_diagram + @diagram = true + end + + opt.separator nil + + opt.on("--fileboxes", "-F", + "Classes are put in boxes which represents", + "files, where these classes reside. Classes", + "shared between more than one file are", + "shown with list of files that are sharing", + "them. Silently discarded if --diagram is", + "not given.") do |value| + @fileboxes = value + end + + opt.separator nil + opt.separator "ri Generator Options:" + opt.separator nil + + opt.on("--ri", "-r", + "Generate output for use by `ri`. The files", + "are stored in the '.rdoc' directory under", + "your home directory unless overridden by a", + "subsequent --op parameter, so no special", + "privileges are needed.") do |value| + @generator_name = "ri" + @op_dir = RDoc::RI::Paths::HOMEDIR + setup_generator + end + + opt.separator nil + + opt.on("--ri-site", "-R", + "Generate output for use by `ri`. The files", + "are stored in a site-wide directory,", + "making them accessible to others, so", + "special privileges are needed.") do |value| + @generator_name = "ri" + @op_dir = RDoc::RI::Paths::SITEDIR + setup_generator + end + + opt.separator nil + + opt.on("--merge", "-M", + "When creating ri output, merge previously", + "processed classes into previously", + "documented classes of the same name.") do |value| + @merge = value + end + + opt.separator nil + opt.separator "Generic Options:" + opt.separator nil + + opt.on("--debug", "-D", + "Displays lots on internal stuff.") do |value| + $DEBUG_RDOC = value + end + + opt.on("--quiet", "-q", + "Don't show progress as we parse.") do |value| + @verbosity = 0 + end + + opt.on("--verbose", "-v", + "Display extra progress as we parse.") do |value| + @verbosity = 2 + end + + opt.separator nil + opt.separator 'Deprecated options - these warn when set' + opt.separator nil + + opt.on("--inline-source", "-S") do |value| + warn "--inline-source will be removed from RDoc on or after August 2009" + end + + opt.on("--promiscuous", "-p") do |value| + warn "--promiscuous will be removed from RDoc on or after August 2009" + end + + opt.separator nil + end + + argv.insert(0, *ENV['RDOCOPT'].split) if ENV['RDOCOPT'] + + opts.parse! argv + + @files = argv.dup + + @rdoc_include << "." if @rdoc_include.empty? + + if @exclude.empty? then + @exclude = nil + else + @exclude = Regexp.new(@exclude.join("|")) + end + + check_files + + # If no template was specified, use the default template for the output + # formatter + + @template ||= @generator_name + + rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e + puts opts + puts + puts e + exit 1 + end + + ## + # Set the title, but only if not already set. This means that a title set + # from the command line trumps one set in a source file + + def title=(string) + @title ||= string + end + + ## + # Don't display progress as we process the files + + def quiet + @verbosity.zero? + end + + def quiet=(bool) + @verbosity = bool ? 0 : 1 + end + + private + + ## + # Set up an output generator for the format in @generator_name + + def setup_generator + @generator = @generators[@generator_name] + + unless @generator then + raise OptionParser::InvalidArgument, "Invalid output formatter" + end + end + + # Check that the right version of 'dot' is available. Unfortunately this + # doesn't work correctly under Windows NT, so we'll bypass the test under + # Windows. + + def check_diagram + return if RUBY_PLATFORM =~ /mswin|cygwin|mingw|bccwin/ + + ok = false + ver = nil + + IO.popen "dot -V 2>&1" do |io| + ver = io.read + if ver =~ /dot.+version(?:\s+gviz)?\s+(\d+)\.(\d+)/ then + ok = ($1.to_i > 1) || ($1.to_i == 1 && $2.to_i >= 8) + end + end + + unless ok then + if ver =~ /^dot.+version/ then + $stderr.puts "Warning: You may need dot V1.8.6 or later to use\n", + "the --diagram option correctly. You have:\n\n ", + ver, + "\nDiagrams might have strange background colors.\n\n" + else + $stderr.puts "You need the 'dot' program to produce diagrams.", + "(see http://www.research.att.com/sw/tools/graphviz/)\n\n" + exit + end + end + end + + ## + # Check that the files on the command line exist + + def check_files + @files.each do |f| + stat = File.stat f rescue next + raise RDoc::Error, "file '#{f}' not readable" unless stat.readable? + end + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser.rb new file mode 100755 index 00000000..df3becd0 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser.rb @@ -0,0 +1,138 @@ +require 'rdoc' +require 'rdoc/code_objects' +require 'rdoc/markup/preprocess' +require 'rdoc/stats' + +## +# A parser is simple a class that implements +# +# #initialize(file_name, body, options) +# +# and +# +# #scan +# +# The initialize method takes a file name to be used, the body of the file, +# and an RDoc::Options object. The scan method is then called to return an +# appropriately parsed TopLevel code object. +# +# The ParseFactory is used to redirect to the correct parser given a +# filename extension. This magic works because individual parsers have to +# register themselves with us as they are loaded in. The do this using the +# following incantation +# +# require "rdoc/parser" +# +# class RDoc::Parser::Xyz < RDoc::Parser +# parse_files_matching /\.xyz$/ # <<<< +# +# def initialize(file_name, body, options) +# ... +# end +# +# def scan +# ... +# end +# end +# +# Just to make life interesting, if we suspect a plain text file, we also +# look for a shebang line just in case it's a potential shell script + +class RDoc::Parser + + @parsers = [] + + class << self + attr_reader :parsers + end + + ## + # Alias an extension to another extension. After this call, files ending + # "new_ext" will be parsed using the same parser as "old_ext" + + def self.alias_extension(old_ext, new_ext) + old_ext = old_ext.sub(/^\.(.*)/, '\1') + new_ext = new_ext.sub(/^\.(.*)/, '\1') + + parser = can_parse "xxx.#{old_ext}" + return false unless parser + + RDoc::Parser.parsers.unshift [/\.#{new_ext}$/, parser] + + true + end + + ## + # Shamelessly stolen from the ptools gem (since RDoc cannot depend on + # the gem). + + def self.binary?(file) + s = (File.read(file, File.stat(file).blksize) || "").split(//) + + if s.size > 0 then + ((s.size - s.grep(" ".."~").size) / s.size.to_f) > 0.30 + else + false + end + end + private_class_method :binary? + + ## + # Return a parser that can handle a particular extension + + def self.can_parse(file_name) + parser = RDoc::Parser.parsers.find { |regexp,| regexp =~ file_name }.last + + # + # The default parser should *NOT* parse binary files. + # + if parser == RDoc::Parser::Simple && file_name !~ /\.(txt|rdoc)$/ then + if binary? file_name then + return nil + end + end + + return parser + end + + ## + # Find the correct parser for a particular file name. Return a SimpleParser + # for ones that we don't know + + def self.for(top_level, file_name, body, options, stats) + # If no extension, look for shebang + if file_name !~ /\.\w+$/ && body =~ %r{\A#!(.+)} then + shebang = $1 + case shebang + when %r{env\s+ruby}, %r{/ruby} + file_name = "dummy.rb" + end + end + + parser = can_parse file_name + + # This method must return a parser. + parser ||= RDoc::Parser::Simple + + parser.new top_level, file_name, body, options, stats + end + + ## + # Record which file types this parser can understand. + + def self.parse_files_matching(regexp) + RDoc::Parser.parsers.unshift [regexp, self] + end + + def initialize(top_level, file_name, content, options, stats) + @top_level = top_level + @file_name = file_name + @content = content + @options = options + @stats = stats + end + +end + +require 'rdoc/parser/simple' + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/c.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/c.rb new file mode 100755 index 00000000..5a11889b --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/c.rb @@ -0,0 +1,678 @@ +require 'rdoc/parser' +require 'rdoc/parser/ruby' +require 'rdoc/known_classes' + +## +# We attempt to parse C extension files. Basically we look for +# the standard patterns that you find in extensions: rb_define_class, +# rb_define_method and so on. We also try to find the corresponding +# C source for the methods and extract comments, but if we fail +# we don't worry too much. +# +# The comments associated with a Ruby method are extracted from the C +# comment block associated with the routine that _implements_ that +# method, that is to say the method whose name is given in the +# rb_define_method call. For example, you might write: +# +# /* +# * Returns a new array that is a one-dimensional flattening of this +# * array (recursively). That is, for every element that is an array, +# * extract its elements into the new array. +# * +# * s = [ 1, 2, 3 ] #=> [1, 2, 3] +# * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]] +# * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10] +# * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +# */ +# static VALUE +# rb_ary_flatten(ary) +# VALUE ary; +# { +# ary = rb_obj_dup(ary); +# rb_ary_flatten_bang(ary); +# return ary; +# } +# +# ... +# +# void +# Init_Array() +# { +# ... +# rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0); +# +# Here RDoc will determine from the rb_define_method line that there's a +# method called "flatten" in class Array, and will look for the implementation +# in the method rb_ary_flatten. It will then use the comment from that +# method in the HTML output. This method must be in the same source file +# as the rb_define_method. +# +# C classes can be diagrammed (see /tc/dl/ruby/ruby/error.c), and RDoc +# integrates C and Ruby source into one tree +# +# The comment blocks may include special directives: +# +# [Document-class: name] +# This comment block is documentation for the given class. Use this +# when the Init_xxx method is not named after the class. +# +# [Document-method: name] +# This comment documents the named method. Use when RDoc cannot +# automatically find the method from it's declaration +# +# [call-seq: text up to an empty line] +# Because C source doesn't give descripive names to Ruby-level parameters, +# you need to document the calling sequence explicitly +# +# In addition, RDoc assumes by default that the C method implementing a +# Ruby function is in the same source file as the rb_define_method call. +# If this isn't the case, add the comment: +# +# rb_define_method(....); // in: filename +# +# As an example, we might have an extension that defines multiple classes +# in its Init_xxx method. We could document them using +# +# /* +# * Document-class: MyClass +# * +# * Encapsulate the writing and reading of the configuration +# * file. ... +# */ +# +# /* +# * Document-method: read_value +# * +# * call-seq: +# * cfg.read_value(key) -> value +# * cfg.read_value(key} { |key| } -> value +# * +# * Return the value corresponding to +key+ from the configuration. +# * In the second form, if the key isn't found, invoke the +# * block and return its value. +# */ + +class RDoc::Parser::C < RDoc::Parser + + parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/) + + ## + # C file the parser is parsing + + attr_accessor :content + + ## + # Resets cross-file state. Call when parsing different projects that need + # separate documentation. + + def self.reset + @@enclosure_classes = {} + @@known_bodies = {} + end + + reset + + ## + # Prepare to parse a C file + + def initialize(top_level, file_name, content, options, stats) + super + + @known_classes = RDoc::KNOWN_CLASSES.dup + @content = handle_tab_width handle_ifdefs_in(@content) + @classes = Hash.new + @file_dir = File.dirname(@file_name) + end + + def do_aliases + @content.scan(%r{rb_define_alias\s*\(\s*(\w+),\s*"([^"]+)",\s*"([^"]+)"\s*\)}m) do + |var_name, new_name, old_name| + class_name = @known_classes[var_name] || var_name + class_obj = find_class(var_name, class_name) + + as = class_obj.add_alias RDoc::Alias.new("", old_name, new_name, "") + + @stats.add_alias as + end + end + + def do_classes + @content.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do + |var_name, class_name| + handle_class_module(var_name, "module", class_name, nil, nil) + end + + # The '.' lets us handle SWIG-generated files + @content.scan(/([\w\.]+)\s* = \s*rb_define_class\s* + \( + \s*"(\w+)", + \s*(\w+)\s* + \)/mx) do |var_name, class_name, parent| + handle_class_module(var_name, "class", class_name, parent, nil) + end + + @content.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do + |var_name, class_name, parent| + parent = nil if parent == "0" + handle_class_module(var_name, "class", class_name, parent, nil) + end + + @content.scan(/(\w+)\s* = \s*rb_define_module_under\s* + \( + \s*(\w+), + \s*"(\w+)" + \s*\)/mx) do |var_name, in_module, class_name| + handle_class_module(var_name, "module", class_name, nil, in_module) + end + + @content.scan(/([\w\.]+)\s* = \s*rb_define_class_under\s* + \( + \s*(\w+), + \s*"(\w+)", + \s*([\w\*\s\(\)\.\->]+)\s* # for SWIG + \s*\)/mx) do |var_name, in_module, class_name, parent| + handle_class_module(var_name, "class", class_name, parent, in_module) + end + end + + def do_constants + @content.scan(%r{\Wrb_define_ + ( + variable | + readonly_variable | + const | + global_const | + ) + \s*\( + (?:\s*(\w+),)? + \s*"(\w+)", + \s*(.*?)\s*\)\s*; + }xm) do |type, var_name, const_name, definition| + var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel" + handle_constants(type, var_name, const_name, definition) + end + end + + ## + # Look for includes of the form: + # + # rb_include_module(rb_cArray, rb_mEnumerable); + + def do_includes + @content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m| + if cls = @classes[c] + m = @known_classes[m] || m + cls.add_include RDoc::Include.new(m, "") + end + end + end + + def do_methods + @content.scan(%r{rb_define_ + ( + singleton_method | + method | + module_function | + private_method + ) + \s*\(\s*([\w\.]+), + \s*"([^"]+)", + \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, + \s*(-?\w+)\s*\) + (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))? + }xm) do + |type, var_name, meth_name, meth_body, param_count, source_file| + + # Ignore top-object and weird struct.c dynamic stuff + next if var_name == "ruby_top_self" + next if var_name == "nstr" + next if var_name == "envtbl" + next if var_name == "argf" # it'd be nice to handle this one + + var_name = "rb_cObject" if var_name == "rb_mKernel" + handle_method(type, var_name, meth_name, + meth_body, param_count, source_file) + end + + @content.scan(%r{rb_define_attr\( + \s*([\w\.]+), + \s*"([^"]+)", + \s*(\d+), + \s*(\d+)\s*\); + }xm) do |var_name, attr_name, attr_reader, attr_writer| + #var_name = "rb_cObject" if var_name == "rb_mKernel" + handle_attr(var_name, attr_name, + attr_reader.to_i != 0, + attr_writer.to_i != 0) + end + + @content.scan(%r{rb_define_global_function\s*\( + \s*"([^"]+)", + \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, + \s*(-?\w+)\s*\) + (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))? + }xm) do |meth_name, meth_body, param_count, source_file| + handle_method("method", "rb_mKernel", meth_name, + meth_body, param_count, source_file) + end + + @content.scan(/define_filetest_function\s*\( + \s*"([^"]+)", + \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, + \s*(-?\w+)\s*\)/xm) do + |meth_name, meth_body, param_count| + + handle_method("method", "rb_mFileTest", meth_name, meth_body, param_count) + handle_method("singleton_method", "rb_cFile", meth_name, meth_body, param_count) + end + end + + def find_attr_comment(attr_name) + if @content =~ %r{((?>/\*.*?\*/\s+)) + rb_define_attr\((?:\s*(\w+),)?\s*"#{attr_name}"\s*,.*?\)\s*;}xmi + $1 + elsif @content =~ %r{Document-attr:\s#{attr_name}\s*?\n((?>.*?\*/))}m + $1 + else + '' + end + end + + ## + # Find the C code corresponding to a Ruby method + + def find_body(class_name, meth_name, meth_obj, body, quiet = false) + case body + when %r"((?>/\*.*?\*/\s*))((?:(?:static|SWIGINTERN)\s+)?(?:intern\s+)?VALUE\s+#{meth_name} + \s*(\([^)]*\))([^;]|$))"xm + comment = $1 + body_text = $2 + params = $3 + + remove_private_comments comment if comment + + # see if we can find the whole body + + re = Regexp.escape(body_text) + '[^(]*^\{.*?^\}' + body_text = $& if /#{re}/m =~ body + + # The comment block may have been overridden with a 'Document-method' + # block. This happens in the interpreter when multiple methods are + # vectored through to the same C method but those methods are logically + # distinct (for example Kernel.hash and Kernel.object_id share the same + # implementation + + override_comment = find_override_comment class_name, meth_obj.name + comment = override_comment if override_comment + + find_modifiers comment, meth_obj if comment + +# meth_obj.params = params + meth_obj.start_collecting_tokens + meth_obj.add_token RDoc::RubyToken::Token.new(1,1).set_text(body_text) + meth_obj.comment = mangle_comment comment + when %r{((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+#{meth_name}\s+(\w+))}m + comment = $1 + body_text = $2 + find_body class_name, $3, meth_obj, body, true + find_modifiers comment, meth_obj + + meth_obj.start_collecting_tokens + meth_obj.add_token RDoc::RubyToken::Token.new(1,1).set_text(body_text) + meth_obj.comment = mangle_comment(comment) + meth_obj.comment.to_s + when %r{^\s*\#\s*define\s+#{meth_name}\s+(\w+)}m + unless find_body(class_name, $1, meth_obj, body, true) + warn "No definition for #{meth_name}" unless @options.quiet + return false + end + else + # No body, but might still have an override comment + comment = find_override_comment(class_name, meth_obj.name) + + if comment + find_modifiers(comment, meth_obj) + meth_obj.comment = mangle_comment(comment) + else + warn "No definition for #{meth_name}" unless @options.quiet + return false + end + end + true + end + + def find_class(raw_name, name) + unless @classes[raw_name] + if raw_name =~ /^rb_m/ + container = @top_level.add_module RDoc::NormalModule, name + else + container = @top_level.add_class RDoc::NormalClass, name + end + + container.record_location @top_level + @classes[raw_name] = container + end + @classes[raw_name] + end + + ## + # Look for class or module documentation above Init_+class_name+(void), + # in a Document-class +class_name+ (or module) comment or above an + # rb_define_class (or module). If a comment is supplied above a matching + # Init_ and a rb_define_class the Init_ comment is used. + # + # /* + # * This is a comment for Foo + # */ + # Init_Foo(void) { + # VALUE cFoo = rb_define_class("Foo", rb_cObject); + # } + # + # /* + # * Document-class: Foo + # * This is a comment for Foo + # */ + # Init_foo(void) { + # VALUE cFoo = rb_define_class("Foo", rb_cObject); + # } + # + # /* + # * This is a comment for Foo + # */ + # VALUE cFoo = rb_define_class("Foo", rb_cObject); + + def find_class_comment(class_name, class_meth) + comment = nil + + if @content =~ %r{((?>/\*.*?\*/\s+)) + (static\s+)?void\s+Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)\)}xmi then + comment = $1 + elsif @content =~ %r{Document-(?:class|module):\s+#{class_name}\s*?(?:<\s+[:,\w]+)?\n((?>.*?\*/))}m then + comment = $1 + elsif @content =~ %r{((?>/\*.*?\*/\s+)) + ([\w\.\s]+\s* = \s+)?rb_define_(class|module).*?"(#{class_name})"}xm then + comment = $1 + end + + class_meth.comment = mangle_comment comment if comment + end + + ## + # Finds a comment matching +type+ and +const_name+ either above the + # comment or in the matching Document- section. + + def find_const_comment(type, const_name) + if @content =~ %r{((?>^\s*/\*.*?\*/\s+)) + rb_define_#{type}\((?:\s*(\w+),)?\s*"#{const_name}"\s*,.*?\)\s*;}xmi + $1 + elsif @content =~ %r{Document-(?:const|global|variable):\s#{const_name}\s*?\n((?>.*?\*/))}m + $1 + else + '' + end + end + + ## + # If the comment block contains a section that looks like: + # + # call-seq: + # Array.new + # Array.new(10) + # + # use it for the parameters. + + def find_modifiers(comment, meth_obj) + if comment.sub!(/:nodoc:\s*^\s*\*?\s*$/m, '') or + comment.sub!(/\A\/\*\s*:nodoc:\s*\*\/\Z/, '') + meth_obj.document_self = false + end + if comment.sub!(/call-seq:(.*?)^\s*\*?\s*$/m, '') or + comment.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '') + seq = $1 + seq.gsub!(/^\s*\*\s*/, '') + meth_obj.call_seq = seq + end + end + + def find_override_comment(class_name, meth_name) + name = Regexp.escape(meth_name) + if @content =~ %r{Document-method:\s+#{class_name}(?:\.|::|#)#{name}\s*?\n((?>.*?\*/))}m then + $1 + elsif @content =~ %r{Document-method:\s#{name}\s*?\n((?>.*?\*/))}m then + $1 + end + end + + def handle_attr(var_name, attr_name, reader, writer) + rw = '' + if reader + #@stats.num_methods += 1 + rw << 'R' + end + if writer + #@stats.num_methods += 1 + rw << 'W' + end + + class_name = @known_classes[var_name] + + return unless class_name + + class_obj = find_class(var_name, class_name) + + if class_obj + comment = find_attr_comment(attr_name) + unless comment.empty? + comment = mangle_comment(comment) + end + att = RDoc::Attr.new '', attr_name, rw, comment + class_obj.add_attribute(att) + end + end + + def handle_class_module(var_name, class_mod, class_name, parent, in_module) + parent_name = @known_classes[parent] || parent + + if in_module + enclosure = @classes[in_module] || @@enclosure_classes[in_module] + unless enclosure + if enclosure = @known_classes[in_module] + handle_class_module(in_module, (/^rb_m/ =~ in_module ? "module" : "class"), + enclosure, nil, nil) + enclosure = @classes[in_module] + end + end + unless enclosure + warn("Enclosing class/module '#{in_module}' for " + + "#{class_mod} #{class_name} not known") + return + end + else + enclosure = @top_level + end + + if class_mod == "class" then + full_name = if RDoc::ClassModule === enclosure then + enclosure.full_name + "::#{class_name}" + else + class_name + end + + if @content =~ %r{Document-class:\s+#{full_name}\s*<\s+([:,\w]+)} then + parent_name = $1 + end + cm = enclosure.add_class RDoc::NormalClass, class_name, parent_name + @stats.add_class cm + else + cm = enclosure.add_module RDoc::NormalModule, class_name + @stats.add_module cm + end + + cm.record_location enclosure.top_level + + find_class_comment cm.full_name, cm + + @classes[var_name] = cm + @@enclosure_classes[var_name] = cm + @known_classes[var_name] = cm.full_name + end + + ## + # Adds constant comments. By providing some_value: at the start ofthe + # comment you can override the C value of the comment to give a friendly + # definition. + # + # /* 300: The perfect score in bowling */ + # rb_define_const(cFoo, "PERFECT", INT2FIX(300); + # + # Will override +INT2FIX(300)+ with the value +300+ in the output RDoc. + # Values may include quotes and escaped colons (\:). + + def handle_constants(type, var_name, const_name, definition) + #@stats.num_constants += 1 + class_name = @known_classes[var_name] + + return unless class_name + + class_obj = find_class(var_name, class_name) + + unless class_obj + warn("Enclosing class/module '#{const_name}' for not known") + return + end + + comment = find_const_comment(type, const_name) + + # In the case of rb_define_const, the definition and comment are in + # "/* definition: comment */" form. The literal ':' and '\' characters + # can be escaped with a backslash. + if type.downcase == 'const' then + elements = mangle_comment(comment).split(':') + if elements.nil? or elements.empty? then + con = RDoc::Constant.new(const_name, definition, + mangle_comment(comment)) + else + new_definition = elements[0..-2].join(':') + if new_definition.empty? then # Default to literal C definition + new_definition = definition + else + new_definition.gsub!("\:", ":") + new_definition.gsub!("\\", '\\') + end + new_definition.sub!(/\A(\s+)/, '') + new_comment = $1.nil? ? elements.last : "#{$1}#{elements.last.lstrip}" + con = RDoc::Constant.new(const_name, new_definition, + mangle_comment(new_comment)) + end + else + con = RDoc::Constant.new const_name, definition, mangle_comment(comment) + end + + class_obj.add_constant(con) + end + + ## + # Removes #ifdefs that would otherwise confuse us + + def handle_ifdefs_in(body) + body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1') + end + + def handle_method(type, var_name, meth_name, meth_body, param_count, + source_file = nil) + class_name = @known_classes[var_name] + + return unless class_name + + class_obj = find_class var_name, class_name + + if class_obj then + if meth_name == "initialize" then + meth_name = "new" + type = "singleton_method" + end + + meth_obj = RDoc::AnyMethod.new '', meth_name + meth_obj.singleton = %w[singleton_method module_function].include? type + + p_count = (Integer(param_count) rescue -1) + + if p_count < 0 + meth_obj.params = "(...)" + elsif p_count == 0 + meth_obj.params = "()" + else + meth_obj.params = "(" + (1..p_count).map{|i| "p#{i}"}.join(", ") + ")" + end + + if source_file then + file_name = File.join(@file_dir, source_file) + body = (@@known_bodies[source_file] ||= File.read(file_name)) + else + body = @content + end + + if find_body(class_name, meth_body, meth_obj, body) and meth_obj.document_self then + class_obj.add_method meth_obj + @stats.add_method meth_obj + meth_obj.visibility = :private if 'private_method' == type + end + end + end + + def handle_tab_width(body) + if /\t/ =~ body + tab_width = @options.tab_width + body.split(/\n/).map do |line| + 1 while line.gsub!(/\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)} && $~ #` + line + end .join("\n") + else + body + end + end + + ## + # Remove the /*'s and leading asterisks from C comments + + def mangle_comment(comment) + comment.sub!(%r{/\*+}) { " " * $&.length } + comment.sub!(%r{\*+/}) { " " * $&.length } + comment.gsub!(/^[ \t]*\*/m) { " " * $&.length } + comment + end + + ## + # Removes lines that are commented out that might otherwise get picked up + # when scanning for classes and methods + + def remove_commented_out_lines + @content.gsub!(%r{//.*rb_define_}, '//') + end + + def remove_private_comments(comment) + comment.gsub!(/\/?\*--\n(.*?)\/?\*\+\+/m, '') + comment.sub!(/\/?\*--\n.*/m, '') + end + + ## + # Extract the classes/modules and methods from a C file and return the + # corresponding top-level object + + def scan + remove_commented_out_lines + do_classes + do_constants + do_methods + do_includes + do_aliases + @top_level + end + + def warn(msg) + $stderr.puts + $stderr.puts msg + $stderr.flush + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/perl.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/perl.rb new file mode 100755 index 00000000..43d1e9ff --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/perl.rb @@ -0,0 +1,165 @@ +require 'rdoc/parser' + +## +# +# This is an attamept to write a basic parser for Perl's +# POD (Plain old Documentation) format. Ruby code must +# co-exist with Perl, and some tasks are easier in Perl +# than Ruby because of existing libraries. +# +# One difficult is that Perl POD has no means of identifying +# the classes (packages) and methods (subs) with which it +# is associated, it is more like literate programming in so +# far as it just happens to be in the same place as the code, +# but need not be. +# +# We would like to support all the markup the POD provides +# so that it will convert happily to HTML. At the moment +# I don't think I can do that: time constraints. +# + +class RDoc::Parser::PerlPOD < RDoc::Parser + + parse_files_matching(/.p[lm]$/) + + ## + # Prepare to parse a perl file + + def initialize(top_level, file_name, content, options, stats) + super + + preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include + + preprocess.handle @content do |directive, param| + warn "Unrecognized directive '#{directive}' in #{@file_name}" + end + end + + ## + # Extract the Pod(-like) comments from the code. + # At its most basic there will ne no need to distinguish + # between the different types of header, etc. + # + # This uses a simple finite state machine, in a very + # procedural pattern. I could "replace case with polymorphism" + # but I think it would obscure the intent, scatter the + # code all over tha place. This machine is necessary + # because POD requires that directives be preceded by + # blank lines, so reading line by line is necessary, + # and preserving state about what is seen is necesary. + + def scan + + @top_level.comment ||= "" + state=:code_blank + line_number = 0 + line = nil + + # This started out as a really long nested case statement, + # which also led to repetitive code. I'd like to avoid that + # so I'm using a "table" instead. + + # Firstly we need some procs to do the transition and processing + # work. Because these are procs they are closures, and they can + # use variables in the local scope. + # + # First, the "nothing to see here" stuff. + code_noop = lambda do + if line =~ /^\s+$/ + state = :code_blank + end + end + + pod_noop = lambda do + if line =~ /^\s+$/ + state = :pod_blank + end + @top_level.comment += filter(line) + end + + begin_noop = lambda do + if line =~ /^\s+$/ + state = :begin_blank + end + @top_level.comment += filter(line) + end + + # Now for the blocks that process code and comments... + + transit_to_pod = lambda do + case line + when /^=(?:pod|head\d+)/ + state = :pod_no_blank + @top_level.comment += filter(line) + when /^=over/ + state = :over_no_blank + @top_level.comment += filter(line) + when /^=(?:begin|for)/ + state = :begin_no_blank + end + end + + process_pod = lambda do + case line + when /^\s*$/ + state = :pod_blank + @top_level.comment += filter(line) + when /^=cut/ + state = :code_no_blank + when /^=end/ + $stderr.puts "'=end' unexpected at #{line_number} in #{@file_name}" + else + @top_level.comment += filter(line) + end + end + + + process_begin = lambda do + case line + when /^\s*$/ + state = :begin_blank + @top_level.comment += filter(line) + when /^=end/ + state = :code_no_blank + when /^=cut/ + $stderr.puts "'=cut' unexpected at #{line_number} in #{@file_name}" + else + @top_level.comment += filter(line) + end + + end + + + transitions = { :code_no_blank => code_noop, + :code_blank => transit_to_pod, + :pod_no_blank => pod_noop, + :pod_blank => process_pod, + :begin_no_blank => begin_noop, + :begin_blank => process_begin} + @content.each_line do |l| + line = l + line_number += 1 + transitions[state].call + end # each line + + @top_level + end + + # Filter the perl markup that does the same as the rdoc + # filtering. Only basic for now. Will probably need a + # proper parser to cope with C<<...>> etc + def filter(comment) + return '' if comment =~ /^=pod\s*$/ + comment.gsub!(/^=pod/, '==') + comment.gsub!(/^=head(\d+)/) do + "=" * $1.to_i + end + comment.gsub!(/=item/, ''); + comment.gsub!(/C<(.*?)>/, '\1'); + comment.gsub!(/I<(.*?)>/, '\1'); + comment.gsub!(/B<(.*?)>/, '\1'); + comment + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/ruby.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/ruby.rb new file mode 100755 index 00000000..84e292d4 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/ruby.rb @@ -0,0 +1,2904 @@ +## +# This file contains stuff stolen outright from: +# +# rtags.rb - +# ruby-lex.rb - ruby lexcal analyzer +# ruby-token.rb - ruby tokens +# by Keiju ISHITSUKA (Nippon Rational Inc.) +# + +require 'e2mmap' +require 'irb/slex' + +require 'rdoc/code_objects' +require 'rdoc/tokenstream' +require 'rdoc/markup/preprocess' +require 'rdoc/parser' + +$TOKEN_DEBUG ||= nil +#$TOKEN_DEBUG = $DEBUG_RDOC + +## +# Definitions of all tokens involved in the lexical analysis + +module RDoc::RubyToken + + EXPR_BEG = :EXPR_BEG + EXPR_MID = :EXPR_MID + EXPR_END = :EXPR_END + EXPR_ARG = :EXPR_ARG + EXPR_FNAME = :EXPR_FNAME + EXPR_DOT = :EXPR_DOT + EXPR_CLASS = :EXPR_CLASS + + class Token + NO_TEXT = "??".freeze + + attr_accessor :text + attr_reader :line_no + attr_reader :char_no + + def initialize(line_no, char_no) + @line_no = line_no + @char_no = char_no + @text = NO_TEXT + end + + def ==(other) + self.class == other.class and + other.line_no == @line_no and + other.char_no == @char_no and + other.text == @text + end + + ## + # Because we're used in contexts that expect to return a token, we set the + # text string and then return ourselves + + def set_text(text) + @text = text + self + end + + end + + class TkNode < Token + attr :node + end + + class TkId < Token + def initialize(line_no, char_no, name) + super(line_no, char_no) + @name = name + end + attr :name + end + + class TkKW < TkId + end + + class TkVal < Token + def initialize(line_no, char_no, value = nil) + super(line_no, char_no) + set_text(value) + end + end + + class TkOp < Token + def name + self.class.op_name + end + end + + class TkOPASGN < TkOp + def initialize(line_no, char_no, op) + super(line_no, char_no) + op = TkReading2Token[op] unless Symbol === op + @op = op + end + attr :op + end + + class TkUnknownChar < Token + def initialize(line_no, char_no, id) + super(line_no, char_no) + @name = char_no.chr + end + attr :name + end + + class TkError < Token + end + + def set_token_position(line, char) + @prev_line_no = line + @prev_char_no = char + end + + def Token(token, value = nil) + tk = nil + case token + when String, Symbol + source = String === token ? TkReading2Token : TkSymbol2Token + raise TkReading2TokenNoKey, token if (tk = source[token]).nil? + tk = Token(tk[0], value) + else + tk = if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty? + token.new(@prev_line_no, @prev_char_no) + else + token.new(@prev_line_no, @prev_char_no, value) + end + end + tk + end + + TokenDefinitions = [ + [:TkCLASS, TkKW, "class", EXPR_CLASS], + [:TkMODULE, TkKW, "module", EXPR_CLASS], + [:TkDEF, TkKW, "def", EXPR_FNAME], + [:TkUNDEF, TkKW, "undef", EXPR_FNAME], + [:TkBEGIN, TkKW, "begin", EXPR_BEG], + [:TkRESCUE, TkKW, "rescue", EXPR_MID], + [:TkENSURE, TkKW, "ensure", EXPR_BEG], + [:TkEND, TkKW, "end", EXPR_END], + [:TkIF, TkKW, "if", EXPR_BEG, :TkIF_MOD], + [:TkUNLESS, TkKW, "unless", EXPR_BEG, :TkUNLESS_MOD], + [:TkTHEN, TkKW, "then", EXPR_BEG], + [:TkELSIF, TkKW, "elsif", EXPR_BEG], + [:TkELSE, TkKW, "else", EXPR_BEG], + [:TkCASE, TkKW, "case", EXPR_BEG], + [:TkWHEN, TkKW, "when", EXPR_BEG], + [:TkWHILE, TkKW, "while", EXPR_BEG, :TkWHILE_MOD], + [:TkUNTIL, TkKW, "until", EXPR_BEG, :TkUNTIL_MOD], + [:TkFOR, TkKW, "for", EXPR_BEG], + [:TkBREAK, TkKW, "break", EXPR_END], + [:TkNEXT, TkKW, "next", EXPR_END], + [:TkREDO, TkKW, "redo", EXPR_END], + [:TkRETRY, TkKW, "retry", EXPR_END], + [:TkIN, TkKW, "in", EXPR_BEG], + [:TkDO, TkKW, "do", EXPR_BEG], + [:TkRETURN, TkKW, "return", EXPR_MID], + [:TkYIELD, TkKW, "yield", EXPR_END], + [:TkSUPER, TkKW, "super", EXPR_END], + [:TkSELF, TkKW, "self", EXPR_END], + [:TkNIL, TkKW, "nil", EXPR_END], + [:TkTRUE, TkKW, "true", EXPR_END], + [:TkFALSE, TkKW, "false", EXPR_END], + [:TkAND, TkKW, "and", EXPR_BEG], + [:TkOR, TkKW, "or", EXPR_BEG], + [:TkNOT, TkKW, "not", EXPR_BEG], + [:TkIF_MOD, TkKW], + [:TkUNLESS_MOD, TkKW], + [:TkWHILE_MOD, TkKW], + [:TkUNTIL_MOD, TkKW], + [:TkALIAS, TkKW, "alias", EXPR_FNAME], + [:TkDEFINED, TkKW, "defined?", EXPR_END], + [:TklBEGIN, TkKW, "BEGIN", EXPR_END], + [:TklEND, TkKW, "END", EXPR_END], + [:Tk__LINE__, TkKW, "__LINE__", EXPR_END], + [:Tk__FILE__, TkKW, "__FILE__", EXPR_END], + + [:TkIDENTIFIER, TkId], + [:TkFID, TkId], + [:TkGVAR, TkId], + [:TkIVAR, TkId], + [:TkCONSTANT, TkId], + + [:TkINTEGER, TkVal], + [:TkFLOAT, TkVal], + [:TkSTRING, TkVal], + [:TkXSTRING, TkVal], + [:TkREGEXP, TkVal], + [:TkCOMMENT, TkVal], + + [:TkDSTRING, TkNode], + [:TkDXSTRING, TkNode], + [:TkDREGEXP, TkNode], + [:TkNTH_REF, TkId], + [:TkBACK_REF, TkId], + + [:TkUPLUS, TkOp, "+@"], + [:TkUMINUS, TkOp, "-@"], + [:TkPOW, TkOp, "**"], + [:TkCMP, TkOp, "<=>"], + [:TkEQ, TkOp, "=="], + [:TkEQQ, TkOp, "==="], + [:TkNEQ, TkOp, "!="], + [:TkGEQ, TkOp, ">="], + [:TkLEQ, TkOp, "<="], + [:TkANDOP, TkOp, "&&"], + [:TkOROP, TkOp, "||"], + [:TkMATCH, TkOp, "=~"], + [:TkNMATCH, TkOp, "!~"], + [:TkDOT2, TkOp, ".."], + [:TkDOT3, TkOp, "..."], + [:TkAREF, TkOp, "[]"], + [:TkASET, TkOp, "[]="], + [:TkLSHFT, TkOp, "<<"], + [:TkRSHFT, TkOp, ">>"], + [:TkCOLON2, TkOp], + [:TkCOLON3, TkOp], +# [:OPASGN, TkOp], # +=, -= etc. # + [:TkASSOC, TkOp, "=>"], + [:TkQUESTION, TkOp, "?"], #? + [:TkCOLON, TkOp, ":"], #: + + [:TkfLPAREN], # func( # + [:TkfLBRACK], # func[ # + [:TkfLBRACE], # func{ # + [:TkSTAR], # *arg + [:TkAMPER], # &arg # + [:TkSYMBOL, TkId], # :SYMBOL + [:TkSYMBEG, TkId], + [:TkGT, TkOp, ">"], + [:TkLT, TkOp, "<"], + [:TkPLUS, TkOp, "+"], + [:TkMINUS, TkOp, "-"], + [:TkMULT, TkOp, "*"], + [:TkDIV, TkOp, "/"], + [:TkMOD, TkOp, "%"], + [:TkBITOR, TkOp, "|"], + [:TkBITXOR, TkOp, "^"], + [:TkBITAND, TkOp, "&"], + [:TkBITNOT, TkOp, "~"], + [:TkNOTOP, TkOp, "!"], + + [:TkBACKQUOTE, TkOp, "`"], + + [:TkASSIGN, Token, "="], + [:TkDOT, Token, "."], + [:TkLPAREN, Token, "("], #(exp) + [:TkLBRACK, Token, "["], #[arry] + [:TkLBRACE, Token, "{"], #{hash} + [:TkRPAREN, Token, ")"], + [:TkRBRACK, Token, "]"], + [:TkRBRACE, Token, "}"], + [:TkCOMMA, Token, ","], + [:TkSEMICOLON, Token, ";"], + + [:TkRD_COMMENT], + [:TkSPACE], + [:TkNL], + [:TkEND_OF_SCRIPT], + + [:TkBACKSLASH, TkUnknownChar, "\\"], + [:TkAT, TkUnknownChar, "@"], + [:TkDOLLAR, TkUnknownChar, "\$"], #" + ] + + # {reading => token_class} + # {reading => [token_class, *opt]} + TkReading2Token = {} + TkSymbol2Token = {} + + def self.def_token(token_n, super_token = Token, reading = nil, *opts) + token_n = token_n.id2name unless String === token_n + + fail AlreadyDefinedToken, token_n if const_defined?(token_n) + + token_c = Class.new super_token + const_set token_n, token_c +# token_c.inspect + + if reading + if TkReading2Token[reading] + fail TkReading2TokenDuplicateError, token_n, reading + end + if opts.empty? + TkReading2Token[reading] = [token_c] + else + TkReading2Token[reading] = [token_c].concat(opts) + end + end + TkSymbol2Token[token_n.intern] = token_c + + if token_c <= TkOp + token_c.class_eval %{ + def self.op_name; "#{reading}"; end + } + end + end + + for defs in TokenDefinitions + def_token(*defs) + end + + NEWLINE_TOKEN = TkNL.new(0,0) + NEWLINE_TOKEN.set_text("\n") + +end + +## +# Lexical analyzer for Ruby source + +class RDoc::RubyLex + + ## + # Read an input stream character by character. We allow for unlimited + # ungetting of characters just read. + # + # We simplify the implementation greatly by reading the entire input + # into a buffer initially, and then simply traversing it using + # pointers. + # + # We also have to allow for the here document diversion. This + # little gem comes about when the lexer encounters a here + # document. At this point we effectively need to split the input + # stream into two parts: one to read the body of the here document, + # the other to read the rest of the input line where the here + # document was initially encountered. For example, we might have + # + # do_something(<<-A, <<-B) + # stuff + # for + # A + # stuff + # for + # B + # + # When the lexer encounters the <= @size + ch = @content[@offset, 1] + + @offset += 1 + @hwm = @offset if @hwm < @offset + + if @newline_pending + @line_num += 1 + @last_newline = @offset - 1 + @newline_pending = false + end + + if ch == "\n" + @newline_pending = true + end + ch + end + + def getc_already_read + getc + end + + def ungetc(ch) + raise "unget past beginning of file" if @offset <= 0 + @offset -= 1 + if @content[@offset] == ?\n + @newline_pending = false + end + end + + def get_read + res = @content[@read_back_offset...@offset] + @read_back_offset = @offset + res + end + + def peek(at) + pos = @offset + at + if pos >= @size + nil + else + @content[pos, 1] + end + end + + def peek_equal(str) + @content[@offset, str.length] == str + end + + def divert_read_from(reserve) + @content[@offset, 0] = reserve + @size = @content.size + end + end + + # end of nested class BufferedReader + + extend Exception2MessageMapper + def_exception(:AlreadyDefinedToken, "Already defined token(%s)") + def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')") + def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')") + def_exception(:TkReading2TokenDuplicateError, + "key duplicate(token_n='%s', key='%s')") + def_exception(:SyntaxError, "%s") + + include RDoc::RubyToken + include IRB + + attr_reader :continue + attr_reader :lex_state + + def self.debug? + false + end + + def initialize(content, options) + lex_init + + @options = options + + @reader = BufferedReader.new content, @options + + @exp_line_no = @line_no = 1 + @base_char_no = 0 + @indent = 0 + + @ltype = nil + @quoted = nil + @lex_state = EXPR_BEG + @space_seen = false + + @continue = false + @line = "" + + @skip_space = false + @read_auto_clean_up = false + @exception_on_syntax_error = true + end + + attr_accessor :skip_space + attr_accessor :read_auto_clean_up + attr_accessor :exception_on_syntax_error + attr_reader :indent + + # io functions + def line_no + @reader.line_num + end + + def char_no + @reader.column + end + + def get_read + @reader.get_read + end + + def getc + @reader.getc + end + + def getc_of_rests + @reader.getc_already_read + end + + def gets + c = getc or return + l = "" + begin + l.concat c unless c == "\r" + break if c == "\n" + end while c = getc + l + end + + + def ungetc(c = nil) + @reader.ungetc(c) + end + + def peek_equal?(str) + @reader.peek_equal(str) + end + + def peek(i = 0) + @reader.peek(i) + end + + def lex + until (TkNL === (tk = token) or TkEND_OF_SCRIPT === tk) and + not @continue or tk.nil? + end + + line = get_read + + if line == "" and TkEND_OF_SCRIPT === tk or tk.nil? then + nil + else + line + end + end + + def token + set_token_position(line_no, char_no) + begin + begin + tk = @OP.match(self) + @space_seen = TkSPACE === tk + rescue SyntaxError => e + raise RDoc::Error, "syntax error: #{e.message}" if + @exception_on_syntax_error + + tk = TkError.new(line_no, char_no) + end + end while @skip_space and TkSPACE === tk + if @read_auto_clean_up + get_read + end +# throw :eof unless tk + tk + end + + ENINDENT_CLAUSE = [ + "case", "class", "def", "do", "for", "if", + "module", "unless", "until", "while", "begin" #, "when" + ] + DEINDENT_CLAUSE = ["end" #, "when" + ] + + PERCENT_LTYPE = { + "q" => "\'", + "Q" => "\"", + "x" => "\`", + "r" => "/", + "w" => "]" + } + + PERCENT_PAREN = { + "{" => "}", + "[" => "]", + "<" => ">", + "(" => ")" + } + + Ltype2Token = { + "\'" => TkSTRING, + "\"" => TkSTRING, + "\`" => TkXSTRING, + "/" => TkREGEXP, + "]" => TkDSTRING + } + Ltype2Token.default = TkSTRING + + DLtype2Token = { + "\"" => TkDSTRING, + "\`" => TkDXSTRING, + "/" => TkDREGEXP, + } + + def lex_init() + @OP = IRB::SLex.new + @OP.def_rules("\0", "\004", "\032") do |chars, io| + Token(TkEND_OF_SCRIPT).set_text(chars) + end + + @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |chars, io| + @space_seen = TRUE + while (ch = getc) =~ /[ \t\f\r\13]/ + chars << ch + end + ungetc + Token(TkSPACE).set_text(chars) + end + + @OP.def_rule("#") do + |op, io| + identify_comment + end + + @OP.def_rule("=begin", proc{@prev_char_no == 0 && peek(0) =~ /\s/}) do + |op, io| + str = op + @ltype = "=" + + + begin + line = "" + begin + ch = getc + line << ch + end until ch == "\n" + str << line + end until line =~ /^=end/ + + ungetc + + @ltype = nil + + if str =~ /\A=begin\s+rdoc/i + str.sub!(/\A=begin.*\n/, '') + str.sub!(/^=end.*/m, '') + Token(TkCOMMENT).set_text(str) + else + Token(TkRD_COMMENT)#.set_text(str) + end + end + + @OP.def_rule("\n") do + print "\\n\n" if RDoc::RubyLex.debug? + case @lex_state + when EXPR_BEG, EXPR_FNAME, EXPR_DOT + @continue = TRUE + else + @continue = FALSE + @lex_state = EXPR_BEG + end + Token(TkNL).set_text("\n") + end + + @OP.def_rules("*", "**", + "!", "!=", "!~", + "=", "==", "===", + "=~", "<=>", + "<", "<=", + ">", ">=", ">>") do + |op, io| + @lex_state = EXPR_BEG + Token(op).set_text(op) + end + + @OP.def_rules("<<") do + |op, io| + tk = nil + if @lex_state != EXPR_END && @lex_state != EXPR_CLASS && + (@lex_state != EXPR_ARG || @space_seen) + c = peek(0) + if /[-\w_\"\'\`]/ =~ c + tk = identify_here_document + end + end + if !tk + @lex_state = EXPR_BEG + tk = Token(op).set_text(op) + end + tk + end + + @OP.def_rules("'", '"') do + |op, io| + identify_string(op) + end + + @OP.def_rules("`") do + |op, io| + if @lex_state == EXPR_FNAME + Token(op).set_text(op) + else + identify_string(op) + end + end + + @OP.def_rules('?') do + |op, io| + if @lex_state == EXPR_END + @lex_state = EXPR_BEG + Token(TkQUESTION).set_text(op) + else + ch = getc + if @lex_state == EXPR_ARG && ch !~ /\s/ + ungetc + @lex_state = EXPR_BEG + Token(TkQUESTION).set_text(op) + else + str = op + str << ch + if (ch == '\\') #' + str << read_escape + end + @lex_state = EXPR_END + Token(TkINTEGER).set_text(str) + end + end + end + + @OP.def_rules("&", "&&", "|", "||") do + |op, io| + @lex_state = EXPR_BEG + Token(op).set_text(op) + end + + @OP.def_rules("+=", "-=", "*=", "**=", + "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do + |op, io| + @lex_state = EXPR_BEG + op =~ /^(.*)=$/ + Token(TkOPASGN, $1).set_text(op) + end + + @OP.def_rule("+@", proc{@lex_state == EXPR_FNAME}) do |op, io| + Token(TkUPLUS).set_text(op) + end + + @OP.def_rule("-@", proc{@lex_state == EXPR_FNAME}) do |op, io| + Token(TkUMINUS).set_text(op) + end + + @OP.def_rules("+", "-") do + |op, io| + catch(:RET) do + if @lex_state == EXPR_ARG + if @space_seen and peek(0) =~ /[0-9]/ + throw :RET, identify_number(op) + else + @lex_state = EXPR_BEG + end + elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/ + throw :RET, identify_number(op) + else + @lex_state = EXPR_BEG + end + Token(op).set_text(op) + end + end + + @OP.def_rule(".") do + @lex_state = EXPR_BEG + if peek(0) =~ /[0-9]/ + ungetc + identify_number("") + else + # for obj.if + @lex_state = EXPR_DOT + Token(TkDOT).set_text(".") + end + end + + @OP.def_rules("..", "...") do + |op, io| + @lex_state = EXPR_BEG + Token(op).set_text(op) + end + + lex_int2 + end + + def lex_int2 + @OP.def_rules("]", "}", ")") do + |op, io| + @lex_state = EXPR_END + @indent -= 1 + Token(op).set_text(op) + end + + @OP.def_rule(":") do + if @lex_state == EXPR_END || peek(0) =~ /\s/ + @lex_state = EXPR_BEG + tk = Token(TkCOLON) + else + @lex_state = EXPR_FNAME + tk = Token(TkSYMBEG) + end + tk.set_text(":") + end + + @OP.def_rule("::") do + if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen + @lex_state = EXPR_BEG + tk = Token(TkCOLON3) + else + @lex_state = EXPR_DOT + tk = Token(TkCOLON2) + end + tk.set_text("::") + end + + @OP.def_rule("/") do + |op, io| + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + identify_string(op) + elsif peek(0) == '=' + getc + @lex_state = EXPR_BEG + Token(TkOPASGN, :/).set_text("/=") #") + elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ + identify_string(op) + else + @lex_state = EXPR_BEG + Token("/").set_text(op) + end + end + + @OP.def_rules("^") do + @lex_state = EXPR_BEG + Token("^").set_text("^") + end + + @OP.def_rules(",", ";") do + |op, io| + @lex_state = EXPR_BEG + Token(op).set_text(op) + end + + @OP.def_rule("~") do + @lex_state = EXPR_BEG + Token("~").set_text("~") + end + + @OP.def_rule("~@", proc{@lex_state = EXPR_FNAME}) do + @lex_state = EXPR_BEG + Token("~").set_text("~@") + end + + @OP.def_rule("(") do + @indent += 1 + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + @lex_state = EXPR_BEG + tk = Token(TkfLPAREN) + else + @lex_state = EXPR_BEG + tk = Token(TkLPAREN) + end + tk.set_text("(") + end + + @OP.def_rule("[]", proc{@lex_state == EXPR_FNAME}) do + Token("[]").set_text("[]") + end + + @OP.def_rule("[]=", proc{@lex_state == EXPR_FNAME}) do + Token("[]=").set_text("[]=") + end + + @OP.def_rule("[") do + @indent += 1 + if @lex_state == EXPR_FNAME + t = Token(TkfLBRACK) + else + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + t = Token(TkLBRACK) + elsif @lex_state == EXPR_ARG && @space_seen + t = Token(TkLBRACK) + else + t = Token(TkfLBRACK) + end + @lex_state = EXPR_BEG + end + t.set_text("[") + end + + @OP.def_rule("{") do + @indent += 1 + if @lex_state != EXPR_END && @lex_state != EXPR_ARG + t = Token(TkLBRACE) + else + t = Token(TkfLBRACE) + end + @lex_state = EXPR_BEG + t.set_text("{") + end + + @OP.def_rule('\\') do #' + if getc == "\n" + @space_seen = true + @continue = true + Token(TkSPACE).set_text("\\\n") + else + ungetc + Token("\\").set_text("\\") #" + end + end + + @OP.def_rule('%') do + |op, io| + if @lex_state == EXPR_BEG || @lex_state == EXPR_MID + identify_quotation('%') + elsif peek(0) == '=' + getc + Token(TkOPASGN, "%").set_text("%=") + elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ + identify_quotation('%') + else + @lex_state = EXPR_BEG + Token("%").set_text("%") + end + end + + @OP.def_rule('$') do #' + identify_gvar + end + + @OP.def_rule('@') do + if peek(0) =~ /[@\w_]/ + ungetc + identify_identifier + else + Token("@").set_text("@") + end + end + + @OP.def_rule("__END__", proc{@prev_char_no == 0 && peek(0) =~ /[\r\n]/}) do + throw :eof + end + + @OP.def_rule("") do + |op, io| + printf "MATCH: start %s: %s\n", op, io.inspect if RDoc::RubyLex.debug? + if peek(0) =~ /[0-9]/ + t = identify_number("") + elsif peek(0) =~ /[\w_]/ + t = identify_identifier + end + printf "MATCH: end %s: %s\n", op, io.inspect if RDoc::RubyLex.debug? + t + end + end + + def identify_gvar + @lex_state = EXPR_END + str = "$" + + tk = case ch = getc + when /[~_*$?!@\/\\;,=:<>".]/ #" + str << ch + Token(TkGVAR, str) + + when "-" + str << "-" << getc + Token(TkGVAR, str) + + when "&", "`", "'", "+" + str << ch + Token(TkBACK_REF, str) + + when /[1-9]/ + str << ch + while (ch = getc) =~ /[0-9]/ + str << ch + end + ungetc + Token(TkNTH_REF) + when /\w/ + ungetc + ungetc + return identify_identifier + else + ungetc + Token("$") + end + tk.set_text(str) + end + + def identify_identifier + token = "" + token.concat getc if peek(0) =~ /[$@]/ + token.concat getc if peek(0) == "@" + + while (ch = getc) =~ /\w|_/ + print ":", ch, ":" if RDoc::RubyLex.debug? + token.concat ch + end + ungetc + + if ch == "!" or ch == "?" + token.concat getc + end + # fix token + + # $stderr.puts "identifier - #{token}, state = #@lex_state" + + case token + when /^\$/ + return Token(TkGVAR, token).set_text(token) + when /^\@/ + @lex_state = EXPR_END + return Token(TkIVAR, token).set_text(token) + end + + if @lex_state != EXPR_DOT + print token, "\n" if RDoc::RubyLex.debug? + + token_c, *trans = TkReading2Token[token] + if token_c + # reserved word? + + if (@lex_state != EXPR_BEG && + @lex_state != EXPR_FNAME && + trans[1]) + # modifiers + token_c = TkSymbol2Token[trans[1]] + @lex_state = trans[0] + else + if @lex_state != EXPR_FNAME + if ENINDENT_CLAUSE.include?(token) + @indent += 1 + elsif DEINDENT_CLAUSE.include?(token) + @indent -= 1 + end + @lex_state = trans[0] + else + @lex_state = EXPR_END + end + end + return Token(token_c, token).set_text(token) + end + end + + if @lex_state == EXPR_FNAME + @lex_state = EXPR_END + if peek(0) == '=' + token.concat getc + end + elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT + @lex_state = EXPR_ARG + else + @lex_state = EXPR_END + end + + if token[0, 1] =~ /[A-Z]/ + return Token(TkCONSTANT, token).set_text(token) + elsif token[token.size - 1, 1] =~ /[!?]/ + return Token(TkFID, token).set_text(token) + else + return Token(TkIDENTIFIER, token).set_text(token) + end + end + + def identify_here_document + ch = getc + if ch == "-" + ch = getc + indent = true + end + if /['"`]/ =~ ch # ' + lt = ch + quoted = "" + while (c = getc) && c != lt + quoted.concat c + end + else + lt = '"' + quoted = ch.dup + while (c = getc) && c =~ /\w/ + quoted.concat c + end + ungetc + end + + ltback, @ltype = @ltype, lt + reserve = "" + + while ch = getc + reserve << ch + if ch == "\\" #" + ch = getc + reserve << ch + elsif ch == "\n" + break + end + end + + str = "" + while (l = gets) + l.chomp! + l.strip! if indent + break if l == quoted + str << l.chomp << "\n" + end + + @reader.divert_read_from(reserve) + + @ltype = ltback + @lex_state = EXPR_END + Token(Ltype2Token[lt], str).set_text(str.dump) + end + + def identify_quotation(initial_char) + ch = getc + if lt = PERCENT_LTYPE[ch] + initial_char += ch + ch = getc + elsif ch =~ /\W/ + lt = "\"" + else + fail SyntaxError, "unknown type of %string ('#{ch}')" + end +# if ch !~ /\W/ +# ungetc +# next +# end + #@ltype = lt + @quoted = ch unless @quoted = PERCENT_PAREN[ch] + identify_string(lt, @quoted, ch, initial_char) + end + + def identify_number(start) + str = start.dup + + if start == "+" or start == "-" or start == "" + start = getc + str << start + end + + @lex_state = EXPR_END + + if start == "0" + if peek(0) == "x" + ch = getc + str << ch + match = /[0-9a-f_]/ + else + match = /[0-7_]/ + end + while ch = getc + if ch !~ match + ungetc + break + else + str << ch + end + end + return Token(TkINTEGER).set_text(str) + end + + type = TkINTEGER + allow_point = TRUE + allow_e = TRUE + while ch = getc + case ch + when /[0-9_]/ + str << ch + + when allow_point && "." + type = TkFLOAT + if peek(0) !~ /[0-9]/ + ungetc + break + end + str << ch + allow_point = false + + when allow_e && "e", allow_e && "E" + str << ch + type = TkFLOAT + if peek(0) =~ /[+-]/ + str << getc + end + allow_e = false + allow_point = false + else + ungetc + break + end + end + Token(type).set_text(str) + end + + def identify_string(ltype, quoted = ltype, opener=nil, initial_char = nil) + @ltype = ltype + @quoted = quoted + subtype = nil + + str = "" + str << initial_char if initial_char + str << (opener||quoted) + + nest = 0 + begin + while ch = getc + str << ch + if @quoted == ch + if nest == 0 + break + else + nest -= 1 + end + elsif opener == ch + nest += 1 + elsif @ltype != "'" && @ltype != "]" and ch == "#" + ch = getc + if ch == "{" + subtype = true + str << ch << skip_inner_expression + else + ungetc(ch) + end + elsif ch == '\\' #' + str << read_escape + end + end + if @ltype == "/" + if peek(0) =~ /i|o|n|e|s/ + str << getc + end + end + if subtype + Token(DLtype2Token[ltype], str) + else + Token(Ltype2Token[ltype], str) + end.set_text(str) + ensure + @ltype = nil + @quoted = nil + @lex_state = EXPR_END + end + end + + def skip_inner_expression + res = "" + nest = 0 + while (ch = getc) + res << ch + if ch == '}' + break if nest.zero? + nest -= 1 + elsif ch == '{' + nest += 1 + end + end + res + end + + def identify_comment + @ltype = "#" + comment = "#" + while ch = getc + if ch == "\\" + ch = getc + if ch == "\n" + ch = " " + else + comment << "\\" + end + else + if ch == "\n" + @ltype = nil + ungetc + break + end + end + comment << ch + end + return Token(TkCOMMENT).set_text(comment) + end + + def read_escape + res = "" + case ch = getc + when /[0-7]/ + ungetc ch + 3.times do + case ch = getc + when /[0-7]/ + when nil + break + else + ungetc + break + end + res << ch + end + + when "x" + res << ch + 2.times do + case ch = getc + when /[0-9a-fA-F]/ + when nil + break + else + ungetc + break + end + res << ch + end + + when "M" + res << ch + if (ch = getc) != '-' + ungetc + else + res << ch + if (ch = getc) == "\\" #" + res << ch + res << read_escape + else + res << ch + end + end + + when "C", "c" #, "^" + res << ch + if ch == "C" and (ch = getc) != "-" + ungetc + else + res << ch + if (ch = getc) == "\\" #" + res << ch + res << read_escape + else + res << ch + end + end + else + res << ch + end + res + end +end + +## +# Extracts code elements from a source file returning a TopLevel object +# containing the constituent file elements. +# +# This file is based on rtags +# +# RubyParser understands how to document: +# * classes +# * modules +# * methods +# * constants +# * aliases +# * private, public, protected +# * private_class_function, public_class_function +# * module_function +# * attr, attr_reader, attr_writer, attr_accessor +# * extra accessors given on the command line +# * metaprogrammed methods +# * require +# * include +# +# == Method Arguments +# +#-- +# NOTE: I don't think this works, needs tests, remove the paragraph following +# this block when known to work +# +# The parser extracts the arguments from the method definition. You can +# override this with a custom argument definition using the :args: directive: +# +# ## +# # This method tries over and over until it is tired +# +# def go_go_go(thing_to_try, tries = 10) # :args: thing_to_try +# puts thing_to_try +# go_go_go thing_to_try, tries - 1 +# end +# +# If you have a more-complex set of overrides you can use the :call-seq: +# directive: +#++ +# +# The parser extracts the arguments from the method definition. You can +# override this with a custom argument definition using the :call-seq: +# directive: +# +# ## +# # This method can be called with a range or an offset and length +# # +# # :call-seq: +# # my_method(Range) +# # my_method(offset, length) +# +# def my_method(*args) +# end +# +# The parser extracts +yield+ expressions from method bodies to gather the +# yielded argument names. If your method manually calls a block instead of +# yielding or you want to override the discovered argument names use +# the :yields: directive: +# +# ## +# # My method is awesome +# +# def my_method(&block) # :yields: happy, times +# block.call 1, 2 +# end +# +# == Metaprogrammed Methods +# +# To pick up a metaprogrammed method, the parser looks for a comment starting +# with '##' before an identifier: +# +# ## +# # This is a meta-programmed method! +# +# add_my_method :meta_method, :arg1, :arg2 +# +# The parser looks at the token after the identifier to determine the name, in +# this example, :meta_method. If a name cannot be found, a warning is printed +# and 'unknown is used. +# +# You can force the name of a method using the :method: directive: +# +# ## +# # :method: woo_hoo! +# +# By default, meta-methods are instance methods. To indicate that a method is +# a singleton method instead use the :singleton-method: directive: +# +# ## +# # :singleton-method: +# +# You can also use the :singleton-method: directive with a name: +# +# ## +# # :singleton-method: woo_hoo! +# +# Additionally you can mark a method as an attribute by +# using :attr:, :attr_reader:, :attr_writer: or :attr_accessor:. Just like +# for :method:, the name is optional. +# +# ## +# # :attr_reader: my_attr_name +# +# == Hidden methods and attributes +# +# You can provide documentation for methods that don't appear using +# the :method:, :singleton-method: and :attr: directives: +# +# ## +# # :attr_writer: ghost_writer +# # There is an attribute here, but you can't see it! +# +# ## +# # :method: ghost_method +# # There is a method here, but you can't see it! +# +# ## +# # this is a comment for a regular method +# +# def regular_method() end +# +# Note that by default, the :method: directive will be ignored if there is a +# standard rdocable item following it. + +class RDoc::Parser::Ruby < RDoc::Parser + + parse_files_matching(/\.rbw?$/) + + include RDoc::RubyToken + include RDoc::TokenStream + + NORMAL = "::" + SINGLE = "<<" + + def initialize(top_level, file_name, content, options, stats) + super + + @size = 0 + @token_listeners = nil + @scanner = RDoc::RubyLex.new content, @options + @scanner.exception_on_syntax_error = false + + reset + end + + def add_token_listener(obj) + @token_listeners ||= [] + @token_listeners << obj + end + + ## + # Look for the first comment in a file that isn't a shebang line. + + def collect_first_comment + skip_tkspace + res = '' + first_line = true + + tk = get_tk + + while TkCOMMENT === tk + if first_line and tk.text =~ /\A#!/ then + skip_tkspace + tk = get_tk + elsif first_line and tk.text =~ /\A#\s*-\*-/ then + first_line = false + skip_tkspace + tk = get_tk + else + first_line = false + res << tk.text << "\n" + tk = get_tk + + if TkNL === tk then + skip_tkspace false + tk = get_tk + end + end + end + + unget_tk tk + + res + end + + def error(msg) + msg = make_message msg + $stderr.puts msg + exit(1) + end + + ## + # Look for a 'call-seq' in the comment, and override the normal parameter + # stuff + + def extract_call_seq(comment, meth) + if comment.sub!(/:?call-seq:(.*?)^\s*\#?\s*$/m, '') then + seq = $1 + seq.gsub!(/^\s*\#\s*/, '') + meth.call_seq = seq + end + + meth + end + + def get_bool + skip_tkspace + tk = get_tk + case tk + when TkTRUE + true + when TkFALSE, TkNIL + false + else + unget_tk tk + true + end + end + + ## + # Look for the name of a class of module (optionally with a leading :: or + # with :: separated named) and return the ultimate name and container + + def get_class_or_module(container) + skip_tkspace + name_t = get_tk + + # class ::A -> A is in the top level + if TkCOLON2 === name_t then + name_t = get_tk + container = @top_level + end + + skip_tkspace(false) + + while TkCOLON2 === peek_tk do + prev_container = container + container = container.find_module_named(name_t.name) + if !container +# warn("Couldn't find module #{name_t.name}") + container = prev_container.add_module RDoc::NormalModule, name_t.name + end + get_tk + name_t = get_tk + end + skip_tkspace(false) + return [container, name_t] + end + + ## + # Return a superclass, which can be either a constant of an expression + + def get_class_specification + tk = get_tk + return "self" if TkSELF === tk + + res = "" + while TkCOLON2 === tk or TkCOLON3 === tk or TkCONSTANT === tk do + res += tk.text + tk = get_tk + end + + unget_tk(tk) + skip_tkspace(false) + + get_tkread # empty out read buffer + + tk = get_tk + + case tk + when TkNL, TkCOMMENT, TkSEMICOLON then + unget_tk(tk) + return res + end + + res += parse_call_parameters(tk) + res + end + + ## + # Parse a constant, which might be qualified by one or more class or module + # names + + def get_constant + res = "" + skip_tkspace(false) + tk = get_tk + + while TkCOLON2 === tk or TkCOLON3 === tk or TkCONSTANT === tk do + res += tk.text + tk = get_tk + end + +# if res.empty? +# warn("Unexpected token #{tk} in constant") +# end + unget_tk(tk) + res + end + + ## + # Get a constant that may be surrounded by parens + + def get_constant_with_optional_parens + skip_tkspace(false) + nest = 0 + while TkLPAREN === (tk = peek_tk) or TkfLPAREN === tk do + get_tk + skip_tkspace(true) + nest += 1 + end + + name = get_constant + + while nest > 0 + skip_tkspace(true) + tk = get_tk + nest -= 1 if TkRPAREN === tk + end + name + end + + def get_symbol_or_name + tk = get_tk + case tk + when TkSYMBOL + tk.text.sub(/^:/, '') + when TkId, TkOp + tk.name + when TkSTRING + tk.text + else + raise "Name or symbol expected (got #{tk})" + end + end + + def get_tk + tk = nil + if @tokens.empty? + tk = @scanner.token + @read.push @scanner.get_read + puts "get_tk1 => #{tk.inspect}" if $TOKEN_DEBUG + else + @read.push @unget_read.shift + tk = @tokens.shift + puts "get_tk2 => #{tk.inspect}" if $TOKEN_DEBUG + end + + if TkSYMBEG === tk then + set_token_position(tk.line_no, tk.char_no) + tk1 = get_tk + if TkId === tk1 or TkOp === tk1 or TkSTRING === tk1 or TkDSTRING === tk1 then + if tk1.respond_to?(:name) + tk = Token(TkSYMBOL).set_text(":" + tk1.name) + else + tk = Token(TkSYMBOL).set_text(":" + tk1.text) + end + # remove the identifier we just read (we're about to + # replace it with a symbol) + @token_listeners.each do |obj| + obj.pop_token + end if @token_listeners + else + warn("':' not followed by identifier or operator") + tk = tk1 + end + end + + # inform any listeners of our shiny new token + @token_listeners.each do |obj| + obj.add_token(tk) + end if @token_listeners + + tk + end + + def get_tkread + read = @read.join("") + @read = [] + read + end + + ## + # Look for directives in a normal comment block: + # + # #-- - don't display comment from this point forward + # + # This routine modifies it's parameter + + def look_for_directives_in(context, comment) + preprocess = RDoc::Markup::PreProcess.new(@file_name, + @options.rdoc_include) + + preprocess.handle(comment) do |directive, param| + case directive + when 'enddoc' then + throw :enddoc + when 'main' then + @options.main_page = param + '' + when 'method', 'singleton-method' then + false # ignore + when 'section' then + context.set_current_section(param, comment) + comment.replace '' + break + when 'startdoc' then + context.start_doc + context.force_documentation = true + '' + when 'stopdoc' then + context.stop_doc + '' + when 'title' then + @options.title = param + '' + else + warn "Unrecognized directive '#{directive}'" + false + end + end + + remove_private_comments(comment) + end + + def make_message(msg) + prefix = "\n" + @file_name + ":" + if @scanner + prefix << "#{@scanner.line_no}:#{@scanner.char_no}: " + end + return prefix + msg + end + + ## + # Creates an RDoc::Attr for the name following +tk+, setting the comment to + # +comment+. + + def parse_attr(context, single, tk, comment) + args = parse_symbol_arg 1 + if args.size > 0 + name = args[0] + rw = "R" + skip_tkspace(false) + tk = get_tk + if TkCOMMA === tk then + rw = "RW" if get_bool + else + unget_tk tk + end + att = RDoc::Attr.new get_tkread, name, rw, comment + read_documentation_modifiers att, RDoc::ATTR_MODIFIERS + if att.document_self + context.add_attribute(att) + end + else + warn("'attr' ignored - looks like a variable") + end + end + + ## + # Creates an RDoc::Attr for each attribute listed after +tk+, setting the + # comment for each to +comment+. + + def parse_attr_accessor(context, single, tk, comment) + args = parse_symbol_arg + read = get_tkread + rw = "?" + + # TODO If nodoc is given, don't document any of them + + tmp = RDoc::CodeObject.new + read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS + return unless tmp.document_self + + case tk.name + when "attr_reader" then rw = "R" + when "attr_writer" then rw = "W" + when "attr_accessor" then rw = "RW" + else + rw = '?' + end + + for name in args + att = RDoc::Attr.new get_tkread, name, rw, comment + context.add_attribute att + end + end + + def parse_alias(context, single, tk, comment) + skip_tkspace + if TkLPAREN === peek_tk then + get_tk + skip_tkspace + end + new_name = get_symbol_or_name + @scanner.instance_eval{@lex_state = EXPR_FNAME} + skip_tkspace + if TkCOMMA === peek_tk then + get_tk + skip_tkspace + end + old_name = get_symbol_or_name + + al = RDoc::Alias.new get_tkread, old_name, new_name, comment + read_documentation_modifiers al, RDoc::ATTR_MODIFIERS + if al.document_self + context.add_alias(al) + end + end + + def parse_call_parameters(tk) + end_token = case tk + when TkLPAREN, TkfLPAREN + TkRPAREN + when TkRPAREN + return "" + else + TkNL + end + nest = 0 + + loop do + case tk + when TkSEMICOLON + break + when TkLPAREN, TkfLPAREN + nest += 1 + when end_token + if end_token == TkRPAREN + nest -= 1 + break if @scanner.lex_state == EXPR_END and nest <= 0 + else + break unless @scanner.continue + end + when TkCOMMENT + unget_tk(tk) + break + end + tk = get_tk + end + res = get_tkread.tr("\n", " ").strip + res = "" if res == ";" + res + end + + def parse_class(container, single, tk, comment) + container, name_t = get_class_or_module container + + case name_t + when TkCONSTANT + name = name_t.name + superclass = "Object" + + if TkLT === peek_tk then + get_tk + skip_tkspace(true) + superclass = get_class_specification + superclass = "" if superclass.empty? + end + + cls_type = single == SINGLE ? RDoc::SingleClass : RDoc::NormalClass + cls = container.add_class cls_type, name, superclass + + @stats.add_class cls + + read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS + cls.record_location @top_level + + parse_statements cls + cls.comment = comment + + when TkLSHFT + case name = get_class_specification + when "self", container.name + parse_statements(container, SINGLE) + else + other = RDoc::TopLevel.find_class_named(name) + unless other +# other = @top_level.add_class(NormalClass, name, nil) +# other.record_location(@top_level) +# other.comment = comment + other = RDoc::NormalClass.new "Dummy", nil + end + + @stats.add_class other + + read_documentation_modifiers other, RDoc::CLASS_MODIFIERS + parse_statements(other, SINGLE) + end + + else + warn("Expected class name or '<<'. Got #{name_t.class}: #{name_t.text.inspect}") + end + end + + def parse_constant(container, single, tk, comment) + name = tk.name + skip_tkspace(false) + eq_tk = get_tk + + unless TkASSIGN === eq_tk then + unget_tk(eq_tk) + return + end + + nest = 0 + get_tkread + + tk = get_tk + if TkGT === tk then + unget_tk(tk) + unget_tk(eq_tk) + return + end + + loop do + case tk + when TkSEMICOLON then + break + when TkLPAREN, TkfLPAREN, TkLBRACE, TkLBRACK, TkDO, TkIF, TkUNLESS, + TkCASE then + nest += 1 + when TkRPAREN, TkRBRACE, TkRBRACK, TkEND then + nest -= 1 + when TkCOMMENT then + if nest <= 0 && @scanner.lex_state == EXPR_END + unget_tk tk + break + end + when TkNL then + if nest <= 0 && + (@scanner.lex_state == EXPR_END || !@scanner.continue) then + unget_tk tk + break + end + end + tk = get_tk + end + + res = get_tkread.tr("\n", " ").strip + res = "" if res == ";" + + con = RDoc::Constant.new name, res, comment + read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS + + container.add_constant con if con.document_self + end + + ## + # Generates an RDoc::Method or RDoc::Attr from +comment+ by looking for + # :method: or :attr: directives in +comment+. + + def parse_comment(container, tk, comment) + line_no = tk.line_no + column = tk.char_no + + singleton = !!comment.sub!(/(^# +:?)(singleton-)(method:)/, '\1\3') + + # REFACTOR + if comment.sub!(/^# +:?method: *(\S*).*?\n/i, '') then + name = $1 unless $1.empty? + + meth = RDoc::GhostMethod.new get_tkread, name + meth.singleton = singleton + + @stats.add_method meth + + meth.start_collecting_tokens + indent = TkSPACE.new 1, 1 + indent.set_text " " * column + + position_comment = TkCOMMENT.new(line_no, 1, "# File #{@top_level.absolute_name}, line #{line_no}") + meth.add_tokens [position_comment, NEWLINE_TOKEN, indent] + + meth.params = '' + + extract_call_seq comment, meth + + container.add_method meth if meth.document_self + + meth.comment = comment + elsif comment.sub!(/# +:?(attr(_reader|_writer|_accessor)?:) *(\S*).*?\n/i, '') then + rw = case $1 + when 'attr_reader' then 'R' + when 'attr_writer' then 'W' + else 'RW' + end + + name = $3 unless $3.empty? + + att = RDoc::Attr.new get_tkread, name, rw, comment + container.add_attribute att + end + end + + def parse_include(context, comment) + loop do + skip_tkspace_comment + + name = get_constant_with_optional_parens + context.add_include RDoc::Include.new(name, comment) unless name.empty? + + return unless TkCOMMA === peek_tk + get_tk + end + end + + def parse_meta_attr(context, single, tk, comment) + args = parse_symbol_arg + read = get_tkread + rw = "?" + + # If nodoc is given, don't document any of them + + tmp = RDoc::CodeObject.new + read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS + return unless tmp.document_self + + if comment.sub!(/^# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '') then + rw = case $1 + when 'attr_reader' then 'R' + when 'attr_writer' then 'W' + else 'RW' + end + name = $3 unless $3.empty? + end + + for name in args + att = RDoc::Attr.new get_tkread, name, rw, comment + context.add_attribute att + end + end + + ## + # Parses a meta-programmed method + + def parse_meta_method(container, single, tk, comment) + line_no = tk.line_no + column = tk.char_no + + start_collecting_tokens + add_token tk + add_token_listener self + + skip_tkspace false + + singleton = !!comment.sub!(/(^# +:?)(singleton-)(method:)/, '\1\3') + + if comment.sub!(/^# +:?method: *(\S*).*?\n/i, '') then + name = $1 unless $1.empty? + end + + if name.nil? then + name_t = get_tk + case name_t + when TkSYMBOL then + name = name_t.text[1..-1] + when TkSTRING then + name = name_t.text[1..-2] + when TkASSIGN then # ignore + remove_token_listener self + return + else + warn "unknown name token #{name_t.inspect} for meta-method '#{tk.name}'" + name = 'unknown' + end + end + + meth = RDoc::MetaMethod.new get_tkread, name + meth.singleton = singleton + + @stats.add_method meth + + remove_token_listener self + + meth.start_collecting_tokens + indent = TkSPACE.new 1, 1 + indent.set_text " " * column + + position_comment = TkCOMMENT.new(line_no, 1, "# File #{@top_level.absolute_name}, line #{line_no}") + meth.add_tokens [position_comment, NEWLINE_TOKEN, indent] + meth.add_tokens @token_stream + + add_token_listener meth + + meth.params = '' + + extract_call_seq comment, meth + + container.add_method meth if meth.document_self + + last_tk = tk + + while tk = get_tk do + case tk + when TkSEMICOLON then + break + when TkNL then + break unless last_tk and TkCOMMA === last_tk + when TkSPACE then + # expression continues + else + last_tk = tk + end + end + + remove_token_listener meth + + meth.comment = comment + end + + ## + # Parses a method + + def parse_method(container, single, tk, comment) + line_no = tk.line_no + column = tk.char_no + + start_collecting_tokens + add_token(tk) + add_token_listener(self) + + @scanner.instance_eval do @lex_state = EXPR_FNAME end + + skip_tkspace(false) + name_t = get_tk + back_tk = skip_tkspace + meth = nil + added_container = false + + dot = get_tk + if TkDOT === dot or TkCOLON2 === dot then + @scanner.instance_eval do @lex_state = EXPR_FNAME end + skip_tkspace + name_t2 = get_tk + + case name_t + when TkSELF then + name = name_t2.name + when TkCONSTANT then + name = name_t2.name + prev_container = container + container = container.find_module_named(name_t.name) + unless container then + added_container = true + obj = name_t.name.split("::").inject(Object) do |state, item| + state.const_get(item) + end rescue nil + + type = obj.class == Class ? RDoc::NormalClass : RDoc::NormalModule + + unless [Class, Module].include?(obj.class) then + warn("Couldn't find #{name_t.name}. Assuming it's a module") + end + + if type == RDoc::NormalClass then + container = prev_container.add_class(type, name_t.name, obj.superclass.name) + else + container = prev_container.add_module(type, name_t.name) + end + + container.record_location @top_level + end + else + warn "unexpected method name token #{name_t2.inspect}" + # break + skip_method(container) + return + end + + meth = RDoc::AnyMethod.new(get_tkread, name) + meth.singleton = true + else + unget_tk dot + back_tk.reverse_each do |token| + unget_tk token + end + + unless name_t.respond_to? :name then + warn "unexpected method name token #{name_t.inspect}" + skip_method container + return + end + + name = name_t.name + + meth = RDoc::AnyMethod.new get_tkread, name + meth.singleton = (single == SINGLE) + end + + @stats.add_method meth + + remove_token_listener self + + meth.start_collecting_tokens + indent = TkSPACE.new 1, 1 + indent.set_text " " * column + + token = TkCOMMENT.new(line_no, 1, "# File #{@top_level.absolute_name}, line #{line_no}") + meth.add_tokens [token, NEWLINE_TOKEN, indent] + meth.add_tokens @token_stream + + add_token_listener meth + + @scanner.instance_eval do @continue = false end + parse_method_parameters meth + + if meth.document_self then + container.add_method meth + elsif added_container then + container.document_self = false + end + + # Having now read the method parameters and documentation modifiers, we + # now know whether we have to rename #initialize to ::new + + if name == "initialize" && !meth.singleton then + if meth.dont_rename_initialize then + meth.visibility = :protected + else + meth.singleton = true + meth.name = "new" + meth.visibility = :public + end + end + + parse_statements(container, single, meth) + + remove_token_listener(meth) + + extract_call_seq comment, meth + + meth.comment = comment + end + + def parse_method_or_yield_parameters(method = nil, + modifiers = RDoc::METHOD_MODIFIERS) + skip_tkspace(false) + tk = get_tk + + # Little hack going on here. In the statement + # f = 2*(1+yield) + # We see the RPAREN as the next token, so we need + # to exit early. This still won't catch all cases + # (such as "a = yield + 1" + end_token = case tk + when TkLPAREN, TkfLPAREN + TkRPAREN + when TkRPAREN + return "" + else + TkNL + end + nest = 0 + + loop do + case tk + when TkSEMICOLON then + break + when TkLBRACE then + nest += 1 + when TkRBRACE then + # we might have a.each {|i| yield i } + unget_tk(tk) if nest.zero? + nest -= 1 + break if nest <= 0 + when TkLPAREN, TkfLPAREN then + nest += 1 + when end_token then + if end_token == TkRPAREN + nest -= 1 + break if @scanner.lex_state == EXPR_END and nest <= 0 + else + break unless @scanner.continue + end + when method && method.block_params.nil? && TkCOMMENT then + unget_tk tk + read_documentation_modifiers method, modifiers + @read.pop + when TkCOMMENT then + @read.pop + end + tk = get_tk + end + + res = get_tkread.gsub(/\s+/, ' ').strip + res = '' if res == ';' + res + end + + ## + # Capture the method's parameters. Along the way, look for a comment + # containing: + # + # # yields: .... + # + # and add this as the block_params for the method + + def parse_method_parameters(method) + res = parse_method_or_yield_parameters method + + res = "(#{res})" unless res =~ /\A\(/ + method.params = res unless method.params + + if method.block_params.nil? then + skip_tkspace(false) + read_documentation_modifiers method, RDoc::METHOD_MODIFIERS + end + end + + def parse_module(container, single, tk, comment) + container, name_t = get_class_or_module(container) + + name = name_t.name + + mod = container.add_module RDoc::NormalModule, name + mod.record_location @top_level + + @stats.add_module mod + + read_documentation_modifiers mod, RDoc::CLASS_MODIFIERS + parse_statements(mod) + mod.comment = comment + end + + def parse_require(context, comment) + skip_tkspace_comment + tk = get_tk + if TkLPAREN === tk then + skip_tkspace_comment + tk = get_tk + end + + name = nil + case tk + when TkSTRING + name = tk.text + # when TkCONSTANT, TkIDENTIFIER, TkIVAR, TkGVAR + # name = tk.name + when TkDSTRING + warn "Skipping require of dynamic string: #{tk.text}" + # else + # warn "'require' used as variable" + end + if name + context.add_require RDoc::Require.new(name, comment) + else + unget_tk(tk) + end + end + + def parse_statements(container, single = NORMAL, current_method = nil, + comment = '') + nest = 1 + save_visibility = container.visibility + + non_comment_seen = true + + while tk = get_tk do + keep_comment = false + + non_comment_seen = true unless TkCOMMENT === tk + + case tk + when TkNL then + skip_tkspace true # Skip blanks and newlines + tk = get_tk + + if TkCOMMENT === tk then + if non_comment_seen then + # Look for RDoc in a comment about to be thrown away + parse_comment container, tk, comment unless comment.empty? + + comment = '' + non_comment_seen = false + end + + while TkCOMMENT === tk do + comment << tk.text << "\n" + tk = get_tk # this is the newline + skip_tkspace(false) # leading spaces + tk = get_tk + end + + unless comment.empty? then + look_for_directives_in container, comment + + if container.done_documenting then + container.ongoing_visibility = save_visibility + end + end + + keep_comment = true + else + non_comment_seen = true + end + + unget_tk tk + keep_comment = true + + when TkCLASS then + if container.document_children then + parse_class container, single, tk, comment + else + nest += 1 + end + + when TkMODULE then + if container.document_children then + parse_module container, single, tk, comment + else + nest += 1 + end + + when TkDEF then + if container.document_self then + parse_method container, single, tk, comment + else + nest += 1 + end + + when TkCONSTANT then + if container.document_self then + parse_constant container, single, tk, comment + end + + when TkALIAS then + if container.document_self then + parse_alias container, single, tk, comment + end + + when TkYIELD then + if current_method.nil? then + warn "Warning: yield outside of method" if container.document_self + else + parse_yield container, single, tk, current_method + end + + # Until and While can have a 'do', which shouldn't increase the nesting. + # We can't solve the general case, but we can handle most occurrences by + # ignoring a do at the end of a line. + + when TkUNTIL, TkWHILE then + nest += 1 + skip_optional_do_after_expression + + # 'for' is trickier + when TkFOR then + nest += 1 + skip_for_variable + skip_optional_do_after_expression + + when TkCASE, TkDO, TkIF, TkUNLESS, TkBEGIN then + nest += 1 + + when TkIDENTIFIER then + if nest == 1 and current_method.nil? then + case tk.name + when 'private', 'protected', 'public', 'private_class_method', + 'public_class_method', 'module_function' then + parse_visibility container, single, tk + keep_comment = true + when 'attr' then + parse_attr container, single, tk, comment + when /^attr_(reader|writer|accessor)$/ then + parse_attr_accessor container, single, tk, comment + when 'alias_method' then + if container.document_self then + parse_alias container, single, tk, comment + end + else + if container.document_self and comment =~ /\A#\#$/ then + parse_meta_method container, single, tk, comment + end + end + end + + case tk.name + when "require" then + parse_require container, comment + when "include" then + parse_include container, comment + end + + when TkEND then + nest -= 1 + if nest == 0 then + read_documentation_modifiers container, RDoc::CLASS_MODIFIERS + container.ongoing_visibility = save_visibility + return + end + + end + + comment = '' unless keep_comment + + begin + get_tkread + skip_tkspace(false) + end while peek_tk == TkNL + end + end + + def parse_symbol_arg(no = nil) + args = [] + skip_tkspace_comment + case tk = get_tk + when TkLPAREN + loop do + skip_tkspace_comment + if tk1 = parse_symbol_in_arg + args.push tk1 + break if no and args.size >= no + end + + skip_tkspace_comment + case tk2 = get_tk + when TkRPAREN + break + when TkCOMMA + else + warn("unexpected token: '#{tk2.inspect}'") if $DEBUG_RDOC + break + end + end + else + unget_tk tk + if tk = parse_symbol_in_arg + args.push tk + return args if no and args.size >= no + end + + loop do + skip_tkspace(false) + + tk1 = get_tk + unless TkCOMMA === tk1 then + unget_tk tk1 + break + end + + skip_tkspace_comment + if tk = parse_symbol_in_arg + args.push tk + break if no and args.size >= no + end + end + end + args + end + + def parse_symbol_in_arg + case tk = get_tk + when TkSYMBOL + tk.text.sub(/^:/, '') + when TkSTRING + eval @read[-1] + else + warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG_RDOC + nil + end + end + + def parse_top_level_statements(container) + comment = collect_first_comment + look_for_directives_in(container, comment) + container.comment = comment unless comment.empty? + parse_statements container, NORMAL, nil, comment + end + + def parse_visibility(container, single, tk) + singleton = (single == SINGLE) + + vis_type = tk.name + + vis = case vis_type + when 'private' then :private + when 'protected' then :protected + when 'public' then :public + when 'private_class_method' then + singleton = true + :private + when 'public_class_method' then + singleton = true + :public + when 'module_function' then + singleton = true + :public + else + raise "Invalid visibility: #{tk.name}" + end + + skip_tkspace_comment false + + case peek_tk + # Ryan Davis suggested the extension to ignore modifiers, because he + # often writes + # + # protected unless $TESTING + # + when TkNL, TkUNLESS_MOD, TkIF_MOD, TkSEMICOLON then + container.ongoing_visibility = vis + else + if vis_type == 'module_function' then + args = parse_symbol_arg + container.set_visibility_for args, :private, false + + module_functions = [] + + container.methods_matching args do |m| + s_m = m.dup + s_m.singleton = true if RDoc::AnyMethod === s_m + s_m.visibility = :public + module_functions << s_m + end + + module_functions.each do |s_m| + case s_m + when RDoc::AnyMethod then + container.add_method s_m + when RDoc::Attr then + container.add_attribute s_m + end + end + else + args = parse_symbol_arg + container.set_visibility_for args, vis, singleton + end + end + end + + def parse_yield_parameters + parse_method_or_yield_parameters + end + + def parse_yield(context, single, tk, method) + if method.block_params.nil? + get_tkread + @scanner.instance_eval{@continue = false} + method.block_params = parse_yield_parameters + end + end + + def peek_read + @read.join('') + end + + ## + # Peek at the next token, but don't remove it from the stream + + def peek_tk + unget_tk(tk = get_tk) + tk + end + + ## + # Directives are modifier comments that can appear after class, module, or + # method names. For example: + # + # def fred # :yields: a, b + # + # or: + # + # class MyClass # :nodoc: + # + # We return the directive name and any parameters as a two element array + + def read_directive(allowed) + tk = get_tk + result = nil + + if TkCOMMENT === tk then + if tk.text =~ /\s*:?(\w+):\s*(.*)/ then + directive = $1.downcase + if allowed.include? directive then + result = [directive, $2] + end + end + else + unget_tk tk + end + + result + end + + def read_documentation_modifiers(context, allow) + dir = read_directive(allow) + + case dir[0] + when "notnew", "not_new", "not-new" then + context.dont_rename_initialize = true + + when "nodoc" then + context.document_self = false + if dir[1].downcase == "all" + context.document_children = false + end + + when "doc" then + context.document_self = true + context.force_documentation = true + + when "yield", "yields" then + unless context.params.nil? + context.params.sub!(/(,|)\s*&\w+/,'') # remove parameter &proc + end + + context.block_params = dir[1] + + when "arg", "args" then + context.params = dir[1] + end if dir + end + + def remove_private_comments(comment) + comment.gsub!(/^#--\n.*?^#\+\+/m, '') + comment.sub!(/^#--\n.*/m, '') + end + + def remove_token_listener(obj) + @token_listeners.delete(obj) + end + + def reset + @tokens = [] + @unget_read = [] + @read = [] + end + + def scan + reset + + catch(:eof) do + catch(:enddoc) do + begin + parse_top_level_statements(@top_level) + rescue Exception => e + $stderr.puts <<-EOF + + +RDoc failure in #{@file_name} at or around line #{@scanner.line_no} column +#{@scanner.char_no} + +Before reporting this, could you check that the file you're documenting +compiles cleanly--RDoc is not a full Ruby parser, and gets confused easily if +fed invalid programs. + +The internal error was: + + EOF + + e.set_backtrace(e.backtrace[0,4]) + raise + end + end + end + + @top_level + end + + ## + # while, until, and for have an optional do + + def skip_optional_do_after_expression + skip_tkspace(false) + tk = get_tk + case tk + when TkLPAREN, TkfLPAREN + end_token = TkRPAREN + else + end_token = TkNL + end + + nest = 0 + @scanner.instance_eval{@continue = false} + + loop do + case tk + when TkSEMICOLON + break + when TkLPAREN, TkfLPAREN + nest += 1 + when TkDO + break if nest.zero? + when end_token + if end_token == TkRPAREN + nest -= 1 + break if @scanner.lex_state == EXPR_END and nest.zero? + else + break unless @scanner.continue + end + end + tk = get_tk + end + skip_tkspace(false) + + get_tk if TkDO === peek_tk + end + + ## + # skip the var [in] part of a 'for' statement + + def skip_for_variable + skip_tkspace(false) + tk = get_tk + skip_tkspace(false) + tk = get_tk + unget_tk(tk) unless TkIN === tk + end + + def skip_method(container) + meth = RDoc::AnyMethod.new "", "anon" + parse_method_parameters(meth) + parse_statements(container, false, meth) + end + + ## + # Skip spaces + + def skip_tkspace(skip_nl = true) + tokens = [] + + while TkSPACE === (tk = get_tk) or (skip_nl and TkNL === tk) do + tokens.push tk + end + + unget_tk(tk) + tokens + end + + ## + # Skip spaces until a comment is found + + def skip_tkspace_comment(skip_nl = true) + loop do + skip_tkspace(skip_nl) + return unless TkCOMMENT === peek_tk + get_tk + end + end + + def unget_tk(tk) + @tokens.unshift tk + @unget_read.unshift @read.pop + + # Remove this token from any listeners + @token_listeners.each do |obj| + obj.pop_token + end if @token_listeners + end + + def warn(msg) + return if @options.quiet + msg = make_message msg + $stderr.puts msg + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/simple.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/simple.rb new file mode 100755 index 00000000..e34ce70e --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/parser/simple.rb @@ -0,0 +1,39 @@ +require 'rdoc/parser' + +## +# Parse a non-source file. We basically take the whole thing as one big +# comment. If the first character in the file is '#', we strip leading pound +# signs. + +class RDoc::Parser::Simple < RDoc::Parser + + parse_files_matching(//) + + ## + # Prepare to parse a plain file + + def initialize(top_level, file_name, content, options, stats) + super + + preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include + + preprocess.handle @content do |directive, param| + warn "Unrecognized directive '#{directive}' in #{@file_name}" + end + end + + ## + # Extract the file contents and attach them to the TopLevel as a comment + + def scan + @top_level.comment = remove_private_comments(@content) + @top_level.parser = self.class + @top_level + end + + def remove_private_comments(comment) + comment.gsub(/^--\n.*?^\+\+/m, '').sub(/^--\n.*/m, '') + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/rdoc.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/rdoc.rb new file mode 100755 index 00000000..b854988a --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/rdoc.rb @@ -0,0 +1,375 @@ +require 'rdoc' + +require 'rdoc/parser' + +# Simple must come first +require 'rdoc/parser/simple' +require 'rdoc/parser/ruby' +require 'rdoc/parser/c' +require 'rdoc/parser/perl' + +require 'rdoc/stats' +require 'rdoc/options' + +require 'rdoc/diagram' + +require 'find' +require 'fileutils' +require 'time' +require 'thread' + +## +# Encapsulate the production of rdoc documentation. Basically you can use this +# as you would invoke rdoc from the command line: +# +# rdoc = RDoc::RDoc.new +# rdoc.document(args) +# +# Where +args+ is an array of strings, each corresponding to an argument you'd +# give rdoc on the command line. See rdoc/rdoc.rb for details. + +class RDoc::RDoc + + ## + # Generator instance used for creating output + + attr_accessor :generator + + ## + # RDoc options + + attr_reader :options + + ## + # Accessor for statistics. Available after each call to parse_files + + attr_reader :stats + + ## + # This is the list of supported output generators + + GENERATORS = {} + + ## + # Add +klass+ that can generate output after parsing + + def self.add_generator(klass) + name = klass.name.sub(/^RDoc::Generator::/, '').downcase + GENERATORS[name] = klass + end + + ## + # Active RDoc::RDoc instance + + def self.current + @current + end + + ## + # Sets the active RDoc::RDoc instance + + def self.current=(rdoc) + @current = rdoc + end + + def initialize + @generator = nil + @options = nil + @stats = nil + end + + ## + # Report an error message and exit + + def error(msg) + raise RDoc::Error, msg + end + + ## + # Turns RDoc from stdin into HTML + + def handle_pipe + @html = RDoc::Markup::ToHtml.new + + out = @html.convert $stdin.read + + $stdout.write out + end + + ## + # Create an output dir if it doesn't exist. If it does exist, but doesn't + # contain the flag file created.rid then we refuse to use it, as + # we may clobber some manually generated documentation + + def setup_output_dir(op_dir, force) + flag_file = output_flag_file op_dir + + if File.exist? op_dir then + unless File.directory? op_dir then + error "'#{op_dir}' exists, and is not a directory" + end + begin + created = File.read(flag_file) + rescue SystemCallError + error "\nDirectory #{op_dir} already exists, but it looks like it\n" + + "isn't an RDoc directory. Because RDoc doesn't want to risk\n" + + "destroying any of your existing files, you'll need to\n" + + "specify a different output directory name (using the\n" + + "--op option).\n\n" + else + last = (Time.parse(created) unless force rescue nil) + end + else + FileUtils.mkdir_p(op_dir) + end + last + end + + ## + # Update the flag file in an output directory. + + def update_output_dir(op_dir, time) + File.open(output_flag_file(op_dir), "w") { |f| f.puts time.rfc2822 } + end + + ## + # Return the path name of the flag file in an output directory. + + def output_flag_file(op_dir) + File.join op_dir, "created.rid" + end + + ## + # The .document file contains a list of file and directory name patterns, + # representing candidates for documentation. It may also contain comments + # (starting with '#') + + def parse_dot_doc_file(in_dir, filename, options) + # read and strip comments + patterns = File.read(filename).gsub(/#.*/, '') + + result = [] + + patterns.split.each do |patt| + candidates = Dir.glob(File.join(in_dir, patt)) + result.concat(normalized_file_list(options, candidates)) + end + + result + end + + ## + # Given a list of files and directories, create a list of all the Ruby + # files they contain. + # + # If +force_doc+ is true we always add the given files, if false, only + # add files that we guarantee we can parse. It is true when looking at + # files given on the command line, false when recursing through + # subdirectories. + # + # The effect of this is that if you want a file with a non-standard + # extension parsed, you must name it explicitly. + + def normalized_file_list(options, relative_files, force_doc = false, + exclude_pattern = nil) + file_list = [] + + relative_files.each do |rel_file_name| + next if exclude_pattern && exclude_pattern =~ rel_file_name + stat = File.stat rel_file_name rescue next + + case type = stat.ftype + when "file" + next if @last_created and stat.mtime < @last_created + + if force_doc or RDoc::Parser.can_parse(rel_file_name) then + file_list << rel_file_name.sub(/^\.\//, '') + end + when "directory" + next if rel_file_name == "CVS" || rel_file_name == ".svn" + dot_doc = File.join(rel_file_name, RDoc::DOT_DOC_FILENAME) + if File.file?(dot_doc) + file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options)) + else + file_list.concat(list_files_in_directory(rel_file_name, options)) + end + else + raise RDoc::Error, "I can't deal with a #{type} #{rel_file_name}" + end + end + + file_list + end + + ## + # Return a list of the files to be processed in a directory. We know that + # this directory doesn't have a .document file, so we're looking for real + # files. However we may well contain subdirectories which must be tested + # for .document files. + + def list_files_in_directory(dir, options) + files = Dir.glob File.join(dir, "*") + + normalized_file_list options, files, false, options.exclude + end + + ## + # Parse each file on the command line, recursively entering directories. + + def parse_files(options) + files = options.files + files = ["."] if files.empty? + + file_list = normalized_file_list(options, files, true, options.exclude) + + return [] if file_list.empty? + + jobs = SizedQueue.new(@options.threads * 3) + workers = [] + file_info = [] + file_info_lock = Mutex.new + + Thread.abort_on_exception = true + @stats = RDoc::Stats.new(file_list.size, options.verbosity) + @stats.begin_adding @options.threads + + # Create worker threads. + @options.threads.times do + thread = Thread.new do + while (filename = jobs.pop) + @stats.add_file(filename) + content = read_file_contents(filename) + top_level = RDoc::TopLevel.new filename + + parser = RDoc::Parser.for(top_level, filename, content, options, + @stats) + result = parser.scan + + file_info_lock.synchronize do + file_info << result + end + end + end + workers << thread + end + + # Feed filenames to the parser worker threads... + file_list.each do |filename| + jobs << filename + end + workers.size.times do + jobs << nil + end + + # ...and wait until they're done. + workers.each do |thread| + thread.join + end + + @stats.done_adding + + file_info + end + + ## + # Format up one or more files according to the given arguments. + # + # For simplicity, _argv_ is an array of strings, equivalent to the strings + # that would be passed on the command line. (This isn't a coincidence, as + # we _do_ pass in ARGV when running interactively). For a list of options, + # see rdoc/rdoc.rb. By default, output will be stored in a directory + # called +doc+ below the current directory, so make sure you're somewhere + # writable before invoking. + # + # Throws: RDoc::Error on error + + def document(argv) + RDoc::TopLevel.reset + + @options = RDoc::Options.new + @options.parse argv + + if @options.pipe then + handle_pipe + exit + end + + @last_created = setup_output_dir @options.op_dir, @options.force_update + + start_time = Time.now + + file_info = parse_files @options + + @options.title = "RDoc Documentation" + + if file_info.empty? + $stderr.puts "\nNo newer files." unless @options.quiet + else + gen_klass = @options.generator + + unless @options.quiet then + $stderr.puts "\nGenerating #{gen_klass.name.sub(/^.*::/, '')}..." + end + + @generator = gen_klass.for @options + + pwd = Dir.pwd + + Dir.chdir @options.op_dir + + begin + self.class.current = self + + RDoc::Diagram.new(file_info, @options).draw if @options.diagram + @generator.generate file_info + update_output_dir ".", start_time + ensure + self.class.current = nil + Dir.chdir pwd + end + end + + unless @options.quiet or not @stats then + puts + @stats.print + end + end + + private + + def read_file_contents(filename) + content = if RUBY_VERSION >= '1.9' then + File.open(filename, "r:ascii-8bit") { |f| f.read } + else + File.read filename + end + + if defined? Encoding then + if /coding:\s*(\S+)/ =~ content[/\A(?:.*\n){0,2}/] + if enc = ::Encoding.find($1) + content.force_encoding(enc) + end + end + end + + content + end + +end + +if Gem.respond_to? :find_files then + rdoc_extensions = Gem.find_files 'rdoc/discover' + + rdoc_extensions.each do |extension| + begin + load extension + rescue => e + warn "error loading #{extension.inspect}: #{e.message} (#{e.class})" + end + end +end + +# require built-in generators after discovery in case they've been replaced +require 'rdoc/generator/darkfish' +require 'rdoc/generator/ri' + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/require.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/require.rb new file mode 100755 index 00000000..407b55af --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/require.rb @@ -0,0 +1,32 @@ +require 'rdoc/code_object' + +## +# A file loaded by \#require + +class RDoc::Require < RDoc::CodeObject + + ## + # Name of the required file + + attr_accessor :name + + ## + # Creates a new Require that loads +name+ with +comment+ + + def initialize(name, comment) + super() + @name = name.gsub(/'|"/, "") #' + self.comment = comment + end + + def inspect # :nodoc: + "#<%s:0x%x require '%s' in %s>" % [ + self.class, + object_id, + @name, + parent_file_name, + ] + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri.rb new file mode 100755 index 00000000..a3a858e6 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri.rb @@ -0,0 +1,8 @@ +require 'rdoc' + +module RDoc::RI + + class Error < RDoc::Error; end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/cache.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/cache.rb new file mode 100755 index 00000000..15935abb --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/cache.rb @@ -0,0 +1,187 @@ +require 'rdoc/ri' + +class RDoc::RI::ClassEntry + + attr_reader :name + attr_reader :path_names + + def initialize(path_name, name, in_class) + @path_names = [ path_name ] + @name = name + @in_class = in_class + @class_methods = [] + @instance_methods = [] + @inferior_classes = [] + end + + # We found this class in more than one place, so add + # in the name from there. + def add_path(path) + @path_names << path + end + + ## + # read in our methods and any classes and modules in our namespace. Methods + # are stored in files called name-c|i.yaml, where the 'name' portion is the + # external form of the method name and the c|i is a class|instance flag + + def load_from(dir) + return unless File.exist? dir + + Dir.foreach(dir) do |name| + next if name =~ /^\./ + + # convert from external to internal form, and + # extract the instance/class flag + + if name =~ /^(.*?)-(c|i).yaml$/ + external_name = $1 + is_class_method = $2 == "c" + internal_name = RDoc::RI::Writer.external_to_internal(external_name) + list = is_class_method ? @class_methods : @instance_methods + path = File.join(dir, name) + list << RDoc::RI::MethodEntry.new(path, internal_name, is_class_method, self) + else + full_name = File.join(dir, name) + if File.directory?(full_name) + inf_class = @inferior_classes.find {|c| c.name == name } + if inf_class + inf_class.add_path(full_name) + else + inf_class = RDoc::RI::ClassEntry.new(full_name, name, self) + @inferior_classes << inf_class + end + inf_class.load_from(full_name) + end + end + end + end + + # Return a list of any classes or modules that we contain + # that match a given string + + def contained_modules_matching(name) + @inferior_classes.find_all {|c| c.name[name]} + end + + def classes_and_modules + @inferior_classes + end + + # Return an exact match to a particular name + def contained_class_named(name) + @inferior_classes.find {|c| c.name == name} + end + + # return the list of local methods matching name + # We're split into two because we need distinct behavior + # when called from the _toplevel_ + def methods_matching(name, is_class_method) + local_methods_matching(name, is_class_method) + end + + # Find methods matching 'name' in ourselves and in + # any classes we contain + def recursively_find_methods_matching(name, is_class_method) + res = local_methods_matching(name, is_class_method) + @inferior_classes.each do |c| + res.concat(c.recursively_find_methods_matching(name, is_class_method)) + end + res + end + + + # Return our full name + def full_name + res = @in_class.full_name + res << "::" unless res.empty? + res << @name + end + + # Return a list of all out method names + def all_method_names + res = @class_methods.map {|m| m.full_name } + @instance_methods.each {|m| res << m.full_name} + res + end + + private + + # Return a list of all our methods matching a given string. + # Is +is_class_methods+ if 'nil', we don't care if the method + # is a class method or not, otherwise we only return + # those methods that match + def local_methods_matching(name, is_class_method) + + list = case is_class_method + when nil then @class_methods + @instance_methods + when true then @class_methods + when false then @instance_methods + else fail "Unknown is_class_method: #{is_class_method.inspect}" + end + + list.find_all {|m| m.name; m.name[name]} + end +end + +## +# A TopLevelEntry is like a class entry, but when asked to search for methods +# searches all classes, not just itself + +class RDoc::RI::TopLevelEntry < RDoc::RI::ClassEntry + def methods_matching(name, is_class_method) + res = recursively_find_methods_matching(name, is_class_method) + end + + def full_name + "" + end + + def module_named(name) + + end + +end + +class RDoc::RI::MethodEntry + attr_reader :name + attr_reader :path_name + + def initialize(path_name, name, is_class_method, in_class) + @path_name = path_name + @name = name + @is_class_method = is_class_method + @in_class = in_class + end + + def full_name + res = @in_class.full_name + unless res.empty? + if @is_class_method + res << "::" + else + res << "#" + end + end + res << @name + end +end + +## +# We represent everything known about all 'ri' files accessible to this program + +class RDoc::RI::Cache + + attr_reader :toplevel + + def initialize(dirs) + # At the top level we have a dummy module holding the + # overall namespace + @toplevel = RDoc::RI::TopLevelEntry.new('', '::', nil) + + dirs.each do |dir| + @toplevel.load_from(dir) + end + end + +end diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/descriptions.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/descriptions.rb new file mode 100755 index 00000000..99a7cb11 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/descriptions.rb @@ -0,0 +1,156 @@ +require 'yaml' +require 'rdoc/markup/fragments' +require 'rdoc/ri' + +## +# Descriptions are created by RDoc (in ri_generator) and written out in +# serialized form into the documentation tree. ri then reads these to generate +# the documentation + +class RDoc::RI::NamedThing + attr_reader :name + def initialize(name) + @name = name + end + + def <=>(other) + @name <=> other.name + end + + def hash + @name.hash + end + + def eql?(other) + @name.eql?(other) + end +end + +class RDoc::RI::AliasName < RDoc::RI::NamedThing; end + +class RDoc::RI::Attribute < RDoc::RI::NamedThing + attr_reader :rw, :comment + + def initialize(name, rw, comment) + super(name) + @rw = rw + @comment = comment + end +end + +class RDoc::RI::Constant < RDoc::RI::NamedThing + attr_reader :value, :comment + + def initialize(name, value, comment) + super(name) + @value = value + @comment = comment + end +end + +class RDoc::RI::IncludedModule < RDoc::RI::NamedThing; end + +class RDoc::RI::MethodSummary < RDoc::RI::NamedThing + def initialize(name="") + super + end +end + +class RDoc::RI::Description + attr_accessor :name + attr_accessor :full_name + attr_accessor :comment + + def serialize + self.to_yaml + end + + def self.deserialize(from) + YAML.load(from) + end + + def <=>(other) + @name <=> other.name + end +end + +class RDoc::RI::ModuleDescription < RDoc::RI::Description + + attr_accessor :class_methods + attr_accessor :class_method_extensions + attr_accessor :instance_methods + attr_accessor :instance_method_extensions + attr_accessor :attributes + attr_accessor :constants + attr_accessor :includes + + # merge in another class description into this one + def merge_in(old) + merge(@class_methods, old.class_methods) + merge(@instance_methods, old.instance_methods) + merge(@attributes, old.attributes) + merge(@constants, old.constants) + merge(@includes, old.includes) + if @comment.nil? || @comment.empty? + @comment = old.comment + else + unless old.comment.nil? or old.comment.empty? then + if @comment.nil? or @comment.empty? then + @comment = old.comment + else + @comment << RDoc::Markup::Flow::RULE.new + @comment.concat old.comment + end + end + end + end + + def display_name + "Module" + end + + # the 'ClassDescription' subclass overrides this + # to format up the name of a parent + def superclass_string + nil + end + + private + + def merge(into, from) + names = {} + into.each {|i| names[i.name] = i } + from.each {|i| names[i.name] = i } + into.replace(names.keys.sort.map {|n| names[n]}) + end +end + +class RDoc::RI::ClassDescription < RDoc::RI::ModuleDescription + attr_accessor :superclass + + def display_name + "Class" + end + + def superclass_string + if @superclass && @superclass != "Object" + @superclass + else + nil + end + end +end + +class RDoc::RI::MethodDescription < RDoc::RI::Description + + attr_accessor :is_class_method + attr_accessor :visibility + attr_accessor :block_params + attr_accessor :is_singleton + attr_accessor :aliases + attr_accessor :is_alias_for + attr_accessor :params + attr_accessor :source_path + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/display.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/display.rb new file mode 100755 index 00000000..17399594 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/display.rb @@ -0,0 +1,340 @@ +require 'rdoc/ri' + +## +# This is a kind of 'flag' module. If you want to write your own 'ri' display +# module (perhaps because you're writing an IDE), you write a class which +# implements the various 'display' methods in RDoc::RI::DefaultDisplay, and +# include the RDoc::RI::Display module in that class. +# +# To access your class from the command line, you can do +# +# ruby -r ../ri .... + +module RDoc::RI::Display + + @@display_class = nil + + def self.append_features(display_class) + @@display_class = display_class + end + + def self.new(*args) + @@display_class.new(*args) + end + +end + +## +# A paging display module. Uses the RDoc::RI::Formatter class to do the actual +# presentation. + +class RDoc::RI::DefaultDisplay + + include RDoc::RI::Display + + attr_reader :formatter + + def initialize(formatter, width, use_stdout, output = $stdout) + @use_stdout = use_stdout + @formatter = formatter.new output, width, " " + end + + ## + # Display information about +klass+. Fetches additional information from + # +ri_reader+ as necessary. + + def display_class_info(klass) + page do + superclass = klass.superclass + + if superclass + superclass = " < " + superclass + else + superclass = "" + end + + @formatter.draw_line(klass.display_name + ": " + + klass.full_name + superclass) + + display_flow(klass.comment) + @formatter.draw_line + + unless klass.includes.empty? + @formatter.blankline + @formatter.display_heading("Includes:", 2, "") + incs = [] + + klass.includes.each do |inc| + incs << inc.name + end + + @formatter.wrap(incs.sort.join(', ')) + end + + unless klass.constants.empty? + @formatter.blankline + @formatter.display_heading("Constants:", 2, "") + + constants = klass.constants.sort_by { |constant| constant.name } + + constants.each do |constant| + @formatter.wrap "#{constant.name} = #{constant.value}" + if constant.comment then + @formatter.indent do + @formatter.display_flow constant.comment + end + else + @formatter.break_to_newline + end + end + end + + unless klass.attributes.empty? then + @formatter.blankline + @formatter.display_heading 'Attributes:', 2, '' + + attributes = klass.attributes.sort_by { |attribute| attribute.name } + + attributes.each do |attribute| + if attribute.comment then + @formatter.wrap "#{attribute.name} (#{attribute.rw}):" + @formatter.indent do + @formatter.display_flow attribute.comment + end + else + @formatter.wrap "#{attribute.name} (#{attribute.rw})" + @formatter.break_to_newline + end + end + end + + return display_class_method_list(klass) + end + end + + ## + # Given a Hash mapping a class' methods to method types (returned by + # display_class_method_list), this method allows the user to choose one of + # the methods. + + def get_class_method_choice(method_map) + end + + ## + # Display methods on +klass+. Returns a hash mapping method name to method + # contents + + def display_class_method_list(klass) + method_map = {} + + class_data = [ + :class_methods, + :class_method_extensions, + :instance_methods, + :instance_method_extensions, + ] + + class_data.each do |data_type| + data = klass.send data_type + + unless data.nil? or data.empty? then + @formatter.blankline + + heading = data_type.to_s.split('_').join(' ').capitalize << ':' + @formatter.display_heading heading, 2, '' + + method_names = [] + data.each do |item| + method_names << item.name + + if(data_type == :class_methods || + data_type == :class_method_extensions) then + method_map["::#{item.name}"] = :class + method_map[item.name] = :class + else + # + # Since we iterate over instance methods after class methods, + # an instance method always will overwrite the unqualified + # class method entry for a class method of the same name. + # + method_map["##{item.name}"] = :instance + method_map[item.name] = :instance + end + end + method_names.sort! + + @formatter.wrap method_names.join(', ') + end + end + + method_map + end + private :display_class_method_list + + ## + # Display an Array of RDoc::Markup::Flow objects, +flow+. + + def display_flow(flow) + if flow and not flow.empty? then + @formatter.display_flow flow + else + @formatter.wrap '[no description]' + end + end + + ## + # Display information about +method+. + + def display_method_info(method) + page do + @formatter.draw_line(method.full_name) + display_params(method) + + @formatter.draw_line + display_flow(method.comment) + + if method.aliases and not method.aliases.empty? then + @formatter.blankline + aka = "(also known as #{method.aliases.map { |a| a.name }.join(', ')})" + @formatter.wrap aka + end + end + end + + ## + # Display the list of +methods+. + + def display_method_list(methods) + page do + @formatter.wrap "More than one method matched your request. You can refine your search by asking for information on one of:" + @formatter.blankline + + methods.each do |method| + @formatter.raw_print_line "#{method.full_name} [#{method.source_path}]\n" + end + end + end + + ## + # Display a list of +methods+ and allow the user to select one of them. + + def display_method_list_choice(methods) + page do + @formatter.wrap "More than one method matched your request. Please choose one of the possible matches." + @formatter.blankline + + methods.each_with_index do |method, index| + @formatter.raw_print_line "%3d %s [%s]\n" % [index + 1, method.full_name, method.source_path] + end + + @formatter.raw_print_line ">> " + + choice = $stdin.gets.strip! + + if(choice == '') + return + end + + choice = choice.to_i + + if ((choice == 0) || (choice > methods.size)) then + @formatter.raw_print_line "Invalid choice!\n" + else + method = methods[choice - 1] + display_method_info(method) + end + end + end + + ## + # Display the params for +method+. + + def display_params(method) + params = method.params + + if params[0,1] == "(" then + if method.is_singleton + params = method.full_name + params + else + params = method.name + params + end + end + + params.split(/\n/).each do |param| + @formatter.wrap param + @formatter.break_to_newline + end + + @formatter.blankline + @formatter.wrap("From #{method.source_path}") + end + + ## + # List the classes in +classes+. + + def list_known_classes(classes) + if classes.empty? then + warn_no_database + else + page do + @formatter.draw_line "Known classes and modules" + @formatter.blankline + + classes.sort.each do |klass| + @formatter.wrap klass + end + end + end + end + + ## + # Paginates output through a pager program. + + def page + if pager = setup_pager then + begin + orig_output = @formatter.output + @formatter.output = pager + yield + ensure + @formatter.output = orig_output + pager.close + end + else + yield + end + rescue Errno::EPIPE + end + + ## + # Sets up a pager program to pass output through. + + def setup_pager + unless @use_stdout then + for pager in [ ENV['PAGER'], "less", "more", 'pager' ].compact.uniq + return IO.popen(pager, "w") rescue nil + end + @use_stdout = true + nil + end + end + + ## + # Displays a message that describes how to build RI data. + + def warn_no_database + output = @formatter.output + + output.puts "No ri data found" + output.puts + output.puts "If you've installed Ruby yourself, you need to generate documentation using:" + output.puts + output.puts " make install-doc" + output.puts + output.puts "from the same place you ran `make` to build ruby." + output.puts + output.puts "If you installed Ruby from a packaging system, then you may need to" + output.puts "install an additional package, or ask the packager to enable ri generation." + end + +end diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/driver.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/driver.rb new file mode 100755 index 00000000..310ff848 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/driver.rb @@ -0,0 +1,828 @@ +require 'abbrev' +require 'optparse' +require 'yaml' + +begin + require 'readline' +rescue LoadError +end + +require 'rdoc/ri' +require 'rdoc/ri/paths' +require 'rdoc/ri/formatter' +require 'rdoc/ri/display' +require 'fileutils' +require 'rdoc/markup' +require 'rdoc/markup/to_flow' + +class RDoc::RI::Driver + + ## + # This class offers both Hash and OpenStruct functionality. We convert from + # the Core Hash to this before calling any of the display methods, in order + # to give the display methods a cleaner API for accessing the data. + + class OpenStructHash < Hash + + ## + # This method converts from a Hash to an OpenStructHash. + + def self.convert(object) + case object + when Hash then + new_hash = new # Convert Hash -> OpenStructHash + + object.each do |key, value| + new_hash[key] = convert value + end + + new_hash + when Array then + object.map do |element| + convert element + end + else + object + end + end + + def merge_enums(other) + other.each do |k, v| + if self[k] then + case v + when Array then + # HACK dunno + if String === self[k] and self[k].empty? then + self[k] = v + else + self[k] += v + end + when Hash then + self[k].update v + else + # do nothing + end + else + self[k] = v + end + end + end + + def method_missing method, *args + self[method.to_s] + end + end + + class Error < RDoc::RI::Error; end + + class NotFoundError < Error + def message + "Nothing known about #{super}" + end + end + + attr_accessor :homepath # :nodoc: + + ## + # Default options for ri + + def self.default_options + options = {} + options[:use_stdout] = !$stdout.tty? + options[:width] = 72 + options[:formatter] = RDoc::RI::Formatter.for 'plain' + options[:interactive] = false + options[:use_cache] = true + + # By default all standard paths are used. + options[:use_system] = true + options[:use_site] = true + options[:use_home] = true + options[:use_gems] = true + options[:extra_doc_dirs] = [] + + return options + end + + ## + # Parses +argv+ and returns a Hash of options + + def self.process_args(argv) + options = default_options + + opts = OptionParser.new do |opt| + opt.program_name = File.basename $0 + opt.version = RDoc::VERSION + opt.release = nil + opt.summary_indent = ' ' * 4 + + directories = [ + RDoc::RI::Paths::SYSDIR, + RDoc::RI::Paths::SITEDIR, + RDoc::RI::Paths::HOMEDIR + ] + + if RDoc::RI::Paths::GEMDIRS then + Gem.path.each do |dir| + directories << "#{dir}/doc/*/ri" + end + end + + opt.banner = <<-EOT +Usage: #{opt.program_name} [options] [names...] + +Where name can be: + + Class | Class::method | Class#method | Class.method | method + +All class names may be abbreviated to their minimum unambiguous form. If a name +is ambiguous, all valid options will be listed. + +The form '.' method matches either class or instance methods, while #method +matches only instance and ::method matches only class methods. + +For example: + + #{opt.program_name} Fil + #{opt.program_name} File + #{opt.program_name} File.new + #{opt.program_name} zip + +Note that shell quoting may be required for method names containing +punctuation: + + #{opt.program_name} 'Array.[]' + #{opt.program_name} compact\\! + +By default ri searches for documentation in the following directories: + + #{directories.join "\n "} + +Specifying the --system, --site, --home, --gems or --doc-dir options will +limit ri to searching only the specified directories. + +Options may also be set in the 'RI' environment variable. + EOT + + opt.separator nil + opt.separator "Options:" + opt.separator nil + + opt.on("--fmt=FORMAT", "--format=FORMAT", "-f", + RDoc::RI::Formatter::FORMATTERS.keys, + "Format to use when displaying output:", + " #{RDoc::RI::Formatter.list}", + "Use 'bs' (backspace) with most pager", + "programs. To use ANSI, either disable the", + "pager or tell the pager to allow control", + "characters.") do |value| + options[:formatter] = RDoc::RI::Formatter.for value + end + + opt.separator nil + + opt.on("--doc-dir=DIRNAME", "-d", Array, + "List of directories from which to source", + "documentation in addition to the standard", + "directories. May be repeated.") do |value| + value.each do |dir| + unless File.directory? dir then + raise OptionParser::InvalidArgument, "#{dir} is not a directory" + end + + options[:extra_doc_dirs] << File.expand_path(dir) + end + end + + opt.separator nil + + opt.on("--[no-]use-cache", + "Whether or not to use ri's cache.", + "True by default.") do |value| + options[:use_cache] = value + end + + opt.separator nil + + opt.on("--no-standard-docs", + "Do not include documentation from", + "the Ruby standard library, site_lib,", + "installed gems, or ~/.rdoc.", + "Equivalent to specifying", + "the options --no-system, --no-site, --no-gems,", + "and --no-home") do + options[:use_system] = false + options[:use_site] = false + options[:use_gems] = false + options[:use_home] = false + end + + opt.separator nil + + opt.on("--[no-]system", + "Include documentation from Ruby's standard", + "library. Defaults to true.") do |value| + options[:use_system] = value + end + + opt.separator nil + + opt.on("--[no-]site", + "Include documentation from libraries", + "installed in site_lib.", + "Defaults to true.") do |value| + options[:use_site] = value + end + + opt.separator nil + + opt.on("--[no-]gems", + "Include documentation from RubyGems.", + "Defaults to true.") do |value| + options[:use_gems] = value + end + + opt.separator nil + + opt.on("--[no-]home", + "Include documentation stored in ~/.rdoc.", + "Defaults to true.") do |value| + options[:use_home] = value + end + + opt.separator nil + + opt.on("--list-doc-dirs", + "List the directories from which ri will", + "source documentation on stdout and exit.") do + options[:list_doc_dirs] = true + end + + opt.separator nil + + opt.on("--no-pager", "-T", + "Send output directly to stdout,", + "rather than to a pager.") do + options[:use_stdout] = true + end + + opt.on("--interactive", "-i", + "This makes ri go into interactive mode.", + "When ri is in interactive mode it will", + "allow the user to disambiguate lists of", + "methods in case multiple methods match", + "against a method search string. It also", + "will allow the user to enter in a method", + "name (with auto-completion, if readline", + "is supported) when viewing a class.") do + options[:interactive] = true + end + + opt.separator nil + + opt.on("--width=WIDTH", "-w", OptionParser::DecimalInteger, + "Set the width of the output.") do |value| + options[:width] = value + end + end + + argv = ENV['RI'].to_s.split.concat argv + + opts.parse! argv + + options[:names] = argv + + options[:formatter] ||= RDoc::RI::Formatter.for('plain') + options[:use_stdout] ||= !$stdout.tty? + options[:use_stdout] ||= options[:interactive] + options[:width] ||= 72 + + options + + rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e + puts opts + puts + puts e + exit 1 + end + + ## + # Runs the ri command line executable using +argv+ + + def self.run(argv = ARGV) + options = process_args argv + ri = new options + ri.run + end + + def initialize(initial_options={}) + options = self.class.default_options.update(initial_options) + + @names = options[:names] + @class_cache_name = 'classes' + + @doc_dirs = RDoc::RI::Paths.path(options[:use_system], + options[:use_site], + options[:use_home], + options[:use_gems], + options[:extra_doc_dirs]) + + @homepath = RDoc::RI::Paths.raw_path(false, false, true, false).first + @homepath = @homepath.sub(/\.rdoc/, '.ri') + @sys_dir = RDoc::RI::Paths.raw_path(true, false, false, false).first + @list_doc_dirs = options[:list_doc_dirs] + + FileUtils.mkdir_p cache_file_path unless File.directory? cache_file_path + @cache_doc_dirs_path = File.join cache_file_path, ".doc_dirs" + + @use_cache = options[:use_cache] + @class_cache = nil + + @interactive = options[:interactive] + @display = RDoc::RI::DefaultDisplay.new(options[:formatter], + options[:width], + options[:use_stdout]) + end + + ## + # Cache of classes ri knows about + + def class_cache + return @class_cache if @class_cache + + # Get the documentation directories used to make the cache in order to see + # whether the cache is valid for the current ri instantiation. + if(File.readable?(@cache_doc_dirs_path)) + cache_doc_dirs = IO.read(@cache_doc_dirs_path).split("\n") + else + cache_doc_dirs = [] + end + + newest = map_dirs('created.rid') do |f| + File.mtime f if test ?f, f + end.max + + # An up to date cache file must have been created more recently than + # the last modification of any of the documentation directories. It also + # must have been created with the same documentation directories + # as those from which ri currently is sourcing documentation. + up_to_date = (File.exist?(class_cache_file_path) and + newest and newest < File.mtime(class_cache_file_path) and + (cache_doc_dirs == @doc_dirs)) + + if up_to_date and @use_cache then + open class_cache_file_path, 'rb' do |fp| + begin + @class_cache = Marshal.load fp.read + rescue + # + # This shouldn't be necessary, since the up_to_date logic above + # should force the cache to be recreated when a new version of + # rdoc is installed. This seems like a worthwhile enhancement + # to ri's robustness, however. + # + $stderr.puts "Error reading the class cache; recreating the class cache!" + @class_cache = create_class_cache + end + end + else + @class_cache = create_class_cache + end + + @class_cache + end + + ## + # Creates the class cache if it is empty + + def create_class_cache + class_cache = OpenStructHash.new + + if(@use_cache) + # Dump the documentation directories to a file in the cache, so that + # we only will use the cache for future instantiations with identical + # documentation directories. + File.open @cache_doc_dirs_path, "wb" do |fp| + fp << @doc_dirs.join("\n") + end + end + + classes = map_dirs('**/cdesc*.yaml') { |f| Dir[f] } + warn "Updating ri class cache with #{classes.size} classes..." + populate_class_cache class_cache, classes + + write_cache class_cache, class_cache_file_path + + class_cache + end + + ## + # Populates +class_cache+ with +classes+, adding +extension+ data for found + # methods when asked + + def populate_class_cache(class_cache, classes, extension = false) + classes.each do |cdesc| + desc = read_yaml cdesc + klassname = desc["full_name"] + + unless class_cache.has_key? klassname then + desc["display_name"] = "Class" + desc["sources"] = [cdesc] + desc["instance_method_extensions"] = [] + desc["class_method_extensions"] = [] + class_cache[klassname] = desc + else + klass = class_cache[klassname] + + if extension then + desc["instance_method_extensions"] = desc.delete "instance_methods" + desc["class_method_extensions"] = desc.delete "class_methods" + end + + klass.merge_enums desc + klass["sources"] << cdesc + end + end + end + + ## + # Path to the class_cache + + def class_cache_file_path + File.join cache_file_path, @class_cache_name + end + + ## + # Path to the cache file for +klassname+ + + def cache_file_for(klassname) + File.join cache_file_path, klassname.gsub(/:+/, "-") + end + + ## + # Directory where cache files live + + def cache_file_path + File.join @homepath, 'cache' + end + + ## + # Displays the module, class or method +name+. For methods, locates the + # method in the ancestors list if it isn't in the named module. + + def display_name(name) + if class_cache.key? name then + method_map = display_class name + elsif name =~ /::|\#|\./ then + method = nil + klass, = parse_name name + + klass = expand_klass klass unless class_cache.key? klass + + orig_klass = klass + orig_name = name + + loop do + method = lookup_method name, klass + + break if method + + ancestor = lookup_ancestor klass, orig_klass + + break unless ancestor + + name = name.sub klass, ancestor + klass = ancestor + end + + raise NotFoundError, orig_name unless method + + display_method method + else + methods = select_methods(/#{name}/) + + if methods.size == 0 + raise NotFoundError, name + elsif methods.size == 1 + display_method methods[0] + else + @display.display_method_list methods + end + end + end + + ## + # Displays info for class or module +name+ + + def display_class(name) + klass = class_cache[name] + @display.display_class_info klass + end + + ## + # Displays info for method +method+ + + def display_method(method) + @display.display_method_info method + end + + ## + # Runs ri interactively using Readline if it is available. + + def interactive + formatter = @display.formatter + + if defined? Readline then + # prepare abbreviations for tab completion + klasses = class_cache.keys + + Readline.completion_proc = proc do |name| + case name + when /(#|\.|::)([^A-Z]|$)/ then + methods = [] + method_type = $1 == '.' ? '#|::' : $1 + + klass, method = if $2.empty? then + [$`, ''] + else + parse_name name + end + + cache = load_cache_for klass + + methods += cache.keys.select do |method_name| + method_name =~ /^#{klass}#{method_type}#{method}/ + end + + # TODO ancestor lookup + + if method_type == '::' and method.empty? then + methods += klasses.grep(/^#{klass}::/) + end + + methods + when /^[A-Z]\w*/ then + klasses.grep(/^#{name}/) + else + [] + end + end + end + + formatter.raw_print_line "\nEnter the method name you want to look up.\n" + + if defined? Readline then + formatter.raw_print_line "You can use tab to autocomplete.\n" + end + + formatter.raw_print_line "Enter a blank line to exit.\n\n" + + loop do + name = if defined? Readline then + Readline.readline ">> " + else + formatter.raw_print_line ">> " + $stdin.gets + end + + return if name.nil? or name.empty? + + name = name.strip + + begin + display_name name + rescue NotFoundError => e + formatter.raw_print_line "#{e.message}\n" + end + end + + rescue Interrupt + exit + end + + ## + # Expands abbreviated klass +klass+ into a fully-qualified klass. "Zl::Da" + # will be expanded to Zlib::DataError. + + def expand_klass(klass) + klass.split('::').inject '' do |expanded, klass_part| + expanded << '::' unless expanded.empty? + short = expanded << klass_part + + subset = class_cache.keys.select do |klass_name| + klass =~ /^#{expanded}[^:]*$/ + end + + abbrevs = Abbrev.abbrev subset + + expanded = abbrevs[short] + + raise NotFoundError, short unless expanded + + expanded.dup + end + end + + ## + # Loads the cache for +klassname+ + + def load_cache_for(klassname) + path = cache_file_for klassname + + cache = nil + + if File.exist? path and + File.mtime(path) >= File.mtime(class_cache_file_path) and + @use_cache then + open path, 'rb' do |fp| + begin + cache = Marshal.load fp.read + rescue + # + # The cache somehow is bad. Recreate the cache. + # + $stderr.puts "Error reading the cache for #{klassname}; recreating the cache!" + cache = create_cache_for klassname, path + end + end + else + cache = create_cache_for klassname, path + end + + cache + end + + ## + # Writes a cache file for +klassname+ to +path+ + + def create_cache_for(klassname, path) + klass = class_cache[klassname] + return nil unless klass + + method_files = klass["sources"] + cache = OpenStructHash.new + + method_files.each do |f| + system_file = f.index(@sys_dir) == 0 + Dir[File.join(File.dirname(f), "*")].each do |yaml| + next unless yaml =~ /yaml$/ + next if yaml =~ /cdesc-[^\/]+yaml$/ + + method = read_yaml yaml + + if system_file then + method["source_path"] = "Ruby #{RDoc::RI::Paths::VERSION}" + else + gem = Gem.path.any? do |gem_path| + pattern = File.join Regexp.escape(gem_path), 'doc', '(.*?)', '' + + f =~ /^#{pattern}/ + end + + method["source_path"] = if gem then + "gem #{$1}" + else + f + end + end + + name = method["full_name"] + cache[name] = method + end + end + + write_cache cache, path + end + + ## + # Finds the next ancestor of +orig_klass+ after +klass+. + + def lookup_ancestor(klass, orig_klass) + # This is a bit hacky, but ri will go into an infinite loop otherwise, + # since Object has an Object ancestor for some reason. Depending on the + # documentation state, I've seen Kernel as an ancestor of Object and not + # as an ancestor of Object. + if orig_klass == "Object" && (klass == "Kernel" || klass == "Object") then + return nil + end + + cache = class_cache[orig_klass] + + return nil unless cache + + ancestors = [orig_klass] + ancestors.push(*cache.includes.map { |inc| inc['name'] }) + ancestors << cache.superclass + + ancestor_index = ancestors.index klass + + if ancestor_index + ancestor = ancestors[ancestors.index(klass) + 1] + return ancestor if ancestor + end + + lookup_ancestor klass, cache.superclass + end + + ## + # Finds the method + + def lookup_method(name, klass) + cache = load_cache_for klass + return nil unless cache + + method = cache[name.gsub('.', '#')] + method = cache[name.gsub('.', '::')] unless method + method + end + + def map_dirs(file_name) + @doc_dirs.map { |dir| yield File.join(dir, file_name) }.flatten.compact + end + + ## + # Extract the class and method name parts from +name+ like Foo::Bar#baz + + def parse_name(name) + parts = name.split(/(::|\#|\.)/) + + if parts[-2] != '::' or parts.last !~ /^[A-Z]/ then + meth = parts.pop + parts.pop + end + + klass = parts.join + + [klass, meth] + end + + ## + # Reads ri YAML data from +path+, converting RDoc 1.x classes to RDoc 2.x + # classes + + def read_yaml(path) + data = File.read path + + # Necessary to be backward-compatible with documentation generated + # by earliar RDoc versions. + data = data.gsub(/ \!ruby\/(object|struct):(RDoc::RI|RI).*/, '') + data = data.gsub(/ \!ruby\/(object|struct):SM::(\S+)/, + ' !ruby/\1:RDoc::Markup::\2') + + OpenStructHash.convert YAML.load(data) + end + + ## + # Looks up and displays ri data according to the options given. + + def run + if @list_doc_dirs then + puts @doc_dirs + elsif @interactive then + interactive + elsif @names.empty? then + @display.list_known_classes class_cache.keys.sort + else + @names.each do |name| + display_name name + end + end + rescue NotFoundError => e + abort e.message + end + + ## + # Selects methods matching +pattern+ from all modules + + def select_methods(pattern) + methods = [] + class_cache.keys.sort.each do |klass| + class_cache[klass]["instance_methods"].map{|h|h["name"]}.grep(pattern) do |name| + method = load_cache_for(klass)[klass+'#'+name] + methods << method if method + end + class_cache[klass]["class_methods"].map{|h|h["name"]}.grep(pattern) do |name| + method = load_cache_for(klass)[klass+'::'+name] + methods << method if method + end + end + methods + end + + ## + # Writes +cache+ to +path+ + + def write_cache(cache, path) + if @use_cache then + File.open path, "wb" do |cache_file| + Marshal.dump cache, cache_file + end + end + + cache + rescue Errno::EISDIR # HACK toplevel, replace with main + cache + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/formatter.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/formatter.rb new file mode 100755 index 00000000..b2c9d07b --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/formatter.rb @@ -0,0 +1,654 @@ +require 'rdoc/ri' +require 'rdoc/markup' + +class RDoc::RI::Formatter + + attr_writer :indent + attr_accessor :output + + FORMATTERS = { } + + def self.for(name) + FORMATTERS[name.downcase] + end + + def self.list + FORMATTERS.keys.sort.join ", " + end + + def initialize(output, width, indent) + @output = output + @width = width + @indent = indent + @original_indent = indent.dup + end + + def draw_line(label=nil) + len = @width + len -= (label.size + 1) if label + + if len > 0 then + @output.print '-' * len + if label + @output.print ' ' + bold_print label + end + + @output.puts + else + @output.print '-' * @width + @output.puts + + @output.puts label + end + end + + def indent + return @indent unless block_given? + + begin + indent = @indent.dup + @indent += @original_indent + yield + ensure + @indent = indent + end + end + + def wrap(txt, prefix=@indent, linelen=@width) + return unless txt && !txt.empty? + + work = conv_markup(txt) + textLen = linelen - prefix.length + patt = Regexp.new("^(.{0,#{textLen}})[ \n]") + next_prefix = prefix.tr("^ ", " ") + + res = [] + + while work.length > textLen + if work =~ patt + res << $1 + work.slice!(0, $&.length) + else + res << work.slice!(0, textLen) + end + end + res << work if work.length.nonzero? + @output.puts(prefix + res.join("\n" + next_prefix)) + end + + def blankline + @output.puts + end + + ## + # Called when we want to ensure a new 'wrap' starts on a newline. Only + # needed for HtmlFormatter, because the rest do their own line breaking. + + def break_to_newline + end + + def bold_print(txt) + @output.print txt + end + + def raw_print_line(txt) + @output.print txt + end + + ## + # Convert HTML entities back to ASCII + + def conv_html(txt) + txt = txt.gsub(/>/, '>') + txt.gsub!(/</, '<') + txt.gsub!(/"/, '"') + txt.gsub!(/&/, '&') + txt + end + + ## + # Convert markup into display form + + def conv_markup(txt) + txt = txt.gsub(%r{(.*?)}, '+\1+') + txt.gsub!(%r{(.*?)}, '+\1+') + txt.gsub!(%r{(.*?)}, '*\1*') + txt.gsub!(%r{(.*?)}, '_\1_') + txt + end + + def display_list(list) + case list.type + when :BULLET + prefixer = proc { |ignored| @indent + "* " } + + when :NUMBER, :UPPERALPHA, :LOWERALPHA then + start = case list.type + when :NUMBER then 1 + when :UPPERALPHA then 'A' + when :LOWERALPHA then 'a' + end + + prefixer = proc do |ignored| + res = @indent + "#{start}.".ljust(4) + start = start.succ + res + end + + when :LABELED, :NOTE then + longest = 0 + + list.contents.each do |item| + if RDoc::Markup::Flow::LI === item and item.label.length > longest then + longest = item.label.length + end + end + + longest += 1 + + prefixer = proc { |li| @indent + li.label.ljust(longest) } + + else + raise ArgumentError, "unknown list type #{list.type}" + end + + list.contents.each do |item| + if RDoc::Markup::Flow::LI === item then + prefix = prefixer.call item + display_flow_item item, prefix + else + display_flow_item item + end + end + end + + def display_flow_item(item, prefix = @indent) + case item + when RDoc::Markup::Flow::P, RDoc::Markup::Flow::LI + wrap(conv_html(item.body), prefix) + blankline + + when RDoc::Markup::Flow::LIST + display_list(item) + + when RDoc::Markup::Flow::VERB + display_verbatim_flow_item(item, @indent) + + when RDoc::Markup::Flow::H + display_heading(conv_html(item.text), item.level, @indent) + + when RDoc::Markup::Flow::RULE + draw_line + + else + raise RDoc::Error, "Unknown flow element: #{item.class}" + end + end + + def display_verbatim_flow_item(item, prefix=@indent) + item.body.split(/\n/).each do |line| + @output.print @indent, conv_html(line), "\n" + end + blankline + end + + def display_heading(text, level, indent) + text = strip_attributes text + + case level + when 1 then + ul = "=" * text.length + @output.puts + @output.puts text.upcase + @output.puts ul + + when 2 then + ul = "-" * text.length + @output.puts + @output.puts text + @output.puts ul + else + @output.print indent, text, "\n" + end + + @output.puts + end + + def display_flow(flow) + flow.each do |f| + display_flow_item(f) + end + end + + def strip_attributes(text) + text.gsub(/(<\/?(?:b|code|em|i|tt)>)/, '') + end + +end + +## +# Handle text with attributes. We're a base class: there are different +# presentation classes (one, for example, uses overstrikes to handle bold and +# underlining, while another using ANSI escape sequences. + +class RDoc::RI::AttributeFormatter < RDoc::RI::Formatter + + BOLD = 1 + ITALIC = 2 + CODE = 4 + + ATTR_MAP = { + "b" => BOLD, + "code" => CODE, + "em" => ITALIC, + "i" => ITALIC, + "tt" => CODE + } + + AttrChar = Struct.new :char, :attr + + class AttributeString + attr_reader :txt + + def initialize + @txt = [] + @optr = 0 + end + + def <<(char) + @txt << char + end + + def empty? + @optr >= @txt.length + end + + # accept non space, then all following spaces + def next_word + start = @optr + len = @txt.length + + while @optr < len && @txt[@optr].char != " " + @optr += 1 + end + + while @optr < len && @txt[@optr].char == " " + @optr += 1 + end + + @txt[start...@optr] + end + end + + ## + # Overrides base class. Looks for ... etc sequences and generates + # an array of AttrChars. This array is then used as the basis for the + # split. + + def wrap(txt, prefix=@indent, linelen=@width) + return unless txt && !txt.empty? + + txt = add_attributes_to(txt) + next_prefix = prefix.tr("^ ", " ") + linelen -= prefix.size + + line = [] + + until txt.empty? + word = txt.next_word + if word.size + line.size > linelen + write_attribute_text(prefix, line) + prefix = next_prefix + line = [] + end + line.concat(word) + end + + write_attribute_text(prefix, line) if line.length > 0 + end + + protected + + def write_attribute_text(prefix, line) + @output.print prefix + line.each do |achar| + @output.print achar.char + end + @output.puts + end + + def bold_print(txt) + @output.print txt + end + + private + + def add_attributes_to(txt) + tokens = txt.split(%r{()}) + text = AttributeString.new + attributes = 0 + tokens.each do |tok| + case tok + when %r{^$} then attributes &= ~(ATTR_MAP[$1]||0) + when %r{^<(\w+)>$} then attributes |= (ATTR_MAP[$1]||0) + else + tok.split(//).each {|ch| text << AttrChar.new(ch, attributes)} + end + end + text + end + +end + +## +# This formatter generates overstrike-style formatting, which works with +# pagers such as man and less. + +class RDoc::RI::OverstrikeFormatter < RDoc::RI::AttributeFormatter + + BS = "\C-h" + + def write_attribute_text(prefix, line) + @output.print prefix + + line.each do |achar| + attr = achar.attr + @output.print "_", BS if (attr & (ITALIC + CODE)) != 0 + @output.print achar.char, BS if (attr & BOLD) != 0 + @output.print achar.char + end + + @output.puts + end + + ## + # Draw a string in bold + + def bold_print(text) + text.split(//).each do |ch| + @output.print ch, BS, ch + end + end + +end + +## +# This formatter uses ANSI escape sequences to colorize stuff works with +# pagers such as man and less. + +class RDoc::RI::AnsiFormatter < RDoc::RI::AttributeFormatter + + def initialize(*args) + super + @output.print "\033[0m" + end + + def write_attribute_text(prefix, line) + @output.print prefix + curr_attr = 0 + line.each do |achar| + attr = achar.attr + if achar.attr != curr_attr + update_attributes(achar.attr) + curr_attr = achar.attr + end + @output.print achar.char + end + update_attributes(0) unless curr_attr.zero? + @output.puts + end + + def bold_print(txt) + @output.print "\033[1m#{txt}\033[m" + end + + HEADINGS = { + 1 => ["\033[1;32m", "\033[m"], + 2 => ["\033[4;32m", "\033[m"], + 3 => ["\033[32m", "\033[m"], + } + + def display_heading(text, level, indent) + level = 3 if level > 3 + heading = HEADINGS[level] + @output.print indent + @output.print heading[0] + @output.print strip_attributes(text) + @output.puts heading[1] + end + + private + + ATTR_MAP = { + BOLD => "1", + ITALIC => "33", + CODE => "36" + } + + def update_attributes(attr) + str = "\033[" + for quality in [ BOLD, ITALIC, CODE] + unless (attr & quality).zero? + str << ATTR_MAP[quality] + end + end + @output.print str, "m" + end + +end + +## +# This formatter uses HTML. + +class RDoc::RI::HtmlFormatter < RDoc::RI::AttributeFormatter + + ## + # We depend on HTML4-conforming user agents to ignore an empty p element + + def blankline + @output.puts '

' + end + + ## + # Emboldens +text+ + + def bold_print(text) + tag("b") { text } + end + + ## + # Outputs a forced line break element + + def break_to_newline + @output.puts '
' + end + + ## + # Outputs heading elements for +text+ with +level+ up to 4. Ignores + # +indent+. + + def display_heading(text, level, indent) + level = 4 if level > 4 + tag("h#{level}") { text } + @output.puts + end + + ## + # Outputs +list+ which is displayed as follows: + # + # BULLET:: unordered list + # NUMBER:: ordered list + # LABELED:: definition list + # NOTE:: table + + def display_list(list) + case list.type + when :BULLET then + list_type = "ul" + prefixer = proc { |ignored| '

  • ' } + suffix = '
  • ' + + when :NUMBER, :UPPERALPHA, :LOWERALPHA then + list_type = "ol" + prefixer = proc { |ignored| '
  • ' } + suffix = '
  • ' + + when :LABELED then + list_type = "dl" + prefixer = proc do |li| + "
    #{escape li.label}
    " + end + suffix = '
    ' + + when :NOTE then + list_type = "table" + prefixer = proc do |li| + %{#{li.label.gsub(/ /, ' ')}} + end + suffix = '' + else + fail "unknown list type" + end + + @output.print "<#{list_type}>" + + list.contents.each do |item| + if item.kind_of? RDoc::Markup::Flow::LI + prefix = prefixer.call item + @output.print prefix + display_flow_item item, prefix + @output.print suffix + else + display_flow_item item + end + end + + @output.print "" + end + + ## + # Outputs a preformatted section for +item+. +prefix+ is ignored. + + def display_verbatim_flow_item(item, prefix=@indent) + @output.print '
    '
    +
    +    item.body.split(/\n/).each do |line|
    +      @output.puts escape(line)
    +    end
    +
    +    @output.puts '
    ' + end + + ## + # Outputs a horizontal rule element, optionally labeled above with +label+ in + # bold. + + def draw_line(label = nil) + bold_print label if label + + @output.puts "
    " + end + + def write_attribute_text(prefix, line) + curr_attr = 0 + + line.each do |achar| + attr = achar.attr + if achar.attr != curr_attr then + update_attributes curr_attr, achar.attr + curr_attr = achar.attr + end + @output.print escape(achar.char) + end + + update_attributes curr_attr, 0 unless curr_attr.zero? + end + + private + + ATTR_MAP = { + BOLD => "b>", + ITALIC => "i>", + CODE => "tt>" + } + + def update_attributes(current, wanted) + str = "" + # first turn off unwanted ones + off = current & ~wanted + for quality in [ BOLD, ITALIC, CODE] + if (off & quality) > 0 + str << "") + @output.print(yield) + @output.print("") + end + + def escape(str) + str = str.gsub(/&/n, '&') + str.gsub!(/\"/n, '"') + str.gsub!(/>/n, '>') + str.gsub!(//system/... +# site:: $datadir/ri//site/... +# user:: ~/.rdoc + +module RDoc::RI::Paths + + #:stopdoc: + require 'rbconfig' + + DOC_DIR = "doc/rdoc" + + VERSION = RbConfig::CONFIG['ruby_version'] + + base = File.join(RbConfig::CONFIG['datadir'], "ri", VERSION) + SYSDIR = File.join(base, "system") + SITEDIR = File.join(base, "site") + homedir = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH'] + + if homedir then + HOMEDIR = File.join(homedir, ".rdoc") + else + HOMEDIR = nil + end + + begin + require 'rubygems' unless defined?(Gem) and defined?(Gem::Enable) and + Gem::Enable + + # HACK dup'd from Gem.latest_partials and friends + all_paths = [] + + all_paths = Gem.path.map do |dir| + Dir[File.join(dir, 'doc', '*', 'ri')] + end.flatten + + ri_paths = {} + + all_paths.each do |dir| + base = File.basename File.dirname(dir) + if base =~ /(.*)-((\d+\.)*\d+)/ then + name, version = $1, $2 + ver = Gem::Version.new version + if ri_paths[name].nil? or ver > ri_paths[name][0] then + ri_paths[name] = [ver, dir] + end + end + end + + GEMDIRS = ri_paths.map { |k,v| v.last }.sort + rescue LoadError + GEMDIRS = [] + end + + # Returns the selected documentation directories as an Array, or PATH if no + # overriding directories were given. + + def self.path(use_system, use_site, use_home, use_gems, *extra_dirs) + path = raw_path(use_system, use_site, use_home, use_gems, *extra_dirs) + return path.select { |directory| File.directory? directory } + end + + # Returns the selected documentation directories including nonexistent + # directories. Used to print out what paths were searched if no ri was + # found. + + def self.raw_path(use_system, use_site, use_home, use_gems, *extra_dirs) + path = [] + path << extra_dirs unless extra_dirs.empty? + path << SYSDIR if use_system + path << SITEDIR if use_site + path << HOMEDIR if use_home + path << GEMDIRS if use_gems + + return path.flatten.compact + end +end diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/reader.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/reader.rb new file mode 100755 index 00000000..de3c8d9a --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/reader.rb @@ -0,0 +1,106 @@ +require 'rdoc/ri' +require 'rdoc/ri/descriptions' +require 'rdoc/ri/writer' +require 'rdoc/markup/to_flow' + +class RDoc::RI::Reader + + def initialize(ri_cache) + @cache = ri_cache + end + + def top_level_namespace + [ @cache.toplevel ] + end + + def lookup_namespace_in(target, namespaces) + result = [] + for n in namespaces + result.concat(n.contained_modules_matching(target)) + end + result + end + + def find_class_by_name(full_name) + names = full_name.split(/::/) + ns = @cache.toplevel + for name in names + ns = ns.contained_class_named(name) + return nil if ns.nil? + end + get_class(ns) + end + + def find_methods(name, is_class_method, namespaces) + result = [] + namespaces.each do |ns| + result.concat ns.methods_matching(name, is_class_method) + end + result + end + + ## + # Return the MethodDescription for a given MethodEntry by deserializing the + # YAML + + def get_method(method_entry) + path = method_entry.path_name + File.open(path) { |f| RDoc::RI::Description.deserialize(f) } + end + + ## + # Return a class description + + def get_class(class_entry) + result = nil + for path in class_entry.path_names + path = RDoc::RI::Writer.class_desc_path(path, class_entry) + desc = File.open(path) {|f| RDoc::RI::Description.deserialize(f) } + if result + result.merge_in(desc) + else + result = desc + end + end + result + end + + ## + # Return the names of all classes and modules + + def full_class_names + res = [] + find_classes_in(res, @cache.toplevel) + end + + ## + # Return a list of all classes, modules, and methods + + def all_names + res = [] + find_names_in(res, @cache.toplevel) + end + + private + + def find_classes_in(res, klass) + classes = klass.classes_and_modules + for c in classes + res << c.full_name + find_classes_in(res, c) + end + res + end + + def find_names_in(res, klass) + classes = klass.classes_and_modules + for c in classes + res << c.full_name + res.concat c.all_method_names + find_names_in(res, c) + end + res + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/util.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/util.rb new file mode 100755 index 00000000..4e91eb97 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/util.rb @@ -0,0 +1,79 @@ +require 'rdoc/ri' + +## +# Break argument into its constituent class or module names, an +# optional method type, and a method name + +class RDoc::RI::NameDescriptor + + attr_reader :class_names + attr_reader :method_name + + ## + # true and false have the obvious meaning. nil means we don't care + + attr_reader :is_class_method + + ## + # +arg+ may be + # + # 1. A class or module name (optionally qualified with other class or module + # names (Kernel, File::Stat etc) + # 2. A method name + # 3. A method name qualified by a optionally fully qualified class or module + # name + # + # We're fairly casual about delimiters: folks can say Kernel::puts, + # Kernel.puts, or Kernel\#puts for example. There's one exception: if you + # say IO::read, we look for a class method, but if you say IO.read, we look + # for an instance method + + def initialize(arg) + @class_names = [] + separator = nil + + tokens = arg.split(/(\.|::|#)/) + + # Skip leading '::', '#' or '.', but remember it might + # be a method name qualifier + separator = tokens.shift if tokens[0] =~ /^(\.|::|#)/ + + # Skip leading '::', but remember we potentially have an inst + + # leading stuff must be class names + + while tokens[0] =~ /^[A-Z]/ + @class_names << tokens.shift + unless tokens.empty? + separator = tokens.shift + break unless separator == "::" + end + end + + # Now must have a single token, the method name, or an empty array + unless tokens.empty? + @method_name = tokens.shift + # We may now have a trailing !, ?, or = to roll into + # the method name + if !tokens.empty? && tokens[0] =~ /^[!?=]$/ + @method_name << tokens.shift + end + + if @method_name =~ /::|\.|#/ or !tokens.empty? + raise RDoc::RI::Error.new("Bad argument: #{arg}") + end + if separator && separator != '.' + @is_class_method = separator == "::" + end + end + end + + # Return the full class name (with '::' between the components) or "" if + # there's no class name + + def full_class_name + @class_names.join("::") + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/writer.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/writer.rb new file mode 100755 index 00000000..92aaa1c2 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/ri/writer.rb @@ -0,0 +1,68 @@ +require 'fileutils' +require 'rdoc/ri' + +class RDoc::RI::Writer + + def self.class_desc_path(dir, class_desc) + File.join(dir, "cdesc-" + class_desc.name + ".yaml") + end + + ## + # Convert a name from internal form (containing punctuation) to an external + # form (where punctuation is replaced by %xx) + + def self.internal_to_external(name) + if ''.respond_to? :ord then + name.gsub(/\W/) { "%%%02x" % $&[0].ord } + else + name.gsub(/\W/) { "%%%02x" % $&[0] } + end + end + + ## + # And the reverse operation + + def self.external_to_internal(name) + name.gsub(/%([0-9a-f]{2,2})/) { $1.to_i(16).chr } + end + + def initialize(base_dir) + @base_dir = base_dir + end + + def remove_class(class_desc) + FileUtils.rm_rf(path_to_dir(class_desc.full_name)) + end + + def add_class(class_desc) + dir = path_to_dir(class_desc.full_name) + FileUtils.mkdir_p(dir) + class_file_name = self.class.class_desc_path(dir, class_desc) + File.open(class_file_name, "w") do |f| + f.write(class_desc.serialize) + end + end + + def add_method(class_desc, method_desc) + dir = path_to_dir(class_desc.full_name) + file_name = self.class.internal_to_external(method_desc.name) + meth_file_name = File.join(dir, file_name) + if method_desc.is_singleton + meth_file_name += "-c.yaml" + else + meth_file_name += "-i.yaml" + end + + File.open(meth_file_name, "w") do |f| + f.write(method_desc.serialize) + end + end + + private + + def path_to_dir(class_name) + File.join(@base_dir, *class_name.split('::')) + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/single_class.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/single_class.rb new file mode 100755 index 00000000..de96a6a3 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/single_class.rb @@ -0,0 +1,8 @@ +require 'rdoc/class_module' + +## +# A singleton class + +class RDoc::SingleClass < RDoc::ClassModule +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/stats.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/stats.rb new file mode 100755 index 00000000..ff5255f9 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/stats.rb @@ -0,0 +1,178 @@ +require 'rdoc' +require 'thread' + +## +# Simple stats collector + +class RDoc::Stats + + attr_reader :num_classes + attr_reader :num_files + attr_reader :num_methods + attr_reader :num_modules + attr_reader :total_files + + def initialize(total_files, verbosity = 1) + @lock = Mutex.new + + @num_classes = 0 + @num_files = 0 + @num_methods = 0 + @num_modules = 0 + @total_files = total_files + + @start = Time.now + + @display = case verbosity + when 0 then Quiet.new + when 1 then Normal.new(total_files) + else Verbose.new + end + end + + def begin_adding(number_of_workers) + @display.begin_adding(number_of_workers) + end + + def add_alias(as) + @lock.synchronize do + @display.print_alias as + @num_methods += 1 + end + end + + def add_class(klass) + @lock.synchronize do + @display.print_class klass + @num_classes += 1 + end + end + + def add_file(file) + @lock.synchronize do + @display.print_file @num_files, file + @num_files += 1 + end + end + + def add_method(method) + @lock.synchronize do + @display.print_method method + @num_methods += 1 + end + end + + def add_module(mod) + @lock.synchronize do + @display.print_module mod + @num_modules += 1 + end + end + + def done_adding + @lock.synchronize do + @display.done_adding + end + end + + def print + puts "Files: #@num_files" + puts "Classes: #@num_classes" + puts "Modules: #@num_modules" + puts "Methods: #@num_methods" + puts "Elapsed: " + sprintf("%0.1fs", Time.now - @start) + end + + class Quiet + def begin_adding(*) end + def print_alias(*) end + def print_class(*) end + def print_file(*) end + def print_method(*) end + def print_module(*) end + def done_adding(*) end + end + + class Normal + def initialize(total_files) + @total_files = total_files + end + + def begin_adding(number_of_workers) + puts "Parsing sources with #{number_of_workers} thread(s)..." + end + + def print_file(files_so_far, filename) + progress_bar = sprintf("%3d%% [%2d/%2d] ", + 100 * (files_so_far + 1) / @total_files, + files_so_far + 1, + @total_files) + + if $stdout.tty? + # Print a progress bar, but make sure it fits on a single line. Filename + # will be truncated if necessary. + terminal_width = (ENV['COLUMNS'] || 80).to_i + max_filename_size = terminal_width - progress_bar.size + if filename.size > max_filename_size + # Turn "some_long_filename.rb" to "...ong_filename.rb" + filename = filename[(filename.size - max_filename_size) .. -1] + filename[0..2] = "..." + end + + # Pad the line with whitespaces so that leftover output from the + # previous line doesn't show up. + line = "#{progress_bar}#{filename}" + padding = terminal_width - line.size + if padding > 0 + line << (" " * padding) + end + + $stdout.print("#{line}\r") + $stdout.flush + else + puts "#{progress_bar} #{filename}" + end + end + + def done_adding + puts "\n" + end + + def print_alias(*) end + def print_class(*) end + def print_method(*) end + def print_module(*) end + end + + class Verbose + def begin_adding(number_of_workers) + puts "Parsing sources with #{number_of_workers} thread(s)..." + end + + def print_alias(as) + puts "\t\talias #{as.new_name} #{as.old_name}" + end + + def print_class(klass) + puts "\tclass #{klass.full_name}" + end + + def print_file(files_so_far, file) + puts file + end + + def print_method(method) + puts "\t\t#{method.singleton ? '::' : '#'}#{method.name}" + end + + def print_module(mod) + puts "\tmodule #{mod.full_name}" + end + + def done_adding + end + end + +end + + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/task.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/task.rb new file mode 100755 index 00000000..67657be7 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/task.rb @@ -0,0 +1,276 @@ +# Copyright (c) 2003, 2004 Jim Weirich, 2009 Eric Hodel +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +require 'rubygems' +begin + gem 'rdoc' +rescue Gem::LoadError +end + +begin + gem 'rake' +rescue Gem::LoadError +end + +require 'rdoc' +require 'rake' +require 'rake/tasklib' + +## +# Create a documentation task that will generate the RDoc files for a project. +# +# The RDoc::Task will create the following targets: +# +# [rdoc] +# Main task for this RDoc task. +# +# [:clobber_rdoc] +# Delete all the rdoc files. This target is automatically added to the main +# clobber target. +# +# [:rerdoc] +# Rebuild the rdoc files from scratch, even if they are not out of date. +# +# Simple Example: +# +# RDoc::Task.new do |rd| +# rd.main = "README.rdoc" +# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") +# end +# +# The +rd+ object passed to the block is an RDoc::Task object. See the +# attributes list for the RDoc::Task class for available customization options. +# +# == Specifying different task names +# +# You may wish to give the task a different name, such as if you are +# generating two sets of documentation. For instance, if you want to have a +# development set of documentation including private methods: +# +# RDoc::Task.new :rdoc_dev do |rd| +# rd.main = "README.doc" +# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") +# rd.options << "--all" +# end +# +# The tasks would then be named :rdoc_dev, +# :clobber_rdoc_dev, and :rerdoc_dev. +# +# If you wish to have completely different task names, then pass a Hash as +# first argument. With the :rdoc, :clobber_rdoc and +# :rerdoc options, you can customize the task names to your liking. +# +# For example: +# +# RDoc::Task.new(:rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", +# :rerdoc => "rdoc:force") +# +# This will create the tasks :rdoc, :rdoc_clean and +# :rdoc:force. + +class RDoc::Task < Rake::TaskLib + + ## + # Name of the main, top level task. (default is :rdoc) + + attr_accessor :name + + ## + # Name of directory to receive the html output files. (default is "html") + + attr_accessor :rdoc_dir + + ## + # Title of RDoc documentation. (defaults to rdoc's default) + + attr_accessor :title + + ## + # Name of file to be used as the main, top level file of the RDoc. (default + # is none) + + attr_accessor :main + + ## + # Name of template to be used by rdoc. (defaults to rdoc's default) + + attr_accessor :template + + ## + # List of files to be included in the rdoc generation. (default is []) + + attr_accessor :rdoc_files + + ## + # Additional list of options to be passed rdoc. (default is []) + + attr_accessor :options + + ## + # Whether to run the rdoc process as an external shell (default is false) + + attr_accessor :external + + ## + # Create an RDoc task with the given name. See the RDoc::Task class overview + # for documentation. + + def initialize(name = :rdoc) # :yield: self + if name.is_a? Hash then + invalid_options = name.keys.map { |k| k.to_sym } - + [:rdoc, :clobber_rdoc, :rerdoc] + + unless invalid_options.empty? then + raise ArgumentError, "invalid options: #{invalid_options.join(", ")}" + end + end + + @name = name + @rdoc_files = Rake::FileList.new + @rdoc_dir = 'html' + @main = nil + @title = nil + @template = nil + @external = false + @options = [] + yield self if block_given? + define + end + + ## + # Create the tasks defined by this task lib. + + def define + if rdoc_task_name != "rdoc" then + desc "Build the RDoc HTML Files" + else + desc "Build the #{rdoc_task_name} HTML Files" + end + task rdoc_task_name + + desc "Force a rebuild of the RDoc files" + task rerdoc_task_name => [clobber_task_name, rdoc_task_name] + + desc "Remove RDoc products" + task clobber_task_name do + rm_r rdoc_dir rescue nil + end + + task :clobber => [clobber_task_name] + + directory @rdoc_dir + task rdoc_task_name => [rdoc_target] + file rdoc_target => @rdoc_files + [Rake.application.rakefile] do + rm_r @rdoc_dir rescue nil + @before_running_rdoc.call if @before_running_rdoc + args = option_list + @rdoc_files + + if @external then + argstring = args.join(' ') + sh %{ruby -Ivendor vendor/rd #{argstring}} + else + if Rake.application.options.trace then + $stderr.puts "rdoc #{args.join ' '}" + end + require 'rdoc/rdoc' + RDoc::RDoc.new.document(args) + end + end + + self + end + + def option_list + result = @options.dup + result << "-o" << @rdoc_dir + result << "--main" << quote(main) if main + result << "--title" << quote(title) if title + result << "-T" << quote(template) if template + result + end + + def quote(str) + if @external + "'#{str}'" + else + str + end + end + + def option_string + option_list.join(' ') + end + + ## + # The block passed to this method will be called just before running the + # RDoc generator. It is allowed to modify RDoc::Task attributes inside the + # block. + + def before_running_rdoc(&block) + @before_running_rdoc = block + end + + private + + def rdoc_target + "#{rdoc_dir}/index.html" + end + + def rdoc_task_name + case name + when Hash + (name[:rdoc] || "rdoc").to_s + else + name.to_s + end + end + + def clobber_task_name + case name + when Hash + (name[:clobber_rdoc] || "clobber_rdoc").to_s + else + "clobber_#{name}" + end + end + + def rerdoc_task_name + case name + when Hash + (name[:rerdoc] || "rerdoc").to_s + else + "re#{name}" + end + end + +end + +# :stopdoc: +module Rake + + ## + # For backwards compatibility + + RDocTask = RDoc::Task + +end +# :startdoc: + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/tokenstream.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/tokenstream.rb new file mode 100755 index 00000000..0a1eb913 --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/tokenstream.rb @@ -0,0 +1,33 @@ +module RDoc; end + +## +# A TokenStream is a list of tokens, gathered during the parse of some entity +# (say a method). Entities populate these streams by being registered with the +# lexer. Any class can collect tokens by including TokenStream. From the +# outside, you use such an object by calling the start_collecting_tokens +# method, followed by calls to add_token and pop_token. + +module RDoc::TokenStream + + def token_stream + @token_stream + end + + def start_collecting_tokens + @token_stream = [] + end + + def add_token(tk) + @token_stream << tk + end + + def add_tokens(tks) + tks.each {|tk| add_token(tk)} + end + + def pop_token + @token_stream.pop + end + +end + diff --git a/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/top_level.rb b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/top_level.rb new file mode 100755 index 00000000..5db404cc --- /dev/null +++ b/vendor/gems/gems/rdoc-2.4.3/lib/rdoc/top_level.rb @@ -0,0 +1,242 @@ +require 'thread' +require 'rdoc/context' + +## +# A TopLevel context is a representation of the contents of a single file + +class RDoc::TopLevel < RDoc::Context + + ## + # This TopLevel's File::Stat struct + + attr_accessor :file_stat + + ## + # Relative name of this file + + attr_accessor :relative_name + + ## + # Absolute name of this file + + attr_accessor :absolute_name + + attr_accessor :diagram + + ## + # The parser that processed this file + + attr_accessor :parser + + ## + # Returns all classes and modules discovered by RDoc + + def self.all_classes_and_modules + classes_hash.values + modules_hash.values + end + + ## + # Returns all classes discovered by RDoc + + def self.classes + classes_hash.values + end + + ## + # Hash of all classes known to RDoc + + def self.classes_hash + @all_classes + end + + ## + # All TopLevels known to RDoc + + def self.files + @all_files.values + end + + ## + # Hash of all files known to RDoc + + def self.files_hash + @all_files + end + + ## + # Finds the class with +name+ in all discovered classes + + def self.find_class_named(name) + @lock.synchronize do + classes_hash.values.find do |c| + c.find_class_named name + end + end + end + + ## + # Finds the file with +name+ in all discovered files + + def self.find_file_named(name) + @lock.synchronize do + @all_files[name] + end + end + + ## + # Finds the module with +name+ in all discovered modules + + def self.find_module_named(name) + @lock.synchronize do + modules_hash.values.find do |c| + c.find_module_named name + end + end + end + + @lock = Mutex.new + + ## + # Lock for global class, module and file stores + + def self.lock + @lock + end + + ## + # Returns all modules discovered by RDoc + + def self.modules + modules_hash.values + end + + ## + # Hash of all modules known to RDoc + + def self.modules_hash + @all_modules + end + + ## + # Empties RDoc of stored class, module and file information + + def self.reset + @lock.synchronize do + @all_classes = {} + @all_modules = {} + @all_files = {} + end + end + + reset + + ## + # Creates a new TopLevel for +file_name+ + + def initialize(file_name) + super() + @name = nil + @relative_name = file_name + @absolute_name = file_name + @file_stat = File.stat(file_name) rescue nil # HACK for testing + @diagram = nil + @parser = nil + + RDoc::TopLevel.lock.synchronize do + RDoc::TopLevel.files_hash[file_name] = self + end + end + + ## + # Adds +method+ to Object instead of RDoc::TopLevel + + def add_method(method) + object = self.class.find_class_named 'Object' + object = add_class RDoc::NormalClass, 'Object' unless object + + object.add_method method + end + + ## + # Base name of this file + + def base_name + File.basename @absolute_name + end + + ## + # Find class or module named +symbol+ in all discovered classes and + # modules + + def find_class_or_module_named(symbol) + RDoc::TopLevel.classes_hash.each_value do |c| + return c if c.full_name == symbol + end + + RDoc::TopLevel.modules_hash.each_value do |m| + return m if m.full_name == symbol + end + + nil + end + + ## + # Finds a class or module named +symbol+ + + def find_local_symbol(symbol) + find_class_or_module_named(symbol) || super + end + + ## + # Finds a module or class with +name+ + + def find_module_named(name) + find_class_or_module_named(name) || find_enclosing_module_named(name) + end + + ## + # The name of this file + + def full_name + @relative_name + end + + ## + # URL for this with a +prefix+ + + def http_url(prefix) + path = [prefix, @relative_name.tr('.', '_')] + + File.join(*path.compact) + '.html' + end + + def inspect # :nodoc: + "#<%s:0x%x %p modules: %p classes: %p>" % [ + self.class, object_id, + base_name, + @modules.map { |n,m| m }, + @classes.map { |n,c| c } + ] + end + + ## + # Date this file was last modified, if known + + def last_modified + @file_stat ? file_stat.mtime.to_s : 'Unknown' + end + + ## + # Base name of this file + + alias name base_name + + ## + # Path to this file + + def path + http_url RDoc::RDoc.current.generator.file_dir + end + +end + diff --git a/vendor/gems/gems/sdoc-0.2.14.1/lib/rdoc/discover.rb b/vendor/gems/gems/sdoc-0.2.14.1/lib/rdoc/discover.rb new file mode 100755 index 00000000..6a539431 --- /dev/null +++ b/vendor/gems/gems/sdoc-0.2.14.1/lib/rdoc/discover.rb @@ -0,0 +1 @@ +require File.join(File.dirname(__FILE__), '/../sdoc') \ No newline at end of file diff --git a/vendor/gems/gems/smusher-0.4.2/rdoc/README.rdoc b/vendor/gems/gems/smusher-0.4.2/rdoc/README.rdoc new file mode 100644 index 00000000..40d5c6ef --- /dev/null +++ b/vendor/gems/gems/smusher-0.4.2/rdoc/README.rdoc @@ -0,0 +1 @@ +documentation is at http://github.com/grosser/smusher