distil 0.11.6 → 0.11.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. data/VERSION +1 -1
  2. data/assets/distil.js +2 -1
  3. data/bin/distil +2 -0
  4. data/distil.gemspec +152 -2
  5. data/lib/distil/configurable.rb +3 -1
  6. data/lib/distil/error-reporter.rb +2 -0
  7. data/lib/distil/product/concatenated.rb +1 -3
  8. data/lib/distil/product/debug.rb +1 -3
  9. data/lib/distil/product/javascript-product.rb +2 -8
  10. data/lib/distil/product.rb +5 -5
  11. data/lib/distil/project/distil-project.rb +18 -1
  12. data/lib/distil/project/external-project.rb +1 -1
  13. data/lib/distil/project/remote-project.rb +39 -0
  14. data/lib/distil/project.rb +18 -9
  15. data/lib/distil/target.rb +13 -12
  16. data/lib/distil/task/css-dependency-task.rb +1 -1
  17. data/lib/distil/task/validate-js-task.rb +6 -1
  18. data/lib/distil.rb +1 -0
  19. data/vendor/pdoc/LICENSE +16 -0
  20. data/vendor/pdoc/PDoc.tmbundle/Commands/Continue PDoc Comment.tmCommand +39 -0
  21. data/vendor/pdoc/PDoc.tmbundle/Macros/Collapse PDoc Blocks.tmMacro +4084 -0
  22. data/vendor/pdoc/PDoc.tmbundle/Macros/Expand PDoc Blocks.tmMacro +1388 -0
  23. data/vendor/pdoc/PDoc.tmbundle/Preferences/PDoc.tmPreferences +50 -0
  24. data/vendor/pdoc/PDoc.tmbundle/Snippets/class.tmSnippet +24 -0
  25. data/vendor/pdoc/PDoc.tmbundle/Snippets/constant.tmSnippet +22 -0
  26. data/vendor/pdoc/PDoc.tmbundle/Snippets/event.tmSnippet +16 -0
  27. data/vendor/pdoc/PDoc.tmbundle/Snippets/method.tmSnippet +22 -0
  28. data/vendor/pdoc/PDoc.tmbundle/Snippets/mixin.tmSnippet +23 -0
  29. data/vendor/pdoc/PDoc.tmbundle/Snippets/namespace.tmSnippet +24 -0
  30. data/vendor/pdoc/PDoc.tmbundle/Snippets/param.tmSnippet +16 -0
  31. data/vendor/pdoc/PDoc.tmbundle/Snippets/property.tmSnippet +22 -0
  32. data/vendor/pdoc/PDoc.tmbundle/Snippets/section.tmSnippet +23 -0
  33. data/vendor/pdoc/PDoc.tmbundle/Syntaxes/PDoc.tmLanguage +33 -0
  34. data/vendor/pdoc/PDoc.tmbundle/info.plist +22 -0
  35. data/vendor/pdoc/README.markdown +34 -0
  36. data/vendor/pdoc/Rakefile +46 -0
  37. data/vendor/pdoc/bin/pdoc +58 -0
  38. data/vendor/pdoc/lib/pdoc/error.rb +4 -0
  39. data/vendor/pdoc/lib/pdoc/generators/abstract_generator.rb +16 -0
  40. data/vendor/pdoc/lib/pdoc/generators/html/helpers.rb +256 -0
  41. data/vendor/pdoc/lib/pdoc/generators/html/page.rb +71 -0
  42. data/vendor/pdoc/lib/pdoc/generators/html/syntax_highlighter.rb +41 -0
  43. data/vendor/pdoc/lib/pdoc/generators/html/template.rb +37 -0
  44. data/vendor/pdoc/lib/pdoc/generators/html/website.rb +194 -0
  45. data/vendor/pdoc/lib/pdoc/generators/html.rb +8 -0
  46. data/vendor/pdoc/lib/pdoc/generators/json.rb +15 -0
  47. data/vendor/pdoc/lib/pdoc/generators/pythonesque.rb +105 -0
  48. data/vendor/pdoc/lib/pdoc/generators.rb +6 -0
  49. data/vendor/pdoc/lib/pdoc/models/argument.rb +37 -0
  50. data/vendor/pdoc/lib/pdoc/models/base.rb +107 -0
  51. data/vendor/pdoc/lib/pdoc/models/callable.rb +19 -0
  52. data/vendor/pdoc/lib/pdoc/models/class.rb +28 -0
  53. data/vendor/pdoc/lib/pdoc/models/class_method.rb +18 -0
  54. data/vendor/pdoc/lib/pdoc/models/class_property.rb +9 -0
  55. data/vendor/pdoc/lib/pdoc/models/constant.rb +9 -0
  56. data/vendor/pdoc/lib/pdoc/models/constructor.rb +14 -0
  57. data/vendor/pdoc/lib/pdoc/models/container.rb +114 -0
  58. data/vendor/pdoc/lib/pdoc/models/entity.rb +54 -0
  59. data/vendor/pdoc/lib/pdoc/models/instance_method.rb +18 -0
  60. data/vendor/pdoc/lib/pdoc/models/instance_property.rb +9 -0
  61. data/vendor/pdoc/lib/pdoc/models/mixin.rb +10 -0
  62. data/vendor/pdoc/lib/pdoc/models/namespace.rb +10 -0
  63. data/vendor/pdoc/lib/pdoc/models/root.rb +27 -0
  64. data/vendor/pdoc/lib/pdoc/models/section.rb +19 -0
  65. data/vendor/pdoc/lib/pdoc/models/signature.rb +27 -0
  66. data/vendor/pdoc/lib/pdoc/models/utility.rb +11 -0
  67. data/vendor/pdoc/lib/pdoc/models.rb +47 -0
  68. data/vendor/pdoc/lib/pdoc/parser/argument_description_nodes.rb +21 -0
  69. data/vendor/pdoc/lib/pdoc/parser/basic_nodes.rb +31 -0
  70. data/vendor/pdoc/lib/pdoc/parser/description_nodes.rb +42 -0
  71. data/vendor/pdoc/lib/pdoc/parser/documentation_nodes.rb +483 -0
  72. data/vendor/pdoc/lib/pdoc/parser/ebnf_arguments_nodes.rb +58 -0
  73. data/vendor/pdoc/lib/pdoc/parser/ebnf_expression_nodes.rb +227 -0
  74. data/vendor/pdoc/lib/pdoc/parser/fragment.rb +55 -0
  75. data/vendor/pdoc/lib/pdoc/parser/section_content_nodes.rb +19 -0
  76. data/vendor/pdoc/lib/pdoc/parser/tags_nodes.rb +14 -0
  77. data/vendor/pdoc/lib/pdoc/parser/treetop_files/argument_description.treetop +31 -0
  78. data/vendor/pdoc/lib/pdoc/parser/treetop_files/basic.treetop +41 -0
  79. data/vendor/pdoc/lib/pdoc/parser/treetop_files/description.treetop +7 -0
  80. data/vendor/pdoc/lib/pdoc/parser/treetop_files/documentation.treetop +75 -0
  81. data/vendor/pdoc/lib/pdoc/parser/treetop_files/ebnf_arguments.treetop +33 -0
  82. data/vendor/pdoc/lib/pdoc/parser/treetop_files/ebnf_expression.treetop +70 -0
  83. data/vendor/pdoc/lib/pdoc/parser/treetop_files/ebnf_javascript.treetop +54 -0
  84. data/vendor/pdoc/lib/pdoc/parser/treetop_files/events.treetop +17 -0
  85. data/vendor/pdoc/lib/pdoc/parser/treetop_files/section_content.treetop +8 -0
  86. data/vendor/pdoc/lib/pdoc/parser/treetop_files/tags.treetop +31 -0
  87. data/vendor/pdoc/lib/pdoc/parser.rb +109 -0
  88. data/vendor/pdoc/lib/pdoc/runner.rb +110 -0
  89. data/vendor/pdoc/lib/pdoc/treemaker.rb +94 -0
  90. data/vendor/pdoc/lib/pdoc.rb +32 -0
  91. data/vendor/pdoc/pdoc-0.2.0.gem +0 -0
  92. data/vendor/pdoc/pdoc.gemspec +31 -0
  93. data/vendor/pdoc/templates/html/assets/images/pdoc/alias.png +0 -0
  94. data/vendor/pdoc/templates/html/assets/images/pdoc/class.png +0 -0
  95. data/vendor/pdoc/templates/html/assets/images/pdoc/class_deprecated.png +0 -0
  96. data/vendor/pdoc/templates/html/assets/images/pdoc/class_method.png +0 -0
  97. data/vendor/pdoc/templates/html/assets/images/pdoc/class_property.png +0 -0
  98. data/vendor/pdoc/templates/html/assets/images/pdoc/constant.png +0 -0
  99. data/vendor/pdoc/templates/html/assets/images/pdoc/constructor.png +0 -0
  100. data/vendor/pdoc/templates/html/assets/images/pdoc/deprecated.png +0 -0
  101. data/vendor/pdoc/templates/html/assets/images/pdoc/description.png +0 -0
  102. data/vendor/pdoc/templates/html/assets/images/pdoc/information.png +0 -0
  103. data/vendor/pdoc/templates/html/assets/images/pdoc/instance_method.png +0 -0
  104. data/vendor/pdoc/templates/html/assets/images/pdoc/instance_property.png +0 -0
  105. data/vendor/pdoc/templates/html/assets/images/pdoc/method.png +0 -0
  106. data/vendor/pdoc/templates/html/assets/images/pdoc/method_deprecated.png +0 -0
  107. data/vendor/pdoc/templates/html/assets/images/pdoc/mixin.png +0 -0
  108. data/vendor/pdoc/templates/html/assets/images/pdoc/namespace.png +0 -0
  109. data/vendor/pdoc/templates/html/assets/images/pdoc/property.png +0 -0
  110. data/vendor/pdoc/templates/html/assets/images/pdoc/related_to.png +0 -0
  111. data/vendor/pdoc/templates/html/assets/images/pdoc/search-background.png +0 -0
  112. data/vendor/pdoc/templates/html/assets/images/pdoc/section-background.png +0 -0
  113. data/vendor/pdoc/templates/html/assets/images/pdoc/section.png +0 -0
  114. data/vendor/pdoc/templates/html/assets/images/pdoc/selected-section-background.png +0 -0
  115. data/vendor/pdoc/templates/html/assets/images/pdoc/subclass.png +0 -0
  116. data/vendor/pdoc/templates/html/assets/images/pdoc/superclass.png +0 -0
  117. data/vendor/pdoc/templates/html/assets/images/pdoc/utility.png +0 -0
  118. data/vendor/pdoc/templates/html/assets/javascripts/pdoc/application.js +478 -0
  119. data/vendor/pdoc/templates/html/assets/javascripts/pdoc/prototype.js +4874 -0
  120. data/vendor/pdoc/templates/html/assets/javascripts/pdoc/tabs.js +506 -0
  121. data/vendor/pdoc/templates/html/assets/stylesheets/pdoc/api.css +677 -0
  122. data/vendor/pdoc/templates/html/assets/stylesheets/pdoc/pygments.css +62 -0
  123. data/vendor/pdoc/templates/html/helpers.rb +35 -0
  124. data/vendor/pdoc/templates/html/index.erb +18 -0
  125. data/vendor/pdoc/templates/html/item_index.js.erb +6 -0
  126. data/vendor/pdoc/templates/html/layout.erb +67 -0
  127. data/vendor/pdoc/templates/html/leaf.erb +22 -0
  128. data/vendor/pdoc/templates/html/node.erb +30 -0
  129. data/vendor/pdoc/templates/html/partials/class_relationships.erb +19 -0
  130. data/vendor/pdoc/templates/html/partials/classes.erb +7 -0
  131. data/vendor/pdoc/templates/html/partials/constructor.erb +5 -0
  132. data/vendor/pdoc/templates/html/partials/description.erb +5 -0
  133. data/vendor/pdoc/templates/html/partials/link_list.erb +1 -0
  134. data/vendor/pdoc/templates/html/partials/method_signatures.erb +14 -0
  135. data/vendor/pdoc/templates/html/partials/methodized_note.erb +9 -0
  136. data/vendor/pdoc/templates/html/partials/mixins.erb +7 -0
  137. data/vendor/pdoc/templates/html/partials/namespaces.erb +7 -0
  138. data/vendor/pdoc/templates/html/partials/related_utilities.erb +5 -0
  139. data/vendor/pdoc/templates/html/partials/relationships.erb +11 -0
  140. data/vendor/pdoc/templates/html/partials/short_description_list.erb +7 -0
  141. data/vendor/pdoc/templates/html/partials/title.erb +22 -0
  142. data/vendor/pdoc/templates/html/section.erb +18 -0
  143. data/vendor/pdoc/test/fixtures/ajax.js +809 -0
  144. data/vendor/pdoc/test/fixtures/prototype.js +5789 -0
  145. data/vendor/pdoc/test/fixtures/test.txt +1 -0
  146. data/vendor/pdoc/test/fixtures/text.txt +13 -0
  147. data/vendor/pdoc/test/unit/parser/argument_description_test.rb +40 -0
  148. data/vendor/pdoc/test/unit/parser/basic_test.rb +55 -0
  149. data/vendor/pdoc/test/unit/parser/description_test.rb +34 -0
  150. data/vendor/pdoc/test/unit/parser/documentation_test.rb +520 -0
  151. data/vendor/pdoc/test/unit/parser/ebnf_arguments_test.rb +81 -0
  152. data/vendor/pdoc/test/unit/parser/ebnf_expression_test.rb +382 -0
  153. data/vendor/pdoc/test/unit/parser/ebnf_javascript_test.rb +37 -0
  154. data/vendor/pdoc/test/unit/parser/events_test.rb +27 -0
  155. data/vendor/pdoc/test/unit/parser/section_content_test.rb +44 -0
  156. data/vendor/pdoc/test/unit/parser/tags_test.rb +39 -0
  157. data/vendor/pdoc/test/unit/parser/test_fragment.rb +80 -0
  158. data/vendor/pdoc/test/unit/parser_test_helper.rb +62 -0
  159. data/vendor/pdoc/test/unit/runner/basic_test.rb +14 -0
  160. data/vendor/pdoc/test/unit/templates/html_helpers_test.rb +25 -0
  161. data/vendor/pdoc/vendor/albino.rb +122 -0
  162. data/vendor/pdoc/website/html/documentation.html +280 -0
  163. data/vendor/pdoc/website/html/images/pdoc.jpg +0 -0
  164. data/vendor/pdoc/website/html/index.html +84 -0
  165. data/vendor/pdoc/website/html/stylesheets/main.css +73 -0
  166. data/vendor/pdoc/website/html/stylesheets/reset.css +18 -0
  167. data/vendor/pdoc/website/markdown/syntax.markdown +226 -0
  168. metadata +153 -3
