class Creole::Parser
Attributes
Allowed url schemes Examples: http https ftp ftps
Non-standard wiki text extensions enabled? E.g. underlined, deleted text etc
Disable url escaping for local links Escaping: [[/Test]] –> %2FTest No escaping: [[/Test]] –> Test
Public Class Methods
Create a new CreoleParser instance.
# File lib/creole/parser.rb, line 57 def initialize(text, options = {}) @allowed_schemes = %w(http https ftp ftps) @text = text @extensions = @no_escape = nil options.each_pair {|k,v| send("#{k}=", v) } end
Public Instance Methods
# File lib/creole/parser.rb, line 48 def extensions?; @extensions; end
# File lib/creole/parser.rb, line 54 def no_escape?; @no_escape; end
Convert CCreole text to HTML and return the result. The resulting HTML does not contain <html> and <body> tags.
Example:
parser = CreoleParser.new("**Hello //World//**", :extensions => true) parser.to_html #=> "<p><strong>Hello <em>World</em></strong></p>"
# File lib/creole/parser.rb, line 73 def to_html @out = '' @p = false @stack = [] parse_block(@text) @out end
Protected Instance Methods
# File lib/creole/parser.rb, line 116 def end_paragraph end_tag while !@stack.empty? @p = false end
# File lib/creole/parser.rb, line 100 def end_tag @out << '</' << @stack.pop << '>' end
Escape any characters with special meaning in HTML using HTML entities.
# File lib/creole/parser.rb, line 85 def escape_html(string) CGI::escapeHTML(string) end
Escape any characters with special meaning in URLs using URL encoding.
# File lib/creole/parser.rb, line 91 def escape_url(string) CGI::escape(string) end
Sanatize a direct url (e.g. wikipedia.org/). The default behaviour returns the original link as-is.
Must ensure that the result is properly URL-escaped. The caller will handle HTML escaping as necessary. Links will not be converted to HTML links if the function returns link.
Custom versions of this function in inherited classes can implement specific link handling behaviour, such as redirection to intermediate pages (for example, for notifing the user that he is leaving the site).
# File lib/creole/parser.rb, line 164 def make_direct_link(url) #:doc: url end
# File lib/creole/parser.rb, line 200 def make_explicit_link(link) begin uri = URI.parse(link) return uri.to_s if uri.scheme && @allowed_schemes.include?(uri.scheme) rescue URI::InvalidURIError end make_local_link(link) end
# File lib/creole/parser.rb, line 196 def make_headline(level, text) "<h#{level}>" << escape_html(text) << "</h#{level}>" end
Create image markup. This method can be overridden to generate custom markup, for example to add html additional attributes or to put divs around the imgs.
# File lib/creole/parser.rb, line 188 def make_image(uri, alt) if alt '<img src="' << escape_html(uri) << '" alt="' << escape_html(alt) << '"/>' else '<img src="' << escape_html(uri) << '"/>' end end
Sanatize and prefix image URLs. When images are encountered in Creole
text, this function is called to obtain the actual URL of the image. The default behaviour is to return the image link as-is. No image tags are inserted if the function returns nil.
Custom version of the method can be used to sanatize URLs (e.g. remove query-parts), inhibit off-site images, or add a base URL, for example:
def make_image_link(url) URI.join("http://mywiki.org/images/", url) end
# File lib/creole/parser.rb, line 180 def make_image_link(url) #:doc: url end
Translate an explicit local link to a desired URL that is properly URL-escaped. The default behaviour is to convert local links directly, escaping any characters that have special meaning in URLs. Relative URLs in local links are not handled.
Examples:
make_local_link("LocalLink") #=> "LocalLink" make_local_link("/Foo/Bar") #=> "%2FFoo%2FBar"
Must ensure that the result is properly URL-escaped. The caller will handle HTML escaping as necessary. HTML links will not be inserted if the function returns nil.
Example custom behaviour:
make_local_link("LocalLink") #=> "/LocalLink" make_local_link("Wikipedia:Bread") #=> "http://en.wikipedia.org/wiki/Bread"
# File lib/creole/parser.rb, line 149 def make_local_link(link) #:doc: no_escape? ? link : escape_url(link) end
# File lib/creole/parser.rb, line 312 def make_nowikiblock(input) input.gsub(/^ (?=\}\}\})/, '') end
# File lib/creole/parser.rb, line 318 def parse_block(str) until str.empty? case str when /\A\{\{\{\r?\n(.*?)\r?\n\}\}\}/m end_paragraph nowikiblock = make_nowikiblock($1) @out << '<pre>' << escape_html(nowikiblock) << '</pre>' when /\A\s*-{4,}\s*$/ end_paragraph @out << '<hr/>' when /\A\s*(={1,6})\s*(.*?)\s*=*\s*$(\r?\n)?/ end_paragraph level = $1.size @out << make_headline(level, $2) when /\A[ \t]*\|.*$(\r?\n)?/ if !@stack.include?('table') end_paragraph start_tag('table') end parse_table_row($&) when /\A\s*$(\r?\n)?/ end_paragraph when /\A(\s*([*#]+)\s*(.*?))$(\r?\n)?/ line, bullet, item = $1, $2, $3 tag = (bullet[0,1] == '*' ? 'ul' : 'ol') if bullet[0,1] == '#' || bullet.size != 2 || @stack.find {|x| ulol?(x) } count = @stack.select { |x| ulol?(x) }.size while !@stack.empty? && count > bullet.size count -= 1 if ulol?(@stack.last) end_tag end end_tag while !@stack.empty? && @stack.last != 'li' if @stack.last == 'li' && count == bullet.size end_tag if @stack.last != tag end_tag count -= 1 end end while count < bullet.size start_tag tag count += 1 start_tag 'li' if count < bullet.size end @p = true start_tag('li') parse_inline(item) else start_paragraph parse_inline(line) end when /\A([ \t]*\S+.*?)$(\r?\n)?/ start_paragraph parse_inline($1) else raise "Parse error at #{str[0,30].inspect}" end #p [$&, $'] str = $' end end_paragraph @out end
# File lib/creole/parser.rb, line 209 def parse_inline(str) until str.empty? case str when /\A(\~)?((https?|ftps?):\/\/\S+?)(?=([\,.?!:;"'\)]+)?(\s|$))/ str = $' if $1 @out << escape_html($2) else if uri = make_direct_link($2) @out << '<a href="' << escape_html(uri) << '">' << escape_html($2) << '</a>' else @out << escape_html($&) end end when /\A\[\[\s*([^|]*?)\s*(\|\s*(.*?))?\s*\]\]/m str = $' link, content = $1, $3 if uri = make_explicit_link(link) @out << '<a href="' << escape_html(uri) << '">' if content until content.empty? content = parse_inline_tag(content) end else @out << escape_html(link) end @out << '</a>' else @out << escape_html($&) end else str = parse_inline_tag(str) end end end
# File lib/creole/parser.rb, line 245 def parse_inline_tag(str) case str when /\A\{\{\{(.*?\}*)\}\}\}/ @out << '<tt>' << escape_html($1) << '</tt>' when /\A\{\{\s*(.*?)\s*(\|\s*(.*?)\s*)?\}\}/ if uri = make_image_link($1) @out << make_image(uri, $3) else @out << escape_html($&) end when /\A([:alpha:]|[:digit:])+/ @out << $& when /\A\s+/ @out << ' ' if @out[-1] != ?\s when /\A\*\*/ toggle_tag 'strong', $& when /\A\/\// toggle_tag 'em', $& when /\A\\\\/ @out << '<br/>' else if @extensions case str when /\A__/ toggle_tag 'u', $& when /\A\-\-/ toggle_tag 'del', $& when /\A\+\+/ toggle_tag 'ins', $& when /\A\^\^/ toggle_tag 'sup', $& when /\A\~\~/ toggle_tag 'sub', $& when /\A\(R\)/i @out << '®' when /\A\(C\)/i @out << '©' when /\A~([^\s])/ @out << escape_html($1) when /./ @out << escape_html($&) end else case str when /\A~([^\s])/ @out << escape_html($1) when /./ @out << escape_html($&) end end end return $' end
# File lib/creole/parser.rb, line 299 def parse_table_row(str) @out << '<tr>' str.scan(/\s*\|(=)?\s*((\[\[.*?\]\]|\{\{.*?\}\}|[^|~]|~.)*)(?=\||$)/) do if !$2.empty? || !$'.empty? @out << ($1 ? '<th>' : '<td>') parse_inline($2) if $2 end_tag while @stack.last != 'table' @out << ($1 ? '</th>' : '</td>') end end @out << '</tr>' end
# File lib/creole/parser.rb, line 121 def start_paragraph if @p @out << ' ' if @out[-1] != ?\s else end_paragraph start_tag('p') @p = true end end
# File lib/creole/parser.rb, line 95 def start_tag(tag) @stack.push(tag) @out << '<' << tag << '>' end
# File lib/creole/parser.rb, line 104 def toggle_tag(tag, match) if @stack.include?(tag) if @stack.last == tag end_tag else @out << escape_html(match) end else start_tag(tag) end end
# File lib/creole/parser.rb, line 316 def ulol?(x); x == 'ul' || x == 'ol'; end