class JsDuck::Format::HtmlStack

Tracks opening and closing of HTML tags, with the purpose of closing down the unfinished tags.

See Format::Doc#replace for the use of this class.

Constants

VOID_TAGS

Tags that don't require closing

Public Class Methods

new(ignore_html={}, doc_context={}) click to toggle source

Initializes the stack with two optional parameters:

@param ignore_html A hash of additional HTML tags that don't need closing. @param doc_context Filename and linenr of the current doc-comment.

# File lib/jsduck/format/html_stack.rb, line 16
def initialize(ignore_html={}, doc_context={})
  @ignore_html = ignore_html
  @doc_context = doc_context
  @open_tags = []
end

Public Instance Methods

close(s) click to toggle source

Scans a closing tag in HTML using the passed in StringScanner.

# File lib/jsduck/format/html_stack.rb, line 28
def close(s)
  s.scan(/<\//)
  tag = s.scan(/\w+/)
  s.scan(/>/)

  pop_tags(tag).map {|t| "</#{t}>" }.join
end
open(s) click to toggle source

Scans an opening tag in HTML using the passed in StringScanner.

# File lib/jsduck/format/html_stack.rb, line 23
def open(s)
  s.scan(/</) + push_tag(s.scan(/\w+/)) + s.scan_until(/>|\Z/)
end
open?(tag) click to toggle source

True when the tag is currently open.

# File lib/jsduck/format/html_stack.rb, line 43
def open?(tag)
  @open_tags.include?(tag)
end
push_tag(tag) click to toggle source

Registers opening of a tag. Returns the tag.

# File lib/jsduck/format/html_stack.rb, line 37
def push_tag(tag)
  @open_tags.push(tag) unless void?(tag)
  tag
end

Private Instance Methods

pop_tags(tag) click to toggle source

Registers closing of a tag. Returns all the tags that need to be closed at that point.

# File lib/jsduck/format/html_stack.rb, line 51
def pop_tags(tag)
  if !@open_tags.include?(tag)
    if @ignore_html[tag]
      return [tag]
    else
      warn_unopened(tag)
      return []
    end
  end

  popped = []
  begin
    popped << t = @open_tags.pop
    if t != tag
      warn_unclosed(t)
    end
  end until t == tag

  popped
end
void?(tag) click to toggle source
# File lib/jsduck/format/html_stack.rb, line 85
def void?(tag)
  VOID_TAGS[tag] || @ignore_html[tag]
end
warn(msg, tags) click to toggle source
# File lib/jsduck/format/html_stack.rb, line 80
def warn(msg, tags)
  tag_list = tags.map {|tag| "<#{tag}>" }.join(", ")
  Logger.warn(:html, "#{msg}: #{tag_list}", @doc_context)
end
warn_unclosed(*tags) click to toggle source
# File lib/jsduck/format/html_stack.rb, line 76
def warn_unclosed(*tags)
  warn("Unclosed HTML tag", tags)
end
warn_unopened(*tags) click to toggle source
# File lib/jsduck/format/html_stack.rb, line 72
def warn_unopened(*tags)
  warn("Unopened HTML tag", tags)
end