class Typeout
Constants
- VERSION
Public Class Methods
convert(text, sanitize = true)
click to toggle source
# File lib/typeout.rb, line 9 def self.convert(text, sanitize = true) self.new(text.to_s).to_html(sanitize) end
Public Instance Methods
archive(text)
click to toggle source
# File lib/typeout.rb, line 76 def archive(text) @archive << text "!a!r!c!h!i!v!e!#{@archive.length-1}!a!r!c!h!i!v!e!" # nobody's going to type that! end
archive_blockquotes(text)
click to toggle source
# File lib/typeout.rb, line 69 def archive_blockquotes(text) text.gsub(/^~{3,}\n(.+?)\n~{3,}$/m) do content = remove_excess_newlines(make_paragraphs(make_lists("\n\n#{$1}\n\n"))) # blockquotes support paragraphs and lists archive("<blockquote>#{content}</blockquote>") end end
archive_code(text)
click to toggle source
# File lib/typeout.rb, line 64 def archive_code(text) text = text.gsub(/^-{3,}\n(.+?)\n-{3,}$/m) { archive("<pre><code>#{$1}</code></pre>") } text.gsub(/`(?!\s)((?:\s*\S)+?)`/) { archive("<code>#{$1}</code>") } end
archive_html(text)
click to toggle source
# File lib/typeout.rb, line 60 def archive_html(text) text.gsub(/\[html\](.*?)\[\/html\]/mi) { archive(sanitize_html($1)) } end
clean_whitespace(text)
click to toggle source
# File lib/typeout.rb, line 50 def clean_whitespace(text) text.gsub(/\r\n/, "\n"). gsub(/\r/, "\n"). gsub(/^ +$/, '') end
make_breaks(text)
click to toggle source
# File lib/typeout.rb, line 122 def make_breaks(text) text.gsub(/([^\n])\n(?!\n)/m, "\\1<br />\n") end
make_headings(text)
click to toggle source
# File lib/typeout.rb, line 88 def make_headings(text) text.gsub(/^(={1,6})(.+?)=*?$/) do depth = $1.length "\n\n<h#{depth}>#{$2.strip}</h#{depth}>\n\n" end end
make_inlines(text)
click to toggle source
# File lib/typeout.rb, line 126 def make_inlines(text) text = text. gsub(/^((?: ?[\w\(\)']){3,}:) (?!\s*$)/, '<b>\1</b> '). # spaces are not allowed directly in front of the colon, there must be a space after it, and the rest of the line can't be blank gsub(/!\((.+?)\)(?:\:([a-zA-Z0-9\_]+))?/) do if $2 "<img src=\"#{archive($1)}\" class=\"#{$2}\" />" else "<img src=\"#{archive($1)}\" />" end end. gsub(/\[(.+?)\]\((.+?)\)(?:\:([a-zA-Z0-9\_]+))?/) do if $3 "<a href=\"#{archive($2)}\" class=\"#{$3}\">#{archive($1)}</a>" else "<a href=\"#{archive($2)}\">#{archive($1)}</a>" end end. gsub(/([a-z0-9\.\-\_\+]+)@((?:[a-z0-9\-]{2,}\.)*)([a-z0-9\-]+\.)(com|org|net|biz|edu|info|gov|co\.uk|co\.us)/i) do "<a href=\"mailto:#{archive($1 + '@' + $2 + $3 + $4)}\">#{archive($1 + '@' + $2 + $3 + $4)}</a>" end. gsub(/(https?:\/\/)?((?:[a-z0-9\-]{2,}\.)*)([a-z0-9\-]+\.)(com|org|net|biz|edu|info|gov|co\.uk|co\.us)((?:\/(?:\.?[a-z0-9\-_=\?&;\%#]+)+)*\/?)/i) do # some of the magic in here is to not grab periods at the end of URLs if $1.nil? protocol = 'http://' else protocol = $1 end "<a href=\"#{archive(protocol + $2 + $3 + $4 + $5)}\">#{archive(protocol + $2 + $3 + $4 + $5)}</a>" end inlines = [ ['*', 'strong'], ['_', 'em'], ['`', 'code'], ['^', 'sup'], ['~', 'sub'] ] inlines.each do |char, tag| char = Regexp.escape(char) re = /#{char} # the opening character (?!\s) # no spaces directly after the char ( # main capture group (?:\s*\S)+? # because of no lookbehinds, every space must be followed by a non-space ) # with lookbehinds, the whole regex is: \*(?! )(.+?)(?<! )\* #{char}/x # closing character, no spaces directly before it #re = /#{char}(.+?)#{char}/ text.gsub!(re, "<#{tag}>\\1</#{tag}>") end text end
make_lists(text, base_level = nil)
click to toggle source
# File lib/typeout.rb, line 95 def make_lists(text, base_level = nil) text.gsub(/^(#{Regexp.escape(base_level.to_s)}[\*\#])[\*\#]* [^\n]+?\n(?:\1[\*\#]* (?:[^\n])+?\n)*/m) do |content| level = $1 content = make_lists(content, level) content = content.gsub(/^#{Regexp.escape(level)} (.+)$/, '<li>\1</li>') content = content.gsub(/<\/li>\n<([uo])l>/m, '<\1l>') if level.last == "*" # its an unordered list content = "<ul>\n#{content}</ul>" else content = "<ol>\n#{content}</ol>" end if base_level content += "</li>\n" else content += "\n" end content end end
make_paragraphs(text)
click to toggle source
# File lib/typeout.rb, line 118 def make_paragraphs(text) text.gsub(/^(?!<|!a!r!c!h!i!v!e!)([^\n]+\n)+\n/m) { |content| "\n\n<p>\n#{make_breaks(content.strip)}</p>\n\n" } end
remove_excess_newlines(text)
click to toggle source
# File lib/typeout.rb, line 56 def remove_excess_newlines(text) text.gsub(/\n{3,}/, "\n\n") end
retrieve_archive(text)
click to toggle source
# File lib/typeout.rb, line 81 def retrieve_archive(text) @archive.each_with_index do |content, index| text = text.sub("!a!r!c!h!i!v!e!#{index}!a!r!c!h!i!v!e!") { content } # the block is so gsub won't substitute \& end text end
sanitize_html(text)
click to toggle source
# File lib/typeout.rb, line 42 def sanitize_html(text) if @sanitize Sanitize.clean(text, Sanitize::Config::RELAXED) else text end end
to_html(sanitize = true)
click to toggle source
# File lib/typeout.rb, line 13 def to_html(sanitize = true) @sanitize = sanitize text = self.dup text = clean_whitespace text text = "\n\n#{text}\n\n" # a few guaranteed newlines @archive = [] text = archive_html text text = html_escape text text = archive_code text text = archive_blockquotes text text = make_headings text text = make_lists text text = make_paragraphs text text = make_inlines text text = remove_excess_newlines text text = retrieve_archive text text end