require 'cgi' require 'nokogiri' module DText def parse(str) state = ['newline'] result = "" # Normalize newlines. str.strip str.gsub!(/(\r?\n)/, "\n") str.gsub!(/\n{3,}/, "\n\n") str = CGI.escapeHTML str # Keep newline, use carriage return for split. str.gsub!("\n", "\n\r") data = str.split("\r") # Parse header and list first, line by line. data.each do |d| result << parseline(d, state) end # Parse inline tags as a whole. result = parseinline(result) # Nokogiri ensures valid html output. Nokogiri::HTML::DocumentFragment.parse(result).to_html end def parseinline(str) # Short links subtitution: str.gsub!(/\[\[(.+?)\]\]/) do # [[title]] or [[title|label]] ;link to wiki data = $1.split('|', 2) title = data[0] label = data[1].nil? ? title : data[1] "#{label}" end str.gsub!(/\{\{(.+?)\}\}/) do # {{post tags here}} ;search post with tags "#{$1}" end # Miscellaneous single line tags subtitution. str.gsub! /\[b\](.+?)\[\/b\]/, '\1' str.gsub! /\[i\](.+?)\[\/i\]/, '\1' str.gsub! /(post #(\d+))/i, '\1' str.gsub! /(forum #(\d+))/i, '\1' str.gsub! /(comment #(\d+))/i, '\1' str.gsub! /(pool #(\d+))/i, '\1' # Single line spoiler tags. str.gsub! /\[spoilers?\](.+?)\[\/spoilers?\]/, 'spoiler' str.gsub! /\[spoilers?=(.+?)\](.+?)\[\/spoilers?\]/, '\1' # Multi line spoiler tags. str.gsub! /\[spoilers?\]/, 'spoiler