class Webgen::PathHandler::Api
Constants
- MANDATORY_INFOS
The mandatory meta info keys that need to be set on an api path.
Public Instance Methods
Adapt a RDoc class/module object to provide a different output path depending on the output_structure meta information of the API path.
# File lib/webgen/path_handler/api.rb 143 def adapt_rdoc_class(api_path, klass) 144 case api_path['output_structure'] 145 when 'hierarchical' 146 api_path['use_proxy_path'] = false 147 def klass.http_url(prefix) 148 if classes_and_modules.size > 0 149 super(prefix).sub(/\.html/, '/index.html') 150 else 151 super(prefix) 152 end 153 end 154 else 155 api_path['use_proxy_path'] = true 156 end 157 end
Add a link definition for the given node.
# File lib/webgen/path_handler/api.rb 276 def add_link_definition(api_path, link_name, url, title) 277 link = if api_path['prefix_link_defs'] 278 "#{api_path['api_name']}:#{link_name}" 279 else 280 link_name 281 end 282 @website.ext.link_definitions[link] = [url, title] 283 end
Create a fragment node for the given constant.
A link definition entry for the method is also created.
# File lib/webgen/path_handler/api.rb 198 def create_fragment_node_for_constant(api_path, parent_node, constant) 199 constant_url = "#{parent_node.alcn.sub(/#.*$/, '')}##{constant.name}" 200 path = Webgen::Path.new(constant_url, 201 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 202 'parent_alcn' => parent_node.alcn, 203 'pipeline' => [], 'no_output' => true, 'title' => constant.name}) 204 @website.ext.path_handler.create_secondary_nodes(path) 205 add_link_definition(api_path, constant.full_name, constant_url, constant.full_name) 206 end
Create a fragment node for the given method.
A link definition entry for the method is also created.
# File lib/webgen/path_handler/api.rb 246 def create_fragment_node_for_method(api_path, parent_node, method) 247 method_url = "#{parent_node.alcn.sub(/#.*$/, '')}##{method.aref}" 248 path = Webgen::Path.new(method_url, 249 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 250 'parent_alcn' => parent_node.alcn, 251 'pipeline' => [], 'no_output' => true, 'title' => method.name}) 252 @website.ext.path_handler.create_secondary_nodes(path) 253 add_link_definition(api_path, method.full_name, method_url, method.full_name) 254 end
Creates fragment nodes for attributes under the “Attributes” fragment.
# File lib/webgen/path_handler/api.rb 210 def create_fragment_nodes_for_attributes(api_path, parent_node, klass) 211 return if klass.attributes.none? {|attr| attr.display? } 212 attributes_url = "#{parent_node.alcn}#Attributes" 213 path = Webgen::Path.new(attributes_url, 214 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 215 'parent_alcn' => parent_node.alcn, 216 'pipeline' => [], 'no_output' => true, 'title' => "Attributes"}) 217 attr_node = @website.ext.path_handler.create_secondary_nodes(path).first 218 klass.attributes.sort_by(&:name).each do |attribute| 219 create_fragment_node_for_method(api_path, attr_node, attribute) 220 end 221 end
Creates fragment nodes for constants under the “Constants” fragment.
# File lib/webgen/path_handler/api.rb 182 def create_fragment_nodes_for_constants(api_path, klass_node, klass) 183 return if klass.constants.none? {|const| const.display? } 184 constants_url = "#{klass_node.alcn}#Constants" 185 path = Webgen::Path.new(constants_url, 186 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 187 'pipeline' => [], 'no_output' => true, 'title' => "Constants"}) 188 const_node = @website.ext.path_handler.create_secondary_nodes(path).first 189 klass.constants.sort_by(&:name).each do |const| 190 create_fragment_node_for_constant(api_path, const_node, const) 191 end 192 end
Creates fragment nodes for methods under the “Class Methods” or “Instance Methods” fragments.
# File lib/webgen/path_handler/api.rb 226 def create_fragment_nodes_for_methods(api_path, klass_node, klass) 227 ["Class", "Instance"].each do |type| 228 method_list = klass.send("#{type.downcase}_method_list") 229 next if method_list.empty? 230 meth_url = "#{klass_node.alcn}##{type}-Methods" 231 path = Webgen::Path.new(meth_url, 232 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 233 'pipeline' => [], 'no_output' => true, 234 'title' => "#{type} Methods"}) 235 meth_node = @website.ext.path_handler.create_secondary_nodes(path).first 236 method_list.sort_by(&:name).each do |method| 237 create_fragment_node_for_method(api_path, meth_node, method) 238 end 239 end 240 end
Create the feed nodes.
# File lib/webgen/path_handler/api.rb 24 def create_nodes(path, blocks) 25 if MANDATORY_INFOS.any? {|t| path.meta_info[t].nil?} 26 raise Webgen::NodeCreationError.new("At least one of #{MANDATORY_INFOS.join('/')} is missing", 27 "path_handler.api", path) 28 end 29 30 path['api_name'] ||= path.basename 31 path['dir_name'] ||= path.basename 32 33 cache_dir = @website.tmpdir(File.join('path_handler.api', path['api_name'])) 34 rdoc = rdoc_object(path['rdoc_options'], cache_dir) 35 output_flag_file = rdoc.output_flag_file(cache_dir) 36 37 dir_node = create_directory(path, Webgen::Path.new(path.parent_path + path['dir_name'] + '/'), false) 38 39 api = OpenStruct.new 40 api.directory = dir_node 41 api.class_nodes = {} 42 api.file_nodes = {} 43 44 rdoc.store.all_classes_and_modules.sort.each do |klass| 45 adapt_rdoc_class(path, klass) 46 klass_node = create_page_node_for_class(path, dir_node, klass, output_flag_file) 47 api.class_nodes[klass.full_name] = klass_node 48 klass_node.node_info[:api] = api 49 create_fragment_nodes_for_constants(path, klass_node, klass) 50 create_fragment_nodes_for_attributes(path, klass_node, klass) 51 create_fragment_nodes_for_methods(path, klass_node, klass) 52 end 53 54 rdoc.store.all_files.sort.each do |file| 55 next unless file.text? 56 file_node = create_page_node_for_file(path, dir_node, file, output_flag_file) 57 api.file_nodes[file.full_name] = file_node 58 file_node.node_info[:api] = api 59 end 60 61 nil 62 end
Create a page node for the given class klass
and return it.
A link definition entry for the class is also created.
# File lib/webgen/path_handler/api.rb 163 def create_page_node_for_class(api_path, dir_node, klass, output_flag_file) 164 klass_path_str = klass.http_url(dir_node.alcn) 165 166 create_directory(api_path, Webgen::Path.new(File.dirname(klass_path_str) + '/'), api_path['use_proxy_path']) 167 168 path = Webgen::Path.new(klass_path_str, 'handler' => 'page', 'modified_at' => api_path['modified_at'], 169 'title' => "#{klass.full_name}", 'api_class_name' => klass.full_name, 170 'api_name' => api_path['api_name'], 'template' => api_path['api_template']) 171 node = @website.ext.path_handler.create_secondary_nodes(path).first 172 173 node.node_info[:rdoc_object] = klass 174 @website.ext.item_tracker.add(node, :file, output_flag_file) 175 add_link_definition(api_path, klass.full_name, node.alcn, klass.full_name) 176 177 node 178 end
Create a page node for the given file and return it.
# File lib/webgen/path_handler/api.rb 258 def create_page_node_for_file(api_path, dir_node, file, output_flag_file) 259 file_path_str = file.http_url(dir_node.alcn) 260 261 create_directory(api_path, Webgen::Path.new(File.dirname(file_path_str) + '/')) 262 263 path = Webgen::Path.new(file_path_str, 'handler' => 'page', 'modified_at' => api_path['modified_at'], 264 'title' => "File #{file.full_name}", 'api_file_name' => file.full_name, 265 'api_name' => api_path['api_name'], 'template' => api_path['api_template']) 266 node = @website.ext.path_handler.create_secondary_nodes(path).first 267 268 node.node_info[:rdoc_object] = file 269 @website.ext.item_tracker.add(node, :file, output_flag_file) 270 271 node 272 end
Create the RDoc instance and use it for generating the API data.
If possible, cached data available under cache_dir
is used.
# File lib/webgen/path_handler/api.rb 87 def rdoc_object(options, cache_dir) 88 start_time = Time.now 89 90 rdoc = RDoc::RDoc.new 91 rdoc.options = rdoc_options(options) 92 rdoc.store = rdoc_store(rdoc.options, cache_dir) 93 94 rdoc.last_modified.replace(rdoc.setup_output_dir(cache_dir, false)) 95 96 if !(rdoc.parse_files(rdoc.options.files)).empty? 97 rdoc.store.complete(rdoc.options.visibility) 98 rdoc.store.save 99 rdoc.update_output_dir(cache_dir, start_time, rdoc.last_modified) 100 end 101 rdoc.store.load_all 102 103 # We need a dummy generator with some methods 104 rdoc.generator = Object.new 105 def (rdoc.generator).class_dir; nil; end 106 def (rdoc.generator).file_dir; nil; end 107 108 rdoc 109 end 110 protected :rdoc_object 111 112 # Return a fully initialized RDoc::Options object. 113 # 114 # Some of the user specified options may not be used if they would interfere with this class' 115 # job. 116 def rdoc_options(user_options) 117 user_options = Shellwords.split(user_options) if user_options.kind_of?(String) 118 options = RDoc::Options.new 119 options.parse(user_options) 120 options.verbosity = 0 121 options.dry_run = false 122 options.update_output_dir = true 123 options.force_output = false 124 options.finish 125 options 126 end 127 protected :rdoc_options 128 129 # Return a fully initialized RDoc::Store object. 130 def rdoc_store(options, cache_dir) 131 store = RDoc::Store.new(cache_dir) 132 store.encoding = options.encoding 133 store.dry_run = options.dry_run 134 store.main = options.main_page 135 store.title = options.title 136 store.load_cache 137 store 138 end 139 protected :rdoc_store 140 141 # Adapt a RDoc class/module object to provide a different output path depending on the 142 # output_structure meta information of the API path. 143 def adapt_rdoc_class(api_path, klass) 144 case api_path['output_structure'] 145 when 'hierarchical' 146 api_path['use_proxy_path'] = false 147 def klass.http_url(prefix) 148 if classes_and_modules.size > 0 149 super(prefix).sub(/\.html/, '/index.html') 150 else 151 super(prefix) 152 end 153 end 154 else 155 api_path['use_proxy_path'] = true 156 end 157 end 158 protected :adapt_rdoc_class 159 160 # Create a page node for the given class +klass+ and return it. 161 # 162 # A link definition entry for the class is also created. 163 def create_page_node_for_class(api_path, dir_node, klass, output_flag_file) 164 klass_path_str = klass.http_url(dir_node.alcn) 165 166 create_directory(api_path, Webgen::Path.new(File.dirname(klass_path_str) + '/'), api_path['use_proxy_path']) 167 168 path = Webgen::Path.new(klass_path_str, 'handler' => 'page', 'modified_at' => api_path['modified_at'], 169 'title' => "#{klass.full_name}", 'api_class_name' => klass.full_name, 170 'api_name' => api_path['api_name'], 'template' => api_path['api_template']) 171 node = @website.ext.path_handler.create_secondary_nodes(path).first 172 173 node.node_info[:rdoc_object] = klass 174 @website.ext.item_tracker.add(node, :file, output_flag_file) 175 add_link_definition(api_path, klass.full_name, node.alcn, klass.full_name) 176 177 node 178 end 179 protected :create_page_node_for_class 180 181 # Creates fragment nodes for constants under the "Constants" fragment. 182 def create_fragment_nodes_for_constants(api_path, klass_node, klass) 183 return if klass.constants.none? {|const| const.display? } 184 constants_url = "#{klass_node.alcn}#Constants" 185 path = Webgen::Path.new(constants_url, 186 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 187 'pipeline' => [], 'no_output' => true, 'title' => "Constants"}) 188 const_node = @website.ext.path_handler.create_secondary_nodes(path).first 189 klass.constants.sort_by(&:name).each do |const| 190 create_fragment_node_for_constant(api_path, const_node, const) 191 end 192 end 193 protected :create_fragment_nodes_for_constants 194 195 # Create a fragment node for the given constant. 196 # 197 # A link definition entry for the method is also created. 198 def create_fragment_node_for_constant(api_path, parent_node, constant) 199 constant_url = "#{parent_node.alcn.sub(/#.*$/, '')}##{constant.name}" 200 path = Webgen::Path.new(constant_url, 201 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 202 'parent_alcn' => parent_node.alcn, 203 'pipeline' => [], 'no_output' => true, 'title' => constant.name}) 204 @website.ext.path_handler.create_secondary_nodes(path) 205 add_link_definition(api_path, constant.full_name, constant_url, constant.full_name) 206 end 207 protected :create_fragment_node_for_constant 208 209 # Creates fragment nodes for attributes under the "Attributes" fragment. 210 def create_fragment_nodes_for_attributes(api_path, parent_node, klass) 211 return if klass.attributes.none? {|attr| attr.display? } 212 attributes_url = "#{parent_node.alcn}#Attributes" 213 path = Webgen::Path.new(attributes_url, 214 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 215 'parent_alcn' => parent_node.alcn, 216 'pipeline' => [], 'no_output' => true, 'title' => "Attributes"}) 217 attr_node = @website.ext.path_handler.create_secondary_nodes(path).first 218 klass.attributes.sort_by(&:name).each do |attribute| 219 create_fragment_node_for_method(api_path, attr_node, attribute) 220 end 221 end 222 protected :create_fragment_nodes_for_attributes 223 224 # Creates fragment nodes for methods under the "Class Methods" or "Instance Methods" 225 # fragments. 226 def create_fragment_nodes_for_methods(api_path, klass_node, klass) 227 ["Class", "Instance"].each do |type| 228 method_list = klass.send("#{type.downcase}_method_list") 229 next if method_list.empty? 230 meth_url = "#{klass_node.alcn}##{type}-Methods" 231 path = Webgen::Path.new(meth_url, 232 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 233 'pipeline' => [], 'no_output' => true, 234 'title' => "#{type} Methods"}) 235 meth_node = @website.ext.path_handler.create_secondary_nodes(path).first 236 method_list.sort_by(&:name).each do |method| 237 create_fragment_node_for_method(api_path, meth_node, method) 238 end 239 end 240 end 241 protected :create_fragment_nodes_for_attributes 242 243 # Create a fragment node for the given method. 244 # 245 # A link definition entry for the method is also created. 246 def create_fragment_node_for_method(api_path, parent_node, method) 247 method_url = "#{parent_node.alcn.sub(/#.*$/, '')}##{method.aref}" 248 path = Webgen::Path.new(method_url, 249 {'handler' => 'copy', 'modified_at' => api_path['modified_at'], 250 'parent_alcn' => parent_node.alcn, 251 'pipeline' => [], 'no_output' => true, 'title' => method.name}) 252 @website.ext.path_handler.create_secondary_nodes(path) 253 add_link_definition(api_path, method.full_name, method_url, method.full_name) 254 end 255 protected :create_fragment_node_for_method 256 257 # Create a page node for the given file and return it. 258 def create_page_node_for_file(api_path, dir_node, file, output_flag_file) 259 file_path_str = file.http_url(dir_node.alcn) 260 261 create_directory(api_path, Webgen::Path.new(File.dirname(file_path_str) + '/')) 262 263 path = Webgen::Path.new(file_path_str, 'handler' => 'page', 'modified_at' => api_path['modified_at'], 264 'title' => "File #{file.full_name}", 'api_file_name' => file.full_name, 265 'api_name' => api_path['api_name'], 'template' => api_path['api_template']) 266 node = @website.ext.path_handler.create_secondary_nodes(path).first 267 268 node.node_info[:rdoc_object] = file 269 @website.ext.item_tracker.add(node, :file, output_flag_file) 270 271 node 272 end 273 protected :create_page_node_for_file 274 275 # Add a link definition for the given node. 276 def add_link_definition(api_path, link_name, url, title) 277 link = if api_path['prefix_link_defs'] 278 "#{api_path['api_name']}:#{link_name}" 279 else 280 link_name 281 end 282 @website.ext.link_definitions[link] = [url, title] 283 end 284 protected :add_link_definition 285 286 end 287 288 end
Return a fully initialized RDoc::Options object.
Some of the user specified options may not be used if they would interfere with this class' job.
# File lib/webgen/path_handler/api.rb 116 def rdoc_options(user_options) 117 user_options = Shellwords.split(user_options) if user_options.kind_of?(String) 118 options = RDoc::Options.new 119 options.parse(user_options) 120 options.verbosity = 0 121 options.dry_run = false 122 options.update_output_dir = true 123 options.force_output = false 124 options.finish 125 options 126 end
Return a fully initialized RDoc::Store object.
# File lib/webgen/path_handler/api.rb 130 def rdoc_store(options, cache_dir) 131 store = RDoc::Store.new(cache_dir) 132 store.encoding = options.encoding 133 store.dry_run = options.dry_run 134 store.main = options.main_page 135 store.title = options.title 136 store.load_cache 137 store 138 end
Private Instance Methods
Create a directory for the path, applying needed meta information from the api path.
Also creates the parent directories when necessary.
# File lib/webgen/path_handler/api.rb 67 def create_directory(api_path, path, set_proxy_path = true) 68 if (dir = @website.tree[path.alcn]) 69 return dir 70 end 71 72 parent_path = Webgen::Path.new(path.parent_path) 73 if !@website.tree[parent_path.alcn] 74 create_directory(api_path, parent_path) 75 end 76 77 path['modified_at'] = api_path['modified_at'] 78 path['handler'] = 'directory' 79 path['proxy_path'] ||= "../#{path.basename}.html" if set_proxy_path 80 @website.ext.path_handler.create_secondary_nodes(path).first 81 end