source: project/wiki/eggref/4/atom @ 37084

Last change on this file since 37084 was 37084, checked in by zbigniew, 4 months ago

Update Chicken 4 docs for zbigniew eggs

These eggs were ported to Chicken 5 and still support
Chicken 4; docs remain synchronized.

atom chickadee chicken-doc chicken-doc-admin doctype
feature-test socket sql-de-lite tcp6 udp6

File size: 36.5 KB
Line 
1== atom
2
3Read and write Atom 1.0 feeds.
4
5[[toc:]]
6
7=== Overview
8
9[[atom]] provides the means to read
10[[http://tools.ietf.org/html/rfc4287|RFC 4287]] conforming Atom 1.0
11documents, which are either feeds or single entries.  Procedures are
12provided to access child elements of feeds and entries, such as the
13feed author, and also to access the child elements and contents of
14these children, such as author name and email.
15
16Elements themselves are returned as plain SXML documents, which are
17for the most part verbatim copies of the XML input elements.  This is
18true even for the Atom document itself, which is the SXML
19representation of the original XML document.  This means that if
20desired, you can access elements or the entire document using standard
21list deconstructors or [[sxpath]] rather than the provided accessors.
22
23For example, accessing the feed author returns an {{atom:author}} child:
24
25 > (feed-author feed)
26   ;=> (atom:author (atom:name "A. Hacker")
27                    (atom:uri "http://www.hacker.dim")
28                    (atom:email "buzz+off@hacker.dim"))
29
30and you can either use the accessors, or deconstruct the result manually:
31
32 > (author-name (feed-author feed))
33   ;=> "A. Hacker"
34 > (cadr (assq 'atom:name (cdr (feed-author G))))
35   ;=> "A. Hacker"
36
37Or for a list of all people (authors, contributors, etc.) mentioned in
38{{atom:name}} elements anywhere in the feed:
39
40 > (delete-duplicates ((sxpath '(// atom:name *text*)) feed))
41   ;=> ("A. Hacker" "A. Contributor" "A. Groupie")
42
43Element contents and element attributes are generally returned as text
44strings.  This includes HTML contents, which will be unescaped for
45you.  It also includes RFC3339 datetime strings, which can be
46deconstructed using the [[rfc3339]] egg, and URIs, which can be
47manipulated with [[uri-common]].  Certain elements may contain XHTML
48or XML documents; special accessors for these elements are provided,
49which return their contents as SXML.
50
51The same rules apply when creating a document; elements may be
52generated using their constructors or created directly in SXML
53if you understand the format.  For example, these two excerpts
54are equivalent:
55
56 > (make-feed authors: (list (make-author name: "Jim"
57                                          email: "himmy@pimmy.dim"))
58              ...)
59 > (make-feed authors: (list '(atom:author (atom:name "Jim")
60                                           (atom:email "himmy@pimmy.dim")))
61              ...)
62
63except that {{make-author}} checks its input, ensuring the required {{name}}
64element is present and that all arguments are strings.  Other constructors
65may do more complicated constraint checking or simplify element creation.
66
67=== Read interface
68
69==== Atom document
70
71<procedure>(read-atom-doc port)</procedure>
72
73Reads an Atom Feed Document or Atom Entry Document from PORT and
74returns an SXML document representing the entire XML document,
75including any processing instructions.  If the document is not
76readable as XML or does not contain a single {{atom:feed}} or {{atom:entry}}
77root element, an error is thrown.
78
79<procedure>(atom-doc-root doc)</procedure>
80
81Return the root element of the document, which will be an {{atom:feed}}
82or {{atom:entry}} node.
83
84<procedure>(atom-doc-encoding doc)</procedure>
85
86Return XML document encoding as provided in the document; defaults to "utf-8".
87
88<procedure>(read-atom-feed port)</procedure>
89
90Convenience function which reads an Atom Feed Document and returns the
91root {{atom:feed}} element.  If this fails, an error is thrown.
92
93<procedure>(read-atom-entry port)</procedure>
94
95Convenience function which reads an Atom Entry Document and returns the
96root {{atom:entry}} element.  If this fails, an error is thrown.
97
98==== Feeds
99
100<record>atom:feed</record>
101
102An {{atom:feed}} element, which represents an Atom feed.  Records such
103as {{atom:feed}} are just SXML documents (list structures) like
104
105 (atom:feed (atom:author ...) (atom:title ...) ...)
106
107and can be queried either via the provided
108accessors, or directly via list destructuring if desired.
109
110<procedure>(feed? F)</procedure>
111
112Returns true if F is an {{atom:feed}} element.
113
114<procedure>(feed-authors F)</procedure>
115<procedure>(feed-author F)</procedure>
116
117{{feed-authors}} returns a list of feed authors; that is,
118{{atom:author}} children of the feed.  A null list designates no
119authors.
120
121{{feed-author}} returns the first feed author, or {{#f}} if none.
122
123Feeds must contain at least one author element unless every
124feed entry contains one, as the default authorship for entries
125is that of the feed.
126
127<procedure>(feed-categories F)</procedure>
128
129Returns a list of feed categories ({{atom:category}} children), or null.
130
131<procedure>(feed-contributors F)</procedure>
132
133Returns a list of feed contributors ({{atom:contributor}} children), or null.
134
135<procedure>(feed-generator F)</procedure>
136
137Returns the feed generator (the {{atom:generator}} child), or {{#f}} if none.
138
139<procedure>(feed-icon F)</procedure>
140
141Returns the feed icon (the {{atom:icon}} child), or {{#f}} if none.
142
143<procedure>(feed-id F)</procedure>
144
145Returns the feed ID as a string (the text contents of the {{atom:id}}
146child), or the empty string if no ID.  The ID is required in an Atom
147feed.
148
149<procedure>(feed-links F)</procedure>
150
151Returns a list of feed links ({{atom:link}} children), or null.
152
153<procedure>(feed-logo F)</procedure>
154
155Returns the feed logo ({{atom:logo}} child), or {{#f}} if none.
156
157<procedure>(feed-rights F)</procedure>
158
159Returns the feed rights ({{atom:rights}} child), or {{#f}} if none.
160
161<procedure>(feed-subtitle F)</procedure>
162
163Returns the feed subtitle ({{atom:subtitle}} child), or {{#f}} if none.
164
165<procedure>(feed-title F)</procedure>
166
167Returns the feed title ({{atom:title}} child), or {{#f}} if none.
168The Atom spec requires a feed title.
169
170<procedure>(feed-updated F)</procedure>
171
172Returns an [[rfc3339]] string representing the last time the feed was updated.
173The Atom spec requires this field to be present.
174
175<procedure>(feed-entries F)</procedure>
176
177Return a list of feed entries ({{atom:entry}} children), or null.
178
179==== Entries
180
181<record>atom:entry</record>
182
183An {{atom:entry}} element, which represents an Atom entry.  Records such
184as {{atom:entry}} are just SXML documents (list structures) like
185
186 (atom:entry (atom:author ...) (atom:id ...) ...)
187
188and can be queried either via the provided accessors, or directly if
189desired.
190
191<procedure>(entry? E)</procedure>
192
193Returns true if E is an {{atom:entry}}.
194
195<procedure>(entry=? E1 E2)</procedure>
196
197Returns true if E1 and E2 represent the same {{atom:entry}}.  This
198tests the entry IDs for equivalence.
199
200<procedure>(entry-authors E)</procedure>
201<procedure>(entry-author E)</procedure>
202
203{{entry-authors}} returns a list of entry authors; that is,
204{{atom:author}} children of the entry.  A null list designates no
205authors.
206
207{{entry-author}} returns the first entry author, or {{#f}} if none.
208
209Each entry must have at least one author.  If not present as a child
210of the entry, it must be present in the entry's source feed element
211(for aggregated content), or in the feed element itself.
212
213Currently, you must handle this manually.  One possibility is:
214
215 (or (entry-author E)
216     (feed-author F))
217
218<procedure>(entry-categories E)</procedure>
219
220Returns a list of entry categories ({{atom:category}} children), or null.
221
222<procedure>(entry-contributors E)</procedure>
223
224Returns a list of entry contributors ({{atom:contributor}} children), or null.
225
226<procedure>(entry-content E)</procedure>
227
228Returns the entry content (the {{atom:content}} child), or {{#f}} if none.
229Entries need not contain a content element, but if not, they must contain
230an {{atom:link}} with a {{link-relation}} of "alternate".
231
232<procedure>(entry-id E)</procedure>
233
234Returns the entry ID as a string (the text contents of the {{atom:id}}
235child), or the empty string if no ID.  Atom entries must contain
236exactly one {{atom:id}} element.
237
238<procedure>(entry-links E)</procedure>
239
240Returns a list of entry links ({{atom:link}} children), or null.
241
242<procedure>(entry-published E)</procedure>
243
244Returns an [[rfc3339]] datetime string, typically representing
245the entry's initial creation time or first availability.
246
247<procedure>(entry-rights E)</procedure>
248
249Returns the entry rights ({{atom:rights}} child), or {{#f}} if none.
250
251If no entry rights are present, the feed's rights are considered
252to apply.  Currently, you must do this manually:
253
254 (or (entry-rights E)
255     (feed-rights F))
256
257<procedure>(entry-source E)</procedure>
258
259Returns the entry's source feed information ({{atom:source}} child), or {{#f}} if none.
260
261The entry's source feed is used by Atom content aggregators to record
262information on where the entry came from.
263
264<procedure>(entry-summary E)</procedure>
265
266Returns the entry summary ({{atom:summary}} child), or {{#f}} if none.
267The summary must be present if the entry's content is of kind
268{{'external}} or {{'binary}}.
269
270<procedure>(entry-title E)</procedure>
271
272Returns the entry title ({{atom:title}} child), or {{#f}} if none.
273Atom entries must contain exactly one {{atom:title}} element.
274
275<procedure>(entry-updated E)</procedure>
276
277Returns an [[rfc3339]] string representing the last time the entry was updated.
278Atom entries must contain exactly one {{atom:updated}} element.
279
280==== Persons
281
282<record>atom:author</record>
283<procedure>(author? A)</procedure>
284<procedure>(author-name A)</procedure>
285<procedure>(author-uri A)</procedure>
286<procedure>(author-email A)</procedure>
287
288Predicate and accessors for {{atom:author}} elements, representing
289the authors of the feed or entry.
290
291; name : (''required by spec'') the author's name, a string
292; uri : a URI associated with the author, a string
293; email : the author's email address, a string conforming to RFC2822
294
295Accessors return the empty string if the field is not present.
296
297<record>atom:contributor</record>
298<procedure>(contributor? A)</procedure>
299<procedure>(contributor-name A)</procedure>
300<procedure>(contributor-uri A)</procedure>
301<procedure>(contributor-email A)</procedure>
302
303Predicate and accessors for {{atom:contributor}} elements, representing
304contributors to the feed or entry.
305
306; name : (''required by spec'') the contributor's name, a string
307; uri : a URI associated with the contributor, a string
308; email : the contributor's email address, a string conforming to RFC2822
309
310Accessors return the empty string if the field is not present.
311
312==== Rights, Summary, Title, Subtitle
313
314<record>atom:rights</record>
315<procedure>(rights? A)</procedure>
316<procedure>(rights-type A)</procedure>
317<procedure>(rights-text A)</procedure>
318<procedure>(rights-xhtml A)</procedure>
319
320Predicate and accessors for {{atom:rights}} elements, which represent
321human-readable rights information for the feed.  This element is an
322''atomtextConstruct'', so it may contain either text (here meaning
323either plain text or HTML), or XHTML content.
324
325{{rights-type}} will return the type of content as a symbol:
326
327; 'text : text content
328; 'html : html content (considered to be text)
329; 'xhtml : XHTML content
330
331{{rights-text}} returns the contents of the element as a string, and is
332what you should use for 'text or 'html types.  HTML will be unescaped for
333you, but is still returned as a string.  It returns the empty string if
334no text is present.
335
336{{rights-xhtml}} returns the XHTML contents of the element as an SXML
337document.  The root element inside the contents ''must'' be an XHTML div
338({{xhtml:div}}).  If such an element is not found, it returns
339{{#f}}.  Note that we return the div as the root of the SXML document,
340but the Atom spec says you must not consider the div itself
341part of the content.
342
343<record>atom:summary</record>
344<procedure>(summary? A)</procedure>
345<procedure>(summary-type A)</procedure>
346<procedure>(summary-text A)</procedure>
347<procedure>(summary-xhtml A)</procedure>
348
349Predicate and accessors for {{atom:summary}} elements, representing
350an excerpt or abstract for an entry.  For meaning,
351see {{atom:rights}}.
352
353<record>atom:subtitle</record>
354<procedure>(subtitle? A)</procedure>
355<procedure>(subtitle-type A)</procedure>
356<procedure>(subtitle-text A)</procedure>
357<procedure>(subtitle-xhtml A)</procedure>
358
359Predicate and accessors for {{atom:subtitle}} elements, representing
360a subtitle for the feed.  For meaning, see {{atom:rights}}.
361
362<record>atom:title</record>
363<procedure>(title? A)</procedure>
364<procedure>(title-type A)</procedure>
365<procedure>(title-text A)</procedure>
366<procedure>(title-xhtml A)</procedure>
367
368Predicate and accessors for {{atom:title}} elements, representing
369a title for the feed or entry.  For meaning, see {{atom:rights}}.
370
371==== Generators
372
373<record>atom:generator</record>
374<procedure>(generator? G)</procedure>
375<procedure>(generator-agent G)</procedure>
376<procedure>(generator-uri G)</procedure>
377<procedure>(generator-version G)</procedure>
378
379Predicate and accessors for {{atom:generator}} elements, which
380represent the (machine) agent that generated the feed.
381
382; agent: a human-readable, plain-text name for the generating agent, as a string
383; uri: URI relevant to the agent, as a string
384; version: version of the generating agent, as a string
385
386==== Icons & Logos
387
388<record>atom:icon</record>
389<procedure>(icon? I)</procedure>
390<procedure>(icon-uri I)</procedure>
391
392Predicate and accessors for {{atom:icon}} elements, which represent
393iconic visual identification for the feed.  {{icon-uri}} returns a URI string
394which points to the icon image.
395
396<record>atom:logo</record>
397<procedure>(logo? I)</procedure>
398<procedure>(logo-uri I)</procedure>
399
400Predicate and accessors for {{atom:logo}} elements, which represent
401visual identification for the feed.  {{logo-uri}} returns a URI string
402which points to the logo image.
403
404==== Categories
405
406<record>atom:category</record>
407<procedure>(category? I)</procedure>
408<procedure>(category-term I)</procedure>
409<procedure>(category-scheme I)</procedure>
410<procedure>(category-label I)</procedure>
411<procedure>(category-contents C)</procedure>
412
413Predicate and accessors for {{atom:category}} elements, which
414represent the categorization of the feed or entry.
415
416; term : (''required by spec'') category name, as a string
417; scheme : URI that identifies a categorization scheme, as a string
418; label : human-readable plain-text label for the category, as a string
419; contents : Contents of the category element as an SXML document; undefined by the specification, but it might be useful.
420
421{{term}}, {{scheme}} and {{label}} accessors return {{#f}} for missing
422information instead of the empty string as {{atom:author}} and
423{{atom:rights}} accessors do.  This inconsistency is probably a bug.
424
425==== Links
426
427<record>atom:link</record>
428<procedure>(link? L)</procedure>
429<procedure>(link-uri L)</procedure>
430<procedure>(link-relation L)</procedure>
431<procedure>(link-type L)</procedure>
432<procedure>(link-uri-language L)</procedure>
433<procedure>(link-title L)</procedure>
434<procedure>(link-length L)</procedure>
435<procedure>(link-contents L)</procedure>
436
437Predicate and accessors for {{atom:link}} elements, which represent a
438reference from an entry or feed to a Web resource.
439
440; uri : (''required by spec'') the URI (@href) of the link, as a string
441; relation : the link relation type (@rel) as a string (defaults to "alternate" if not present)
442; title : human-readable, plain-text title for the link, as a string
443; type : advisory MIME media type for the referenced resource, as a string
444; length : advisory length in octets for the referenced resource, as an exact integer
445; uri-language : an [[http://tools.ietf.org/html/rfc3066|RFC3066]] language tag (@hreflang) for the referenced resource, as a string
446; contents : Contents of the atom:link element as an SXML document; undefined by the specification, and unlikely to be present
447
448Accessors return {{#f}} if the associate attribute is not present in the document,
449except for {{link-relation}}, which returns "alternate".
450
451==== Source feeds
452
453<record>(source? S)</record>
454<procedure>(source-authors S)</procedure>
455<procedure>(source-author S)</procedure>
456<procedure>(source-categories S)</procedure>
457<procedure>(source-contributors S)</procedure>
458<procedure>(source-generator S)</procedure>
459<procedure>(source-icon S)</procedure>
460<procedure>(source-id S)</procedure>
461<procedure>(source-links S)</procedure>
462<procedure>(source-logo S)</procedure>
463<procedure>(source-rights S)</procedure>
464<procedure>(source-subtitle S)</procedure>
465<procedure>(source-title S)</procedure>
466<procedure>(source-updated S)</procedure>
467
468Predicate and accessors for {{atom:source}} elements, which represent
469metadata about the source feed from which the containing entry was
470taken, and are used for feed aggregators.
471
472Accessors have the same meaning as the corresponding accessors [[#Feeds|for
473feeds]].
474
475==== Content
476
477<record>atom:content</record>
478<procedure>content?</procedure>
479<procedure>(content-kind C)</procedure>
480<procedure>(content-type C)</procedure>
481<procedure>(content-source C)</procedure>
482<procedure>(content-text C)</procedure>
483<procedure>(content-xhtml C)</procedure>
484<procedure>(content-xml C)</procedure>
485<procedure>(content-contents C)</procedure>
486
487Predicate and accessors for {{atom:content}} elements, which represent
488feed or entry content.
489
490Atom content types may be one of "text", "html", "xhtml", or any valid
491MIME type; further, the structure and meaning of the content itself
492depends on the MIME type.  To simplify this, we normalize the MIME type
493and we categorize it by kind:
494
495; type : The indicated MIME media type of the contents.  If the type in the source document is {{text}}, {{html}}, or {{xhtml}}, we normalize this to {{text/plain}}, {{text/html}}, or {{application/xhtml+xml}} respectively. If no type is explicitly indicated, it defaults to {{text/plain}}.
496; kind : The computed "kind" of the contents, as a symbol.  This determines how you should handle the content.
497
498{{kind}} may be one of the following symbols, which represent
499
500; text : plain text ({{text/plain}}), the default
501; html : HTML text ({{text/html}})
502; xhtml : an XHTML div element ({{application/xhtml+xml}})
503; xml : XML; any MIME type string ending with {{/xml}} or {{+xml}}, or one of the [[http://tools.ietf.org/html/rfc3023|RFC3023]] XML media types
504; textual : text data; any other MIME type starting with {{text/}}
505; binary : base64-encoded binary data; any other MIME type other than those mentioned above
506; external : external data pointed to by a URI
507
508To obtain the content, you should use the proper accessor based on the kind:
509
510; text : {{content-text}}, returning a string (or empty string, if no content)
511; html : {{content-text}}, returning an unescaped HTML string (or empty string)
512; xhtml : {{content-xhtml}}, returning the XHTML div element as SXML, or {{#f}}
513; xml : {{content-xml}}, returning the root element (whatever it is) as SXML, or {{#f}} [*]
514; textual : {{content-text}}, returning a string (or empty string)
515; binary : {{content-text}}, returning a base64-encoded string; use [[base64]] to decode it
516; external : {{content-source}}, returning the external URI as a string, or {{#f}}
517
518[*] XML contents conventionally consist of a single root element with no siblings, which is returned directly as {{(node ...)}}.  If more than one such element is found, they are all returned wrapped in a {{*TOP*}} node, like {{(*TOP* (node1 ...) (node2 ...) ...)}}.
519
520For {{xml}}, {{textual}}, {{binary}} and {{external}} kinds, you will
521then need to refer to the content media {{type}} to actually process it.
522
523And finally the raw content accessor, just in case:
524
525; contents : Contents of the {{atom:contents}} element as a raw list of nodes.  Does not try to process the content.
526
527==== IDs
528
529<record>atom:id</record>
530<procedure>(id=? id1 id2)</procedure>
531
532Atom IDs are represented by plain strings in this egg, rather than
533{{atom:id}} elements.  ID equality should be tested using {{id=?}},
534which is aliased to {{string=?}}.
535
536=== Write interface
537
538==== Producing an Atom document
539
540<procedure>(write-atom-doc doc #!optional (port (current-output-port)))</procedure>
541
542Write the Atom Feed or Atom Entry Document DOC, an SXML document typically created
543by {{make-atom-doc}}, to PORT.
544
545<procedure>(make-atom-doc root #!key (declare-xml? #t) (encoding "utf-8") (headers '()))</procedure>
546
547Create an Atom Feed Document or Atom Entry Document.  ROOT is the
548{{atom:feed}} or {{atom:entry}} SXML root node, usually created
549by {{make-feed}} or {{make-entry}}.  Returns a SXML document representing
550the entire Atom document, which can be written out using {{write-atom-doc}}.
551
552; declare-xml? : Whether to add an XML declaration to the document, as a boolean value.
553; encoding: The encoding to declare in the (optional) XML declaration, as a string.
554; headers: A list of headers to include in the output document; see below.
555
556Arbitrary headers may be added to the output document.  These headers
557should, generally, be XML processing instructions or comments, since the document
558must consist of only one root node.  For example, you can prepend some stylesheet
559instructions:
560
561 (write-atom-doc
562  (make-atom-doc feed
563   headers: '((*PI* xml-stylesheet
564               "type=\"text/xsl\" href=\"http://3e8.org/styles/atom.xsl\"")
565              (*PI* xml-stylesheet
566               "type=\"text/css\" href=\"http://3e8.org/styles/atom.css\"")))
567 
568 <?xml version="1.0" encoding="utf-8"?>
569 <?xml-stylesheet type="text/xsl" href="http://3e8.org/styles/atom.xsl"?>
570 <?xml-stylesheet type="text/css" href="http://3e8.org/styles/atom.css"?>
571 <atom:feed xmlns:atom="http://www.w3.org/2005/Atom">
572  ...
573
574Since this procedure just returns a complete SXML document beginning with
575a *TOP* node, you could instead modify the returned document and add any
576processing instructions yourself.  {{headers}} is just a convenient way
577of doing so.
578
579==== Feed constructor
580
581<procedure>(make-feed #!key KEYS)</procedure>
582
583Make a new {{atom:feed}} element, with KEYS corresponding to child elements.
584Raises an error if any required elements are missing.
585
586Required elements:
587
588; authors : a list of atom:author elements, the authors of the feed
589; id : an atom:id string, a permanent, unique absolute IRI identifier
590; title : an atom:title element, a human-readable title for the feed
591; updated : an atom:updated element, an RFC3339 timestamp indicating last update time
592
593Optional elements:
594
595; categories: a list of atom:category elements, the feed categories
596; contributors : a list of atom:contributor elements, the contributors to the feed
597; generator : an atom:generator element, the feed generator
598; icon : an atom:icon element, the feed icon
599; links : a list of atom:link elements, the feed links
600; logo : an atom:logo element, the feed logo
601; rights : an atom:rights element, a human-readable description of rights held over the feed
602; subtitle : an atom:subtitle element, a human-readable subtitle for the feed
603; entries : a list of atom:entry elements, the feed entries
604
605Notes:
606
607* It's a good idea to provide an "alternate" link for your feed and for each entry, pointing to
608the source document.  See [[#Link constructor|make-link]].
609
610* {{authors}} may be omitted if all entries contain authorship information
611(meaning, {{atom:author}} elements as direct children).  {{make-feed}} will detect
612this case.
613
614* If you omit {{generator}}, it defaults to describing this egg.  To completely
615omit the generator element, which would make me sad, pass {{#f}}.
616
617==== Entry constructor
618
619<procedure>(make-entry #!key KEYS)</procedure>
620
621Make a new {{atom:entry}} element, with KEYS corresponding to child elements.
622Raises an error if any required elements are missing.
623
624Required elements:
625
626; id : an atom:id string, a permanent, unique absolute IRI identifier for the entry
627; title : an atom:title element, a human-readable title for the entry
628; updated : an atom:updated element, an RFC3339 timestamp indicating last update time
629
630Optional elements:
631
632; authors : a list of atom:author elements, the authors of the entry
633; categories: a list of atom:category elements, the entry categories
634; contributors : a list of atom:contributor elements, the contributors to the entry
635; content: an atom:content element, the entry content
636; links : a list of atom:link elements, the entry links
637; published : an atom:published element, an RFC3339 timestamp indicating initial creation time
638; rights : an atom:rights element, a human-readable description of rights held over the entry
639; source : an atom:source element, information about the feed source for content aggregators
640; summary : an atom:summary element, a human-readable summary, abstract or excerpt of the entry
641
642Additional notes:
643
644Entry author elements are optional as long as the containing feed
645contains authorship information.  If the feed does not, the entry must
646contain least one author element.  This will be checked in
647{{make-feed}}.
648
649Entry elements without a {{atom:content}} element must contain an {{atom:link}}
650with link-relation "alternate".  This is checked in {{make-entry}}.
651
652Entry summary elements are optional unless an atom:content element is present and
653its content kind is {{'external}} or {{'binary}}.  This is checked in {{make-entry}}.
654
655It is illegal for entries to contain more than one atom:link element
656with a link-relation of "alternate" and the same type and uri-language values.
657This is ''not'' checked in {{make-entry}}.
658
659==== Person constructors
660
661<procedure>(make-author #!key name uri email)</procedure>
662
663Create an atom:author element.
664
665; name : (''required'') the author's name, a string
666; uri : a URI associated with the author, a string
667; email : the author's email address, a string conforming to RFC2822
668
669<procedure>(make-contributor #!key name uri email)</procedure>
670
671Create an atom:contributor element.
672
673; name : (''required'') the contributor's name, a string
674; uri : a URI associated with the contributor, a string
675; email : the contributor's email address, a string conforming to RFC2822
676
677==== Text constructors
678
679<procedure>(make-rights contents #!key (type 'text))</procedure>
680<procedure>(make-subtitle contents #!key (type 'text))</procedure>
681<procedure>(make-summary contents #!key (type 'text))</procedure>
682<procedure>(make-title contents #!key (type 'text))</procedure>
683
684Create a new {{atom:rights}}, {{atom:subtitle}}, {{atom:summary}},
685or {{atom:title}} element with CONTENTS of type TYPE.
686The accepted value for CONTENT varies according to TYPE:
687
688; 'text : (''default'') a plain text string
689; 'html : an HTML string (it will be escaped for you when written to XML)
690; 'xhtml : an XHTML div element as SXML
691
692 > (make-title "Mesoamerican Deities and You")
693   ; => (atom:title (@ (type "text")) "Mesoamerican Deities and You")
694 > (make-rights '(xhtml:div "Copyright (c) 2012 the feathered serpent, "
695                            (xhtml:b "Quetzlcoatl"))
696                type: 'xhtml)
697   ; => (atom:rights (@ (type "xhtml"))
698         (xhtml:div "Copyright (c) 2012 the feathered serpent, "
699                    (xhtml:b "Quetzlcoatl")))
700 > (make-summary
701    "<p>Coping strategies for when your best friend is a
702    <a href='http://en.wikipedia.org/wiki/Quetzalcoatl'>mythical god</a>
703    and just <i>won't move out</i> of your cramped apartment</p>"
704    type: 'html)
705   ; => (atom:summary (@ (type "html"))
706         "<p>Coping strategies for when your best friend is a
707          <a href='http://en.wikipedia.org/wiki/Quetzalcoatl'>mythical god</a>
708          and just <i>won't move out</i> of your cramped apartment</p>")
709
710==== Generator constructor
711
712<procedure>(make-generator agent #!key uri version)</procedure>
713
714Create an atom:generator element representing the feed generator.
715
716; agent: a human-readable, plain-text name for the generating agent, as a string
717; uri: URI relevant to the agent, as a string
718; version: version of the generating agent, as a string
719
720==== Icon & Logo constructors
721
722<procedure>(make-icon uri)</procedure>
723
724Create an atom:icon element, which represents iconic visual identification for the feed.
725URI should be a URI string pointing to the icon image.
726
727<procedure>(make-logo uri)</procedure>
728
729Create an atom:logo element, which represents visual identification for the feed.
730URI should be a URI string pointing to the logo image.  Compare to {{make-icon}}.
731
732==== ID constructor
733
734IDs are plain strings, and will be automatically converted to
735{{atom:id}} elements when passed to {{make-feed}} or {{make-entry}}.
736No constructors are currently provided.
737
738Each unique entry and feed must contain a unique {{atom:id}}, which
739must be an absolute URI.  One option is to use the permalink of your entry
740or feed in this field.  Another is to use a [[http://www.faqs.org/rfcs/rfc4151.html|tag URI]],
741which is generally considered more robust.  An example tag URI for an entry might look like:
742
743 tag:domain.org,2012-12-21:/blog/the-mayans-are-coming
744
745Also see [[http://tools.ietf.org/html/rfc4287#section-4.2.6|The
746"atom:id" Element]] in RFC 4287 for details on {{atom:id}} and e.g.
747[[http://diveintomark.org/archives/2004/05/28/howto-atom-id|these]]
748[[http://starling.us/atom/#GUS-3|tutorials]] for ideas on ID creation.
749Note that tag URIs have some important restrictions on which characters are valid.
750
751==== Category constructor
752
753<procedure>(make-category #!key term scheme label)</procedure>
754
755Create an atom:category element representing the feed or entry category.
756
757; term : (''required'') category name, as a string
758; scheme : URI that identifies a categorization scheme, as a string
759; label : human-readable plain-text label for the category, as a string
760
761==== Link constructor
762
763<procedure>(make-link #!key uri relation title ...)</procedure>
764
765Create an atom:link element representing a reference from an entry or feed
766to a Web resource.
767
768; uri : (''required'') the URI (@href) of the link
769; relation : (default "alternate") the link relation type (@rel) as a string; see below
770; title : human-readable, plain-text title for the link, as a string
771; type : advisory MIME media type for the referenced resource, as a string or MIME-type symbol
772; length : advisory length in octets for the referenced resource, as an exact integer
773; uri-language : an [[http://tools.ietf.org/html/rfc3066|RFC3066]] language tag (@hreflang) for the referenced resource, as a string
774
775The five common link relations are:
776
777; "alternate" : an alternate version of this resource.  For a feed, it might be a link to your webpage; for an entry, it might be a permalink to your blog entry, with {{type: 'html}}.  Feed readers work better when you include such a link.
778; "self" : a link to this Atom document, usually the URI to your Atom feed with {{type: 'atom}}.
779; "related" : a related link
780; "enclosure" : identifies a "potentially large" external resource; you should provide {{length:}}
781; "via" : a link to the source of the information
782
783For {{type:}}, the currently known MIME-type symbol shortcuts are 'text,
784'html, 'xhtml, and 'atom.  Otherwise, use the full type name as a string.
785
786==== Source constructor
787
788<procedure>(make-source #!key authors categories contributors ...)</procedure>
789
790Create an atom:source element representing the source feed from which
791the containing entry was taken.  This is used by content aggregators
792to preserve metadata about their source feeds. 
793
794See the feed constructor [[#Feed constructor|make-feed]] for the meaning of
795these elements, and then see [[http://tools.ietf.org/html/rfc4287|RFC
7964287]] for what metadata you would typically preserve.
797
798==== Content constructor
799
800<procedure>(make-content content #!key (type 'text) source)</procedure>
801
802Create an atom:content element representing the content of an entry.
803Acceptable values for CONTENT vary according to the value of TYPE.
804
805; type: (default {{'text}}) the MIME media type of the content as a string, or one of the shorthand symbols 'text, 'html or 'xhtml.  See below.
806; source: a source URI the client must dereference to obtain the content, as a string.  In this case, CONTENT is ignored and the element content will be empty.  Use a dummy value for content such as {{#f}} or the empty string.
807
808The content type may be:
809
810; 'text or "text/plain" : a human-readable, plain text string
811; 'html or "text/html" : a string containing HTML markup (which will be escaped for you)
812; 'xhtml or "application/xhtml+xml" : an {{xhtml:div}} element
813; an XML MIME type : an SXML document consisting of a single root node.  An XML MIME type is any MIME type string ending with "/xml" or "+xml", or one of the [[http://tools.ietf.org/html/rfc3023|RFC3023]] XML media types
814; a textual MIME type : a text string; a textual MIME type is any MIME type string starting with "text/"
815; any other MIME type : the content is considered binary, and the user must pass a [[base64]] encoded string as the content.
816
817=== Miscellany
818
819<parameter>(atom-ns-prefixes)</parameter>
820
821An alist of XML namespace prefixes used when reading or writing feeds.
822Most known namespaces relevant to Atom are included, so it is normally
823not necessary to touch this unless you come across an unusual namespace.
824
825A symptom of a missing namespace is that on read, some feed elements
826are qualified with a full URI instead of a prefix abbreviation, and on
827write that some are qualified with namespace 'prfx1:' or the like.
828
829=== Examples
830
831Creating the "extensive" example feed from RFC4287:
832
833<enscript language="scheme">
834(use atom rfc3339)
835(write-atom-doc
836 (make-atom-doc
837  (make-feed
838   title: (make-title "dive into mark")
839   subtitle: (make-subtitle "A <em>lot</em> of effort went into making this effortless"
840                            type: 'html)
841   updated: "2005-07-31T12:29:29Z"
842   id: "tag:example.org,2003:3"
843   links: (list (make-link type: 'html
844                           uri-language: "en"
845                           uri: "http://example.org")
846                (make-link relation: "self"
847                           type: "application/atom+xml"
848                           uri: "http://example.org/feed.atom"))
849   rights: (make-rights "Copyright (c) 2003, Mark Pilgrim")
850   generator: (make-generator "Example Toolkit"
851                              uri: "http://www.example.com"
852                              version: "1.0")
853   entries: (list
854             (make-entry
855              title: (make-title "Atom draft-07 snapshot")
856              links: (list (make-link type: 'html
857                                      uri: "http://example.org/2005/04/02/atom")
858                           (make-link relation: "enclosure"
859                                      type: "audio/mpeg"
860                                      length: 1337
861                                      uri: "http://example.org/audio/ph34r_my_podcast.mp3"))
862              id: "tag:example.org,2003:3.2397"
863              updated: (rfc3339->string (make-rfc3339 2005 07 31 12 29 29 0 0))
864              published: (rfc3339->string (make-rfc3339 2003 12 13 08 29 29 0 (* 3600 4)))
865              authors: (list (make-author name: "Mark Pilgrim"
866                                          uri: "http://example.org"
867                                          email: "f8dy@example.com"))
868              contributors: (list (make-contributor
869                                   name: "Sam Ruby")
870                                  (make-contributor
871                                   name: "Joe Gregorio"))
872              ;; xml:base, xml:lang cannot be handled yet
873              content: (make-content
874                        '(xhtml:div
875                          (xhtml:p (xhtml:i "[Update: The Atom draft is finished.]")))
876                        type: 'xhtml))))))
877</enscript>
878
879<enscript>
880<?xml version="1.0" encoding="utf-8"?>
881<feed xmlns="http://www.w3.org/2005/Atom">
882  <generator uri="http://www.example.com"
883             version="1.0">Example Toolkit</generator>
884  <id>tag:example.org,2003:3</id>
885  <link href="http://example.org" rel="alternate"
886        type="text/html" hreflang="en" />
887  <link href="http://example.org/feed.atom"
888        rel="self" type="application/atom+xml" />
889  <rights type="text">Copyright (c) 2003, Mark Pilgrim</rights>
890  <subtitle type="html">A &lt;em&gt;lot&lt;/em&gt; of effort
891    went into making this effortless</subtitle>
892  <title type="text">dive into mark</title>
893  <updated>2005-07-31T12:29:29Z</updated>
894  <entry>
895    <author>
896      <name>Mark Pilgrim</name>
897      <uri>http://example.org</uri>
898      <email>f8dy@example.com</email>
899    </author>
900    <contributor>
901      <name>Sam Ruby</name>
902    </contributor>
903    <contributor>
904      <name>Joe Gregorio</name>
905    </contributor>
906    <content type="xhtml">
907      <div xmlns="http://www.w3.org/1999/xhtml">
908        <p>
909          <i>[Update: The Atom draft is finished.]</i>
910        </p>
911      </div>
912    </content>
913    <id>tag:example.org,2003:3.2397</id>
914    <published>2003-12-13T08:29:29-04:00</published>
915    <title type="text">Atom draft-07 snapshot</title>
916    <updated>2005-07-31T12:29:29Z</updated>
917    <link href="http://example.org/2005/04/02/atom"
918          rel="alternate" type="text/html" />
919    <link href="http://example.org/audio/ph34r_my_podcast.mp3"
920          rel="enclosure" type="audio/mpeg" length="1337" />
921  </entry>
922</feed>
923</enscript>
924=== Known Issues
925
926* {{xml:base}} and {{xml:lang}} are not supported, either on reading or writing.
927  You can add these attributes manually to the output document for writing, but
928  for reading the parser will not understand them and relative URLs will not
929  be resolved.
930* Elements outside the {{atom:}} namespace, such as {{feedburner:}}, will repeatedly declare their
931  prefix mapping in the element itself instead of in the root element, leading to
932  a large amount of redundant verbosity.
933* Dealing with extension elements and attributes is a bit painful as you must manipulate the SXML directly.
934
935=== About this egg
936
937==== Source
938
939[[https://github.com/ursetto/atom-egg]]
940
941==== Author
942
943[[http://3e8.org|Jim Ursetto]]
944
945==== Version history
946
947; 0.1.3 : Add Chicken 5 support. Convert test examples to real tests.
948; 0.1.2 : Fix missing regex dependency
949; 0.1.1 : Use default namespace for atom and xhtml
950; 0.1 : Initial release
951
952==== License
953
954BSD.
Note: See TracBrowser for help on using the repository browser.