# TextFormatter plugin allows you filter user input, before it is saved to # the database. module TextFormatter # Before Use: # # The following gems will need to be installed to make full use TextFormatter: # # gem install htmltokenizer # gem install syntax # gem install hpricot # # # If you are using the syntax highlighting or SimpleTextMarkup, copy # the css from /vender/plugins/text_formatter/stylesheets/text_formatter.css # into your css file. require 'syntax/convertors/html' require 'hpricot_text_transform' require 'simple_text_markup' # # def self.included(base) base.extend(ClassMethods) end # # strip html tags def self.stripHtmlTags(html) return html if html.blank? if html.index("<") text = "" tokenizer = HTML::Tokenizer.new(html) while token = tokenizer.next node = HTML::Node.parse(nil, 0, 0, token, false) # result is only the content of any Text nodes text << node.to_s if node.class == HTML::Text end # strip any comments, and if they have a newline at the end (ie. line with # only a comment) strip that too text.gsub(/[\n]?/m, "") else html # already plain text end end # # encode special char's and not html tags def self.escapeText(text) return nil unless text Hpricot(text).text_transform!(:except => :pre) do |text| ERB::Util::html_escape(text) end.to_s end # # encode special char's and not html tags also add new lines def self.escapeTextAndAddNewLines(text) return nil unless text Hpricot(text).text_transform!(:except => :pre) do |text| ERB::Util::html_escape(text).gsub(/\n/, "
\n") end.to_s end # # add syntax to all pre tags def self.syntaxToPreTags(pString) return pString if pString.blank? #create syntax object oSyntaxConvertor = Syntax::Convertors::HTML.for_syntax("ruby") return pString.gsub(/
(.*?)<\/pre>/m) { |pCode| addSyntax(pCode, oSyntaxConvertor)}
    end
    
    
    #
    # add syntax to a provided string and remove existing pre tags as will be replaced
    def self.addSyntax(pString, oSyntaxConvertor)
        return pString if pString.blank?
        
        return oSyntaxConvertor.convert(pString.sub(/
/, '').sub(/<\/pre>/, ''))
    end
    
    
    module ClassMethods
        
        #
        # Full technical formatting
        # Transform a given field (remove all html tags, textile, encode tags within html tags, syntax highlighting)
        # 
        # Example:
        #  tf_content_formatter :fieldname
        #  e.g. tf_content_formatter :title, :post
        # 
        def tf_content_formatter(*attr_names)
            attr_names.each do |field|
                before_save do |record|
                
                    if record[field].kind_of? String
                        #remove all html tags
                        record[field] = TextFormatter.stripHtmlTags(record[field])
                        
                        #add simple textile markup
                        record[field] = SimpleTextMarkup.new(record[field]).to_xhtml
                        
                        #encode special char's and not html tags
                        record[field] = TextFormatter.escapeTextAndAddNewLines(record[field])
                        
                        #syntax highlighting
                        record[field] = TextFormatter.syntaxToPreTags(record[field]) 
                    end
                    
                end
            end
        end      
        
        
        #
        # Formatting without syntax and pre tags
        # Transform a given field (remove all html tags, textile, encode tags within html tags)
        # 
        # Example:
        #  tf_basic_formatter :fieldname
        #  e.g. tf_basic_formatter :title, :post
        # 
        def tf_basic_formatter(*attr_names)
            attr_names.each do |field|
                before_save do |record|
                
                    if record[field].kind_of? String
                        #remove all html tags
                        record[field] = TextFormatter.stripHtmlTags(record[field])
                        
                        #add simple textile markup
                        record[field] = SimpleTextMarkup.new(record[field]).to_xhtml_basic
                        
                        #encode special char's and not html tags
                        record[field] = TextFormatter.escapeTextAndAddNewLines(record[field])
                    end
                    
                end
            end
        end 
        
        
        
        #
        # add coloured syntax to all text inside 
 tags
        # 
        # Example:
        #  tf_syntax_highlighting :fieldname
        #  e.g. tf_syntax_highlighting :title, :post
        # 
        def tf_syntax_highlighting(*attr_names)
            
            attr_names.each do |field|
                before_save do |record|                    
                    record[field] = TextFormatter.syntaxToPreTags(record[field]) if record[field].kind_of? String
                end
            end
        end
           
           
        #
        # Escape all HTML text inside tags, except pre tags from given fields
        #
        # Example:
        #  tf_escape_text_characters :fieldname
        #  e.g. tf_escape_text_characters :title, :post
        #  
        def tf_escape_text_characters(*attr_names)
            attr_names.each do |field|
                before_save do |record|
                    record[field] = TextFormatter.escapeText(record[field]) if record[field].kind_of? String
                end
            end
        end

           
        #
        # Escapes all HTML tag characters from given fields
        # 
        # Example:
        #  tf_escape_html_characters :fieldname
        #  e.g. tf_escape_html_characters :title, :post
        # 
        def tf_escape_all_html_characters(*attr_names)
            attr_names.each do |field|
                before_save do |record|
                    record[field] = ERB::Util::html_escape(record[field]) if record[field].kind_of? String
                end
            end
        end
        
          
        #
        # Removes all html tags from given fields
        # 
        # Example:
        #  tf_remove_html_tags :fieldname
        #  e.g. tf_remove_html_tags :title, :post
        # 
        def tf_remove_html_tags(*attr_names)
            attr_names.each do |field|
                before_save do |record|
                    record[field] = TextFormatter.stripHtmlTags(record[field]) if record[field].kind_of? String
                end
            end
        end
      
        
        #
        # Add Simple Text Markup (STM)
        # 
        # Example:
        #  tf_simple_text_markup :fieldname
        #  e.g. tf_simple_text_markup :title, :post
        #  
        def tf_simple_text_markup(*attr_names)
            attr_names.each do |field|
                before_save do |record|
                    record[field] = SimpleTextMarkup.new(record[field]).to_xhtml if record[field].kind_of? String
                end
            end
        end
        
 
    end #end ClassMethods
end #end module TextFormatter