class Gollum::Filter::Tags

Render all tags (things in double-square-brackets). This one's a biggie.

Constants

PREFORMATTED_TAGS

Public Instance Methods

extract(data) click to toggle source

Extract all tags into the tagmap and replace with placeholders.

# File lib/gollum-lib/filter/tags.rb, line 5
def extract(data)
  return data if @markup.format == :txt || @markup.format == :asciidoc
  data.gsub!(/(.?)\[\[(.+?)\]\]([^\[]?)/m) do
    if Regexp.last_match[1] == "'" && Regexp.last_match[3] != "'"
      "[[#{Regexp.last_match[2]}]]#{Regexp.last_match[3]}"
    elsif Regexp.last_match[2].include?('][')
      if Regexp.last_match[2][0..4] == 'file:'
        pre            = Regexp.last_match[1]
        post           = Regexp.last_match[3]
        parts          = Regexp.last_match[2].split('][')
        parts[0][0..4] = ""
        link           = "#{parts[1]}|#{parts[0].sub(/\.org/, '')}"
        id             = register_tag(link)
        "#{pre}#{id}#{post}"
      else
        Regexp.last_match[0]
      end
    else
      id = register_tag(Regexp.last_match[2])
      "#{Regexp.last_match[1]}#{id}#{Regexp.last_match[3]}"
    end
  end
  data
end
process(rendered_data) click to toggle source

Process all text nodes from the doc and replace the placeholders with the final markup.

# File lib/gollum-lib/filter/tags.rb, line 38
def process(rendered_data)
  doc  = Nokogiri::HTML::DocumentFragment.parse(rendered_data)
  doc.traverse do |node|
    if node.text? then
      content = node.content
      content.gsub!(/TAG[a-f0-9]+TAG/) do |id|
        if (tag = @map[id]) then
          if is_preformatted?(node) then
            "[[#{tag}]]"
          else
            process_tag(tag).gsub('%2f', '/')
          end
        end
      end
      node.replace(content) if content != node.content
    end
  end

  doc.to_html
end
register_tag(tag) click to toggle source
# File lib/gollum-lib/filter/tags.rb, line 30
def register_tag(tag)
  id       = "TAG#{Digest::SHA1.hexdigest(tag)}TAG"
  @map[id] = tag
  id
end

Private Instance Methods

find_page_from_name(cname) click to toggle source

Find a page from a given cname. If the page has an anchor (#) and has no match, strip the anchor and try again.

cname - The String canonical page name including path.

Returns a Gollum::Page instance if a page is found, or an Array of

Gollum::Page, String extra

if a page without the extra anchor data

is found.

# File lib/gollum-lib/filter/tags.rb, line 302
def find_page_from_name(cname)
  slash = cname.rindex('/')

  unless slash.nil?
    name = cname[slash+1..-1]
    path = cname[0..slash]
    page = @markup.wiki.paged(name, path)
  else
    page = @markup.wiki.paged(cname, '/') || @markup.wiki.page(cname)
  end

  if page
    return page
  end
  if (pos = cname.index('#'))
    [@markup.wiki.page(cname[0...pos]), cname[pos..-1]]
  end
end
is_preformatted?(node) click to toggle source
# File lib/gollum-lib/filter/tags.rb, line 63
def is_preformatted?(node)
  node && (PREFORMATTED_TAGS.include?(node.name) ||
      node.ancestors.any? { |a| PREFORMATTED_TAGS.include?(a.name) })
end
parse_image_tag_options(tag) click to toggle source

Parse any options present on the image tag and extract them into a Hash of option names and values.

tag - The String tag contents (the stuff inside the double brackets).

Returns the options Hash:

key - The String option name.
val - The String option value or true if it is a binary option.
# File lib/gollum-lib/filter/tags.rb, line 197
def parse_image_tag_options(tag)
  tag.split('|')[1..-1].inject({}) do |memo, attr|
    parts          = attr.split('=').map { |x| x.strip }
    memo[parts[0]] = (parts.size == 1 ? true : parts[1])
    memo
  end
end
process_image_tag(tag) click to toggle source

Attempt to process the tag as an image tag.

tag - The String tag contents (the stuff inside the double brackets).

Returns the String HTML if the tag is a valid image tag or nil

if it is not.
# File lib/gollum-lib/filter/tags.rb, line 122
def process_image_tag(tag)
  parts = tag.split('|')
  return if parts.size.zero?

  name = parts[0].strip
  if (file = @markup.find_file(name))
    path = ::File.join @markup.wiki.base_path, file.path
  elsif name =~ /^https?:\/\/.+(jpg|png|gif|svg|bmp)$/i
    path = name
  end

  if path
    opts = parse_image_tag_options(tag)

    containered = false

    classes = [] # applied to whatever the outermost container is
    attrs   = [] # applied to the image

    align = opts['align']
    if opts['float']
      containered = true
      align       ||= 'left'
      if %w{left right}.include?(align)
        classes << "float-#{align}"
      end
    elsif %w{top texttop middle absmiddle bottom absbottom baseline}.include?(align)
      attrs << %Q{align="#{align}"}
    elsif align
      if %w{left center right}.include?(align)
        containered = true
        classes << "align-#{align}"
      end
    end

    if (width = opts['width'])
      if width =~ /^\d+(\.\d+)?(em|px)$/
        attrs << %Q{width="#{width}"}
      end
    end

    if (height = opts['height'])
      if height =~ /^\d+(\.\d+)?(em|px)$/
        attrs << %Q{height="#{height}"}
      end
    end

    if (alt = opts['alt'])
      attrs << %Q{alt="#{alt}"}
    end

    attr_string = attrs.size > 0 ? attrs.join(' ') + ' ' : ''

    if opts['frame'] || containered
      classes << 'frame' if opts['frame']
      %Q{<span class="#{classes.join(' ')}">} +
          %Q{<span>} +
          %Q{<img src="#{path}" #{attr_string}/>} +
          (alt ? %Q{<span>#{alt}</span>} : '') +
          %Q{</span>} +
          %Q{</span>}
    else
      %Q{<img src="#{path}" #{attr_string}/>}
    end
  end
end
process_include_tag(tag) click to toggle source

Attempt to process the tag as an include tag

tag - The String tag contents (the stuff inside the double brackets).

Returns the String HTML if the tag is a valid image tag or nil

if it is not.
# File lib/gollum-lib/filter/tags.rb, line 99
def process_include_tag(tag)
  return unless /^include:/.match(tag)
  page_name          = tag[8..-1]
  resolved_page_name = ::File.expand_path(page_name, "/"+@markup.dir)

  if @markup.include_levels > 0
    page = find_page_from_name(resolved_page_name)
    if page
      page.formatted_data(@markup.encoding, @markup.include_levels-1)
    else
      html_error("Cannot include #{process_page_link_tag(resolved_page_name)} - does not exist yet")
    end
  else
    html_error("Too many levels of included pages, will not include #{process_page_link_tag(resolved_page_name)}")
  end
end
process_tag(tag) click to toggle source

Process a single tag into its final HTML form.

tag - The String tag contents (the stuff inside the double

brackets).

Returns the String HTML version of the tag.

# File lib/gollum-lib/filter/tags.rb, line 74
def process_tag(tag)
  if tag =~ /^_TOC_/
    %Q{[[#{tag}]]}
  elsif tag =~ /^_$/
    %Q{<div class="clearfloats"></div>}
  elsif (html = process_include_tag(tag))
    html
  elsif (html = process_image_tag(tag))
    html
  elsif (html = process_external_link_tag(tag))
    html
  elsif (html = process_file_link_tag(tag))
    html
  else
    process_page_link_tag(tag)
  end
end