class Bizside::Redmine::HtmlToTextile::Converter

SAX parser

Constants

BLOCK

Typical block elements

CLOSING_TAGS

Maps tokens for closing tags

INLINE

Note that th/td in Textile are sort of inline despite truly being block

OPENING_TAGS

Maps tokens for opening tags

ROW

This is kinda a special case for block elements

SHARED_TAGS

Maps tokens for opening and closing tags

Attributes

converted[R]
original[R]
stack[R]

Public Class Methods

new() click to toggle source
# File lib/bizside/redmine/html_to_textile.rb, line 60
def initialize
  @converted = ''
  @stack = []
end

Public Instance Methods

characters(text) click to toggle source

Normal character stream

# File lib/bizside/redmine/html_to_textile.rb, line 105
def characters(text)
  # # Newlines should not be treated like <br /> tags, however don't indent
  # on new lines so consume any preceeding whitespace
  content = CGI.unescapeHTML(text).gsub(NEWLINE, ' ')
  content.rstrip! if content.ends_with? NEWLINE
  content.lstrip! if converted.ends_with? NEWLINE
  converted << content
end
end_element(tag_name) click to toggle source

Closing tag callback

# File lib/bizside/redmine/html_to_textile.rb, line 90
def end_element(tag_name)
  element, attribs = stack.pop
  spaces = spacing(element)
  closing = CLOSING_TAGS[element].to_s

  # Deal with cases for a/img
  converted << case element
    when :a
      special_ending(attribs['title']) + closing + attribs['href'].to_s
    else closing
  end
  append_white(spaces)
end
start_element(tag_name, attributes = []) click to toggle source

Opening tag callback

# File lib/bizside/redmine/html_to_textile.rb, line 66
def start_element(tag_name, attributes = [])
  # Preprocess, and push to stack
  element = tag_name.downcase.to_sym
  attribs = Hash[attributes]
  opening = OPENING_TAGS[element].to_s.dup
  styling = prepare_styles(attribs, element)
  spaces = spacing(element)
  stack << [element, attribs]

  # Styling info gets positioned depending on element type
  content = case
    when BLOCK.include?(element)
      opening.sub('.', styling + '.')
    when ROW.include?(element)
      (styling.empty?) ? opening + ' ' : opening + styling + ('.' if :td == element).to_s + ' '
    else opening + styling
  end

  # add white space & content
  append_white(spaces)
  converted << content
end

Private Instance Methods

append_white(spacing) click to toggle source

Put white space at the end, but only if required

# File lib/bizside/redmine/html_to_textile.rb, line 117
def append_white(spacing)
  (- spacing.size).upto(-1) do |i|
    space, last = spacing[i], converted[i]
    converted << space unless space == last or NEWLINE == last
  end
end
prepare_styles(attribs, element) click to toggle source

Create styles, id, CSS classes, colspans, padding

# File lib/bizside/redmine/html_to_textile.rb, line 125
def prepare_styles(attribs, element)
  styling = attribs['class'].to_s.split(/\s+/)
  styling << '#' + attribs['id'] unless attribs['id'].blank?
  [].tap do |items|
    styles = attribs['style'].to_s.dup.strip
    unless styles.blank?
      items << '{%s}' % styles unless styles.blank?
    end
    items << '(%s)' % styling.join(' ') unless styling.empty?
  end.join
end
spacing(element) click to toggle source

Get spacing gap for a tag

# File lib/bizside/redmine/html_to_textile.rb, line 143
def spacing(element)
  return NEWLINE * 2 if BLOCK.include? element
  return NEWLINE if ROW.include? element
  ''
end
special_ending(text) click to toggle source

For special case closing tags (a and img)

# File lib/bizside/redmine/html_to_textile.rb, line 138
def special_ending(text)
  (text.present?) ? '(%s)' % text : ''
end