atom-tools 0.9.0 → 2.0.5

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 (93) hide show
  1. data/COPYING +3 -3
  2. data/README +9 -49
  3. data/Rakefile +65 -62
  4. data/bin/atom-cp +159 -0
  5. data/bin/atom-grep +78 -0
  6. data/bin/atom-post +73 -0
  7. data/bin/atom-purge +82 -0
  8. data/doc/classes/Atom/AttrEl.html +163 -0
  9. data/doc/classes/Atom/Author.html +2 -19
  10. data/doc/classes/Atom/AutodiscoveryFailure.html +111 -0
  11. data/doc/classes/Atom/Categories.html +168 -0
  12. data/doc/classes/Atom/Category.html +10 -1
  13. data/doc/classes/Atom/Collection.html +194 -91
  14. data/doc/classes/Atom/Content.html +42 -1
  15. data/doc/classes/Atom/Contributor.html +2 -8
  16. data/doc/classes/Atom/Control.html +126 -0
  17. data/doc/classes/Atom/Converters.html +571 -0
  18. data/doc/classes/Atom/DigestAuth.html +285 -0
  19. data/doc/classes/Atom/Element.html +673 -106
  20. data/doc/classes/Atom/FileCache.html +287 -0
  21. data/doc/classes/Atom/HTTP.html +211 -95
  22. data/doc/classes/Atom/HTTPResponse.html +190 -0
  23. data/doc/classes/Atom/HasCategories.html +187 -0
  24. data/doc/classes/Atom/HasLinks.html +168 -0
  25. data/doc/classes/Atom/Link.html +80 -3
  26. data/doc/classes/Atom/NilCache.html +202 -0
  27. data/doc/classes/Atom/ParseError.html +111 -0
  28. data/doc/classes/Atom/Parsers.html +311 -0
  29. data/doc/classes/Atom/Person.html +130 -0
  30. data/doc/classes/Atom/Rights.html +113 -0
  31. data/doc/classes/Atom/Service.html +298 -0
  32. data/doc/{files/lib/atom/yaml_rb.html → classes/Atom/Source.html} +26 -24
  33. data/doc/classes/Atom/Subtitle.html +113 -0
  34. data/doc/classes/Atom/Summary.html +113 -0
  35. data/doc/classes/Atom/Text.html +196 -53
  36. data/doc/classes/Atom/Title.html +113 -0
  37. data/doc/classes/Atom/Tools.html +525 -0
  38. data/doc/classes/Atom/Workspace.html +121 -0
  39. data/doc/classes/Object.html +204 -0
  40. data/doc/created.rid +1 -1
  41. data/doc/files/README.html +9 -49
  42. data/doc/files/lib/atom/cache_rb.html +302 -0
  43. data/doc/files/lib/atom/collection_rb.html +1 -2
  44. data/doc/files/lib/atom/element_rb.html +2 -1
  45. data/doc/files/lib/atom/entry_rb.html +2 -2
  46. data/doc/files/lib/atom/feed_rb.html +1 -2
  47. data/doc/files/lib/atom/http_rb.html +6 -1
  48. data/doc/files/lib/atom/{xml_rb.html → service_rb.html} +8 -6
  49. data/doc/files/lib/atom/text_rb.html +2 -1
  50. data/doc/files/lib/atom/{app_rb.html → tools_rb.html} +4 -6
  51. data/doc/fr_class_index.html +23 -3
  52. data/doc/fr_file_index.html +3 -3
  53. data/doc/fr_method_index.html +111 -36
  54. data/lib/atom/cache.rb +178 -0
  55. data/lib/atom/collection.rb +90 -40
  56. data/lib/atom/element.rb +569 -161
  57. data/lib/atom/entry.rb +63 -89
  58. data/lib/atom/feed.rb +65 -67
  59. data/lib/atom/http.rb +421 -49
  60. data/lib/atom/service.rb +106 -0
  61. data/lib/atom/text.rb +138 -61
  62. data/lib/atom/tools.rb +163 -0
  63. data/spec/entry_spec.rb +364 -0
  64. data/spec/ext_spec.rb +42 -0
  65. data/spec/feed_spec.rb +39 -0
  66. data/spec/fixtures/contacts-feed.xml +34 -0
  67. data/spec/fixtures/entry-w-ext.xml +15 -0
  68. data/spec/fixtures/entry-w-xml.xml +24 -0
  69. data/spec/fixtures/entry.xml +42 -0
  70. data/spec/fixtures/feed-w-ext.xml +33 -0
  71. data/spec/fixtures/service-w-xhtml-ns.xml +21 -0
  72. data/spec/fixtures/service.xml +36 -0
  73. data/spec/service_spec.rb +108 -0
  74. data/spec/spec_helper.rb +9 -0
  75. data/test/conformance/order.rb +11 -10
  76. data/test/conformance/title.rb +9 -9
  77. data/test/conformance/updated.rb +2 -1
  78. data/test/runtests.rb +0 -0
  79. data/test/test_constructs.rb +78 -8
  80. data/test/test_feed.rb +35 -29
  81. data/test/test_general.rb +3 -30
  82. data/test/test_http.rb +248 -34
  83. data/test/test_protocol.rb +143 -24
  84. data/test/test_xml.rb +145 -53
  85. metadata +116 -62
  86. data/bin/atom-client.rb +0 -246
  87. data/bin/atom-server.rb~ +0 -71
  88. data/doc/classes/Atom/App.html +0 -217
  89. data/doc/classes/Atom/Entry.html +0 -365
  90. data/doc/classes/Atom/Feed.html +0 -585
  91. data/lib/atom/app.rb +0 -87
  92. data/lib/atom/xml.rb +0 -200
  93. data/lib/atom/yaml.rb +0 -101
