Like RSS only more so. Wikipedia . Comparison with RSS 2.0 .
HE: Defined in http://www.ietf.org/rfc/rfc4287
q3cpma 2021-03-27:
Here's a little module to create and update Atom feeds using tDOM that I made to use in two of my projects: mangadex-tools and haggle . Except a little ternary helper I left in, it is standalone.
# Simple Atom reading/writing, exported procs: # create, read, add_entry, write package require tdom # Ternary proc ? {test a {b ""}} { tailcall if $test [list subst $a] [list subst $b] } namespace eval atom { namespace export create read read_or_create add_entry write namespace ensemble create variable xmlns http://www.w3.org/2005/Atom proc timestamp {} { clock format [clock seconds] -format %Y-%m-%dT%XZ -timezone :UTC } # nodespec: {tag ?text? ?attrname attrval...?} # Use {tag {} attrname attrval...} if you want an attribute but no text proc node {doc nodespec} { variable xmlns set attrs [lassign $nodespec tag text] set node [$doc createElementNS $xmlns $tag] if {$text ne ""} { $node appendChild [$doc createTextNode $text] } if {$attrs ne ""} { $node setAttribute {*}$attrs } return $node } # args: node's nodespec proc add {doc node args} { $node appendChild [node $doc $args] } # Wrapper around domNode selectNodes proc select_nodes {doc args} { variable xmlns [$doc documentElement] selectNodes -namespaces [list atom $xmlns] \ {*}$args } # Ignore id for local feeds (a file:// URI will be used) proc create {path title {id {}}} { variable xmlns set path [file normalize $path] set atom [dict create path $path entry_count 0 modified 1] set doc [dom createDocumentNS $xmlns feed] dict set atom xml $doc set root [$doc documentElement] add $doc $root title $title add $doc $root id [? {$id ne ""} {$id} {file://$path}] add $doc $root updated [timestamp] return $atom } proc read {path} { set atom [dict create path [file normalize $path] modified 0] set chan [open $path] set doc [dom parse [read $chan]] close $chan dict set atom xml $doc dict set atom entry_count [llength [select_nodes $doc //atom:entry]] return $atom } proc read_or_create {path title} { if {[file exists $path]} { read $path } else { set ret [create $path $title] atom write $ret return $ret } } proc write {atom} { if {[dict get $atom modified]} { set chan [open [dict get $atom path] w] puts $chan [[dict get $atom xml] asXML -indent 2] close $chan } } # Add an entry to the feed in the _atom variable # args is a dictionary containing the optional values for keys id, content # and link; no id means local feed, thus a unique URI based on feed path # and entry count will be used proc add_entry {_atom title args} { upvar $_atom atom set doc [dict get $atom xml] set id [if {[dict exists $args id]} { \ dict get $args id \ } else { \ string cat "file://[dict get $atom path]#[dict get $atom entry_count]" \ }] set timestamp [timestamp] set entry [node $doc entry] add $doc $entry title $title add $doc $entry id $id add $doc $entry updated $timestamp if {[dict exists $args content]} { add $doc $entry content [dict get $args content] type html } if {[dict exists $args link]} { add $doc $entry link {} href [dict get $args link] } [$doc documentElement] appendChild $entry dict incr atom entry_count dict set atom modified 1 [select_nodes $doc //atom:feed/atom:updated/text()] nodeValue $timestamp } }
An example:
source atom.tcl set feed [atom read_or_create atom.xml "My blog"] atom add_entry feed "Article 1" \ content "Content of article 1" \ link "http://myblog.net/2021/03/article_1.html" \ id "http://myblog.net/2021/03/article_1.html" atom write $feed