class WikiCloth::WikiBuffer::HTMLElement

Constants

ALLOWED_ATTRIBUTES
ALLOWED_ELEMENTS
DISABLE_GLOBALS_FOR
ESCAPED_TAGS
NO_NEED_TO_CLOSE
SHORT_TAGS

Public Class Methods

new(d="",options={},check=nil) click to toggle source
Calls superclass method WikiCloth::WikiBuffer::new
# File lib/wikicloth/wiki_buffer/html_element.rb, line 17
def initialize(d="",options={},check=nil)
  super("",options)
  self.buffer_type = "Element"
  @in_quotes = false
  @in_single_quotes = false
  @start_tag = 1
  @tag_check = check
end

Public Instance Methods

debug() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 26
def debug
  case self.element_name
  when "template"
    self.get_param("__name")
  else
    ret = self.class.to_s + "["
    ret += self.element_name
    tmp = self.get_param("id")
    ret += tmp.nil? ? "" : "##{tmp}"
    ret + "]"
  end
end
element_attributes() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 102
def element_attributes
  attr = {}
  params.each { |p| attr[p[:name]] = p[:value] if p.kind_of?(Hash) }
  if ALLOWED_ELEMENTS.include?(self.element_name.strip.downcase)
    attr.delete_if { |key,value| !ALLOWED_ATTRIBUTES.include?(key.strip) }
  end
  return attr
end
element_content() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 115
def element_content
  @econtent ||= ""
end
element_name() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 111
def element_name
  @ename ||= ""
end
get_attribute_by_name(name) click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 97
def get_attribute_by_name(name)
  params.each { |p| return p[:value] if p.kind_of?(Hash) && p[:name] == name }
  nil
end
run_globals?() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 44
def run_globals?
  return false if self.in_template? && self.element_name == "noinclude"
  return false if !self.in_template? && self.element_name == "includeonly"
  return Extension.run_globals?(self.element_name) if Extension.element_exists?(self.element_name)
  return DISABLE_GLOBALS_FOR.include?(self.element_name) ? false : true
end
skip_html?() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 39
def skip_html?
  return Extension.skip_html?(self.element_name) if Extension.element_exists?(self.element_name)
  DISABLE_GLOBALS_FOR.include?(self.element_name) ? true : false
