module WikiThat::HTMLTag

Lexer module for handling HTML tags @author Bryan T. Meyers

Lexer module for HTML tags @author Bryan T. Meyers

Public Instance Methods

lex_tag() click to toggle source

Lex the current text as an HTML Tag

# File lib/wiki-that/lexer/tokens/html_tag.rb, line 29
def lex_tag
  buff = current
  advance
  if end?
    append Token.new(:text, buff)
    return
  end
  case current
    when *TAG_SPECIAL
      # Escape a less-than, try again
      append Token.new(:text, '<')
      return
    when '!'
      # Lexing a Comment
      type = :comment
      buff += current
      advance
      # First '-'
      if not_match? %w(-)
        append Token.new(:text, buff)
        return
      end
      buff += current
      advance
      # Second '-'
      if not_match? %w(-)
        append Token.new(:text, buff)
        return
      end
      buff += current
      advance
      # Read Comment
      while not_match? ['-', "\n", "\r", '<']
        if end?
          append Token.new(:text, buff.gsub('<','&lt;'))
          return
        end
        buff += current
        advance
      end
      # First Closing '-'
      if not_match? %w(-)
        append Token.new(:text, buff)
        return
      end
      buff += current
      advance
      # Second Closing '-'
      if not_match? %w(-)
        append Token.new(:text, buff)
        return
      end
      buff += current
      advance
      # Closing '>'
      if not_match? %w(>)
        append Token.new(:text, buff)
        return
      end
      advance
      buff.gsub!('<!--','')
      buff.gsub!('--','')
      append Token.new(type, buff)
      return
    when '/'
      type = :tag_close
      advance
    else
      type = :tag_open
  end

  tag = ''
  until end? or match? %W(\r \n > <)
    tag += current
    advance
  end
  if end? or not_match? %w(>)
    case type
      when :tag_close
        tag = '&lt;/' + tag
      else
        tag = '&lt;' + tag
    end
    append Token.new(:text, tag)
  else
    ## Skip closing >
    advance
    # Handle special <nowiki> and <pre> tags
    if type == :tag_open and (tag == 'nowiki' or tag == 'pre')
      content = ''
      done = false
      until done or end?
        until end? or match? TAG_SPECIAL
          content += current
          advance
        end
        if end?
          break
        end
        lex_tag
        t = @result.pop
        case t.type
          when :tag_open
            content += "<#{t.value}>"
          when :tag_close
            if t.value == tag
              done = true
            else
              content += "</#{t.value}>"
            end
          else
            content += t.value
        end
      end
      append Token.new(tag.to_sym, content)
    else
      append Token.new(type, tag)
    end
  end
end
parse_nowiki() click to toggle source

Parse the current token as nowiki/pre

# File lib/wiki-that/parser/elements/html_tag.rb, line 68
def parse_nowiki
  e = Element.new(current.type, current.value)
  @line += current.value.count("\r\n")
  advance
  e
end
parse_tag() click to toggle source

Parse the current token as an HTML tag

# File lib/wiki-that/parser/elements/html_tag.rb, line 25
def parse_tag
  case current.type
    when :comment
      tag = Element.new(:comment, current.value)
      @line += current.value.count("\r\n")
      advance
    when :tag_close
      tag = Element.new(:text, "</#{current.value}>")
      advance
    else
      name = current.value
      if name.end_with? '/'
        name.chop!
        name.strip!
        advance
        return Element.new(name.to_sym)
      end
      if name == 'br'
        advance
        return Element.new(name.to_sym)
      end
      tag = Element.new(name.to_sym)
      advance
      until end? or match? [:tag_close]
        p = parse_inline
        tag.add_children(*p)
        if match? [:break]
          @line += current.value
          advance
        end
      end
      if not_match? [:tag_close]
        warning "HTML tag '#{name}' not terminated, but closing anyways"
      else
        advance
      end
  end
  tag
end