Skip to content

Commit be53133

Browse files
committed
Close to a complete rewrite.
1 parent 42b924c commit be53133

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+625
-585
lines changed

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2008 Tobie Langel
1+
Copyright (c) 2008 - 2010 Tobie Langel
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy
44
of this software and associated documentation files (the "Software"), to deal

lib/pdoc.rb

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
require 'pdoc/runner'
1616
require 'pdoc/generators'
1717
require 'pdoc/parser'
18+
require 'pdoc/models'
19+
require 'pdoc/treemaker'
1820

1921
module PDoc
2022
def self.run(options = {})

lib/pdoc/generators/abstract_generator.rb

+2-6
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,15 @@ module PDoc
22
module Generators
33
class AbstractGenerator
44
attr_reader :options, :root
5-
def initialize(parser_output, options = {})
6-
@root = parser_output
5+
def initialize(root, options = {})
6+
@root = root
77
@options = options
88
end
99

1010
# Creates a new directory with read, write and execute permission.
1111
def mkdir(name)
1212
Dir.mkdir(name, 0755)
1313
end
14-
15-
def log(msg)
16-
puts " #{msg}"
17-
end
1814
end
1915
end
2016
end

lib/pdoc/generators/html/helpers.rb

+72-77
Original file line numberDiff line numberDiff line change
@@ -64,43 +64,35 @@ module LinkHelper
6464
def path_prefix
6565
"../" * depth
6666
end
67-
68-
def path_to(obj, methodized = false)
69-
path_prefix << raw_path_to(obj, methodized)
70-
end
7167

72-
def raw_path_to(obj, methodized = false)
73-
return "#{obj.name.downcase}/" if obj.is_a?(Documentation::Section)
74-
75-
path = [obj.section.name.downcase].concat(obj.namespace_string.downcase.split('.')).join("/")
76-
if obj.is_a?(Documentation::InstanceMethod) || obj.is_a?(Documentation::InstanceProperty)
77-
"#{path}/prototype/#{obj.id.downcase}/"
78-
elsif obj.is_a?(Documentation::KlassMethod)
79-
methodized ? "#{path}/prototype/#{obj.id.downcase}/" : "#{path}/#{obj.id.downcase}/"
80-
else
81-
"#{path}/#{obj.id.downcase}/"
82-
end
68+
def path_to(obj)
69+
path = path_prefix << raw_path_to(obj).join('/')
70+
Website.pretty_urls? ? "#{path}" : "#{path}/index.html"
8371
end
8472

85-
# deprecated
86-
def path_to_section(obj)
87-
"#{obj.name.downcase}/"
73+
def raw_path_to(obj)
74+
result = []
75+
begin
76+
result << obj.name.downcase.sub(' section', '').gsub('$', 'dollar')
77+
if obj.is_a?(Models::InstanceMethod) || obj.is_a?(Models::InstanceProperty)
78+
result << 'prototype'
79+
end
80+
obj = obj.parent
81+
end while obj.respond_to?(:name)
82+
result.reverse
8883
end
89-
90-
def section_from_name(name)
91-
root.sections.find { |section| section.name == name }
92-
end
9384

9485
def auto_link(obj, options = {})
9586
if obj.is_a?(String)
9687
original = obj
97-
obj = root.find_by_name(obj)
88+
obj = root.find(obj)
9889
return original unless obj
9990
end
10091
name = options.delete(:name) == :short ? obj.name : obj.full_name
101-
type = obj.is_a?(Documentation::KlassMethod) && options[:methodized] ? 'instance method' : obj.type
102-
path = path_to(obj, options.delete(:methodized))
103-
link_to(name, path, { :title => "#{obj.full_name} (#{type})" }.merge(options))
92+
path = path_to(obj)
93+
title = obj.full_name
94+
title = "#{title} (#{obj.type})" unless obj.type == 'section'
95+
link_to(name, path, { :title => title }.merge(options))
10496
end
10597

