mirror of
https://github.com/php/phd.git
synced 2026-03-23 22:52:05 +01:00
322 lines
13 KiB
PHP
322 lines
13 KiB
PHP
<?php
|
|
namespace phpdotnet\phd;
|
|
|
|
class Package_PHP_PDF extends Package_Generic_PDF {
|
|
protected $elementmap = array(
|
|
'article' => 'format_tocnode_newpage',
|
|
'appendix' => 'format_tocnode_newpage',
|
|
'book' => 'format_book',
|
|
'bibliography' => array(
|
|
/* DEFAULT */ 'format_suppressed_tags',
|
|
'article' => 'format_tocnode_newpage',
|
|
'book' => 'format_tocnode_newpage',
|
|
'part' => 'format_tocnode_newpage',
|
|
),
|
|
'callout' => 'format_collect_id',
|
|
'chapter' => 'format_tocnode_newpage',
|
|
'co' => 'format_collect_id',
|
|
'colophon' => 'format_tocnode_newpage',
|
|
'footnote' => 'format_collect_id',
|
|
'glossary' => array(
|
|
/* DEFAULT */ 'format_suppressed_tags',
|
|
'article' => 'format_tocnode_newpage',
|
|
'book' => 'format_tocnode_newpage',
|
|
'part' => 'format_tocnode_newpage',
|
|
),
|
|
'index' => array(
|
|
/* DEFAULT */ 'format_suppressed_tags',
|
|
'article' => 'format_tocnode_newpage',
|
|
'book' => 'format_tocnode_newpage',
|
|
'part' => 'format_tocnode_newpage',
|
|
),
|
|
'legalnotice' => 'format_tocnode_newpage',
|
|
'part' => 'format_tocnode_newpage',
|
|
'phpdoc:exceptionref' => 'format_tocnode_exception',
|
|
'phpdoc:classref' => 'format_tocnode_class',
|
|
'preface' => 'format_tocnode_newpage',
|
|
'refentry' => 'format_tocnode_newpage',
|
|
'reference' => 'format_tocnode_newpage',
|
|
'phpdoc:varentry' => 'format_tocnode_newpage',
|
|
'sect1' => 'format_tocnode',
|
|
'sect2' => 'format_tocnode',
|
|
'sect3' => 'format_tocnode',
|
|
'sect4' => 'format_tocnode',
|
|
'sect5' => 'format_tocnode',
|
|
'section' => 'format_tocnode',
|
|
'set' => array(
|
|
/* DEFAULT */ 'format_root_set',
|
|
'set' => 'format_set',
|
|
),
|
|
'setindex' => 'format_tocnode_newpage',
|
|
|
|
);
|
|
|
|
protected $textmap = array(
|
|
'title' => array(
|
|
/* DEFAULT */ false,
|
|
'book' => 'format_bookname',
|
|
'set' => array(
|
|
/* DEFAULT */ 'format_setname',
|
|
'set' => false,
|
|
),
|
|
),
|
|
'type' => array(
|
|
/* DEFAULT */ 'format_type_text',
|
|
'classsynopsisinfo' => false,
|
|
'fieldsynopsis' => 'format_type_if_object_or_pseudo_text',
|
|
'methodparam' => 'format_type_if_object_or_pseudo_text',
|
|
'methodsynopsis' => array(
|
|
/* DEFAULT */ 'format_type_if_object_or_pseudo_text',
|
|
'classsynopsis' => false,
|
|
),
|
|
),
|
|
'titleabbrev' => array(
|
|
/* DEFAULT */ 'format_suppressed_tags',
|
|
'phpdoc:classref' => 'format_grep_classname_text',
|
|
'phpdoc:exceptionref' => 'format_grep_classname_text',
|
|
),
|
|
|
|
|
|
);
|
|
|
|
/* Common properties for all functions pages */
|
|
protected $bookName = "";
|
|
|
|
/* Current Chunk settings */
|
|
protected $cchunk = array();
|
|
/* Default Chunk settings */
|
|
protected $dchunk = array(
|
|
"phpdoc:classref" => null,
|
|
"bookname" => null,
|
|
"setname" => null,
|
|
"toc-root" => null,
|
|
"id-to-outline" => array(),
|
|
"id-to-page" => array(),
|
|
"root-outline" => null,
|
|
);
|
|
|
|
public function __construct(
|
|
Config $config,
|
|
OutputHandler $outputHandler
|
|
) {
|
|
parent::__construct($config, $outputHandler);
|
|
$this->registerFormatName("PHP-PDF");
|
|
$this->setTitle("PHP Manual");
|
|
}
|
|
|
|
public function __destruct() {}
|
|
|
|
public function update($event, $value = null) {
|
|
switch($event) {
|
|
case Render::STANDALONE:
|
|
if ($value) {
|
|
$this->registerElementMap($this->getDefaultElementMap());
|
|
$this->registerTextMap($this->getDefaultTextMap());
|
|
} else {
|
|
$this->registerElementMap($this->elementmap);
|
|
$this->registerTextMap($this->elementmap);
|
|
}
|
|
break;
|
|
|
|
case Render::INIT:
|
|
if (!class_exists("HaruDoc")) die ("PDF output needs libharu & haru/pecl extensions... Please install them and start PhD again.\n");
|
|
$this->setOutputDir($this->config->outputDir . strtolower($this->getFormatName()) . DIRECTORY_SEPARATOR);
|
|
if(!file_exists($this->getOutputDir()) || is_file($this->getOutputDir())) mkdir($this->getOutputDir(), 0777, true) or die("Can't create the cache directory.\n");
|
|
break;
|
|
case Render::VERBOSE:
|
|
$this->outputHandler->v("Starting %s rendering", $this->getFormatName(), VERBOSE_FORMAT_RENDERING);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public function getDefaultElementMap() {
|
|
return array_merge(parent::getDefaultElementMap(), $this->elementmap);
|
|
}
|
|
|
|
public function getDefaultTextMap() {
|
|
return array_merge(parent::getDefaultTextMap(), $this->textmap);
|
|
}
|
|
|
|
// Do nothing
|
|
public function appendData($data) {}
|
|
|
|
// To override
|
|
public function format_root_set($open, $name, $attrs, $props) {}
|
|
public function format_set($open, $name, $attrs, $props) {}
|
|
|
|
public function format_book($open, $name, $attrs, $props) {
|
|
if ($open) {
|
|
parent::newChunk();
|
|
$this->cchunk = $this->dchunk;
|
|
$pdfDoc = new PdfWriter();
|
|
try {
|
|
$pdfDoc->setCompressionMode(\HaruDoc::COMP_ALL);
|
|
} catch (\HaruException $e) {
|
|
trigger_error("PDF Compression failed, you need to compile libharu with Zlib...", E_USER_WARNING);
|
|
}
|
|
parent::setPdfDoc($pdfDoc);
|
|
if (isset($attrs[Reader::XMLNS_XML]["base"]) && $base = $attrs[Reader::XMLNS_XML]["base"])
|
|
parent::setChunkInfo("xml-base", $base);
|
|
|
|
$id = $attrs[Reader::XMLNS_XML]["id"];
|
|
$this->cchunk["root-outline"] = $this->cchunk["id-to-outline"][$id] =
|
|
$pdfDoc->createOutline(Format::getShortDescription($id), null, true);
|
|
$this->setIdToPage($id);
|
|
} else {
|
|
$this->resolveLinks($this->cchunk["bookname"]);
|
|
$pdfDoc = parent::getPdfDoc();
|
|
$this->outputHandler->v("Writing PDF Manual (%s)", $this->cchunk["bookname"], VERBOSE_TOC_WRITING);
|
|
$pdfDoc->saveToFile($this->getOutputDir() . $this->toValidName($this->cchunk["bookname"]) . $this->getExt());
|
|
unset($pdfDoc);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function format_bookname($value, $tag) {
|
|
$this->cchunk["bookname"] = trim($value);
|
|
parent::getPdfDoc()->setCurrentBookName($this->cchunk["bookname"]);
|
|
parent::getPdfDoc()->appendText($this->cchunk["bookname"]);
|
|
return false;
|
|
}
|
|
|
|
public function format_setname($value, $tag) {
|
|
$this->cchunk["setname"] = trim($value);
|
|
parent::getPdfDoc()->appendText($this->cchunk["setname"]);
|
|
return false;
|
|
}
|
|
|
|
public function format_tocnode($open, $name, $attrs, $props, $newpage = false) {
|
|
if ($open) {
|
|
if ($newpage) {
|
|
parent::getPdfDoc()->add(PdfWriter::PAGE);
|
|
} else {
|
|
parent::getPdfDoc()->add(PdfWriter::LINE_JUMP);
|
|
}
|
|
if (isset($attrs[Reader::XMLNS_XML]["base"]) && $base = $attrs[Reader::XMLNS_XML]["base"]) {
|
|
parent::setChunkInfo("xml-base", $base);
|
|
}
|
|
|
|
if (isset($attrs[Reader::XMLNS_XML]["id"]) && $id = $attrs[Reader::XMLNS_XML]["id"]) {
|
|
$parentId = Format::getParent($id);
|
|
if (isset($this->cchunk["id-to-outline"][$parentId])) {
|
|
$this->cchunk["id-to-outline"][$id] = parent::getPdfDoc()->createOutline
|
|
(Format::getShortDescription($id), $this->cchunk["id-to-outline"][$parentId], false);
|
|
} else {
|
|
$this->cchunk["id-to-outline"][$id] = parent::getPdfDoc()->createOutline
|
|
(Format::getShortDescription($id), $this->cchunk["root-outline"], false);
|
|
}
|
|
$this->setIdToPage($id);
|
|
}
|
|
parent::setChunkInfo("examplenumber", 0);
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public function format_tocnode_newpage($open, $name, $attrs, $props) {
|
|
return $this->format_tocnode($open, $name, $attrs, $props, true);
|
|
}
|
|
|
|
public function format_tocnode_exception($open, $name, $attrs, $props) {
|
|
return $this->format_tocnode($open, "reference", $attrs, $props, true);
|
|
}
|
|
|
|
public function format_tocnode_class($open, $name, $attrs, $props) {
|
|
return $this->format_tocnode($open, "reference", $attrs, $props, true);
|
|
}
|
|
|
|
public function format_grep_classname_text($value, $tag) {
|
|
$this->cchunk["phpdoc:classref"] = strtolower($value);
|
|
}
|
|
|
|
// Convert the book name to a Unix valid filename
|
|
protected function toValidName($functionName) {
|
|
return str_replace(array(":", "::", "->", "/", "\\", " "), array(".", ".", ".", "-", "-", "-"), $functionName);
|
|
}
|
|
|
|
protected function setIdToPage($id) {
|
|
if (isset($this->cchunk["id-to-page"]) && is_array($this->cchunk["id-to-page"])) {
|
|
$this->cchunk["id-to-page"][$id] = parent::getPdfDoc()->getCurrentPage();
|
|
}
|
|
}
|
|
|
|
protected function resolveLinks($name) {
|
|
$this->outputHandler->v("Resolving Internal Links... (%s)", $name, VERBOSE_TOC_WRITING);
|
|
$linksToResolve = parent::getChunkInfo("links-to-resolve");
|
|
foreach ($linksToResolve as $link => $targets) {
|
|
if (isset($this->cchunk["id-to-page"][$link]) && $destPage = $this->cchunk["id-to-page"][$link]) {
|
|
foreach ($targets as $target) {
|
|
$page = $target[0];
|
|
$rectangle = array($target[1], $target[2], $target[3], $target[4]);
|
|
parent::getPdfDoc()->resolveInternalLink($page, $rectangle, $destPage);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public function format_type_text($type) {
|
|
$type = trim(preg_replace('/[ \n\t]+/', ' ', $type));
|
|
$t = strtolower($type);
|
|
|
|
switch($t) {
|
|
case "bool":
|
|
$href = "language.types.boolean";
|
|
break;
|
|
case "int":
|
|
case "long":
|
|
$href = "language.types.integer";
|
|
break;
|
|
case "double":
|
|
$href = "language.types.float";
|
|
break;
|
|
case "void":
|
|
case "boolean":
|
|
case "integer":
|
|
case "float":
|
|
case "string":
|
|
case "array":
|
|
case "object":
|
|
case "resource":
|
|
case "null":
|
|
case "callable":
|
|
case "iterable":
|
|
$href = "language.types.$t";
|
|
break;
|
|
case "mixed":
|
|
$href = "language.types.declarations";
|
|
break;
|
|
default:
|
|
/* Check if its a classname. */
|
|
$t = strtolower(str_replace(array("_", "::", "->"), array("-", "-", "-"), $t));
|
|
$href = Format::getFilename("class.$t");
|
|
}
|
|
|
|
parent::getPdfDoc()->setFont(PdfWriter::FONT_NORMAL, 12, array(0, 0, 1)); // blue
|
|
$linkAreas = parent::getPdfDoc()->add(PdfWriter::LINK_ANNOTATION, $type);
|
|
$linksToResolve = parent::getChunkInfo("links-to-resolve");
|
|
if (!isset($linksToResolve[$href]))
|
|
$linksToResolve[$href] = array();
|
|
foreach ($linkAreas as $area)
|
|
$linksToResolve[$href][] = $area;
|
|
parent::setChunkInfo("links-to-resolve", $linksToResolve);
|
|
parent::getPdfDoc()->revertFont();
|
|
return '';
|
|
}
|
|
|
|
public function format_type_if_object_or_pseudo_text($type) {
|
|
if (in_array(strtolower($type), array("bool", "int", "double", "boolean", "integer", "float", "string", "array", "object", "resource", "null"))) {
|
|
parent::getPdfDoc()->appendText(" " . $type);
|
|
return false;
|
|
}
|
|
return self::format_type_text($type);
|
|
}
|
|
|
|
public function format_collect_id($open, $name, $attrs) {
|
|
if ($open && isset($attrs[Reader::XMLNS_XML]["id"]) && $id = $attrs[Reader::XMLNS_XML]["id"]) {
|
|
$this->setIdToPage($id);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|