data/bin/atom-client.rb DELETED
@@ -1,246 +0,0 @@
1
- #!/usr/bin/ruby
2
-
3
- # syntax: ./atom-client.rb <introspection-url> [username] [password]
4
- # a
5
-
6
- require "tempfile"
7
-
8
- require "atom/yaml"
9
- require "atom/app"
10
- require "atom/http"
11
-
12
- require "rubygems"
13
- require "bluecloth"
14
-
15
- require "time"
16
-
17
- require 'yaml'
18
-
19
- class Tempfile
20
- def edit_externally
21
- self.close
22
-
23
- system("#{EDITOR} #{self.path}")
24
-
25
- self.open
26
- end
27
- end
28
-
29
- class String
30
- def edit_externally
31
- tempfile = Tempfile.new("entry")
32
- tempfile.puts self
33
-
34
- tempfile.edit_externally
35
-
36
- ret = tempfile.read
37
- tempfile.delete
38
-
39
- ret
40
- end
41
- end
42
-
43
- class Atom::Entry
44
- def prepare_for_output
45
- filter_hook
46
-
47
- update!
48
- end
49
-
50
- def filter_hook
51
- # so much for actual text content...
52
- if @content and @content["type"] == "text"
53
- self.content = BlueCloth.new( @content.to_s ).to_html
54
- @content["type"] = "xhtml"
55
- end
56
- end
57
-
58
- def edit
59
- yaml = YAML.load(self.to_yaml)
60
-
61
- # humans don't care about these things
62
- yaml.delete "id"
63
-
64
- if yaml["links"]
65
- yaml["links"].delete(yaml["links"].find { |l| l["rel"] == "edit" })
66
- yaml["links"].delete(yaml["links"].find { |l| l["rel"] == "alternate" })
67
- yaml.delete("links") if yaml["links"].empty?
68
- end
69
-
70
- entry = write_entry(yaml.to_yaml)
71
- # the id doesn't appear in YAML, it should remain the same
72
- entry.id = self.id
73
-
74
- entry
75
- end
76
- end
77
-
78
- # maybe this should handle displaying the list too.
79
- def choose_from list
80
- item = nil
81
- itemno = nil
82
-
83
- # oh wow this is pathetic
84
- until item
85
- if itemno
86
- puts "try picking a number on the list."
87
- end
88
-
89
- print "? "
90
- itemno = $stdin.gets.chomp
91
-
92
- item = list[itemno.to_i]
93
- end
94
-
95
- item
96
- end
97
-
98
- def choose_collection server
99
- puts "which collection?"
100
-
101
- collections = []
102
-
103
- # still lame
104
- server.collections.each_with_index do |coll, index|
105
- collections << coll
106
-
107
- puts "#{index}: #{coll.title}"
108
- end
109
-
110
- choose_from collections
111
- end
112
-
113
- def choose_entry_url coll
114
- puts "which entry?"
115
-
116
- coll.entries.each_with_index do |entry, index|
117
- puts "#{index}: #{entry.title}"
118
- end
119
-
120
- entry = choose_from coll.entries
121
-
122
- edit_link = entry.links.find do |link|
123
- link["rel"] = "edit"
124
- end
125
-
126
- edit_link["href"]
127
- end
128
-
129
- def write_entry(editstring = "")
130
- begin
131
- edited = editstring.edit_externally
132
-
133
- if edited == editstring
134
- puts "unchanged content, aborted"
135
- exit
136
- end
137
-
138
- entry = Atom::Entry.from_yaml edited
139
-
140
- entry.prepare_for_output
141
-
142
- # XXX disabled until the APP WG can decide what a valid entry is
143
- =begin
144
- valid, message = entry.valid?
145
- unless valid
146
- print "entry is invalid (#{message}). post anyway? (y/n)? "
147
- (gets.chomp == "y") || (raise Atom::InvalidEntry.new)
148
- end
149
- =end
150
-
151
- # this has to be here ATM to we can detect malformed atom:content
152
- puts entry.to_s
153
- rescue ArgumentError,REXML::ParseException => e
154
- puts e
155
-
156
- puts "press enter to edit again..."
157
- $stdin.gets
158
-
159
- editstring = edited
160
-
161
- retry
162
- rescue Atom::InvalidEntry
163
- editstring = edited
164
- retry
165
- end
166
-
167
- entry
168
- end
169
-
170
- module Atom
171
- class InvalidEntry < RuntimeError
172
- end
173
- end
174
-
175
- EDITOR = ENV["EDITOR"] || "env vim"
176
-
177
- # now that i'm supporting -07 the interface has been shittified. apologies.
178
- introspection_url = ARGV[0]
179
-
180
- http = Atom::HTTP.new
181
- http.user = ARGV[1]
182
- http.pass = ARGV[2]
183
-
184
- server = Atom::App.new(introspection_url, http)
185
-
186
- coll = choose_collection server
187
-
188
- # XXX the server should *probably* replace this, but who knows yet?
189
- CLIENT_ID = "http://necronomicorp.com/dev/null"
190
-
191
- new = lambda do
192
- entry = Atom::Entry.new
193
-
194
- entry.title = ""
195
- entry.content = ""
196
-
197
- entry = entry.edit
198
-
199
- entry.id = CLIENT_ID
200
- entry.published = Time.now.iso8601
201
-
202
- res = coll.post! entry
203
-
204
- # XXX error recovery here, lost updates suck
205
- puts res.body
206
- end
207
-
208
- edit = lambda do
209
- coll.update!
210
-
211
- coll.entries.each_with_index do |entry,idx|
212
- puts "#{idx}: #{entry.title}"
213
- end
214
-
215
- entry = choose_from(coll.entries) { |entry| entry.title }
216
-
217
- url = entry.edit_url
218
-
219
- entry = http.get_atom_entry url
220
-
221
- res = coll.put! entry.edit, url
222
-
223
- # XXX error recovery here, lost updates suck
224
- puts res.body
225
- end
226
-
227
- delete = lambda do
228
- coll.update!
229
-
230
- coll.entries.each_with_index do |entry,idx|
231
- puts "#{idx} #{entry.title}"
232
- end
233
-
234
- entry = choose_from(coll.entries)
235
- res = coll.delete! entry
236
-
237
- puts res.body
238
- end
239
-
240
- actions = [ new, edit, delete ]
241
-
242
- puts "0: new entry"
243
- puts "1: edit entry"
244
- puts "2: delete entry"
245
-
246
- choose_from(actions).call
data/bin/atom-server.rb~ DELETED
@@ -1,71 +0,0 @@
1
- #!/usr/bin/ruby
2
-
3
- require "atom/pub-server"
4
- require "webrick/httpserver"
5
- require "atom/feed"
6
-
7
- # syntax: ./atom-server <port> <path>
8
-
9
- module Atom
10
- # @docs must implement [], []=, next_id!
11
- # including servlet must implement gen_id, url_to_key, key_to_url, do_GET
12
- class MemoryCollection < WEBrick::HTTPServlet::AbstractServlet
13
- include Atom::AtomPub
14
-
15
- def initialize server, docs
16
- super
17
-
18
- @docs = docs
19
- end
20
-
21
- def gen_id key
22
- key
23
- end
24
-
25
- def key_to_url req, key
26
- req.script_name + "/" + key
27
- end
28
-
29
- def url_to_key url
30
- url.split("/").last
31
- end
32
-
33
- def add_edit entry, key
34
- edit = entry.links.new
35
- edit["rel"] = "edit"
36
- edit
37
- end
38
-
39
- def do_GET req, res
40
- res.body = if req.path_info.empty? or req.path_info == "/"
41
- feed = Atom::Feed.new
42
-
43
- @docs.each do |key,doc|
44
- entry = doc.to_atom_entry
45
- add_edit(entry, key)["href"] = key_to_url(req, key)
46
- feed << entry
47
- end
48
-
49
- feed.entries.first.to_s
50
- else
51
- key = url_to_key(req.request_uri.to_s)
52
- entry = @docs[key].to_atom_entry
53
- add_edit(entry, key)["href"] = key_to_url(req, key)
54
- entry.to_s
55
- end
56
- end
57
- end
58
- end
59
-
60
- h = WEBrick::HTTPServer.new(:Port => ARGV[0])
61
-
62
- docs = {}
63
- docs.instance_variable_set :@last_key, "0"
64
-
65
- def docs.next_key!
66
- @last_key.next!
67
- end
68
-
69
- h.mount(ARGV[1], Atom::MemoryCollection, docs)
70
-
71
- h.start
@@ -1,217 +0,0 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
- <head>
8
- <title>Class: Atom::App</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
- <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12
- <script type="text/javascript">
13
- // <![CDATA[
14
-
15
- function popupCode( url ) {
16
- window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
- }
18
-
19
- function toggleCode( id ) {
20
- if ( document.getElementById )
21
- elem = document.getElementById( id );
22
- else if ( document.all )
23
- elem = eval( "document.all." + id );
24
- else
25
- return false;
26
-
27
- elemStyle = elem.style;
28
-
29
- if ( elemStyle.display != "block" ) {
30
- elemStyle.display = "block"
31
- } else {
32
- elemStyle.display = "none"
33
- }
34
-
35
- return true;
36
- }
37
-
38
- // Make codeblocks hidden by default
39
- document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
-
41
- // ]]>
42
- </script>
43
-
44
- </head>
45
- <body>
46
-
47
-
48
-
49
- <div id="classHeader">
50
- <table class="header-table">
51
- <tr class="top-aligned-row">
52
- <td><strong>Class</strong></td>
53
- <td class="class-name-in-header">Atom::App</td>
54
- </tr>
55
- <tr class="top-aligned-row">
56
- <td><strong>In:</strong></td>
57
- <td>
58
- <a href="../../files/lib/atom/app_rb.html">
59
- lib/atom/app.rb
60
- </a>
61
- <br />
62
- </td>
63
- </tr>
64
-
65
- <tr class="top-aligned-row">
66
- <td><strong>Parent:</strong></td>
67
- <td>
68
- Object
69
- </td>
70
- </tr>
71
- </table>
72
- </div>
73
- <!-- banner header -->
74
-
75
- <div id="bodyContent">
76
-
77
-
78
-
79
- <div id="contextContent">
80
-
81
- <div id="description">
82
- <p>
83
- <a href="App.html">Atom::App</a> represents an Atom Publishing Protocol
84
- introspection document.
85
- </p>
86
-
87
- </div>
88
-
89
-
90
- </div>
91
-
92
- <div id="method-list">
93
- <h3 class="section-bar">Methods</h3>
94
-
95
- <div class="name-list">
96
- <a href="#M000006">new</a>&nbsp;&nbsp;
97
- </div>
98
- </div>
99
-
100
- </div>
101
-
102
-
103
- <!-- if includes -->
104
-
105
- <div id="section">
106
-
107
-
108
-
109
-
110
-
111
- <div id="attribute-list">
112
- <h3 class="section-bar">Attributes</h3>
113
-
114
- <div class="name-list">
115
- <table>
116
- <tr class="top-aligned-row context-row">
117
- <td class="context-item-name">collections</td>
118
- <td class="context-item-value">&nbsp;[R]&nbsp;</td>
119
- <td class="context-item-desc">
120
- collections referred to by the introspection document
121
-
122
- </td>
123
- </tr>
124
- </table>
125
- </div>
126
- </div>
127
-
128
-
129
-
130
- <!-- if method_list -->
131
- <div id="methods">
132
- <h3 class="section-bar">Public Class methods</h3>
133
-
134
- <div id="method-M000006" class="method-detail">
135
- <a name="M000006"></a>
136
-
137
- <div class="method-heading">
138
- <a href="#M000006" class="method-signature">
139
- <span class="method-name">new</span><span class="method-args">(introspection_url, http = Atom::HTTP.new)</span>
140
- </a>
141
- </div>
142
-
143
- <div class="method-description">
144
- <p>
145
- retrieves and parses an Atom introspection document.
146
- </p>
147
- <p><a class="source-toggle" href="#"
148
- onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
149
- <div class="method-source-code" id="M000006-source">
150
- <pre>
151
- <span class="ruby-comment cmt"># File lib/atom/app.rb, line 23</span>
152
- 23: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">introspection_url</span>, <span class="ruby-identifier">http</span> = <span class="ruby-constant">Atom</span><span class="ruby-operator">::</span><span class="ruby-constant">HTTP</span>.<span class="ruby-identifier">new</span>)
153
- 24: <span class="ruby-identifier">i_url</span> = <span class="ruby-constant">URI</span>.<span class="ruby-identifier">parse</span>(<span class="ruby-identifier">introspection_url</span>)
154
- 25:
155
- 26: <span class="ruby-identifier">rxml</span> = <span class="ruby-keyword kw">nil</span>
156
- 27:
157
- 28: <span class="ruby-identifier">res</span> = <span class="ruby-identifier">http</span>.<span class="ruby-identifier">get</span>(<span class="ruby-identifier">i_url</span>)
158
- 29:
159
- 30: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">res</span>.<span class="ruby-identifier">code</span> <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;200&quot;</span> <span class="ruby-comment cmt"># redirects, &amp;c.</span>
160
- 31: <span class="ruby-identifier">raise</span> <span class="ruby-constant">WrongResponse</span>, <span class="ruby-node">&quot;introspection document responded with unexpected code #{res.code}&quot;</span>
161
- 32: <span class="ruby-keyword kw">end</span>
162
- 33:
163
- 34: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">res</span>.<span class="ruby-identifier">content_type</span> <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;application/atomserv+xml&quot;</span>
164
- 35: <span class="ruby-identifier">raise</span> <span class="ruby-constant">WrongMimetype</span>, <span class="ruby-value str">&quot;this isn't an introspection document!&quot;</span>
165
- 36: <span class="ruby-keyword kw">end</span>
166
- 37:
167
- 38: <span class="ruby-identifier">rxml</span> = <span class="ruby-constant">REXML</span><span class="ruby-operator">::</span><span class="ruby-constant">Document</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">res</span>.<span class="ruby-identifier">body</span>)
168
- 39:
169
- 40: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">rxml</span>.<span class="ruby-identifier">root</span>.<span class="ruby-identifier">namespace</span> <span class="ruby-operator">==</span> <span class="ruby-constant">PP_NS</span>
170
- 41: <span class="ruby-identifier">raise</span> <span class="ruby-constant">WrongNamespace</span>, <span class="ruby-value str">&quot;this isn't an introspection document!&quot;</span>
171
- 42: <span class="ruby-keyword kw">end</span>
172
- 43:
173
- 44: <span class="ruby-comment cmt"># TODO: expose workspaces</span>
174
- 45: <span class="ruby-identifier">colls</span> = <span class="ruby-constant">REXML</span><span class="ruby-operator">::</span><span class="ruby-constant">XPath</span>.<span class="ruby-identifier">match</span>( <span class="ruby-identifier">rxml</span>,
175
- 46: <span class="ruby-value str">&quot;/app:service/app:workspace/app:collection&quot;</span>,
176
- 47: {<span class="ruby-value str">&quot;app&quot;</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-constant">Atom</span><span class="ruby-operator">::</span><span class="ruby-constant">PP_NS</span>} )
177
- 48:
178
- 49: <span class="ruby-ivar">@collections</span> = []
179
- 50:
180
- 51: <span class="ruby-identifier">colls</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">collection</span><span class="ruby-operator">|</span>
181
- 52: <span class="ruby-comment cmt"># absolutize relative URLs</span>
182
- 53: <span class="ruby-identifier">url</span> = <span class="ruby-identifier">i_url</span> <span class="ruby-operator">+</span> <span class="ruby-constant">URI</span>.<span class="ruby-identifier">parse</span>(<span class="ruby-identifier">collection</span>.<span class="ruby-identifier">attributes</span>[<span class="ruby-value str">&quot;href&quot;</span>])
183
- 54:
184
- 55: <span class="ruby-identifier">coll</span> = <span class="ruby-constant">Atom</span><span class="ruby-operator">::</span><span class="ruby-constant">Collection</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">url</span>, <span class="ruby-identifier">http</span>)
185
- 56:
186
- 57: <span class="ruby-comment cmt"># XXX this is a Text Construct, and should be parsed as such</span>
187
- 58: <span class="ruby-identifier">coll</span>.<span class="ruby-identifier">title</span> = <span class="ruby-constant">REXML</span><span class="ruby-operator">::</span><span class="ruby-constant">XPath</span>.<span class="ruby-identifier">first</span>( <span class="ruby-identifier">collection</span>,
188
- 59: <span class="ruby-value str">&quot;./atom:title&quot;</span>,
189
- 60: {<span class="ruby-value str">&quot;app&quot;</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-constant">Atom</span><span class="ruby-operator">::</span><span class="ruby-constant">PP_NS</span>,
190
- 61: <span class="ruby-value str">&quot;atom&quot;</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-constant">Atom</span><span class="ruby-operator">::</span><span class="ruby-constant">NS</span> } ).<span class="ruby-identifier">text</span>
191
- 62:
192
- 63: <span class="ruby-identifier">accepts</span> = <span class="ruby-constant">REXML</span><span class="ruby-operator">::</span><span class="ruby-constant">XPath</span>.<span class="ruby-identifier">first</span>( <span class="ruby-identifier">collection</span>,
193
- 64: <span class="ruby-value str">&quot;./app:accept&quot;</span>,
194
- 65: {<span class="ruby-value str">&quot;app&quot;</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-constant">Atom</span><span class="ruby-operator">::</span><span class="ruby-constant">PP_NS</span>} )
195
- 66: <span class="ruby-identifier">coll</span>.<span class="ruby-identifier">accepts</span> = (<span class="ruby-identifier">accepts</span> <span class="ruby-value">? </span><span class="ruby-identifier">accepts</span>.<span class="ruby-identifier">text</span> <span class="ruby-operator">:</span> <span class="ruby-value str">&quot;entry&quot;</span>)
196
- 67:
197
- 68: <span class="ruby-ivar">@collections</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">coll</span>
198
- 69: <span class="ruby-keyword kw">end</span>
199
- 70: <span class="ruby-keyword kw">end</span>
200
- </pre>
201
- </div>
202
- </div>
203
- </div>
204
-
205
-
206
- </div>
207
-
208
-
209
- </div>
210
-
211
-
212
- <div id="validator-badges">
213
- <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
214
- </div>
215
-
216
- </body>
217
- </html>