language_filter 0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dee09f095e1774912cf628728f5acc6735b2b85f
4
+ data.tar.gz: 159c7624452c4d90cd44252edc64187e36b9a644
5
+ SHA512:
6
+ metadata.gz: d16829605c4b949b8ba758d4ba40aa23e3c164b36a5a8c3d564dce66803e995e9043619efe3036bf3d14161cb351e259ca0a9a72690d3ec9fae67f1d87d2b6f6
7
+ data.tar.gz: db03b6a6a94847f9076ccc8feca139b9d17ffd1da498a21b78e31df58c9cdfa8ab1e965b70da812b18a760461ca5de23dd1afd1da3b56813979c6238f435c4d2
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in language_filter.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Chris Fritz
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,190 @@
1
+ # LanguageFilter
2
+
3
+ LanguageFilter is a Ruby gem to detect and optionally filter multiple categories of language. It was adapted from Thiago Jackiw's Obscenity gem for [FractalWriting.org](http://fractalwriting.org) and features many improvements, including:
4
+
5
+ - The ability to create and independently configure multiple language filters.
6
+ - Comes pre-packaged with multiple matchlists (for hate, profanity, sex, and violence), for more fine-tuned language detection. I think this aligns much better with the real needs of communities that might need language filtering. For example, I probably want to flag and eventually ban users that use hateful language. Then for content featuring sex, profanity, and/or violence, I can let users know exactly what to expect before delving into content, much more so than with a single, all-encompassing "mature" tag.
7
+ - Simpler, more intuitive configuration.
8
+ - More neutral language to accommodate a wider variety of use cases. For example, LanguageFilter uses `matchlist` and `exceptionlist` instead of `blacklist` and `whitelist`, since the gem can be used not only for censorship, but also for content *type* identification (e.g. fantasy, sci-fi, historical, etc in the context of creative writing)
9
+ - More robust exceptionlist (i.e. whitelist) handling. Given a simple example of a matchlist containing `cock` and an exceptionlist containing `game cock`, the other filtering gems I've seen will flag the `cock` in `game cock`, despite the exceptionlist. LanguageFilter is a little smarter and does what you would expect, so that when sanitizing the string `cock is usually sexual, but a game cock is just an animal`, the returned string will be `**** is usually sexual, but a game cock is just an animal`.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ``` ruby
16
+ gem 'language_filter'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ ``` bash
22
+ $ bundle
23
+ ```
24
+
25
+ Or install it yourself as:
26
+
27
+ ``` bash
28
+ $ gem install language_filter
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ Need a new language filter? Here's a quick usage example:
34
+
35
+ ``` ruby
36
+ sex_filter = LanguageFilter::Filter.new matchlist: :sex, replacement: :stars
37
+
38
+ # returns true if any content matched the filter's matchlist, else false
39
+ sex_filter.match?('This is some sexual content.')
40
+ => true
41
+
42
+ # returns a "cleaned up" version of the text, based on the replacement rule
43
+ sex_filter.sanitize('This is some sexual content.')
44
+ => "This is some ****** content."
45
+
46
+ # returns an array of the words and phrases that matched an item in the matchlist
47
+ sex_filter.matched('This is some sexual content.')
48
+ => ["sexual"]
49
+ ```
50
+
51
+ Now let's go over this a little more methodically. When you create a new LanguageFilter, you simply call LanguageFilter::Filter.new, with any of the following optional parameters. Below, you can see their defaults.
52
+
53
+ ``` ruby
54
+ LanguageFilter::Filter.new(
55
+ matchlist: :profanity,
56
+ exceptionlist: [],
57
+ replacement: :stars
58
+ )
59
+ ```
60
+
61
+ Now let's dive a little deeper into each parameter.
62
+
63
+ ### `:matchlist` and `:exceptionlist`
64
+
65
+ Both of these lists can take four different kinds of inputs.
66
+
67
+ #### Symbol signifying a pre-packaged list
68
+
69
+ By default, LanguageFilter comes with four different matchlists, each screening for a different category of language. These filters are accessible via:
70
+
71
+ - `matchlist: :hate` (for hateful language, like `f**k you`, `b***h`, or `f*g`)
72
+ - `matchlist: :profanity` (for swear/cuss words and phrases)
73
+ - `matchlist: :sex` (for content of a sexual nature)
74
+ - `matchlist: :violence` (for language indicating violence, such as `stab`, `gun`, or `murder`)
75
+
76
+ There's quite a bit of overlap between these lists, but they can be useful for communities that may want to self-monitor, giving them an idea of the kind of content in a story or article before clicking through.
77
+
78
+ #### An array of words and phrases to screen for
79
+
80
+ - `matchlist: ['giraffes?','rhino\w*','elephants?'] # a non-exhaustive list of African animals`
81
+
82
+ As you may have noticed, you can include regex! However, if you do, keep in mind that the more complicated regex you include, the slower the matching will be. Also, if you're assigning an array directly to matchlist and want to use regex, be sure to use single quotes (`'like this'`), rather than double quotes (`"like this"`). Otherwise, Ruby will think your backslashes are to help it interpolate the string, rather than to be intrepreted literally and passed into your regex, untouched.
83
+
84
+ In the actual matching, each item you enter in the list is dumped into the middle of the following regex, through the `list_item` variable.
85
+
86
+ ``` ruby
87
+ /\b#{list_item}\b/i
88
+ ```
89
+
90
+ There's not a whole lot going on there, but I'll quickly parse it for any who aren't very familiar with regex.
91
+
92
+ - `#{list_item}` just dumps in the item from our list that we want to check.
93
+ - The two `\b` on either side ensure that only text surrounded by non-word characters (anything other than letters, numbers, and the underscore), or the beginning or end of a string, are matched.
94
+ - The two `/` wrapping (almost) the whole statement lets Ruby know that this is a regex statement.
95
+ - The `i` right after the regex tells it to match case-insensitively, so that whether someone writes `giraffe`, `GIRAFFE`, or `gIrAffE`, the match won't fail.
96
+
97
+ If you'd like to master some regex Rubyfu, I highly recommend stopping at [Rubular.com](http://rubular.com/).
98
+
99
+ #### A filepath or string pointing to a filepath
100
+
101
+ If you want to use your own lists, there are two ways to do it.
102
+
103
+ 1) Pass in a filepath:
104
+
105
+ ``` ruby
106
+ matchlist: File.join(Rails.root,"/config/language_filters/my_custom_list.yml")
107
+ ```
108
+
109
+ 2) Pass in a `Pathname`, like Rails.root. I'm honestly not sure when you'd do this, but it was in option in Obscenity and it's still an option now.
110
+
111
+ ##### Formatting your lists
112
+
113
+ Now when you're actually writing these lists, they both use the same, relatively simple format, which looks something like this:
114
+
115
+ ``` regex
116
+ giraffes?
117
+ rhino\w*
118
+ elephants?
119
+ ```
120
+
121
+ It's a pretty simple pattern. Each word, phrase, or regex is on its own line - and that's it.
122
+
123
+ ### `:replacement`
124
+
125
+ If you're not using this gem to filter out potentially offensive content, then you don't have to worry about this part. For the rest of you the `:replacement` parameter specifies what to replace matches with, when sanitizing text.
126
+
127
+ Here are the options:
128
+
129
+ `replacement: :stars` (this is the default replacement method)
130
+
131
+ Example: This is some ****** up ****.
132
+
133
+ `replacement: :garbled`
134
+
135
+ Example: This is some $@!#% up $@!#%.
136
+
137
+ `replacement: :vowels`
138
+
139
+ Example: This is some f*ck*d up sh*t.
140
+
141
+ `replacement: :nonconsonants` (useful where letters might be replaced with numbers, for example in L3375P34|< - i.e. leetspeak)
142
+
143
+ Example: 7|-|1$ 1$ $0/\/\3 Ph*****D UP ******.
144
+
145
+ ### Methods to modify filters after creation
146
+
147
+ If you ever want to change the matchlist, exceptionlist, or replacement type, each parameter is accessible via an assignment method.
148
+
149
+ For example:
150
+
151
+ ``` ruby
152
+ my_filter = LanguageFilter::Filter.new(
153
+ matchlist: ['dogs?'],
154
+ exceptionlist: ['dogs drool'],
155
+ replacement: :garbled
156
+ )
157
+
158
+ my_filter.sanitize('Dogs rule, cats drool!')
159
+ => "$@!#% rule, cats drool!"
160
+ my_filter.sanitize('Cats rule, dogs drool!')
161
+ => "Cats rule, dogs drool!"
162
+
163
+ my_filter.matchlist = ['dogs?','cats drool']
164
+ my_filter.exceptionlist = ['dogs drool','dogs are cruel']
165
+ my_filter.replacement = :stars
166
+
167
+ my_filter.sanitize('Dogs rule, cats drool!')
168
+ => "**** rule, **********!"
169
+ my_filter.sanitize('Cats rule, dogs drool!')
170
+ => "Cats rule, dogs drool!"
171
+ ```
172
+
173
+ In the above case though, we just wanted to add items to the existing lists, so there's actually a better solution. They're stored as arrays, so treat them as such. Any array methods are fair game.
174
+
175
+ For example:
176
+
177
+ ``` ruby
178
+ my_filter.matchlist.pop
179
+ my_filter.matchlist << "cats are liars" << "don't listen to( the)? cats" << "why does no one heed my warnings about the cats?! aren't you getting my messages?"
180
+ my_filter.matchlist.uniq!
181
+ # etc...
182
+ ```
183
+
184
+ ## Contributing
185
+
186
+ 1. Fork it
187
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
188
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
189
+ 4. Push to the branch (`git push origin my-new-feature`)
190
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,6 @@
1
+ \w*f[\b_]*[uv][\b_]*c[\b_]*k[\b_][a([e3]r)]s?
2
+ \w*f[\b_]*a[\b_]*g\w*
3
+ \w*c[\b_]*u[\b_]*n[\b_]*t\w*
4
+ \w*a[s\$5z]{2}h[o0]l[e3]\w*
5
+ \w*b[\b_]*i[\b_]*t[\b_]*c[\b_]*h\w*
6
+ fudge ?pack\w*
@@ -0,0 +1,10 @@
1
+ \w*f[\b_]*[uv][\b_]*c[\b_]*k\w*
2
+ \w*f[\b_]*c[\b_]*[uv][\b_]*k\w*
3
+ \w*f[\b_]*[uv][\b_]*k\w*
4
+ \w*[s\$5][\b_]*h[\b_]*[i1][\b_]*t\w*
5
+ a[s\$5z]{2}\w*
6
+ \w*a[s\$5z]{2}(e[s\$5z])?
7
+ b[\b_]*a[\b_]*s[\b_]*t[\b_]*a[\b_]*r[\b_]*d\w*
8
+ b[\b_]*i[\b_]*t[\b_]*c[\b_]*h\w*
9
+ c[\b_]*u[\b_]*n[\b_]*t\w*
10
+ f[\b_]*a[\b_]*g\w*
@@ -0,0 +1,56 @@
1
+ \w*sex\w*
2
+ blow ?job\w*
3
+ fellat\w*
4
+ felch\w*
5
+ \w*f[\b_]*[uv][\b_]*c[\b_]*k\w*
6
+ wank\w*
7
+ cock\w*
8
+ cock suck\w*
9
+ poll ?smok\w*
10
+ dick\w*
11
+ dick ?suck\w*
12
+ fudge ?pack\w*
13
+ rim ?job\w*
14
+ knob ?gobbl\w*
15
+ anal\w*
16
+ rectums?
17
+ \w*a[s\$5z]{2}
18
+ \w*a[s\$5z]{2}h[o0]l[e3]\w*
19
+ ballsacks?
20
+ scrotums?
21
+ bollocks
22
+ penis(es)?
23
+ boners?
24
+ pricks?
25
+ knobends?
26
+ manhoods?
27
+ wieners?
28
+ breasts?
29
+ tit\w*
30
+ boob\w*
31
+ honkers?
32
+ cleavages?
33
+ vagina\w*
34
+ puss[y(ies)(ee)]
35
+ muffs?
36
+ cunt\w*
37
+ twats?
38
+ clit\w*
39
+ quims?
40
+ labias?
41
+ buttplugs?
42
+ dildos?
43
+ heteros?
44
+ homos?
45
+ sluts?
46
+ whor\w*
47
+ skank\w*
48
+ g+[\b_]*h?[\b_]*[ae][\b_]*ys?
49
+ dykes?
50
+ \w*f[\b_]*a[\b_]*g\w*
51
+ \w*cum\w*
52
+ jizz\w*
53
+ pubes?
54
+ pubic
55
+ smegma
56
+ boy ?butter
@@ -0,0 +1,13 @@
1
+ stab\w*
2
+ kill\w*
3
+ beat ?up
4
+ beat the \w+ out of
5
+ beat the \w+ out of
6
+ fuck ?\w* up
7
+ murder\w*
8
+ genocide
9
+ shoot [(him)(her)(it)(me)(us)(them)]
10
+ shot [(him)(her)(it)(me)(us)(them)]
11
+ gun\w*
12
+ phasers?
13
+ death ?(ray)?
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'language_filter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "language_filter"
8
+ spec.version = LanguageFilter::VERSION
9
+ spec.authors = ["Chris Fritz"]
10
+ spec.email = ["chrisvfritz@gmail.com"]
11
+ spec.description = %q{LanguageFilter is a Ruby gem to detect and optionally filter various categories of language.}
12
+ spec.summary = %q{LanguageFilter is a Ruby gem to detect and optionally filter various categories of language.}
13
+ spec.homepage = "http://github.com/chrisvfritz/language_filter"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,172 @@
1
+ require 'pathname'
2
+ require 'yaml'
3
+ require 'language_filter/error'
4
+ require 'language_filter/version'
5
+
6
+ module LanguageFilter
7
+ class Filter
8
+ attr_accessor :matchlist, :exceptionlist, :replacement
9
+
10
+ DEFAULT_EXCEPTIONLIST = []
11
+ DEFAULT_MATCHLIST = File.dirname(__FILE__) + "/../config/filters/profanity.txt"
12
+ DEFAULT_REPLACEMENT = :stars
13
+
14
+ def initialize(options={})
15
+ @matchlist = if options[:matchlist] then
16
+ validate_list_content(options[:matchlist])
17
+ set_list_content(options[:matchlist])
18
+ else set_list_content(DEFAULT_MATCHLIST) end
19
+ @exceptionlist = if options[:exceptionlist] then
20
+ validate_list_content(options[:exceptionlist])
21
+ set_list_content(options[:exceptionlist])
22
+ else set_list_content(DEFAULT_EXCEPTIONLIST) end
23
+ @replacement = options[:replacement] || DEFAULT_REPLACEMENT
24
+ validate_replacement
25
+ end
26
+
27
+ # SETTERS
28
+
29
+ def matchlist=(content)
30
+ validate_list_content(content)
31
+ @matchlist = case content
32
+ when :default then set_list_content(DEFAULT_MATCHLIST)
33
+ else @matchlist = set_list_content(content)
34
+ end
35
+ end
36
+
37
+ def exceptionlist=(content)
38
+ if content == :default then
39
+ @exceptionlist = set_list_content(DEFAULT_EXCEPTIONLIST)
40
+ else
41
+ validate_list_content(content)
42
+ @exceptionlist = set_list_content(content)
43
+ end
44
+ end
45
+
46
+ def replacement=(value)
47
+ @replacement = case value
48
+ when :default then :stars
49
+ else value
50
+ end
51
+ validate_replacement
52
+ end
53
+
54
+ # LANGUAGE
55
+
56
+ def match?(text)
57
+ return false unless text.to_s.size >= 3
58
+ @matchlist.each do |list_item|
59
+ start_at = 0
60
+ text.scan(/\b#{list_item}\b/i) do |match|
61
+ match_start = text[start_at,text.size].index(/\b#{list_item}\b/i) unless @exceptionlist.empty?
62
+ match_end = match_start + match.size unless @exceptionlist.empty?
63
+ unless match == [nil] then
64
+ return true if @exceptionlist.empty? or not protected_by_exceptionlist?(match_start,match_end,text,start_at)
65
+ end
66
+ start_at = match_end + 1
67
+ end
68
+ end
69
+ false
70
+ end
71
+
72
+ def matched(text)
73
+ words = []
74
+ return words unless text.to_s.size >= 3
75
+ @matchlist.each do |list_item|
76
+ start_at = 0
77
+ text.scan(/\b#{list_item}\b/i) do |match|
78
+ match_start = text[start_at,text.size].index(/\b#{list_item}\b/i) unless @exceptionlist.empty?
79
+ match_end = match_start + match.size unless @exceptionlist.empty?
80
+ unless match == [nil] then
81
+ words << match if @exceptionlist.empty? or not protected_by_exceptionlist?(match_start,match_end,text,start_at)
82
+ end
83
+ start_at = match_end + 1
84
+ end
85
+ end
86
+ words.uniq
87
+ end
88
+
89
+ def sanitize(text)
90
+ return text unless text.to_s.size >= 3
91
+ @matchlist.each do |list_item|
92
+ start_at = 0
93
+ text.gsub! /\b#{list_item}\b/i do |match|
94
+ match_start = text[start_at,text.size].index(/\b#{list_item}\b/i) unless @exceptionlist.empty?
95
+ match_end = match_start + match.size unless @exceptionlist.empty?
96
+ unless @exceptionlist.empty? or not protected_by_exceptionlist?(match_start,match_end,text,start_at) then
97
+ start_at = match_end + 1
98
+ match
99
+ else
100
+ start_at = match_end + 1
101
+ replace(match)
102
+ end
103
+ end
104
+ end
105
+ text
106
+ end
107
+
108
+ private
109
+
110
+ # VALIDATIONS
111
+
112
+ def validate_list_content(content)
113
+ case content
114
+ when Array then content.all? {|c| c.class == String} || raise(LanguageFilter::EmptyContentList.new("List content array is empty."))
115
+ when String then File.exists?(content) || raise(LanguageFilter::UnkownContentFile.new("List content file \"#{content}\" can't be found."))
116
+ when Pathname then content.exist? || raise(LanguageFilter::UnkownContentFile.new("List content file \"#{content}\" can't be found."))
117
+ when Symbol then
118
+ case content
119
+ when :default, :hate, :profanity, :sex, :violence then true
120
+ else raise(LanguageFilter::UnkownContent.new("The only accepted symbols are :default, :hate, :profanity, :sex, and :violence."))
121
+ end
122
+ else raise LanguageFilter::UnkownContent.new("The list content can be either an Array, Pathname, or String path to a file.")
123
+ end
124
+ end
125
+
126
+ def validate_replacement
127
+ case @replacement
128
+ when :default, :garbled, :vowels, :stars, :nonconsonants
129
+ else raise LanguageFilter::UnknownReplacement.new("This is not a known replacement type.")
130
+ end
131
+ end
132
+
133
+ # HELPERS
134
+
135
+ def set_list_content(list)
136
+ case list
137
+ when :hate then load_list File.dirname(__FILE__) + "/../config/filters/hate.txt"
138
+ when :profanity then load_list File.dirname(__FILE__) + "/../config/filters/profanity.txt"
139
+ when :sex then load_list File.dirname(__FILE__) + "/../config/filters/sex.txt"
140
+ when :violence then load_list File.dirname(__FILE__) + "/../config/filters/violence.txt"
141
+ when Array then list
142
+ when String, Pathname then load_list list.to_s
143
+ else []
144
+ end
145
+ end
146
+
147
+ def load_list(filepath)
148
+ IO.readlines(filepath).each {|line| line.gsub!(/\n/,'')}
149
+ end
150
+
151
+ def protected_by_exceptionlist?(match_start,match_end,text,start_at)
152
+ @exceptionlist.each do |list_item|
153
+ exception_start = text[start_at,text.size].index(/\b#{list_item}\b/i)
154
+ if exception_start and exception_start <= match_start then
155
+ return true if exception_start + text[start_at,text.size][/\b#{list_item}\b/i].size >= match_end
156
+ end
157
+ end
158
+ return false
159
+ end
160
+
161
+ # This was moved to private because users should just use sanitize for any content
162
+ def replace(word)
163
+ case @replacement
164
+ when :vowels then word.gsub(/[aeiou]/i, '*')
165
+ when :stars then '*' * word.size
166
+ when :nonconsonants then word.gsub(/[^bcdfghjklmnpqrstvwxyz]/i, '*')
167
+ when :default, :garbled then '$@!#%'
168
+ else raise LanguageFilter::UnknownReplacement.new("#{@replacement} is not a known replacement type.")
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,7 @@
1
+ module LanguageFilter
2
+ class Error < RuntimeError; end
3
+
4
+ class UnkownContent < Error; end
5
+ class UnkownContentFile < Error; end
6
+ class EmptyContentList < Error; end
7
+ end
@@ -0,0 +1,3 @@
1
+ module LanguageFilter
2
+ VERSION = "0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: language_filter
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.2'
5
+ platform: ruby
6
+ authors:
7
+ - Chris Fritz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: LanguageFilter is a Ruby gem to detect and optionally filter various
42
+ categories of language.
43
+ email:
44
+ - chrisvfritz@gmail.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - config/filters/hate.txt
55
+ - config/filters/profanity.txt
56
+ - config/filters/sex.txt
57
+ - config/filters/violence.txt
58
+ - language_filter.gemspec
59
+ - lib/language_filter.rb
60
+ - lib/language_filter/error.rb
61
+ - lib/language_filter/version.rb
62
+ homepage: http://github.com/chrisvfritz/language_filter
63
+ licenses:
64
+ - MIT
65
+ metadata: {}
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 2.0.3
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: LanguageFilter is a Ruby gem to detect and optionally filter various categories
86
+ of language.
87
+ test_files: []