jsduck 4.0.1 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +14 -0
- data/esprima/esprima.js +210 -85
- data/jsduck.gemspec +3 -3
- data/lib/jsduck/accessors.rb +10 -8
- data/lib/jsduck/aggregator.rb +7 -7
- data/lib/jsduck/app.rb +24 -164
- data/lib/jsduck/app_data.rb +2 -4
- data/lib/jsduck/assets.rb +5 -2
- data/lib/jsduck/ast.rb +9 -4
- data/lib/jsduck/batch_formatter.rb +54 -0
- data/lib/jsduck/batch_parser.rb +106 -0
- data/lib/jsduck/categories.rb +5 -6
- data/lib/jsduck/class.rb +77 -239
- data/lib/jsduck/class_doc_expander.rb +0 -5
- data/lib/jsduck/class_formatter.rb +14 -10
- data/lib/jsduck/class_name.rb +23 -0
- data/lib/jsduck/class_writer.rb +9 -8
- data/lib/jsduck/doc_ast.rb +5 -6
- data/lib/jsduck/doc_formatter.rb +61 -272
- data/lib/jsduck/enum.rb +4 -4
- data/lib/jsduck/esprima.rb +10 -4
- data/lib/jsduck/examples.rb +5 -5
- data/lib/jsduck/export_writer.rb +62 -0
- data/lib/jsduck/exporter/app.rb +62 -0
- data/lib/jsduck/exporter/examples.rb +58 -0
- data/lib/jsduck/exporter/full.rb +60 -0
- data/lib/jsduck/file_categories.rb +7 -4
- data/lib/jsduck/function_ast.rb +99 -0
- data/lib/jsduck/grouped_asset.rb +27 -16
- data/lib/jsduck/guide_writer.rb +8 -7
- data/lib/jsduck/guides.rb +31 -29
- data/lib/jsduck/icons.rb +12 -1
- data/lib/jsduck/images.rb +3 -3
- data/lib/jsduck/importer.rb +7 -7
- data/lib/jsduck/index_html.rb +20 -6
- data/lib/jsduck/inherit_doc.rb +9 -12
- data/lib/jsduck/inline/example.rb +42 -0
- data/lib/jsduck/inline/img.rb +55 -0
- data/lib/jsduck/inline/link.rb +227 -0
- data/lib/jsduck/inline/video.rb +67 -0
- data/lib/jsduck/inline_examples.rb +7 -7
- data/lib/jsduck/js_parser.rb +5 -4
- data/lib/jsduck/lint.rb +14 -2
- data/lib/jsduck/logger.rb +5 -6
- data/lib/jsduck/members_index.rb +132 -0
- data/lib/jsduck/merger.rb +3 -9
- data/lib/jsduck/options.rb +39 -41
- data/lib/jsduck/override.rb +3 -7
- data/lib/jsduck/relations.rb +9 -9
- data/lib/jsduck/renderer.rb +3 -3
- data/lib/jsduck/return_values.rb +72 -0
- data/lib/jsduck/search_data.rb +16 -20
- data/lib/jsduck/shortener.rb +58 -0
- data/lib/jsduck/signature_renderer.rb +1 -2
- data/lib/jsduck/source/file.rb +98 -0
- data/lib/jsduck/source/file_parser.rb +72 -0
- data/lib/jsduck/source/writer.rb +89 -0
- data/lib/jsduck/tag/aside.rb +1 -1
- data/lib/jsduck/tag/since.rb +1 -1
- data/lib/jsduck/template_dir.rb +2 -2
- data/lib/jsduck/util/html.rb +27 -0
- data/lib/jsduck/util/io.rb +32 -0
- data/lib/jsduck/util/json.rb +60 -0
- data/lib/jsduck/util/null_object.rb +23 -0
- data/lib/jsduck/util/os.rb +14 -0
- data/lib/jsduck/util/parallel.rb +34 -0
- data/lib/jsduck/util/singleton.rb +35 -0
- data/lib/jsduck/util/stdout.rb +33 -0
- data/lib/jsduck/videos.rb +5 -5
- data/lib/jsduck/web_writer.rb +79 -0
- data/lib/jsduck/welcome.rb +6 -6
- data/spec/class_factory.rb +20 -0
- metadata +32 -20
- data/lib/jsduck/api_exporter.rb +0 -48
- data/lib/jsduck/app_exporter.rb +0 -60
- data/lib/jsduck/examples_exporter.rb +0 -56
- data/lib/jsduck/full_exporter.rb +0 -35
- data/lib/jsduck/html.rb +0 -25
- data/lib/jsduck/inline_img.rb +0 -53
- data/lib/jsduck/inline_video.rb +0 -58
- data/lib/jsduck/io.rb +0 -30
- data/lib/jsduck/json_duck.rb +0 -52
- data/lib/jsduck/lexer.rb +0 -251
- data/lib/jsduck/null_object.rb +0 -19
- data/lib/jsduck/os.rb +0 -11
- data/lib/jsduck/parallel_wrap.rb +0 -32
- data/lib/jsduck/source_file.rb +0 -97
- data/lib/jsduck/source_file_parser.rb +0 -70
- data/lib/jsduck/source_writer.rb +0 -87
- data/lib/jsduck/stats.rb +0 -103
- data/lib/jsduck/stdout.rb +0 -31
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'jsduck/logger'
|
2
|
+
require 'jsduck/util/parallel'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module JsDuck
|
6
|
+
module Source
|
7
|
+
|
8
|
+
# Writes HTML JavaScript/CSS source into HTML files.
|
9
|
+
class Writer
|
10
|
+
def initialize(source_files)
|
11
|
+
@source_files = source_files
|
12
|
+
end
|
13
|
+
|
14
|
+
# Writes all source files as HTML files into destination dir.
|
15
|
+
def write(destination)
|
16
|
+
generate_html_filenames
|
17
|
+
|
18
|
+
FileUtils.mkdir(destination)
|
19
|
+
Util::Parallel.each(@source_files) do |file|
|
20
|
+
Logger.log("Writing source", file.html_filename)
|
21
|
+
write_single(destination + "/" + file.html_filename, file.to_html)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Generates unique HTML filenames for each file.
|
28
|
+
#
|
29
|
+
# Can't be done in parallel for obvious reasons, but also
|
30
|
+
# because file.html_filename= method updates all the doc-objects
|
31
|
+
# related to the file.
|
32
|
+
def generate_html_filenames
|
33
|
+
filenames = {}
|
34
|
+
@source_files.each do |file|
|
35
|
+
i = 0
|
36
|
+
begin
|
37
|
+
name = html_filename(file.filename, i)
|
38
|
+
ci_name = name.downcase # case insensitive name
|
39
|
+
i += 1
|
40
|
+
end while filenames.has_key?(ci_name)
|
41
|
+
filenames[ci_name] = true
|
42
|
+
file.html_filename = name
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns HTML filename for n'th file with given name.
|
47
|
+
#
|
48
|
+
# html_filename("Foo.js", 0) => "Foo.html"
|
49
|
+
# html_filename("Foo.js", 1) => "Foo2.html"
|
50
|
+
# html_filename("Foo.js", 2) => "Foo3.html"
|
51
|
+
#
|
52
|
+
def html_filename(filename, nr=0)
|
53
|
+
::File.basename(filename, ".js") + (nr > 0 ? (nr+1).to_s : "") + ".html"
|
54
|
+
end
|
55
|
+
|
56
|
+
def write_single(filename, source)
|
57
|
+
::File.open(filename, 'w') {|f| f.write(wrap_page(source)) }
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns source wrapped inside HTML page
|
61
|
+
def wrap_page(source)
|
62
|
+
return <<-EOHTML
|
63
|
+
<!DOCTYPE html>
|
64
|
+
<html>
|
65
|
+
<head>
|
66
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
67
|
+
<title>The source code</title>
|
68
|
+
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
|
69
|
+
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
|
70
|
+
<style type="text/css">
|
71
|
+
.highlight { display: block; background-color: #ddd; }
|
72
|
+
</style>
|
73
|
+
<script type="text/javascript">
|
74
|
+
function highlight() {
|
75
|
+
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
76
|
+
}
|
77
|
+
</script>
|
78
|
+
</head>
|
79
|
+
<body onload="prettyPrint(); highlight();">
|
80
|
+
<pre class="prettyprint lang-js">#{source}</pre>
|
81
|
+
</body>
|
82
|
+
</html>
|
83
|
+
EOHTML
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
data/lib/jsduck/tag/aside.rb
CHANGED
data/lib/jsduck/tag/since.rb
CHANGED
@@ -11,7 +11,7 @@ module JsDuck::Tag
|
|
11
11
|
|
12
12
|
def to_value(contents)
|
13
13
|
if contents.length > 1
|
14
|
-
JsDuck::Logger.
|
14
|
+
JsDuck::Logger.warn(nil, "Only one @since tag allowed per class/member.")
|
15
15
|
end
|
16
16
|
contents[0]
|
17
17
|
end
|
data/lib/jsduck/template_dir.rb
CHANGED
@@ -21,10 +21,10 @@ module JsDuck
|
|
21
21
|
def write
|
22
22
|
FileUtils.mkdir(@opts.output_dir)
|
23
23
|
if @opts.template_links
|
24
|
-
Logger.
|
24
|
+
Logger.log("Linking template files to", @opts.output_dir)
|
25
25
|
move_files(:symlink)
|
26
26
|
else
|
27
|
-
Logger.
|
27
|
+
Logger.log("Copying template files to", @opts.output_dir)
|
28
28
|
move_files(:cp_r)
|
29
29
|
end
|
30
30
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module JsDuck
|
4
|
+
module Util
|
5
|
+
|
6
|
+
# Helpers for dealing with HTML
|
7
|
+
class HTML
|
8
|
+
|
9
|
+
# Strips tags from HTML text
|
10
|
+
def self.strip_tags(html)
|
11
|
+
html.gsub(/<.*?>/, "")
|
12
|
+
end
|
13
|
+
|
14
|
+
# Escapes HTML, replacing < with < ...
|
15
|
+
def self.escape(html)
|
16
|
+
CGI.escapeHTML(html)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Unescapes HTML, replacing < with < ...
|
20
|
+
def self.unescape(html)
|
21
|
+
CGI.unescapeHTML(html)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module JsDuck
|
2
|
+
module Util
|
3
|
+
|
4
|
+
# A helper to use instead the builtin IO class to read files in
|
5
|
+
# correct encoding.
|
6
|
+
#
|
7
|
+
# By default in Ruby 1.9 the encoding is auto-detected, which can
|
8
|
+
# have surprising results. So in here we read in all files in UTF-8
|
9
|
+
# (the default) or in some other encoding specified through --encoding
|
10
|
+
# option and convert it to UTF-8 internally.
|
11
|
+
class IO
|
12
|
+
@@encoding = "UTF-8"
|
13
|
+
|
14
|
+
# Sets the external encoding to be used for reading files.
|
15
|
+
# When it's different from UTF-8, the input will be converted to UTF-8.
|
16
|
+
def self.encoding=(e)
|
17
|
+
if e =~ /^UTF-8$/i
|
18
|
+
@@encoding = e
|
19
|
+
else
|
20
|
+
@@encoding = e+":UTF-8"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Reads given filename into string
|
25
|
+
def self.read(filename)
|
26
|
+
File.open(filename, "r:"+@@encoding) {|f| f.read }
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'jsduck/util/singleton'
|
2
|
+
require 'jsduck/util/io'
|
3
|
+
require 'jsduck/logger'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module JsDuck
|
7
|
+
module Util
|
8
|
+
|
9
|
+
# Wrapper around the json gem for use in JsDuck.
|
10
|
+
#
|
11
|
+
# The main benefit of it is that we have a central place for
|
12
|
+
# controlling how the JSON is created (pretty-formatted or not).
|
13
|
+
class Json
|
14
|
+
include Util::Singleton
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@pretty = false
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set to true to turn on pretty-formatting of JSON
|
21
|
+
def pretty=(pretty)
|
22
|
+
@pretty = pretty
|
23
|
+
end
|
24
|
+
|
25
|
+
# Turns object into JSON, places it inside JavaScript that calls the
|
26
|
+
# given callback name, and writes the result to file.
|
27
|
+
def write_jsonp(filename, callback_name, data)
|
28
|
+
jsonp = "Ext.data.JsonP." + callback_name + "(" + generate(data) + ");"
|
29
|
+
File.open(filename, 'w') {|f| f.write(jsonp) }
|
30
|
+
end
|
31
|
+
|
32
|
+
# Turns object into JSON and writes inside a file
|
33
|
+
def write_json(filename, data)
|
34
|
+
File.open(filename, 'w') {|f| f.write(generate(data)) }
|
35
|
+
end
|
36
|
+
|
37
|
+
# Generates JSON from object
|
38
|
+
def generate(data)
|
39
|
+
@pretty ? JSON.pretty_generate(data) : JSON.generate(data)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Reads and parses JSON from file
|
43
|
+
def read(filename)
|
44
|
+
begin
|
45
|
+
parse(Util::IO.read(filename))
|
46
|
+
rescue
|
47
|
+
Logger.fatal("#{filename} is not a valid JSON file")
|
48
|
+
exit(1)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Parses JSON string
|
53
|
+
def parse(string, opts = {})
|
54
|
+
JSON.parse(string, opts)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module JsDuck
|
2
|
+
module Util
|
3
|
+
|
4
|
+
# A class that does nothing.
|
5
|
+
# Responds to all methods by returning self, unless a hash passed to
|
6
|
+
# constructor.
|
7
|
+
# See: http://en.wikipedia.org/wiki/Null_Object_pattern
|
8
|
+
class NullObject
|
9
|
+
# Optionally takes a hash of method_name => return_value pairs,
|
10
|
+
# making it return those values for those methods, sort of like
|
11
|
+
# OpenStruct, but for all other methods self is still returned and
|
12
|
+
# any number of arguments is accepted.
|
13
|
+
def initialize(methods={})
|
14
|
+
@methods = methods
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing(meth, *args, &block)
|
18
|
+
@methods.has_key?(meth) ? @methods[meth] : self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'parallel'
|
2
|
+
|
3
|
+
module JsDuck
|
4
|
+
module Util
|
5
|
+
|
6
|
+
# Wrapper around the parallel gem that falls back to simple
|
7
|
+
# Array#map and Array#each when :in_processes => 0 specified.
|
8
|
+
class Parallel
|
9
|
+
@@in_processes = nil
|
10
|
+
|
11
|
+
# Sets globally the nr of processes to use.
|
12
|
+
def self.in_processes=(n)
|
13
|
+
@@in_processes = n
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.each(arr, &block)
|
17
|
+
if @@in_processes == 0
|
18
|
+
arr.each &block
|
19
|
+
else
|
20
|
+
::Parallel.each(arr, {:in_processes => @@in_processes}, &block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.map(arr, &block)
|
25
|
+
if @@in_processes == 0
|
26
|
+
arr.map &block
|
27
|
+
else
|
28
|
+
::Parallel.map(arr, {:in_processes => @@in_processes}, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module JsDuck
|
4
|
+
module Util
|
5
|
+
|
6
|
+
# A more convenient Singleton implementation.
|
7
|
+
#
|
8
|
+
# With the standard ruby Singleton you need to call the methods of
|
9
|
+
# your singleton instance as follows:
|
10
|
+
#
|
11
|
+
# MyClass.instance.my_method()
|
12
|
+
#
|
13
|
+
# But with JsDuck::Util::Singleton you can skip the .instance. part:
|
14
|
+
#
|
15
|
+
# MyClass.my_method()
|
16
|
+
#
|
17
|
+
# This also conveniently hides from the calling code the fact that
|
18
|
+
# a class is implemented as Singleton - it could just as well only
|
19
|
+
# have static methods.
|
20
|
+
#
|
21
|
+
module Singleton
|
22
|
+
def self.included(base)
|
23
|
+
base.class_eval do
|
24
|
+
include ::Singleton
|
25
|
+
|
26
|
+
# Redirect calls from MyClass.method to MyClass.instance.method
|
27
|
+
def self.method_missing(meth, *args, &block)
|
28
|
+
self.instance.send(meth, *args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'jsduck/util/json'
|
2
|
+
require 'jsduck/util/singleton'
|
3
|
+
|
4
|
+
module JsDuck
|
5
|
+
module Util
|
6
|
+
|
7
|
+
# Central place for buffering JSON data that's meant to be written to STDOUT
|
8
|
+
class Stdout
|
9
|
+
include Util::Singleton
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@data = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# Adds array of new data
|
16
|
+
def add(data)
|
17
|
+
if @data
|
18
|
+
@data += data
|
19
|
+
else
|
20
|
+
@data = data
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Writes data to STDOUT in JSON format,
|
25
|
+
# but only if some data was added.
|
26
|
+
def flush
|
27
|
+
puts Util::Json.generate(@data) if @data
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
data/lib/jsduck/videos.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'jsduck/
|
2
|
-
require 'jsduck/null_object'
|
1
|
+
require 'jsduck/util/json'
|
2
|
+
require 'jsduck/util/null_object'
|
3
3
|
require 'jsduck/grouped_asset'
|
4
4
|
|
5
5
|
module JsDuck
|
@@ -11,14 +11,14 @@ module JsDuck
|
|
11
11
|
if filename
|
12
12
|
Videos.new(filename)
|
13
13
|
else
|
14
|
-
NullObject.new(:to_array => [], :[] => nil)
|
14
|
+
Util::NullObject.new(:to_array => [], :[] => nil)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
def initialize(filename)
|
19
|
-
@groups =
|
19
|
+
@groups = Util::Json.read(filename)
|
20
20
|
add_names_if_missing
|
21
|
-
build_map_by_name
|
21
|
+
build_map_by_name
|
22
22
|
end
|
23
23
|
|
24
24
|
# Each video should have a name, which is used in URL to reference the video.
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'jsduck/exporter/app'
|
2
|
+
require 'jsduck/batch_formatter'
|
3
|
+
require 'jsduck/template_dir'
|
4
|
+
require 'jsduck/index_html'
|
5
|
+
require 'jsduck/app_data'
|
6
|
+
require 'jsduck/class_writer'
|
7
|
+
require 'jsduck/source/writer'
|
8
|
+
require 'jsduck/inline_examples'
|
9
|
+
require 'fileutils'
|
10
|
+
|
11
|
+
module JsDuck
|
12
|
+
|
13
|
+
# Performs the generation of docs web app.
|
14
|
+
class WebWriter
|
15
|
+
def initialize(relations, assets, parsed_files, opts)
|
16
|
+
@relations = relations
|
17
|
+
@assets = assets
|
18
|
+
@parsed_files = parsed_files
|
19
|
+
@opts = opts
|
20
|
+
end
|
21
|
+
|
22
|
+
def write
|
23
|
+
clean_output_dir
|
24
|
+
|
25
|
+
write_template_files
|
26
|
+
write_app_data
|
27
|
+
|
28
|
+
# class-formatting is done in parallel which breaks the links
|
29
|
+
# between source files and classes. Therefore it MUST to be done
|
30
|
+
# after writing sources which needs the links to work.
|
31
|
+
write_source if @opts.source
|
32
|
+
format_classes
|
33
|
+
|
34
|
+
write_inline_examples if @opts.tests
|
35
|
+
|
36
|
+
write_classes
|
37
|
+
|
38
|
+
@assets.write
|
39
|
+
end
|
40
|
+
|
41
|
+
def write_template_files
|
42
|
+
TemplateDir.new(@opts).write
|
43
|
+
IndexHtml.new(@assets, @opts).write
|
44
|
+
end
|
45
|
+
|
46
|
+
def write_app_data
|
47
|
+
AppData.new(@relations, @assets, @opts).write(@opts.output_dir+"/data.js")
|
48
|
+
end
|
49
|
+
|
50
|
+
def write_source
|
51
|
+
source_writer = Source::Writer.new(@parsed_files)
|
52
|
+
source_writer.write(@opts.output_dir + "/source")
|
53
|
+
end
|
54
|
+
|
55
|
+
def write_inline_examples
|
56
|
+
examples = InlineExamples.new
|
57
|
+
examples.add_classes(@relations)
|
58
|
+
examples.add_guides(@assets.guides)
|
59
|
+
examples.write(@opts.output_dir+"/inline-examples.js")
|
60
|
+
end
|
61
|
+
|
62
|
+
def write_classes
|
63
|
+
class_writer = ClassWriter.new(Exporter::App, @relations, @opts)
|
64
|
+
class_writer.write(@opts.output_dir+"/output", ".js")
|
65
|
+
end
|
66
|
+
|
67
|
+
# -- util routines --
|
68
|
+
|
69
|
+
def clean_output_dir
|
70
|
+
FileUtils.rm_rf(@opts.output_dir)
|
71
|
+
end
|
72
|
+
|
73
|
+
def format_classes
|
74
|
+
BatchFormatter.format_all!(@relations, @assets, @opts)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|