10698
def auto_link_code(obj, options = {})
@@ -110,11 +102,11 @@ def auto_link_code(obj, options = {})
110102
def auto_link_content(content)
111103
return '' if content.nil?
112104
content.gsub!(/\[\[([a-zA-Z]+)\s+section\]\]/) do |m|
113-
result = auto_link(section_from_name($1), :name => :long)
105+
result = auto_link(root.find($1), :name => :long)
114106
result
115107
end
116108
content.gsub(/\[\[([a-zA-Z$\.#]+)(?:\s+([^\]]+))?\]\]/) do |m|
117-
if doc_instance = root.find_by_name($1)
109+
if doc_instance = root.find($1)
118110
$2 ? link_to($2, path_to(doc_instance)) : auto_link_code(doc_instance, :name => :long)
119111
else
120112
$1
@@ -152,101 +144,104 @@ def methodize_full_name(obj)
152144
obj.full_name.sub(/\.([^.]+)$/, '#\1')
153145
end
154146

155-
def method_synopsis(object, methodized = false)
147+
def method_synopsis(object)
156148
result = []
157-
object.ebnf_expressions.each do |ebnf|
158-
if object.is_a?(Documentation::Constructor)
159-
result << "#{object.full_name}#{ebnf.args.text_value}"
160-
else
161-
types = auto_link_types(ebnf.returns, :name => :long).join(' | ')
162-
if object.is_a?(Documentation::KlassMethod) && object.methodized? && methodized
163-
result << "#{methodize_signature(ebnf.signature)} &rarr; #{types}"
164-
else
165-
result << "#{ebnf.signature} &rarr; #{types}"
166-
end
149+
object.signatures.each do |signature|
150+
if return_value = signature.return_value
151+
types = auto_link_types(return_value, :name => :long).join(' | ')
152+
result << "#{signature.name} &rarr; #{types}"
153+
else # Constructors
154+
result << signature.name
167155
end
168156
end
169157
result
170158
end
171159

172160
def breadcrumb(obj, options)
173161
result = []
174-
original_obj = obj
175162
begin
176163
result << auto_link(obj, options)
177-
end while obj = obj.namespace
178-
unless original_obj.is_a?(Documentation::Section)
179-
result << auto_link(original_obj.section, options)
180-
end
164+
obj = obj.parent
165+
end until obj.is_a?(Models::Root)
181166
result.reverse!
182167
end
183168
end
184169

185170
module MenuHelper
171+
NODES = [
172+
:namespaces,
173+
:classes,
174+
:mixins,
175+
:utilities
176+
]
177+
LEAVES = [
178+
:constants,
179+
:class_methods,
180+
:class_properties,
181+
:instance_methods,
182+
:instance_properties
183+
]
184+
186185
def menu(obj)
187186
html = menu_item(obj, :name => :long)
188187

189-
if !obj.children.empty?
190-
list_items = obj.children.map { |n| menu(n) }.join("\n")
191-
li_class_names = obj.type == "section" ? "menu-section" : ""
192-
html << content_tag(:ul, list_items, :class => li_class_names)
193-
elsif obj == doc_instance && obj.respond_to?(:constants)
194-
html << submenu(obj)
195-
elsif doc_instance && doc_instance.respond_to?(:namespace)
196-
namespace = doc_instance.namespace
197-
html << submenu(namespace) if namespace == obj && obj.respond_to?(:constants)
188+
html << node_submenu(obj)
189+
190+
if obj == doc_instance && obj.respond_to?(:constants)
191+
html << leaf_submenu(obj)
192+
elsif doc_instance && doc_instance.respond_to?(:parent)
193+
parent = doc_instance.parent
194+
html << leaf_submenu(parent) if parent == obj && obj.respond_to?(:constants)
198195
end
199196

200197
content_tag(:li, html)
201198
end
202199

200+
def node_submenu(obj)
201+
children = []
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) }.join("\n")
208+
li_class_names = obj.type == "section" ? "menu-section" : ""
209+
content_tag(:ul, list_items, :class => li_class_names)
210+
end
211+
203212
def menu_item(obj, options = {})
204213
options = options.dup
205214
options[:class] = class_names_for(obj, options)
206215
content_tag(:div, auto_link(obj, options), :class => 'menu-item')
207216
end
208217

209-
def submenu(obj)
218+
def leaf_submenu(obj)
210219
items = []
211220
if obj.respond_to?(:constructor) && obj.constructor
212221
items << content_tag(:li, menu_item(obj.constructor, :name => :short))
213222
end
214-
[ :constants,
215-
:klass_methods,
216-
:klass_properties,
217-
].each do |prop|
218-
obj.send(prop).map { |item| items << content_tag(:li, menu_item(item, :name => :short)) }
219-
end
220-
instance_methods = obj.instance_methods.dup
221-
methodized_methods = obj.klass_methods.select { |m| m.methodized? }
222-
instance_methods.concat(methodized_methods)
223-
instance_methods = instance_methods.sort_by { |e| e.name }
224-
instance_methods.map do |item|
225-
items << content_tag(:li, menu_item(item, :name => :short, :methodized => true ))
223+
LEAVES.each do |prop|
224+
if obj.respond_to?(prop)
225+
obj.send(prop).sort!.map do |item|
226+
items << content_tag(:li, menu_item(item, :name => :short))
227+
end
228+
end
226229
end
227-
obj.instance_properties.map { |item| items << content_tag(:li, menu_item(item, :name => :short)) }
228-
229230
content_tag(:ul, items.join("\n"))
230231
end
231232

232233
def class_names_for(obj, options = {})
233234
classes = []
234-
if obj.is_a?(Documentation::KlassMethod) && obj.methodized? && options[:methodized]
235-
classes << 'instance-method'
236-
else
237-
classes << obj.type.gsub(/\s+/, '-')
238-
end
235+
classes << obj.type.gsub(/\s+/, '-')
239236
classes << "deprecated" if obj.deprecated?
240237
if doc_instance
241238
if obj == doc_instance
242239
classes << "current"
243-
elsif doc_instance.namespace == obj ||
244-
obj.descendants.include?(doc_instance) ||
245-
obj.descendants.include?(doc_instance.namespace)
240+
elsif obj.ancestor_of?(doc_instance)
246241
classes << "current-parent"
247242
end
248243
end
249-
classes.join(" ")
244+
classes.join(' ')
250245
end
251246
end
252247
end

lib/pdoc/generators/html/page.rb

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Html
44
class Page
55

66
include Helpers::BaseHelper
7+
include Helpers::LinkHelper
78

89
def initialize(template, layout, variables = {})
910
@template = template

lib/pdoc/generators/html/website.rb

+22-36
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,26 @@ module Html
99
class Website < AbstractGenerator
1010

1111
include Helpers::BaseHelper
12+
include Helpers::LinkHelper
1213

1314
class << Website
1415
attr_accessor :syntax_highlighter
1516
attr_accessor :markdown_parser
17+
def pretty_urls?
18+
!!@pretty_urls
19+
end
20+
21+
def pretty_urls=(boolean)
22+
@pretty_urls = boolean
23+
end
1624
end
1725

1826
def initialize(parser_output, options = {})
1927
super
2028
@templates_directory = File.expand_path(options[:templates] || TEMPLATES_DIRECTORY)
2129
@index_page = options[:index_page] && File.expand_path(options[:index_page])
2230
Website.syntax_highlighter = SyntaxHighlighter.new(options[:syntax_highlighter])
31+
Website.pretty_urls = options[:pretty_urls]
2332
set_markdown_parser(options[:markdown_parser])
2433
load_custom_helpers
2534
end
@@ -79,33 +88,24 @@ def render_index
7988
def render_template(template, var = {})
8089
@depth += 1
8190
doc = var[:doc_instance]
82-
dest = path(doc, var[:methodized])
83-
log "\c[[F\c[[K Rendering: #{dest}"
91+
dest = File.join(*raw_path_to(doc))
92+
puts " Rendering #{dest}..."
8493
FileUtils.mkdir_p(dest)
8594
DocPage.new(template, variables.merge(var)).render_to_file(File.join(dest, 'index.html'))
8695
render_children(doc)
8796
@depth -= 1
8897
end
8998

9099
def render_children(obj)
91-
if obj.is_a?(Documentation::Section)
92-
obj.children.each { |c| is_leaf?(c) ? render_leaf(c) : render_node(c) }
93-
else
94-
obj.children.select { |c| c.namespace === obj }.each(&method(:render_node))
100+
[:namespaces, :classes, :mixins].each do |prop|
101+
obj.send(prop).each(&method(:render_node)) if obj.respond_to?(prop)
95102
end
96103

104+
obj.utilities.each(&method(:render_leaf)) if obj.respond_to?(:utilities)
97105
render_leaf(obj.constructor) if obj.respond_to?(:constructor) && obj.constructor
98106

99-
obj.instance_methods.each(&method(:render_leaf)) if obj.respond_to?(:instance_methods)
100-
obj.instance_properties.each(&method(:render_leaf)) if obj.respond_to?(:instance_properties)
101-
obj.klass_properties.each(&method(:render_leaf)) if obj.respond_to?(:klass_properties)
102-
obj.constants.each(&method(:render_leaf)) if obj.respond_to?(:constants)
103-
104-
if obj.respond_to?(:klass_methods)
105-
obj.klass_methods.each do |m|
106-
render_leaf(m)
107-
render_leaf(m, true) if m.methodized?
108-
end
107+
[:instance_methods, :instance_properties, :class_methods, :class_properties, :constants].each do |prop|
108+
obj.send(prop).each(&method(:render_leaf)) if obj.respond_to?(prop)
109109
end
110110
end
111111

@@ -115,10 +115,10 @@ def copy_assets
115115
FileUtils.cp_r(Dir.glob(File.join(@templates_directory, "assets", "**")), '.')
116116
end
117117

118-
def render_leaf(object, methodized = false)
119-
is_proto_prop = is_proto_prop?(object, methodized)
118+
def render_leaf(object)
119+
is_proto_prop = is_proto_prop?(object)
120120
@depth += 1 if is_proto_prop
121-
render_template('leaf', { :doc_instance => object, :methodized => methodized })
121+
render_template('leaf', { :doc_instance => object })
122122
@depth -= 1 if is_proto_prop
123123
end
124124

@@ -131,23 +131,9 @@ def variables
131131
{:root => root, :depth => @depth, :templates_directory => @templates_directory}
132132
end
133133

134-
def path(object, methodized = false)
135-
return object.name.downcase if object.is_a?(Documentation::Section)
136-
path = [object.section.name.downcase].concat(object.namespace_string.downcase.split('.'))
137-
path << 'prototype' if is_proto_prop?(object, methodized)
138-
File.join(path, object.id)
139-
end
140-
141-
def is_proto_prop?(object, methodized = false)
142-
object.is_a?(Documentation::InstanceMethod) ||
143-
object.is_a?(Documentation::InstanceProperty) ||
144-
(methodized && object.is_a?(Documentation::KlassMethod))
145-
end
146-
147-
def is_leaf?(object)
148-
object.is_a?(Documentation::Method) ||
149-
object.is_a?(Documentation::Property) ||
150-
object.is_a?(Documentation::Constant)
134+
def is_proto_prop?(object)
135+
object.is_a?(Models::InstanceMethod) ||
136+
object.is_a?(Models::InstanceProperty)
151137
end
152138

153139
def index_page_content

0 commit comments

Comments
 (0)