# 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