Commit 82823676 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Merge branch 'master' into inline-examples.

parents 34519c9b ff79798e
Loading
Loading
Loading
Loading
+78 −110
Original line number Diff line number Diff line
JsDuck
======

Simple JavaScript Duckumentation generator.
API documentation generator for ExtJS 4.

           ,~~.
          (  6 )-_,
@@ -10,46 +10,16 @@ Simple JavaScript Duckumentation generator.
       \ `-' /    hjw
    ~'`~'`~'`~'`~

JsDuck aims to be a better documentation generator for [ExtJS][].
While it tries to do everything that [ext-doc][] does, it isn't
satisfied with it and aims to make your life much easier.
JsDuck aims to be a better documentation generator for [ExtJS][] than
the old [ext-doc][] was.

Basically JsDuck thinks that the following doc-comment really sucks:
The standard way to give some structure to the JavaDoc-style code
documentation is to use HTML in doc-comments.  Although the resulting
documentation will look pretty, this is often achieved by sacrificing
the readability of comments - HTML can get quite ugly.

    /**
     * @class Ext.form.TextField
     * @extends Ext.form.Field
     * <p>Basic text field.  Can be used as a direct replacement for traditional
     * text inputs, or as the base class for more sophisticated input controls
     * (like {@link Ext.form.TextArea} and {@link Ext.form.ComboBox}).</p>
     * <p><b><u>Validation</u></b></p>
     * <p>The validation procedure is described in the documentation for
     * {@link #validateValue}.</p>
     * <p><b><u>Alter Validation Behavior</u></b></p>
     * <p>Validation behavior for each field can be configured:</p>
     * <div class="mdetail-params"><ul>
     * <li><code>{@link Ext.form.TextField#invalidText invalidText}</code> :
     * the default validation message to show if any validation step above does
     * not provide a message when invalid</li>
     * <li><code>{@link Ext.form.TextField#maskRe maskRe}</code> :
     * filter out keystrokes before any validation occurs</li>
     * <li><code>{@link Ext.form.TextField#stripCharsRe stripCharsRe}</code> :
     * filter characters after being typed in, but before being validated</li>
     * </ul></div>
     *
     * @constructor Creates a new TextField
     * @param {Object} config Configuration options
     *
     * @xtype textfield
     */
    Ext.form.TextField = Ext.extend(Ext.form.Field,  {

Not quite so readable is it?  The source of ExtJS is filled with
comments just like that, and when you use ext-doc, you too are forced
to write such comments.

JsDuck does not like it.  Although it can handle comments like this,
it would like that you wrote comments like that instead:
JsDuck does not like it.  Although it can handle comments written in
HTML, it prefers a friendlier [Markdown][] syntax:

    /**
     * Basic text field.  Can be used as a direct replacement for traditional
@@ -77,16 +47,12 @@ it would like that you wrote comments like that instead:
     *
     * @xtype textfield
     */
    Ext.form.TextField = Ext.extend(Ext.form.Field,  {

As you can see, JsDuck supports formatting comments with friendly
[Markdown][] syntax.  And it can infer several things from the code
(like @class and @extends in this case), so you don't have to repeat
yourself.  Also the constructor documentation is inherited from parent
class - so you don't have to restate that it takes a config object
again.
    Ext.define('Ext.form.field.Text', {
        extend: 'Ext.form.field.Base',

That's basically it.  Have fun.
As you can see, JsDuck can infer several things from the code (like
`@class` and `@extends` in this case), so you don't have to repeat
yourself.

[ExtJS]: http://www.sencha.com/products/js/
[ext-doc]: http://ext-doc.org/
@@ -96,18 +62,27 @@ That's basically it. Have fun.
Getting it
----------

Standard rubygems install should do:
Standard rubygems install should do (use the `--pre` switch to get the
latest 2.0 version which this README documents, otherwise you will get
the stable but quite old [0.6][v0.6] version):

    $ [sudo] gem install jsduck
    $ [sudo] gem install --pre jsduck

For hacking fork it from github.
For hacking fork it from github:

    $ git clone git://github.com/nene/jsduck.git
    $ git clone git://github.com/senchalabs/jsduck.git
    $ cd jsduck
    $ rake --tasks

JsDuck depends on [json][], [RDiscount][], and [parallel][] plus [RSpec][] for tests.
JsDuck depends on [json][], [RDiscount][], and [parallel][]; plus
[RSpec][] for tests.

If you encounter errors during gem installation, you may need to
install the header files for compiling extension modules for ruby 1.8.
For Debian systems you'll need the `ruby1.8-dev` package.  For Red Hat
/ CentOS / Fedora use the `ruby-devel` package.

[v0.6]: https://github.com/senchalabs/jsduck/tree/v0.6
[json]: http://flori.github.com/json/
[RDiscount]: https://github.com/rtomayko/rdiscount
[parallel]: https://github.com/grosser/parallel
@@ -120,90 +95,83 @@ Usage
Just call it from command line with output directory and a directory
containing your JavaScript files:

    $ jsduck --verbose --output some/dir  your/project/js
    $ jsduck your/project/js --verbose --output your/docs

The `--verbose` flag creates a lot of output, but at least you will
see that something is happening.

You pass in both directories and JavaScript files.  For example to
generate docs for ExtJS 3, the simplest way is the following:

    $ jsduck -v -o output/ ext-3.3.1/src/

But this will give you a bunch of warnings, so you should better
create a script that takes just the files really needed and passes
them through `xargs` to `jsduck`:

    $ find ext-3.3.1/src/ -name '*.js' | egrep -v 'locale/|test/|adapter/' | xargs jsduck -v -o output/
## Generating Docs for ExtJS 4

Here's how the resulting documentation will look (ExtJS 3.3.1):
For the simplest test-run just pass in the src/ dir of ExtJS 4.  But
to get more similar result to the [official ExtJS 4
documentation][official], you should pass in some extra options and
copy over the doc-resources directory, which contains the images
referenced by the documentation:

* [JsDuck generated documentation](http://triin.net/temp/jsduck/)
* [Official ExtJS documentation](http://dev.sencha.com/deploy/dev/docs/) (for comparison)
    $ jsduck ext-4.0.2a/src --output your/docs --ignore-global --exclude Error
    $ cp -r ext-4.0.2a/docs/doc-resources your/docs/doc-resources

Here's the same for ExtJS 4:
The `--ignore-global` will avoid the creation of a `global` class.
The `--exclude Error` will ignore references to the `Error` class,
which would otherwise result in several warnings.

* [JsDuck generated documentation](http://triin.net/temp/jsduck4/)
* [Official ExtJS documentation](http://docs.sencha.com/ext-js/4-0/api) (for comparison)
Still, running JSDuck with the current ext-4.0.2a release is expected
to generate a lot of warnings.  These should be fixed in some later
releases.

[official]: http://docs.sencha.com/ext-js/4-0/

Documentation
-------------

Overview of documenting your code with JsDuck:
Documenting your code with JSDuck
---------------------------------

* [Class](https://github.com/nene/jsduck/wiki/Class)
* [Constructor](https://github.com/nene/jsduck/wiki/Constructor)
* [Config options](https://github.com/nene/jsduck/wiki/Cfg)
* [Properties](https://github.com/nene/jsduck/wiki/Property)
* [Methods](https://github.com/nene/jsduck/wiki/Method)
* [Events](https://github.com/nene/jsduck/wiki/Event)
Here's an overview of [all the available @tags][tags], and how to use
them:

More details:
* [Class](https://github.com/senchalabs/jsduck/wiki/Class)
* [Constructor](https://github.com/senchalabs/jsduck/wiki/Constructor)
* [Config options](https://github.com/senchalabs/jsduck/wiki/Cfg)
* [Properties](https://github.com/senchalabs/jsduck/wiki/Property)
* [Methods](https://github.com/senchalabs/jsduck/wiki/Method)
* [Events](https://github.com/senchalabs/jsduck/wiki/Event)

* [List of supported @tags][tags]
* [List of doc-comment errors(?) found in ExtJS source][errors]

[tags]: https://github.com/nene/jsduck/wiki/List-of-supported-@tags
[errors]: https://github.com/nene/jsduck/wiki/List-of-doc-comment-errors(%3F)-found-in-ExtJS-source


Features and differences from ext-doc
-------------------------------------

JsDuck has some strong opinions, so some things are intentionally
missing.

* Support for Markdown in comments
* More things inferred from the code
* No XML configuration file, just command line options
* Class documentation header doesn't separately list Package and Class -
  these are IMHO redundant.
* Class documentation header doesn't duplicate toolbar buttons -
  another redundancy
* Ext.Component has a component icon too, not only its descendants


Missing features and TODO
-------------------------

* Support for custom @tags. Ext-doc supports this, I personally have
  never used this feature, so I'm thinking it's not really needed.
[tags]: https://github.com/senchalabs/jsduck/wiki/List-of-supported-@tags


Copying
-------

JsDuck is distributed under the terms of the GNU General Public License version 3.
JsDuck is distributed under the terms of the GNU General Public
License version 3.

JsDuck was developed by [Rene Saarsoo](http://triin.net),
with contributions from [Ondřej Jirman](https://github.com/megous)
and [Nick Poulden](https://github.com/nick).
with many contributions from [Nick Poulden](https://github.com/nick).

Thanks to [Ondřej Jirman](https://github.com/megous),
[Thomas Aylott](https://github.com/subtleGradient),
[johnnywengluu](https://github.com/johnnywengluu),
[gevik](https://github.com/gevik),
[ligaard](https://github.com/ligaard), and many-many others who
reported bugs, submitted patches, and provided a lot of useful input.


Changelog
---------

* 2.0.pre2 - Fixes for the previous pre-release.
  * New --stdout command line option.
  * Fix opening links in new tabs.
  * Few other small bugfixes and enhancements.

* 2.0.pre - Completely overhauled Ext4-themed version.
  * Currently in a pre-release state.

* 0.6.1 - Bug fixes.
  * Fix scrolling to class members in Chrome 12.
  * Make JSDuck work with Ruby 1.8.6.
  * Upgrade the embedded ExtJS to 3.4.0.

* 0.6 - JsDuck is now used for creating the official ExtJS4 documentation.
  * Automatic linking of class names found in comments.  Instead of writing
    `{@link Ext.Panel}` one can simply write `Ext.Panel` and link will be
+11 −8
Original line number Diff line number Diff line
@@ -43,11 +43,9 @@ def run_jsduck(extra_options)
    "ruby", "bin/jsduck",
    # --external=Error to ignore the Error class that Ext.Error extends.
    "--external", "Error",
    '--link', '<a href="#/api/%c%-%m" rel="%c%-%m" class="docClass">%a</a>',
    # Note that we wrap image template inside <p> because {@img} often
    # appears inline withing text, but that just looks ugly in HTML
    '--img', '<p><img src="doc-resources/%u" alt="%a"></p>',
    "--guides", "#{SDK_DIR}/guides",
    "--guides-order", "getting,class,application,layouts,data,grid,tree,drawing,forms,components,theming,direct",
    "--categories", "#{SDK_DIR}/extjs/doc-resources/categories.json",
    "--output", "#{OUT_DIR}",
  ].concat(extra_options))

@@ -60,6 +58,7 @@ desc "Run JSDuck on ExtJS SDK"
task :sdk do
  load_sdk_vars
  run_jsduck([
    "--extjs-path", "extjs/ext-debug.js",
    # to create symbolic links to template files instead of copying them over.
    # Useful for development.  Turn off for deployment.
    "--template-links",
@@ -72,11 +71,15 @@ end
def run_jsduck_export(extra_options, ext_dir)
  load_sdk_vars
  rev = `git rev-parse HEAD`.slice(0, 7)
  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">
  EOHTML

  run_jsduck([
    "--title", "Ext JS 4.0.2a API Documentation",
    "--footer", "ExtJS 4.0.2a Documentation from Sencha. Generated with <a href='https://github.com/nene/jsduck'>JSDuck</a> revison #{rev}",
    "--extjs-path", "extjs/ext-all.js",
    "--footer", "ExtJS 4.0.2a Documentation from Sencha. Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> revison #{rev}",
    "--head-html", head_html,
    "#{SDK_DIR}/extjs/src",
    "#{SDK_DIR}/platform/src",
    "#{SDK_DIR}/platform/core/src",
@@ -94,7 +97,7 @@ desc "Run JSDuck on ExtJS SDK to create release version of docs app"
task :export do
  load_sdk_vars
  run_jsduck_export([
    "--append-html", <<-EOHTML
    "--body-html", <<-EOHTML
    <div id="notice-text" style="display: none">
      Use <a href="http://docs.sencha.com/ext-js/4-0">http://docs.sencha.com/ext-js/4-0</a> for up to date documentation and features
    </div>
@@ -106,7 +109,7 @@ desc "Run JSDuck on ExtJS SDK to create live docs app"
task :live_docs do
  load_sdk_vars
  run_jsduck_export([
    "--append-html", <<-EOHTML
    "--body-html", <<-EOHTML
    <script type="text/javascript">
      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', 'UA-1396058-10']);
+101 −59
Original line number Diff line number Diff line
@@ -26,8 +26,18 @@ app.template_dir = File.dirname(File.dirname(__FILE__)) + "/template"
opts = OptionParser.new do | opts |
  opts.banner = "Usage: jsduck [options] files/dirs...\n\n"

  opts.on('--append-html=HTML', "Extra code to append to the index.html page.", " ") do |html|
    app.append_html = html
  opts.on('-o', '--output=PATH',
    "Directory to output all this amazing documentation.",
    "This option MUST be specified.", " ") do |path|
    app.output_dir = path
  end

  opts.on('--ignore-global', "Turns off the creation of global class.", " ") do
    app.ignore_global = true
  end

  opts.on('--private-classes', "Include private classes to docs.", " ") do
    app.show_private_classes = true
  end

  opts.on('--external=CLASSNAME',
@@ -38,16 +48,37 @@ opts = OptionParser.new do | opts |
    app.external_classes << classname
  end

  opts.on('--extjs-path=PATH',
    "Path for main ExtJS JavaScript file.  Useful for specifying",
    "something different than extjs/ext-all-debug.js", " ") do |path|
    app.extjs_path = path
  opts.on('--no-warnings', "Turns off warnings.", " ") do
    app.warnings = false
  end

  opts.on('-v', '--verbose', "This will fill up your console.", " ") do
    app.verbose = true
  end

  opts.on('--footer=TEXT', "Custom footer text for the documentation app.", " ") do |text|
  opts.separator "Customizing output:"
  opts.separator ""

  opts.on('--title=TEXT',
    "Custom title for the documentation app.",
    "Defaults to 'ExtJS API Documentation'", " ") do |text|
    app.title = text
  end

  opts.on('--footer=TEXT',
    "Custom footer text for the documentation app.",
    "Defaults to: 'Generated with JSDuck.'", " ") do |text|
    app.footer = text
  end

  opts.on('--head-html=HTML', "HTML to append to the <head> section of index.html.", " ") do |html|
    app.head_html = html
  end

  opts.on('--body-html=HTML', "HTML to append to the <body> section index.html.", " ") do |html|
    app.body_html = html
  end

  opts.on('--guides=PATH', "Path to guides directory.",
    "Each subdirectory of that is treated as a guide",
    "and is expectd to contain a REAME.md file,",
@@ -55,26 +86,17 @@ opts = OptionParser.new do | opts |
    app.guides_dir = path
  end

  opts.on('-h', '--help', "Prints this help message", " ") do
    puts opts
    exit
  opts.on('--guides-order=a,b,c', Array,
    "The order in which the guides should appear. When",
    "a guide name is not specified here, it will be excluded.",
    "You don't have to write the whole name of the guide,",
    "just the beginning of it, as long as it's unique.", " ") do |list|
    app.guides_order = list
  end

  opts.on('--ignore-global', "Turns off the creation of global class.", " ") do
    app.ignore_global = true
  end

  opts.on('--img=TPL',
    "HTML template for replacing {@img}.",
    "Possible placeholders:",
    "%u - URL from @img tag (e.g. 'some/path.png')",
    "%a - alt text for image",
    "Default value in export: '<img src=\"%u\" alt=\"%a\"/>'", " ") do |tpl|
    app.img_tpl = tpl
  end

  opts.on('--json', "Produces JSON export instead of HTML documentation.", " ") do
    app.export = :json
  opts.on('--categories=PATH',
    "Path to JSON file which defines categories for classes.", " ") do |path|
    app.categories_path = path
  end

  opts.on('--link=TPL',
@@ -86,22 +108,30 @@ opts = OptionParser.new do | opts |
    "%# - inserts '#' if member name present",
    "%- - inserts '-' if member name present",
    "%a - anchor text for link",
    "Default value in export: '<a href=\"%c%#%m\">%a</a>'", " ") do |tpl|
    "Default is: '<a href=\"#/api/%c%-%m\" rel=\"%c%-%m\" class=\"docClass\">%a</a>'", " ") do |tpl|
    app.link_tpl = tpl
  end

  opts.on('--no-warnings', "Turns off warnings.", " ") do
    app.warnings = false
  opts.on('--img=TPL',
    "HTML template for replacing {@img}.",
    "Possible placeholders:",
    "%u - URL from @img tag (e.g. 'some/path.png')",
    "%a - alt text for image",
    "Default is: '<p><img src=\"doc-resources/%u\" alt=\"%a\"></p>'", " ") do |tpl|
    app.img_tpl = tpl
  end

  opts.on('-o', '--output=PATH', "Directory to output all this amazing documentation.", " ") do |path|
    app.output_dir = path
  opts.on('--json', "Produces JSON export instead of HTML documentation.", " ") do
    app.export = :json
  end

  opts.on('--private-classes', "Include private classes to docs.", " ") do
    app.show_private_classes = true
  opts.on('--stdout', "Writes JSON export to STDOUT instead of writing to the filesystem", " ") do
    app.export = :stdout
  end

  opts.separator "Debugging:"
  opts.separator ""

  # For debugging it's often useful to set --processes=0 to get deterministic results.
  opts.on('-p', '--processes=COUNT',
    "The number of parallel processes to use.",
@@ -110,7 +140,8 @@ opts = OptionParser.new do | opts |
    app.processes = count.to_i
  end

  opts.on('-t', '--template=PATH', "Directory containing doc-browser UI template.", " ") do |path|
  opts.on('--template=PATH',
    "Directory containing doc-browser UI template.", " ") do |path|
    app.template_dir = path
  end

@@ -121,12 +152,21 @@ opts = OptionParser.new do | opts |
    app.template_links = true
  end

  opts.on('--title=TEXT', "Custom title for the documentation app.", " ") do |text|
    app.title = text
  opts.on('--extjs-path=PATH',
    "Path for main ExtJS JavaScript file.  Useful for specifying",
    "something different than extjs/ext-all.js", " ") do |path|
    app.extjs_path = path
  end

  opts.on('-v', '--verbose', "This will fill up your console.", " ") do
    app.verbose = true
  opts.on('--local-storage-db=NAME',
    "Prefix for LocalStorage database names.",
    "Defaults to 'docs'.", " ") do |name|
    app.local_storage_db = name
  end

  opts.on('-h', '--help', "Prints this help message", " ") do
    puts opts
    exit
  end

end
@@ -141,7 +181,7 @@ opts.parse!(ARGV).each do |fname|
      js_files << fname
    end
  else
    puts "Warning: File #{fname} not found"
    $stderr.puts "Warning: File #{fname} not found"
  end
end
app.input_files = js_files
@@ -149,7 +189,8 @@ app.input_files = js_files
if app.input_files.length == 0
  puts "You should specify some input files, otherwise there's nothing I can do :("
  exit(1)
elsif !app.output_dir
elsif app.export != :stdout
  if !app.output_dir
    puts "You should also specify an output directory, where I could write all this amazing documentation."
    exit(1)
  elsif File.exists?(app.output_dir) && !File.directory?(app.output_dir)
@@ -171,5 +212,6 @@ elsif !File.exists?(app.template_dir + "/resources/css")
    puts "    $ compass compile " + app.template_dir + "/resources/sass"
    exit(1)
  end
end

app.run()
+10 −7
Original line number Diff line number Diff line
@@ -2,18 +2,21 @@ Gem::Specification.new do |s|
  s.required_rubygems_version = ">= 1.3.7"

  s.name = 'jsduck'
  s.version = '0.6'
  s.date = '2011-04-27'
  s.version = '2.0.pre2'
  s.date = '2011-07-06'
  s.summary = "Simple JavaScript Duckumentation generator"
  s.description = "Better ext-doc like JavaScript documentation generator for ExtJS"
  s.homepage = "https://github.com/nene/jsduck"
  s.authors = ["Rene Saarsoo"]
  s.email = "nene@triin.net"
  s.description = "Documentation generator for ExtJS 4"
  s.homepage = "https://github.com/senchalabs/jsduck"
  s.authors = ["Rene Saarsoo", "Nick Poulden"]
  s.email = "rene.saarsoo@sencha.com"
  s.rubyforge_project = s.name

  s.files = `git ls-files`.split("\n").find_all do |file|
    file !~ /spec.rb$/ && file !~ /benchmark/
    file !~ /spec.rb$/ && file !~ /benchmark/ && file !~ /resources\/sass/
  end
  # Add files not in git
  s.files += ['template/extjs/ext-all.js']
  s.files += Dir['template/resources/css/*.css']

  s.executables = ["jsduck"]

+12 −1
Original line number Diff line number Diff line
@@ -57,7 +57,9 @@ module JsDuck
        old[tag] = old[tag] + new[tag]
      end
      old[:doc] = old[:doc].length > 0 ? old[:doc] : new[:doc]
      old[:members][:cfg] = old[:members][:cfg] + new[:members][:cfg]
      # Additionally the doc-comment can contain configs and constructor
      old[:members][:cfg] += new[:members][:cfg]
      old[:members][:method] += new[:members][:method]
    end

    # Tries to place members into classes where they belong.
@@ -145,7 +147,10 @@ module JsDuck
    end

    # Appends Ext4 options parameter to each event parameter list.
    # But only when we are dealing with Ext4 codebase.
    def append_ext4_event_options
      return unless ext4?

      options = {
        :tagname => :param,
        :name => "options",
@@ -157,6 +162,12 @@ module JsDuck
      end
    end

    # Are we dealing with ExtJS 4?
    # True if any of the classes is defined with Ext.define()
    def ext4?
      @documentation.any? {|cls| cls[:code_type] == :ext_define }
    end

    def result
      @documentation + @orphans
    end
Loading