<?php
/**
* This is the way MOBI files should be created if you want all features (TOC, images).
*
* File modified by Dawson for use in eBook Creator
* Added pagebreaks and a setting to remove table of contents.
*/
class MOBIFile extends ContentProvider {
const PARAGRAPH = 0;
const H2 = 1;
const H3 = 2;
const IMAGE = 3;
const PAGEBREAK = 4;
private $settings = array("title" => "Unknown Title", "toc" => true);
private $parts = array();
private $images = array();
/**
* Get the text data (the "html" code)
*/
public function getTextData(){
$prefix = "<html><head><guide><reference title='CONTENT' type='toc' filepos=0000000000 /></guide></head><body>";
$title = "<h1>".$this->settings["title"]."</h1>";
list($text, $entries) = $this->generateText();
if($this->settings["toc"]) {
$toc = $this->generateTOC($entries); //Generate TOC to get the right length
$toc = $this->generateTOC($entries, strlen($prefix)+strlen($toc)+strlen($title)); //Generate the real TOC
}
$suffix = "</body></html>";
return $prefix.$toc.$title.$text.$suffix;
}
/**
* Generate the body's text and the chapter entries
* @return array($string, $entries) $string is the html data, $entries
* contains the level, the title and the position of the titles.
*/
public function generateText(){
$str = "";
$entries = array();
for($i = 0; $i < sizeof($this->parts); $i++){
list($type, $data) = $this->parts[$i];
$id = "title_".$i;
switch($type){
case self::PARAGRAPH:
$str .= "<p>".$data."</p>";
break;
case self::PAGEBREAK:
$str .= '<mbp:pagebreak/>';
break;
case self::H2:
$entries[] = array("level" => 2, "position" => strlen($str), "title" => $data, "id" => $id);
$str .= "<h2 id='" . $id . "'>".$data."</h2>";
break;
case self::H3:
$entries[] = array("level" => 3, "position" => strlen($str), "title" => $data, "id" => $id);
$str .= "<h3 id='" . $id . "'>".$data."</h3>";
break;
case self::IMAGE:
$str .= "<img recindex=".str_pad($data+1, 10, "0", STR_PAD_LEFT)." />";
break;
}
}
return array($str, $entries);
}
/**
* Generate a TOC
* @param $entries The entries array generated by generateText
* @param $base The zero position
*/
public function generateTOC($entries, $base = 0){
$toc = "<h2>Contents</h2>";
$toc .= "<blockquote><table summary='Table of Contents'><col/><tbody>";
for($i = 0, $len = sizeof($entries); $i < $len; $i++){
$entry = $entries[$i];
$pos = str_pad($entry["position"]+$base, 10, "0", STR_PAD_LEFT);
$toc .= "<tr><td><a href='#".$entry["id"]."' filepos='".$pos."'>".$entry["title"]."</a></td></tr>";
}
return $toc."</tbody></b></table></blockquote><mbp:pagebreak/>";
}
/**
* Get the file records of the images
*/
public function getImages(){
return $this->images;
}
/**
* Get the metadata
*/
public function getMetaData(){
return $this->settings;
}
/**
* Change the file's settings. For example set("author", "John Doe") or set("title", "The adventures of John Doe").
* @param $key Key of the setting to insert.
*/
public function set($key, $value){
$this->settings[$key] = $value;
}
/**
* Get the file's settings.
*/
public function get($key){
return $this->settings[$key];
}
/**
* Append a paragraph of text to the file.
* @param string $text The text to insert.
*/
public function appendParagraph($text){
$this->parts[] = array(self::PARAGRAPH, $text);
}
/**
* Append a chapter title (H2)
* @param string $title The title to insert.
*/
public function appendChapterTitle($title){
$this->parts[] = array(self::H2, $title);
}
/**
* Append a section title (H3)
* @param string $title The title to insert.
*/
public function appendSectionTitle($title){
$this->parts[] = array(self::H3, $title);
}
public function appendPageBreak() {
$this->parts[] = array(self::PAGEBREAK, null);
}
/**
* Append an image.
* @param resource $img An image file (for example, created by `imagecreate`)
*/
public function appendImage($img){
$imgIndex = sizeof($this->images);
$this->images[] = new FileRecord(new Record(ImageHandler::CreateImage($img)));
$this->parts[] = array(self::IMAGE, $imgIndex);
}
}