WebRI  WebRI::Generator

[Validate]
Generated with WebRI Redfish 1.2

Generator

This is the static website generator.

Constants

PATH
(Not documented)
PATH_STATIC

Common template directory.

PATH_TEMPLATE

Common template directory.

DIR_CLASS

Directory where generated classes live relative to the root

DIR_FILE

Directory where generated files live relative to the root

DIR_ASSETS

Directory where static assets are located in the template

Attributes

options[R]

User options from the command line.

components[R]

Component instances.

provisions[R]

Component provisions.

template[R]

The template type selected to be generated.

path_base[R]

Current pathname.

path_output[R]

The output path.

output[R]

Directory in which to store generated html files

Public Class Methods

components() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 86
    def self.components
      @components ||= []
    end
for(options) click to toggle source

Standard generator factory method.

# File lib/webri/generators/abstract/generator.rb, line 92
    def self.for(options)
      new(options)
    end
include(*mods) click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 78
    def self.include(*mods)
      comps, mods = *mods.partition{ |m| m < Component }
      components.concat(comps)
      super(*mods)
    end
inherited(base) click to toggle source

::RDoc::RDoc.add_generator(self)

# File lib/webri/generators/abstract/generator.rb, line 72
    def self.inherited(base)
      ::RDoc::RDoc.add_generator(base)
    end
new(service, options={}) click to toggle source
# File lib/webri/server/generator.rb, line 19
    def initialize(service, options={})
      super(service, options)
      #@cgi = {} #CGI.new('html4')
      #@service = service
      @directory_depth = 0
    end
new(options) click to toggle source

Initialization

# File lib/webri/generators/abstract/generator.rb, line 325
    def initialize(options)
      @options = options
      @options.diagram = false  # why?

      @path_base   = Pathname.pwd.expand_path
      @path_output = Pathname.new(@options.op_dir).expand_path(@path_base)

      @provisions = {}

      initialize_template
      initialize_methods
      initialize_components
    end

Public Instance Methods

class_dir() click to toggle source

RDoc needs this to function. ?

# File lib/webri/generators/abstract/generator.rb, line 258
    def class_dir ; DIR_CLASS ; end
classes() click to toggle source

In the world of the RDoc Generators classes is the same as all_classes_and_modules. Well, except that its sorted too. For classes sans modules, see types.

# File lib/webri/generators/abstract/generator.rb, line 130
    def classes
      @classes ||= RDoc::TopLevel.all_classes_and_modules.sort
    end
classes_hash() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 148
    def classes_hash
      @classes_hash ||= RDoc::TopLevel.modules_hash.merge(RDoc::TopLevel.classes_hash)
    end
classes_salient() click to toggle source

Documented classes and modules sorted by salience first, then by name.

# File lib/webri/generators/abstract/generator.rb, line 142
    def classes_salient
      @classes_salient ||= sort_salient(classes)
    end
classes_toplevel() click to toggle source

Only toplevel classes and modules.

# File lib/webri/generators/abstract/generator.rb, line 136
    def classes_toplevel
      @classes_toplevel ||= classes.select {|klass| !(RDoc::ClassModule === klass.parent) }
    end
current_content() click to toggle source
# File lib/webri/server/generator.rb, line 158
    def current_content
      @current_content
    end
file_dir() click to toggle source

RDoc needs this to function. ?

# File lib/webri/generators/abstract/generator.rb, line 262
    def file_dir  ; DIR_FILE ; end
files() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 202
    def files
      @files ||= RDoc::TopLevel.files
    end
files_hash() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 214
    def files_hash
      @files ||= RDoc::TopLevel.files_hash
    end
files_toplevel() click to toggle source

List of toplevel files. RDoc supplies this via the generate method.

# File lib/webri/generators/abstract/generator.rb, line 208
    def files_toplevel
      @files_toplevel ||= @files_rdoc.select { |f| f.parser == RDoc::Parser::Simple }
    end
find_class_named(*a,&b) click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 226
    def find_class_named(*a,&b)
      RDoc::TopLevel.find_class_named(*a,&b) || RDoc::TopLevel.find_module_named(*a,&b)
    end
find_file_named(*a,&b) click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 244
    def find_file_named(*a,&b)
      RDoc::TopLevel.find_file_named(*a,&b)
    end
find_module_named(*a,&b) click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 232
    def find_module_named(*a,&b)
      RDoc::TopLevel.find_module_named(*a,&b)
    end