end
to_html() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 51
def to_html
  if NO_NEED_TO_CLOSE.include?(self.element_name)
    return "<#{self.element_name} />" if SHORT_TAGS.include?(self.element_name)
    return "</#{self.element_name}><#{self.element_name}>" if @tag_check == self.element_name
  end

  if ESCAPED_TAGS.include?(self.element_name)
    # remove empty first line
    self.element_content = $1 if self.element_content =~ /^\s*\n(.*)$/m
    # escape all html inside this element
    self.element_content = self.element_content.gsub('<','&lt;').gsub('>','&gt;')
    # hack to fix <code><nowiki> nested mess
    self.element_content = self.element_content.gsub(/&lt;[\/]*\s*nowiki\s*&gt;/,'')
  end

  case self.element_name
  when "template"
    @options[:link_handler].cache({ :name => self.element_attributes["__name"], :content => self.element_content, :md5 => self.element_attributes["__hash"] })
    return self.element_content
  when "noinclude"
    return self.in_template? ? "" : self.element_content
  when "includeonly"
    return self.in_template? ? self.element_content : ""
  when "nowiki"
    return self.element_content
  when "a"
    if self.element_attributes['href'] =~ /:\/\//
      return @options[:link_handler].external_link(self.element_attributes['href'], self.element_content)
    elsif self.element_attributes['href'].nil? || self.element_attributes['href'] =~ /^\s*([\?\/])/
      # if a element has no href attribute, or href starts with / or ?
      return elem.tag!(self.element_name, self.element_attributes) { |x| x << self.element_content }
    end
  else
    if Extension.element_exists?(self.element_name)
      return Extension.html_elements[self.element_name][:klass].new(@options).instance_exec( self, &Extension.html_elements[self.element_name][:block] ).to_s
    end
  end

  tmp = elem.tag!(self.element_name, self.element_attributes) { |x| x << self.element_content }
  unless ALLOWED_ELEMENTS.include?(self.element_name)
    tmp.gsub!(/[\-!\|&"\{\}\[\]]/) { |r| self.escape_char(r) }
    return tmp.gsub('<', '&lt;').gsub('>', '&gt;')
  end
  tmp
end

Protected Instance Methods

elem() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 144
def elem
  Builder::XmlMarkup.new
end
element_content=(val) click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 152
def element_content=(val)
  @econtent = val
end
element_name=(val) click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 148
def element_name=(val)
  @ename = val
end
escape_char(c) click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 121
def escape_char(c)
  c = case c
  when '-' then '&#45;'
  when '!' then '&#33;'
  when '|' then '&#124;'
  when '&' then '&amp;'
  when '"' then '&quot;'
  when '{' then '&#123;'
  when '}' then '&#125;'
  when '[' then '&#91;'
  when ']' then '&#93;'
  when '*' then '&#42;'
  when '#' then '&#35;'
  when ':' then '&#58;'
  when ';' then '&#59;'
  when "'" then '&#39;'
  when '=' then '&#61;'
  else
    c
  end
  return c
end
in_quotes?() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 156
def in_quotes?
  @in_quotes || @in_single_quotes ? true : false
end
new_char() click to toggle source
# File lib/wikicloth/wiki_buffer/html_element.rb, line 160
def new_char()
  case
  # tag name
  when @start_tag == 1 && current_char == ' '
    self.element_name = self.data.strip.downcase
    self.data = ""
    @start_tag = 2

  # tag is closed <tag/> no attributes
  when @start_tag == 1 && previous_char == '/' && current_char == '>'
    self.data.chop!
    self.element_name = self.data.strip.downcase
    self.data = ""
    @start_tag = 0
    return false

  # open tag
  when @start_tag == 1 && previous_char != '/' && current_char == '>'
    self.element_name = self.data.strip.downcase
    self.data = ""
    @start_tag = 0
    return false if SHORT_TAGS.include?(self.element_name)
    return false if self.element_name == @tag_check && NO_NEED_TO_CLOSE.include?(self.element_name)

  # new tag attr
  when @start_tag == 2 && current_char == ' ' && self.in_quotes? == false
    self.current_param = self.data
    self.data = ""
    self.params << ""

  # tag attribute name
  when @start_tag == 2 && current_char == '=' && self.in_quotes? == false
    self.current_param = self.data
    self.data = ""
    self.name_current_param()

  # tag is now open
  when @start_tag == 2 && previous_char != '/' && current_char == '>'
    self.current_param = self.data
    self.data = ""
    @start_tag = 0
    return false if SHORT_TAGS.include?(self.element_name)
    return false if self.element_name == @tag_check && NO_NEED_TO_CLOSE.include?(self.element_name)

  # tag is closed <example/>
  when @start_tag == 2 && previous_char == '/' && current_char == '>'
    self.current_param = self.data.chop
    self.data = ""
    @start_tag = 0
    return false

  # in quotes
  when @start_tag == 2 && current_char == "'" && previous_char != '\\' && !@in_quotes
    @in_single_quotes = !@in_single_quotes

  # in quotes
  when @start_tag == 2 && current_char == '"' && previous_char != '\\' && !@in_single_quotes
    @in_quotes = !@in_quotes

  # start of a closing tag
  when @start_tag == 0 && previous_char == '<' && current_char == '/'
    self.element_content += self.data.chop
    self.data = ""
    @start_tag = 5

  when @start_tag == 5 && (current_char == '>' || current_char == ' ') && !self.data.blank?
    self.data = self.data.strip.downcase
    if self.data == self.element_name
      self.data = ""
      return false
    else
      if @tag_check == self.data && NO_NEED_TO_CLOSE.include?(self.element_name)
        self.data = "</#{self.data}>"
        return false
      else
        self.element_content += skip_html? ? "</#{self.data}>" : "&lt;/#{self.data}&gt;"
        @start_tag = 0
        self.data = ""
      end
    end

  else
    if @start_tag == 0 && ESCAPED_TAGS.include?(self.element_name)
      self.data << self.escape_char(current_char)
    else
      self.data << current_char
    end
  end
  return true
end