pdoc 0.2.0
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/README.markdown +34 -0
- data/Rakefile +46 -0
- data/bin/pdoc +58 -0
- data/lib/pdoc.rb +32 -0
- data/lib/pdoc/error.rb +4 -0
- data/lib/pdoc/generators.rb +6 -0
- data/lib/pdoc/generators/abstract_generator.rb +16 -0
- data/lib/pdoc/generators/html.rb +8 -0
- data/lib/pdoc/generators/html/helpers.rb +256 -0
- data/lib/pdoc/generators/html/page.rb +71 -0
- data/lib/pdoc/generators/html/syntax_highlighter.rb +41 -0
- data/lib/pdoc/generators/html/template.rb +37 -0
- data/lib/pdoc/generators/html/website.rb +194 -0
- data/lib/pdoc/generators/json.rb +15 -0
- data/lib/pdoc/generators/pythonesque.rb +105 -0
- data/lib/pdoc/models.rb +47 -0
- data/lib/pdoc/models/argument.rb +37 -0
- data/lib/pdoc/models/base.rb +107 -0
- data/lib/pdoc/models/callable.rb +19 -0
- data/lib/pdoc/models/class.rb +28 -0
- data/lib/pdoc/models/class_method.rb +18 -0
- data/lib/pdoc/models/class_property.rb +9 -0
- data/lib/pdoc/models/constant.rb +9 -0
- data/lib/pdoc/models/constructor.rb +14 -0
- data/lib/pdoc/models/container.rb +114 -0
- data/lib/pdoc/models/entity.rb +54 -0
- data/lib/pdoc/models/instance_method.rb +18 -0
- data/lib/pdoc/models/instance_property.rb +9 -0
- data/lib/pdoc/models/mixin.rb +10 -0
- data/lib/pdoc/models/namespace.rb +10 -0
- data/lib/pdoc/models/root.rb +27 -0
- data/lib/pdoc/models/section.rb +19 -0
- data/lib/pdoc/models/signature.rb +27 -0
- data/lib/pdoc/models/utility.rb +11 -0
- data/lib/pdoc/parser.rb +109 -0
- data/lib/pdoc/parser/argument_description_nodes.rb +21 -0
- data/lib/pdoc/parser/basic_nodes.rb +31 -0
- data/lib/pdoc/parser/description_nodes.rb +42 -0
- data/lib/pdoc/parser/documentation_nodes.rb +483 -0
- data/lib/pdoc/parser/ebnf_arguments_nodes.rb +58 -0
- data/lib/pdoc/parser/ebnf_expression_nodes.rb +227 -0
- data/lib/pdoc/parser/fragment.rb +55 -0
- data/lib/pdoc/parser/section_content_nodes.rb +19 -0
- data/lib/pdoc/parser/tags_nodes.rb +14 -0
- data/lib/pdoc/parser/treetop_files/argument_description.treetop +31 -0
- data/lib/pdoc/parser/treetop_files/basic.treetop +41 -0
- data/lib/pdoc/parser/treetop_files/description.treetop +7 -0
- data/lib/pdoc/parser/treetop_files/documentation.treetop +75 -0
- data/lib/pdoc/parser/treetop_files/ebnf_arguments.treetop +33 -0
- data/lib/pdoc/parser/treetop_files/ebnf_expression.treetop +70 -0
- data/lib/pdoc/parser/treetop_files/ebnf_javascript.treetop +54 -0
- data/lib/pdoc/parser/treetop_files/events.treetop +17 -0
- data/lib/pdoc/parser/treetop_files/section_content.treetop +8 -0
- data/lib/pdoc/parser/treetop_files/tags.treetop +31 -0
- data/lib/pdoc/runner.rb +110 -0
- data/lib/pdoc/treemaker.rb +94 -0
- data/pdoc.gemspec +31 -0
- data/templates/html/assets/images/pdoc/alias.png +0 -0
- data/templates/html/assets/images/pdoc/class.png +0 -0
- data/templates/html/assets/images/pdoc/class_deprecated.png +0 -0
- data/templates/html/assets/images/pdoc/class_method.png +0 -0
- data/templates/html/assets/images/pdoc/class_property.png +0 -0
- data/templates/html/assets/images/pdoc/constant.png +0 -0
- data/templates/html/assets/images/pdoc/constructor.png +0 -0
- data/templates/html/assets/images/pdoc/deprecated.png +0 -0
- data/templates/html/assets/images/pdoc/description.png +0 -0
- data/templates/html/assets/images/pdoc/information.png +0 -0
- data/templates/html/assets/images/pdoc/instance_method.png +0 -0
- data/templates/html/assets/images/pdoc/instance_property.png +0 -0
- data/templates/html/assets/images/pdoc/method.png +0 -0
- data/templates/html/assets/images/pdoc/method_deprecated.png +0 -0
- data/templates/html/assets/images/pdoc/mixin.png +0 -0
- data/templates/html/assets/images/pdoc/namespace.png +0 -0
- data/templates/html/assets/images/pdoc/property.png +0 -0
- data/templates/html/assets/images/pdoc/related_to.png +0 -0
- data/templates/html/assets/images/pdoc/search-background.png +0 -0
- data/templates/html/assets/images/pdoc/section-background.png +0 -0
- data/templates/html/assets/images/pdoc/section.png +0 -0
- data/templates/html/assets/images/pdoc/selected-section-background.png +0 -0
- data/templates/html/assets/images/pdoc/subclass.png +0 -0
- data/templates/html/assets/images/pdoc/superclass.png +0 -0
- data/templates/html/assets/images/pdoc/utility.png +0 -0
- data/templates/html/assets/javascripts/pdoc/application.js +478 -0
- data/templates/html/assets/javascripts/pdoc/prototype.js +4874 -0
- data/templates/html/assets/javascripts/pdoc/tabs.js +506 -0
- data/templates/html/assets/stylesheets/pdoc/api.css +677 -0
- data/templates/html/assets/stylesheets/pdoc/pygments.css +62 -0
- data/templates/html/helpers.rb +35 -0
- data/templates/html/index.erb +18 -0
- data/templates/html/item_index.js.erb +6 -0
- data/templates/html/layout.erb +67 -0
- data/templates/html/leaf.erb +22 -0
- data/templates/html/node.erb +30 -0
- data/templates/html/partials/class_relationships.erb +19 -0
- data/templates/html/partials/classes.erb +7 -0
- data/templates/html/partials/constructor.erb +5 -0
- data/templates/html/partials/description.erb +5 -0
- data/templates/html/partials/link_list.erb +1 -0
- data/templates/html/partials/method_signatures.erb +14 -0
- data/templates/html/partials/methodized_note.erb +9 -0
- data/templates/html/partials/mixins.erb +7 -0
- data/templates/html/partials/namespaces.erb +7 -0
- data/templates/html/partials/related_utilities.erb +5 -0
- data/templates/html/partials/relationships.erb +11 -0
- data/templates/html/partials/short_description_list.erb +7 -0
- data/templates/html/partials/title.erb +22 -0
- data/templates/html/section.erb +18 -0
- data/test/unit/parser/argument_description_test.rb +40 -0
- data/test/unit/parser/basic_test.rb +55 -0
- data/test/unit/parser/description_test.rb +34 -0
- data/test/unit/parser/documentation_test.rb +520 -0
- data/test/unit/parser/ebnf_arguments_test.rb +81 -0
- data/test/unit/parser/ebnf_expression_test.rb +382 -0
- data/test/unit/parser/ebnf_javascript_test.rb +37 -0
- data/test/unit/parser/events_test.rb +27 -0
- data/test/unit/parser/section_content_test.rb +44 -0
- data/test/unit/parser/tags_test.rb +39 -0
- data/test/unit/parser/test_fragment.rb +80 -0
- data/test/unit/parser_test_helper.rb +62 -0
- data/test/unit/runner/basic_test.rb +14 -0
- data/test/unit/templates/html_helpers_test.rb +25 -0
- metadata +222 -0
data/README.markdown
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
PDoc
|
|
2
|
+
====
|
|
3
|
+
|
|
4
|
+
PDoc is an inline comment parser and JavaScript documentation generator written in Ruby. It is designed for documenting [Prototype](http://prototypejs.org) and Prototype-based libraries.
|
|
5
|
+
|
|
6
|
+
PDoc uses [Treetop](http://treetop.rubyforge.org/), a Ruby-based DSL for text parsing and interpretation, and its own ActionView-inspired, ERB-based templating system for HTML generation. Other documentation generators (e.g., DocBook XML) are planned.
|
|
7
|
+
|
|
8
|
+
Unlike other inline-doc parsers, PDoc does not rely on the JavaScript source code at all; it only parses the comments. This approach, though slightly more verbose, is much better at generating consistent, reliable documentation, and avoids the headaches encountered when documenting highly dynamic languages.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
PDoc depends on Rake, your choice of markdown parser, and treetop, all of which can be obtained through RubyGems:
|
|
13
|
+
|
|
14
|
+
gem install rake bluecloth treetop
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
For hints on how to run PDoc on the command line, consult the built-in Rake tasks (in `Rakefile`) and the `PDoc::Runner` class (in `lib/pdoc/runner.rb`).
|
|
19
|
+
|
|
20
|
+
## How it works
|
|
21
|
+
|
|
22
|
+
The process of turning inline PDoc comments into a human-friendly document has two phases.
|
|
23
|
+
|
|
24
|
+
### Parsing phase
|
|
25
|
+
In this phase, the source files are scanned for PDoc comments, then parsed with the Ruby files generated from the Treetop language grammar. The product of this phase is a tree full of specialized classes, all of which inherit from `Treetop::Runtime::SyntaxNode`.
|
|
26
|
+
|
|
27
|
+
The root of the tree is an instance of `Documentation::Doc`. It comprises one or more instances of `Documentation::Section`; which in turn comprise language elements like namespaces, classes, constants, etc., all of which have class representations.
|
|
28
|
+
|
|
29
|
+
### Rendering phase
|
|
30
|
+
Next, PDoc asks a _generator_ how to translate this abstract tree into a hierarchical document. The default generator outputs organized HTML in a manner similar to [RDoc](http://rdoc.sourceforge.net/ "RDoc - Document Generator for Ruby Source")'s.
|
|
31
|
+
|
|
32
|
+
The HTML generator (`PDoc::Generators::Html`) has associated _templates_ (in the `templates` directory) that accept syntax nodes and echo their metadata onto the page using [ERB](http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/index.html "erb: Ruby Standard Library Documentation"). Templates are modular, so it's quite easy to apply a custom "skin" to one's documentation pages.
|
|
33
|
+
|
|
34
|
+
Furthermore, generators themselves are modular; PDoc can, theoretically, parse once and render to several different targets (HTML, [DocBook XML](http://www.docbook.org/ "DocBook.org"), CHM, PDF, even [ScriptDoc](http://www.scriptdoc.org/ "ScriptDoc.org: Dynamic Language Documentation").) We hope many such generators will exist in the future.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'lib/pdoc'
|
|
3
|
+
|
|
4
|
+
desc "Builds the documentation"
|
|
5
|
+
task :build_doc do
|
|
6
|
+
PDoc.run({
|
|
7
|
+
:source_files => [File.join(File.dirname(__FILE__), "test", "fixtures", "ajax.js")],
|
|
8
|
+
:destination => OUTPUT_DIR,
|
|
9
|
+
:syntax_highlighter => :pygments,
|
|
10
|
+
:markdown_parser => :bluecloth,
|
|
11
|
+
:src_code_href => proc { |file, line|
|
|
12
|
+
"http://github.com/example/ex/#{file}##{line}"
|
|
13
|
+
},
|
|
14
|
+
:pretty_urls => false,
|
|
15
|
+
:bust_cache => true,
|
|
16
|
+
:name => 'Example JavaScript Framework',
|
|
17
|
+
:short_name => 'Ex',
|
|
18
|
+
:home_url => 'http://example.com',
|
|
19
|
+
:doc_url => 'http://example.com/api',
|
|
20
|
+
:version => "1.2.0",
|
|
21
|
+
:copyright_notice => 'This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0 Unported License</a>.'
|
|
22
|
+
})
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
desc "Empties output directory"
|
|
26
|
+
task :remove_doc do
|
|
27
|
+
rm_rf Dir.glob(File.join(OUTPUT_DIR, "*"))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
desc "Empties the output directory and builds the documentation."
|
|
31
|
+
task :doc => [:remove_doc, :build_doc]
|
|
32
|
+
|
|
33
|
+
desc "Runs all the unit tests."
|
|
34
|
+
task :test do
|
|
35
|
+
require 'rake/runtest'
|
|
36
|
+
Rake.run_tests '**/*_test.rb'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
task :compile_parser do
|
|
40
|
+
require 'treetop'
|
|
41
|
+
compiler = Treetop::Compiler::GrammarCompiler.new
|
|
42
|
+
treetop_dir = File.expand_path(File.join(File.dirname(__FILE__), "lib", "pdoc", "parser", "treetop_files"))
|
|
43
|
+
Dir.glob(File.join(treetop_dir, "*.treetop")).each do |treetop_file_path|
|
|
44
|
+
compiler.compile(treetop_file_path)
|
|
45
|
+
end
|
|
46
|
+
end
|
data/bin/pdoc
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
require 'oyster'
|
|
4
|
+
require File.dirname(__FILE__) + '/../lib/pdoc'
|
|
5
|
+
|
|
6
|
+
spec = Oyster.spec do
|
|
7
|
+
name "pdoc -- Inline comment parser and JavaScript documentation generator"
|
|
8
|
+
author "Tobie Langel <tobie.langel@gmail.com>"
|
|
9
|
+
|
|
10
|
+
synopsis <<-EOS
|
|
11
|
+
pdoc [-o OUTPUT_DIR] [-t TEMPLATE_DIR] SOURCE_FILES
|
|
12
|
+
pdoc [OPTIONS] -d SOURCE_DIRECTORY
|
|
13
|
+
EOS
|
|
14
|
+
|
|
15
|
+
string :directory,
|
|
16
|
+
:desc => "Directory to search for JavaScript files. Will take all *.js " +
|
|
17
|
+
"files from the given directory (including subdirectories) and use " +
|
|
18
|
+
"them to generate documentation. This option takes precedence over " +
|
|
19
|
+
"SOURCE_FILES."
|
|
20
|
+
|
|
21
|
+
string :output,
|
|
22
|
+
:desc => "Directory in which to dump output files",
|
|
23
|
+
:default => "pdoc"
|
|
24
|
+
|
|
25
|
+
string :templates,
|
|
26
|
+
:desc => "Directory containing template files"
|
|
27
|
+
|
|
28
|
+
subcommand :'copy-templates' do
|
|
29
|
+
synopsis <<-EOS
|
|
30
|
+
pdoc copy-templates TYPE DESTINATION
|
|
31
|
+
EOS
|
|
32
|
+
|
|
33
|
+
description <<-EOS
|
|
34
|
+
PDoc includes a set of default templates for each type of output generator.
|
|
35
|
+
This command lets you extract a set of these templates into a local directory
|
|
36
|
+
so you can tweak it to suit your needs. Be sure to specify your set of
|
|
37
|
+
templates next time you run pdoc.
|
|
38
|
+
EOS
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
begin; options = spec.parse
|
|
43
|
+
rescue Oyster::HelpRendered; exit
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if command = options[:'copy-templates']
|
|
47
|
+
args = command[:unclaimed]
|
|
48
|
+
PDoc.copy_templates(args[0], File.expand_path(args[1]))
|
|
49
|
+
exit
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
files = (d = options[:directory]) ?
|
|
53
|
+
Dir["#{d}/**/*.js"].map(&File.method(:expand_path)) :
|
|
54
|
+
options[:unclaimed].dup
|
|
55
|
+
|
|
56
|
+
files << {:destination => options[:output], :templates => options[:templates]}
|
|
57
|
+
PDoc::Runner.new(*files).run
|
|
58
|
+
|
data/lib/pdoc.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
DIR = File.expand_path(File.dirname(__FILE__))
|
|
2
|
+
OUTPUT_DIR = File.join(DIR, '..', 'output')
|
|
3
|
+
TEMPLATES_DIR = File.join(DIR, '..', 'templates')
|
|
4
|
+
VENDOR_DIR = File.join(DIR, '..', 'vendor')
|
|
5
|
+
PARSER_DIR = File.join(DIR, 'pdoc', 'parser')
|
|
6
|
+
|
|
7
|
+
[DIR, VENDOR_DIR, PARSER_DIR, OUTPUT_DIR, TEMPLATES_DIR].each do |c|
|
|
8
|
+
$:.unshift(c)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
require 'rubygems'
|
|
12
|
+
require 'erb'
|
|
13
|
+
require 'fileutils'
|
|
14
|
+
|
|
15
|
+
require 'pdoc/error'
|
|
16
|
+
require 'pdoc/runner'
|
|
17
|
+
require 'pdoc/generators'
|
|
18
|
+
require 'pdoc/parser'
|
|
19
|
+
require 'pdoc/models'
|
|
20
|
+
require 'pdoc/treemaker'
|
|
21
|
+
|
|
22
|
+
module PDoc
|
|
23
|
+
def self.run(options = {})
|
|
24
|
+
Runner.new(options.dup).run
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.copy_templates(template_type, destination)
|
|
28
|
+
dir = File.expand_path(destination)
|
|
29
|
+
raise "File already exists: #{destination}" if File.exist?(dir)
|
|
30
|
+
FileUtils.cp_r("#{TEMPLATES_DIR}/#{template_type}", dir)
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/pdoc/error.rb
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'generators', 'abstract_generator'))
|
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'generators', 'html'))
|
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'generators', 'pythonesque'))
|
|
4
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'generators', 'json'))
|
|
5
|
+
|
|
6
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module PDoc
|
|
2
|
+
module Generators
|
|
3
|
+
class AbstractGenerator
|
|
4
|
+
attr_reader :options, :root
|
|
5
|
+
def initialize(root, options = {})
|
|
6
|
+
@root = root
|
|
7
|
+
@options = options
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Creates a new directory with read, write and execute permission.
|
|
11
|
+
def mkdir(name)
|
|
12
|
+
Dir.mkdir(name, 0755)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
HTML_DIR = File.expand_path(File.join(File.dirname(__FILE__), "html"))
|
|
2
|
+
|
|
3
|
+
require File.join(HTML_DIR, "helpers")
|
|
4
|
+
require File.join(HTML_DIR, "template")
|
|
5
|
+
require File.join(HTML_DIR, "page")
|
|
6
|
+
require File.join(HTML_DIR, "website")
|
|
7
|
+
require File.join(HTML_DIR, "syntax_highlighter")
|
|
8
|
+
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
module PDoc
|
|
2
|
+
module Generators
|
|
3
|
+
module Html
|
|
4
|
+
module Helpers
|
|
5
|
+
module BaseHelper
|
|
6
|
+
def content_tag(tag_name, content, attributes = {})
|
|
7
|
+
"<#{tag_name}#{attributes_to_html(attributes)}>#{content}</#{tag_name}>"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def img_tag(filename, attributes = {})
|
|
11
|
+
attributes.merge! :src => "#{path_prefix}images/#{filename}"
|
|
12
|
+
tag(:img, attributes)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def tag(tag_name, attributes = {})
|
|
16
|
+
"<#{tag_name}#{attributes_to_html(attributes)} />"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def link_to(name, path, attributes={})
|
|
20
|
+
content_tag(:a, name, attributes.merge(:href => path))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def htmlize(markdown)
|
|
24
|
+
markdown = Website.syntax_highlighter.parse(markdown)
|
|
25
|
+
Website.markdown_parser.new(markdown).to_html
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Gah, what an ugly hack.
|
|
29
|
+
def inline_htmlize(markdown)
|
|
30
|
+
htmlize(markdown).gsub(/^<p>/, '').gsub(/<\/p>$/, '')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def javascript_include_tag(*names)
|
|
34
|
+
names.map do |name|
|
|
35
|
+
attributes = {
|
|
36
|
+
:src => "#{path_prefix}javascripts/#{name}.js",
|
|
37
|
+
:type => "text/javascript",
|
|
38
|
+
:charset => "utf-8"
|
|
39
|
+
}
|
|
40
|
+
content_tag(:script, "", attributes)
|
|
41
|
+
end.join("\n")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def stylesheet_link_tag(*names)
|
|
45
|
+
names.map do |name|
|
|
46
|
+
attributes = {
|
|
47
|
+
:href => "#{path_prefix}stylesheets/#{name}.css",
|
|
48
|
+
:type => "text/css",
|
|
49
|
+
:media => "screen, projection",
|
|
50
|
+
:charset => "utf-8",
|
|
51
|
+
:rel => "stylesheet"
|
|
52
|
+
}
|
|
53
|
+
tag(:link, attributes)
|
|
54
|
+
end.join("\n")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
def attributes_to_html(attributes)
|
|
59
|
+
attributes = attributes.sort { |a, b| a.to_s <=> b.to_s }
|
|
60
|
+
attributes.map do |a|
|
|
61
|
+
k, v = a
|
|
62
|
+
k ? " #{k}=\"#{v}\"" : ""
|
|
63
|
+
end.join
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
module LinkHelper
|
|
68
|
+
def path_prefix
|
|
69
|
+
"../" * depth
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def path_to(obj)
|
|
73
|
+
path = path_prefix << obj.url << '/'
|
|
74
|
+
Website.pretty_urls? ? path : "#{path}index.html"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def auto_link(obj, options = {})
|
|
78
|
+
if obj.is_a?(String)
|
|
79
|
+
original = obj
|
|
80
|
+
obj = root.find(obj)
|
|
81
|
+
return original unless obj
|
|
82
|
+
end
|
|
83
|
+
name = options.delete(:name) == :short ? obj.name : obj.full_name
|
|
84
|
+
if obj.type == 'section'
|
|
85
|
+
title = obj.full_name
|
|
86
|
+
else
|
|
87
|
+
title = "#{obj.full_name} (#{obj.type})"
|
|
88
|
+
end
|
|
89
|
+
link_to(name, path_to(obj), { :title => title }.merge(options))
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def auto_link_code(obj, options = {})
|
|
93
|
+
"<code>#{auto_link(obj, options)}</code>"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def auto_link_content(content)
|
|
97
|
+
return '' if content.nil?
|
|
98
|
+
content.gsub!(/\[\[([a-zA-Z]+)\s+section\]\]/) do |m|
|
|
99
|
+
result = auto_link(root.find($1), :name => :long)
|
|
100
|
+
result
|
|
101
|
+
end
|
|
102
|
+
content.gsub(/\[\[([a-zA-Z$\.#]+)(?:\s+([^\]]+))?\]\]/) do |m|
|
|
103
|
+
if doc_instance = root.find($1)
|
|
104
|
+
$2 ? link_to($2, path_to(doc_instance)) : auto_link_code(doc_instance, :name => :long)
|
|
105
|
+
else
|
|
106
|
+
$1
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def auto_link_types(types, options = {})
|
|
112
|
+
types = types.split(/\s+\|\s+/) if types.is_a?(String)
|
|
113
|
+
types.map do |t|
|
|
114
|
+
if match = /^\[([\w\d\$\.\(\)#]*[\w\d\$\(\)#])...\s*\]$/.match(t) # e.g.: [Element...]
|
|
115
|
+
"[#{auto_link(match[1], options)}…]"
|
|
116
|
+
else
|
|
117
|
+
auto_link(t, options)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def dom_id(obj)
|
|
123
|
+
"#{obj.id}-#{obj.type.gsub(/\s+/, '_')}"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
module CodeHelper
|
|
128
|
+
def methodize_signature(sig)
|
|
129
|
+
sig.sub(/\.([\w\d\$]+)\((.*?)(,\s*|\))/) do
|
|
130
|
+
first_arg = $2.to_s.strip
|
|
131
|
+
prefix = first_arg[-1, 1] == '[' ? '([' : '('
|
|
132
|
+
rest = $3 == ')' ? $3 : ''
|
|
133
|
+
"##{$1}#{prefix}#{rest}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def methodize_full_name(obj)
|
|
138
|
+
obj.full_name.sub(/\.([^.]+)$/, '#\1')
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def method_synopsis(object)
|
|
142
|
+
result = []
|
|
143
|
+
object.signatures.each do |signature|
|
|
144
|
+
if return_value = signature.return_value
|
|
145
|
+
types = auto_link_types(return_value, :name => :long).join(' | ')
|
|
146
|
+
result << "#{signature.name} → #{types}"
|
|
147
|
+
else # Constructors
|
|
148
|
+
result << signature.name
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
result
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def breadcrumb(obj, options = {})
|
|
155
|
+
options = {:name => :short}.merge(options)
|
|
156
|
+
result = []
|
|
157
|
+
begin
|
|
158
|
+
result << auto_link(obj, options.dup)
|
|
159
|
+
obj = obj.parent
|
|
160
|
+
end until obj.is_a?(Models::Root)
|
|
161
|
+
result.reverse!
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
module MenuHelper
|
|
166
|
+
NODES = [
|
|
167
|
+
:namespaces,
|
|
168
|
+
:classes,
|
|
169
|
+
:mixins,
|
|
170
|
+
:utilities
|
|
171
|
+
]
|
|
172
|
+
LEAVES = [
|
|
173
|
+
:constants,
|
|
174
|
+
:class_methods,
|
|
175
|
+
:class_properties,
|
|
176
|
+
:instance_methods,
|
|
177
|
+
:instance_properties
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
def menu(obj)
|
|
181
|
+
if obj.parent
|
|
182
|
+
html = menu_item(obj, :name => :long)
|
|
183
|
+
|
|
184
|
+
html << node_submenu(obj)
|
|
185
|
+
|
|
186
|
+
if obj == doc_instance && obj.respond_to?(:constants)
|
|
187
|
+
html << leaf_submenu(obj)
|
|
188
|
+
elsif doc_instance && doc_instance.respond_to?(:parent)
|
|
189
|
+
parent = doc_instance.parent
|
|
190
|
+
html << leaf_submenu(parent) if parent == obj && obj.respond_to?(:constants)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
content_tag(:li, html)
|
|
194
|
+
else #root
|
|
195
|
+
node_submenu(obj)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def node_submenu(obj)
|
|
200
|
+
children = []
|
|
201
|
+
options = {}
|
|
202
|
+
|
|
203
|
+
NODES.each do |prop|
|
|
204
|
+
children.concat(obj.send(prop)) if obj.respond_to?(prop)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
list_items = children.sort.map { |item| menu(item) }
|
|
208
|
+
if obj.respond_to?(:sections)
|
|
209
|
+
obj.sections.each { |section| list_items << menu(section) }
|
|
210
|
+
options[:class] = "menu-items"
|
|
211
|
+
options[:id] = "api_menu"
|
|
212
|
+
elsif obj.type == "section"
|
|
213
|
+
options[:class] = "menu-section"
|
|
214
|
+
end
|
|
215
|
+
list_items.empty? ? '' : content_tag(:ul, list_items.join("\n"), options)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def menu_item(obj, options = {})
|
|
219
|
+
options = options.dup
|
|
220
|
+
options[:class] = class_names_for(obj, options)
|
|
221
|
+
content_tag(:div, auto_link(obj, options), :class => 'menu-item')
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def leaf_submenu(obj)
|
|
225
|
+
items = []
|
|
226
|
+
if obj.respond_to?(:constructor) && obj.constructor
|
|
227
|
+
items << content_tag(:li, menu_item(obj.constructor, :name => :short))
|
|
228
|
+
end
|
|
229
|
+
LEAVES.each do |prop|
|
|
230
|
+
if obj.respond_to?(prop)
|
|
231
|
+
obj.send(prop).sort!.map do |item|
|
|
232
|
+
items << content_tag(:li, menu_item(item, :name => :short))
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
content_tag(:ul, items.join("\n"))
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def class_names_for(obj, options = {})
|
|
240
|
+
classes = []
|
|
241
|
+
classes << obj.type.gsub(/\s+/, '-')
|
|
242
|
+
classes << "deprecated" if obj.deprecated?
|
|
243
|
+
if doc_instance
|
|
244
|
+
if obj == doc_instance
|
|
245
|
+
classes << "current"
|
|
246
|
+
elsif obj.ancestor_of?(doc_instance)
|
|
247
|
+
classes << "current-parent"
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
classes.join(' ')
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|