find_type_named(*a,&b) click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 238
    def find_type_named(*a,&b)
      RDoc::TopLevel.find_class_named(*a,&b)
    end
generate(files) click to toggle source

Build the initial indices and output objects based on an array of top level objects containing the extracted information.

# File lib/webri/generators/abstract/generator.rb, line 269
    def generate(files)
      @files_rdoc = files.sort
      generate_setup
      generate_commons
      generate_components
      generate_static
      generate_template
    rescue StandardError => err
      debug_msg "%s: %s\n  %s" % [ err.class.name, err.message, err.backtrace.join("\n  ") ]
      raise
    end
generate(output=".") click to toggle source

Generate webpages.

# File lib/webri/server/generator.rb, line 65
    def generate(output=".")
      @output = File.expand_path(output)
      # traverse the the hierarchy

      generate_support_files

      #generate_recurse(heirarchy)

#      heirarchy.class_methods.each do |name|
#        p name
#      end

#      heirarchy.instance_methods.each do |name|
#        p name
#      end

      heirarchy.subspaces.each do |name, entry|
        #p name, entry
        generate_recurse(entry)
      end
    end
generate_recurse(entry) click to toggle source

Recrusive HTML generation on a hierarchy entry.

# File lib/webri/server/generator.rb, line 88
    def generate_recurse(entry)
      keyword = entry.full_name

      if keyword
        puts keyword
        @current_content = service.info(keyword) #lookup(keyword)
      else
        keyword = ''
        @current_content = "Welcome"
      end

      file = entry.file_name
      file = File.join(output, file)

      #file = keyword
      #file = file.gsub('::', '--')
      #file = file.gsub('.' , '--')
      #file = file.gsub('#' , '-')
      #file = File.join(output, file + '.html')

      write(file, service.info(keyword))

      cmethods = entry.class_methods.map{ |x| x.to_s }.sort
      cmethods.each do |name|
        mname = "#{entry.full_name}.#{name}"
        mfile = WebRI.entry_to_path(mname)
        mfile = File.join(output, mfile)
        #mfile = File.join(output, "#{entry.file_name}/c-#{esc(name)}.html")
        write(mfile, service.info(mname))
      end

      imethods = entry.instance_methods.map{ |x| x.to_s }.sort
      imethods.each do |name|
        mname = "#{entry.full_name}##{name}"
        mfile = WebRI.entry_to_path(mname)
        mfile = File.join(output, mfile)
        #mfile = File.join(output, "#{entry.file_name}/i-#{esc(name)}.html")
        write(mfile, service.info(mname))
      end

      entry.subspaces.each do |child_name, child_entry|
        next if child_entry == entry
        @directory_depth += 1
        generate_recurse(child_entry)
        @directory_depth -= 1
      end
    end
generate_support_files() click to toggle source

Generate files.

# File lib/webri/server/generator.rb, line 137
    def generate_support_files
      FileUtils.mkdir_p(output)

      write(File.join(output, 'index.html'),  index)
      #write(File.join(output, 'header.html'), page_header)
      #write(File.join(output, 'tree.html'),   page_tree)
      #write(File.join(output, 'main.html'),   page_main)

      # copy assets
      dir = File.join(directory, 'assets')
      FileUtils.cp_r(dir, output)
    end
json_creatable?() click to toggle source

TODO: What’s this then?

# File lib/webri/generators/abstract/generator.rb, line 251
    def json_creatable?
      RDoc::TopLevel.json_creatable?
    end
methods_all() click to toggle source

List of all methods in all classes and modules.

# File lib/webri/generators/abstract/generator.rb, line 220
    def methods_all
      @methods_all ||= classes.map{ |m| m.method_list }.flatten.sort
    end
modules() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 154
    def modules
      @modules ||= RDoc::TopLevel.modules.sort
    end
modules_hash() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 172
    def modules_hash
      @modules_hash ||= RDoc::TopLevel.modules_hash
    end
modules_salient() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 166
    def modules_salient
      @modules_salient ||= sort_salient(modules)
    end
modules_toplevel() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 160
    def modules_toplevel
      @modules_toplevel ||= modules.select {|klass| !(RDoc::ClassModule === klass.parent) }
    end
provision(method, &block) click to toggle source

Components may need to define a method on the rendering context.

# File lib/webri/generators/abstract/generator.rb, line 284
    def provision(method, &block)
      #if block
        #@provisions[method] = block
        (class << self; self; end).class_eval do
          define_method(method) do |*a, &b|
            block.call(*a, &b)
          end
        end
      #else
      #  @provisions[method] = lambda do |*a, &b|
      #    __send__(method, *a, &b)
      #  end
      #end
    end
