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 ? "<" : ""); + $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 ? "<" : ""); - $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 - )
- -
- bool SplDoublyLinkedList::offsetExists - ( mixed $index - )
- -
- mixed SplDoublyLinkedList::offsetGet - ( mixed $index - )
+
SplDoublyLinkedList::bottom(): mixed
+ +
SplDoublyLinkedList::count(): int
+ +
SplDoublyLinkedList::current(): mixed
+ +
SplDoublyLinkedList::getIteratorMode(): int
+ +
SplDoublyLinkedList::offsetExists(mixed $index): bool
+ +
SplDoublyLinkedList::offsetGet(mixed $index): mixed
} 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 + ); +}