class Swordfish::Document

Attributes

images[RW]
nodes[R]

Public Class Methods

new() click to toggle source

On initialization, set the nodes list to an empty array

# File lib/swordfish/document.rb, line 28
def initialize
  @nodes = []
  @images = {}
end

Public Instance Methods

append(node) click to toggle source

Pass in a node and append it to the nodes array

# File lib/swordfish/document.rb, line 34
def append(node)
  if Swordfish::Node.constants.include? node.class.to_s.split('::').last.to_sym
    @nodes << node
  else
    raise ArgumentError, "Object is not a node"
  end
end
get_image(name) click to toggle source

Retrieve an image by name

# File lib/swordfish/document.rb, line 43
def get_image(name)
  @images[name]
end
save_image(image, dest) click to toggle source

Save an image to a specified directory

# File lib/swordfish/document.rb, line 48
def save_image(image, dest)
  @images[image].open
  File.open(dest, 'w') { |f| f.write(@images[image].read) }
  @images[image].close
end
settings(opts = {}) click to toggle source

Perform various destructive operations that may result in improved output

# File lib/swordfish/document.rb, line 64
def settings(opts = {})
  find_headers! if opts[:guess_headers]
  find_footnotes! if opts[:footnotes]
  clean_line_breaks! if opts[:smart_br]
  @generate_full_document = !!opts[:full_document]
  self
end
to_html() click to toggle source
# File lib/swordfish/document.rb, line 72
def to_html
  if @generate_full_document
    prefix = "<!DOCTYPE html><html><head><title></title></head><body>"
    suffix = "</body></html>"
    prefix + @nodes.map(&:to_html).join + suffix
  else
    @nodes.map(&:to_html).join
  end
end
update_image_path(original_name, new_path) click to toggle source

Change the value that an image should report its source to be

# File lib/swordfish/document.rb, line 55
def update_image_path(original_name, new_path)
  find_nodes_by_type(Swordfish::Node::Image).each do |image_node|
    if image_node.original_name == original_name
      image_node.path = new_path
    end
  end
end

Private Instance Methods

clean_line_breaks!() click to toggle source

Remove superfluous linebreaks

# File lib/swordfish/document.rb, line 135
def clean_line_breaks!
  find_nodes_by_type(Swordfish::Node::Paragraph).each do |paragraph|
    paragraph.children.delete_at(0) if paragraph.children.first.is_a?(Swordfish::Node::Linebreak)
    paragraph.children.delete_at(-1) if paragraph.children.last.is_a?(Swordfish::Node::Linebreak)
  end
end
find_footnotes!() click to toggle source

Find all foot/endnotes and number them

# File lib/swordfish/document.rb, line 125
def find_footnotes!
  find_nodes_by_type(Swordfish::Node::Footnote).each_with_index do |footnote, idx|
    footnote.inform!({:index => idx})
    footnote_content = Swordfish::Node::Raw.new
    footnote_content.content = footnote.content_to_html
    @nodes << footnote_content
  end
end
find_headers!() click to toggle source

Attempt to identify header nodes

# File lib/swordfish/document.rb, line 90
def find_headers!
  font_sizes = []
  # If a paragraph has a single font size throughout, mark it in the array.
  @nodes.each_with_index do |node, idx|
    if node.is_a?(Swordfish::Node::Paragraph)
      para_size = node.style.font_size
      run_sizes = node.children.collect{ |n| n.style.font_size }.compact
      if (run_sizes.length == 1) || (run_sizes.length == 0 && para_size)
        font_sizes << {:idx => idx, :size => run_sizes.first || para_size}
      end
    end
  end

  # For each node with a consistent size, if it is larger than both of
  # its neighbors, flag it as a header
  header_sizes = []
  font_sizes.each_with_index do |f, idx|
    if idx == 0
      header_sizes << f[:size] if f[:size] > font_sizes[idx+1][:size]
    elsif idx != font_sizes.length - 1
      header_sizes << f[:size] if (f[:size] > font_sizes[idx-1][:size] && f[:size] > font_sizes[idx+1][:size])
    end
  end
  header_sizes = header_sizes.uniq.sort.reverse
  font_sizes.each do |f|
    level = header_sizes.find_index(f[:size])
    if level
      header = @nodes[f[:idx]].replace_with(Swordfish::Node::Header)
      header.inform! :level => (level + 1)
      @nodes[f[:idx]] = header
    end
  end
end
find_nodes_by_type(klass) click to toggle source

Return all nodes of a given type

# File lib/swordfish/document.rb, line 85
def find_nodes_by_type(klass)
  @nodes.collect{|n| n.find_nodes_by_type(klass)}.flatten
end