title() click to toggle source

Get title from options or metadata.

# File lib/webri/generators/abstract/generator.rb, line 106
    def title
      @title ||= (
        if options.title == "RDoc Documentation"
          metadata.title || "RDoc Documentation"
        else
          options.title
        end
      )
    end
types() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 178
    def types
      @types ||= RDoc::TopLevel.classes.sort
    end
types_hash() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 196
    def types_hash
      @types_hash ||= RDoc::TopLevel.classes_hash
    end
types_salient() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 190
    def types_salient
      @types_salient ||= sort_salient(types)
    end
types_toplevel() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 184
    def types_toplevel
      @types_toplevel ||= types.select {|klass| !(RDoc::ClassModule === klass.parent) }
    end
write(file, text) click to toggle source

Write file.

# File lib/webri/server/generator.rb, line 151
    def write(file, text)
      puts file
      FileUtils.mkdir_p(File.dirname(file))
      File.open(file, 'w') { |f| f << text.to_s }
    end

Protected Instance Methods

debug_msg(msg) click to toggle source

Output progress information if rdoc debugging is enabled

# File lib/webri/generators/abstract/generator.rb, line 656
    def debug_msg(msg)
      return unless $DEBUG_RDOC
      case msg[-1,1]
        when '.' then tab = "= "
        when ':' then tab = "== "
        else          tab = "* "
      end
      $stderr.puts(tab + msg)
    end
erb_template() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 622
    def erb_template
      @erb_template ||= Template.new(self, provisions)
    end
eval_template(templatefile, context) click to toggle source

Load and render the erb template in the given templatefile within the specified context (a Binding object) and return output Both templatefile and outfile should be Pathname-like objects.

# File lib/webri/generators/abstract/generator.rb, line 604
    def eval_template(templatefile, context)
      template_src = templatefile.read
      template = ERB.new(template_src, nil, '<>')
      template.filename = templatefile.to_s

      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
    end
generate_classes() click to toggle source

Generate a documentation file for each class

# File lib/webri/generators/abstract/generator.rb, line 495
    def generate_classes
      debug_msg "Generating class documentation in #{path_output_relative}:"
      templatefile = self.path_template + 'class.rhtml'

      classes.each do |klass|
        debug_msg "working on %s (%s)" % [ klass.full_name, klass.path ]
        outfile    = self.path_output + klass.path

        rel_prefix = self.path_output.relative_path_from(outfile.dirname)

        debug_msg "rendering #{path_output_relative(outfile)}"
        self.render_template( templatefile, outfile, :klass=>klass, :rel_prefix=>rel_prefix )
      end
    end
generate_commons() click to toggle source

This method copies the common static files of the abstract generator, which are overlayed with the files from the subclass. This way there is always a standard base to draw upon, and anything the subclass doesn’t like it can override, which provides a sort-of, albeit simplistic, file inheritence system.

# File lib/webri/generators/abstract/generator.rb, line 423
    def generate_commons
      from = Dir[(PATH_STATIC + '**').to_s]
      dest = path_output.to_s
      show_from = PATH_STATIC.to_s.sub(PATH.to_s+'/','')
      debug_msg "Copying #{show_from}/** to #{path_output_relative}/:"
      fileutils.cp_r from, dest, :preserve => true
    end
generate_components() click to toggle source

Let the components generate what they need. Iterates through each componenet and calls generate.

# File lib/webri/generators/abstract/generator.rb, line 463
    def generate_components
      components.each do |component|
        component.generate
      end
    end
generate_files() click to toggle source

Generate a documentation file for each file

# File lib/webri/generators/abstract/generator.rb, line 477
    def generate_files
      debug_msg "Generating file documentation in #{path_output_relative}:"
      templatefile = self.path_template + 'file.rhtml'

      files.each do |file|
        outfile     = self.path_output + file.path
        debug_msg "working on %s (%s)" % [ file.full_name, path_output_relative(outfile) ]

        rel_prefix  = self.path_output.relative_path_from( outfile.dirname )
        #context     = binding()

        debug_msg "rendering #{path_output_relative(outfile)}"
        self.render_template(templatefile, outfile, :file=>file, :rel_prefix=>rel_prefix)
      end
    end
generate_index() click to toggle source

Create index.html

