class Gollum::Filter::Tags
Render all tags (things in double-square-brackets). This one's a biggie.
Constants
- PREFORMATTED_TAGS
Public Instance Methods
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 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
# 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 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 308 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
# 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 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 203 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
Return the String HTML if the tag is a valid external link tag or nil if it is not.
# File lib/gollum-lib/filter/tags.rb, line 213 def process_external_link_tag(tag) parts = tag.split('|') parts.reverse! if @markup.reverse_links? return if parts.size.zero? if parts.size == 1 url = parts[0].strip else name, url = *parts.compact.map(&:strip) end accepted_protocols = @markup.wiki.sanitization.protocols['a']['href'].dup if accepted_protocols.include?(:relative) accepted_protocols.select!{|protocol| protocol != :relative} regexp = %r{^((#{accepted_protocols.join("|")}):)?(//)} else regexp = %r{^((#{accepted_protocols.join("|")}):)} end if url =~ regexp if name.nil? %Q{<a href="#{url}">#{url}</a>} else %Q{<a href="#{url}">#{name}</a>} end else nil end end
Attempt to process the tag as a file link tag.
tag - The String tag contents (the stuff inside the double
brackets).
Returns the String HTML if the tag is a valid file link tag or nil
if it is not.
# File lib/gollum-lib/filter/tags.rb, line 248 def process_file_link_tag(tag) parts = tag.split('|') return if parts.size.zero? name = parts[0].strip path = parts[1] && parts[1].strip if path && file = @markup.find_file(path) path = ::File.join @markup.wiki.base_path, file.path else path = nil end if name && path && file %Q{<a href="#{::File.join @markup.wiki.base_path, file.path}">#{name}</a>} elsif name && path %Q{<a href="#{path}">#{name}</a>} else nil end end
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 elsif name =~ /.+(jpg|png|gif|svg|bmp)$/i # If is image, file not found and no link, then populate with empty String # We can than add an image not found alt attribute for this later path = "" 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 path != "" && (alt = opts['alt']) attrs << %Q{alt="#{alt}"} elsif path == "" attrs << %Q{alt="Image not found"} 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
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
Attempt to process the tag as a page link tag.
tag - The String tag contents (the stuff inside the double
brackets).
Returns the String HTML if the tag is a valid page link tag or nil
if it is not.
# File lib/gollum-lib/filter/tags.rb, line 276 def process_page_link_tag(tag) parts = tag.split('|') parts.reverse! if @markup.reverse_links? name, page_name = *parts.compact.map(&:strip) cname = @markup.wiki.page_class.cname(page_name || name) presence = "absent" link_name = cname page, extra = find_page_from_name(cname) if page link_name = @markup.wiki.page_class.cname(page.name) presence = "present" end link = ::File.join(@markup.wiki.base_path, page ? page.escaped_url_path : CGI.escape(link_name)) # //page is invalid # strip all duplicate forward slashes using helpers.rb trim_leading_slash # //page => /page link = trim_leading_slash link %Q{<a class="internal #{presence}" href="#{link}#{extra}">#{name}</a>} end
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