summaryrefslogtreecommitdiff
path: root/jni/ruby/lib/rdoc/generator/json_index.rb
diff options
context:
space:
mode:
Diffstat (limited to 'jni/ruby/lib/rdoc/generator/json_index.rb')
-rw-r--r--jni/ruby/lib/rdoc/generator/json_index.rb292
1 files changed, 292 insertions, 0 deletions
diff --git a/jni/ruby/lib/rdoc/generator/json_index.rb b/jni/ruby/lib/rdoc/generator/json_index.rb
new file mode 100644
index 0000000..9d6f0d4
--- /dev/null
+++ b/jni/ruby/lib/rdoc/generator/json_index.rb
@@ -0,0 +1,292 @@
+require 'json'
+require 'zlib'
+
+##
+# The JsonIndex generator is designed to complement an HTML generator and
+# produces a JSON search index. This generator is derived from sdoc by
+# Vladimir Kolesnikov and contains verbatim code written by him.
+#
+# This generator is designed to be used with a regular HTML generator:
+#
+# class RDoc::Generator::Darkfish
+# def initialize options
+# # ...
+# @base_dir = Pathname.pwd.expand_path
+#
+# @json_index = RDoc::Generator::JsonIndex.new self, options
+# end
+#
+# def generate
+# # ...
+# @json_index.generate
+# end
+# end
+#
+# == Index Format
+#
+# The index is output as a JSON file assigned to the global variable
+# +search_data+. The structure is:
+#
+# var search_data = {
+# "index": {
+# "searchIndex":
+# ["a", "b", ...],
+# "longSearchIndex":
+# ["a", "a::b", ...],
+# "info": [
+# ["A", "A", "A.html", "", ""],
+# ["B", "A::B", "A::B.html", "", ""],
+# ...
+# ]
+# }
+# }
+#
+# The same item is described across the +searchIndex+, +longSearchIndex+ and
+# +info+ fields. The +searchIndex+ field contains the item's short name, the
+# +longSearchIndex+ field contains the full_name (when appropriate) and the
+# +info+ field contains the item's name, full_name, path, parameters and a
+# snippet of the item's comment.
+#
+# == LICENSE
+#
+# Copyright (c) 2009 Vladimir Kolesnikov
+#
+# 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.
+
+class RDoc::Generator::JsonIndex
+
+ include RDoc::Text
+
+ ##
+ # Where the search index lives in the generated output
+
+ SEARCH_INDEX_FILE = File.join 'js', 'search_index.js'
+
+ attr_reader :index # :nodoc:
+
+ ##
+ # Creates a new generator. +parent_generator+ is used to determine the
+ # class_dir and file_dir of links in the output index.
+ #
+ # +options+ are the same options passed to the parent generator.
+
+ def initialize parent_generator, options
+ @parent_generator = parent_generator
+ @store = parent_generator.store
+ @options = options
+
+ @template_dir = File.expand_path '../template/json_index', __FILE__
+ @base_dir = @parent_generator.base_dir
+
+ @classes = nil
+ @files = nil
+ @index = nil
+ end
+
+ ##
+ # Builds the JSON index as a Hash.
+
+ def build_index
+ reset @store.all_files.sort, @store.all_classes_and_modules.sort
+
+ index_classes
+ index_methods
+ index_pages
+
+ { :index => @index }
+ end
+
+ ##
+ # Output progress information if debugging is enabled
+
+ def debug_msg *msg
+ return unless $DEBUG_RDOC
+ $stderr.puts(*msg)
+ end
+
+ ##
+ # Writes the JSON index to disk
+
+ def generate
+ debug_msg "Generating JSON index"
+
+ debug_msg " writing search index to %s" % SEARCH_INDEX_FILE
+ data = build_index
+
+ return if @options.dry_run
+
+ out_dir = @base_dir + @options.op_dir
+ index_file = out_dir + SEARCH_INDEX_FILE
+
+ FileUtils.mkdir_p index_file.dirname, :verbose => $DEBUG_RDOC
+
+ index_file.open 'w', 0644 do |io|
+ io.set_encoding Encoding::UTF_8 if Object.const_defined? :Encoding
+ io.write 'var search_data = '
+
+ JSON.dump data, io, 0
+ end
+
+ Dir.chdir @template_dir do
+ Dir['**/*.js'].each do |source|
+ dest = File.join out_dir, source
+
+ FileUtils.install source, dest, :mode => 0644, :verbose => $DEBUG_RDOC
+ end
+ end
+ end
+
+ ##
+ # Compress the search_index.js file using gzip
+
+ def generate_gzipped
+ debug_msg "Compressing generated JSON index"
+ out_dir = @base_dir + @options.op_dir
+
+ search_index_file = out_dir + SEARCH_INDEX_FILE
+ outfile = out_dir + "#{search_index_file}.gz"
+
+ debug_msg "Reading the JSON index file from %s" % search_index_file
+ search_index = search_index_file.read
+
+ debug_msg "Writing gzipped search index to %s" % outfile
+
+ Zlib::GzipWriter.open(outfile) do |gz|
+ gz.mtime = File.mtime(search_index_file)
+ gz.orig_name = search_index_file.to_s
+ gz.write search_index
+ gz.close
+ end
+
+ # GZip the rest of the js files
+ Dir.chdir @template_dir do
+ Dir['**/*.js'].each do |source|
+ dest = out_dir + source
+ outfile = out_dir + "#{dest}.gz"
+
+ debug_msg "Reading the original js file from %s" % dest
+ data = dest.read
+
+ debug_msg "Writing gzipped file to %s" % outfile
+
+ Zlib::GzipWriter.open(outfile) do |gz|
+ gz.mtime = File.mtime(dest)
+ gz.orig_name = dest.to_s
+ gz.write data
+ gz.close
+ end
+ end
+ end
+ end
+
+ ##
+ # Adds classes and modules to the index
+
+ def index_classes
+ debug_msg " generating class search index"
+
+ documented = @classes.uniq.select do |klass|
+ klass.document_self_or_methods
+ end
+
+ documented.each do |klass|
+ debug_msg " #{klass.full_name}"
+ record = klass.search_record
+ @index[:searchIndex] << search_string(record.shift)
+ @index[:longSearchIndex] << search_string(record.shift)
+ @index[:info] << record
+ end
+ end
+
+ ##
+ # Adds methods to the index
+
+ def index_methods
+ debug_msg " generating method search index"
+
+ list = @classes.uniq.map do |klass|
+ klass.method_list
+ end.flatten.sort_by do |method|
+ [method.name, method.parent.full_name]
+ end
+
+ list.each do |method|
+ debug_msg " #{method.full_name}"
+ record = method.search_record
+ @index[:searchIndex] << "#{search_string record.shift}()"
+ @index[:longSearchIndex] << "#{search_string record.shift}()"
+ @index[:info] << record
+ end
+ end
+
+ ##
+ # Adds pages to the index
+
+ def index_pages
+ debug_msg " generating pages search index"
+
+ pages = @files.select do |file|
+ file.text?
+ end
+
+ pages.each do |page|
+ debug_msg " #{page.page_name}"
+ record = page.search_record
+ @index[:searchIndex] << search_string(record.shift)
+ @index[:longSearchIndex] << ''
+ record.shift
+ @index[:info] << record
+ end
+ end
+
+ ##
+ # The directory classes are written to
+
+ def class_dir
+ @parent_generator.class_dir
+ end
+
+ ##
+ # The directory files are written to
+
+ def file_dir
+ @parent_generator.file_dir
+ end
+
+ def reset files, classes # :nodoc:
+ @files = files
+ @classes = classes
+
+ @index = {
+ :searchIndex => [],
+ :longSearchIndex => [],
+ :info => []
+ }
+ end
+
+ ##
+ # Removes whitespace and downcases +string+
+
+ def search_string string
+ string.downcase.gsub(/\s/, '')
+ end
+
+end
+