Commit 2c4bd194 authored by Nick Poulden's avatar Nick Poulden
Browse files

Merge branch 'master' into comments

parents 76336231 ec5391c9
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -59,7 +59,10 @@ You can also use `--verbose` option to see what's actually happening.

To generate docs for Ext JS 4 add path to the corresponding src/ dir:

    $ jsduck --builtin-classes --output your/docs  extjs-4.0.2a/src
    $ jsduck extjs-4.0.2a/src \
             --builtin-classes \
             --images extjs-4.0.2a/docs/doc-resources \
             --output your/docs

Running JSDuck with the current ext-4.0.2a release is expected to
generate a lot of warnings.  Because of the bugs in doc-comments a
@@ -71,12 +74,6 @@ line options type `jsduck --help=full`.
The latest ext-4.0.6 release will produce only few warnings, so use
that if you can get it.

Finally, to get more similar result to the [official Ext JS 4
documentation][official], copy over the doc-resources directory, which
contains the images referenced by the documentation:

    $ cp -r ext-4.0.2a/docs/doc-resources your/docs/doc-resources

Note that the resulting documentation will only contain the API
documentation.  Guides, videos and examples will not be present.
These can be added using more command line options, but for now those
@@ -96,7 +93,6 @@ classes inherit from Ext JS classes.
To create guides, videos and other sections, read about the
[Advanced Usage][adv] in wiki.

[official]: http://docs.sencha.com/ext-js/4-0/
[adv]: https://github.com/senchalabs/jsduck/wiki/Advanced-Usage


+29 −4
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ def load_sdk_vars
    puts "For example:"
    puts
    puts "    # path to Ext JS 4 build"
    puts "    EXT_DIR='/path/to/ext-4.0.6'"
    puts "    EXT_DIR='/path/to/ext-4.0.7'"
    puts "    # where to output the docs"
    puts "    OUT_DIR='/path/to/ouput/dir'"
    puts "    # path to SDK (for developers at Sencha)"
