Index: book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book.module,v retrieving revision 1.310 diff -u -p -r1.310 book.module --- book.module 29 Jul 2005 07:13:25 -0000 1.310 +++ book.module 23 Aug 2005 22:23:57 -0000 @@ -61,11 +61,10 @@ function book_link($type, $node = 0, $ma $links[] = l(t('add child page'), "node/add/book/parent/$node->nid"); } $links[] = l(t('printer-friendly version'), 'book/export/html/'. $node->nid, array('title' => t('Show a printer-friendly version of this book page and its sub-pages.'))); - $links[] = l(t('export DocBook XML'), 'book/export/docbook/'. $node->nid, array('title' => t('Export this book page and its sub-pages as DocBook XML.'))); + $links[] = l(t('export Drupal XML'), 'book/export/dxml/'. $node->nid, array('title' => t('Export this book page and its sub-pages as Drupal XML (suitable for re-import)'))); $links[] = l(t('export OPML'), 'book/export/opml/'. $node->nid, array('title' => t('Export this book page and its sub-pages as OPML.'))); } } - return $links; } @@ -633,85 +632,129 @@ function book_render() { /** * Menu callback; Generates various representation of a book page with * all descendants and prints the requested representation to output. - * - * Notes: For HTML output, the given node is /embedded to its absolute - * depth in a top level section/. For example, a child node with - * depth 2 in the hierarchy is contained in (otherwise empty)
- * elements corresponding to depth 0 and depth 1. This is intended to - * support WYSIWYG output - e.g., level 3 sections always look like - * level 3 sections, no matter their depth relative to the node - * selected to be exported as printer-friendly HTML. - * - * DocBook XML and OPML outputs do not attempt to embed a node to its - * absolute level in the parent book. - - * For DocBook output, the exported node will be a document fragment - * unless the node is a level 0 node (book), specifically - * - * - * For OPML output, the exported node will be the top level element - * in the OPML outline. - * + * + * The function delegates the generation of output to helper functions. + * The function name is derived by prepending 'book_export_' to the + * given output type. So, e.g., a type of 'html' results in a call to + * the function book_export_html(). + * * @param type * - a string encoding the type of output requested. - * The following types are supported: - * 1) HTML (printer friendly output) - * 2) DocBook XML - * 3) OPML (Outline Processor Markup Language) outlines + * The following types are currently supported: + * html: HTML (printer friendly output) + * dxml: Drupal book XML + * opml: OPML (Outline Processor Markup Language) outlines * @param nid * - an integer representing the node id (nid) of the node to export * */ function book_export($type = 'html', $nid = 0) { - global $base_url; $type = drupal_strtolower($type); $depth = _book_get_depth($nid); - switch ($type) { - case 'docbook': - $xml = "\n"; - $xml .= "\n"; - $xml .= book_recurse($nid, $depth, 'book_node_visitor_xml_pre', 'book_node_visitor_xml_post'); - drupal_set_header('Content-Type: text/xml; charset=utf-8'); - print $xml; - break; - case 'html': - for ($i = 1; $i < $depth; $i++) { - $output .= "
\n"; - } - $output .= book_recurse($nid, $depth, 'book_node_visitor_html_pre', 'book_node_visitor_html_post'); - for ($i = 1; $i < $depth; $i++) { - $output .= "
\n"; - } - $html = "\n"; - $html .= ''; - $html .= "\n". check_plain($node->title) ."\n"; - $html .= ''; - $html .= '' . "\n"; - $html .= "\n"; - $html .= "\n\n". $output . "\n\n\n"; - print $html; - break; - case 'opml': - $output .= book_recurse($nid, $depth, 'book_node_visitor_opml_pre', 'book_node_visitor_opml_post'); - $ompl = "\n"; - $opml .= "\n"; - $opml .= "\n". check_plain($node->title) ."\n"; - $opml .= "\n\n". $output . "\n\n\n"; - drupal_set_header('Content-Type: text/xml; charset=utf-8'); - print $opml; - break; + + $export_function = 'book_export_' . $type; + + if (function_exists($export_function)) { + print call_user_func($export_function, $nid, $depth); } } /** + * This function is called by book_export() to generate HTML for export. + * + * The given node is /embedded to its absolute depth in a top level + * section/. For example, a child node with depth 2 in the hierarchy + * is contained in (otherwise empty) <div> elements + * corresponding to depth 0 and depth 1. This is intended to support + * WYSIWYG output - e.g., level 3 sections always look like level 3 + * sections, no matter their depth relative to the node selected to be + * exported as printer-friendly HTML. + * + * @param nid + * - an integer representing the node id (nid) of the node to export + * @param depth + * - an integer giving the depth in the book hierarchy of the node + which is to be exported + * @return + * - the HTML representing the node and its children in the book hierarchy +*/ +function book_export_html($nid, $depth) { + global $base_url; + for ($i = 1; $i < $depth; $i++) { + $output .= "
\n"; + } + $output .= book_recurse($nid, $depth, 'book_node_visitor_html_pre', 'book_node_visitor_html_post'); + for ($i = 1; $i < $depth; $i++) { + $output .= "
\n"; + } + $html = "\n"; + $html .= ''; + $html .= "\n". check_plain($node->title) ."\n"; + $html .= ''; + $html .= '' . "\n"; + $html .= "\n"; + $html .= "\n\n". $output . "\n\n\n"; + return $html; +} + +/** + * This function is called by book_export() to generate DXML for export. + * + * The function also calls drupal_set_header() to set a header suitable + * for returning XML content. + * + * @param nid + * - an integer representing the node id (nid) of the node to export + * @param depth + * - an integer giving the depth in the book hierarchy of the node + which is to be exported + * @return + * - the DXML representing the node and its children in the book hierarchy +*/ +function book_export_dxml($nid, $depth) { + drupal_set_header('Content-Type: text/xml; charset=utf-8'); + $xml = "\n"; + $xml .= "\n"; + $xml .= book_recurse($nid, $depth, 'book_node_visitor_dxml_pre', 'book_node_visitor_dxml_post'); + return $xml; +} + +/** + * This function is called by book_export() to generate OPML for export. + * + * Unlike HTML output, OPML output is not embedded to its absolute + * level in the parent book. The exported node will be the top level + * element in the OPML outline. + * + * The function also calls drupal_set_header() to set a header suitable + * for returning XML content. + * + * @param nid + * - an integer representing the node id (nid) of the node to export + * @param depth + * - an integer giving the depth in the book hierarchy of the node + which is to be exported + * @return + * - the OPML representing the node and its children in the book + * hierarchy. Only titles are exported. + +*/ +function book_export_opml($nid, $depth) { + drupal_set_header('Content-Type: text/xml; charset=utf-8'); + $output .= book_recurse($nid, $depth, 'book_node_visitor_opml_pre', 'book_node_visitor_opml_post'); + $ompl = "\n"; + $opml .= "\n"; + $opml .= "\n". check_plain($node->title) ."\n"; + $opml .= "\n\n". $output . "\n\n\n"; + return $opml; +} + +/** * Given a node, this function returns the depth of the node in its hierarchy. * A root node has depth 1, and children of a node of depth n have depth (n+1). * - * @param node - * - the node whose depth to compute. + * @param nid + * - the nid of the node whose depth to compute. * @return * - the depth of the given node in its hierarchy. Returns 0 if the node * does not exist or is not part of a book hierarchy. @@ -835,91 +878,102 @@ function book_node_visitor_html_post($no return "
\n"; } + /** * Generates XML for a given node. This function is a 'pre-node' - * visitor function for book_recurse(). The generated XML is valid - * DocBook, but each node's HTML content is wrapped in a CDATA - * section, and put inside a element. The node body - * has an md5-hash applied; the value of this is stored as node - * metadata to allow importing code to determine if contents have - * changed. The weight of a node is also stored as metadata to - * allow the node to be properly re-imported. + * visitor function for book_recurse(). The generated XML consists + * of nested <node> elements. Each Drupal node's HTML content + * is wrapped in a CDATA section. The node body has an md5-hash + * applied; the value of this is stored as node metadata to allow + * importing code to determine if contents have changed. The weight + * of a node is also stored as metadata to allow the node to be + * properly re-imported. * * @param $node * - the node to generate output for. * @param $depth - * - the depth of the given node in the hierarchy. This - * is currently not used. + * - the depth of the given node in the hierarchy. * @param $nid * - the node id (nid) of the given node. This * is used only for generating output (e.g., id attribute) * @return * - the generated XML for the given node. */ -function book_node_visitor_xml_pre($node, $depth, $nid) { - // Output the content: - if (node_hook($node, 'content')) { - $node = node_invoke($node, 'content'); +function book_node_visitor_dxml_pre($node, $depth, $nid) { + + $revision = book_revision_load($node); + if ($revision) { + $node = $revision; } // Allow modules to change $node->body before viewing. node_invoke_nodeapi($node, 'export_xml', $node->body, false); - $releaseinfo = "\n"; - $releaseinfo .= "md5-hash:" . md5($node->body) . "\n"; - $releaseinfo .= "weight:". $node->weight . "\n"; - $releaseinfo .= "depth:". $depth . "\n"; - $releaseinfo .= "\n"; - $title = "". check_plain($node->title) ."\n"; // wrap the node body in a CDATA declaration - $content = ""; + $content = "\n"; $content .= "body) { $content .= $node->body; } - $content .= "]]>"; - $content .= "\n"; + $content .= "]]>\n"; + $content .= "\n"; - if ($depth == 1) { - $output .= "\n"; - $output .= $title; - $output .= "\n$releaseinfo\n"; - $output .= "\n"; - $output .= "Preface\n"; - $output .= $content; - $output .= "\n"; - } - else if ($depth == 2) { - $output .= "nid ."\">\n"; - $output .= "\n$releaseinfo\n"; - $output .= $title; - $output .= $content; - } - else { - $output .= "
nid ."\">\n"; - $output .= "\n$releaseinfo\n"; - $output .= $title; - $output .= $content; + // wrap the teaser in a CDATA declaration + $teaser = "\n"; + $teaser .= "body) { + $teaser .= $node->teaser; } + $teaser .= "]]>\n"; + $teaser .= "\n"; + + $output = "nid ."\">\n"; + + // now store metadata + $output .= "body) . "'"; + $output .= " weight='$node->weight'"; + $output .= " depth='$depth'"; + $output .= " type='$node->type'"; + $output .= " author='".get_author($node->uid)."'"; + $output .= " uid='$node->uid'"; + $output .= " created='$node->created'"; + $output .= " status='$node->status'"; + $output .= " format='$node->format'"; + $output .= " sticky='$node->sticky'"; + $output .= " promote='$node->promote'"; + $output .= "/>\n"; + + $output .= $title; + $output .= $teaser; + $output .= $content; return $output; } +function get_author($uid) { + static $users = array(); + global $user_cache_stats; + + $username = ""; + if (is_string($users[$uid]) && $users[$uid] != '') { + $username = $users[$uid]; + } + else { + $user = user_load (array('uid' => $uid)); + $username = $user->name; + $users[$uid] = $username; + } + return $username; +} + /** * Completes the XML generation for the node. This function is a * 'post-node' visitor function for book_recurse(). */ -function book_node_visitor_xml_post($node, $depth) { - if ($depth == 1) { - return "\n"; - } - else if ($depth == 2) { - return "\n"; - } - else { - return "
\n"; - } +function book_node_visitor_dxml_post($node, $depth) { + return "\n"; } /** @@ -1097,7 +1151,7 @@ function book_help($section) { block administration page.

-

Users can select the \"printer-friendly version\" link visible at the bottom of a book page to generate a printer-friendly display of the page and all of its subsections. They can choose to export the page and its subsections as DocBook XML (for offline editing, or production of print or other electronic publication formats) by selecting the \"export DocBook XML\" link. DocBook export currently treats node content as preformatted text. Selecting the \"export OPML\" link will generate an outline document (titles only) in OPML format, readable by many outline editing tools. Note: it may be neccessary to shift-click on the link to save the results to a file on the local computer.

+

Users can select the \"printer-friendly version\" link visible at the bottom of a book page to generate a printer-friendly display of the page and all of its subsections. They can choose to export the page and its subsections as Drupal XML (for offline editing, or to move books between sites) by selecting the \"export Drupal XML\" link. Selecting the \"export OPML\" link will generate an outline document (titles only) in OPML format, readable by many outline editing tools. Note: it may be neccessary to shift-click on the link to save the results to a file on the local computer.

Administrators can view a book outline, from which is it possible to change the titles of sections, and their weight (thus reordering sections). From this outline, it is also possible to edit and/or delete book pages. Many content types besides pages (for example, blog entries, stories, and polls) can be added to a collaborative book by choosing the \"outline\" tab when viewing the post.