Class | Webgen::SourceHandler::Fragment |
In: |
lib/webgen/sourcehandler/fragment.rb
|
Parent: | Object |
Handles page fragment nodes and provides utility methods for parsing HTML headers and generating fragment nodes from them.
HTML_HEADER_REGEXP | = | /<h([123456])(?:>|\s([^>]*)>)(.*?)<\/h\1\s*>/i |
HTML_ATTR_REGEXP | = | /\s*(\w+)\s*=\s*('|")(.+?)\2\s*/ |
Create nested fragment nodes under parent from sections (which can be created using parse_html_headers). path is the source path that defines the fragments (which is not the same as the creation path for parent). The meta information in_menu of the fragment nodes is set to the parameter in_menu and the meta info sort_info is calculated from the base si value.
# File lib/webgen/sourcehandler/fragment.rb, line 53 53: def create_fragment_nodes(sections, parent, path, in_menu, si = 1000) 54: sections.each do |level, id, title, sub_sections| 55: fragment_path = parent.alcn.sub(/#.*$/, '') + '#' + id 56: node = website.blackboard.invoke(:create_nodes, 57: Webgen::Path.new(fragment_path, path.source_path), 58: self) do |cn_path| 59: cn_path.meta_info['title'] = title 60: cn_path.meta_info['in_menu'] = in_menu 61: cn_path.meta_info['sort_info'] = si = si.succ 62: create_node(cn_path, :parent => parent) 63: end.first 64: create_fragment_nodes(sub_sections, node, path, in_menu, si.succ) 65: end 66: end
Parse the string content for headers +h1+, …, +h6+ and return the found, nested sections.
Only those headers are used which have an id attribute set. The method returns a list of arrays with entries level, id, title, sub sections where sub sections is such a list again.
# File lib/webgen/sourcehandler/fragment.rb, line 20 20: def parse_html_headers(content) 21: sections = [] 22: stack = [] 23: content.scan(HTML_HEADER_REGEXP).each do |level,attrs,title| 24: next if attrs.nil? 25: id_attr = attrs.scan(HTML_ATTR_REGEXP).find {|name,sep,value| name == 'id'} 26: next if id_attr.nil? 27: id = id_attr[2] 28: 29: section = [level.to_i, id, title, []] 30: success = false 31: while !success 32: if stack.empty? 33: sections << section 34: stack << section 35: success = true 36: elsif stack.last.first < section.first 37: stack.last.last << section 38: stack << section 39: success = true 40: else 41: stack.pop 42: end 43: end 44: end 45: sections 46: end