@@ -155,17 +155,42 @@ class JsDuckRunner
    @options += options
  end

  def add_sdk
  def add_sdk(mode = nil)

    head_html = <<-EOHTML
      <link rel="canonical" href="http://docs.sencha.com/ext-js/4-0/" />
      <meta name="description" content="Ext JS 4.0 API Documentation from Sencha. Class documentation, Guides and Videos on how to create Javascript applications with Ext JS 4" />
      <script type="text/javascript">Docs.enableComments = true; Docs.baseUrl = "#{@base_url}"; Docs.commentsDb = 'comments-ext-js-4';</script>
    EOHTML

    if mode == 'export'

      relative_sdk_path = "../"

      ["template-min/extIframe.html", "template-min/welcome.html"].each do |file|
        html = IO.read(file);

        out = []

        html.each_line do |line|
          out << line.sub(/((src|href)="extjs\/)/, '\2="' + relative_sdk_path)
        end

        File.open(file, 'w') {|f| f.write(out) }
      end

      head_html = <<-EOHTML
        <script type="text/javascript">
          Docs.exampleBaseUrl = "#{relative_sdk_path}examples/";
        </script>
      EOHTML

    end

    @options += [
      "--title", "Sencha Docs - Ext JS 4.0",
      "--head-html", head_html,
      "--footer", "Ext JS 4.0.6 Docs - Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> rev #{revision}",
      "--footer", "Ext JS 4.0.7 Docs - Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> rev #{revision}",
      "--welcome", "template/welcome.html",
      "--guides", "#{@sdk_dir}/extjs/docs/guides.json",
      "--videos", "#{@sdk_dir}/extjs/docs/videos.json",
@@ -523,7 +548,7 @@ task :sdk, [:mode] => :sass do |t, args|
  compress if mode == "export" || mode == "live"

  runner = JsDuckRunner.new
  runner.add_sdk
  runner.add_sdk(mode)
  runner.add_debug if mode == "debug"
  runner.add_seo if mode == "debug" || mode == "live"
  runner.add_sdk_export_notice if mode == "export"
+3 −3
Original line number Diff line number Diff line
@@ -2,10 +2,10 @@ Gem::Specification.new do |s|
  s.required_rubygems_version = ">= 1.3.7"

  s.name = 'jsduck'
  s.version = '3.0.pre2'
  s.date = '2011-09-20'
  s.version = '3.0.pre3'
  s.date = '2011-10-17'
  s.summary = "Simple JavaScript Duckumentation generator"
  s.description = "Documentation generator for ExtJS 4"
  s.description = "Documentation generator for Sencha JS frameworks"
  s.homepage = "https://github.com/senchalabs/jsduck"
  s.authors = ["Rene Saarsoo", "Nick Poulden"]
  s.email = "rene.saarsoo@sencha.com"
+28 −32
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@ require 'jsduck/relations'
require 'jsduck/aliases'
require 'jsduck/exporter'
require 'jsduck/renderer'
require 'jsduck/timer'
require 'jsduck/parallel_wrap'
require 'jsduck/logger'
require 'jsduck/welcome'
@@ -31,7 +30,6 @@ module JsDuck
    # Initializes app with JsDuck::Options object
    def initialize(opts)
      @opts = opts
      @timer = Timer.new
      # Sets the nr of parallel processes to use.
      # Set to 0 to disable parallelization completely.
      @parallel = ParallelWrap.new(:in_processes => @opts.processes)
@@ -44,9 +42,9 @@ module JsDuck

    # Call this after input parameters set
    def run
      parsed_files = @timer.time(:parsing) { parallel_parse(@opts.input_files) }
      result = @timer.time(:aggregating) { aggregate(parsed_files) }
      @relations = @timer.time(:aggregating) { filter_classes(result) }
      parsed_files = parallel_parse(@opts.input_files)
      result = aggregate(parsed_files)
      @relations = filter_classes(result)
      Aliases.new(@relations).resolve_all
      Lint.new(@relations).run

@@ -54,39 +52,38 @@ module JsDuck

      @welcome = Welcome.new
      if @opts.welcome
        @timer.time(:parsing) { @welcome.parse(@opts.welcome) }
        @welcome.parse(@opts.welcome)
      end

      @guides = Guides.new(get_doc_formatter)
      if @opts.guides
        @timer.time(:parsing) { @guides.parse(@opts.guides) }
        @guides.parse(@opts.guides)
      end

      @videos = Videos.new
      if @opts.videos
        @timer.time(:parsing) { @videos.parse(@opts.videos) }
        @videos.parse(@opts.videos)
      end

      @examples = Examples.new
      if @opts.examples
        @timer.time(:parsing) { @examples.parse(@opts.examples) }
        @examples.parse(@opts.examples)
      end

      @categories = Categories.new(get_doc_formatter, @relations)
      if @opts.categories_path
        @timer.time(:parsing) do
        @categories.parse(@opts.categories_path)
          @categories.validate
        end
      else
        @categories.auto_generate
      end

      clear_output_dir unless @opts.export == :stdout
      if @opts.export == :stdout
        @timer.time(:generating) { puts JsonDuck.generate(@relations.classes) }
        puts JsonDuck.generate(@relations.classes)
      elsif @opts.export == :json
        FileUtils.mkdir(@opts.output_dir)
        @timer.time(:generating) { format_classes }
        @timer.time(:generating) { write_classes }
        format_classes
        write_classes
      else
        if @opts.template_links
          link_template
@@ -99,23 +96,22 @@ module JsDuck
          FileUtils.rm(@opts.output_dir+"/index.php")
          FileUtils.cp(@opts.output_dir+"/template.html", @opts.output_dir+"/index.html")
        end
        @timer.time(:generating) { write_src(parsed_files) }
        @timer.time(:generating) { format_classes }
        @timer.time(:generating) { write_app_data }
        @timer.time(:generating) { write_classes }
        @timer.time(:generating) { @guides.write(@opts.output_dir+"/guides") }
        @timer.time(:generating) { @videos.write(@opts.output_dir+"/videos") }
        @timer.time(:generating) { @examples.write(@opts.output_dir+"/examples") }
        @timer.time(:generating) { @images.copy(@opts.output_dir+"/images") }
        write_src(parsed_files)
        format_classes
        write_app_data
        write_classes
        @guides.write(@opts.output_dir+"/guides")
        @videos.write(@opts.output_dir+"/videos")
        @examples.write(@opts.output_dir+"/examples")
        @images.copy(@opts.output_dir+"/images")
      end

      @timer.report
    end

    # Parses the files in parallel using as many processes as available CPU-s
    def parallel_parse(filenames)
      @parallel.map(filenames) do |fname|
        Logger.instance.log("Parsing #{fname} ...")
        Logger.instance.log("Parsing", fname)
        SourceFile.new(IO.read(fname), fname, @opts)
      end
    end
@@ -124,7 +120,7 @@ module JsDuck
    def aggregate(parsed_files)
      agr = Aggregator.new
      parsed_files.each do |file|
        Logger.instance.log("Aggregating #{file.filename} ...")
        Logger.instance.log("Aggregating", file.filename)
        agr.aggregate(file)
      end
      agr.classify_orphans
@@ -196,7 +192,7 @@ module JsDuck
      dir = @opts.output_dir + (@opts.export ? "" : "/output")
      @parallel.each(@relations.classes) do |cls|
        filename = dir + "/" + cls[:name] + (@opts.export ? ".json" : ".js")
        Logger.instance.log("Writing to #{filename} ...")
        Logger.instance.log("Writing docs", filename)
        data = exporter.export(cls)
        if @opts.export
          JsonDuck.write_json(filename, data)
@@ -215,7 +211,7 @@ module JsDuck
      # updates all the doc-objects related to the file
      parsed_files.each do |file|
        html_filename = src.write(file.to_html, file.filename)
        Logger.instance.log("Writing to #{html_filename} ...")
        Logger.instance.log("Writing source", html_filename)
        file.html_filename = File.basename(html_filename)
      end
    end
@@ -230,13 +226,13 @@ module JsDuck
    end

    def copy_template
      Logger.instance.log("Copying template files to #{@opts.output_dir}...")
      Logger.instance.log("Copying template files to", @opts.output_dir)
      FileUtils.cp_r(@opts.template_dir, @opts.output_dir)
      init_output_dirs
    end

    def link_template
      Logger.instance.log("Linking template files to #{@opts.output_dir}...")
      Logger.instance.log("Linking template files to", @opts.output_dir)
      FileUtils.mkdir(@opts.output_dir)
      Dir.glob(@opts.template_dir + "/*").each do |file|
        File.symlink(File.expand_path(file), @opts.output_dir+"/"+File.basename(file))
@@ -283,7 +279,7 @@ module JsDuck
    def write_template(filename, replacements)
      in_file = @opts.template_dir + '/' + filename
      out_file = @opts.output_dir + '/' + filename
      Logger.instance.log("Creating #{out_file}...")
      Logger.instance.log("Writing", out_file)
      html = IO.read(in_file)
      html.gsub!(/\{\w+\}/) do |key|
        replacements[key] ? replacements[key] : key
+80 −0
Original line number Diff line number Diff line
module JsDuck

  # Automatically divides all available classes into categories
  class AutoCategories
    def initialize(relations)
      @relations = relations
    end

    # Performs the generation
    def generate
      # list names of all public classes
      class_names = @relations.to_a.find_all {|cls| !cls[:private] }.map {|cls| cls[:name] }

      # divide classes into top-level categories by namespace
      categories = categorize(class_names)

      # in each category, create sub-categories
      categories.each_pair do |ns, classes|
        categories[ns] = categorize(classes, 1)
      end

      # Turn categories hash into array, sort everything
      categories_array = []
      categories.each_pair do |ns, groups|
        groups_array = []
        groups.each_pair do |gns, classes|
          groups_array << {
            "name" => gns,
            "classes" => classes.sort
          }
        end
        groups_array.sort! {|a, b| cat_compare(a, b) }
        categories_array << {
          "name" => ns,
          "groups" => groups_array
        }
      end
      categories_array.sort! {|a, b| cat_compare(a, b) }

      return categories_array
    end

    # Divides classes into categories by namespace.  Collapses
    # categories having only one class into a category "Others..."
    def categorize(class_names, level=0)
      categories = {}
      class_names.each do |name|
        ns = name.split(/\./)[level] || name.split(/\./)[0]
        categories[ns] = [] unless categories[ns]
        categories[ns] << name
      end

      globals = []
      categories.each_pair do |ns, classes|
        if classes.length == 1
          globals << classes[0]
          categories.delete(ns)
        end
      end
      if globals.length > 0
        categories["Others..."] = globals
      end

      categories
    end

    # Comparison function for sorting categories that always places
    # "Others..." category at the end.
    def cat_compare(a, b)
      if a["name"] == "Others..."
        1
      elsif b["name"] == "Others..."
        -1
      else
        a["name"] <=> b["name"]
      end
    end
  end

end
Loading