formattedstring 0.0.1
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.
- data/LICENSE +16 -0
- data/README +57 -0
- data/Rakefile +79 -0
- data/doc/classes/Enumerable.html +146 -0
- data/doc/classes/Enumerable.src/M000025.html +21 -0
- data/doc/classes/Enumerable.src/M000026.html +34 -0
- data/doc/classes/FormattedString/Formats/Xml.html +144 -0
- data/doc/classes/FormattedString/Formats/Xml.src/M000004.html +49 -0
- data/doc/classes/FormattedString/Formats.html +111 -0
- data/doc/classes/FormattedString.html +111 -0
- data/doc/classes/Inflector/Inflections.html +321 -0
- data/doc/classes/Inflector/Inflections.src/M000019.html +18 -0
- data/doc/classes/Inflector/Inflections.src/M000020.html +18 -0
- data/doc/classes/Inflector/Inflections.src/M000021.html +18 -0
- data/doc/classes/Inflector/Inflections.src/M000022.html +26 -0
- data/doc/classes/Inflector/Inflections.src/M000023.html +18 -0
- data/doc/classes/Inflector/Inflections.src/M000024.html +23 -0
- data/doc/classes/Inflector.html +516 -0
- data/doc/classes/Inflector.src/M000005.html +22 -0
- data/doc/classes/Inflector.src/M000006.html +25 -0
- data/doc/classes/Inflector.src/M000007.html +25 -0
- data/doc/classes/Inflector.src/M000008.html +22 -0
- data/doc/classes/Inflector.src/M000009.html +18 -0
- data/doc/classes/Inflector.src/M000010.html +22 -0
- data/doc/classes/Inflector.src/M000011.html +18 -0
- data/doc/classes/Inflector.src/M000012.html +18 -0
- data/doc/classes/Inflector.src/M000013.html +18 -0
- data/doc/classes/Inflector.src/M000014.html +18 -0
- data/doc/classes/Inflector.src/M000015.html +19 -0
- data/doc/classes/Inflector.src/M000016.html +18 -0
- data/doc/classes/Inflector.src/M000017.html +22 -0
- data/doc/classes/Inflector.src/M000018.html +27 -0
- data/doc/classes/String.html +191 -0
- data/doc/classes/String.src/M000001.html +18 -0
- data/doc/classes/String.src/M000002.html +20 -0
- data/doc/classes/String.src/M000003.html +19 -0
- data/doc/created.rid +1 -0
- data/doc/files/LICENSE.html +129 -0
- data/doc/files/README.html +196 -0
- data/doc/files/lib/formatted_string/formats/xml_rb.html +119 -0
- data/doc/files/lib/formatted_string_rb.html +108 -0
- data/doc/files/lib/inflections_rb.html +101 -0
- data/doc/files/lib/inflector_rb.html +108 -0
- data/doc/fr_class_index.html +33 -0
- data/doc/fr_file_index.html +32 -0
- data/doc/fr_method_index.html +52 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/formatted_string/formats/xml.rb +163 -0
- data/lib/formatted_string.rb +34 -0
- data/lib/inflections.rb +53 -0
- data/lib/inflector.rb +282 -0
- metadata +120 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
3
|
+
<!DOCTYPE html
|
4
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
5
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
6
|
+
|
7
|
+
<!--
|
8
|
+
|
9
|
+
Methods
|
10
|
+
|
11
|
+
-->
|
12
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
13
|
+
<head>
|
14
|
+
<title>Methods</title>
|
15
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
16
|
+
<link rel="stylesheet" href="rdoc-style.css" type="text/css" />
|
17
|
+
<base target="docwin" />
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<div id="index">
|
21
|
+
<h1 class="section-bar">Methods</h1>
|
22
|
+
<div id="index-entries">
|
23
|
+
<a href="classes/Inflector.html#M000008">camelize (Inflector)</a><br />
|
24
|
+
<a href="classes/Inflector.html#M000015">classify (Inflector)</a><br />
|
25
|
+
<a href="classes/Inflector/Inflections.html#M000024">clear (Inflector::Inflections)</a><br />
|
26
|
+
<a href="classes/Inflector.html#M000017">constantize (Inflector)</a><br />
|
27
|
+
<a href="classes/Enumerable.html#M000026">crawl (Enumerable)</a><br />
|
28
|
+
<a href="classes/Inflector.html#M000011">dasherize (Inflector)</a><br />
|
29
|
+
<a href="classes/Inflector.html#M000013">demodulize (Inflector)</a><br />
|
30
|
+
<a href="classes/Inflector.html#M000016">foreign_key (Inflector)</a><br />
|
31
|
+
<a href="classes/String.html#M000001">format (String)</a><br />
|
32
|
+
<a href="classes/String.html#M000002">format= (String)</a><br />
|
33
|
+
<a href="classes/String.html#M000003">formatted (String)</a><br />
|
34
|
+
<a href="classes/Enumerable.html#M000025">group_by (Enumerable)</a><br />
|
35
|
+
<a href="classes/Inflector.html#M000012">humanize (Inflector)</a><br />
|
36
|
+
<a href="classes/Inflector.html#M000005">inflections (Inflector)</a><br />
|
37
|
+
<a href="classes/Inflector/Inflections.html#M000022">irregular (Inflector::Inflections)</a><br />
|
38
|
+
<a href="classes/Inflector/Inflections.html#M000019">new (Inflector::Inflections)</a><br />
|
39
|
+
<a href="classes/Inflector.html#M000018">ordinalize (Inflector)</a><br />
|
40
|
+
<a href="classes/Inflector/Inflections.html#M000020">plural (Inflector::Inflections)</a><br />
|
41
|
+
<a href="classes/Inflector.html#M000006">pluralize (Inflector)</a><br />
|
42
|
+
<a href="classes/Inflector/Inflections.html#M000021">singular (Inflector::Inflections)</a><br />
|
43
|
+
<a href="classes/Inflector.html#M000007">singularize (Inflector)</a><br />
|
44
|
+
<a href="classes/Inflector.html#M000014">tableize (Inflector)</a><br />
|
45
|
+
<a href="classes/Inflector.html#M000009">titleize (Inflector)</a><br />
|
46
|
+
<a href="classes/FormattedString/Formats/Xml.html#M000004">to_hash (FormattedString::Formats::Xml)</a><br />
|
47
|
+
<a href="classes/Inflector/Inflections.html#M000023">uncountable (Inflector::Inflections)</a><br />
|
48
|
+
<a href="classes/Inflector.html#M000010">underscore (Inflector)</a><br />
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
</body>
|
52
|
+
</html>
|
data/doc/index.html
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
|
5
|
+
|
6
|
+
<!--
|
7
|
+
|
8
|
+
FormattedString
|
9
|
+
|
10
|
+
-->
|
11
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
12
|
+
<head>
|
13
|
+
<title>FormattedString</title>
|
14
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
15
|
+
</head>
|
16
|
+
<frameset rows="20%, 80%">
|
17
|
+
<frameset cols="25%,35%,45%">
|
18
|
+
<frame src="fr_file_index.html" title="Files" name="Files" />
|
19
|
+
<frame src="fr_class_index.html" name="Classes" />
|
20
|
+
<frame src="fr_method_index.html" name="Methods" />
|
21
|
+
</frameset>
|
22
|
+
<frame src="files/README.html" name="docwin" />
|
23
|
+
</frameset>
|
24
|
+
</html>
|
data/doc/rdoc-style.css
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
|
2
|
+
body {
|
3
|
+
font-family: Verdana,Arial,Helvetica,sans-serif;
|
4
|
+
font-size: 90%;
|
5
|
+
margin: 0;
|
6
|
+
margin-left: 40px;
|
7
|
+
padding: 0;
|
8
|
+
background: white;
|
9
|
+
}
|
10
|
+
|
11
|
+
h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
|
12
|
+
h1 { font-size: 150%; }
|
13
|
+
h2,h3,h4 { margin-top: 1em; }
|
14
|
+
|
15
|
+
a { background: #eef; color: #039; text-decoration: none; }
|
16
|
+
a:hover { background: #039; color: #eef; }
|
17
|
+
|
18
|
+
/* Override the base stylesheet's Anchor inside a table cell */
|
19
|
+
td > a {
|
20
|
+
background: transparent;
|
21
|
+
color: #039;
|
22
|
+
text-decoration: none;
|
23
|
+
}
|
24
|
+
|
25
|
+
/* and inside a section title */
|
26
|
+
.section-title > a {
|
27
|
+
background: transparent;
|
28
|
+
color: #eee;
|
29
|
+
text-decoration: none;
|
30
|
+
}
|
31
|
+
|
32
|
+
/* === Structural elements =================================== */
|
33
|
+
|
34
|
+
div#index {
|
35
|
+
margin: 0;
|
36
|
+
margin-left: -40px;
|
37
|
+
padding: 0;
|
38
|
+
font-size: 90%;
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
div#index a {
|
43
|
+
margin-left: 0.7em;
|
44
|
+
}
|
45
|
+
|
46
|
+
div#index .section-bar {
|
47
|
+
margin-left: 0px;
|
48
|
+
padding-left: 0.7em;
|
49
|
+
background: #ccc;
|
50
|
+
font-size: small;
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
div#classHeader, div#fileHeader {
|
55
|
+
width: auto;
|
56
|
+
color: white;
|
57
|
+
padding: 0.5em 1.5em 0.5em 1.5em;
|
58
|
+
margin: 0;
|
59
|
+
margin-left: -40px;
|
60
|
+
border-bottom: 3px solid #006;
|
61
|
+
}
|
62
|
+
|
63
|
+
div#classHeader a, div#fileHeader a {
|
64
|
+
background: inherit;
|
65
|
+
color: white;
|
66
|
+
}
|
67
|
+
|
68
|
+
div#classHeader td, div#fileHeader td {
|
69
|
+
background: inherit;
|
70
|
+
color: white;
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
div#fileHeader {
|
75
|
+
background: #057;
|
76
|
+
}
|
77
|
+
|
78
|
+
div#classHeader {
|
79
|
+
background: #048;
|
80
|
+
}
|
81
|
+
|
82
|
+
|
83
|
+
.class-name-in-header {
|
84
|
+
font-size: 180%;
|
85
|
+
font-weight: bold;
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
div#bodyContent {
|
90
|
+
padding: 0 1.5em 0 1.5em;
|
91
|
+
}
|
92
|
+
|
93
|
+
div#description {
|
94
|
+
padding: 0.5em 1.5em;
|
95
|
+
background: #efefef;
|
96
|
+
border: 1px dotted #999;
|
97
|
+
}
|
98
|
+
|
99
|
+
div#description h1,h2,h3,h4,h5,h6 {
|
100
|
+
color: #125;;
|
101
|
+
background: transparent;
|
102
|
+
}
|
103
|
+
|
104
|
+
div#validator-badges {
|
105
|
+
text-align: center;
|
106
|
+
}
|
107
|
+
div#validator-badges img { border: 0; }
|
108
|
+
|
109
|
+
div#copyright {
|
110
|
+
color: #333;
|
111
|
+
background: #efefef;
|
112
|
+
font: 0.75em sans-serif;
|
113
|
+
margin-top: 5em;
|
114
|
+
margin-bottom: 0;
|
115
|
+
padding: 0.5em 2em;
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
/* === Classes =================================== */
|
120
|
+
|
121
|
+
table.header-table {
|
122
|
+
color: white;
|
123
|
+
font-size: small;
|
124
|
+
}
|
125
|
+
|
126
|
+
.type-note {
|
127
|
+
font-size: small;
|
128
|
+
color: #DEDEDE;
|
129
|
+
}
|
130
|
+
|
131
|
+
.xxsection-bar {
|
132
|
+
background: #eee;
|
133
|
+
color: #333;
|
134
|
+
padding: 3px;
|
135
|
+
}
|
136
|
+
|
137
|
+
.section-bar {
|
138
|
+
color: #333;
|
139
|
+
border-bottom: 1px solid #999;
|
140
|
+
margin-left: -20px;
|
141
|
+
}
|
142
|
+
|
143
|
+
|
144
|
+
.section-title {
|
145
|
+
background: #79a;
|
146
|
+
color: #eee;
|
147
|
+
padding: 3px;
|
148
|
+
margin-top: 2em;
|
149
|
+
margin-left: -30px;
|
150
|
+
border: 1px solid #999;
|
151
|
+
}
|
152
|
+
|
153
|
+
.top-aligned-row { vertical-align: top }
|
154
|
+
.bottom-aligned-row { vertical-align: bottom }
|
155
|
+
|
156
|
+
/* --- Context section classes ----------------------- */
|
157
|
+
|
158
|
+
.context-row { }
|
159
|
+
.context-item-name { font-family: monospace; font-weight: bold; color: black; }
|
160
|
+
.context-item-value { font-size: small; color: #448; }
|
161
|
+
.context-item-desc { color: #333; padding-left: 2em; }
|
162
|
+
|
163
|
+
/* --- Method classes -------------------------- */
|
164
|
+
.method-detail {
|
165
|
+
background: #efefef;
|
166
|
+
padding: 0;
|
167
|
+
margin-top: 0.5em;
|
168
|
+
margin-bottom: 1em;
|
169
|
+
border: 1px dotted #ccc;
|
170
|
+
}
|
171
|
+
.method-heading {
|
172
|
+
color: black;
|
173
|
+
background: #ccc;
|
174
|
+
border-bottom: 1px solid #666;
|
175
|
+
padding: 0.2em 0.5em 0 0.5em;
|
176
|
+
}
|
177
|
+
.method-signature { color: black; background: inherit; }
|
178
|
+
.method-name { font-weight: bold; }
|
179
|
+
.method-args { font-style: italic; }
|
180
|
+
.method-description { padding: 0 0.5em 0 0.5em; }
|
181
|
+
|
182
|
+
/* --- Source code sections -------------------- */
|
183
|
+
|
184
|
+
a.source-toggle { font-size: 90%; }
|
185
|
+
div.method-source-code {
|
186
|
+
background: #262626;
|
187
|
+
color: #ffdead;
|
188
|
+
margin: 1em;
|
189
|
+
padding: 0.5em;
|
190
|
+
border: 1px dashed #999;
|
191
|
+
overflow: hidden;
|
192
|
+
}
|
193
|
+
|
194
|
+
div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
195
|
+
|
196
|
+
/* --- Ruby keyword styles --------------------- */
|
197
|
+
|
198
|
+
.standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
|
199
|
+
|
200
|
+
.ruby-constant { color: #7fffd4; background: transparent; }
|
201
|
+
.ruby-keyword { color: #00ffff; background: transparent; }
|
202
|
+
.ruby-ivar { color: #eedd82; background: transparent; }
|
203
|
+
.ruby-operator { color: #00ffee; background: transparent; }
|
204
|
+
.ruby-identifier { color: #ffdead; background: transparent; }
|
205
|
+
.ruby-node { color: #ffa07a; background: transparent; }
|
206
|
+
.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
|
207
|
+
.ruby-regexp { color: #ffa07a; background: transparent; }
|
208
|
+
.ruby-value { color: #7fffd4; background: transparent; }
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# This is a slighly modified version of the XMLUtilityNode from
|
2
|
+
# http://merb.devjavu.com/projects/merb/ticket/95 (has.sox@gmail.com)
|
3
|
+
# It's mainly just adding vowels, as I ht cd wth n vwls :)
|
4
|
+
# This represents the hard part of the work, all I did was change the underlying
|
5
|
+
# parser
|
6
|
+
|
7
|
+
require 'rexml/light/node'
|
8
|
+
require 'rexml/document'
|
9
|
+
|
10
|
+
module Enumerable
|
11
|
+
def group_by
|
12
|
+
inject({}) do |groups, element|
|
13
|
+
(groups[yield(element)] ||= []) << element
|
14
|
+
groups
|
15
|
+
end
|
16
|
+
end if RUBY_VERSION < '1.9'
|
17
|
+
|
18
|
+
def crawl(&block)
|
19
|
+
raise ArgumentError, "no block given" unless block_given?
|
20
|
+
self.each do |v|
|
21
|
+
k = self
|
22
|
+
v = case block.arity
|
23
|
+
when 1
|
24
|
+
yield(v)
|
25
|
+
when 2
|
26
|
+
yield(k,v)
|
27
|
+
when 3
|
28
|
+
yield(self,k,v)
|
29
|
+
end
|
30
|
+
if v.is_a?(Array)
|
31
|
+
v.crawl(&block)
|
32
|
+
elsif v.is_a?(Hash)
|
33
|
+
v.crawl(&block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class REXMLUtilityNode # :nodoc:
|
40
|
+
attr_accessor :name, :attributes, :children
|
41
|
+
|
42
|
+
def initialize(name, attributes = {})
|
43
|
+
@name = name.tr("-", "_")
|
44
|
+
@attributes = undasherize_keys(attributes)
|
45
|
+
@children = []
|
46
|
+
@text = false
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_node(node)
|
50
|
+
@text = true if node.is_a? String
|
51
|
+
@children << node
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_hash
|
55
|
+
if @text
|
56
|
+
return { name => typecast_value( translate_xml_entities( inner_html ) ) }
|
57
|
+
else
|
58
|
+
#change repeating groups into an array
|
59
|
+
# group by the first key of each element of the array to find repeating groups
|
60
|
+
groups = @children.group_by{ |c| c.name }
|
61
|
+
|
62
|
+
hash = {}
|
63
|
+
groups.each do |key, values|
|
64
|
+
if values.size == 1
|
65
|
+
hash.merge! values.first
|
66
|
+
else
|
67
|
+
hash.merge! key => values.map { |element| element.to_hash[key] }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# merge the arrays, including attributes
|
72
|
+
hash.merge! attributes unless attributes.empty?
|
73
|
+
|
74
|
+
{ name => hash }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def typecast_value(value)
|
79
|
+
return value unless attributes["type"]
|
80
|
+
|
81
|
+
case attributes["type"]
|
82
|
+
when "integer" then value.to_i
|
83
|
+
when "boolean" then value.strip == "true"
|
84
|
+
when "datetime" then ::Time.parse(value).utc
|
85
|
+
when "date" then ::Date.parse(value)
|
86
|
+
else value
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def translate_xml_entities(value)
|
91
|
+
value.gsub(/</, "<").
|
92
|
+
gsub(/>/, ">").
|
93
|
+
gsub(/"/, '"').
|
94
|
+
gsub(/'/, "'").
|
95
|
+
gsub(/&/, "&")
|
96
|
+
end
|
97
|
+
|
98
|
+
def undasherize_keys(params)
|
99
|
+
params.keys.each do |key, vvalue|
|
100
|
+
params[key.tr("-", "_")] = params.delete(key)
|
101
|
+
end
|
102
|
+
params
|
103
|
+
end
|
104
|
+
|
105
|
+
def inner_html
|
106
|
+
@children.join
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_html
|
110
|
+
"<#{name}#{attributes.to_xml_attributes}>#{inner_html}</#{name}>"
|
111
|
+
end
|
112
|
+
|
113
|
+
def to_s
|
114
|
+
to_html
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
module FormattedString
|
119
|
+
module Formats
|
120
|
+
module Xml
|
121
|
+
XML_OPTIONS = {
|
122
|
+
:include_key => :attribute, # Can be false, :element, or :attribute
|
123
|
+
:report_nil => true, # Sets an attribute nil="true" on elements that are nil, so that the reader doesn't read as an empty string
|
124
|
+
:key_name => 'id', # Default key name
|
125
|
+
}
|
126
|
+
|
127
|
+
def to_hash(options={})
|
128
|
+
options = XML_OPTIONS.merge(options)
|
129
|
+
|
130
|
+
stack = []
|
131
|
+
parser = REXML::Parsers::BaseParser.new(self)
|
132
|
+
|
133
|
+
while true
|
134
|
+
event = parser.pull
|
135
|
+
case event[0]
|
136
|
+
when :end_document
|
137
|
+
break
|
138
|
+
when :end_doctype, :start_doctype
|
139
|
+
# do nothing
|
140
|
+
when :start_element
|
141
|
+
stack.push REXMLUtilityNode.new(event[1], event[2])
|
142
|
+
when :end_element
|
143
|
+
if stack.size > 1
|
144
|
+
temp = stack.pop
|
145
|
+
stack.last.add_node(temp)
|
146
|
+
end
|
147
|
+
when :text, :cdata
|
148
|
+
stack.last.add_node(event[1]) unless event[1].strip.length == 0
|
149
|
+
end
|
150
|
+
end
|
151
|
+
data = stack.pop.to_hash
|
152
|
+
|
153
|
+
# Turn any {} || {"nil" => "true"} into just nil
|
154
|
+
if options[:report_nil]
|
155
|
+
data.crawl {|h,k,v| h[k] = nil if v == {} || v == {'nil' => 'true'}; v}
|
156
|
+
else
|
157
|
+
data.crawl {|h,k,v| h[k] = nil if v == {}; v}
|
158
|
+
end
|
159
|
+
data
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'inflector'
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
# Use this to see what format you've set to the string.
|
6
|
+
# s = '<some><xml>text</xml></some>'
|
7
|
+
# s.format = :xml
|
8
|
+
# s.format
|
9
|
+
# => :xml
|
10
|
+
def format
|
11
|
+
@format
|
12
|
+
end
|
13
|
+
|
14
|
+
# Use this to specify that this string is a certain format.
|
15
|
+
# s = '<some><xml>text</xml></some>'
|
16
|
+
# s.format = :xml
|
17
|
+
# s.to_hash # a method extended onto the `s' object from the xml format module.
|
18
|
+
# => {'some' => {'xml' => 'text'}}
|
19
|
+
def format=(fmat)
|
20
|
+
require "formatted_string/formats/#{fmat.to_s}" rescue nil
|
21
|
+
extend Object.module_eval("::FormattedString::Formats::#{Inflector.camelize(fmat.to_s)}", __FILE__, __LINE__)
|
22
|
+
@format = [@format, fmat].flatten.compact
|
23
|
+
end
|
24
|
+
|
25
|
+
# Simply sets format=, but returns the string object.
|
26
|
+
def formatted(fmat)
|
27
|
+
self.format = fmat
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
# I'd like to eventually make this auto-recognize the format, but I haven't yet had the time.
|
32
|
+
# def auto_recognize_format
|
33
|
+
# end
|
34
|
+
end
|
data/lib/inflections.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
Inflector.inflections do |inflect|
|
2
|
+
inflect.plural(/$/, 's')
|
3
|
+
inflect.plural(/s$/i, 's')
|
4
|
+
inflect.plural(/(ax|test)is$/i, '\1es')
|
5
|
+
inflect.plural(/(octop|vir)us$/i, '\1i')
|
6
|
+
inflect.plural(/(alias|status)$/i, '\1es')
|
7
|
+
inflect.plural(/(bu)s$/i, '\1ses')
|
8
|
+
inflect.plural(/(buffal|tomat)o$/i, '\1oes')
|
9
|
+
inflect.plural(/([ti])um$/i, '\1a')
|
10
|
+
inflect.plural(/sis$/i, 'ses')
|
11
|
+
inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
|
12
|
+
inflect.plural(/(hive)$/i, '\1s')
|
13
|
+
inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
|
14
|
+
inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
|
15
|
+
inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices')
|
16
|
+
inflect.plural(/([m|l])ouse$/i, '\1ice')
|
17
|
+
inflect.plural(/^(ox)$/i, '\1en')
|
18
|
+
inflect.plural(/(quiz)$/i, '\1zes')
|
19
|
+
|
20
|
+
inflect.singular(/s$/i, '')
|
21
|
+
inflect.singular(/(n)ews$/i, '\1ews')
|
22
|
+
inflect.singular(/([ti])a$/i, '\1um')
|
23
|
+
inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
|
24
|
+
inflect.singular(/(^analy)ses$/i, '\1sis')
|
25
|
+
inflect.singular(/([^f])ves$/i, '\1fe')
|
26
|
+
inflect.singular(/(hive)s$/i, '\1')
|
27
|
+
inflect.singular(/(tive)s$/i, '\1')
|
28
|
+
inflect.singular(/([lr])ves$/i, '\1f')
|
29
|
+
inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
|
30
|
+
inflect.singular(/(s)eries$/i, '\1eries')
|
31
|
+
inflect.singular(/(m)ovies$/i, '\1ovie')
|
32
|
+
inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
|
33
|
+
inflect.singular(/([m|l])ice$/i, '\1ouse')
|
34
|
+
inflect.singular(/(bus)es$/i, '\1')
|
35
|
+
inflect.singular(/(o)es$/i, '\1')
|
36
|
+
inflect.singular(/(shoe)s$/i, '\1')
|
37
|
+
inflect.singular(/(cris|ax|test)es$/i, '\1is')
|
38
|
+
inflect.singular(/(octop|vir)i$/i, '\1us')
|
39
|
+
inflect.singular(/(alias|status)es$/i, '\1')
|
40
|
+
inflect.singular(/^(ox)en/i, '\1')
|
41
|
+
inflect.singular(/(vert|ind)ices$/i, '\1ex')
|
42
|
+
inflect.singular(/(matr)ices$/i, '\1ix')
|
43
|
+
inflect.singular(/(quiz)zes$/i, '\1')
|
44
|
+
|
45
|
+
inflect.irregular('person', 'people')
|
46
|
+
inflect.irregular('man', 'men')
|
47
|
+
inflect.irregular('child', 'children')
|
48
|
+
inflect.irregular('sex', 'sexes')
|
49
|
+
inflect.irregular('move', 'moves')
|
50
|
+
inflect.irregular('cow', 'kine')
|
51
|
+
|
52
|
+
inflect.uncountable(%w(equipment information rice money species series fish sheep))
|
53
|
+
end
|