tokamak 1.0.0.beta2
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/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +27 -0
- data/Gemfile.lock +77 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +69 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/lib/tokamak.rb +21 -0
- data/lib/tokamak/atom.rb +8 -0
- data/lib/tokamak/atom/base.rb +87 -0
- data/lib/tokamak/atom/builder.rb +107 -0
- data/lib/tokamak/atom/helpers.rb +13 -0
- data/lib/tokamak/error.rb +6 -0
- data/lib/tokamak/json.rb +10 -0
- data/lib/tokamak/json/base.rb +83 -0
- data/lib/tokamak/json/builder.rb +98 -0
- data/lib/tokamak/json/helpers.rb +13 -0
- data/lib/tokamak/representation.rb +3 -0
- data/lib/tokamak/representation/atom.rb +18 -0
- data/lib/tokamak/representation/atom/atom.rng +597 -0
- data/lib/tokamak/representation/atom/base.rb +140 -0
- data/lib/tokamak/representation/atom/category.rb +39 -0
- data/lib/tokamak/representation/atom/entry.rb +56 -0
- data/lib/tokamak/representation/atom/factory.rb +48 -0
- data/lib/tokamak/representation/atom/feed.rb +108 -0
- data/lib/tokamak/representation/atom/link.rb +66 -0
- data/lib/tokamak/representation/atom/person.rb +46 -0
- data/lib/tokamak/representation/atom/source.rb +57 -0
- data/lib/tokamak/representation/atom/tag_collection.rb +36 -0
- data/lib/tokamak/representation/atom/xml.rb +94 -0
- data/lib/tokamak/representation/generic.rb +20 -0
- data/lib/tokamak/representation/json.rb +11 -0
- data/lib/tokamak/representation/json/base.rb +25 -0
- data/lib/tokamak/representation/json/keys_as_methods.rb +72 -0
- data/lib/tokamak/representation/json/link.rb +27 -0
- data/lib/tokamak/representation/json/link_collection.rb +21 -0
- data/lib/tokamak/representation/links.rb +9 -0
- data/lib/tokamak/values.rb +29 -0
- data/lib/tokamak/xml.rb +12 -0
- data/lib/tokamak/xml/base.rb +60 -0
- data/lib/tokamak/xml/builder.rb +115 -0
- data/lib/tokamak/xml/helpers.rb +13 -0
- data/lib/tokamak/xml/link.rb +31 -0
- data/lib/tokamak/xml/links.rb +35 -0
- data/spec/integration/atom/atom_spec.rb +191 -0
- data/spec/integration/full_atom.xml +92 -0
- data/spec/integration/full_json.js +46 -0
- data/spec/integration/json/json_spec.rb +172 -0
- data/spec/integration/xml/xml_spec.rb +203 -0
- data/spec/spec_helper.rb +12 -0
- metadata +248 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
module Tokamak
|
2
|
+
module Atom
|
3
|
+
module Helpers
|
4
|
+
def collection(obj, *args, &block)
|
5
|
+
Tokamak::Atom.to_atom(obj, :atom_type => :feed, &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def member(obj, *args, &block)
|
9
|
+
Tokamak::Atom.to_atom(obj, :atom_type => :entry, &block)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/tokamak/json.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
module Tokamak
|
2
|
+
module Json
|
3
|
+
module Base
|
4
|
+
module ClassMethods
|
5
|
+
mattr_reader :media_type_name
|
6
|
+
@@media_type_name = 'application/json'
|
7
|
+
|
8
|
+
mattr_reader :headers
|
9
|
+
@@headers = {
|
10
|
+
:get => { 'Accept' => media_type_name },
|
11
|
+
:post => { 'Content-Type' => media_type_name }
|
12
|
+
}
|
13
|
+
|
14
|
+
mattr_reader :recipes
|
15
|
+
@@recipes = {}
|
16
|
+
|
17
|
+
def describe_recipe(recipe_name, options={}, &block)
|
18
|
+
raise 'Undefined recipe' unless block_given?
|
19
|
+
raise 'Undefined recipe_name' unless recipe_name
|
20
|
+
@@recipes[recipe_name] = block
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_json(obj = nil, options = {:root => {}}, &block)
|
24
|
+
# just instantiate the string with the atom factory
|
25
|
+
return Tokamak::Representation::Json.create(obj) if obj.kind_of?(String)
|
26
|
+
|
27
|
+
if block_given?
|
28
|
+
recipe = block
|
29
|
+
else
|
30
|
+
recipe = options[:recipe]
|
31
|
+
end
|
32
|
+
|
33
|
+
# Check if the object is already an json
|
34
|
+
unless recipe
|
35
|
+
if obj.kind_of?(Hash) || obj.kind_of?(Array)
|
36
|
+
return Tokamak::Representation::Json.create(obj)
|
37
|
+
else
|
38
|
+
raise Tokamak::ConverterError.new("Recipe required")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get recipe already described
|
43
|
+
recipe = @@recipes[recipe] unless recipe.respond_to?(:call)
|
44
|
+
|
45
|
+
# Create representation and proxy
|
46
|
+
builder = Tokamak::Json::Builder.new(obj, (options[:root] || {}))
|
47
|
+
|
48
|
+
# Check recipe arity size before calling it
|
49
|
+
recipe.call(*[builder, obj, options][0,recipe.arity])
|
50
|
+
|
51
|
+
builder.representation
|
52
|
+
end
|
53
|
+
|
54
|
+
alias_method :unmarshal, :to_json
|
55
|
+
|
56
|
+
def to_hash(obj)
|
57
|
+
return obj if obj.kind_of?(Hash) || obj.kind_of?(Array)
|
58
|
+
|
59
|
+
if obj.kind_of?(::String)
|
60
|
+
Tokamak::Representation::Json.create(obj)
|
61
|
+
else
|
62
|
+
raise Tokamak::ConverterError.new("It was not possible to convert this object to a Hash")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_s(obj)
|
67
|
+
return obj if obj.kind_of?(String)
|
68
|
+
Tokamak::Representation::Json.create(obj).to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
def marshal(obj, options = nil)
|
72
|
+
return obj if obj.kind_of? String
|
73
|
+
to_json(obj, options).to_json
|
74
|
+
end
|
75
|
+
|
76
|
+
# returns the current helper
|
77
|
+
def helper
|
78
|
+
Helpers
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Tokamak
|
2
|
+
module Json
|
3
|
+
class Builder
|
4
|
+
def initialize(obj, initial_obj = {})
|
5
|
+
@doc = initial_obj
|
6
|
+
@obj = obj
|
7
|
+
@current = @doc
|
8
|
+
end
|
9
|
+
|
10
|
+
def values(options = nil, &block)
|
11
|
+
yield Values.new(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
def members(options = {}, &block)
|
15
|
+
collection = options[:collection] || @obj
|
16
|
+
raise Error::BuilderError.new("Members method require a collection to execute") unless collection.respond_to?(:each)
|
17
|
+
root = options[:root] || Tokamak.root_element_for(collection)
|
18
|
+
|
19
|
+
collection.each do |member|
|
20
|
+
node = {}
|
21
|
+
|
22
|
+
parent = @current
|
23
|
+
@current = node
|
24
|
+
block.call(self, member)
|
25
|
+
@current = parent
|
26
|
+
|
27
|
+
add_to_current(root, node)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def link(relationship, uri, options = {})
|
32
|
+
options["rel"] = relationship.to_s
|
33
|
+
options["href"] = uri
|
34
|
+
options["type"] ||= "application/json"
|
35
|
+
insert_value("link", nil, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def insert_value(name, prefix, *args, &block)
|
39
|
+
node = create_element(block_given?, *args)
|
40
|
+
|
41
|
+
if block_given?
|
42
|
+
parent = @current
|
43
|
+
@current = node
|
44
|
+
block.call
|
45
|
+
@current = parent
|
46
|
+
end
|
47
|
+
|
48
|
+
add_to_current(name, node)
|
49
|
+
end
|
50
|
+
|
51
|
+
def representation
|
52
|
+
Tokamak::Representation::Json.create(@doc).to_json
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def create_element(has_block, *args)
|
58
|
+
vals = []
|
59
|
+
hashes = []
|
60
|
+
|
61
|
+
args.each do |arg|
|
62
|
+
arg.kind_of?(Hash) ? hashes << arg : vals << arg
|
63
|
+
end
|
64
|
+
|
65
|
+
if hashes.empty?
|
66
|
+
# only simple values
|
67
|
+
unless vals.empty?
|
68
|
+
vals = vals.first if vals.size == 1
|
69
|
+
node = has_block ? {} : vals
|
70
|
+
else
|
71
|
+
node = has_block ? {} : nil
|
72
|
+
end
|
73
|
+
else
|
74
|
+
# yes we have hashes
|
75
|
+
node = {}
|
76
|
+
hashes.each { |hash| node.merge!(hash) }
|
77
|
+
unless vals.empty?
|
78
|
+
vals = vals.first if vals.size == 1
|
79
|
+
node = has_block ? {} : [node, vals]
|
80
|
+
end
|
81
|
+
node
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_to_current(name, value)
|
86
|
+
if @current[name]
|
87
|
+
if @current[name].kind_of?(Array)
|
88
|
+
@current[name] << value
|
89
|
+
else
|
90
|
+
@current[name] = [@current[name], value]
|
91
|
+
end
|
92
|
+
else
|
93
|
+
@current[name] = value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Tokamak
|
4
|
+
module Representation
|
5
|
+
module Atom
|
6
|
+
autoload :Factory, 'tokamak/representation/atom/factory'
|
7
|
+
autoload :XML, 'tokamak/representation/atom/xml'
|
8
|
+
autoload :Base, 'tokamak/representation/atom/base'
|
9
|
+
autoload :TagCollection, 'tokamak/representation/atom/tag_collection'
|
10
|
+
autoload :Link, 'tokamak/representation/atom/link'
|
11
|
+
autoload :Person, 'tokamak/representation/atom/person'
|
12
|
+
autoload :Category, 'tokamak/representation/atom/category'
|
13
|
+
autoload :Feed, 'tokamak/representation/atom/feed'
|
14
|
+
autoload :Entry, 'tokamak/representation/atom/entry'
|
15
|
+
autoload :Source, 'tokamak/representation/atom/source'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,597 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!--
|
3
|
+
-*- rnc -*-
|
4
|
+
RELAX NG Compact Syntax Grammar for the
|
5
|
+
Atom Format Specification Version 11
|
6
|
+
-->
|
7
|
+
<grammar xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:s="http://www.ascc.net/xml/schematron" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
8
|
+
<start>
|
9
|
+
<choice>
|
10
|
+
<ref name="atomFeed"/>
|
11
|
+
<ref name="atomEntry"/>
|
12
|
+
</choice>
|
13
|
+
</start>
|
14
|
+
<!-- Common attributes -->
|
15
|
+
<define name="atomCommonAttributes">
|
16
|
+
<optional>
|
17
|
+
<attribute name="xml:base">
|
18
|
+
<ref name="atomUri"/>
|
19
|
+
</attribute>
|
20
|
+
</optional>
|
21
|
+
<optional>
|
22
|
+
<attribute name="xml:lang">
|
23
|
+
<ref name="atomLanguageTag"/>
|
24
|
+
</attribute>
|
25
|
+
</optional>
|
26
|
+
<zeroOrMore>
|
27
|
+
<ref name="undefinedAttribute"/>
|
28
|
+
</zeroOrMore>
|
29
|
+
</define>
|
30
|
+
<!-- Text Constructs -->
|
31
|
+
<define name="atomPlainTextConstruct">
|
32
|
+
<ref name="atomCommonAttributes"/>
|
33
|
+
<optional>
|
34
|
+
<attribute name="type">
|
35
|
+
<choice>
|
36
|
+
<value>text</value>
|
37
|
+
<value>html</value>
|
38
|
+
</choice>
|
39
|
+
</attribute>
|
40
|
+
</optional>
|
41
|
+
<text/>
|
42
|
+
</define>
|
43
|
+
<define name="atomXHTMLTextConstruct">
|
44
|
+
<ref name="atomCommonAttributes"/>
|
45
|
+
<attribute name="type">
|
46
|
+
<value>xhtml</value>
|
47
|
+
</attribute>
|
48
|
+
<ref name="xhtmlDiv"/>
|
49
|
+
</define>
|
50
|
+
<define name="atomTextConstruct">
|
51
|
+
<choice>
|
52
|
+
<ref name="atomPlainTextConstruct"/>
|
53
|
+
<ref name="atomXHTMLTextConstruct"/>
|
54
|
+
</choice>
|
55
|
+
</define>
|
56
|
+
<!-- Person Construct -->
|
57
|
+
<define name="atomPersonConstruct">
|
58
|
+
<ref name="atomCommonAttributes"/>
|
59
|
+
<interleave>
|
60
|
+
<element name="atom:name">
|
61
|
+
<text/>
|
62
|
+
</element>
|
63
|
+
<optional>
|
64
|
+
<element name="atom:uri">
|
65
|
+
<ref name="atomUri"/>
|
66
|
+
</element>
|
67
|
+
</optional>
|
68
|
+
<optional>
|
69
|
+
<element name="atom:email">
|
70
|
+
<ref name="atomEmailAddress"/>
|
71
|
+
</element>
|
72
|
+
</optional>
|
73
|
+
<zeroOrMore>
|
74
|
+
<ref name="extensionElement"/>
|
75
|
+
</zeroOrMore>
|
76
|
+
</interleave>
|
77
|
+
</define>
|
78
|
+
<!-- Date Construct -->
|
79
|
+
<define name="atomDateConstruct">
|
80
|
+
<ref name="atomCommonAttributes"/>
|
81
|
+
<data type="dateTime"/>
|
82
|
+
</define>
|
83
|
+
<!-- atom:feed -->
|
84
|
+
<define name="atomFeed">
|
85
|
+
<element name="atom:feed">
|
86
|
+
<s:rule context="atom:feed">
|
87
|
+
<s:assert test="atom:author or not(atom:entry[not(atom:author)])">An atom:feed must have an atom:author unless all of its atom:entry children have an atom:author.</s:assert>
|
88
|
+
</s:rule>
|
89
|
+
<ref name="atomCommonAttributes"/>
|
90
|
+
<interleave>
|
91
|
+
<zeroOrMore>
|
92
|
+
<ref name="atomAuthor"/>
|
93
|
+
</zeroOrMore>
|
94
|
+
<zeroOrMore>
|
95
|
+
<ref name="atomCategory"/>
|
96
|
+
</zeroOrMore>
|
97
|
+
<zeroOrMore>
|
98
|
+
<ref name="atomContributor"/>
|
99
|
+
</zeroOrMore>
|
100
|
+
<optional>
|
101
|
+
<ref name="atomGenerator"/>
|
102
|
+
</optional>
|
103
|
+
<optional>
|
104
|
+
<ref name="atomIcon"/>
|
105
|
+
</optional>
|
106
|
+
<ref name="atomId"/>
|
107
|
+
<zeroOrMore>
|
108
|
+
<ref name="atomLink"/>
|
109
|
+
</zeroOrMore>
|
110
|
+
<optional>
|
111
|
+
<ref name="atomLogo"/>
|
112
|
+
</optional>
|
113
|
+
<optional>
|
114
|
+
<ref name="atomRights"/>
|
115
|
+
</optional>
|
116
|
+
<optional>
|
117
|
+
<ref name="atomSubtitle"/>
|
118
|
+
</optional>
|
119
|
+
<ref name="atomTitle"/>
|
120
|
+
<ref name="atomUpdated"/>
|
121
|
+
<zeroOrMore>
|
122
|
+
<ref name="extensionElement"/>
|
123
|
+
</zeroOrMore>
|
124
|
+
</interleave>
|
125
|
+
<zeroOrMore>
|
126
|
+
<ref name="atomEntry"/>
|
127
|
+
</zeroOrMore>
|
128
|
+
</element>
|
129
|
+
</define>
|
130
|
+
<!-- atom:entry -->
|
131
|
+
<define name="atomEntry">
|
132
|
+
<element name="atom:entry">
|
133
|
+
<s:rule context="atom:entry">
|
134
|
+
<s:assert test="atom:link[@rel='alternate'] or atom:link[not(@rel)] or atom:content">An atom:entry must have at least one atom:link element with a rel attribute of 'alternate' or an atom:content.</s:assert>
|
135
|
+
</s:rule>
|
136
|
+
<s:rule context="atom:entry">
|
137
|
+
<s:assert test="atom:author or ../atom:author or atom:source/atom:author">An atom:entry must have an atom:author if its feed does not.</s:assert>
|
138
|
+
</s:rule>
|
139
|
+
<ref name="atomCommonAttributes"/>
|
140
|
+
<interleave>
|
141
|
+
<zeroOrMore>
|
142
|
+
<ref name="atomAuthor"/>
|
143
|
+
</zeroOrMore>
|
144
|
+
<zeroOrMore>
|
145
|
+
<ref name="atomCategory"/>
|
146
|
+
</zeroOrMore>
|
147
|
+
<optional>
|
148
|
+
<ref name="atomContent"/>
|
149
|
+
</optional>
|
150
|
+
<zeroOrMore>
|
151
|
+
<ref name="atomContributor"/>
|
152
|
+
</zeroOrMore>
|
153
|
+
<ref name="atomId"/>
|
154
|
+
<zeroOrMore>
|
155
|
+
<ref name="atomLink"/>
|
156
|
+
</zeroOrMore>
|
157
|
+
<optional>
|
158
|
+
<ref name="atomPublished"/>
|
159
|
+
</optional>
|
160
|
+
<optional>
|
161
|
+
<ref name="atomRights"/>
|
162
|
+
</optional>
|
163
|
+
<optional>
|
164
|
+
<ref name="atomSource"/>
|
165
|
+
</optional>
|
166
|
+
<optional>
|
167
|
+
<ref name="atomSummary"/>
|
168
|
+
</optional>
|
169
|
+
<ref name="atomTitle"/>
|
170
|
+
<ref name="atomUpdated"/>
|
171
|
+
<zeroOrMore>
|
172
|
+
<ref name="extensionElement"/>
|
173
|
+
</zeroOrMore>
|
174
|
+
</interleave>
|
175
|
+
</element>
|
176
|
+
</define>
|
177
|
+
<!-- atom:content -->
|
178
|
+
<define name="atomInlineTextContent">
|
179
|
+
<element name="atom:content">
|
180
|
+
<ref name="atomCommonAttributes"/>
|
181
|
+
<optional>
|
182
|
+
<attribute name="type">
|
183
|
+
<choice>
|
184
|
+
<value>text</value>
|
185
|
+
<value>html</value>
|
186
|
+
</choice>
|
187
|
+
</attribute>
|
188
|
+
</optional>
|
189
|
+
<zeroOrMore>
|
190
|
+
<text/>
|
191
|
+
</zeroOrMore>
|
192
|
+
</element>
|
193
|
+
</define>
|
194
|
+
<define name="atomInlineXHTMLContent">
|
195
|
+
<element name="atom:content">
|
196
|
+
<ref name="atomCommonAttributes"/>
|
197
|
+
<attribute name="type">
|
198
|
+
<value>xhtml</value>
|
199
|
+
</attribute>
|
200
|
+
<ref name="xhtmlDiv"/>
|
201
|
+
</element>
|
202
|
+
</define>
|
203
|
+
<define name="atomInlineOtherContent">
|
204
|
+
<element name="atom:content">
|
205
|
+
<ref name="atomCommonAttributes"/>
|
206
|
+
<optional>
|
207
|
+
<attribute name="type">
|
208
|
+
<ref name="atomMediaType"/>
|
209
|
+
</attribute>
|
210
|
+
</optional>
|
211
|
+
<zeroOrMore>
|
212
|
+
<choice>
|
213
|
+
<text/>
|
214
|
+
<ref name="anyElement"/>
|
215
|
+
</choice>
|
216
|
+
</zeroOrMore>
|
217
|
+
</element>
|
218
|
+
</define>
|
219
|
+
<define name="atomOutOfLineContent">
|
220
|
+
<element name="atom:content">
|
221
|
+
<ref name="atomCommonAttributes"/>
|
222
|
+
<optional>
|
223
|
+
<attribute name="type">
|
224
|
+
<ref name="atomMediaType"/>
|
225
|
+
</attribute>
|
226
|
+
</optional>
|
227
|
+
<attribute name="src">
|
228
|
+
<ref name="atomUri"/>
|
229
|
+
</attribute>
|
230
|
+
<empty/>
|
231
|
+
</element>
|
232
|
+
</define>
|
233
|
+
<define name="atomContent">
|
234
|
+
<choice>
|
235
|
+
<ref name="atomInlineTextContent"/>
|
236
|
+
<ref name="atomInlineXHTMLContent"/>
|
237
|
+
<ref name="atomInlineOtherContent"/>
|
238
|
+
<ref name="atomOutOfLineContent"/>
|
239
|
+
</choice>
|
240
|
+
</define>
|
241
|
+
<!-- atom:author -->
|
242
|
+
<define name="atomAuthor">
|
243
|
+
<element name="atom:author">
|
244
|
+
<ref name="atomPersonConstruct"/>
|
245
|
+
</element>
|
246
|
+
</define>
|
247
|
+
<!-- atom:category -->
|
248
|
+
<define name="atomCategory">
|
249
|
+
<element name="atom:category">
|
250
|
+
<ref name="atomCommonAttributes"/>
|
251
|
+
<attribute name="term"/>
|
252
|
+
<optional>
|
253
|
+
<attribute name="scheme">
|
254
|
+
<ref name="atomUri"/>
|
255
|
+
</attribute>
|
256
|
+
</optional>
|
257
|
+
<optional>
|
258
|
+
<attribute name="label"/>
|
259
|
+
</optional>
|
260
|
+
<ref name="undefinedContent"/>
|
261
|
+
</element>
|
262
|
+
</define>
|
263
|
+
<!-- atom:contributor -->
|
264
|
+
<define name="atomContributor">
|
265
|
+
<element name="atom:contributor">
|
266
|
+
<ref name="atomPersonConstruct"/>
|
267
|
+
</element>
|
268
|
+
</define>
|
269
|
+
<!-- atom:generator -->
|
270
|
+
<define name="atomGenerator">
|
271
|
+
<element name="atom:generator">
|
272
|
+
<ref name="atomCommonAttributes"/>
|
273
|
+
<optional>
|
274
|
+
<attribute name="uri">
|
275
|
+
<ref name="atomUri"/>
|
276
|
+
</attribute>
|
277
|
+
</optional>
|
278
|
+
<optional>
|
279
|
+
<attribute name="version"/>
|
280
|
+
</optional>
|
281
|
+
<text/>
|
282
|
+
</element>
|
283
|
+
</define>
|
284
|
+
<!-- atom:icon -->
|
285
|
+
<define name="atomIcon">
|
286
|
+
<element name="atom:icon">
|
287
|
+
<ref name="atomCommonAttributes"/>
|
288
|
+
<ref name="atomUri"/>
|
289
|
+
</element>
|
290
|
+
</define>
|
291
|
+
<!-- atom:id -->
|
292
|
+
<define name="atomId">
|
293
|
+
<element name="atom:id">
|
294
|
+
<ref name="atomCommonAttributes"/>
|
295
|
+
<ref name="atomUri"/>
|
296
|
+
</element>
|
297
|
+
</define>
|
298
|
+
<!-- atom:logo -->
|
299
|
+
<define name="atomLogo">
|
300
|
+
<element name="atom:logo">
|
301
|
+
<ref name="atomCommonAttributes"/>
|
302
|
+
<ref name="atomUri"/>
|
303
|
+
</element>
|
304
|
+
</define>
|
305
|
+
<!-- atom:link -->
|
306
|
+
<define name="atomLink">
|
307
|
+
<element name="atom:link">
|
308
|
+
<ref name="atomCommonAttributes"/>
|
309
|
+
<attribute name="href">
|
310
|
+
<ref name="atomUri"/>
|
311
|
+
</attribute>
|
312
|
+
<optional>
|
313
|
+
<attribute name="rel">
|
314
|
+
<choice>
|
315
|
+
<ref name="atomNCName"/>
|
316
|
+
<ref name="atomUri"/>
|
317
|
+
</choice>
|
318
|
+
</attribute>
|
319
|
+
</optional>
|
320
|
+
<optional>
|
321
|
+
<attribute name="type">
|
322
|
+
<ref name="atomMediaType"/>
|
323
|
+
</attribute>
|
324
|
+
</optional>
|
325
|
+
<optional>
|
326
|
+
<attribute name="hreflang">
|
327
|
+
<ref name="atomLanguageTag"/>
|
328
|
+
</attribute>
|
329
|
+
</optional>
|
330
|
+
<optional>
|
331
|
+
<attribute name="title"/>
|
332
|
+
</optional>
|
333
|
+
<optional>
|
334
|
+
<attribute name="length"/>
|
335
|
+
</optional>
|
336
|
+
<ref name="undefinedContent"/>
|
337
|
+
</element>
|
338
|
+
</define>
|
339
|
+
<!-- atom:published -->
|
340
|
+
<define name="atomPublished">
|
341
|
+
<element name="atom:published">
|
342
|
+
<ref name="atomDateConstruct"/>
|
343
|
+
</element>
|
344
|
+
</define>
|
345
|
+
<!-- atom:rights -->
|
346
|
+
<define name="atomRights">
|
347
|
+
<element name="atom:rights">
|
348
|
+
<ref name="atomTextConstruct"/>
|
349
|
+
</element>
|
350
|
+
</define>
|
351
|
+
<!-- atom:source -->
|
352
|
+
<define name="atomSource">
|
353
|
+
<element name="atom:source">
|
354
|
+
<ref name="atomCommonAttributes"/>
|
355
|
+
<interleave>
|
356
|
+
<zeroOrMore>
|
357
|
+
<ref name="atomAuthor"/>
|
358
|
+
</zeroOrMore>
|
359
|
+
<zeroOrMore>
|
360
|
+
<ref name="atomCategory"/>
|
361
|
+
</zeroOrMore>
|
362
|
+
<zeroOrMore>
|
363
|
+
<ref name="atomContributor"/>
|
364
|
+
</zeroOrMore>
|
365
|
+
<optional>
|
366
|
+
<ref name="atomGenerator"/>
|
367
|
+
</optional>
|
368
|
+
<optional>
|
369
|
+
<ref name="atomIcon"/>
|
370
|
+
</optional>
|
371
|
+
<optional>
|
372
|
+
<ref name="atomId"/>
|
373
|
+
</optional>
|
374
|
+
<zeroOrMore>
|
375
|
+
<ref name="atomLink"/>
|
376
|
+
</zeroOrMore>
|
377
|
+
<optional>
|
378
|
+
<ref name="atomLogo"/>
|
379
|
+
</optional>
|
380
|
+
<optional>
|
381
|
+
<ref name="atomRights"/>
|
382
|
+
</optional>
|
383
|
+
<optional>
|
384
|
+
<ref name="atomSubtitle"/>
|
385
|
+
</optional>
|
386
|
+
<optional>
|
387
|
+
<ref name="atomTitle"/>
|
388
|
+
</optional>
|
389
|
+
<optional>
|
390
|
+
<ref name="atomUpdated"/>
|
391
|
+
</optional>
|
392
|
+
<zeroOrMore>
|
393
|
+
<ref name="extensionElement"/>
|
394
|
+
</zeroOrMore>
|
395
|
+
</interleave>
|
396
|
+
</element>
|
397
|
+
</define>
|
398
|
+
<!-- atom:subtitle -->
|
399
|
+
<define name="atomSubtitle">
|
400
|
+
<element name="atom:subtitle">
|
401
|
+
<ref name="atomTextConstruct"/>
|
402
|
+
</element>
|
403
|
+
</define>
|
404
|
+
<!-- atom:summary -->
|
405
|
+
<define name="atomSummary">
|
406
|
+
<element name="atom:summary">
|
407
|
+
<ref name="atomTextConstruct"/>
|
408
|
+
</element>
|
409
|
+
</define>
|
410
|
+
<!-- atom:title -->
|
411
|
+
<define name="atomTitle">
|
412
|
+
<element name="atom:title">
|
413
|
+
<ref name="atomTextConstruct"/>
|
414
|
+
</element>
|
415
|
+
</define>
|
416
|
+
<!-- atom:updated -->
|
417
|
+
<define name="atomUpdated">
|
418
|
+
<element name="atom:updated">
|
419
|
+
<ref name="atomDateConstruct"/>
|
420
|
+
</element>
|
421
|
+
</define>
|
422
|
+
<!-- Low-level simple types -->
|
423
|
+
<define name="atomNCName">
|
424
|
+
<data type="string">
|
425
|
+
<param name="minLength">1</param>
|
426
|
+
<param name="pattern">[^:]*</param>
|
427
|
+
</data>
|
428
|
+
</define>
|
429
|
+
<!-- Whatever a media type is, it contains at least one slash -->
|
430
|
+
<define name="atomMediaType">
|
431
|
+
<data type="string">
|
432
|
+
<param name="pattern">.+/.+</param>
|
433
|
+
</data>
|
434
|
+
</define>
|
435
|
+
<!-- As defined in RFC 3066 -->
|
436
|
+
<define name="atomLanguageTag">
|
437
|
+
<data type="string">
|
438
|
+
<param name="pattern">[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*</param>
|
439
|
+
</data>
|
440
|
+
</define>
|
441
|
+
<!--
|
442
|
+
Unconstrained; it's not entirely clear how IRI fit into
|
443
|
+
xsd:anyURI so let's not try to constrain it here
|
444
|
+
-->
|
445
|
+
<define name="atomUri">
|
446
|
+
<text/>
|
447
|
+
</define>
|
448
|
+
<!-- Whatever an email address is, it contains at least one @ -->
|
449
|
+
<define name="atomEmailAddress">
|
450
|
+
<data type="string">
|
451
|
+
<param name="pattern">.+@.+</param>
|
452
|
+
</data>
|
453
|
+
</define>
|
454
|
+
<!-- Simple Extension -->
|
455
|
+
<define name="simpleExtensionElement">
|
456
|
+
<element>
|
457
|
+
<anyName>
|
458
|
+
<except>
|
459
|
+
<nsName ns="http://www.w3.org/2005/Atom"/>
|
460
|
+
</except>
|
461
|
+
</anyName>
|
462
|
+
<text/>
|
463
|
+
</element>
|
464
|
+
</define>
|
465
|
+
<!-- Structured Extension -->
|
466
|
+
<define name="structuredExtensionElement">
|
467
|
+
<element>
|
468
|
+
<anyName>
|
469
|
+
<except>
|
470
|
+
<nsName ns="http://www.w3.org/2005/Atom"/>
|
471
|
+
</except>
|
472
|
+
</anyName>
|
473
|
+
<choice>
|
474
|
+
<group>
|
475
|
+
<oneOrMore>
|
476
|
+
<attribute>
|
477
|
+
<anyName/>
|
478
|
+
</attribute>
|
479
|
+
</oneOrMore>
|
480
|
+
<zeroOrMore>
|
481
|
+
<choice>
|
482
|
+
<text/>
|
483
|
+
<ref name="anyElement"/>
|
484
|
+
</choice>
|
485
|
+
</zeroOrMore>
|
486
|
+
</group>
|
487
|
+
<group>
|
488
|
+
<zeroOrMore>
|
489
|
+
<attribute>
|
490
|
+
<anyName/>
|
491
|
+
</attribute>
|
492
|
+
</zeroOrMore>
|
493
|
+
<group>
|
494
|
+
<optional>
|
495
|
+
<text/>
|
496
|
+
</optional>
|
497
|
+
<oneOrMore>
|
498
|
+
<ref name="anyElement"/>
|
499
|
+
</oneOrMore>
|
500
|
+
<zeroOrMore>
|
501
|
+
<choice>
|
502
|
+
<text/>
|
503
|
+
<ref name="anyElement"/>
|
504
|
+
</choice>
|
505
|
+
</zeroOrMore>
|
506
|
+
</group>
|
507
|
+
</group>
|
508
|
+
</choice>
|
509
|
+
</element>
|
510
|
+
</define>
|
511
|
+
<!-- Other Extensibility -->
|
512
|
+
<define name="extensionElement">
|
513
|
+
<choice>
|
514
|
+
<ref name="simpleExtensionElement"/>
|
515
|
+
<ref name="structuredExtensionElement"/>
|
516
|
+
</choice>
|
517
|
+
</define>
|
518
|
+
<define name="undefinedAttribute">
|
519
|
+
<attribute>
|
520
|
+
<anyName>
|
521
|
+
<except>
|
522
|
+
<name>xml:base</name>
|
523
|
+
<name>xml:lang</name>
|
524
|
+
<nsName ns=""/>
|
525
|
+
</except>
|
526
|
+
</anyName>
|
527
|
+
</attribute>
|
528
|
+
</define>
|
529
|
+
<define name="undefinedContent">
|
530
|
+
<zeroOrMore>
|
531
|
+
<choice>
|
532
|
+
<text/>
|
533
|
+
<ref name="anyForeignElement"/>
|
534
|
+
</choice>
|
535
|
+
</zeroOrMore>
|
536
|
+
</define>
|
537
|
+
<define name="anyElement">
|
538
|
+
<element>
|
539
|
+
<anyName/>
|
540
|
+
<zeroOrMore>
|
541
|
+
<choice>
|
542
|
+
<attribute>
|
543
|
+
<anyName/>
|
544
|
+
</attribute>
|
545
|
+
<text/>
|
546
|
+
<ref name="anyElement"/>
|
547
|
+
</choice>
|
548
|
+
</zeroOrMore>
|
549
|
+
</element>
|
550
|
+
</define>
|
551
|
+
<define name="anyForeignElement">
|
552
|
+
<element>
|
553
|
+
<anyName>
|
554
|
+
<except>
|
555
|
+
<nsName ns="http://www.w3.org/2005/Atom"/>
|
556
|
+
</except>
|
557
|
+
</anyName>
|
558
|
+
<zeroOrMore>
|
559
|
+
<choice>
|
560
|
+
<attribute>
|
561
|
+
<anyName/>
|
562
|
+
</attribute>
|
563
|
+
<text/>
|
564
|
+
<ref name="anyElement"/>
|
565
|
+
</choice>
|
566
|
+
</zeroOrMore>
|
567
|
+
</element>
|
568
|
+
</define>
|
569
|
+
<!-- XHTML -->
|
570
|
+
<define name="anyXHTML">
|
571
|
+
<element>
|
572
|
+
<nsName ns="http://www.w3.org/1999/xhtml"/>
|
573
|
+
<zeroOrMore>
|
574
|
+
<choice>
|
575
|
+
<attribute>
|
576
|
+
<anyName/>
|
577
|
+
</attribute>
|
578
|
+
<text/>
|
579
|
+
<ref name="anyXHTML"/>
|
580
|
+
</choice>
|
581
|
+
</zeroOrMore>
|
582
|
+
</element>
|
583
|
+
</define>
|
584
|
+
<define name="xhtmlDiv">
|
585
|
+
<element name="xhtml:div">
|
586
|
+
<zeroOrMore>
|
587
|
+
<choice>
|
588
|
+
<attribute>
|
589
|
+
<anyName/>
|
590
|
+
</attribute>
|
591
|
+
<text/>
|
592
|
+
<ref name="anyXHTML"/>
|
593
|
+
</choice>
|
594
|
+
</zeroOrMore>
|
595
|
+
</element>
|
596
|
+
</define>
|
597
|
+
</grammar>
|