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.
Files changed (53) hide show
  1. data/LICENSE +16 -0
  2. data/README +57 -0
  3. data/Rakefile +79 -0
  4. data/doc/classes/Enumerable.html +146 -0
  5. data/doc/classes/Enumerable.src/M000025.html +21 -0
  6. data/doc/classes/Enumerable.src/M000026.html +34 -0
  7. data/doc/classes/FormattedString/Formats/Xml.html +144 -0
  8. data/doc/classes/FormattedString/Formats/Xml.src/M000004.html +49 -0
  9. data/doc/classes/FormattedString/Formats.html +111 -0
  10. data/doc/classes/FormattedString.html +111 -0
  11. data/doc/classes/Inflector/Inflections.html +321 -0
  12. data/doc/classes/Inflector/Inflections.src/M000019.html +18 -0
  13. data/doc/classes/Inflector/Inflections.src/M000020.html +18 -0
  14. data/doc/classes/Inflector/Inflections.src/M000021.html +18 -0
  15. data/doc/classes/Inflector/Inflections.src/M000022.html +26 -0
  16. data/doc/classes/Inflector/Inflections.src/M000023.html +18 -0
  17. data/doc/classes/Inflector/Inflections.src/M000024.html +23 -0
  18. data/doc/classes/Inflector.html +516 -0
  19. data/doc/classes/Inflector.src/M000005.html +22 -0
  20. data/doc/classes/Inflector.src/M000006.html +25 -0
  21. data/doc/classes/Inflector.src/M000007.html +25 -0
  22. data/doc/classes/Inflector.src/M000008.html +22 -0
  23. data/doc/classes/Inflector.src/M000009.html +18 -0
  24. data/doc/classes/Inflector.src/M000010.html +22 -0
  25. data/doc/classes/Inflector.src/M000011.html +18 -0
  26. data/doc/classes/Inflector.src/M000012.html +18 -0
  27. data/doc/classes/Inflector.src/M000013.html +18 -0
  28. data/doc/classes/Inflector.src/M000014.html +18 -0
  29. data/doc/classes/Inflector.src/M000015.html +19 -0
  30. data/doc/classes/Inflector.src/M000016.html +18 -0
  31. data/doc/classes/Inflector.src/M000017.html +22 -0
  32. data/doc/classes/Inflector.src/M000018.html +27 -0
  33. data/doc/classes/String.html +191 -0
  34. data/doc/classes/String.src/M000001.html +18 -0
  35. data/doc/classes/String.src/M000002.html +20 -0
  36. data/doc/classes/String.src/M000003.html +19 -0
  37. data/doc/created.rid +1 -0
  38. data/doc/files/LICENSE.html +129 -0
  39. data/doc/files/README.html +196 -0
  40. data/doc/files/lib/formatted_string/formats/xml_rb.html +119 -0
  41. data/doc/files/lib/formatted_string_rb.html +108 -0
  42. data/doc/files/lib/inflections_rb.html +101 -0
  43. data/doc/files/lib/inflector_rb.html +108 -0
  44. data/doc/fr_class_index.html +33 -0
  45. data/doc/fr_file_index.html +32 -0
  46. data/doc/fr_method_index.html +52 -0
  47. data/doc/index.html +24 -0
  48. data/doc/rdoc-style.css +208 -0
  49. data/lib/formatted_string/formats/xml.rb +163 -0
  50. data/lib/formatted_string.rb +34 -0
  51. data/lib/inflections.rb +53 -0
  52. data/lib/inflector.rb +282 -0
  53. 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>
@@ -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(/&lt;/, "<").
92
+ gsub(/&gt;/, ">").
93
+ gsub(/&quot;/, '"').
94
+ gsub(/&apos;/, "'").
95
+ gsub(/&amp;/, "&")
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
@@ -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