mill 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.
- checksums.yaml +7 -0
- data/.gitignore +37 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +4 -0
- data/Rakefile +1 -0
- data/TODO.txt +38 -0
- data/lib/mill.rb +336 -0
- data/lib/mill/file_types.rb +30 -0
- data/lib/mill/html_helpers.rb +166 -0
- data/lib/mill/navigator.rb +84 -0
- data/lib/mill/resource.rb +116 -0
- data/lib/mill/resources/feed.rb +63 -0
- data/lib/mill/resources/generic.rb +15 -0
- data/lib/mill/resources/image.rb +36 -0
- data/lib/mill/resources/redirect.rb +36 -0
- data/lib/mill/resources/robots.rb +25 -0
- data/lib/mill/resources/sitemap.rb +35 -0
- data/lib/mill/resources/text.rb +157 -0
- data/lib/mill/schemas/atom.xsd +244 -0
- data/lib/mill/schemas/sitemap.xsd +116 -0
- data/lib/mill/tasks.rake +31 -0
- data/lib/mill/version.rb +5 -0
- data/mill.gemspec +37 -0
- metadata +247 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
class Mill
|
2
|
+
|
3
|
+
class Resource
|
4
|
+
|
5
|
+
class Image < Resource
|
6
|
+
|
7
|
+
include HTMLHelpers
|
8
|
+
|
9
|
+
attr_accessor :width
|
10
|
+
attr_accessor :height
|
11
|
+
|
12
|
+
def self.type
|
13
|
+
:image
|
14
|
+
end
|
15
|
+
|
16
|
+
def load
|
17
|
+
info = ImageSize.path(@input_file.to_s)
|
18
|
+
@width, @height = *info.size
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def img_html
|
23
|
+
html_fragment do |html|
|
24
|
+
html.img(
|
25
|
+
src: uri,
|
26
|
+
alt: @title,
|
27
|
+
height: @height,
|
28
|
+
width: @width)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Mill
|
2
|
+
|
3
|
+
class Resource
|
4
|
+
|
5
|
+
class Redirect < Resource
|
6
|
+
|
7
|
+
attr_accessor :redirect_uri
|
8
|
+
attr_accessor :redirect_code
|
9
|
+
|
10
|
+
def self.type
|
11
|
+
:redirect
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(params={})
|
15
|
+
super(
|
16
|
+
{
|
17
|
+
redirect_code: 303,
|
18
|
+
}.merge(params)
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def load
|
23
|
+
@content = "%s %d" % [@redirect_uri, @redirect_code]
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def build
|
28
|
+
@output_file = @output_file.add_extension('.redirect')
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# see http://www.robotstxt.org/robotstxt.html
|
2
|
+
|
3
|
+
class Mill
|
4
|
+
|
5
|
+
class Resource
|
6
|
+
|
7
|
+
class Robots < Resource
|
8
|
+
|
9
|
+
def self.type
|
10
|
+
:robots
|
11
|
+
end
|
12
|
+
|
13
|
+
def load
|
14
|
+
info = {
|
15
|
+
'Sitemap' => @mill.sitemap_resource.absolute_uri,
|
16
|
+
}
|
17
|
+
@content = info.map { |key, value| "#{key}: #{value}" }.join("\n")
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# see http://www.sitemaps.org/protocol.php
|
2
|
+
|
3
|
+
class Mill
|
4
|
+
|
5
|
+
class Resource
|
6
|
+
|
7
|
+
class Sitemap < Resource
|
8
|
+
|
9
|
+
def self.type
|
10
|
+
:sitemap
|
11
|
+
end
|
12
|
+
|
13
|
+
def load
|
14
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
15
|
+
xml.urlset('xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
16
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
17
|
+
'xsi:schemaLocation' => 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd') do
|
18
|
+
@mill.public_resources.each do |resource|
|
19
|
+
xml.url do
|
20
|
+
xml.loc(resource.absolute_uri)
|
21
|
+
xml.lastmod(resource.date.iso8601)
|
22
|
+
xml.changefreq(resource.change_frequency.to_s)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
@content = builder.doc
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
class Mill
|
2
|
+
|
3
|
+
class Resource
|
4
|
+
|
5
|
+
class Text < Resource
|
6
|
+
|
7
|
+
include HTMLHelpers
|
8
|
+
|
9
|
+
attr_accessor :title
|
10
|
+
|
11
|
+
def self.type
|
12
|
+
:text
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(params={})
|
16
|
+
super(
|
17
|
+
{
|
18
|
+
public: true,
|
19
|
+
}.merge(params)
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def load
|
24
|
+
if @input_file
|
25
|
+
@content = @input_file.read
|
26
|
+
markup_class = case @input_file.extname
|
27
|
+
when '.md', '.mdown', '.markdown'
|
28
|
+
Kramdown::Document
|
29
|
+
when '.textile'
|
30
|
+
RedCloth
|
31
|
+
when '.txt'
|
32
|
+
PreText
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
if markup_class
|
37
|
+
parse_text_header
|
38
|
+
raise "#{uri}: Content is empty" unless @content
|
39
|
+
@content = markup_class.new(@content).to_html
|
40
|
+
@output_file = @output_file.replace_extension('.html')
|
41
|
+
end
|
42
|
+
begin
|
43
|
+
@content = parse_html(@content)
|
44
|
+
rescue HTMLError => e
|
45
|
+
raise "failed to parse #{@input_file}: #{e}"
|
46
|
+
end
|
47
|
+
parse_html_header
|
48
|
+
end
|
49
|
+
add_image_sizes
|
50
|
+
convert_relative_links
|
51
|
+
super
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_html_header
|
55
|
+
if (title_elem = @content.at_xpath('/html/head/title'))
|
56
|
+
@title = title_elem.text
|
57
|
+
end
|
58
|
+
@content.xpath('/html/head/meta[@name]').each do |meta|
|
59
|
+
send("#{meta['name']}=", meta['content'])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_text_header
|
64
|
+
if @content =~ /^\w+:\s+/
|
65
|
+
header, @content = @content.split(/\n\n/, 2)
|
66
|
+
header.split(/\n/).map do |line|
|
67
|
+
key, value = line.strip.split(/:\s+/, 2)
|
68
|
+
key = key.gsub('-', '_').downcase.to_sym
|
69
|
+
send("#{key}=", value)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def final_content
|
75
|
+
html_document do |doc|
|
76
|
+
doc.html(lang: 'en') do |html|
|
77
|
+
html.head do
|
78
|
+
html << head.to_html
|
79
|
+
end
|
80
|
+
html.body do
|
81
|
+
html << body.to_html
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def head
|
88
|
+
@content.at_xpath('/html/head').children
|
89
|
+
end
|
90
|
+
|
91
|
+
def body
|
92
|
+
@content.at_xpath('/html/body').children
|
93
|
+
end
|
94
|
+
|
95
|
+
def verify
|
96
|
+
tidy_html(@output_file.read) do |error_str|
|
97
|
+
warn "#{uri}: #{error_str}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def add_external_link_targets
|
102
|
+
@content.xpath('//a').each do |a|
|
103
|
+
if a['href'] && a['href'] =~ /^\w+:/
|
104
|
+
a['target'] = '_blank'
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def add_image_sizes
|
110
|
+
@content.xpath('//img').each do |img|
|
111
|
+
# skip elements that already have width/height defined
|
112
|
+
next if img[:width] || img[:height]
|
113
|
+
img_link = Addressable::URI.parse(img['src'])
|
114
|
+
raise "no link in <img> element: #{img.to_s}" if img_link.nil? || img_link.empty?
|
115
|
+
next if img_link.host
|
116
|
+
img_uri = uri + img_link
|
117
|
+
img_resource = @mill.find_resource(img_uri) or raise "Can't find image for #{img_uri}"
|
118
|
+
img[:width], img[:height] = img_resource.width, img_resource.height
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def convert_relative_links
|
123
|
+
@mill.link_elem_attrs.each do |xpath|
|
124
|
+
convert_relative_link(xpath)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def convert_relative_link(elem_attr)
|
129
|
+
@content.xpath("//#{elem_attr}").each do |attribute|
|
130
|
+
elem = attribute.parent
|
131
|
+
link_uri = Addressable::URI.parse(attribute.value) or raise "Can't parse #{attribute.value.inspect} from #{xpath.inspect}"
|
132
|
+
if !link_uri.path.empty? && link_uri.path[0] != '/'
|
133
|
+
attribute.value = uri + link_uri
|
134
|
+
# ;;warn "[#{uri}] absolutized #{elem.name}/@#{attribute.name}: #{link_uri} => #{attribute.value}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def feed_summary
|
140
|
+
;;raise "#{uri} has no content" unless @content
|
141
|
+
if (p = @content.at_xpath('/html/body/p[1]'))
|
142
|
+
['html', p.to_html]
|
143
|
+
else
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def feed_content
|
149
|
+
body = @content.at_xpath('/html/body') or raise "#{uri} has no content"
|
150
|
+
['html', body.children.to_html]
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<xs:schema targetNamespace="http://www.w3.org/2005/Atom" elementFormDefault="qualified"
|
3
|
+
attributeFormDefault="unqualified"
|
4
|
+
xmlns:atom="http://www.w3.org/2005/Atom"
|
5
|
+
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
6
|
+
xmlns:xml="http://www.w3.org/XML/1998/namespace">
|
7
|
+
<xs:annotation>
|
8
|
+
<xs:documentation>
|
9
|
+
This version of the Atom schema is based on version 1.0 of the format specifications,
|
10
|
+
found here http://www.atomenabled.org/developers/syndication/atom-format-spec.php.
|
11
|
+
</xs:documentation>
|
12
|
+
</xs:annotation>
|
13
|
+
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/03/xml.xsd" />
|
14
|
+
<xs:annotation>
|
15
|
+
<xs:documentation>
|
16
|
+
An Atom document may have two root elements, feed and entry, as defined in section 2.
|
17
|
+
</xs:documentation>
|
18
|
+
</xs:annotation>
|
19
|
+
<xs:element name="feed" type="atom:feedType"/>
|
20
|
+
<xs:element name="entry" type="atom:entryType"/>
|
21
|
+
<xs:complexType name="textType" mixed="true">
|
22
|
+
<xs:annotation>
|
23
|
+
<xs:documentation>
|
24
|
+
The Atom text construct is defined in section 3.1 of the format spec.
|
25
|
+
</xs:documentation>
|
26
|
+
</xs:annotation>
|
27
|
+
<xs:sequence>
|
28
|
+
<xs:any namespace="http://www.w3.org/1999/xhtml" minOccurs="0"/>
|
29
|
+
</xs:sequence>
|
30
|
+
<xs:attribute name="type" >
|
31
|
+
<xs:simpleType>
|
32
|
+
<xs:restriction base="xs:token">
|
33
|
+
<xs:enumeration value="text"/>
|
34
|
+
<xs:enumeration value="html"/>
|
35
|
+
<xs:enumeration value="xhtml"/>
|
36
|
+
</xs:restriction>
|
37
|
+
</xs:simpleType>
|
38
|
+
</xs:attribute>
|
39
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
40
|
+
</xs:complexType>
|
41
|
+
<xs:complexType name="personType">
|
42
|
+
<xs:annotation>
|
43
|
+
<xs:documentation>
|
44
|
+
The Atom person construct is defined in section 3.2 of the format spec.
|
45
|
+
</xs:documentation>
|
46
|
+
</xs:annotation>
|
47
|
+
<xs:choice minOccurs="1" maxOccurs="unbounded">
|
48
|
+
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
|
49
|
+
<xs:element name="uri" type="atom:uriType" minOccurs="0" maxOccurs="1" />
|
50
|
+
<xs:element name="email" type="atom:emailType" minOccurs="0" maxOccurs="1" />
|
51
|
+
<xs:any namespace="##other"/>
|
52
|
+
</xs:choice>
|
53
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
54
|
+
</xs:complexType>
|
55
|
+
<xs:simpleType name="emailType">
|
56
|
+
<xs:annotation>
|
57
|
+
<xs:documentation>
|
58
|
+
Schema definition for an email address.
|
59
|
+
</xs:documentation>
|
60
|
+
</xs:annotation>
|
61
|
+
<xs:restriction base="xs:normalizedString">
|
62
|
+
<!--
|
63
|
+
<xs:pattern value="\w+@(\w+\.)+\w+" />
|
64
|
+
-->
|
65
|
+
<xs:maxLength value="254"/>
|
66
|
+
<xs:pattern value="[_\-a-zA-Z0-9\.\+]+@[a-zA-Z0-9](\.?[\-a-zA-Z0-9]*[a-zA-Z0-9])*"/>
|
67
|
+
</xs:restriction>
|
68
|
+
</xs:simpleType>
|
69
|
+
<xs:complexType name="feedType">
|
70
|
+
<xs:annotation>
|
71
|
+
<xs:documentation>
|
72
|
+
The Atom feed construct is defined in section 4.1.1 of the format spec.
|
73
|
+
</xs:documentation>
|
74
|
+
</xs:annotation>
|
75
|
+
<xs:choice minOccurs="3" maxOccurs="unbounded">
|
76
|
+
<xs:element name="author" type="atom:personType" minOccurs="0" maxOccurs="unbounded" />
|
77
|
+
<xs:element name="category" type="atom:categoryType" minOccurs="0" maxOccurs="unbounded" />
|
78
|
+
<xs:element name="contributor" type="atom:personType" minOccurs="0" maxOccurs="unbounded" />
|
79
|
+
<xs:element name="generator" type="atom:generatorType" minOccurs="0" maxOccurs="1" />
|
80
|
+
<xs:element name="icon" type="atom:iconType" minOccurs="0" maxOccurs="1" />
|
81
|
+
<xs:element name="id" type="atom:idType" minOccurs="1" maxOccurs="1" />
|
82
|
+
<xs:element name="link" type="atom:linkType" minOccurs="0" maxOccurs="unbounded" />
|
83
|
+
<xs:element name="logo" type="atom:logoType" minOccurs="0" maxOccurs="1" />
|
84
|
+
<xs:element name="rights" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
85
|
+
<xs:element name="subtitle" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
86
|
+
<xs:element name="title" type="atom:textType" minOccurs="1" maxOccurs="1" />
|
87
|
+
<xs:element name="updated" type="atom:dateTimeType" minOccurs="1" maxOccurs="1" />
|
88
|
+
<xs:element name="entry" type="atom:entryType" minOccurs="0" maxOccurs="unbounded" />
|
89
|
+
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
|
90
|
+
</xs:choice>
|
91
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
92
|
+
</xs:complexType>
|
93
|
+
<xs:complexType name="entryType">
|
94
|
+
<xs:annotation>
|
95
|
+
<xs:documentation>
|
96
|
+
The Atom entry construct is defined in section 4.1.2 of the format spec.
|
97
|
+
</xs:documentation>
|
98
|
+
</xs:annotation>
|
99
|
+
<xs:choice maxOccurs="unbounded">
|
100
|
+
<xs:element name="author" type="atom:personType" minOccurs="0" maxOccurs="unbounded" />
|
101
|
+
<xs:element name="category" type="atom:categoryType" minOccurs="0" maxOccurs="unbounded" />
|
102
|
+
<xs:element name="content" type="atom:contentType" minOccurs="0" maxOccurs="1" />
|
103
|
+
<xs:element name="contributor" type="atom:personType" minOccurs="0" maxOccurs="unbounded" />
|
104
|
+
<xs:element name="id" type="atom:idType" minOccurs="1" maxOccurs="1" />
|
105
|
+
<xs:element name="link" type="atom:linkType" minOccurs="0" maxOccurs="unbounded" />
|
106
|
+
<xs:element name="published" type="atom:dateTimeType" minOccurs="0" maxOccurs="1" />
|
107
|
+
<xs:element name="rights" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
108
|
+
<xs:element name="source" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
109
|
+
<xs:element name="summary" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
110
|
+
<xs:element name="title" type="atom:textType" minOccurs="1" maxOccurs="1" />
|
111
|
+
<xs:element name="updated" type="atom:dateTimeType" minOccurs="1" maxOccurs="1" />
|
112
|
+
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
|
113
|
+
</xs:choice>
|
114
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
115
|
+
</xs:complexType>
|
116
|
+
<xs:complexType name="contentType" mixed="true">
|
117
|
+
<xs:annotation>
|
118
|
+
<xs:documentation>
|
119
|
+
The Atom content construct is defined in section 4.1.3 of the format spec.
|
120
|
+
</xs:documentation>
|
121
|
+
</xs:annotation>
|
122
|
+
<xs:sequence>
|
123
|
+
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" />
|
124
|
+
</xs:sequence>
|
125
|
+
<xs:attribute name="type" type="xs:string"/>
|
126
|
+
<xs:attribute name="src" type="xs:anyURI"/>
|
127
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
128
|
+
</xs:complexType>
|
129
|
+
<xs:complexType name="categoryType">
|
130
|
+
<xs:annotation>
|
131
|
+
<xs:documentation>
|
132
|
+
The Atom cagegory construct is defined in section 4.2.2 of the format spec.
|
133
|
+
</xs:documentation>
|
134
|
+
</xs:annotation>
|
135
|
+
<xs:attribute name="term" type="xs:string" use="required"/>
|
136
|
+
<xs:attribute name="scheme" type="xs:anyURI" use="optional"/>
|
137
|
+
<xs:attribute name="label" type="xs:string" use="optional"/>
|
138
|
+
<xs:attributeGroup ref="atom:commonAttributes" />
|
139
|
+
</xs:complexType>
|
140
|
+
<xs:complexType name="generatorType">
|
141
|
+
<xs:annotation>
|
142
|
+
<xs:documentation>
|
143
|
+
The Atom generator element is defined in section 4.2.4 of the format spec.
|
144
|
+
</xs:documentation>
|
145
|
+
</xs:annotation>
|
146
|
+
<xs:simpleContent>
|
147
|
+
<xs:extension base="xs:string">
|
148
|
+
<xs:attribute name="uri" use="optional" type="xs:anyURI" />
|
149
|
+
<xs:attribute name="version" use="optional" type="xs:string" />
|
150
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
151
|
+
</xs:extension>
|
152
|
+
</xs:simpleContent>
|
153
|
+
</xs:complexType>
|
154
|
+
<xs:complexType name="iconType">
|
155
|
+
<xs:annotation>
|
156
|
+
<xs:documentation>
|
157
|
+
The Atom icon construct is defined in section 4.2.5 of the format spec.
|
158
|
+
</xs:documentation>
|
159
|
+
</xs:annotation>
|
160
|
+
<xs:simpleContent>
|
161
|
+
<xs:extension base="xs:anyURI">
|
162
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
163
|
+
</xs:extension>
|
164
|
+
</xs:simpleContent>
|
165
|
+
</xs:complexType>
|
166
|
+
<xs:complexType name="idType">
|
167
|
+
<xs:annotation>
|
168
|
+
<xs:documentation>
|
169
|
+
The Atom id construct is defined in section 4.2.6 of the format spec.
|
170
|
+
</xs:documentation>
|
171
|
+
</xs:annotation>
|
172
|
+
<xs:simpleContent>
|
173
|
+
<xs:extension base="xs:anyURI">
|
174
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
175
|
+
</xs:extension>
|
176
|
+
</xs:simpleContent>
|
177
|
+
</xs:complexType>
|
178
|
+
<xs:complexType name="linkType" mixed="true">
|
179
|
+
<xs:annotation>
|
180
|
+
<xs:documentation>
|
181
|
+
The Atom link construct is defined in section 3.4 of the format spec.
|
182
|
+
</xs:documentation>
|
183
|
+
</xs:annotation>
|
184
|
+
<xs:attribute name="href" use="required" type="xs:anyURI" />
|
185
|
+
<xs:attribute name="rel" type="xs:string" use="optional"/>
|
186
|
+
<xs:attribute name="type" use="optional" type="xs:string" />
|
187
|
+
<xs:attribute name="hreflang" use="optional" type="xs:NMTOKEN" />
|
188
|
+
<xs:attribute name="title" use="optional" type="xs:string" />
|
189
|
+
<xs:attribute name="length" use="optional" type="xs:positiveInteger" />
|
190
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
191
|
+
</xs:complexType>
|
192
|
+
<xs:complexType name="logoType">
|
193
|
+
<xs:annotation>
|
194
|
+
<xs:documentation>
|
195
|
+
The Atom logo construct is defined in section 4.2.8 of the format spec.
|
196
|
+
</xs:documentation>
|
197
|
+
</xs:annotation>
|
198
|
+
<xs:simpleContent>
|
199
|
+
<xs:extension base="xs:anyURI">
|
200
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
201
|
+
</xs:extension>
|
202
|
+
</xs:simpleContent>
|
203
|
+
</xs:complexType>
|
204
|
+
<xs:complexType name="sourceType">
|
205
|
+
<xs:annotation>
|
206
|
+
<xs:documentation>
|
207
|
+
The Atom source construct is defined in section 4.2.11 of the format spec.
|
208
|
+
</xs:documentation>
|
209
|
+
</xs:annotation>
|
210
|
+
<xs:choice maxOccurs="unbounded">
|
211
|
+
<xs:element name="author" type="atom:personType" minOccurs="0" maxOccurs="unbounded"/>
|
212
|
+
<xs:element name="category" type="atom:categoryType" minOccurs="0" maxOccurs="unbounded"/>
|
213
|
+
<xs:element name="contributor" type="atom:personType" minOccurs="0" maxOccurs="unbounded"/>
|
214
|
+
<xs:element name="generator" type="atom:generatorType" minOccurs="0" maxOccurs="1"/>
|
215
|
+
<xs:element name="icon" type="atom:iconType" minOccurs="0" maxOccurs="1"/>
|
216
|
+
<xs:element name="id" type="atom:idType" minOccurs="0" maxOccurs="1"/>
|
217
|
+
<xs:element name="link" type="atom:linkType" minOccurs="0" maxOccurs="unbounded"/>
|
218
|
+
<xs:element name="logo" type="atom:logoType" minOccurs="0" maxOccurs="1"/>
|
219
|
+
<xs:element name="rights" type="atom:textType" minOccurs="0" maxOccurs="1"/>
|
220
|
+
<xs:element name="subtitle" type="atom:textType" minOccurs="0" maxOccurs="1"/>
|
221
|
+
<xs:element name="title" type="atom:textType" minOccurs="0" maxOccurs="1"/>
|
222
|
+
<xs:element name="updated" type="atom:dateTimeType" minOccurs="0" maxOccurs="1"/>
|
223
|
+
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
|
224
|
+
</xs:choice>
|
225
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
226
|
+
</xs:complexType>
|
227
|
+
<xs:complexType name="uriType">
|
228
|
+
<xs:simpleContent>
|
229
|
+
<xs:extension base="xs:anyURI">
|
230
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
231
|
+
</xs:extension>
|
232
|
+
</xs:simpleContent>
|
233
|
+
</xs:complexType>
|
234
|
+
<xs:complexType name="dateTimeType">
|
235
|
+
<xs:simpleContent>
|
236
|
+
<xs:extension base="xs:dateTime">
|
237
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
238
|
+
</xs:extension>
|
239
|
+
</xs:simpleContent>
|
240
|
+
</xs:complexType>
|
241
|
+
<xs:attributeGroup name="commonAttributes">
|
242
|
+
<xs:anyAttribute namespace="##other"/>
|
243
|
+
</xs:attributeGroup>
|
244
|
+
</xs:schema>
|