# frozen_string_literal: true module ActiveCleaner # = MarkdownCleaner # # Cleans a string by squishing all the extra space characters, but preserves new lines # (with a max of 2 successive new lines) and spaces in the beginning of lines (the indentation). # # Useful for Markdown. # # It turns " My todo \n * todo 1 \n * todo 2 \t " into "My todo\n * todo 1\n * todo 2". # # == Options # # [:nilify] # Whether or not set the field to +nil+ when the field was or is cleaned to "". # Default to +false+. # # == Example # # class Article # include ActiveCleaner # # clean :body, as: :markdown # end # # article = Article.new(body: " My todo \n * todo 1 \n * todo 2 \t ") # article.save # article.body # # => "My todo\n * todo 1\n * todo 2" class MarkdownCleaner < BaseCleaner # Cleans the value. def clean_value(old_value, _record = nil) case old_value when String value = old_value.dup value.strip! # clean the new lines mess among OS value.gsub!(/\r\n|\r/, "\n") # protect stuff to keep with a markup value.gsub!(/\n/, "__NEW_LINE__") value.gsub!(/(?<=__NEW_LINE__)\s+/) { |match| match.gsub(/\s/, "__SPACE__") } value.gsub!(/\s+/, " ") value.gsub!(/(__SPACE__|\s)*__NEW_LINE__\s*/, "__NEW_LINE__") value.gsub!(/(__NEW_LINE__){3,}/, "__NEW_LINE____NEW_LINE__") # reverse the safe markup value.gsub!(/__NEW_LINE__/, "\n") value.gsub!(/__SPACE__/, " ") value else old_value end end end end