# File lib/webri/generators/abstract/generator.rb, line 512
    def generate_index
      debug_msg "Generating index file in #{path_output_relative}:"
      templatefile = self.path_template + 'index.rhtml'
      outfile      = self.path_output   + 'index.html'

      index_path   = index_file.path

      debug_msg "rendering #{path_output_relative(outfile)}"
      self.render_template(templatefile, outfile, :index_path=>index_path)
    end
generate_setup() click to toggle source

Prepare generator.

# File lib/webri/generators/abstract/generator.rb, line 414
    def generate_setup
    end
generate_static() click to toggle source

Copy static files to output. All the common static content is stored in the assets/ directory. WebRI’s assets/ directory more or less follows an Abbreviated Monash convention:

  assets/
    css/      <- stylesheets
    json/     <- json data table (*maybe top level is better?)
    img/      <- images
    inc/      <- server-side includes
    js/       <- javascripts

Components can utilize this method by providing a path.

# File lib/webri/generators/abstract/generator.rb, line 444
    def generate_static
      from = Dir[(path_static + '**').to_s]
      dest = path_output.to_s
      show_from = path_static.to_s.sub(PATH.to_s+'/', '')
      debug_msg "Copying #{show_from}/** to #{path_output_relative}/:"
      fileutils.cp_r from, dest, :preserve => true
    end
generate_template() click to toggle source

Rendered and save templates.

# File lib/webri/generators/abstract/generator.rb, line 454
    def generate_template
      generate_files
      generate_classes
      generate_index
    end
index_file() click to toggle source

TODO: Make public?

# File lib/webri/generators/abstract/generator.rb, line 525
    def index_file
      if self.options.main_page && file = self.files.find { |f| f.full_name == self.options.main_page }
        file
      else
        self.files.first
      end
    end
initialize_components() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 353
    def initialize_components
      @components = []
      self.class.components.each do |comp|
        @components << comp.new(self)
      end
    end
initialize_methods() click to toggle source

Overide this method to set up any rendering provisions.

# File lib/webri/generators/abstract/generator.rb, line 348
    def initialize_methods
    end
initialize_template() click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 341
    def initialize_template
      @template = @options.template #|| DEFAULT_TEMPLATE
      raise RDoc::Error, "could not find template #{template.inspect}" unless path_template.directory?
    end
path() click to toggle source

Path to the static files. This should be defined in the subclass as:

 def path
  @path ||= Pathname.new(__FILE__).parent
 end
# File lib/webri/generators/abstract/generator.rb, line 387
    def path
      raise "Must be implemented by subclass!"
    end
path_output_relative(path=nil) click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 404
    def path_output_relative(path=nil)
      if path
        path.to_s.sub(path_base.to_s+'/', '')
      else
        @path_output_relative ||= path_output.to_s.sub(path_base.to_s+'/', '')
      end
    end
path_static() click to toggle source

Path to static files. This is path + 'static'.

# File lib/webri/generators/abstract/generator.rb, line 392
    def path_static
      Pathname.new(LOADPATH + "/webri/generators/#{template}/static")
      #path + '#{template}/static'
    end
path_template() click to toggle source

Path to static files. This is path + 'template'.

# File lib/webri/generators/abstract/generator.rb, line 398
    def path_template
      Pathname.new(LOADPATH + "/webri/generators/#{template}/template")
      #path + '#{template}/template'
    end
render_template(templatefile, outfile, local_assigns) click to toggle source

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.

# File lib/webri/generators/abstract/generator.rb, line 574
    def render_template(templatefile, outfile, local_assigns)
      output = erb_template.render(templatefile, local_assigns)

      #output = eval_template(templatefile, context)
      # TODO: delete this dirty hack when documentation for example for GeneratorMethods will not be cutted off by <script> tag
      begin
        if output.respond_to? :force_encoding
          encoding = output.encoding
          output = output.force_encoding('ASCII-8BIT').gsub('<script>', '&lt;script;&gt;').force_encoding(encoding)
        else
          output = output.gsub('<script>', '&lt;script&gt;')
        end
      rescue Exception => e
      end

      unless $dryrun
        outfile.dirname.mkpath
        outfile.open( 'w', 0644 ) do |file|
          file.print( output )
        end
      else
        debug_msg "would have written %d bytes to %s" %
        [ output.length, outfile ]
      end
    end
sort_salient(classes) click to toggle source
# File lib/webri/generators/abstract/generator.rb, line 303
    def sort_salient(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

Disabled; run with --debug to generate this.