diff --git a/.gitignore b/.gitignore index 7598a1f5c..f8ecc3509 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ output tags -vendor *.swp *.tgz *.tar diff --git a/composer.json b/composer.json index cc9df81bd..7e41f7058 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ } ], "require": { - "php": ">=5.3.0", + "php": ">=5.6", "ext-dom": "*", "ext-sqlite3": "*", "ext-xmlreader": "*" @@ -27,8 +27,14 @@ "easybook/geshi": "For using GeSHi as code highlighter" }, "autoload": { - "psr-0": { - "phpdotnet\\": "." + "files": ["src/functions.php"], + "psr-4": { + "phpdotnet\\phd\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "phpdotnet\\phd\\Tests\\": "tests/" } } } diff --git a/composer.lock b/composer.lock index 437da44da..654f65ca6 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0a86baeef26e4be1985b6083fa956efe", + "content-hash": "cdaa121cc1abeadc0ca97d3244204222", "packages": [], "packages-dev": [], "aliases": [], @@ -13,10 +13,11 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.3.0", + "php": ">=5.6", "ext-dom": "*", "ext-sqlite3": "*", "ext-xmlreader": "*" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.0.0" } diff --git a/phpdotnet/phd/Autoloader.php b/phpdotnet/phd/Autoloader.php deleted file mode 100644 index 05f1c40b9..000000000 --- a/phpdotnet/phd/Autoloader.php +++ /dev/null @@ -1,36 +0,0 @@ - 'Package_IDE_XML', - 'funclist' => 'Package_IDE_Funclist', - 'json' => 'Package_IDE_JSON', - 'php' => 'Package_IDE_PHP', - 'phpstub' => 'Package_IDE_PHPStub', - 'sqlite' => 'Package_IDE_SQLite', - ); - - /** - * The package version - */ - private $version = '@phd_ide_version@'; - - public function __construct() { - parent::setPackageName("IDE"); - parent::setPackageVersion($this->version); - parent::registerOutputFormats($this->formats); - } -} - -/* -* vim600: sw=4 ts=4 syntax=php et -* vim<600: sw=4 ts=4 -*/ diff --git a/phpdotnet/phd/Package/PHP/Factory.php b/phpdotnet/phd/Package/PHP/Factory.php deleted file mode 100644 index 6b61f1da9..000000000 --- a/phpdotnet/phd/Package/PHP/Factory.php +++ /dev/null @@ -1,35 +0,0 @@ - 'Package_PHP_ChunkedXHTML', - 'bigxhtml' => 'Package_PHP_BigXHTML', - 'php' => 'Package_PHP_Web', - 'howto' => 'Package_PHP_HowTo', - 'manpage' => 'Package_PHP_Manpage', - 'pdf' => 'Package_PHP_PDF', - 'bigpdf' => 'Package_PHP_BigPDF', - 'kdevelop' => 'Package_PHP_KDevelop', - 'chm' => 'Package_PHP_CHM', - 'tocfeed' => 'Package_PHP_TocFeed', - 'epub' => 'Package_PHP_Epub', - 'enhancedchm' => 'Package_PHP_EnhancedCHM', - ); - - /** - * The package version - */ - private $version = '@phd_php_version@'; - - public function __construct() { - parent::setPackageName("PHP"); - parent::setPackageVersion($this->version); - parent::registerOutputFormats($this->formats); - } -} - -/* -* vim600: sw=4 ts=4 syntax=php et -* vim<600: sw=4 ts=4 -*/ diff --git a/render.php b/render.php index 4b97bcb64..c6f7a599b 100644 --- a/render.php +++ b/render.php @@ -4,13 +4,16 @@ // @php_dir@ gets replaced by pear with the install dir. use __DIR__ when // running from SVN -define("__INSTALLDIR__", '@php_dir@' == '@'.'php_dir@' ? __DIR__ : '@php_dir@'); +use phpdotnet\phd\Format\Factory; +use phpdotnet\phd\Options\Parser; +use phpdotnet\phd\Reader\Partial; -require __INSTALLDIR__ . '/phpdotnet/phd/Autoloader.php'; -require __INSTALLDIR__ . '/phpdotnet/phd/functions.php'; +define("__INSTALLDIR__", '@php_dir@' == '@'.'php_dir@' ? __DIR__ : '@php_dir@'); -spl_autoload_register(array(__NAMESPACE__ . "\\Autoloader", "autoload")); +require_once __INSTALLDIR__ . '/vendor/autoload.php'; +$olderrrep = error_reporting(); +error_reporting($olderrrep | VERBOSE_DEFAULT); $conf = array(); if (file_exists("phd.config.php")) { @@ -22,7 +25,7 @@ Config::init(array()); } -Options_Parser::getopt(); +Parser::getopt(); /* If no docbook file was passed, die */ if (!is_dir(Config::xml_root()) || !is_file(Config::xml_file())) { @@ -40,9 +43,8 @@ // This needs to be moved. Preferably into the PHP package. if (!$conf) { Config::init(array( - "lang_dir" => __INSTALLDIR__ . DIRECTORY_SEPARATOR . "phpdotnet" . DIRECTORY_SEPARATOR - . "phd" . DIRECTORY_SEPARATOR . "data" . DIRECTORY_SEPARATOR - . "langs" . DIRECTORY_SEPARATOR, + "lang_dir" => __INSTALLDIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR + . "data" . DIRECTORY_SEPARATOR . "langs" . DIRECTORY_SEPARATOR, "phpweb_version_filename" => Config::xml_root() . DIRECTORY_SEPARATOR . 'version.xml', "phpweb_acronym_filename" => Config::xml_root() . DIRECTORY_SEPARATOR . 'entities' . DIRECTORY_SEPARATOR . 'acronyms.xml', )); @@ -62,7 +64,7 @@ function make_reader() { $idlist = Config::render_ids() + Config::skip_ids(); if (!empty($idlist)) { v("Running partial build", VERBOSE_RENDER_STYLE); - $reader = new Reader_Partial(); + $reader = new Partial(); } else { v("Running full build", VERBOSE_RENDER_STYLE); $reader = new Reader(); @@ -97,7 +99,7 @@ function make_reader() { } foreach((array)Config::package() as $package) { - $factory = Format_Factory::createFactory($package); + $factory = Factory::createFactory($package); // Default to all output formats specified by the package if (count(Config::output_format()) == 0) { diff --git a/phpdotnet/phd/Config.php b/src/Config.php similarity index 98% rename from phpdotnet/phd/Config.php rename to src/Config.php index 686870a98..1f4f5bc76 100644 --- a/phpdotnet/phd/Config.php +++ b/src/Config.php @@ -143,7 +143,7 @@ public static function __callStatic($name, $params) public static function getSupportedPackages() { $packageList = array(); foreach(Config::package_dirs() as $dir) { - foreach (glob($dir . "/phpdotnet/phd/Package/*", GLOB_ONLYDIR) as $item) { + foreach (glob($dir . "/src/Package/*", GLOB_ONLYDIR) as $item) { $baseitem = basename($item); if ($baseitem[0] != '.') { $packageList[] = $baseitem; diff --git a/phpdotnet/phd/Format.php b/src/Format.php similarity index 100% rename from phpdotnet/phd/Format.php rename to src/Format.php diff --git a/phpdotnet/phd/Format/Factory.php b/src/Format/Factory.php similarity index 82% rename from phpdotnet/phd/Format/Factory.php rename to src/Format/Factory.php index 0e6e54888..c1046017c 100644 --- a/phpdotnet/phd/Format/Factory.php +++ b/src/Format/Factory.php @@ -1,7 +1,10 @@ optionsHandler; } - public final function registerOptionsHandler(Options_Interface $optionsHandler) { + public final function registerOptionsHandler(OptionsInterface $optionsHandler) { $this->optionsHandler = $optionsHandler; } @@ -41,7 +44,7 @@ public final function getPackageName() { public final function createFormat($format) { if (isset($this->formats[$format]) && $this->formats[$format]) { - $classname = __NAMESPACE__ . "\\" . $this->formats[$format]; + $classname = "phpdotnet\\phd\\Package\\" . $this->formats[$format]; $obj = new $classname(); if (!($obj instanceof Format)) { @@ -60,11 +63,11 @@ public static final function createFactory($package) { } if (!isset($factories[$package])) { - $classname = __NAMESPACE__ . "\\Package_" . $package . "_Factory"; + $classname = 'phpdotnet\\phd\\Package\\' . $package . '\\Factory'; $factory = new $classname(); - if (!($factory instanceof Format_Factory)) { - throw new \Exception("All Factories must inherit Format_Factory"); + if (!($factory instanceof Factory)) { + throw new \Exception("All Factories must inherit Format\Factory"); } $factories[$package] = $factory; } diff --git a/phpdotnet/phd/Format/Abstract/Manpage.php b/src/Format/Manpage.php similarity index 92% rename from phpdotnet/phd/Format/Abstract/Manpage.php rename to src/Format/Manpage.php index 845e185f2..652949636 100644 --- a/phpdotnet/phd/Format/Abstract/Manpage.php +++ b/src/Format/Manpage.php @@ -1,7 +1,9 @@ pdfDoc; + } + + public function setPdfDoc($pdfDoc) { + $this->pdfDoc = $pdfDoc; + } + + public function UNDEF($open, $name, $attrs, $props) { + if ($open) { + trigger_error("No mapper found for '{$name}'", E_USER_WARNING); + } + $this->pdfDoc->setFont(PdfWriter::FONT_NORMAL, 14, array(1, 0, 0)); // Helvetica 14 red + $this->pdfDoc->appendText(($open ? "<" : "") . $name . ">"); + $this->pdfDoc->revertFont(); + return ""; + } + + public function CDATA($str) { + $this->pdfDoc->appendText(utf8_decode(trim($str))); + return ""; + } + + public function transformFromMap($open, $tag, $name, $attrs, $props) { + return ""; + } + + public function createLink($for, &$desc = null, $type = Format::SDESC){} + + public function TEXT($str) {} + +} diff --git a/phpdotnet/phd/Format/Abstract/PDF.php b/src/Format/PdfWriter.php similarity index 93% rename from phpdotnet/phd/Format/Abstract/PDF.php rename to src/Format/PdfWriter.php index 5aea11f6b..06f824d6b 100644 --- a/phpdotnet/phd/Format/Abstract/PDF.php +++ b/src/Format/PdfWriter.php @@ -1,912 +1,876 @@ -pdfDoc; - } - - public function setPdfDoc($pdfDoc) { - $this->pdfDoc = $pdfDoc; - } - - public function UNDEF($open, $name, $attrs, $props) { - if ($open) { - trigger_error("No mapper found for '{$name}'", E_USER_WARNING); - } - $this->pdfDoc->setFont(PdfWriter::FONT_NORMAL, 14, array(1, 0, 0)); // Helvetica 14 red - $this->pdfDoc->appendText(($open ? "<" : "") . $name . ">"); - $this->pdfDoc->revertFont(); - return ""; - } - - public function CDATA($str) { - $this->pdfDoc->appendText(utf8_decode(trim($str))); - return ""; - } - - public function transformFromMap($open, $tag, $name, $attrs, $props) { - return ""; - } - - public function createLink($for, &$desc = null, $type = Format::SDESC){} - - public function TEXT($str) {} - -} - -class PdfWriter { - // Font type constants (for setFont()) - const FONT_NORMAL = 0x01; - const FONT_ITALIC = 0x02; - const FONT_BOLD = 0x03; - const FONT_VERBATIM = 0x04; - const FONT_VERBATIM_ITALIC = 0x05; - const FONT_MANUAL = 0x06; - - // "Objects" constants (for add()) - const PARA = 0x10; - const INDENTED_PARA = 0x11; - const TITLE = 0x12; - const DRAW_LINE = 0x13; - const LINE_JUMP = 0x14; - const PAGE = 0x15; - const TITLE2 = 0x16; - const VERBATIM_BLOCK = 0x17; - const ADMONITION = 0x18; - const ADMONITION_CONTENT = 0x19; - const END_ADMONITION = 0x1A; - const URL_ANNOTATION = 0x1B; - const LINK_ANNOTATION = 0x1C; - const ADD_BULLET = 0x1D; - const FRAMED_BLOCK = 0x1E; - const END_FRAMED_BLOCK = 0x1F; - const TITLE3 = 0x20; - const TABLE = 0x21; - const TABLE_ROW = 0x22; - const TABLE_ENTRY = 0x23; - const TABLE_END_ENTRY = 0x24; - const END_TABLE = 0x25; - const TABLE_END_ROW = 0x26; - const ADD_NUMBER_ITEM = 0x27; - const IMAGE = 0x28; - - // Page format - const VMARGIN = 56.7; // = 1 centimeter - const HMARGIN = 56.7; // = 1 centimeter - const LINE_SPACING = 2; // nb of points between two lines - const INDENT_SPACING = 10; // nb of points for indent - const DEFAULT_SHIFT = 20; // default value (points) for shifted paragraph - private $SCALE; // nb of points for 1 centimeter - private $PAGE_WIDTH; // in points - private $PAGE_HEIGHT; // in points - - private $haruDoc; - private $pages = array(); - private $currentPage; - private $currentPageNumber; - private $currentBookName; - - private $currentFont; - private $currentFontSize; - private $currentFontColor; - private $fonts; - private $oldFonts = array(); - private $text; - - private $vOffset = 0; - private $hOffset = 0; - private $lastPage = array( - "vOffset" => 0, - "hOffset" => 0, - ); - private $permanentLeftSpacing = 0; - private $permanentRightSpacing = 0; - - private $appendToBuffer = false; - // To append afterwards - private $buffer = array( - /* array( - 'text' => "", - 'font' => "", - 'size' => "", - 'color' => "", - )*/ - ); - - private $current = array( - "leftSpacing" => 0, - "rightSpacing" => 0, - "oldVPosition" => 0, - "vOffset" => 0, - "newVOffset" => 0, - "pages" => array(), - "row" => array(), - "align" => "", - "char" => "", - "charOffset" => 0, - ); - - // To temporarily store $current(s) - private $old = array(); - - function __construct($pageWidth = 210, $pageHeight = 297) { - // Initialization of properties - $this->haruDoc = new \HaruDoc; - $this->haruDoc->addPageLabel(1, \HaruPage::NUM_STYLE_DECIMAL, 1, "Page "); - - $this->haruDoc->setPageMode(\HaruDoc::PAGE_MODE_USE_OUTLINE); - $this->haruDoc->setPagesConfiguration(2); - - // Page format - $this->SCALE = 72/25.4; - $this->PAGE_WIDTH = $pageWidth * $this->SCALE; - $this->PAGE_HEIGHT = $pageHeight * $this->SCALE; - - // Set fonts - $this->fonts["Helvetica"] = $this->haruDoc->getFont("Helvetica", "WinAnsiEncoding"); - $this->fonts["Helvetica-Bold"] = $this->haruDoc->getFont("Helvetica-Bold", "WinAnsiEncoding"); - $this->fonts["Helvetica-Oblique"] = $this->haruDoc->getFont("Helvetica-Oblique", "WinAnsiEncoding"); - $this->fonts["Courier"] = $this->haruDoc->getFont("Courier", "WinAnsiEncoding"); - $this->fonts["Courier-Oblique"] = $this->haruDoc->getFont("Courier-Oblique", "WinAnsiEncoding"); - - // Add first page and default font settings - $this->currentFont = $this->fonts["Helvetica"]; - $this->currentFontSize = 12; - $this->currentFontColor = array(0, 0, 0); // Black - $this->nextPage(); - $this->haruDoc->addPageLabel(1, \HaruPage::NUM_STYLE_DECIMAL, 1, "Page "); - } - - public function getCurrentPage() { - return $this->currentPage; - } - - public function setCompressionMode($mode) { - $this->haruDoc->setCompressionMode($mode); - } - - // Append text into the current position - public function appendText($text) { -// if ($this->vOffset > $this->current["charOffset"] + 3*LINE_SPACING + 3*$this->currentFontSize) -// $this->vOffset = $this->current["charOffset"] + 3*LINE_SPACING + 3*$this->currentFontSize; - if ($this->appendToBuffer) { - array_push($this->buffer, array( - "text" => $text, - "font" => $this->currentFont, - "size" => $this->currentFontSize, - "color" => $this->currentFontColor - )); - return; - } - - $this->currentPage->beginText(); - do { - // Clear the whitespace if it begins the line or if last char is a special char - if (strpos($text, " ") === 0 && ($this->hOffset == 0 || in_array($this->current["char"], array("&", "$")))) { - $text = substr($text, 1); - } - - // Number of chars allowed in the current line - $nbCarac = $this->currentFont->measureText($text, - ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->hOffset - $this->permanentLeftSpacing - $this->permanentRightSpacing), - $this->currentFontSize, $this->currentPage->getCharSpace(), - $this->currentPage->getWordSpace(), true); - - // If a the text content can't be appended (either there is no whitespaces, - // either the is not enough space in the line) - if ($nbCarac === 0) { - $isEnoughSpaceOnNextLine = $this->currentFont->measureText($text, - ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->permanentLeftSpacing - $this->permanentRightSpacing), - $this->currentFontSize, $this->currentPage->getCharSpace(), - $this->currentPage->getWordSpace(), true); - if ($isEnoughSpaceOnNextLine) { - $this->vOffset += $this->currentFontSize + self::LINE_SPACING; - $this->hOffset = 0; - $isLastLine = false; - continue; - } else { - $nbCarac = $this->currentFont->measureText($text, - ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->hOffset - $this->permanentLeftSpacing - $this->permanentRightSpacing), - $this->currentFontSize, $this->currentPage->getCharSpace(), - $this->currentPage->getWordSpace(), false); - } - } - $isLastLine = ($nbCarac == strlen($text)); - - $textToAppend = substr($text, 0, $nbCarac); - $text = substr($text, $nbCarac); - - // Append text (in a new page if needed) with align - if ($this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset) < self::VMARGIN) { - $this->currentPage->endText(); - $this->current["pages"][] = $this->currentPage; - $this->nextPage(); - $this->currentPage->beginText(); - } - if ($this->current["align"] == "center") { - $spacing = $this->PAGE_WIDTH - 2*self::HMARGIN - - $this->permanentLeftSpacing - $this->permanentRightSpacing - $this->currentPage->getTextWidth($textToAppend); - $this->currentPage->textOut(self::HMARGIN + $this->hOffset + $this->permanentLeftSpacing + $spacing/2, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset), $textToAppend); - } elseif ($this->current["align"] == "right") { - $spacing = $this->PAGE_WIDTH - 2*self::HMARGIN - - $this->permanentLeftSpacing - $this->permanentRightSpacing - $this->currentPage->getTextWidth($textToAppend); - $this->currentPage->textOut(self::HMARGIN + $this->hOffset + $this->permanentLeftSpacing + $spacing, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset), $textToAppend); - } else { // left - $this->currentPage->textOut(self::HMARGIN + $this->hOffset + $this->permanentLeftSpacing, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset), $textToAppend); - } - if ($textToAppend) - $this->current["char"] = $textToAppend{strlen($textToAppend)-1}; - - // Offsets for next line - if (!$isLastLine) { - $this->vOffset += $this->currentFontSize + self::LINE_SPACING; - $this->hOffset = 0; - } else { - $this->hOffset += $this->currentPage->getTextWidth($textToAppend); - } - - } - while(!$isLastLine); // While it remains chars to append - $this->currentPage->endText(); - $this->current["charOffset"] = $this->vOffset; - } - - // Same function one line at a time - public function appendOneLine($text) { - if (strpos($text, " ") === 0 && ($this->hOffset == 0 || in_array($this->current["char"], array("&", "$")))) { - $text = substr($text, 1); - } - - $this->currentPage->beginText(); - $nbCarac = $this->currentFont->measureText($text, - ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->hOffset - $this->permanentLeftSpacing - $this->permanentRightSpacing), - $this->currentFontSize, $this->currentPage->getCharSpace(), - $this->currentPage->getWordSpace(), true); - - // If a the text content can't be appended (either there is no whitespaces, - // either the is not enough space in the line) - if ($nbCarac === 0) { - $isEnoughSpaceOnNextLine = $this->currentFont->measureText($text, - ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->permanentLeftSpacing - $this->permanentRightSpacing), - $this->currentFontSize, $this->currentPage->getCharSpace(), - $this->currentPage->getWordSpace(), true); - if ($isEnoughSpaceOnNextLine) { - $this->currentPage->endText(); - return $text; - } else { - $nbCarac = $this->currentFont->measureText($text, - ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->hOffset - $this->permanentLeftSpacing - $this->permanentRightSpacing), - $this->currentFontSize, $this->currentPage->getCharSpace(), - $this->currentPage->getWordSpace(), false); - } - } - - $isLastLine = ($nbCarac == strlen($text)); - - $textToAppend = substr($text, 0, $nbCarac); - $text = substr($text, $nbCarac); - - // Append text (in a new page if needed) - if ($this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset) < self::VMARGIN) { - $this->currentPage->endText(); - $this->current["pages"][] = $this->currentPage; - $this->nextPage(); - $this->currentPage->beginText(); - } - $this->currentPage->textOut(self::HMARGIN + $this->hOffset + $this->permanentLeftSpacing, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset), $textToAppend); - if ($textToAppend) - $this->current["char"] = $textToAppend{strlen($textToAppend)-1}; - - $this->hOffset += $this->currentPage->getTextWidth($textToAppend); - - $this->currentPage->endText(); - $this->current["charOffset"] = $this->vOffset; - - return ($isLastLine ? null : $text); - } - - public function setAppendToBuffer($appendToBuffer) { - $this->appendToBuffer = $appendToBuffer; - } - - public function appendBufferNow() { - foreach($this->buffer as $row) { - if ($row["text"] == "\n") { - $this->lineJump(); - } else { - $this->setFont(self::FONT_MANUAL, $row["size"], $row["color"], $row["font"]); - $this->appendText($row["text"]); - $this->revertFont(); - } - } - $this->buffer = array(); - } - - public function add($type, $option = null) { - if ($this->appendToBuffer) return; - switch ($type) { - case self::INDENTED_PARA: - $this->lineJump(); - $this->indent(); - break; - case self::PARA: - $this->lineJump(); - break; - case self::VERBATIM_BLOCK: - $this->setFont(self::FONT_VERBATIM, 10, array(0.3, 0.3, 0.3)); - $this->lineJump(); - break; - case self::TITLE: - $this->setFont(self::FONT_BOLD, 20); - $this->lineJump(); - break; - case self::TITLE2: - $this->setFont(self::FONT_BOLD, 14); - $this->lineJump(); - break; - case self::TITLE3: - $this->setFont(self::FONT_BOLD, 12); - $this->lineJump(); - break; - case self::DRAW_LINE: - $this->traceLine($option); - break; - case self::LINE_JUMP: - if ($option) - $this->lineJump($option); - else $this->lineJump(); - break; - case self::PAGE: - $this->nextPage(); - break; - case self::ADMONITION: - $this->beginAdmonition(); - break; - case self::ADMONITION_CONTENT: - $this->admonitionContent(); - break; - case self::END_ADMONITION: - $this->endAdmonition(); - break; - case self::URL_ANNOTATION: - $this->appendUrlAnnotation($option[0], $option[1]); - break; - case self::LINK_ANNOTATION: - return $this->prepareInternalLinkAnnotation($option); - break; - case self::ADD_BULLET: - $this->indent(-self::INDENT_SPACING-$this->currentPage->getTextWidth(chr(149))); - $this->appendText(chr(149)); // ANSI Bullet - $this->indent(0); - break; - case self::ADD_NUMBER_ITEM: - $this->indent(-self::INDENT_SPACING-$this->currentPage->getTextWidth($option)); - $this->appendText($option); - $this->indent(0); - break; - case self::FRAMED_BLOCK: - $this->beginFrame(); - break; - case self::END_FRAMED_BLOCK: - $this->endFrame($option); - break; - case self::TABLE: - $this->addTable($option); - break; - case self::END_TABLE: - $this->endTable(); - break; - case self::TABLE_ROW: - $this->newTableRow($option[0], $option[1]); - break; - case self::TABLE_END_ROW: - $this->endTableRow(); - break; - case self::TABLE_ENTRY: - $this->beginTableEntry($option[0], $option[1], $option[2]); - break; - case self::TABLE_END_ENTRY: - $this->endTableEntry(); - break; - case self::IMAGE: - $this->addImage($option); - break; - default: - trigger_error("Unknown object type : {$type}", E_USER_WARNING); - break; - } - } - - // Switch font on-the-fly - public function setFont($type, $size = null, $color = null, $font = null) { - if ($this->currentPage == null) - return false; - $this->oldFonts[] = array($this->currentFont, $this->currentFontSize, $this->currentFontColor); - $this->currentFontSize = ($size ? $size : $this->currentFontSize); - if ($color && count($color) === 3) { - $this->setColor($color[0], $color[1], $color[2]); - $this->currentFontColor = $color; - } - else - $this->setColor($this->currentFontColor[0], $this->currentFontColor[1], $this->currentFontColor[2]); - switch ($type) { - case self::FONT_NORMAL: - $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Helvetica"], - $this->currentFontSize); - break; - case self::FONT_ITALIC: - $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Helvetica-Oblique"], - $this->currentFontSize); - break; - case self::FONT_BOLD: - $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Helvetica-Bold"], - $this->currentFontSize); - break; - case self::FONT_VERBATIM: - $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Courier"], - $this->currentFontSize); - break; - case self::FONT_VERBATIM_ITALIC: - $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Courier-Oblique"], - $this->currentFontSize); - break; - case self::FONT_MANUAL: - $this->currentPage->setFontAndSize($this->currentFont = $font, $this->currentFontSize); - break; - default: - trigger_error("Unknown font type : {$type}", E_USER_WARNING); - break; - } - } - - // Back to the last used font - public function revertFont() { - $lastFont = array_pop($this->oldFonts); - $this->currentFont = $lastFont[0]; - $this->currentFontSize = $lastFont[1]; - $this->currentFontColor = $lastFont[2]; - $this->currentPage->setFontAndSize($lastFont[0], $lastFont[1]); - $this->setColor($lastFont[2][0], $lastFont[2][1], $lastFont[2][2]); - } - - // Change font color (1, 1, 1 = white, 0, 0, 0 = black) - public function setColor($r, $g, $b) { - if ($r < 0 || $r > 1 || $g < 0 || $g > 1 || $b < 0 || $b > 1) - return false; - $this->currentPage->setRGBStroke($r, $g, $b); - $this->currentPage->setRGBFill($r, $g, $b); - $this->currentFontColor = array($r, $g, $b); - return true; - } - - // Save the current PDF Document to a file - public function saveToFile($filename) { - $this->haruDoc->save($filename); - } - - public function createOutline($description, $parentOutline = null, $opened = false) { - $outline = $this->haruDoc->createOutline($description, $parentOutline); - $dest = $this->currentPage->createDestination(); - $dest->setXYZ(0, $this->currentPage->getHeight(), 1); - $outline->setDestination($dest); - $outline->setOpened($opened); - return $outline; - } - - public function shift($offset = self::DEFAULT_SHIFT) { - $this->permanentLeftSpacing += $offset; - } - - public function unshift($offset = self::DEFAULT_SHIFT) { - $this->permanentLeftSpacing -= $offset; - } - - public function vOffset($offset) { - $this->vOffset += $offset; - } - - private function indent($offset = self::INDENT_SPACING) { - $this->hOffset = $offset; - } - - // Jump to next page (or create a new one if none exists) - private function nextPage() { - $this->lastPage = array( - "vOffset" => $this->vOffset, - "hOffset" => $this->hOffset, - ); - $footerToAppend = false; - $this->currentPageNumber++; - if (isset($this->pages[$this->currentPageNumber])) { - $this->currentPage = $this->pages[$this->currentPageNumber]; - $this->vOffset = $this->currentFontSize; - $this->hOffset = 0; - } else { - $this->pages[$this->currentPageNumber] = $this->haruDoc->addPage(); - $this->currentPage = $this->pages[$this->currentPageNumber]; - $this->currentPage->setTextRenderingMode(\HaruPage::FILL); - $this->vOffset = $this->currentFontSize; - $this->hOffset = ($this->hOffset ? $this->hOffset : 0); - $footerToAppend = true; - } - if ($this->currentFont && $this->currentFontSize && $this->currentFontColor) { - $this->currentPage->setFontAndSize($this->currentFont, $this->currentFontSize); - $this->setColor($this->currentFontColor[0], $this->currentFontColor[1], $this->currentFontColor[2]); - } - if ($footerToAppend && $this->currentPageNumber > 1) { - $this->currentPage->beginText(); - $this->setFont(self::FONT_NORMAL, 12, array(0,0,0)); - $this->currentPage->textOut($this->PAGE_WIDTH - self::HMARGIN - $this->currentPage->getTextWidth($this->currentPageNumber), - self::VMARGIN - 30, $this->currentPageNumber); - $this->revertFont(); - $this->setFont(self::FONT_BOLD, 12, array(0,0,0)); - $this->currentPage->textOut(self::HMARGIN, - self::VMARGIN - 30, $this->currentBookName); - $this->revertFont(); - $this->currentPage->endText(); - - } - - } - - public function setCurrentBookName($currentBookName) { - $this->currentBookName = $currentBookName; - } - - // Set last page as the current page - private function lastPage() { - $this->currentPageNumber--; - $this->currentPage = $this->pages[$this->currentPageNumber]; - $this->vOffset = $this->lastPage["vOffset"]; - $this->hOffset = $this->lastPage["hOffset"]; - } - - // Returns true if a next page exists - private function isNextPage() { - return isset($this->pages[$this->currentPageNumber + 1]); - } - - // Jump a line - private function lineJump($nbLines = 1) { - $this->vOffset += $nbLines * ($this->currentFontSize + self::LINE_SPACING); - $this->hOffset = 0; - } - - // Trace a line from the current position - private function traceLine() { - $this->lineJump(); - $this->currentPage->rectangle(self::HMARGIN + $this->hOffset, $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset, $this->PAGE_WIDTH - 2*$this->hOffset - 2*self::HMARGIN, 1); - $this->currentPage->stroke(); - } - - private function beginAdmonition() { - // If this admonition is inside another frame - array_push($this->old, $this->current); - - $this->setFont(self::FONT_BOLD, 12); - $this->lineJump(); - // If no space for admonition title + interleave + admonition first line on this page, then creates a new one - if (($this->PAGE_HEIGHT - 2*self::VMARGIN - $this->vOffset) < (3*$this->currentFontSize + 3*self::LINE_SPACING)) - $this->nextPage(); - $this->current["vOffset"] = $this->vOffset; - $this->lineJump(); - $this->permanentLeftSpacing += self::INDENT_SPACING; - $this->permanentRightSpacing += self::INDENT_SPACING; - $this->current["pages"] = array(); - } - - private function admonitionContent() { - if ($this->current["pages"]) - $this->current["vOffset"] = 0; - $this->beginFrame(); - $this->revertFont(); - $this->currentPage->rectangle(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset, - $this->PAGE_WIDTH - 2*self::HMARGIN - ($this->permanentLeftSpacing - self::INDENT_SPACING) - ($this->permanentRightSpacing - self::INDENT_SPACING), - $this->vOffset - $this->current["vOffset"]); - $this->currentPage->stroke(); - } - - private function endAdmonition() { - $this->endFrame(); - $this->permanentLeftSpacing -= self::INDENT_SPACING; - $this->permanentRightSpacing -= self::INDENT_SPACING; - $current = array_pop($this->old); - $current["pages"] = array_merge($current["pages"], $this->current["pages"]); - $this->current = $current; - } - - private function beginFrame() { - $this->lineJump(); - $this->current["newVOffset"] = $this->vOffset; - $this->current["pages"] = array(); - } - - private function endFrame($dash = null) { - $onSinglePage = true; - foreach ($this->current["pages"] as $page) { - $page->setRGBStroke(0, 0, 0); - $page->setLineWidth(1.0); - $page->setDash($dash, 0); - // left border - $page->moveTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), - self::VMARGIN); - $page->lineTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); - // right border - $page->moveTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), - self::VMARGIN); - $page->lineTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); - $page->stroke(); - $page->setDash(null, 0); - $this->current["newVOffset"] = 0; - $onSinglePage = false; - } - $this->currentPage->setRGBStroke(0, 0, 0); - $this->currentPage->setLineWidth(1.0); - $this->currentPage->setDash($dash, 0); - // left border - $this->currentPage->moveTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); - $this->currentPage->lineTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); - // right border - $this->currentPage->moveTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); - $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); - // bottom border - $this->currentPage->moveTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); - $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); - // top border (if frame's on a single page) - if ($onSinglePage) { - $this->currentPage->moveTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); - $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), - $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); - } - - $this->currentPage->stroke(); - $this->lineJump(); - $this->currentPage->setDash(null, 0); - $this->current["oldVPosition"] = 0; - } - - // Append $text with an underlined blue style with a link to $url - private function appendUrlAnnotation($text, $url) { - $this->appendText(" "); - $fromHOffset = $this->hOffset; - - // If more than one text line to append - while ($text = $this->appendOneLine($text)) { - // Trace the underline - $this->currentPage->setLineWidth(1.0); - $this->currentPage->setDash(null, 0); - $this->currentPage->moveTo(self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING)); - $this->currentPage->lineTo(self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING)); - $this->currentPage->stroke(); - - // Create link - $annotationArea = array(self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING), - self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset - $this->currentFontSize)); - $this->currentPage->createURLAnnotation($annotationArea, $url)->setBorderStyle(0, 0, 0); - - // Prepare the next line - $this->vOffset += $this->currentFontSize + self::LINE_SPACING; - $this->hOffset = 0; - $fromHOffset = $this->hOffset; - } - - // Trace the underline - $this->currentPage->setLineWidth(1.0); - $this->currentPage->setDash(null, 0); - $this->currentPage->moveTo(self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING)); - $this->currentPage->lineTo(self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING)); - $this->currentPage->stroke(); - - // Create link - $annotationArea = array(self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING), - self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset - $this->currentFontSize)); - $this->currentPage->createURLAnnotation($annotationArea, $url)->setBorderStyle(0, 0, 0); - - } - - // Append $text with an underlined blue style and prepare an internal link (which will be resolved later) - private function prepareInternalLinkAnnotation($text) { - $this->appendText(" "); - $fromHOffset = $this->hOffset; - $linkAreas = array(/* page, left, bottom, right, top */); - - // If more than one text line to append - while ($text = $this->appendOneLine($text)) { - // Create link - $linkAreas[] = array($this->currentPage, - self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING), - self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset - $this->currentFontSize)); - - // Prepare the next line - $this->vOffset += $this->currentFontSize + self::LINE_SPACING; - $this->hOffset = 0; - $fromHOffset = $this->hOffset; - } - - // Prepare link - $linkAreas[] = array($this->currentPage, - self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING), - self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, - $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset - $this->currentFontSize)); - - return $linkAreas; - } - - public function resolveInternalLink($page, $rectangle, $destPage) { - $page->setRGBStroke(0, 0, 1); // blue - // Trace the underline - $page->setLineWidth(1.0); - $page->setDash(array(2), 1); - $page->moveTo($rectangle[0], $rectangle[1]); - $page->lineTo($rectangle[2], $rectangle[1]); - $page->stroke(); - // Create link - $page->createLinkAnnotation($rectangle, $destPage->createDestination()) - ->setBorderStyle(0, 0, 0); - $page->setDash(null, 0); - } - - public function addTable($colCount) { - // If this table is inside another table or frame - array_push($this->old, $this->current); - $this->current["leftSpacing"] = $this->permanentLeftSpacing; - $this->current["rightSpacing"] = $this->permanentRightSpacing; - // First horizontal line - $this->currentPage->moveTo(self::HMARGIN + $this->current["leftSpacing"], $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); - $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - $this->current["rightSpacing"], $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); - $this->currentPage->stroke(); - } - - public function endTable() { - $this->permanentLeftSpacing = $this->current["leftSpacing"]; - $this->permanentRightSpacing = $this->current["rightSpacing"]; - $this->lineJump(); - $current = array_pop($this->old); - $current["pages"] = array_merge($current["pages"], $this->current["pages"]); - $this->current = $current; - } - - public function newTableRow($colCount, $valign) { - $this->current["vOffset"] = $this->vOffset; - $this->current["row"]["cellCount"] = $colCount; - $this->current["row"]["activeCell"] = 0; - $this->current["row"]["hSize"] = ($this->PAGE_WIDTH - 2*self::HMARGIN - - $this->current["leftSpacing"] - $this->current["rightSpacing"]) / $this->current["row"]["cellCount"]; - $this->current["row"]["vPosition"] = 0; - $this->current["row"]["pages"] = array(); - $this->current["row"]["cutPolicy"] = array(1); - $this->current["pages"] = array(); - } - - public function beginTableEntry($colspan, $rowspan, $align) { - $this->permanentLeftSpacing = ($this->current["row"]["activeCell"]++) * $this->current["row"]["hSize"] + - self::LINE_SPACING + $this->current["leftSpacing"]; - $this->permanentRightSpacing = $this->PAGE_WIDTH - 2*self::HMARGIN - - ($this->current["row"]["activeCell"] + $colspan - 1) * $this->current["row"]["hSize"] - - $this->current["leftSpacing"] + self::LINE_SPACING; - - foreach ($this->current["pages"] as $page) { - $this->lastPage(); - } - $this->current["pages"] = array(); - - $this->hOffset = 0; - $this->vOffset = $this->current["vOffset"] + $this->currentFontSize + self::LINE_SPACING; - $this->current["align"] = $align; - - array_push($this->current["row"]["cutPolicy"], $colspan); - } - - public function endTableEntry() { - $this->current["align"] = ""; - $newOffset = $this->vOffset + $this->currentFontSize + self::LINE_SPACING; - if ($newOffset + $this->PAGE_HEIGHT * count($this->current["pages"]) > $this->current["row"]["vPosition"]) { - $this->current["row"]["vPosition"] = $newOffset + $this->PAGE_HEIGHT * count($this->current["pages"]); - } - if (count($this->current["pages"]) > count($this->current["row"]["pages"])) { - $this->current["row"]["pages"] = $this->current["pages"]; - } - } - - public function endTableRow() { - $vOffset = $this->current["vOffset"]; - while($this->isNextPage()) - $this->nextPage(); - // Vertical lines - for ($i = 0, $x = self::HMARGIN + $this->current["leftSpacing"]; $i <= $this->current["row"]["cellCount"]; $i++, $x += $this->current["row"]["hSize"]) { - - // Don't trace vertical line if colspan - if (($cellCount = array_shift($this->current["row"]["cutPolicy"])) > 1) { - array_unshift($this->current["row"]["cutPolicy"], $cellCount - 1); - continue; - } - - foreach ($this->current["row"]["pages"] as $page) { - $page->setRGBStroke(0, 0, 0); - $page->moveTo($x, self::VMARGIN); - $page->lineTo($x, $this->PAGE_HEIGHT - self::VMARGIN - $this->current["vOffset"]); - $page->stroke(); - $this->current["vOffset"] = 0; - } - - $this->currentPage->moveTo($x, $this->PAGE_HEIGHT - self::VMARGIN - ($this->current["vOffset"])); - $this->currentPage->lineTo($x, $this->PAGE_HEIGHT - self::VMARGIN - ($this->current["row"]["vPosition"] % $this->PAGE_HEIGHT)); - $this->currentPage->stroke(); - $this->current["vOffset"] = $vOffset; - } - // Horizontal line - $this->currentPage->moveTo(self::HMARGIN + $this->current["leftSpacing"], $this->PAGE_HEIGHT - self::VMARGIN - ($this->current["row"]["vPosition"] % $this->PAGE_HEIGHT)); - $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - $this->current["rightSpacing"], - $this->PAGE_HEIGHT - self::VMARGIN - ($this->current["row"]["vPosition"] % $this->PAGE_HEIGHT)); - $this->currentPage->stroke(); - - // Store position - $this->vOffset = $this->current["row"]["vPosition"] % $this->PAGE_HEIGHT; - - // Store pages - $last = array_pop($this->old); - $last["pages"] = array_merge($last["pages"], $this->current["row"]["pages"]); - array_push($this->old, $last); - - // Erase current properties - $this->current["row"] = array(); - } - - private function endsWith($str, $sub) { - return ( substr( $str, strlen( $str ) - strlen( $sub ) ) === $sub ); - } - - private function addImage($url) { - $image = null; - if ($this->endsWith(strtolower($url), ".png")) { - $image = $this->haruDoc->loadPNG($url); - } elseif ($this->endsWith(strtolower($url), ".jpg") || $this->endsWith(strtolower($url), ".jpeg")) { - $image = $this->haruDoc->loadJPEG($url); - } - if ($image) { - if ($this->PAGE_HEIGHT - $this->vOffset - 2*self::VMARGIN < $image->getHeight()) - $this->nextPage(); - $this->currentPage->drawImage($image, - self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, - $this->PAGE_HEIGHT - self::HMARGIN - $this->vOffset - $image->getHeight(), - $image->getWidth(), - $image->getHeight()); - - $this->hOffset = 0; - $this->vOffset += $image->getWidth(); - } - } -} - -/* -* vim600: sw=4 ts=4 syntax=php et -* vim<600: sw=4 ts=4 -*/ + 0, + "hOffset" => 0, + ); + private $permanentLeftSpacing = 0; + private $permanentRightSpacing = 0; + + private $appendToBuffer = false; + // To append afterwards + private $buffer = array( + /* array( + 'text' => "", + 'font' => "", + 'size' => "", + 'color' => "", + )*/ + ); + + private $current = array( + "leftSpacing" => 0, + "rightSpacing" => 0, + "oldVPosition" => 0, + "vOffset" => 0, + "newVOffset" => 0, + "pages" => array(), + "row" => array(), + "align" => "", + "char" => "", + "charOffset" => 0, + ); + + // To temporarily store $current(s) + private $old = array(); + + function __construct($pageWidth = 210, $pageHeight = 297) { + // Initialization of properties + $this->haruDoc = new \HaruDoc; + $this->haruDoc->addPageLabel(1, \HaruPage::NUM_STYLE_DECIMAL, 1, "Page "); + + $this->haruDoc->setPageMode(\HaruDoc::PAGE_MODE_USE_OUTLINE); + $this->haruDoc->setPagesConfiguration(2); + + // Page format + $this->SCALE = 72/25.4; + $this->PAGE_WIDTH = $pageWidth * $this->SCALE; + $this->PAGE_HEIGHT = $pageHeight * $this->SCALE; + + // Set fonts + $this->fonts["Helvetica"] = $this->haruDoc->getFont("Helvetica", "WinAnsiEncoding"); + $this->fonts["Helvetica-Bold"] = $this->haruDoc->getFont("Helvetica-Bold", "WinAnsiEncoding"); + $this->fonts["Helvetica-Oblique"] = $this->haruDoc->getFont("Helvetica-Oblique", "WinAnsiEncoding"); + $this->fonts["Courier"] = $this->haruDoc->getFont("Courier", "WinAnsiEncoding"); + $this->fonts["Courier-Oblique"] = $this->haruDoc->getFont("Courier-Oblique", "WinAnsiEncoding"); + + // Add first page and default font settings + $this->currentFont = $this->fonts["Helvetica"]; + $this->currentFontSize = 12; + $this->currentFontColor = array(0, 0, 0); // Black + $this->nextPage(); + $this->haruDoc->addPageLabel(1, \HaruPage::NUM_STYLE_DECIMAL, 1, "Page "); + } + + public function getCurrentPage() { + return $this->currentPage; + } + + public function setCompressionMode($mode) { + $this->haruDoc->setCompressionMode($mode); + } + + // Append text into the current position + public function appendText($text) { +// if ($this->vOffset > $this->current["charOffset"] + 3*LINE_SPACING + 3*$this->currentFontSize) +// $this->vOffset = $this->current["charOffset"] + 3*LINE_SPACING + 3*$this->currentFontSize; + if ($this->appendToBuffer) { + array_push($this->buffer, array( + "text" => $text, + "font" => $this->currentFont, + "size" => $this->currentFontSize, + "color" => $this->currentFontColor + )); + return; + } + + $this->currentPage->beginText(); + do { + // Clear the whitespace if it begins the line or if last char is a special char + if (strpos($text, " ") === 0 && ($this->hOffset == 0 || in_array($this->current["char"], array("&", "$")))) { + $text = substr($text, 1); + } + + // Number of chars allowed in the current line + $nbCarac = $this->currentFont->measureText($text, + ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->hOffset - $this->permanentLeftSpacing - $this->permanentRightSpacing), + $this->currentFontSize, $this->currentPage->getCharSpace(), + $this->currentPage->getWordSpace(), true); + + // If a the text content can't be appended (either there is no whitespaces, + // either the is not enough space in the line) + if ($nbCarac === 0) { + $isEnoughSpaceOnNextLine = $this->currentFont->measureText($text, + ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->permanentLeftSpacing - $this->permanentRightSpacing), + $this->currentFontSize, $this->currentPage->getCharSpace(), + $this->currentPage->getWordSpace(), true); + if ($isEnoughSpaceOnNextLine) { + $this->vOffset += $this->currentFontSize + self::LINE_SPACING; + $this->hOffset = 0; + $isLastLine = false; + continue; + } else { + $nbCarac = $this->currentFont->measureText($text, + ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->hOffset - $this->permanentLeftSpacing - $this->permanentRightSpacing), + $this->currentFontSize, $this->currentPage->getCharSpace(), + $this->currentPage->getWordSpace(), false); + } + } + $isLastLine = ($nbCarac == strlen($text)); + + $textToAppend = substr($text, 0, $nbCarac); + $text = substr($text, $nbCarac); + + // Append text (in a new page if needed) with align + if ($this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset) < self::VMARGIN) { + $this->currentPage->endText(); + $this->current["pages"][] = $this->currentPage; + $this->nextPage(); + $this->currentPage->beginText(); + } + if ($this->current["align"] == "center") { + $spacing = $this->PAGE_WIDTH - 2*self::HMARGIN - + $this->permanentLeftSpacing - $this->permanentRightSpacing - $this->currentPage->getTextWidth($textToAppend); + $this->currentPage->textOut(self::HMARGIN + $this->hOffset + $this->permanentLeftSpacing + $spacing/2, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset), $textToAppend); + } elseif ($this->current["align"] == "right") { + $spacing = $this->PAGE_WIDTH - 2*self::HMARGIN - + $this->permanentLeftSpacing - $this->permanentRightSpacing - $this->currentPage->getTextWidth($textToAppend); + $this->currentPage->textOut(self::HMARGIN + $this->hOffset + $this->permanentLeftSpacing + $spacing, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset), $textToAppend); + } else { // left + $this->currentPage->textOut(self::HMARGIN + $this->hOffset + $this->permanentLeftSpacing, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset), $textToAppend); + } + if ($textToAppend) + $this->current["char"] = $textToAppend[strlen($textToAppend)-1]; + + // Offsets for next line + if (!$isLastLine) { + $this->vOffset += $this->currentFontSize + self::LINE_SPACING; + $this->hOffset = 0; + } else { + $this->hOffset += $this->currentPage->getTextWidth($textToAppend); + } + + } + while(!$isLastLine); // While it remains chars to append + $this->currentPage->endText(); + $this->current["charOffset"] = $this->vOffset; + } + + // Same function one line at a time + public function appendOneLine($text) { + if (strpos($text, " ") === 0 && ($this->hOffset == 0 || in_array($this->current["char"], array("&", "$")))) { + $text = substr($text, 1); + } + + $this->currentPage->beginText(); + $nbCarac = $this->currentFont->measureText($text, + ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->hOffset - $this->permanentLeftSpacing - $this->permanentRightSpacing), + $this->currentFontSize, $this->currentPage->getCharSpace(), + $this->currentPage->getWordSpace(), true); + + // If a the text content can't be appended (either there is no whitespaces, + // either the is not enough space in the line) + if ($nbCarac === 0) { + $isEnoughSpaceOnNextLine = $this->currentFont->measureText($text, + ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->permanentLeftSpacing - $this->permanentRightSpacing), + $this->currentFontSize, $this->currentPage->getCharSpace(), + $this->currentPage->getWordSpace(), true); + if ($isEnoughSpaceOnNextLine) { + $this->currentPage->endText(); + return $text; + } else { + $nbCarac = $this->currentFont->measureText($text, + ($this->PAGE_WIDTH - 2*self::HMARGIN - $this->hOffset - $this->permanentLeftSpacing - $this->permanentRightSpacing), + $this->currentFontSize, $this->currentPage->getCharSpace(), + $this->currentPage->getWordSpace(), false); + } + } + + $isLastLine = ($nbCarac == strlen($text)); + + $textToAppend = substr($text, 0, $nbCarac); + $text = substr($text, $nbCarac); + + // Append text (in a new page if needed) + if ($this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset) < self::VMARGIN) { + $this->currentPage->endText(); + $this->current["pages"][] = $this->currentPage; + $this->nextPage(); + $this->currentPage->beginText(); + } + $this->currentPage->textOut(self::HMARGIN + $this->hOffset + $this->permanentLeftSpacing, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset), $textToAppend); + if ($textToAppend) + $this->current["char"] = $textToAppend[strlen($textToAppend)-1]; + + $this->hOffset += $this->currentPage->getTextWidth($textToAppend); + + $this->currentPage->endText(); + $this->current["charOffset"] = $this->vOffset; + + return ($isLastLine ? null : $text); + } + + public function setAppendToBuffer($appendToBuffer) { + $this->appendToBuffer = $appendToBuffer; + } + + public function appendBufferNow() { + foreach($this->buffer as $row) { + if ($row["text"] == "\n") { + $this->lineJump(); + } else { + $this->setFont(self::FONT_MANUAL, $row["size"], $row["color"], $row["font"]); + $this->appendText($row["text"]); + $this->revertFont(); + } + } + $this->buffer = array(); + } + + public function add($type, $option = null) { + if ($this->appendToBuffer) return; + switch ($type) { + case self::INDENTED_PARA: + $this->lineJump(); + $this->indent(); + break; + case self::PARA: + $this->lineJump(); + break; + case self::VERBATIM_BLOCK: + $this->setFont(self::FONT_VERBATIM, 10, array(0.3, 0.3, 0.3)); + $this->lineJump(); + break; + case self::TITLE: + $this->setFont(self::FONT_BOLD, 20); + $this->lineJump(); + break; + case self::TITLE2: + $this->setFont(self::FONT_BOLD, 14); + $this->lineJump(); + break; + case self::TITLE3: + $this->setFont(self::FONT_BOLD, 12); + $this->lineJump(); + break; + case self::DRAW_LINE: + $this->traceLine($option); + break; + case self::LINE_JUMP: + if ($option) + $this->lineJump($option); + else $this->lineJump(); + break; + case self::PAGE: + $this->nextPage(); + break; + case self::ADMONITION: + $this->beginAdmonition(); + break; + case self::ADMONITION_CONTENT: + $this->admonitionContent(); + break; + case self::END_ADMONITION: + $this->endAdmonition(); + break; + case self::URL_ANNOTATION: + $this->appendUrlAnnotation($option[0], $option[1]); + break; + case self::LINK_ANNOTATION: + return $this->prepareInternalLinkAnnotation($option); + break; + case self::ADD_BULLET: + $this->indent(-self::INDENT_SPACING-$this->currentPage->getTextWidth(chr(149))); + $this->appendText(chr(149)); // ANSI Bullet + $this->indent(0); + break; + case self::ADD_NUMBER_ITEM: + $this->indent(-self::INDENT_SPACING-$this->currentPage->getTextWidth($option)); + $this->appendText($option); + $this->indent(0); + break; + case self::FRAMED_BLOCK: + $this->beginFrame(); + break; + case self::END_FRAMED_BLOCK: + $this->endFrame($option); + break; + case self::TABLE: + $this->addTable($option); + break; + case self::END_TABLE: + $this->endTable(); + break; + case self::TABLE_ROW: + $this->newTableRow($option[0], $option[1]); + break; + case self::TABLE_END_ROW: + $this->endTableRow(); + break; + case self::TABLE_ENTRY: + $this->beginTableEntry($option[0], $option[1], $option[2]); + break; + case self::TABLE_END_ENTRY: + $this->endTableEntry(); + break; + case self::IMAGE: + $this->addImage($option); + break; + default: + trigger_error("Unknown object type : {$type}", E_USER_WARNING); + break; + } + } + + // Switch font on-the-fly + public function setFont($type, $size = null, $color = null, $font = null) { + if ($this->currentPage == null) + return false; + $this->oldFonts[] = array($this->currentFont, $this->currentFontSize, $this->currentFontColor); + $this->currentFontSize = ($size ? $size : $this->currentFontSize); + if ($color && count($color) === 3) { + $this->setColor($color[0], $color[1], $color[2]); + $this->currentFontColor = $color; + } + else + $this->setColor($this->currentFontColor[0], $this->currentFontColor[1], $this->currentFontColor[2]); + switch ($type) { + case self::FONT_NORMAL: + $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Helvetica"], + $this->currentFontSize); + break; + case self::FONT_ITALIC: + $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Helvetica-Oblique"], + $this->currentFontSize); + break; + case self::FONT_BOLD: + $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Helvetica-Bold"], + $this->currentFontSize); + break; + case self::FONT_VERBATIM: + $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Courier"], + $this->currentFontSize); + break; + case self::FONT_VERBATIM_ITALIC: + $this->currentPage->setFontAndSize($this->currentFont = $this->fonts["Courier-Oblique"], + $this->currentFontSize); + break; + case self::FONT_MANUAL: + $this->currentPage->setFontAndSize($this->currentFont = $font, $this->currentFontSize); + break; + default: + trigger_error("Unknown font type : {$type}", E_USER_WARNING); + break; + } + } + + // Back to the last used font + public function revertFont() { + $lastFont = array_pop($this->oldFonts); + $this->currentFont = $lastFont[0]; + $this->currentFontSize = $lastFont[1]; + $this->currentFontColor = $lastFont[2]; + $this->currentPage->setFontAndSize($lastFont[0], $lastFont[1]); + $this->setColor($lastFont[2][0], $lastFont[2][1], $lastFont[2][2]); + } + + // Change font color (1, 1, 1 = white, 0, 0, 0 = black) + public function setColor($r, $g, $b) { + if ($r < 0 || $r > 1 || $g < 0 || $g > 1 || $b < 0 || $b > 1) + return false; + $this->currentPage->setRGBStroke($r, $g, $b); + $this->currentPage->setRGBFill($r, $g, $b); + $this->currentFontColor = array($r, $g, $b); + return true; + } + + // Save the current PDF Document to a file + public function saveToFile($filename) { + $this->haruDoc->save($filename); + } + + public function createOutline($description, $parentOutline = null, $opened = false) { + $outline = $this->haruDoc->createOutline($description, $parentOutline); + $dest = $this->currentPage->createDestination(); + $dest->setXYZ(0, $this->currentPage->getHeight(), 1); + $outline->setDestination($dest); + $outline->setOpened($opened); + return $outline; + } + + public function shift($offset = self::DEFAULT_SHIFT) { + $this->permanentLeftSpacing += $offset; + } + + public function unshift($offset = self::DEFAULT_SHIFT) { + $this->permanentLeftSpacing -= $offset; + } + + public function vOffset($offset) { + $this->vOffset += $offset; + } + + private function indent($offset = self::INDENT_SPACING) { + $this->hOffset = $offset; + } + + // Jump to next page (or create a new one if none exists) + private function nextPage() { + $this->lastPage = array( + "vOffset" => $this->vOffset, + "hOffset" => $this->hOffset, + ); + $footerToAppend = false; + $this->currentPageNumber++; + if (isset($this->pages[$this->currentPageNumber])) { + $this->currentPage = $this->pages[$this->currentPageNumber]; + $this->vOffset = $this->currentFontSize; + $this->hOffset = 0; + } else { + $this->pages[$this->currentPageNumber] = $this->haruDoc->addPage(); + $this->currentPage = $this->pages[$this->currentPageNumber]; + $this->currentPage->setTextRenderingMode(\HaruPage::FILL); + $this->vOffset = $this->currentFontSize; + $this->hOffset = ($this->hOffset ? $this->hOffset : 0); + $footerToAppend = true; + } + if ($this->currentFont && $this->currentFontSize && $this->currentFontColor) { + $this->currentPage->setFontAndSize($this->currentFont, $this->currentFontSize); + $this->setColor($this->currentFontColor[0], $this->currentFontColor[1], $this->currentFontColor[2]); + } + if ($footerToAppend && $this->currentPageNumber > 1) { + $this->currentPage->beginText(); + $this->setFont(self::FONT_NORMAL, 12, array(0,0,0)); + $this->currentPage->textOut($this->PAGE_WIDTH - self::HMARGIN - $this->currentPage->getTextWidth($this->currentPageNumber), + self::VMARGIN - 30, $this->currentPageNumber); + $this->revertFont(); + $this->setFont(self::FONT_BOLD, 12, array(0,0,0)); + $this->currentPage->textOut(self::HMARGIN, + self::VMARGIN - 30, $this->currentBookName); + $this->revertFont(); + $this->currentPage->endText(); + + } + + } + + public function setCurrentBookName($currentBookName) { + $this->currentBookName = $currentBookName; + } + + // Set last page as the current page + private function lastPage() { + $this->currentPageNumber--; + $this->currentPage = $this->pages[$this->currentPageNumber]; + $this->vOffset = $this->lastPage["vOffset"]; + $this->hOffset = $this->lastPage["hOffset"]; + } + + // Returns true if a next page exists + private function isNextPage() { + return isset($this->pages[$this->currentPageNumber + 1]); + } + + // Jump a line + private function lineJump($nbLines = 1) { + $this->vOffset += $nbLines * ($this->currentFontSize + self::LINE_SPACING); + $this->hOffset = 0; + } + + // Trace a line from the current position + private function traceLine() { + $this->lineJump(); + $this->currentPage->rectangle(self::HMARGIN + $this->hOffset, $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset, $this->PAGE_WIDTH - 2*$this->hOffset - 2*self::HMARGIN, 1); + $this->currentPage->stroke(); + } + + private function beginAdmonition() { + // If this admonition is inside another frame + array_push($this->old, $this->current); + + $this->setFont(self::FONT_BOLD, 12); + $this->lineJump(); + // If no space for admonition title + interleave + admonition first line on this page, then creates a new one + if (($this->PAGE_HEIGHT - 2*self::VMARGIN - $this->vOffset) < (3*$this->currentFontSize + 3*self::LINE_SPACING)) + $this->nextPage(); + $this->current["vOffset"] = $this->vOffset; + $this->lineJump(); + $this->permanentLeftSpacing += self::INDENT_SPACING; + $this->permanentRightSpacing += self::INDENT_SPACING; + $this->current["pages"] = array(); + } + + private function admonitionContent() { + if ($this->current["pages"]) + $this->current["vOffset"] = 0; + $this->beginFrame(); + $this->revertFont(); + $this->currentPage->rectangle(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset, + $this->PAGE_WIDTH - 2*self::HMARGIN - ($this->permanentLeftSpacing - self::INDENT_SPACING) - ($this->permanentRightSpacing - self::INDENT_SPACING), + $this->vOffset - $this->current["vOffset"]); + $this->currentPage->stroke(); + } + + private function endAdmonition() { + $this->endFrame(); + $this->permanentLeftSpacing -= self::INDENT_SPACING; + $this->permanentRightSpacing -= self::INDENT_SPACING; + $current = array_pop($this->old); + $current["pages"] = array_merge($current["pages"], $this->current["pages"]); + $this->current = $current; + } + + private function beginFrame() { + $this->lineJump(); + $this->current["newVOffset"] = $this->vOffset; + $this->current["pages"] = array(); + } + + private function endFrame($dash = null) { + $onSinglePage = true; + foreach ($this->current["pages"] as $page) { + $page->setRGBStroke(0, 0, 0); + $page->setLineWidth(1.0); + $page->setDash($dash, 0); + // left border + $page->moveTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), + self::VMARGIN); + $page->lineTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); + // right border + $page->moveTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), + self::VMARGIN); + $page->lineTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); + $page->stroke(); + $page->setDash(null, 0); + $this->current["newVOffset"] = 0; + $onSinglePage = false; + } + $this->currentPage->setRGBStroke(0, 0, 0); + $this->currentPage->setLineWidth(1.0); + $this->currentPage->setDash($dash, 0); + // left border + $this->currentPage->moveTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); + $this->currentPage->lineTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); + // right border + $this->currentPage->moveTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); + $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); + // bottom border + $this->currentPage->moveTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); + $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); + // top border (if frame's on a single page) + if ($onSinglePage) { + $this->currentPage->moveTo(self::HMARGIN + ($this->permanentLeftSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); + $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - ($this->permanentRightSpacing - self::INDENT_SPACING), + $this->PAGE_HEIGHT - self::VMARGIN - $this->current["newVOffset"]); + } + + $this->currentPage->stroke(); + $this->lineJump(); + $this->currentPage->setDash(null, 0); + $this->current["oldVPosition"] = 0; + } + + // Append $text with an underlined blue style with a link to $url + private function appendUrlAnnotation($text, $url) { + $this->appendText(" "); + $fromHOffset = $this->hOffset; + + // If more than one text line to append + while ($text = $this->appendOneLine($text)) { + // Trace the underline + $this->currentPage->setLineWidth(1.0); + $this->currentPage->setDash(null, 0); + $this->currentPage->moveTo(self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING)); + $this->currentPage->lineTo(self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING)); + $this->currentPage->stroke(); + + // Create link + $annotationArea = array(self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING), + self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset - $this->currentFontSize)); + $this->currentPage->createURLAnnotation($annotationArea, $url)->setBorderStyle(0, 0, 0); + + // Prepare the next line + $this->vOffset += $this->currentFontSize + self::LINE_SPACING; + $this->hOffset = 0; + $fromHOffset = $this->hOffset; + } + + // Trace the underline + $this->currentPage->setLineWidth(1.0); + $this->currentPage->setDash(null, 0); + $this->currentPage->moveTo(self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING)); + $this->currentPage->lineTo(self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING)); + $this->currentPage->stroke(); + + // Create link + $annotationArea = array(self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING), + self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset - $this->currentFontSize)); + $this->currentPage->createURLAnnotation($annotationArea, $url)->setBorderStyle(0, 0, 0); + + } + + // Append $text with an underlined blue style and prepare an internal link (which will be resolved later) + private function prepareInternalLinkAnnotation($text) { + $this->appendText(" "); + $fromHOffset = $this->hOffset; + $linkAreas = array(/* page, left, bottom, right, top */); + + // If more than one text line to append + while ($text = $this->appendOneLine($text)) { + // Create link + $linkAreas[] = array($this->currentPage, + self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING), + self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset - $this->currentFontSize)); + + // Prepare the next line + $this->vOffset += $this->currentFontSize + self::LINE_SPACING; + $this->hOffset = 0; + $fromHOffset = $this->hOffset; + } + + // Prepare link + $linkAreas[] = array($this->currentPage, + self::HMARGIN + $this->permanentLeftSpacing + $fromHOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset + self::LINE_SPACING), + self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, + $this->PAGE_HEIGHT - (self::VMARGIN + $this->vOffset - $this->currentFontSize)); + + return $linkAreas; + } + + public function resolveInternalLink($page, $rectangle, $destPage) { + $page->setRGBStroke(0, 0, 1); // blue + // Trace the underline + $page->setLineWidth(1.0); + $page->setDash(array(2), 1); + $page->moveTo($rectangle[0], $rectangle[1]); + $page->lineTo($rectangle[2], $rectangle[1]); + $page->stroke(); + // Create link + $page->createLinkAnnotation($rectangle, $destPage->createDestination()) + ->setBorderStyle(0, 0, 0); + $page->setDash(null, 0); + } + + public function addTable($colCount) { + // If this table is inside another table or frame + array_push($this->old, $this->current); + $this->current["leftSpacing"] = $this->permanentLeftSpacing; + $this->current["rightSpacing"] = $this->permanentRightSpacing; + // First horizontal line + $this->currentPage->moveTo(self::HMARGIN + $this->current["leftSpacing"], $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); + $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - $this->current["rightSpacing"], $this->PAGE_HEIGHT - self::VMARGIN - $this->vOffset); + $this->currentPage->stroke(); + } + + public function endTable() { + $this->permanentLeftSpacing = $this->current["leftSpacing"]; + $this->permanentRightSpacing = $this->current["rightSpacing"]; + $this->lineJump(); + $current = array_pop($this->old); + $current["pages"] = array_merge($current["pages"], $this->current["pages"]); + $this->current = $current; + } + + public function newTableRow($colCount, $valign) { + $this->current["vOffset"] = $this->vOffset; + $this->current["row"]["cellCount"] = $colCount; + $this->current["row"]["activeCell"] = 0; + $this->current["row"]["hSize"] = ($this->PAGE_WIDTH - 2*self::HMARGIN - + $this->current["leftSpacing"] - $this->current["rightSpacing"]) / $this->current["row"]["cellCount"]; + $this->current["row"]["vPosition"] = 0; + $this->current["row"]["pages"] = array(); + $this->current["row"]["cutPolicy"] = array(1); + $this->current["pages"] = array(); + } + + public function beginTableEntry($colspan, $rowspan, $align) { + $this->permanentLeftSpacing = ($this->current["row"]["activeCell"]++) * $this->current["row"]["hSize"] + + self::LINE_SPACING + $this->current["leftSpacing"]; + $this->permanentRightSpacing = $this->PAGE_WIDTH - 2*self::HMARGIN - + ($this->current["row"]["activeCell"] + $colspan - 1) * $this->current["row"]["hSize"] - + $this->current["leftSpacing"] + self::LINE_SPACING; + + foreach ($this->current["pages"] as $page) { + $this->lastPage(); + } + $this->current["pages"] = array(); + + $this->hOffset = 0; + $this->vOffset = $this->current["vOffset"] + $this->currentFontSize + self::LINE_SPACING; + $this->current["align"] = $align; + + array_push($this->current["row"]["cutPolicy"], $colspan); + } + + public function endTableEntry() { + $this->current["align"] = ""; + $newOffset = $this->vOffset + $this->currentFontSize + self::LINE_SPACING; + if ($newOffset + $this->PAGE_HEIGHT * count($this->current["pages"]) > $this->current["row"]["vPosition"]) { + $this->current["row"]["vPosition"] = $newOffset + $this->PAGE_HEIGHT * count($this->current["pages"]); + } + if (count($this->current["pages"]) > count($this->current["row"]["pages"])) { + $this->current["row"]["pages"] = $this->current["pages"]; + } + } + + public function endTableRow() { + $vOffset = $this->current["vOffset"]; + while($this->isNextPage()) + $this->nextPage(); + // Vertical lines + for ($i = 0, $x = self::HMARGIN + $this->current["leftSpacing"]; $i <= $this->current["row"]["cellCount"]; $i++, $x += $this->current["row"]["hSize"]) { + + // Don't trace vertical line if colspan + if (($cellCount = array_shift($this->current["row"]["cutPolicy"])) > 1) { + array_unshift($this->current["row"]["cutPolicy"], $cellCount - 1); + continue; + } + + foreach ($this->current["row"]["pages"] as $page) { + $page->setRGBStroke(0, 0, 0); + $page->moveTo($x, self::VMARGIN); + $page->lineTo($x, $this->PAGE_HEIGHT - self::VMARGIN - $this->current["vOffset"]); + $page->stroke(); + $this->current["vOffset"] = 0; + } + + $this->currentPage->moveTo($x, $this->PAGE_HEIGHT - self::VMARGIN - ($this->current["vOffset"])); + $this->currentPage->lineTo($x, $this->PAGE_HEIGHT - self::VMARGIN - ($this->current["row"]["vPosition"] % $this->PAGE_HEIGHT)); + $this->currentPage->stroke(); + $this->current["vOffset"] = $vOffset; + } + // Horizontal line + $this->currentPage->moveTo(self::HMARGIN + $this->current["leftSpacing"], $this->PAGE_HEIGHT - self::VMARGIN - ($this->current["row"]["vPosition"] % $this->PAGE_HEIGHT)); + $this->currentPage->lineTo($this->PAGE_WIDTH - self::HMARGIN - $this->current["rightSpacing"], + $this->PAGE_HEIGHT - self::VMARGIN - ($this->current["row"]["vPosition"] % $this->PAGE_HEIGHT)); + $this->currentPage->stroke(); + + // Store position + $this->vOffset = $this->current["row"]["vPosition"] % $this->PAGE_HEIGHT; + + // Store pages + $last = array_pop($this->old); + $last["pages"] = array_merge($last["pages"], $this->current["row"]["pages"]); + array_push($this->old, $last); + + // Erase current properties + $this->current["row"] = array(); + } + + private function endsWith($str, $sub) { + return ( substr( $str, strlen( $str ) - strlen( $sub ) ) === $sub ); + } + + private function addImage($url) { + $image = null; + if ($this->endsWith(strtolower($url), ".png")) { + $image = $this->haruDoc->loadPNG($url); + } elseif ($this->endsWith(strtolower($url), ".jpg") || $this->endsWith(strtolower($url), ".jpeg")) { + $image = $this->haruDoc->loadJPEG($url); + } + if ($image) { + if ($this->PAGE_HEIGHT - $this->vOffset - 2*self::VMARGIN < $image->getHeight()) + $this->nextPage(); + $this->currentPage->drawImage($image, + self::HMARGIN + $this->permanentLeftSpacing + $this->hOffset, + $this->PAGE_HEIGHT - self::HMARGIN - $this->vOffset - $image->getHeight(), + $image->getWidth(), + $image->getHeight()); + + $this->hOffset = 0; + $this->vOffset += $image->getWidth(); + } + } +} + +/* +* vim600: sw=4 ts=4 syntax=php et +* vim<600: sw=4 ts=4 +*/ \ No newline at end of file diff --git a/phpdotnet/phd/Format/Abstract/XHTML.php b/src/Format/XHTML.php similarity index 95% rename from phpdotnet/phd/Format/Abstract/XHTML.php rename to src/Format/XHTML.php index 2f772da3c..83aed0384 100644 --- a/phpdotnet/phd/Format/Abstract/XHTML.php +++ b/src/Format/XHTML.php @@ -1,7 +1,12 @@ ' - . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') - . "\n"; - } + return highlight_string($text, 1); } else { return '
'
. htmlspecialchars($text, ENT_QUOTES, 'UTF-8')
diff --git a/phpdotnet/phd/Highlighter/GeSHi.php b/src/Highlighter/GeSHi.php
similarity index 96%
rename from phpdotnet/phd/Highlighter/GeSHi.php
rename to src/Highlighter/GeSHi.php
index dc6aa0435..b6e64bfac 100644
--- a/phpdotnet/phd/Highlighter/GeSHi.php
+++ b/src/Highlighter/GeSHi.php
@@ -10,7 +10,9 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-namespace phpdotnet\phd;
+namespace phpdotnet\phd\Highlighter;
+
+use phpdotnet\phd\Highlighter;
/**
* Yes, geshi needs to be in your include path
@@ -41,7 +43,7 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-class Highlighter_GeSHi extends Highlighter
+class GeSHi extends Highlighter
{
/**
* Create a new highlighter instance for the given format.
diff --git a/phpdotnet/phd/Highlighter/GeSHi11x.php b/src/Highlighter/GeSHi11x.php
similarity index 96%
rename from phpdotnet/phd/Highlighter/GeSHi11x.php
rename to src/Highlighter/GeSHi11x.php
index 20ce1be1a..e78371a2d 100644
--- a/phpdotnet/phd/Highlighter/GeSHi11x.php
+++ b/src/Highlighter/GeSHi11x.php
@@ -10,7 +10,9 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-namespace phpdotnet\phd;
+namespace phpdotnet\phd\Highlighter;
+
+use phpdotnet\phd\Highlighter;
/**
* Yes, geshi needs to be in your include path.
@@ -33,7 +35,7 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-class Highlighter_GeSHi11x extends Highlighter
+class GeSHi11x extends Highlighter
{
/**
* Create a new highlighter instance for the given format.
@@ -43,7 +45,7 @@ class Highlighter_GeSHi11x extends Highlighter
*
* @param string $format Output format (pdf, xhtml, troff, ...)
*
- * @return PhDHighlighter Highlighter object
+ * @return self Highlighter object
*/
public static function factory($format)
{
diff --git a/phpdotnet/phd/Index.php b/src/Index.php
similarity index 99%
rename from phpdotnet/phd/Index.php
rename to src/Index.php
index c07cbe36d..d7e7ad525 100644
--- a/phpdotnet/phd/Index.php
+++ b/src/Index.php
@@ -79,8 +79,8 @@ class Index extends Format
private $mytextmap = array(
);
private $pihandlers = array(
- 'dbhtml' => 'PI_DBHTMLHandler',
- 'phpdoc' => 'PI_PHPDOCHandler',
+ 'dbhtml' => 'PI\\DBHTMLHandler',
+ 'phpdoc' => 'PI\\PHPDOCHandler',
);
private $chunks = array();
diff --git a/phpdotnet/phd/MediaManager.php b/src/MediaManager.php
similarity index 100%
rename from phpdotnet/phd/MediaManager.php
rename to src/MediaManager.php
diff --git a/phpdotnet/phd/ObjectStorage.php b/src/ObjectStorage.php
similarity index 100%
rename from phpdotnet/phd/ObjectStorage.php
rename to src/ObjectStorage.php
diff --git a/phpdotnet/phd/Options/Handler.php b/src/Options/Handler.php
similarity index 97%
rename from phpdotnet/phd/Options/Handler.php
rename to src/Options/Handler.php
index df3c7c2e3..ecffdabe9 100644
--- a/phpdotnet/phd/Options/Handler.php
+++ b/src/Options/Handler.php
@@ -1,7 +1,12 @@
getOutputFormats();
+ $formats = Factory::createFactory($package)->getOutputFormats();
echo "\t" . $package . "\n\t\t" . implode("\n\t\t", $formats) . "\n";
}
@@ -375,7 +380,7 @@ public function option_version($k, $v)
$packageList = Config::getSupportedPackages();
foreach ($packageList as $package) {
- $version = Format_Factory::createFactory($package)->getPackageVersion();
+ $version = Factory::createFactory($package)->getPackageVersion();
fprintf($output, "\t%s: %s\n", term_color($package, $color), term_color($version, $color));
}
fprintf($output, "%s\n", term_color('PHP Version: ' . phpversion(), $color));
diff --git a/phpdotnet/phd/Options/Interface.php b/src/Options/OptionsInterface.php
similarity index 62%
rename from phpdotnet/phd/Options/Interface.php
rename to src/Options/OptionsInterface.php
index a2a77f472..6641380b2 100644
--- a/phpdotnet/phd/Options/Interface.php
+++ b/src/Options/OptionsInterface.php
@@ -1,7 +1,7 @@
defaultHandler = new Options_Handler();
+ $this->defaultHandler = new Handler();
$this->packageHandlers = $this->loadPackageHandlers();
}
@@ -24,7 +27,7 @@ private function loadPackageHandlers() {
$packageList = Config::getSupportedPackages();
$list = array();
foreach ($packageList as $package) {
- if ($handler = Format_Factory::createFactory($package)->getOptionsHandler()) {
+ if ($handler = Factory::createFactory($package)->getOptionsHandler()) {
$list[strtolower($package)] = $handler;
}
}
diff --git a/phpdotnet/phd/PI/DBHTMLHandler.php b/src/PI/DBHTMLHandler.php
similarity index 97%
rename from phpdotnet/phd/PI/DBHTMLHandler.php
rename to src/PI/DBHTMLHandler.php
index 7eca27f0e..7814b93e8 100644
--- a/phpdotnet/phd/PI/DBHTMLHandler.php
+++ b/src/PI/DBHTMLHandler.php
@@ -1,7 +1,9 @@
"",
"bgcolor" => "",
diff --git a/phpdotnet/phd/PI/PHPDOCHandler.php b/src/PI/PHPDOCHandler.php
similarity index 98%
rename from phpdotnet/phd/PI/PHPDOCHandler.php
rename to src/PI/PHPDOCHandler.php
index 2101cd0d9..a95e2b105 100644
--- a/phpdotnet/phd/PI/PHPDOCHandler.php
+++ b/src/PI/PHPDOCHandler.php
@@ -1,7 +1,10 @@
registerFormatName("Big-XHTML");
diff --git a/phpdotnet/phd/Package/Generic/ChunkedXHTML.php b/src/Package/Generic/ChunkedXHTML.php
similarity index 97%
rename from phpdotnet/phd/Package/Generic/ChunkedXHTML.php
rename to src/Package/Generic/ChunkedXHTML.php
index 8c75f0a61..b3d8f1bb2 100644
--- a/phpdotnet/phd/Package/Generic/ChunkedXHTML.php
+++ b/src/Package/Generic/ChunkedXHTML.php
@@ -1,7 +1,12 @@
registerFormatName("Chunked-XHTML");
diff --git a/phpdotnet/phd/Package/Generic/Factory.php b/src/Package/Generic/Factory.php
similarity index 64%
rename from phpdotnet/phd/Package/Generic/Factory.php
rename to src/Package/Generic/Factory.php
index 53893d1b5..3c59e222e 100644
--- a/phpdotnet/phd/Package/Generic/Factory.php
+++ b/src/Package/Generic/Factory.php
@@ -1,7 +1,9 @@
'Package_Generic_ChunkedXHTML',
- 'bigxhtml' => 'Package_Generic_BigXHTML',
- 'manpage' => 'Package_Generic_Manpage',
+ 'xhtml' => 'Generic\\ChunkedXHTML',
+ 'bigxhtml' => 'Generic\\BigXHTML',
+ 'manpage' => 'Generic\\Manpage',
);
/**
diff --git a/phpdotnet/phd/Package/Generic/Manpage.php b/src/Package/Generic/Manpage.php
similarity index 99%
rename from phpdotnet/phd/Package/Generic/Manpage.php
rename to src/Package/Generic/Manpage.php
index 329a2789c..4bf38fbda 100644
--- a/phpdotnet/phd/Package/Generic/Manpage.php
+++ b/src/Package/Generic/Manpage.php
@@ -1,7 +1,14 @@
'format_suppressed_tags',
'abbrev' => 'format_suppressed_tags',
diff --git a/phpdotnet/phd/Package/Generic/TocFeed.php b/src/Package/Generic/TocFeed.php
similarity index 98%
rename from phpdotnet/phd/Package/Generic/TocFeed.php
rename to src/Package/Generic/TocFeed.php
index 8b9c324b8..32c12a387 100644
--- a/phpdotnet/phd/Package/Generic/TocFeed.php
+++ b/src/Package/Generic/TocFeed.php
@@ -1,5 +1,11 @@
'div', /* Docbook-xsl prints "abstract"... */
'abbrev' => 'abbr',
@@ -458,8 +466,8 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML {
);
protected $pihandlers = array(
- 'dbhtml' => 'PI_DBHTMLHandler',
- 'dbtimestamp' => 'PI_DBHTMLHandler',
+ 'dbhtml' => 'PI\\DBHTMLHandler',
+ 'dbtimestamp' => 'PI\\DBHTMLHandler',
);
protected $stylesheets = array();
diff --git a/phpdotnet/phd/Package/IDE/API.php b/src/Package/IDE/API.php
similarity index 94%
rename from phpdotnet/phd/Package/IDE/API.php
rename to src/Package/IDE/API.php
index 6764f8a31..42b54be26 100644
--- a/phpdotnet/phd/Package/IDE/API.php
+++ b/src/Package/IDE/API.php
@@ -10,7 +10,9 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-namespace phpdotnet\phd;
+namespace phpdotnet\phd\Package\IDE;
+
+use phpdotnet\phd\Package\IDE\API\APIFunction;
/**
* Class to load and parse the files generated by the PhD IDE Package.
@@ -28,7 +30,7 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-class Package_IDE_API
+class API
{
/**
* Output directory of the functions format in the IDE Package.
@@ -83,7 +85,7 @@ public function __construct($dir)
* Loads a function file and returns a Package_IDE_API_Function.
*
* @param string $filename File of the function.
- * @return Package_IDE_API_Function Object representing the function.
+ * @return APIFunction Object representing the function.
*/
private function loadFunction($filename)
{
@@ -91,7 +93,7 @@ private function loadFunction($filename)
return NULL;
}
$xml = simplexml_load_file($filename);
- return new Package_IDE_API_Function($xml);
+ return new APIFunction($xml);
}
/**
@@ -122,7 +124,7 @@ public function getFunctionList()
*
* @param string $functionName Function name.
* @param string $class TODO.
- * @return Package_IDE_API_Function A function object.
+ * @return APIFunction A function object.
*/
public function getFunctionByName($functionName, $class = null)
{
diff --git a/phpdotnet/phd/Package/IDE/API/Function.php b/src/Package/IDE/API/APIFunction.php
similarity index 98%
rename from phpdotnet/phd/Package/IDE/API/Function.php
rename to src/Package/IDE/API/APIFunction.php
index b7de4275f..8540e69eb 100644
--- a/phpdotnet/phd/Package/IDE/API/Function.php
+++ b/src/Package/IDE/API/APIFunction.php
@@ -10,7 +10,7 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-namespace phpdotnet\phd;
+namespace phpdotnet\phd\Package\IDE\API;
/**
* Class to parse the IDE Function xml.
@@ -21,7 +21,7 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-class Package_IDE_API_Function
+class APIFunction
{
/**
* Function name.
@@ -123,7 +123,7 @@ public function __construct(\SimpleXMLElement $xmlElement)
if (isset($xmlElement->params->param)) {
foreach ($xmlElement->params->param as $param) {
- $this->params[] = new Package_IDE_API_Param($param);
+ $this->params[] = new Param($param);
}
}
if (isset($xmlElement->seealso->entry)) {
diff --git a/phpdotnet/phd/Package/IDE/API/Param.php b/src/Package/IDE/API/Param.php
similarity index 98%
rename from phpdotnet/phd/Package/IDE/API/Param.php
rename to src/Package/IDE/API/Param.php
index 4b67f7f96..23902fb6c 100644
--- a/phpdotnet/phd/Package/IDE/API/Param.php
+++ b/src/Package/IDE/API/Param.php
@@ -10,7 +10,7 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-namespace phpdotnet\phd;
+namespace phpdotnet\phd\Package\IDE\API;
/**
* Class to parse the function parameters.
@@ -21,7 +21,7 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD Style
* @link https://doc.php.net/phd/
*/
-class Package_IDE_API_Param
+class Param
{
/**
* Parameter name.
diff --git a/phpdotnet/phd/Package/IDE/Base.php b/src/Package/IDE/Base.php
similarity index 97%
rename from phpdotnet/phd/Package/IDE/Base.php
rename to src/Package/IDE/Base.php
index 0b23ba3bc..9976b236a 100644
--- a/phpdotnet/phd/Package/IDE/Base.php
+++ b/src/Package/IDE/Base.php
@@ -1,7 +1,15 @@
'format_notes',
'entry' => 'format_changelog_entry',
@@ -112,7 +120,7 @@ function writeChunk() {
public function renderHTML() {
static $format = null;
if ($format == null) {
- $format = new Package_Generic_ChunkedXHTML();
+ $format = new ChunkedXHTML();
}
return $format->parse(trim(ReaderKeeper::getReader()->readInnerXML()));
}
diff --git a/src/Package/IDE/Factory.php b/src/Package/IDE/Factory.php
new file mode 100644
index 000000000..20f567aa2
--- /dev/null
+++ b/src/Package/IDE/Factory.php
@@ -0,0 +1,31 @@
+ 'IDE\\XML',
+ 'funclist' => 'IDE\\Funclist',
+ 'json' => 'IDE\\JSON',
+ 'php' => 'IDE\\PHP',
+ 'phpstub' => 'IDE\\PHPStub',
+ 'sqlite' => 'IDE\\SQLite',
+ );
+
+ /**
+ * The package version
+ */
+ private $version = '@phd_ide_version@';
+
+ public function __construct() {
+ parent::setPackageName("IDE");
+ parent::setPackageVersion($this->version);
+ parent::registerOutputFormats($this->formats);
+ }
+}
+
+/*
+* vim600: sw=4 ts=4 syntax=php et
+* vim<600: sw=4 ts=4
+*/
diff --git a/phpdotnet/phd/Package/IDE/Funclist.php b/src/Package/IDE/Funclist.php
similarity index 91%
rename from phpdotnet/phd/Package/IDE/Funclist.php
rename to src/Package/IDE/Funclist.php
index 4a3cec0b3..904a823ab 100644
--- a/phpdotnet/phd/Package/IDE/Funclist.php
+++ b/src/Package/IDE/Funclist.php
@@ -1,7 +1,13 @@
'format_refname',
'set' => 'format_set',
diff --git a/phpdotnet/phd/Package/IDE/JSON.php b/src/Package/IDE/JSON.php
similarity index 78%
rename from phpdotnet/phd/Package/IDE/JSON.php
rename to src/Package/IDE/JSON.php
index 024206c1d..dfe5cd1e0 100644
--- a/phpdotnet/phd/Package/IDE/JSON.php
+++ b/src/Package/IDE/JSON.php
@@ -1,7 +1,9 @@
registerFormatName('IDE-JSON');
diff --git a/phpdotnet/phd/Package/IDE/PHP.php b/src/Package/IDE/PHP.php
similarity index 82%
rename from phpdotnet/phd/Package/IDE/PHP.php
rename to src/Package/IDE/PHP.php
index 3a4a9a216..d7915e180 100644
--- a/phpdotnet/phd/Package/IDE/PHP.php
+++ b/src/Package/IDE/PHP.php
@@ -1,7 +1,9 @@
registerFormatName('IDE-PHP');
diff --git a/phpdotnet/phd/Package/IDE/PHPStub.php b/src/Package/IDE/PHPStub.php
similarity index 96%
rename from phpdotnet/phd/Package/IDE/PHPStub.php
rename to src/Package/IDE/PHPStub.php
index 7a2fcdc8e..19efda435 100644
--- a/phpdotnet/phd/Package/IDE/PHPStub.php
+++ b/src/Package/IDE/PHPStub.php
@@ -1,6 +1,8 @@
registerFormatName('IDE-PHPStub');
diff --git a/phpdotnet/phd/Package/IDE/SQLite.php b/src/Package/IDE/SQLite.php
similarity index 98%
rename from phpdotnet/phd/Package/IDE/SQLite.php
rename to src/Package/IDE/SQLite.php
index abc435182..e23afd93c 100644
--- a/phpdotnet/phd/Package/IDE/SQLite.php
+++ b/src/Package/IDE/SQLite.php
@@ -1,7 +1,9 @@
registerFormatName('IDE-XML');
diff --git a/phpdotnet/phd/Package/IDE/demo.php b/src/Package/IDE/demo.php
similarity index 93%
rename from phpdotnet/phd/Package/IDE/demo.php
rename to src/Package/IDE/demo.php
index 35786a5f8..f8ddbf987 100644
--- a/phpdotnet/phd/Package/IDE/demo.php
+++ b/src/Package/IDE/demo.php
@@ -1,17 +1,19 @@
#!@php_bin@
getMethodsByClass($OPTION['class']);
diff --git a/phpdotnet/phd/Package/PEAR/BigXHTML.php b/src/Package/PEAR/BigXHTML.php
old mode 100755
new mode 100644
similarity index 95%
rename from phpdotnet/phd/Package/PEAR/BigXHTML.php
rename to src/Package/PEAR/BigXHTML.php
index f3de3d79e..399707d60
--- a/phpdotnet/phd/Package/PEAR/BigXHTML.php
+++ b/src/Package/PEAR/BigXHTML.php
@@ -1,7 +1,11 @@
registerFormatName("PEAR-BigXHTML");
diff --git a/phpdotnet/phd/Package/PEAR/CHM.php b/src/Package/PEAR/CHM.php
old mode 100755
new mode 100644
similarity index 98%
rename from phpdotnet/phd/Package/PEAR/CHM.php
rename to src/Package/PEAR/CHM.php
index b6fc58f5f..0bb2c399e
--- a/phpdotnet/phd/Package/PEAR/CHM.php
+++ b/src/Package/PEAR/CHM.php
@@ -1,7 +1,13 @@
registerFormatName("PEAR-Chunked-XHTML");
diff --git a/phpdotnet/phd/Package/PEAR/Factory.php b/src/Package/PEAR/Factory.php
similarity index 52%
rename from phpdotnet/phd/Package/PEAR/Factory.php
rename to src/Package/PEAR/Factory.php
index 2534e8051..d9211c47a 100644
--- a/phpdotnet/phd/Package/PEAR/Factory.php
+++ b/src/Package/PEAR/Factory.php
@@ -1,13 +1,16 @@
'Package_PEAR_ChunkedXHTML',
- 'bigxhtml' => 'Package_PEAR_BigXHTML',
- 'php' => 'Package_PEAR_Web',
- 'chm' => 'Package_PEAR_CHM',
- 'tocfeed' => 'Package_PEAR_TocFeed',
+ 'xhtml' => 'PEAR\\ChunkedXHTML',
+ 'bigxhtml' => 'PEAR\\BigXHTML',
+ 'php' => 'PEAR\\Web',
+ 'chm' => 'PEAR\\CHM',
+ 'tocfeed' => 'PEAR\\TocFeed',
);
/**
diff --git a/phpdotnet/phd/Package/PEAR/TocFeed.php b/src/Package/PEAR/TocFeed.php
similarity index 93%
rename from phpdotnet/phd/Package/PEAR/TocFeed.php
rename to src/Package/PEAR/TocFeed.php
index da3490325..601842ba0 100644
--- a/phpdotnet/phd/Package/PEAR/TocFeed.php
+++ b/src/Package/PEAR/TocFeed.php
@@ -1,5 +1,8 @@
'format_div',
'abbrev' => 'abbr',
diff --git a/phpdotnet/phd/Package/PHP/BigPDF.php b/src/Package/PHP/BigPDF.php
similarity index 91%
rename from phpdotnet/phd/Package/PHP/BigPDF.php
rename to src/Package/PHP/BigPDF.php
index 54469f5f0..0b23828d5 100644
--- a/phpdotnet/phd/Package/PHP/BigPDF.php
+++ b/src/Package/PHP/BigPDF.php
@@ -1,7 +1,14 @@
registerFormatName("PHP-BigPDF");
diff --git a/phpdotnet/phd/Package/PHP/BigXHTML.php b/src/Package/PHP/BigXHTML.php
similarity index 95%
rename from phpdotnet/phd/Package/PHP/BigXHTML.php
rename to src/Package/PHP/BigXHTML.php
index 34a1f593b..69285d3f5 100644
--- a/phpdotnet/phd/Package/PHP/BigXHTML.php
+++ b/src/Package/PHP/BigXHTML.php
@@ -1,7 +1,11 @@
registerFormatName("PHP-BigXHTML");
diff --git a/phpdotnet/phd/Package/PHP/CHM.php b/src/Package/PHP/CHM.php
similarity index 98%
rename from phpdotnet/phd/Package/PHP/CHM.php
rename to src/Package/PHP/CHM.php
index 36692bf61..91dc2fe1f 100644
--- a/phpdotnet/phd/Package/PHP/CHM.php
+++ b/src/Package/PHP/CHM.php
@@ -1,7 +1,12 @@
'PHP\\ChunkedXHTML',
+ 'bigxhtml' => 'PHP\\BigXHTML',
+ 'php' => 'PHP\\Web',
+ 'howto' => 'PHP\\HowTo',
+ 'manpage' => 'PHP\\Manpage',
+ 'pdf' => 'PHP\\PDF',
+ 'bigpdf' => 'PHP\\BigPDF',
+ 'kdevelop' => 'PHP\\KDevelop',
+ 'chm' => 'PHP\\CHM',
+ 'tocfeed' => 'PHP\\TocFeed',
+ 'epub' => 'PHP\\Epub',
+ 'enhancedchm' => 'PHP\\EnhancedCHM',
+ );
+
+ /**
+ * The package version
+ */
+ private $version = '@phd_php_version@';
+
+ public function __construct() {
+ parent::setPackageName("PHP");
+ parent::setPackageVersion($this->version);
+ parent::registerOutputFormats($this->formats);
+ }
+}
+
+/*
+* vim600: sw=4 ts=4 syntax=php et
+* vim<600: sw=4 ts=4
+*/
diff --git a/phpdotnet/phd/Package/PHP/HOWTO.GENERATE_CHM b/src/Package/PHP/HOWTO.GENERATE_CHM
similarity index 100%
rename from phpdotnet/phd/Package/PHP/HOWTO.GENERATE_CHM
rename to src/Package/PHP/HOWTO.GENERATE_CHM
diff --git a/phpdotnet/phd/Package/PHP/HowTo.php b/src/Package/PHP/HowTo.php
similarity index 94%
rename from phpdotnet/phd/Package/PHP/HowTo.php
rename to src/Package/PHP/HowTo.php
index 4648d9492..19a45ac43 100644
--- a/phpdotnet/phd/Package/PHP/HowTo.php
+++ b/src/Package/PHP/HowTo.php
@@ -1,7 +1,12 @@
'format_chunk',
diff --git a/phpdotnet/phd/Package/PHP/PDF.php b/src/Package/PHP/PDF.php
similarity index 97%
rename from phpdotnet/phd/Package/PHP/PDF.php
rename to src/Package/PHP/PDF.php
index 9aab2742f..0b4a2c149 100644
--- a/phpdotnet/phd/Package/PHP/PDF.php
+++ b/src/Package/PHP/PDF.php
@@ -1,7 +1,16 @@
'format_tocnode_newpage',
'appendix' => 'format_tocnode_newpage',
diff --git a/phpdotnet/phd/Package/PHP/README b/src/Package/PHP/README
similarity index 100%
rename from phpdotnet/phd/Package/PHP/README
rename to src/Package/PHP/README
diff --git a/phpdotnet/phd/Package/PHP/TocFeed.php b/src/Package/PHP/TocFeed.php
similarity index 95%
rename from phpdotnet/phd/Package/PHP/TocFeed.php
rename to src/Package/PHP/TocFeed.php
index 70b33f6fa..827e04c33 100644
--- a/phpdotnet/phd/Package/PHP/TocFeed.php
+++ b/src/Package/PHP/TocFeed.php
@@ -1,5 +1,9 @@
registerFormatName("PHP-Web");
diff --git a/phpdotnet/phd/Package/PHP/XHTML.php b/src/Package/PHP/XHTML.php
similarity index 98%
rename from phpdotnet/phd/Package/PHP/XHTML.php
rename to src/Package/PHP/XHTML.php
index 461475605..4768775de 100644
--- a/phpdotnet/phd/Package/PHP/XHTML.php
+++ b/src/Package/PHP/XHTML.php
@@ -1,7 +1,15 @@
'format_suppressed_tags',
'appendix' => 'format_container_chunk',
@@ -171,9 +179,9 @@ abstract class Package_PHP_XHTML extends Package_Generic_XHTML {
private $simple_nullable = null;
protected $pihandlers = array(
- 'dbhtml' => 'PI_DBHTMLHandler',
- 'dbtimestamp' => 'PI_DBHTMLHandler',
- 'phpdoc' => 'PI_PHPDOCHandler',
+ 'dbhtml' => 'PI\\DBHTMLHandler',
+ 'dbtimestamp' => 'PI\\DBHTMLHandler',
+ 'phpdoc' => 'PI\\PHPDOCHandler',
);
public function __construct() {
diff --git a/phpdotnet/phd/Reader.php b/src/Reader.php
similarity index 100%
rename from phpdotnet/phd/Reader.php
rename to src/Reader.php
diff --git a/phpdotnet/phd/Reader/Partial.php b/src/Reader/Partial.php
similarity index 96%
rename from phpdotnet/phd/Reader/Partial.php
rename to src/Reader/Partial.php
index 0c8cda3f2..a6063546a 100644
--- a/phpdotnet/phd/Reader/Partial.php
+++ b/src/Reader/Partial.php
@@ -1,7 +1,11 @@
$v) {
$method = "set_$k";
Config::$method($v);
@@ -12,8 +17,7 @@ public function __construct($formatclass, $opts, $extra = array()) {
if (count($extra) != 0) {
Config::init($extra);
}
- $classname = __NAMESPACE__ . "\\" . $formatclass;
- $this->format = new $classname();
+ $this->format = new $formatClass();
}
public function run() {
diff --git a/tests/php/TestBigXHTML.php b/tests/php/TestBigXHTML.php
index bae3950a9..12775a9c3 100644
--- a/tests/php/TestBigXHTML.php
+++ b/tests/php/TestBigXHTML.php
@@ -1,7 +1,10 @@
__DIR__ . "/../../phpdotnet/phd/data/langs/",
+ "lang_dir" => __DIR__ . "/../../src/data/langs/",
"phpweb_version_filename" => dirname($xml_file) . '/version.xml',
"phpweb_acronym_filename" => dirname($xml_file) . '/acronyms.xml',
);
diff --git a/tests/php/bug49101-2.phpt b/tests/php/bug49101-2.phpt
index 8f03faa83..27f78fc14 100644
--- a/tests/php/bug49101-2.phpt
+++ b/tests/php/bug49101-2.phpt
@@ -2,13 +2,14 @@
Bug #49101 - Thick border again - Big XHTML
--FILE--
__DIR__ . "/../../phpdotnet/phd/data/langs/",
+ "lang_dir" => __DIR__ . "/../../src/data/langs/",
"phpweb_version_filename" => dirname($xml_file) . '/version.xml',
"phpweb_acronym_filename" => dirname($xml_file) . '/acronyms.xml',
);
diff --git a/tests/php/bug49102-1.phpt b/tests/php/bug49102-1.phpt
index b8f657cf1..7b94036dd 100644
--- a/tests/php/bug49102-1.phpt
+++ b/tests/php/bug49102-1.phpt
@@ -2,13 +2,13 @@
Bug #49102 - Class reference pages don't normalize the methodnames in PhD trunk/
--FILE--
__DIR__ . "/../../phpdotnet/phd/data/langs/",
+ "lang_dir" => __DIR__ . "/../../src/data/langs/",
"phpweb_version_filename" => dirname($xml_file) . '/version.xml',
"phpweb_acronym_filename" => dirname($xml_file) . '/acronyms.xml',
);
@@ -42,73 +42,40 @@ Content:
Class synopsis
-
+
- SplStack
+ class SplStack
extends
- SplDoublyLinkedList
-
-
- implements
- Iterator
+ SplDoublyLinkedList
- ,
- ArrayAccess
-
-
- ,
- Countable
-
- {
+ implements
+ Iterator, ArrayAccess, Countable {
/* Methods */
- __construct
- ( void
- )
+ __construct()
-
- void setIteratorMode
- ( int $mode
- )
+ setIteratorMode(int $mode): void
/* Inherited methods */
-
- mixed SplDoublyLinkedList::bottom
- ( void
- )
-
-
- int SplDoublyLinkedList::count
- ( void
- )
-
-
- mixed SplDoublyLinkedList::current
- ( void
- )
-
-
- int SplDoublyLinkedList::getIteratorMode
- ( void
- )
-
-
-
-
+ SplDoublyLinkedList::bottom(): mixed
+
+ SplDoublyLinkedList::count(): int
+
+ SplDoublyLinkedList::current(): mixed
+
+ SplDoublyLinkedList::getIteratorMode(): int
+
+
+
+
}
diff --git a/tests/php/faq001.phpt b/tests/php/faq001.phpt
index ae9de799c..f4975a509 100644
--- a/tests/php/faq001.phpt
+++ b/tests/php/faq001.phpt
@@ -2,13 +2,13 @@
Testing a simple FAQ
--FILE--
__DIR__ . "/../../phpdotnet/phd/data/langs/",
+ "lang_dir" => __DIR__ . "/../../src/data/langs/",
"phpweb_version_filename" => dirname($xml_file) . '/version.xml',
"phpweb_acronym_filename" => dirname($xml_file) . '/acronyms.xml',
);
diff --git a/tests/setup.php b/tests/setup.php
index ec946228f..c539df1fc 100644
--- a/tests/setup.php
+++ b/tests/setup.php
@@ -1,19 +1,11 @@
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier
+ * @author Jordi Boggiano
+ * @see https://www.php-fig.org/psr/psr-0/
+ * @see https://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ // PSR-4
+ private $prefixLengthsPsr4 = array();
+ private $prefixDirsPsr4 = array();
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ private $prefixesPsr0 = array();
+ private $fallbackDirsPsr0 = array();
+
+ private $useIncludePath = false;
+ private $classMap = array();
+ private $classMapAuthoritative = false;
+ private $missingClasses = array();
+ private $apcuPrefix;
+
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
+ }
+
+ return array();
+ }
+
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array $classMap Class to filename map
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ (array) $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ (array) $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 base directories
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return bool|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ includeFile($file);
+
+ return true;
+ }
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath . '\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+
+ return false;
+ }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+ include $file;
+}
diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php
new file mode 100644
index 000000000..7b53e0fa9
--- /dev/null
+++ b/vendor/composer/InstalledVersions.php
@@ -0,0 +1,219 @@
+
+ array (
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => '12596032ec2ffb3da9d6d254d6cc6c000e9245e1',
+ 'name' => 'php/phd',
+ ),
+ 'versions' =>
+ array (
+ 'php/phd' =>
+ array (
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => '12596032ec2ffb3da9d6d254d6cc6c000e9245e1',
+ ),
+ ),
+);
+
+
+
+
+
+
+
+public static function getInstalledPackages()
+{
+return array_keys(self::$installed['versions']);
+}
+
+
+
+
+
+
+
+
+
+public static function isInstalled($packageName)
+{
+return isset(self::$installed['versions'][$packageName]);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+public static function satisfies(VersionParser $parser, $packageName, $constraint)
+{
+$constraint = $parser->parseConstraints($constraint);
+$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
+
+return $provided->matches($constraint);
+}
+
+
+
+
+
+
+
+
+
+
+public static function getVersionRanges($packageName)
+{
+if (!isset(self::$installed['versions'][$packageName])) {
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+$ranges = array();
+if (isset(self::$installed['versions'][$packageName]['pretty_version'])) {
+$ranges[] = self::$installed['versions'][$packageName]['pretty_version'];
+}
+if (array_key_exists('aliases', self::$installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']);
+}
+if (array_key_exists('replaced', self::$installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']);
+}
+if (array_key_exists('provided', self::$installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']);
+}
+
+return implode(' || ', $ranges);
+}
+
+
+
+
+
+public static function getVersion($packageName)
+{
+if (!isset(self::$installed['versions'][$packageName])) {
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+if (!isset(self::$installed['versions'][$packageName]['version'])) {
+return null;
+}
+
+return self::$installed['versions'][$packageName]['version'];
+}
+
+
+
+
+
+public static function getPrettyVersion($packageName)
+{
+if (!isset(self::$installed['versions'][$packageName])) {
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) {
+return null;
+}
+
+return self::$installed['versions'][$packageName]['pretty_version'];
+}
+
+
+
+
+
+public static function getReference($packageName)
+{
+if (!isset(self::$installed['versions'][$packageName])) {
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+if (!isset(self::$installed['versions'][$packageName]['reference'])) {
+return null;
+}
+
+return self::$installed['versions'][$packageName]['reference'];
+}
+
+
+
+
+
+public static function getRootPackage()
+{
+return self::$installed['root'];
+}
+
+
+
+
+
+
+
+public static function getRawData()
+{
+return self::$installed;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+public static function reload($data)
+{
+self::$installed = $data;
+}
+}
diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE
new file mode 100644
index 000000000..f27399a04
--- /dev/null
+++ b/vendor/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
new file mode 100644
index 000000000..b26f1b13b
--- /dev/null
+++ b/vendor/composer/autoload_classmap.php
@@ -0,0 +1,10 @@
+ $vendorDir . '/composer/InstalledVersions.php',
+);
diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php
new file mode 100644
index 000000000..9985e9b4e
--- /dev/null
+++ b/vendor/composer/autoload_files.php
@@ -0,0 +1,10 @@
+ $baseDir . '/src/functions.php',
+);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
new file mode 100644
index 000000000..b7fc0125d
--- /dev/null
+++ b/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,9 @@
+ array($baseDir . '/tests'),
+ 'phpdotnet\\phd\\' => array($baseDir . '/src'),
+);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
new file mode 100644
index 000000000..616738f64
--- /dev/null
+++ b/vendor/composer/autoload_real.php
@@ -0,0 +1,75 @@
+= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
+ if ($useStaticLoader) {
+ require __DIR__ . '/autoload_static.php';
+
+ call_user_func(\Composer\Autoload\ComposerStaticInit5e2bbd784826d9f6e0821e8f96356bff::getInitializer($loader));
+ } else {
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
+
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
+
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
+ }
+ }
+
+ $loader->register(true);
+
+ if ($useStaticLoader) {
+ $includeFiles = Composer\Autoload\ComposerStaticInit5e2bbd784826d9f6e0821e8f96356bff::$files;
+ } else {
+ $includeFiles = require __DIR__ . '/autoload_files.php';
+ }
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequire5e2bbd784826d9f6e0821e8f96356bff($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
+
+function composerRequire5e2bbd784826d9f6e0821e8f96356bff($fileIdentifier, $file)
+{
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ require $file;
+
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+ }
+}
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
new file mode 100644
index 000000000..b572464b9
--- /dev/null
+++ b/vendor/composer/autoload_static.php
@@ -0,0 +1,45 @@
+ __DIR__ . '/../..' . '/src/functions.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 'p' =>
+ array (
+ 'phpdotnet\\phd\\Tests\\' => 20,
+ 'phpdotnet\\phd\\' => 14,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'phpdotnet\\phd\\Tests\\' =>
+ array (
+ 0 => __DIR__ . '/../..' . '/tests',
+ ),
+ 'phpdotnet\\phd\\' =>
+ array (
+ 0 => __DIR__ . '/../..' . '/src',
+ ),
+ );
+
+ public static $classMap = array (
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInit5e2bbd784826d9f6e0821e8f96356bff::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit5e2bbd784826d9f6e0821e8f96356bff::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInit5e2bbd784826d9f6e0821e8f96356bff::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
new file mode 100644
index 000000000..87fda747e
--- /dev/null
+++ b/vendor/composer/installed.json
@@ -0,0 +1,5 @@
+{
+ "packages": [],
+ "dev": true,
+ "dev-package-names": []
+}
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
new file mode 100644
index 000000000..82223ac61
--- /dev/null
+++ b/vendor/composer/installed.php
@@ -0,0 +1,24 @@
+
+ array (
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => '12596032ec2ffb3da9d6d254d6cc6c000e9245e1',
+ 'name' => 'php/phd',
+ ),
+ 'versions' =>
+ array (
+ 'php/phd' =>
+ array (
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => '12596032ec2ffb3da9d6d254d6cc6c000e9245e1',
+ ),
+ ),
+);
diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php
new file mode 100644
index 000000000..8b379f446
--- /dev/null
+++ b/vendor/composer/platform_check.php
@@ -0,0 +1,26 @@
+= 50600)) {
+ $issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.';
+}
+
+if ($issues) {
+ if (!headers_sent()) {
+ header('HTTP/1.1 500 Internal Server Error');
+ }
+ if (!ini_get('display_errors')) {
+ if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+ fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
+ } elseif (!headers_sent()) {
+ echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
+ }
+ }
+ trigger_error(
+ 'Composer detected issues in your platform: ' . implode(' ', $issues),
+ E_USER_ERROR
+ );
+}