@@ -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} &rarr; #{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
@@ -0,0 +1,71 @@
1
+ module PDoc
2
+ module Generators
3
+ module Html
4
+ class Page
5
+
6
+ include Helpers::BaseHelper
7
+ include Helpers::LinkHelper
8
+
9
+ def initialize(template, layout, variables = {})
10
+ @template = template
11
+ @layout = layout
12
+ assign_variables(variables)
13
+ end
14
+
15
+ # Renders the page as a string using the assigned layout.
16
+ def render
17
+ if @layout
18
+ @content_for_layout = Template.new(@template, @templates_directory).result(binding)
19
+ Template.new(@layout, @templates_directory).result(binding)
20
+ else
21
+ Template.new(@template, @templates_directory).result(binding)
22
+ end
23
+ end
24
+
25
+ # Creates a new file and renders the page to it
26
+ # using the assigned layout.
27
+ def render_to_file(filename)
28
+ filename ||= ""
29
+ FileUtils.mkdir_p(File.dirname(filename))
30
+ File.open(filename, "w+") { |f| f << render }
31
+ end
32
+
33
+ def include(path, options = {})
34
+ r = ''
35
+ options.each { |k, v| r << "#{k.to_s} = options[:#{k}];" }
36
+ eval(r)
37
+
38
+ if options[:collection]
39
+ options[:collection].map { |object| Template.new(path, @templates_directory).result(binding) }.join("\n")
40
+ else
41
+ Template.new(path, @templates_directory).result(binding)
42
+ end
43
+ end
44
+
45
+ private
46
+ def assign_variables(variables)
47
+ variables.each { |key, value| instance_variable_set("@#{key}", value) }
48
+ end
49
+ end
50
+
51
+ class DocPage < Page
52
+ include Helpers::LinkHelper, Helpers::CodeHelper, Helpers::MenuHelper
53
+
54
+ attr_reader :doc_instance, :depth, :root
55
+
56
+ def initialize(template, layout = "layout", variables = {})
57
+ if layout.is_a?(Hash)
58
+ variables = layout
59
+ layout = "layout"
60
+ end
61
+ super(template, layout, variables)
62
+ end
63
+
64
+ def htmlize(markdown)
65
+ super(auto_link_content(markdown))
66
+ end
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,41 @@
1
+ module PDoc
2
+ module Generators
3
+ module Html
4
+ class SyntaxHighlighter
5
+ CODE_BLOCK_REGEXP = /(?:\n\n|\A)(?:\s{4,}lang(?:uage)?:\s*(\w+)\s*\n)?((?:\s{4}.*\n*)+)(^\s{0,3}\S|\z)?/
6
+
7
+ attr_reader :highlighter
8
+
9
+ def initialize(h = nil)
10
+ @highlighter = h.nil? ? :none : h.to_sym
11
+ end
12
+
13
+ def parse(input)
14
+ input.gsub(CODE_BLOCK_REGEXP) do |block|
15
+ language, codeblock, remainder = $1, $2, $3
16
+ codeblock = codeblock.gsub(/^\s{4}/, '').rstrip
17
+ "\n\n#{highlight_block(codeblock, language)}\n#{remainder}"
18
+ end
19
+ end
20
+
21
+ def highlight_block(code, language)
22
+ language = :javascript if language.nil?
23
+ case highlighter.to_sym
24
+ when :none
25
+ require 'cgi'
26
+ code = CGI.escapeHTML(code)
27
+ "<pre><code class=\"#{language}\">#{code}</code></pre>"
28
+ when :coderay
29
+ require 'coderay'
30
+ CodeRay.scan(code, language).div
31
+ when :pygments
32
+ require 'albino'
33
+ Albino.new(code, language).colorize
34
+ else
35
+ raise "Requested unsupported syntax highlighter: #{highlighter}"
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ begin
2
+ require 'erubis'
3
+ rescue LoadError
4
+ end
5
+
6
+ module PDoc
7
+ module Generators
8
+ module Html
9
+ class Template
10
+ def initialize(file_name = "layout.erb", templates_directory = nil)
11
+ @file_name = file_name
12
+ @templates_directory = templates_directory
13
+ @template = create_template(IO.read(file_path))
14
+ end
15
+
16
+ def result(binding)
17
+ @template.result(binding)
18
+ end
19
+
20
+ private
21
+ def file_path
22
+ @file_name << '.erb' unless @file_name =~ /\.erb$/
23
+ path = File.join(@templates_directory, @file_name.split("/"))
24
+ File.expand_path(path, DIR)
25
+ end
26
+
27
+ def create_template(input)
28
+ if defined?(Erubis)
29
+ Erubis::Eruby.new(input)
30
+ else
31
+ ERB.new(input, nil, '%')
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,194 @@
1
+ module PDoc
2
+ module Generators
3
+ module Html
4
+
5
+ unless defined? TEMPLATES_DIRECTORY
6
+ TEMPLATES_DIRECTORY = File.join(TEMPLATES_DIR, "html")
7
+ end
8
+
9
+ class Website < AbstractGenerator
10
+
11
+ include Helpers::BaseHelper
12
+ include Helpers::LinkHelper
13
+
14
+ class << Website
15
+ attr_accessor :syntax_highlighter
16
+ 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
24
+ end
25
+ attr_reader :templates_directory, :custom_assets, :index_page
26
+ def initialize(parser_output, options = {})
27
+ super
28
+ @templates_directory = File.expand_path(options[:templates] || TEMPLATES_DIRECTORY)
29
+ @index_page = options[:index_page] && File.expand_path(options[:index_page])
30
+ @custom_assets = @options[:assets] && File.expand_path(@options[:assets])
31
+ self.class.syntax_highlighter = SyntaxHighlighter.new(options[:syntax_highlighter])
32
+ self.class.pretty_urls = options[:pretty_urls]
33
+ set_markdown_parser(options[:markdown_parser])
34
+ load_custom_helpers
35
+ end
36
+
37
+ def set_markdown_parser(parser = nil)
38
+ parser = :rdiscount if parser.nil?
39
+ case parser.to_sym
40
+ when :rdiscount
41
+ require 'rdiscount'
42
+ self.class.markdown_parser = RDiscount
43
+ when :bluecloth
44
+ require 'bluecloth'
45
+ self.class.markdown_parser = BlueCloth
46
+ when :maruku
47
+ require 'maruku'
48
+ self.class.markdown_parser = Maruku
49
+ else
50
+ raise "Requested unsupported Markdown parser: #{parser}."
51
+ end
52
+ end
53
+
54
+ def load_custom_helpers
55
+ begin
56
+ require File.join(templates_directory, "helpers")
57
+ rescue LoadError => e
58
+ return nil
59
+ end
60
+ self.class.__send__(:include, Helpers::BaseHelper)
61
+ Page.__send__(:include, Helpers::BaseHelper)
62
+ Helpers.constants.map(&Helpers.method(:const_get)).each(&DocPage.method(:include))
63
+ end
64
+
65
+ # Generates the website to the specified directory.
66
+ def render(output)
67
+ @depth = 0
68
+ path = File.expand_path(output)
69
+ FileUtils.mkdir_p(path)
70
+ Dir.chdir(path) do
71
+
72
+ render_index
73
+ copy_assets
74
+ copy_custom_assets
75
+
76
+ render_children(root)
77
+ if root.sections?
78
+ root.sections.each do |section|
79
+ @depth = 0
80
+ render_template('section', { :doc_instance => section })
81
+ end
82
+ end
83
+
84
+ dest = File.join("javascripts", "pdoc", "item_index.js")
85
+ DocPage.new("item_index.js", false, variables).render_to_file(dest)
86
+ end
87
+ end
88
+
89
+ def render_index
90
+ vars = variables.merge(:index_page_content => index_page_content, :home => true)
91
+ DocPage.new('index', 'layout', vars).render_to_file('index.html')
92
+ end
93
+
94
+ def render_template(template, var = {})
95
+ @depth += 1
96
+ doc = var[:doc_instance]
97
+ dest = doc.url(File::SEPARATOR)
98
+ puts " Rendering #{dest}..."
99
+ FileUtils.mkdir_p(dest)
100
+ DocPage.new(template, variables.merge(var)).render_to_file(File.join(dest, 'index.html'))
101
+ render_json("#{dest}.json", doc) if json_api?
102
+ render_children(doc)
103
+ @depth -= 1
104
+ end
105
+
106
+ def render_json(dest, obj)
107
+ open(dest, 'w') { |file| file << obj.to_json }
108
+ end
109
+
110
+ def render_children(obj)
111
+ [:namespaces, :classes, :mixins].each do |prop|
112
+ obj.send(prop).each(&method(:render_node)) if obj.respond_to?(prop)
113
+ end
114
+
115
+ obj.utilities.each(&method(:render_leaf)) if obj.respond_to?(:utilities)
116
+ render_leaf(obj.constructor) if obj.respond_to?(:constructor) && obj.constructor
117
+
118
+ [:instance_methods, :instance_properties, :class_methods, :class_properties, :constants].each do |prop|
119
+ obj.send(prop).each(&method(:render_leaf)) if obj.respond_to?(prop)
120
+ end
121
+ end
122
+
123
+ # Copies the content of the assets folder to the generated website's
124
+ # root directory.
125
+ def copy_assets
126
+ FileUtils.cp_r(Dir.glob(File.join(templates_directory, "assets", "**")), '.')
127
+ end
128
+
129
+ def copy_custom_assets
130
+ if custom_assets
131
+ FileUtils.cp_r(Dir.glob(File.join(custom_assets, "**")), ".")
132
+ end
133
+ end
134
+
135
+ def render_leaf(object)
136
+ is_proto_prop = is_proto_prop?(object)
137
+ @depth += 1 if is_proto_prop
138
+ render_template('leaf', { :doc_instance => object })
139
+ @depth -= 1 if is_proto_prop
140
+ end
141
+
142
+ def render_node(object)
143
+ render_template('node', { :doc_instance => object })
144
+ end
145
+
146
+ private
147
+ def variables
148
+ {
149
+ :root => root,
150
+ :depth => @depth,
151
+ :templates_directory => templates_directory,
152
+ :name => @options[:name],
153
+ :short_name => @options[:short_name] || @options[:name],
154
+ :home_url => @options[:home_url],
155
+ :version => @options[:version],
156
+ :footer => footer,
157
+ :index_header => index_header,
158
+ :header => header,
159
+ :timestamp => timestamp
160
+ }
161
+ end
162
+
163
+ def header
164
+ @header ||= @options[:header] ? htmlize(@options[:header]) : ''
165
+ end
166
+
167
+ def index_header
168
+ @index_header ||= @options[:index_header] ? htmlize(@options[:index_header]) : ''
169
+ end
170
+
171
+ def footer
172
+ @footer ||= @options[:footer] ? htmlize(@options[:footer]) : ''
173
+ end
174
+
175
+ def timestamp
176
+ @timestamp ||= @options[:timestamp] == false ? nil : Time.now.utc
177
+ end
178
+
179
+ def json_api?
180
+ !!options[:json_api]
181
+ end
182
+
183
+ def is_proto_prop?(object)
184
+ object.is_a?(Models::InstanceMethod) ||
185
+ object.is_a?(Models::InstanceProperty)
186
+ end
187
+
188
+ def index_page_content
189
+ @index_page ? htmlize(File.read(@index_page)) : nil
190
+ end
191
+ end
192
+ end
193
+ end
194
+ 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,15 @@
1
+ require 'json'
2
+ module PDoc
3
+ module Generators
4
+ class JSON < AbstractGenerator
5
+ def render(output)
6
+ open(output, "w+") do |file|
7
+ json = root.registry.map do |k, obj|
8
+ "#{k.inspect}: #{obj.to_json}"
9
+ end.join(",\n ")
10
+ file << "{\n #{json}\n}"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end