mirror of
https://github.com/php/phd.git
synced 2026-03-24 15:12:18 +01:00
469 lines
16 KiB
PHP
469 lines
16 KiB
PHP
<?php
|
|
namespace phpdotnet\phd;
|
|
|
|
abstract class Package_IDE_Base extends Format {
|
|
protected $elementmap = array(
|
|
'caution' => 'format_notes',
|
|
'entry' => 'format_changelog_entry',
|
|
'function' => 'format_seealso_entry',
|
|
'listitem' => 'format_parameter_desc',
|
|
'methodparam' => 'format_methodparam',
|
|
'methodname' => 'format_seealso_entry',
|
|
'member' => 'format_member',
|
|
'note' => 'format_notes',
|
|
'refentry' => 'format_refentry',
|
|
'refpurpose' => 'format_refpurpose',
|
|
'refnamediv' => 'format_suppressed_tags',
|
|
'refsect1' => 'format_refsect1',
|
|
'row' => 'format_changelog_row',
|
|
'set' => 'format_set',
|
|
'tbody' => 'format_changelog_tbody',
|
|
'tip' => 'format_notes',
|
|
'warning' => 'format_notes',
|
|
);
|
|
protected $textmap = array(
|
|
'function' => 'format_seealso_entry_text',
|
|
'initializer' => 'format_initializer_text',
|
|
'methodname' => 'format_seealso_entry_text',
|
|
'parameter' => 'format_parameter_text',
|
|
'refname' => 'format_refname_text',
|
|
'title' => 'format_suppressed_text',
|
|
'type' => 'format_type_text',
|
|
);
|
|
protected $cchunk = array();
|
|
protected $dchunk = array(
|
|
'function' => array(),
|
|
'methodparam' => false,
|
|
'param' => array(
|
|
'name' => false,
|
|
'type' => false,
|
|
'description' => false,
|
|
'opt' => false,
|
|
'initializer' => false,
|
|
),
|
|
'seealso' => array(
|
|
'name' => false,
|
|
'type' => false,
|
|
'description' => false,
|
|
),
|
|
'changelog' => array(
|
|
'entry' => false,
|
|
'version' => false,
|
|
'change' => false,
|
|
),
|
|
);
|
|
|
|
protected $isFunctionRefSet;
|
|
protected $isChangelogRow = false;
|
|
protected $role = false;
|
|
protected $versions;
|
|
|
|
protected $function = array();
|
|
protected $dfunction = array(
|
|
'name' => null,
|
|
'purpose' => null,
|
|
'manualid' => null,
|
|
'version' => null,
|
|
'params' => array(),
|
|
'currentParam' => null,
|
|
'return' => array(
|
|
'type' => null,
|
|
'description' => null,
|
|
),
|
|
'errors' => null,
|
|
'notes' => array(),
|
|
'changelog' => array(),
|
|
'seealso' => array(),
|
|
);
|
|
|
|
private array $chunkFlags = [];
|
|
|
|
public function __construct(
|
|
Config $config,
|
|
OutputHandler $outputHandler
|
|
) {
|
|
parent::__construct($config, $outputHandler);
|
|
}
|
|
|
|
public function createLink($for, &$desc = null, $type = Format::SDESC) {}
|
|
public function UNDEF($open, $name, $attrs, $props) {}
|
|
public function TEXT($value) {}
|
|
public function CDATA($value) {}
|
|
public function transformFromMap($open, $tag, $name, $attrs, $props) {}
|
|
public function appendData($data) {}
|
|
|
|
public abstract function parseFunction();
|
|
|
|
function writeChunk() {
|
|
if (!isset($this->cchunk['funcname'][0])) {
|
|
return;
|
|
}
|
|
if (false !== strpos($this->cchunk['funcname'][0], ' ')) {
|
|
return;
|
|
}
|
|
$this->function['name'] = $this->cchunk['funcname'][0];
|
|
$this->function['version'] = $this->versionInfo($this->function['name']);
|
|
$data = $this->parseFunction();
|
|
|
|
$filename = $this->getOutputDir() . $this->function['name'] . $this->getExt();
|
|
file_put_contents($filename, $data);
|
|
|
|
$index = 0;
|
|
while(isset($this->cchunk['funcname'][++$index])) {
|
|
$filename = $this->getOutputDir() . $this->cchunk['funcname'][$index] . $this->getExt();
|
|
// Replace the default function name by the alternative one
|
|
$content = preg_replace('/' . $this->cchunk['funcname'][0] . '/',
|
|
$this->cchunk['funcname'][$index], $data, 1);
|
|
file_put_contents($filename, $content);
|
|
}
|
|
}
|
|
|
|
public function renderHTML() {
|
|
static $format = null;
|
|
if ($format == null) {
|
|
$format = new Package_Generic_ChunkedXHTML(
|
|
$this->config,
|
|
$this->outputHandler
|
|
);
|
|
}
|
|
return $format->parse(trim(ReaderKeeper::getReader()->readInnerXML()));
|
|
}
|
|
|
|
public function CHUNK($value) {
|
|
$this->chunkFlags = $value;
|
|
}
|
|
|
|
public function STANDALONE($value) {
|
|
$this->registerElementMap($this->elementmap);
|
|
$this->registerTextMap($this->textmap);
|
|
}
|
|
|
|
public function INIT($value) {
|
|
$this->loadVersionInfo();
|
|
$this->createOutputDirectory();
|
|
}
|
|
|
|
public function FINALIZE($value) {
|
|
}
|
|
|
|
public function VERBOSE($value) {
|
|
$this->outputHandler->v('Starting %s rendering', $this->getFormatName(), VERBOSE_FORMAT_RENDERING);
|
|
}
|
|
|
|
public function update($event, $value = null) {
|
|
switch($event) {
|
|
case Render::CHUNK:
|
|
$this->CHUNK($value);
|
|
break;
|
|
case Render::STANDALONE:
|
|
$this->STANDALONE($value);
|
|
break;
|
|
case Render::INIT:
|
|
$this->INIT($value);
|
|
break;
|
|
case Render::FINALIZE:
|
|
$this->FINALIZE($value);
|
|
break;
|
|
case Render::VERBOSE:
|
|
$this->VERBOSE($value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public static function generateVersionInfo($filename) {
|
|
static $info;
|
|
if ($info) {
|
|
return $info;
|
|
}
|
|
$r = new \XMLReader;
|
|
if (!$r->open($filename)) {
|
|
throw new \Exception;
|
|
}
|
|
$versions = array();
|
|
while($r->read()) {
|
|
if (
|
|
$r->moveToAttribute('name')
|
|
&& ($funcname = str_replace(
|
|
array('::', '->', '__', '_', '$'),
|
|
array('-', '-', '-', '-', ''),
|
|
$r->value))
|
|
&& $r->moveToAttribute('from')
|
|
&& ($from = $r->value)
|
|
) {
|
|
$versions[strtolower($funcname)] = $from;
|
|
$r->moveToElement();
|
|
}
|
|
}
|
|
$r->close();
|
|
$info = $versions;
|
|
return $versions;
|
|
}
|
|
|
|
public function versionInfo($funcname) {
|
|
$funcname = str_replace(
|
|
array('.', '::', '->', '->', '__', '_', '$', '()'),
|
|
array('-', '-', '-', '-', '-', '-', '', ''),
|
|
strtolower($funcname));
|
|
if(isset($this->versions[$funcname])) {
|
|
return $this->versions[$funcname];
|
|
}
|
|
$this->outputHandler->v('No version info for %s', $funcname, VERBOSE_NOVERSION);
|
|
return false;
|
|
}
|
|
|
|
public function loadVersionInfo() {
|
|
if (file_exists($this->config->phpwebVersionFilename)) {
|
|
$this->versions = self::generateVersionInfo($this->config->phpwebVersionFilename);
|
|
} else {
|
|
throw new \Error("Can't load the versions file");
|
|
}
|
|
}
|
|
|
|
public function createOutputDirectory() {
|
|
$this->setOutputDir($this->config->outputDir . strtolower($this->getFormatName()) . '/');
|
|
if (file_exists($this->getOutputDir())) {
|
|
if (!is_dir($this->getOutputDir())) {
|
|
throw new \Error('Output directory is a file?');
|
|
}
|
|
} else {
|
|
if (!mkdir($this->getOutputDir(), 0777, true)) {
|
|
throw new \Error("Can't create output directory");
|
|
}
|
|
}
|
|
}
|
|
|
|
public function format_suppressed_tags($open, $name, $attrs, $props) {
|
|
return '';
|
|
}
|
|
|
|
public function format_suppressed_text($value, $tag) {
|
|
return '';
|
|
}
|
|
|
|
public function format_set($open, $name, $attrs, $props) {
|
|
if (isset($attrs[Reader::XMLNS_XML]['id']) && $attrs[Reader::XMLNS_XML]['id'] == 'funcref') {
|
|
$this->isFunctionRefSet = $open;
|
|
}
|
|
}
|
|
|
|
public function format_refentry($open, $name, $attrs, $props) {
|
|
if (!$this->isFunctionRefSet) {
|
|
return;
|
|
}
|
|
if ($open) {
|
|
$this->function = $this->dfunction;
|
|
$this->cchunk = $this->dchunk;
|
|
|
|
$this->function['manualid'] = $attrs[Reader::XMLNS_XML]['id'];
|
|
return;
|
|
}
|
|
$this->writeChunk();
|
|
}
|
|
|
|
public function format_refname_text($value, $tag) {
|
|
if ($this->isFunctionRefSet) {
|
|
$this->cchunk['funcname'][] = $this->toValidName(trim($value));
|
|
}
|
|
}
|
|
|
|
public function format_refpurpose($open, $name, $attrs, $props) {
|
|
if ($this->isFunctionRefSet && $open) {
|
|
$this->function['purpose'] = str_replace("\n", '', trim(ReaderKeeper::getReader()->readString()));
|
|
}
|
|
}
|
|
|
|
public function format_refsect1($open, $name, $attrs, $props) {
|
|
if (!$this->isFunctionRefSet) {
|
|
return;
|
|
}
|
|
if ($open) {
|
|
if (isset($attrs[Reader::XMLNS_DOCBOOK]['role']) && $attrs[Reader::XMLNS_DOCBOOK]['role']) {
|
|
$this->role = $attrs[Reader::XMLNS_DOCBOOK]['role'];
|
|
} else {
|
|
$this->role = false;
|
|
}
|
|
} else {
|
|
$this->role = false;
|
|
}
|
|
if ($this->role == 'errors') {
|
|
return $this->format_errors($open, $name, $attrs, $props);
|
|
} elseif ($this->role == 'returnvalues') {
|
|
return $this->format_return($open, $name, $attrs, $props);
|
|
}
|
|
}
|
|
|
|
public function format_type_text($value, $tag) {
|
|
if (!$this->isFunctionRefSet) {
|
|
return;
|
|
}
|
|
if ($this->role == 'description') {
|
|
if (isset($this->cchunk['methodparam']) && !$this->cchunk['methodparam']) {
|
|
$this->function['return']['type'] = $value;
|
|
return;
|
|
}
|
|
$this->cchunk['param']['type'] = $value;
|
|
}
|
|
}
|
|
|
|
public function format_methodparam($open, $name, $attrs, $props) {
|
|
if ($this->role != 'description' || !$this->isFunctionRefSet ) {
|
|
return;
|
|
}
|
|
if ($open) {
|
|
$this->cchunk['methodparam'] = true;
|
|
if (isset($attrs[Reader::XMLNS_DOCBOOK]['choice']) && $attrs[Reader::XMLNS_DOCBOOK]['choice'] == 'opt') {
|
|
$this->cchunk['param']['opt'] = 'true';
|
|
} else {
|
|
$this->cchunk['param']['opt'] = 'false';
|
|
}
|
|
return;
|
|
}
|
|
$param['name'] = $this->cchunk['param']['name'];
|
|
$param['type'] = $this->cchunk['param']['type'];
|
|
$param['optional'] = $this->cchunk['param']['opt'];
|
|
if (!empty($this->cchunk['param']['initializer'])) {
|
|
$param['initializer'] = $this->cchunk['param']['initializer'];
|
|
}
|
|
$this->cchunk['methodparam'] = $this->dchunk['methodparam'];
|
|
$this->cchunk['param'] = $this->dchunk['param'];
|
|
$this->function['params'][$param['name']] = $param;
|
|
}
|
|
|
|
public function format_parameter_text($value, $tag) {
|
|
if (!$this->isFunctionRefSet) {
|
|
return;
|
|
}
|
|
if (!empty($this->cchunk['methodparam'])) {
|
|
$this->cchunk['param']['name'] = $value;
|
|
}
|
|
if ($this->role == 'parameters') {
|
|
$this->cchunk['currentParam'] = trim($value);
|
|
}
|
|
}
|
|
|
|
public function format_parameter_desc($open, $name, $attrs, $props) {
|
|
if ($this->role != 'parameters') {
|
|
return;
|
|
}
|
|
if ($open) {
|
|
//Read the description
|
|
$content = $this->renderHTML();
|
|
if (isset($this->cchunk['currentParam']) && isset($this->function['params'][$this->cchunk['currentParam']])) {
|
|
$this->function['params'][$this->cchunk['currentParam']]['description'] = $content;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function format_initializer_text($value, $tag) {
|
|
if (!$this->isFunctionRefSet) {
|
|
return;
|
|
}
|
|
if (isset($this->cchunk['methodparam']) && !$this->cchunk['methodparam']) {
|
|
return;
|
|
}
|
|
$this->cchunk['param']['initializer'] = $value;
|
|
}
|
|
|
|
public function format_return($open, $name, $attrs, $props) {
|
|
if ($open) {
|
|
//Read the description
|
|
$content = $this->renderHTML();
|
|
//Remove default title
|
|
$content = str_replace('<h1 class="title">Return Values</h1>', '', $content);
|
|
$this->function['return']['description'] = trim($content);
|
|
}
|
|
}
|
|
|
|
public function format_notes($open, $name, $attrs, $props) {
|
|
if ($this->role != 'notes' || !$this->isFunctionRefSet) {
|
|
return;
|
|
}
|
|
if ($open) {
|
|
//Read the description
|
|
$content = $this->renderHTML();
|
|
$note = array();
|
|
$note['type'] = $name;
|
|
$note['description'] = $content;
|
|
$this->function['notes'][] = $note;
|
|
}
|
|
}
|
|
|
|
public function format_errors($open, $name, $attrs, $props) {
|
|
if ($open) {
|
|
//Read the description
|
|
$content = $this->renderHTML();
|
|
//Remove default title
|
|
$content = str_replace('<h1 class="title">Errors/Exceptions</h1>', '', $content);
|
|
$this->function['errors'] = trim($content);
|
|
}
|
|
}
|
|
|
|
public function format_changelog_tbody($open, $name, $attrs, $props) {
|
|
if ($this->role == 'changelog' && $this->isFunctionRefSet) {
|
|
$this->isChangelogRow = $open;
|
|
}
|
|
}
|
|
|
|
public function format_changelog_row($open, $name, $attrs, $props) {
|
|
if ($this->isChangelogRow) {
|
|
if ($open) {
|
|
$this->cchunk['changelog'] = $this->dchunk['changelog'];
|
|
} else {
|
|
$change['version'] = $this->cchunk['changelog']['version'];
|
|
$change['change'] = $this->cchunk['changelog']['change'];
|
|
$this->function['changelog'][] = $change;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function format_changelog_entry($open, $name, $attrs, $props) {
|
|
if ($this->isChangelogRow && $open) {
|
|
$entryType = ($this->cchunk['changelog']['entry'] == 'version')
|
|
? 'change'
|
|
: 'version';
|
|
$this->cchunk['changelog'][$entryType] = trim(ReaderKeeper::getReader()->readString());
|
|
$this->cchunk['changelog']['entry'] = $entryType;
|
|
}
|
|
}
|
|
|
|
public function format_changelog_entry_text($value, $tag) {
|
|
if ($this->isChangelogRow) {
|
|
$this->cchunk['changelog'][$this->cchunk['changelog']['entry']] = $value;
|
|
}
|
|
}
|
|
|
|
public function format_member($open, $name, $attrs, $props) {
|
|
if ($this->role == 'seealso' && $this->isFunctionRefSet) {
|
|
if ($open) {
|
|
$this->cchunk['seealso'] = $this->dchunk['seealso'];
|
|
} else {
|
|
$seealso = array();
|
|
$seealso['type'] = $this->cchunk['seealso']['type'];
|
|
$seealso['name'] = $this->cchunk['seealso']['name'];
|
|
$this->cchunk['seealso'] = $this->dchunk['seealso'];
|
|
if ($seealso['name'] == '') {
|
|
return false;
|
|
}
|
|
return $this->function['seealso'][] = $seealso;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function format_seealso_entry($open, $name, $attrs, $props) {
|
|
if ($this->role == 'seealso' && $this->isFunctionRefSet) {
|
|
$this->cchunk['seealso']['type'] = $name;
|
|
}
|
|
}
|
|
|
|
public function format_seealso_entry_text($value, $tag) {
|
|
if ($this->role == 'seealso' && $this->isFunctionRefSet) {
|
|
$this->cchunk['seealso']['name'] = $value;
|
|
}
|
|
}
|
|
|
|
public function toValidName($functionName) {
|
|
return str_replace(array('::', '->', '()'), array('.', '.', ''), $functionName);
|
|
}
|
|
|
|
}
|