Index: modules/book/book.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.module,v
retrieving revision 1.406.2.2
diff -u -p -r1.406.2.2 book.module
--- modules/book/book.module	13 May 2009 19:41:56 -0000	1.406.2.2
+++ modules/book/book.module	11 Oct 2009 20:37:42 -0000
@@ -76,6 +76,13 @@ function book_link($type, $node = NULL, 
           'attributes' => array('title' => t('Show a printer-friendly version of this book page and its sub-pages.'))
         );
       }
+      if (user_access('access content')) {
+        $links['book_feed'] = array(
+          'title' => t('Feed'),
+          'href' => 'book/feed/'. $node->nid,
+          'attributes' => array('title' => t('Access a feed of all changes below that page in the book hierarchy.'))
+        );
+      }
     }
   }
 
@@ -119,6 +126,12 @@ function book_menu($may_cache) {
       'type' => MENU_CALLBACK);
   }
   else {
+    $items[] = array(
+      'path' => 'book/feed',
+      'callback' => 'book_feed',
+      'access' => user_access('access content'),
+      'type' => MENU_CALLBACK);
+
     // Add the CSS for this module
     // We put this in !$may_cache so it's only added once per request
     drupal_add_css(drupal_get_path('module', 'book') .'/book.css');
@@ -675,7 +688,7 @@ function book_export($type = 'html', $ni
  * @return
  *   - string containing HTML representing the node and its children in
  *     the book hierarchy
-*/
+ */
 function book_export_html($nid, $depth) {
   if (user_access('see printer-friendly version')) {
     $node = node_load($nid);
@@ -705,7 +718,7 @@ function theme_book_export_html($title, 
   $html .= "\n<head>\n";
   $html .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
   $html .= "\n<title>". $title ."</title>\n";
-  $html .= '<base href="'. $base_url .'/" />' . "\n";
+  $html .= '<base href="'. $base_url .'/" />'."\n";
   $html .= "<style type=\"text/css\">\n@import url(misc/print.css);\n</style>\n";
   $html .= "</head>\n<body>\n". $content ."\n</body>\n</html>\n";
   return $html;
@@ -863,7 +876,7 @@ function theme_book_admin_table($form) {
       drupal_render($form[$key]['weight']),
       l(t('view'), 'node/'. $nid),
       l(t('edit'), 'node/'. $nid .'/edit'),
-      l(t('delete'), 'node/'. $nid .'/delete', NULL, 'destination=admin/content/book'. (arg(3) == 'orphan' ? '/orphan' : '') . ($pid != $nid ? '/'.$pid : ''))
+      l(t('delete'), 'node/'. $nid .'/delete', NULL, 'destination=admin/content/book'. (arg(3) == 'orphan' ? '/orphan' : '') . ($pid != $nid ? '/'. $pid : ''))
     );
   }
 
@@ -1001,3 +1014,40 @@ function book_help($section) {
 }
 
 
+function book_feed_pre($node) {
+  $pub_date = date(DATE_RSS, $node->changed);
+  return format_rss_item(
+    $node->title,
+    url("node/$node->nid", NULL, NULL, TRUE),
+    strip_tags($node->teaser),
+    array('pubDate' => $pub_date)
+  );
+}
+
+function book_feed_post($node) {
+  return NULL ; //"post $node->nid ";
+}
+
+/**
+ * Generates a RSS feed for the pages of the book below the page at the
+ * passed-in nid, with a depth of $depth
+ *
+ * @param int $nid 0 is invalid
+ * @param int $depth 0 means unlimited
+ * @return string RSS 2.0 feed
+ */
+function book_feed($nid, $depth = 0) {
+  global $base_url;
+
+  $namespaces = array('xmlns:dc="http://purl.org/dc/elements/1.1/"');
+  $items = book_recurse($nid, $depth, 'book_feed_pre', 'book_feed_post');
+  $node = node_load($nid);
+
+  $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+    ."<rss version=\"2.0\" xml:base=\"$base_url\" ". implode(' ', $namespaces) .">\n"
+    . format_rss_channel($node->title, url('node/'. $nid), $node->teaser, $items)
+    ."</rss>\n";
+  drupal_set_header('Content-Type: application/rss+xml; charset=utf-8');
+  print $output;
+  die();
+}
