Class: Nanoc::Toolbox::Filters::AddSections

Inherits:
Filter
  • Object
show all
Defined in:
lib/nanoc/toolbox/filters/add_sections.rb

Overview

This filters adds section div’s based on headers. For example, this:

Examples:

h1
p
foo
  p
  h2
  p
p
h2
p
p
h1
p

section
  h1
  p
  foo
    p
    section
      h2
      p
    p
  section
    h2
    p
    p
section
  p

Author:

Instance Method Summary collapse

Instance Method Details

#run(content, arguments = {}) ⇒ Object


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/nanoc/toolbox/filters/add_sections.rb', line 38

def run(content, arguments={})
  require 'nokogiri'

  # Parse
  doc = Nokogiri::HTML.fragment(content)

  # Add sections for all headers
  (1..6).each do |level|
    # For each header on this level
    doc.css("h#{level}").each do |header|
      # Get all siblings
      siblings = header.parent.children

      # Remove previous siblings
      siblings_after = []
      should_include = false
      siblings.each do |sibling|
        if sibling == header
          should_include = true
        elsif should_include
          siblings_after << sibling
        end
      end

      # Remove next siblings that should not be part of this section
      siblings_in_between = []
      siblings_after.each do |sibling|
        if sibling.name =~ /^h(\d)/ && $1.to_i <= level
          break
        else
          siblings_in_between << sibling
        end
      end

      # Create section
      section = Nokogiri::XML::Node.new('div', doc)
      section['class'] = 'section'
      section['id'] = header.content.downcase.gsub(/\W+/, '-').gsub(/^-|-$/, '')
      header.add_previous_sibling(section)

      # Move children into section
      header.unlink
      section.add_child(header)
      siblings_in_between.each do |sibling|
        sibling.unlink
        section.add_child(sibling)
      end
    end
  end

  # Done
  doc.to_s
end