module WikiThat::Links
Lexer
module for links and embedded media
This module deviates from standard MediaWiki in its use of namespaces and support for media tags. It is not compliant with the Wikimedia Foundation grammar.
@author Bryan T. Meyers
Lexer
module for links and embedded media
This module deviates from standard MediaWiki in its use of namespaces and support for media tags. It is not compliant with the Wikimedia Foundation grammar.
@author Bryan T. Meyers
Constants
- IMAGE_ATTRIBUTES
Property attributes for images
Public Instance Methods
Lex any link , internal or external
# File lib/wiki-that/lexer/tokens/links.rb, line 34 def lex_link count = 0 while match? LINK_SPECIAL count += 1 advance end append Token.new(:link_start, count) until end? or match? BREAK_SPECIAL lex_text(%w(: | ] )) case current when ':' value = '' if @result.last != nil && @result.last.type == :text value = @result.pop.value end append Token.new(:link_namespace, value) advance when '|' append Token.new(:link_attribute) advance when ']' count = 0 while current == ']' count += 1 advance end append Token.new(:link_end, count) return else ## do nothing end end end
Create an audio element from tokens @param [String] link the URL for the audio source @return [Element] the generated element
# File lib/wiki-that/parser/elements/links/audio.rb, line 23 def parse_audio_link(link) e = Element.new(:audio) e.set_attribute(:src, URI.escape(link)) e.set_attribute(:controls, true) e end
Create an img tag from the pre-parsed link data @param [String] link the URL for the img source @param [String] attrs the attributes for this img tag @return [String] the generated tag
# File lib/wiki-that/parser/elements/links/image.rb, line 23 def parse_image_link(link, attrs) e = Element.new(:img) e.set_attribute(:src, URI.escape(link)) if attrs.length > 0 classes = [] width = nil attrs.each do |a| if IMAGE_ATTRIBUTES.include? a classes.push(a) end if a =~ /\d+px/ width = a end end wrapper = Element.new(:figure) if classes.length > 0 wrapper.set_attribute(:class, classes.join(' ')) end if width attrs -= [width] e.set_attribute(:width, width.sub('px','')) end attrs -= classes if attrs.length > 1 warning 'Ignoring all but the last attribute' e.set_attribute(:alt, attrs.last) elsif attrs.length > 0 e.set_attribute(:alt, attrs.last) end if classes.empty? return e end wrapper.add_child(e) if classes.include?('frame') || classes.include?('thumb') || classes.include?('thumbnail') caption = Element.new(:figcaption) caption.add_child(Element.new(:text, attrs.last)) wrapper.add_child(caption) end wrapper else e end end
Parse any link , internal or external
# File lib/wiki-that/parser/elements/links.rb, line 194 def parse_link if current.value > 1 return parse_link_internal end advance url = '' while match? [:link_namespace, :text] url += current.value if match? [:link_namespace] url += ':' end advance end unless match? [:link_end] and current.value == 1 warning 'External link not closed by "]"' return Element.new(:text, "[#{url}") end advance anchor = Element.new(:a) url = url.split(' ') anchor.set_attribute(:href, URI.escape(url[0] ? url[0] : '')) if url.length > 2 anchor.add_child(Element.new(:text, url[1...url.length].join(' '))) elsif url.length == 2 anchor.add_child(Element.new(:text, url[1])) end anchor end
Parse the current text as a link to content in a namespace
# File lib/wiki-that/parser/elements/links.rb, line 38 def parse_link_internal advance url = '' namespaces = [] while match? [:link_namespace] temp = current.value.strip if temp == 'http' or temp == 'https' warning 'External link in internal link brackets?' end namespaces.push(temp) advance end attributes = [] alt = '' first = true while match? [:text] if first alt = current.value.strip if alt.start_with? '/' alt = '' end first = false else alt += current.value.strip end url += current.value.strip advance end while match? [:link_attribute] advance attr = '' while match? [:text] attr += current.value advance end if attr.length > 0 attributes.push(attr.strip) end end if not_match? [:link_end] or (match? [:link_end] and current.value != 2) warning 'Internal Link not terminated by "]]"' text = '[[' if namespaces.length > 0 text += namespaces.join(':') + ':' end text += url if attributes.length > 0 text += '|' + attributes.join('|') end if match? [:link_end] (0...current.value).each do text += ']' end advance end return Element.new(:text, text) end advance pieces = [''] if @base_url and not @base_url.empty? pieces.push(@base_url) end case namespaces.length when 0 ns_index = -1 when 1 ns_index = 0 when 2 ns_index = 1 else ns_index = 1 warning 'Ignoring all but the first two namespaces' end if ns_index == -1 or %w(Audio Image Video).include? namespaces[ns_index].capitalize if @default_namespace and not @default_namespace.empty? pieces.push(@default_namespace) end else pieces.push(namespaces[ns_index]) end unless url.start_with? '/' if @sub_url and not @sub_url.empty? pieces.push(@sub_url, '') else pieces.push('') end end if namespaces.length > 0 case namespaces[0].capitalize when 'Audio' if attributes.length > 0 warning 'Ignoring all attributes' end pieces[1] = @media_base url = pieces.join('/') + url parse_audio_link(url) when 'Image' pieces[1] = @media_base url = pieces.join('/') + url parse_image_link(url, attributes) when 'Video' if attributes.length > 0 warning 'Ignoring all attributes' end pieces[1] = @media_base url = pieces.join('/') + url parse_video_link(url) else url = pieces.join('/') + url anchor = Element.new(:a) case attributes.length when 0 if alt.empty? or alt.include? '/' anchor.add_child(Element.new(:text, url)) else anchor.add_child(Element.new(:text, alt)) end when 1 anchor.add_child(Element.new(:text, attributes.last)) else warning 'Ignoring all but the last link attribute' anchor.add_child(Element.new(:text, attributes.last)) end anchor.set_attribute(:href, URI.escape(url)) anchor end else anchor = Element.new(:a) if url.start_with? '#' url.gsub!(' ','_') anchor.set_attribute(:href,url) else url = pieces.join('/') + url anchor.set_attribute(:href, URI.escape(url)) end case attributes.length when 0 if alt.empty? or alt.include? '/' anchor.add_child(Element.new(:text, url)) else anchor.add_child(Element.new(:text, alt)) end when 1 anchor.add_child(Element.new(:text, attributes.last)) else warning 'Ignoring all but the last link attribute' anchor.add_child(Element.new(:text, attributes.last)) end anchor end end
Create a video element from tokens @param [String] link the URL for the audio source @return [Element] the generated element
# File lib/wiki-that/parser/elements/links/video.rb, line 24 def parse_video_link(link) e = Element.new(:video) e.set_attribute(:src, URI.escape(link)) e.set_attribute(:controls, true) e end