This repository has been archived by the owner on May 1, 2022. It is now read-only.
forked from defunkt/acts_as_textiled
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change module to ActsAsSanitiled, add rails/init.rb, and tidy up requ…
…ires
- Loading branch information
Showing
4 changed files
with
99 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,132 +1,122 @@ | ||
require 'sanitize' unless defined? Sanitize | ||
require 'rubygems' | ||
require 'sanitize' | ||
require 'RedCloth' | ||
|
||
begin | ||
require 'RedCloth' unless defined? RedCloth | ||
rescue LoadError | ||
nil | ||
end | ||
|
||
module Err | ||
module Acts #:nodoc: all | ||
module Textiled | ||
def self.included(klass) | ||
klass.extend ClassMethods | ||
end | ||
module ActsAsSanitiled #:nodoc: all | ||
def self.included(klass) | ||
klass.extend ClassMethods | ||
end | ||
|
||
module ClassMethods | ||
def acts_as_textiled(*attributes) | ||
@textiled_attributes ||= [] | ||
module ClassMethods | ||
def acts_as_textiled(*attributes) | ||
@textiled_attributes ||= [] | ||
|
||
@textiled_unicode = String.new.respond_to? :chars | ||
@textiled_unicode = String.new.respond_to? :chars | ||
|
||
options = attributes.last.is_a?(Hash) ? attributes.pop : {} | ||
skip_textile = options.delete(:skip_textile) | ||
skip_sanitize = options.delete(:skip_sanitize) | ||
options = attributes.last.is_a?(Hash) ? attributes.pop : {} | ||
skip_textile = options.delete(:skip_textile) | ||
skip_sanitize = options.delete(:skip_sanitize) | ||
|
||
raise 'Both textile and sanitize were skipped' if skip_textile && skip_sanitize | ||
raise 'Both textile and sanitize were skipped' if skip_textile && skip_sanitize | ||
|
||
sanitize_options = options.empty? ? Sanitize::Config::RELAXED : options | ||
red_cloth_options = attributes.last && attributes.last.is_a?(Array) ? attributes.pop : [] | ||
sanitize_options = options.empty? ? Sanitize::Config::RELAXED : options | ||
red_cloth_options = attributes.last && attributes.last.is_a?(Array) ? attributes.pop : [] | ||
|
||
raise 'No attributes were specified to filter' if attributes.empty? | ||
raise 'No attributes were specified to filter' if attributes.empty? | ||
|
||
type_options = %w( plain source ) | ||
type_options = %w( plain source ) | ||
|
||
attributes.each do |attribute| | ||
define_method(attribute) do |*type| | ||
type = type.first | ||
attributes.each do |attribute| | ||
define_method(attribute) do |*type| | ||
type = type.first | ||
|
||
if type.nil? && self[attribute] | ||
if textiled[attribute.to_s].nil? | ||
string = self[attribute] | ||
string = RedCloth.new(string, red_cloth_options).to_html unless skip_textile | ||
string = Sanitize.clean(string, sanitize_options) unless skip_sanitize | ||
textiled[attribute.to_s] = string | ||
end | ||
textiled[attribute.to_s] | ||
elsif type.nil? && self[attribute].nil? | ||
nil | ||
elsif type_options.include?(type.to_s) | ||
send("#{attribute}_#{type}") | ||
else | ||
raise "I don't understand the `#{type}' option. Try #{type_options.join(' or ')}." | ||
end | ||
if type.nil? && self[attribute] | ||
if textiled[attribute.to_s].nil? | ||
string = self[attribute] | ||
string = RedCloth.new(string, red_cloth_options).to_html unless skip_textile | ||
string = Sanitize.clean(string, sanitize_options) unless skip_sanitize | ||
textiled[attribute.to_s] = string | ||
end | ||
|
||
define_method("#{attribute}_plain", proc { strip_redcloth_html(__send__(attribute)) if __send__(attribute) } ) | ||
define_method("#{attribute}_source", proc { __send__("#{attribute}_before_type_cast") } ) | ||
|
||
@textiled_attributes << attribute | ||
textiled[attribute.to_s] | ||
elsif type.nil? && self[attribute].nil? | ||
nil | ||
elsif type_options.include?(type.to_s) | ||
send("#{attribute}_#{type}") | ||
else | ||
raise "I don't understand the `#{type}' option. Try #{type_options.join(' or ')}." | ||
end | ||
|
||
include Err::Acts::Textiled::InstanceMethods | ||
end | ||
|
||
def textiled_attributes | ||
Array(@textiled_attributes) | ||
end | ||
define_method("#{attribute}_plain", proc { strip_redcloth_html(__send__(attribute)) if __send__(attribute) } ) | ||
define_method("#{attribute}_source", proc { __send__("#{attribute}_before_type_cast") } ) | ||
|
||
@textiled_attributes << attribute | ||
end | ||
|
||
module InstanceMethods | ||
def textiled | ||
textiled? ? (@textiled ||= {}) : @attributes.dup | ||
end | ||
include ActsAsSanitiled::InstanceMethods | ||
end | ||
|
||
def textiled? | ||
@is_textiled != false | ||
end | ||
def textiled_attributes | ||
Array(@textiled_attributes) | ||
end | ||
end | ||
|
||
def textiled=(bool) | ||
@is_textiled = !!bool | ||
end | ||
module InstanceMethods | ||
def textiled | ||
textiled? ? (@textiled ||= {}) : @attributes.dup | ||
end | ||
|
||
def textilize | ||
self.class.textiled_attributes.each { |attr| __send__(attr) } | ||
end | ||
def textiled? | ||
@is_textiled != false | ||
end | ||
|
||
def reload | ||
textiled.clear | ||
super | ||
end | ||
def textiled=(bool) | ||
@is_textiled = !!bool | ||
end | ||
|
||
def write_attribute(attr_name, value) | ||
textiled[attr_name.to_s] = nil | ||
super | ||
end | ||
def textilize | ||
self.class.textiled_attributes.each { |attr| __send__(attr) } | ||
end | ||
|
||
private | ||
def strip_redcloth_html(html) | ||
returning html.dup.gsub(html_regexp, '') do |h| | ||
redcloth_glyphs.each do |(entity, char)| | ||
sub = [ :gsub!, entity, char ] | ||
@textiled_unicode ? h.chars.send(*sub) : h.send(*sub) | ||
end | ||
end | ||
end | ||
def reload | ||
textiled.clear | ||
super | ||
end | ||
|
||
def redcloth_glyphs | ||
[[ '’', "'" ], | ||
[ '‘', "'" ], | ||
[ '<', '<' ], | ||
[ '>', '>' ], | ||
[ '”', '"' ], | ||
[ '“', '"' ], | ||
[ '…', '...' ], | ||
[ '\1—', '--' ], | ||
[ ' → ', '->' ], | ||
[ ' – ', '-' ], | ||
[ '×', 'x' ], | ||
[ '™', '(TM)' ], | ||
[ '®', '(R)' ], | ||
[ '©', '(C)' ]] | ||
end | ||
def write_attribute(attr_name, value) | ||
textiled[attr_name.to_s] = nil | ||
super | ||
end | ||
|
||
def html_regexp | ||
%r{<(?:[^>"']+|"(?:\\.|[^\\"]+)*"|'(?:\\.|[^\\']+)*')*>}xm | ||
private | ||
def strip_redcloth_html(html) | ||
returning html.dup.gsub(html_regexp, '') do |h| | ||
redcloth_glyphs.each do |(entity, char)| | ||
sub = [ :gsub!, entity, char ] | ||
@textiled_unicode ? h.chars.send(*sub) : h.send(*sub) | ||
end | ||
end | ||
end | ||
|
||
def redcloth_glyphs | ||
[[ '’', "'" ], | ||
[ '‘', "'" ], | ||
[ '<', '<' ], | ||
[ '>', '>' ], | ||
[ '”', '"' ], | ||
[ '“', '"' ], | ||
[ '…', '...' ], | ||
[ '\1—', '--' ], | ||
[ ' → ', '->' ], | ||
[ ' – ', '-' ], | ||
[ '×', 'x' ], | ||
[ '™', '(TM)' ], | ||
[ '®', '(R)' ], | ||
[ '©', '(C)' ]] | ||
end | ||
|
||
def html_regexp | ||
%r{<(?:[^>"']+|"(?:\\.|[^\\"]+)*"|'(?:\\.|[^\\']+)*')*>}xm | ||
end | ||
end | ||
end | ||
|
||
ActiveRecord::Base.send(:include, Err::Acts::Textiled) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ActiveRecord::Base.send(:include, ActsAsSanitiled) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters