<?php
/* ====================================================================
* Copyright (c) 2000 Steven Haryanto. All rights reserved.
*
* StoryPager
* A PHP module to do automatic story paging
*
* This module is released under the GNU General Public License. See:
* http://www.gnu.org/copyleft/gpl.html
*
* Version
* 0.011, Wed Dec 13 03:24:45 2000
*
* For latest version and example, visit:
* http://steven.haryan.to/php/StoryPager.html
*
* ====================================================================
*
*/
class StoryPager {
function StoryPager() {
// default values
$this->nb_tag = "<!-- NOBREAK -->";
$this->mb_tag = "<!-- BREAK -->";
$this->even_paging = 1;
}
// whether to do even paging
function even_paging($value) {
if (isset($value)) $this->even_paging = $value;
return $this->even_paging;
}
// target number of pages
function target_nop($value) {
if (isset($value)) $this->target_nop = $value;
return $this->target_nop;
}
// optimum page length, in bytes
function optimum_pl($value) {
if (isset($value)) $this->optimum_pl = $value;
return $this->optimum_pl;
}
// string to look for to prevent breaking/paging the whole story
function nb_tag($value) {
if (isset($value)) $this->nb_tag = $value;
return $this->nb_tag;
}
// string to look for doing manual breaking
function mb_tag($value) {
if (isset($value)) $this->mb_tag = $value;
return $this->mb_tag;
}
// do the split
function split($content) {
$this->pages = array();
// should we break at all?
if (preg_match("/\Q$this->nb_tag/is", &$content)) {
push($this->pages, &$content);
return;
}
// if yes, should we manual-break?
if (preg_match("/\Q$this->mb_tag/is", &$content)) {
$this->pages = preg_split("/\Q$this->mb_tag/is", &$content);
return;
}
// if no manual break is specified, try to do automatic paging
$content_length = strlen(&$content);
if (!$this->even_paging) {
if (!$this->optimum_pl) {
die("You must specify desired page length (optimum_pl)");
}
if ($this->target_nop) {
$pl = round(strlen(&$content)/$this->target_nop);
} else {
$pl = $this->optimum_pl;
}
} else {
if ($this->target_nop) {
$nop = $this->target_nop;
} else if ($this->optimum_pl) {
$nop = round($content_length/$this->optimum_pl);
} else {
die("At least specify target number of pages (target_nop) ".
"or optimum page length (optimum_pl)");
}
if ($nop == 0) $nop=1;
$pl = round($content_length/$nop);
}
$lines = explode("\n", &$content);
$in_table = 0;
$in_pre = 0;
$offset = 0;
$cur_offset = 0;
$distance = 0;
$index = 0;
$this->pages[$index] = '';
foreach ($lines as $line) {
$linebr = $line . "\n";
$len = strlen(&$linebr);
$p_tag=0;
$p_tag = preg_match("/<\/?p>/i", &$line);
preg_match_all("/<pre>/i", &$line, $m); $in_pre += sizeof($m[0]);
preg_match_all("/<table/i", &$line, $m); $in_table += sizeof($m[0]);
$offset += $len;
// is it time to start a new page?
if (
$in_pre <= 0 && $in_table <= 0 &&
($p_tag || !preg_match("/\S/", $line)) &&
(!$this->target_nop || $index+1 < $this->target_nop) &&
($cur_offset > 0.75*$pl) && // don't let a page be too short
$offset > $pl*($index+1)
) {
++$index;
$this->pages[$index] = $linebr;
$cur_offset = 0;
} else { // nope, keep writing to the current page
$this->pages[$index] .= $linebr;
$cur_offset += $len;
}
preg_match_all("/<\/pre>/i", &$line, $m); $in_pre -= sizeof($m[0]);
preg_match_all("/<\/table>/i", &$line, $m); $in_table -= sizeof($m[0]);
}
// remove last page if empty
// if (!preg_match("/\S/", $this->pages[$index])) array_pop($this->pages);
}
// retrieve the number of pages
function nop() {
return sizeof($this->pages);
}
// retrieve the pages
function &page($index) {
return $this->pages[$index-1];
}
} // class
?> |