more_possessive 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/LICENSE +20 -0
- data/README.md +35 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/lib/core_ext/string/inflections.rb +7 -0
- data/lib/possessive.rb +5 -0
- data/lib/possessive/inflections.rb +16 -0
- data/lib/possessive/inflector/inflections.rb +65 -0
- data/lib/possessive/inflector/methods.rb +32 -0
- data/more_possessive.gemspec +40 -0
- data/rails/init.rb +1 -0
- data/test/helper.rb +6 -0
- data/test/test_possessive.rb +84 -0
- metadata +61 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: ddf5f5426b6d841f2b96f530ecf3f07c63f66ec1
|
|
4
|
+
data.tar.gz: 5e85a0a56dec4b39f748a9083ee6e9295ea8bcb4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 400a39f4b776574a66fbc004165dc1d011117b1a0d27e415f36492bad661e0251f6e6ce603bb85565a2c0f091eec13d403f61f038420208acc925bacaf2efbfb
|
|
7
|
+
data.tar.gz: 0e791dcefb6fedfc3600bf186048b995c3967af4eaca4f7bbb892db40875fca9a5c3cdb409866480c22edf740046988c79578292f2a36985984e59581e677c4a
|
data/.document
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2017 Brian Clubb, Robert Wünsch, Alizain Feerasta
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# possessive
|
|
2
|
+
|
|
3
|
+
Rails gem that lets you get a possessive form of a string. Supports localization in the style of ActiveSupport::Inflector.
|
|
4
|
+
|
|
5
|
+
## Example
|
|
6
|
+
|
|
7
|
+
"Brian".possessive # => Brian's
|
|
8
|
+
"Sooners".possessive # => Sooners'
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
# Gemfile
|
|
13
|
+
gem "more_possessive"
|
|
14
|
+
|
|
15
|
+
## Localization
|
|
16
|
+
|
|
17
|
+
Sample configuration for German:
|
|
18
|
+
|
|
19
|
+
# config/initializers/inflections.rb
|
|
20
|
+
Possessive::Inflector.inflections(:de) do |inflect|
|
|
21
|
+
inflect.possessive /$/, 's'
|
|
22
|
+
inflect.possessive /(s|x|z)$/i, '\1’'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
## Note on Patches/Pull Requests
|
|
26
|
+
|
|
27
|
+
* Fork the project.
|
|
28
|
+
* Make your feature addition or bug fix.
|
|
29
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
|
30
|
+
* Commit, do not mess with rakefile, version, or history. (If you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull.)
|
|
31
|
+
* Send me a pull request. Bonus points for topic branches.
|
|
32
|
+
|
|
33
|
+
## Copyright
|
|
34
|
+
|
|
35
|
+
Copyright (c) 2017 Brian Clubb, Robert Wünsch, Alizain Feerasta. See LICENSE for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'jeweler'
|
|
6
|
+
Jeweler::Tasks.new do |gem|
|
|
7
|
+
gem.name = "more_possessive"
|
|
8
|
+
gem.summary = "Rails plugin that lets you get a possessive form of a string for use on sites"
|
|
9
|
+
gem.description = "Rails plugin that lets you get a possessive form of a string for use on sites"
|
|
10
|
+
gem.email = "alizain.feerasta@gmail.com"
|
|
11
|
+
gem.homepage = "http://github.com/alizain/more_possessive"
|
|
12
|
+
gem.authors = ["Brian Clubb", "Jamie Flournoy", "Nick Howard"]
|
|
13
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
|
14
|
+
end
|
|
15
|
+
Jeweler::GemcutterTasks.new
|
|
16
|
+
rescue LoadError
|
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
require 'rake/testtask'
|
|
21
|
+
Rake::TestTask.new(:test) do |test|
|
|
22
|
+
test.libs << 'lib' << 'test'
|
|
23
|
+
test.pattern = 'test/**/test_*.rb'
|
|
24
|
+
test.verbose = true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
begin
|
|
28
|
+
require 'rcov/rcovtask'
|
|
29
|
+
Rcov::RcovTask.new do |test|
|
|
30
|
+
test.libs << 'test'
|
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
|
32
|
+
test.verbose = true
|
|
33
|
+
end
|
|
34
|
+
rescue LoadError
|
|
35
|
+
task :rcov do
|
|
36
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
task :test => :check_dependencies
|
|
41
|
+
|
|
42
|
+
task :default => :test
|
|
43
|
+
|
|
44
|
+
require 'rdoc/task'
|
|
45
|
+
Rake::RDocTask.new do |rdoc|
|
|
46
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
|
47
|
+
|
|
48
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
49
|
+
rdoc.title = "more_possessive #{version}"
|
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
51
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.0
|
data/lib/possessive.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'possessive/inflector/inflections'
|
|
3
|
+
|
|
4
|
+
#--
|
|
5
|
+
# Defines the standard inflection rules. These are the starting point for
|
|
6
|
+
# new projects and are not considered complete. The current set of inflection
|
|
7
|
+
# rules is frozen. This means, we do not change them to become more complete.
|
|
8
|
+
# This is a safety measure to keep existing applications from breaking.
|
|
9
|
+
#++
|
|
10
|
+
Possessive::Inflector.inflections(:en) do |inflect|
|
|
11
|
+
inflect.possessive /$/, '’s'
|
|
12
|
+
inflect.possessive /([^’]s)$/i, '\1’'
|
|
13
|
+
inflect.possessive /(sh)$/i, '\1es’'
|
|
14
|
+
inflect.possessive /(ss)$/i, '\1’s'
|
|
15
|
+
inflect.possessive 'it', 'its'
|
|
16
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Inspired by ActiveSupport::Inflector
|
|
2
|
+
module Possessive
|
|
3
|
+
module Inflector
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
# A singleton instance of this class is yielded by Inflector.inflections,
|
|
7
|
+
# which can then be used to specify additional inflection rules. If passed
|
|
8
|
+
# an optional locale, rules for other languages can be specified. The
|
|
9
|
+
# default locale is <tt>:en</tt>. Only rules for English are provided.
|
|
10
|
+
#
|
|
11
|
+
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
|
12
|
+
# inflect.possessive /(sh)$/i, '\1es’'
|
|
13
|
+
# inflect.possessive /(ss)$/i, '\1’s'
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# Later rules override previous rules.
|
|
17
|
+
class Inflections
|
|
18
|
+
@__instance__ = {}
|
|
19
|
+
|
|
20
|
+
def self.instance(locale = :en)
|
|
21
|
+
@__instance__[locale] ||= new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
attr_reader :possessives
|
|
25
|
+
|
|
26
|
+
def initialize
|
|
27
|
+
@possessives = []
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Specifies a possessive form of a string by a regular expression rule or
|
|
31
|
+
# by a string mapping. When using a regular expression based replacement,
|
|
32
|
+
# the normal possessive form is called after the replacement. When a
|
|
33
|
+
# string is used, the possessive form should be specified as desired (example:
|
|
34
|
+
# 'The name', not 'the_name').
|
|
35
|
+
#
|
|
36
|
+
# possessive /$/, '’s'
|
|
37
|
+
# possessive 'it', 'its'
|
|
38
|
+
def possessive(rule, replacement)
|
|
39
|
+
rule = /^#{rule}$/ if rule.is_a?(String)
|
|
40
|
+
@possessives.insert(0, [rule, replacement])
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Clears the loaded inflections.
|
|
44
|
+
def clear
|
|
45
|
+
@possessives = []
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Yields a singleton instance of Inflector::Inflections so you can specify
|
|
50
|
+
# additional inflector rules. If passed an optional locale, rules for other
|
|
51
|
+
# languages can be specified. If not specified, defaults to <tt>:en</tt>.
|
|
52
|
+
# Only rules for English are provided.
|
|
53
|
+
#
|
|
54
|
+
# Possessive::Inflector.inflections(:en) do |inflect|
|
|
55
|
+
# inflect.uncountable 'rails'
|
|
56
|
+
# end
|
|
57
|
+
def inflections(locale = :en)
|
|
58
|
+
if block_given?
|
|
59
|
+
yield Inflections.instance(locale)
|
|
60
|
+
else
|
|
61
|
+
Inflections.instance(locale)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Inspired by ActiveSupport::Inflector
|
|
2
|
+
module Possessive
|
|
3
|
+
# The Inflector transforms words into their possessive form.
|
|
4
|
+
# The default inflections for possessive form are kept in inflections.rb.
|
|
5
|
+
module Inflector
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
# Returns the possessive form of the word in the string.
|
|
9
|
+
#
|
|
10
|
+
# If passed an optional +locale+ parameter, the possessive form of the word
|
|
11
|
+
# will be determined using rules defined for that language. By default,
|
|
12
|
+
# this parameter is set to <tt>:en</tt>.
|
|
13
|
+
#
|
|
14
|
+
# 'Brian'.possessive # => "Brian’s"
|
|
15
|
+
# 'Steelers'.possessive # => "Steelers’"
|
|
16
|
+
# 'class'.possessive # => "class’s"
|
|
17
|
+
# 'fish'.possessive # => "fishes’"
|
|
18
|
+
# 'Brian'.possessive(:de) # => "Brians"
|
|
19
|
+
def possessive(word, locale = :en)
|
|
20
|
+
result = word.to_s.dup
|
|
21
|
+
|
|
22
|
+
if word.empty?
|
|
23
|
+
result
|
|
24
|
+
else
|
|
25
|
+
inflections(locale).possessives.each do |(rule, replacement)|
|
|
26
|
+
break if result.sub!(rule, replacement)
|
|
27
|
+
end
|
|
28
|
+
result
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
# stub: more_possessive 1.0.0 ruby lib
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |s|
|
|
8
|
+
s.name = "more_possessive".freeze
|
|
9
|
+
s.version = "1.0.0"
|
|
10
|
+
|
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
12
|
+
s.require_paths = ["lib".freeze]
|
|
13
|
+
s.authors = ["Brian Clubb".freeze, "Jamie Flournoy".freeze, "Nick Howard".freeze]
|
|
14
|
+
s.date = "2017-02-26"
|
|
15
|
+
s.description = "Rails plugin that lets you get a possessive form of a string for use on sites".freeze
|
|
16
|
+
s.email = "alizain.feerasta@gmail.com".freeze
|
|
17
|
+
s.extra_rdoc_files = [
|
|
18
|
+
"LICENSE",
|
|
19
|
+
"README.md"
|
|
20
|
+
]
|
|
21
|
+
s.files = [
|
|
22
|
+
".document",
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"README.md",
|
|
25
|
+
"Rakefile",
|
|
26
|
+
"VERSION",
|
|
27
|
+
"lib/core_ext/string/inflections.rb",
|
|
28
|
+
"lib/possessive.rb",
|
|
29
|
+
"lib/possessive/inflections.rb",
|
|
30
|
+
"lib/possessive/inflector/inflections.rb",
|
|
31
|
+
"lib/possessive/inflector/methods.rb",
|
|
32
|
+
"more_possessive.gemspec",
|
|
33
|
+
"rails/init.rb",
|
|
34
|
+
"test/helper.rb",
|
|
35
|
+
"test/test_possessive.rb"
|
|
36
|
+
]
|
|
37
|
+
s.homepage = "http://github.com/alizain/more_possessive".freeze
|
|
38
|
+
s.rubygems_version = "2.6.4".freeze
|
|
39
|
+
s.summary = "Rails plugin that lets you get a possessive form of a string for use on sites".freeze
|
|
40
|
+
end
|
data/rails/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "possessive"
|
data/test/helper.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'helper'
|
|
3
|
+
|
|
4
|
+
class InflectorTest < Test::Unit::TestCase
|
|
5
|
+
test "Possessive with a normal string" do
|
|
6
|
+
assert_equal "Brian’s", "Brian".possessive
|
|
7
|
+
assert_equal "BRIAN’s", "BRIAN".possessive
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
test "Possessive with a string ending with s" do
|
|
11
|
+
assert_equal "Steelers’", "Steelers".possessive
|
|
12
|
+
assert_equal "STEELERS’", "STEELERS".possessive
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test "Possessive with strings ending in sh" do
|
|
16
|
+
assert_equal "fishes’", "fish".possessive
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test "Possessive with strings ending in ss" do
|
|
20
|
+
assert_equal "class’s", "class".possessive
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
test "Possessive with it" do
|
|
24
|
+
assert_equal "its", "it".possessive
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
test "Possessive with something containing the string rule: 'it', 'its'" do
|
|
28
|
+
assert_equal "little’s", "little".possessive
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test "Possessive with an empty string" do
|
|
32
|
+
assert_equal "", "".possessive
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
test "Possessive with localization" do
|
|
36
|
+
Possessive::Inflector.inflections(:de) do |inflect|
|
|
37
|
+
inflect.possessive /$/, 's'
|
|
38
|
+
inflect.possessive /(s|x|z)$/i, '\1’'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
assert_equal('Bachs', 'Bach'.possessive(:de))
|
|
42
|
+
assert_equal('Bach’s', 'Bach'.possessive)
|
|
43
|
+
|
|
44
|
+
assert_equal('Blitz’', 'Blitz'.possessive(:de))
|
|
45
|
+
assert_equal('Blitz’s', 'Blitz'.possessive)
|
|
46
|
+
|
|
47
|
+
assert_equal('Felix’', 'Felix'.possessive(:de))
|
|
48
|
+
assert_equal('Felix’s', 'Felix'.possessive)
|
|
49
|
+
|
|
50
|
+
assert_equal('Fuchs’', 'Fuchs'.possessive(:de))
|
|
51
|
+
assert_equal('Fuchs’', 'Fuchs'.possessive)
|
|
52
|
+
|
|
53
|
+
Possessive::Inflector.inflections(:de) { |inflect| inflect.clear }
|
|
54
|
+
|
|
55
|
+
assert Possessive::Inflector.inflections(:de).possessives.empty?
|
|
56
|
+
assert !Possessive::Inflector.inflections.possessives.empty?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test "clear rules" do
|
|
60
|
+
with_dup do
|
|
61
|
+
Possessive::Inflector.inflections do |inflect|
|
|
62
|
+
# ensure any data is present
|
|
63
|
+
inflect.possessive(/$/, '’s')
|
|
64
|
+
|
|
65
|
+
inflect.clear
|
|
66
|
+
|
|
67
|
+
assert inflect.possessives.empty?
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Dups the singleton and yields, restoring the original inflections later.
|
|
73
|
+
# Use this in tests what modify the state of the singleton.
|
|
74
|
+
#
|
|
75
|
+
# This helper is implemented by setting @__instance__ because in some tests
|
|
76
|
+
# there are module functions that access Possessive::Inflector.inflections,
|
|
77
|
+
# so we need to replace the singleton itself.
|
|
78
|
+
def with_dup
|
|
79
|
+
original = Possessive::Inflector::Inflections.instance_variable_get(:@__instance__)
|
|
80
|
+
Possessive::Inflector::Inflections.instance_variable_set(:@__instance__, original.dup)
|
|
81
|
+
ensure
|
|
82
|
+
Possessive::Inflector::Inflections.instance_variable_set(:@__instance__, original)
|
|
83
|
+
end
|
|
84
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: more_possessive
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Brian Clubb
|
|
8
|
+
- Jamie Flournoy
|
|
9
|
+
- Nick Howard
|
|
10
|
+
autorequire:
|
|
11
|
+
bindir: bin
|
|
12
|
+
cert_chain: []
|
|
13
|
+
date: 2017-02-26 00:00:00.000000000 Z
|
|
14
|
+
dependencies: []
|
|
15
|
+
description: Rails plugin that lets you get a possessive form of a string for use
|
|
16
|
+
on sites
|
|
17
|
+
email: alizain.feerasta@gmail.com
|
|
18
|
+
executables: []
|
|
19
|
+
extensions: []
|
|
20
|
+
extra_rdoc_files:
|
|
21
|
+
- LICENSE
|
|
22
|
+
- README.md
|
|
23
|
+
files:
|
|
24
|
+
- ".document"
|
|
25
|
+
- LICENSE
|
|
26
|
+
- README.md
|
|
27
|
+
- Rakefile
|
|
28
|
+
- VERSION
|
|
29
|
+
- lib/core_ext/string/inflections.rb
|
|
30
|
+
- lib/possessive.rb
|
|
31
|
+
- lib/possessive/inflections.rb
|
|
32
|
+
- lib/possessive/inflector/inflections.rb
|
|
33
|
+
- lib/possessive/inflector/methods.rb
|
|
34
|
+
- more_possessive.gemspec
|
|
35
|
+
- rails/init.rb
|
|
36
|
+
- test/helper.rb
|
|
37
|
+
- test/test_possessive.rb
|
|
38
|
+
homepage: http://github.com/alizain/more_possessive
|
|
39
|
+
licenses: []
|
|
40
|
+
metadata: {}
|
|
41
|
+
post_install_message:
|
|
42
|
+
rdoc_options: []
|
|
43
|
+
require_paths:
|
|
44
|
+
- lib
|
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '0'
|
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
requirements: []
|
|
56
|
+
rubyforge_project:
|
|
57
|
+
rubygems_version: 2.6.4
|
|
58
|
+
signing_key:
|
|
59
|
+
specification_version: 4
|
|
60
|
+
summary: Rails plugin that lets you get a possessive form of a string for use on sites
|
|
61
|
+
test_files: []
|