Class: Peregrin::Componentizer

Inherits:
Object
  • Object
show all
Defined in:
lib/peregrin/componentizer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(doc) ⇒ Componentizer

Returns a new instance of Componentizer.



6
7
8
9
# File 'lib/peregrin/componentizer.rb', line 6

def initialize(doc)
  @document = doc
  @component_xpaths = []
end

Instance Attribute Details

#component_xpathsObject (readonly)

Returns the value of attribute component_xpaths.



3
4
5
# File 'lib/peregrin/componentizer.rb', line 3

def component_xpaths
  @component_xpaths
end

Instance Method Details

#generate_component(xpath) ⇒ Object



22
23
24
25
26
# File 'lib/peregrin/componentizer.rb', line 22

def generate_component(xpath)
  raise "Not a component: #{xpath}"  unless @component_xpaths.include?(xpath)
  node = @document.at_xpath(xpath)
  generate_document(node)
end

#generate_document(node) ⇒ Object

Creates a new document with the same root and head nodes, but with a body that just contains the nodes at the given xpath.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/peregrin/componentizer.rb', line 32

def generate_document(node)
  # Clean up the "shell" document.
  @shell_document ||= @document.dup
  bdy = @shell_document.at_xpath('/html/body')
  bdy.children.remove

  # Find the node we're going to copy into the shell document.
  # Create a deep clone of it. Remove any children of it that are
  # componentizable in their own right.
  ndup = node.dup
  node.children.collect { |ch|
    next  unless component_xpaths.include?(ch.path)
    dpath = ch.path.sub(/^#{Regexp.escape(node.path)}/, ndup.path)
    ndup.children.detect { |dch| dch.path == dpath }
  }.compact.each { |ch|
    ch.unlink
  }

  # Append the node to the body of the shell (or replace the body, if
  # the node is a body itself).
  if node.name.downcase == "body"
    bdy.replace(ndup)
  else
    bdy.add_child(ndup)
  end

  @shell_document.dup
end

#process(from) ⇒ Object

Build a list of xpaths for nodes that can be turned into standalone components.



15
16
17
18
19
# File 'lib/peregrin/componentizer.rb', line 15

def process(from)
  @component_xpaths = []
  walk(from)
  @component_xpaths.reject! { |xpath| emptied?(xpath) }
end

#write_component(xpath, path, &blk) ⇒ Object

Writes the componentizable node at the given xpath to the given filesystem path.

If you provide a block, you get the new document object, and you are expected to return the string containing its HTML form – in this way you can tweak the HTML output. Default is simply: doc.to_html



69
70
71
72
73
74
# File 'lib/peregrin/componentizer.rb', line 69

def write_component(xpath, path, &blk)
  new_doc = generate_component(xpath)
  out = block_given? ? blk.call(new_doc) : new_doc.to_html
  File.open(path, 'w') { |f| f.write(out) }
  out
end