Important: This wiki is no longer in use. Use the nanoc wiki on GitHub instead. Not everything from this wiki was migrated to the new wiki because quite a bit was no longer relevant. The contents of the old wiki are nonetheless preserved here in case you need it.
← homepage

Adding Permalinks To Headers

You can let nanoc add permalinks to headers, so that linking to specific sections of a HTML document is a lot easier. Rather than generating these links by hand, you can let nanoc do this automatically. The easiest way to do this is using a custom filter. For this, you'll need Hpricot. This tip assumes that your HTML file is structured in a certain way (similar to HTML5's usage of
and ). First of all, each section should be a div with a "section" class. Each section should have a header. Additionally, each section must have an id. For example:

#!text/html

Foo

...

Bar

...

Baz

...

Quux

...
This filter should do the following: 1. Find all sections 2. For all sections: 1. Get the section ID 2. Find the section header 3. Append the permalink to the section with the given ID to the header Its implementation looks like this:

#!ruby
class AddLinksToHeadersFilter < Nanoc3::Filter

  identifiers :add_links_to_headers

  def run(content)
    require 'hpricot'

    # Parse with Hpricot
    doc = Hpricot(content)

    # Find all sections
    doc.search('.section').each do |section|
      # Find ID
      section_id = section['id']
      next if section_id.nil?

      # Add permalink to header
      section_header = section.search((1..6).map { |i| "> h#{i}" }.join(', '))
      section_header.append(permalink_for(section_id))
    end

    doc.to_s
  end

private

  # Creates a permalink for the given section ID
  def permalink_for(section_id)
    %[ ]
  end

end
Some remarks/ideas/tips: * This code returns XHTML, not HTML (seems to be a bug or a feature in Hpricot). If you need HTML, you need to manually fix Hpricot's output. You can do so by replacing doc.to_s with doc.to_s.gsub(' />', '>'). (This is not really an elegant solution, so I'm open for feedback!) * If you're one of those HTML5 geeks, you can easy adapt the code to use the HTML5
element instead of div's with a "section" class. Simply replace doc.search('.section') with doc.search('section'). * The permalink uses the rel-bookmark microformat. * If you don't like manually assigning section IDs, you could let nanoc automatically generate the section IDs based off the text of the section header. * The permalink uses the paragraph symbol (¶). You may want to change this into something else, or even replace it with an image.