Optionally create a new book page at each html heading and subheading (<h1>, <h2>, etc) in the body text. This makes it possible to use documents created in word processing programs to automatically create a multi-page Drupal book or book section in a single step. To use this feature, click on the input split collapsible box below the book body in the edit form.

All text before the first heading will be retained as the body of the original page. Subsequent pages will be added as children of that page, using the heading as their title and all text from that point to the next heading as their body. Child pages will be nested based on the subheadding number, i.e. h2 pages will be nested below the h1 page they follow, h3 pages will be nested below h2 pages, etc. Each new book page will have the same author, categories, and other settings selected in the original page.

If the source is a word processing document, be sure it has been saved as html rather than as a word processing document so the HTML2Book module can locate the headings in the text. Microsoft Word documents pasted into the body should be saved as \'Html, filtered\' for best results.

'); $output .= t('EXAMPLE:
INPUT:

Node 1 Title: My Book
Node 1 Body:
<div>Here is my page.</div>
<h1>Page 1</h1>
  <p>Here is my text for page 1.</p>
  <h2>Page 1a</h2>
    <p>This is page 1a.</p>
  <h2>Page 1b</h2>
    <p>This is page 1b.</p>
<h1>Page 2</h1>
  <p>This is page 2.</p>

CREATES:

Node 1 Title: My Book
Node 1 Body: <div>Here is my page.</div>
Node 1 Parent: <top level>
Node 1 Weight: -15

    Node 2 Title: Page 1
    Node 2 Body: <p>Here is my text for page 1.</p>
    Node 2 Parent: Node 1
    Node 2 Weight: -15

       Node 3 Title: Page 1a
       Node 3 Body: <p>This is page 1a.</p>
       Node 3 Parent: Node 2
       Node 3 Weight: -15

       Node 4 Title: Page 1b
       Node 4 Body: <p>This is page 1b.</p>
       Node 4 Parent: Node 2
       Node 4 Weight: -14

    Node 5 Title: Page 2
    Node 5 Body: <p>This is page 2.</p>
    Node 5 Parent: Node 1
    Node 5 Weight: -14
    
'); return $output; break; } } /** * Implementation of hook_perm(). */ function html2book_perm() { return array('use html2book'); } /** * Implementation of hook_form_alter(). */ function html2book_form_alter(&$form, $form_state, $form_id) { if ($form_id == 'book_node_form' && user_access('use html2book')) { $form['html2book_group'] = array( '#type' => 'fieldset', '#title' => t('Input split'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['html2book_group']['html2book'] = array( '#type' => 'radios', '#title' => t('Heading treatment'), '#description' => t('Should the input text be !help at each HTML heading?', array('!help' => l(t('split into new book pages'), 'admin/help/html2book'))), '#default_value' => $form['html2book'] ? $form['html2book'] : 0, '#options' => array(0 => t('Do not split input text.'), 1 => t('Create a new book page at each HTML heading.')), ); } } /** * Implementation of hook_nodeapi(). */ function html2book_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) { if ($node->type == 'book' && $node->html2book && user_access('use html2book')) { switch ($op) { case 'presave': $items = preg_split('//U', $node->body, -1, PREG_SPLIT_DELIM_CAPTURE ); $node->temp = $node->body; $node->body = $items[0]; $node->teaser = node_teaser($node->body); break; case 'insert': html2book_split($node); unset($node->temp); break; } } } /** * html2book operation. */ function html2book_split(&$node) { // This may take some time since new nodes are created. $original_time = ini_get('max_execution_time'); ini_set('max_execution_time', 0); // Break body into separate pages wherever there is a heading. $items = preg_split('//U', $node->temp, -1, PREG_SPLIT_DELIM_CAPTURE ); // Track heading levels, weights, and page parents and children. $istag = FALSE; $weight[0] = -15; $prev_level = 0; foreach ($items as $item) { if ($istag) { $parts = explode(' ', $item); $level = $parts[0]; } else { if (isset($level)) { $string = ''. $item; $split = explode('', $string); $title = trim(str_replace(' ', ' ', strip_tags($split[0]))); $body = trim($split[1]); } else { // If $level isn't set, this is the body text that preceeds the first heading. // This will become the parent node's body text. $title = ''; $body = $item; } if (!empty($title) || !empty($body) || !isset($parent)) { if (!isset($parent)) { // The first time through, make sure we have a nid for the parent // and adjust the parent body and teaser. $parent = array(0 => $node->nid); $book = array(0 => $node); $page = 1; } else { // After the first time through, clone the parent as a starting point for child nodes. $child_node = drupal_clone($node); // Set the child nid and vid to zero so new nodes are created. $child_node->nid = 0; $child_node->vid = 0; // Make sure the title is not empty and create the child's body, teaser, and weight. $child_node->title = !empty($title) ? $title : t('Page !$page', array('!page' => $page)); $child_node->body = $body; $child_node->teaser = node_teaser($body); if ($level > $prev_level || !isset($weight[$level])) { $weight[$level] = -15; } else { $weight[$level]++; } //$child_node->weight = $weight[$level]; $child_node->book['weight'] = $weight[$level]; // Find the parent id for this node using the value stored for the // next higher level. $parent_level = intval($level - 1); $child_node->parent = !empty($parent[$parent_level]) ? $parent[$parent_level] : $node->nid; $child_node->book['bid'] = $parent[0]; $child_node->book['menu_name'] = $book[0]->book['menu_name']; $child_node->book['plid'] = $book[$parent_level]->book['mlid']; // Make sure html2book is not run again on the child nodes that are created. $child_node->html2book = 0; // Save the child node. node_save($child_node); // Set a parent nid for this level that can be used by later children. $parent[$level] = $child_node->nid; $book[$level] = $child_node; $page++; } } } $istag = !$istag; $prev_level = $level; } // Make sure html2book isn't run more than once on the same text. $node->html2book = 0; // Reset max_execution_time ini_set('max_execution_time', $original_time); }