class Inkcite::Renderer::List

Public Instance Methods

render(tag, opt, ctx) click to toggle source
# File lib/inkcite/renderer/list.rb, line 5
def render tag, opt, ctx

  html = ''

  # Get the stack of list helpers which will used based on whether this is
  # a list item or a list open/close
  tag_stack = ctx.tag_stack(:list)

  # Check for the close of any list
  if tag == 'ul' || tag == 'ol'
    html << '{table}'

    # Add the type of list as an attribute so the list item can determine the
    # appropriate bullet/number.
    opt[:type] = tag

    # Initialize the child count to zero which will be incremented with each
    # list child added.
    opt[:children] = 0

    # Push the options onto the stack so they can be referenced by the list items.
    tag_stack << opt

  elsif tag == '/ul' || tag == '/ol'
    html << '</td>{/table}'

    # Remove the previously open list declaration.
    tag_stack.pop

  elsif tag == 'li'

    # Get the options declared when the list was started.
    parent_opts = tag_stack.opts

    # Increment the child count in the parent opts
    child_count = parent_opts[:children] = parent_opts[:children] + 1

    if child_count > 1

      # Add a separator between this and previous list items
      spacing = (parent_opts[:spacing] || 3).to_i
      if spacing > 0
        html << "{div height=#{spacing} line-height=#{spacing} font-size=#{spacing}}&nbsp;{/div}</td>"
      end

      # Start a new row after the previous one.
      html << '</tr><tr>'

    end

    bullet = if parent_opts[:type] == 'ol'
      "#{child_count}."
    else
      detect(opt[:bullet], parent_opts[:bullet], '&bull;')
    end

    # Lists can be repurposed sans bullets to be tables of items with
    # adjustable space between them by setting the bullet to none.
    unless none?(bullet)

      # Start a new <td> to hold the bullet and spacing.
      bullet_td = Element.new('td', :valign => :top)

      # Apply fonts to the bullet to it displays consistently.
      mix_font bullet_td, opt, ctx, parent_opts

      html << bullet_td.to_s

      # Number of non-breaking spaces to put before the bullet.
      indent = (parent_opts[:indent] || 2).to_i
      html << '&nbsp;' * indent if indent > 0

      html << bullet
      html << '&nbsp;</td>'

    end

    # Start a new <td> to hold the list item itself.
    item_td = Element.new('td')

    # Consistent font handling for the items int he list.
    mix_font item_td, opt, ctx, parent_opts

    html << item_td.to_s

  elsif tag == '/li'

    # This space left intentionally blank.  The closing {/td} is added either
    # by the next child in the list (so that vertical space can be injected into
    # /this/ list item) or by closing the list itself.

  end

  html
end