function update_quickbook($refresh = false)
    {
        $pages = $this->load_pages();
        if (!$refresh) {
            $pages->scan_for_new_quickbook_pages();
            $pages->save();
        }
        // Translate new and changed pages
        $pages->convert_quickbook_pages($refresh);
        // Extract data for generating site from $pages:
        $released_versions = array();
        $beta_versions = array();
        $all_versions = array();
        $all_downloads = array();
        $news = array();
        foreach ($pages->reverse_chronological_pages() as $page) {
            switch ($page->section) {
                case 'news':
                    if ($page->is_published()) {
                        $news[] = $page;
                    }
                    break;
                case 'history':
                    if ($page->is_published()) {
                        $all_versions[] = $page;
                    }
                    if ($page->is_published('released')) {
                        $all_downloads[] = $page;
                        $released_versions[] = $page;
                        $news[] = $page;
                    } else {
                        if ($page->is_published('beta')) {
                            $beta_versions[] = $page;
                        }
                    }
                    break;
                case 'downloads':
                    if ($page->is_published('released')) {
                        $all_downloads[] = $page;
                    }
                    break;
                default:
                    echo "Unknown website section: {$page->section}.\n";
                    break;
            }
        }
        $downloads = array_filter(array($this->get_downloads('live', 'Current', $released_versions, 1), $this->get_downloads('beta', 'Beta', $beta_versions)));
        $index_page_variables = array('released_versions' => $released_versions, 'all_versions' => $all_versions, 'news' => $news, 'downloads' => $downloads);
        // Generate 'Index' pages
        BoostPages::write_template("{$this->root}/generated/download-items.html", __DIR__ . '/templates/download.php', $index_page_variables);
        BoostPages::write_template("{$this->root}/generated/history-items.html", __DIR__ . '/templates/history.php', $index_page_variables);
        BoostPages::write_template("{$this->root}/generated/news-items.html", __DIR__ . '/templates/news.php', $index_page_variables);
        BoostPages::write_template("{$this->root}/generated/home-items.html", __DIR__ . '/templates/index.php', $index_page_variables);
        # Generate RSS feeds
        if (!$refresh) {
            $rss = new BoostRss($this->root, "generated/state/rss-items.txt");
            $rss->generate_rss_feed(array('path' => 'generated/downloads.rss', 'link' => 'users/download/', 'title' => 'Boost Downloads', 'pages' => $all_downloads, 'count' => 3));
            $rss->generate_rss_feed(array('path' => 'generated/history.rss', 'link' => 'users/history/', 'title' => 'Boost History', 'pages' => $released_versions));
            $rss->generate_rss_feed(array('path' => 'generated/news.rss', 'link' => 'users/news/', 'title' => 'Boost News', 'pages' => $news, 'count' => 5));
            $rss->generate_rss_feed(array('path' => 'generated/dev.rss', 'link' => '', 'title' => 'Release notes for work in progress boost', 'pages' => $all_versions, 'count' => 5));
        }
        # Create a list of release in reverse version order
        #
        # This is normally the default order, but it's possible that a point
        # release might be released after a later major release.
        $releases_by_version = $released_versions;
        usort($releases_by_version, function ($x, $y) {
            $x_has_version = array_key_exists('version', $x->release_data);
            $y_has_version = array_key_exists('version', $y->release_data);
            if (!$x_has_version) {
                return $y_has_version ? 1 : 0;
            }
            if (!$y_has_version) {
                return -1;
            }
            return $y->release_data['version']->compare($x->release_data['version']);
        });
        $latest_version = $releases_by_version[0]->release_data['version'];
        # Write out the current version for reference
        file_put_contents(__DIR__ . '/../../generated/current_version.txt', $latest_version);
        # Update doc/.htaccess
        $final_doc_dir = $latest_version->final_doc_dir();
        $redirect_block = "# REDIRECT_UPDATE_START\n";
        $redirect_block .= "#\n";
        $redirect_block .= "# This section is automatically updated.\n";
        $redirect_block .= "# Any edits will be overwritten.\n";
        $redirect_block .= "#\n";
        $redirect_block .= "# Redirect from symbolic names to current versions.\n";
        $redirect_block .= "RewriteRule ^libs/release(/.*)?\\\$ libs/{$final_doc_dir}\\\$1 [R=303]\n";
        $redirect_block .= "RewriteRule ^libs/development(/.*)?\\\$ libs/{$final_doc_dir}\\\$1 [R=303]\n";
        $redirect_block .= "#\n";
        $redirect_block .= "# REDIRECT_UPDATE_END\n";
        $htaccss_file = __DIR__ . '/../../doc/.htaccess';
        $htaccess = file_get_contents($htaccss_file);
        $count = 0;
        $htaccess = preg_replace('@^# REDIRECT_UPDATE_START$.*^# REDIRECT_UPDATE_END$\\n@ms', $redirect_block, $htaccess, -1, $count);
        if ($count != 1) {
            throw new BoostException("Error updating doc/.htaccess");
        }
        file_put_contents($htaccss_file, $htaccess);
        # Generate documentation list
        $documentation_list = <<<EOL
  <h4><a href="/doc/" class="internal">Documentation <span class=
  "link">&gt;</span></a></h4>

  <ul>
    <li><a href="/doc/libs/release/more/getting_started/">Getting Started
    <span class="link">&gt;</span></a></li>

    <li>
      <a href="/doc/libs">Libraries <span class="link">&gt;</span></a>

      <ul>
EOL;
        $first = true;
        foreach ($releases_by_version as $page) {
            if (array_key_exists('documentation', $page->release_data)) {
                $version = $page->release_data['version'];
                $documentation_list .= "\n";
                $documentation_list .= "        <li><a href=\"";
                $documentation_list .= "/doc/libs/{$version->final_doc_dir()}/";
                $documentation_list .= "\" rel=\"nofollow\">{$version}";
                if ($first) {
                    $documentation_list .= " - Current\n";
                    $documentation_list .= "        Release <span class=\"link\">&gt;</span></a></li>\n";
                    $first = false;
                } else {
                    $documentation_list .= " <span class=\n";
                    $documentation_list .= "        \"link\">&gt;</span></a></li>\n";
                }
            }
        }
        $documentation_list .= <<<EOL
      </ul>
    </li>

    <li>
      <a href="/doc/tools.html">Tools <span class="link">&gt;</span></a>

      <ul>
        <li><a href="/build/">Boost Build <span class=
        "link">&gt;</span></a></li>

        <li><a href="/tools/regression/">Regression <span class=
        "link">&gt;</span></a></li>

        <li><a href="/tools/inspect/">Inspect <span class=
        "link">&gt;</span></a></li>

        <li><a href="/doc/html/boostbook.html">BoostBook <span class=
        "link">&gt;</span></a></li>

        <li><a href="/tools/quickbook/">QuickBook <span class=
        "link">&gt;</span></a></li>

        <li><a href="/tools/bcp/">bcp <span class=
        "link">&gt;</span></a></li>

        <li><a href="/libs/wave/doc/wave_driver.html">Wave <span class=
        "link">&gt;</span></a></li>

        <li><a href="/tools/auto_index/">AutoIndex <span class=
        "link">&gt;</span></a></li>
      </ul>
    </li>
  </ul>

EOL;
        file_put_contents(__DIR__ . '/../../generated/menu-doc.html', $documentation_list);
        $pages->save();
    }
 function update_quickbook($refresh = false)
 {
     $pages = $this->load_pages();
     if (!$refresh) {
         $this->scan_for_new_quickbook_pages($pages);
     }
     // Translate new and changed pages
     $pages->convert_quickbook_pages($refresh);
     // Generate 'Index' pages
     $downloads = array();
     foreach (BoostPageSettings::$downloads as $x) {
         $entries = $pages->match_pages($x['matches'], null, true);
         if (isset($x['count'])) {
             $entries = array_slice($entries, 0, $x['count']);
         }
         if ($entries) {
             $y = array('anchor' => $x['anchor'], 'entries' => $entries);
             if (count($entries) == 1) {
                 $y['label'] = $x['single'];
             } else {
                 $y['label'] = $x['plural'];
             }
             $downloads[] = $y;
         }
     }
     $index_page_variables = compact('pages', 'downloads');
     foreach (BoostPageSettings::$index_pages as $index_page => $template) {
         BoostPages::write_template("{$this->root}/{$index_page}", __DIR__ . '/' . $template, $index_page_variables);
     }
     # Generate RSS feeds
     if (!$refresh) {
         $rss_items = BoostState::load("{$this->root}/generated/state/rss-items.txt");
         foreach (BoostPageSettings::$feeds as $feed_file => $feed_data) {
             $rss_feed = $this->rss_prefix($feed_file, $feed_data);
             $feed_pages = $pages->match_pages($feed_data['matches']);
             if (isset($feed_data['count'])) {
                 $feed_pages = array_slice($feed_pages, 0, $feed_data['count']);
             }
             foreach ($feed_pages as $qbk_page) {
                 $item_xml = null;
                 if ($qbk_page->loaded) {
                     $item = $this->generate_rss_item($qbk_page->qbk_file, $qbk_page);
                     $item['item'] = self::fragment_to_string($item['item']);
                     $rss_items[$qbk_page->qbk_file] = $item;
                     BoostState::save($rss_items, "{$this->root}/generated/state/rss-items.txt");
                     $rss_feed .= $item['item'];
                 } else {
                     if (isset($rss_items[$qbk_page->qbk_file])) {
                         $rss_feed .= $rss_items[$qbk_page->qbk_file]['item'];
                     } else {
                         echo "Missing entry for {$qbk_page->qbk_file}\n";
                     }
                 }
             }
             $rss_feed .= $this->rss_postfix($feed_file, $feed_data);
             $output_file = fopen("{$this->root}/{$feed_file}", 'wb');
             fwrite($output_file, $rss_feed);
             fclose($output_file);
         }
     }
     $pages->save();
 }