diff --git a/phpdotnet/phd/Format/Abstract/XHTML.php b/phpdotnet/phd/Format/Abstract/XHTML.php index a28b59ab..12f57171 100644 --- a/phpdotnet/phd/Format/Abstract/XHTML.php +++ b/phpdotnet/phd/Format/Abstract/XHTML.php @@ -6,6 +6,9 @@ abstract class Format_Abstract_XHTML extends Format { /** @var array Last In First Out stack of roles */ private array $role = []; + /** @var array Last In First Out stack of annotations */ + private array $annotations = []; + /* XHTMLPhDFormat */ protected $openPara = 0; protected $escapedPara = array(); @@ -44,13 +47,19 @@ public function UNDEF($open, $name, $attrs, $props) { } public function CDATA($value) { + $annotations = $this->getAnnotations(); + $annotationsStr = ''; + if (count($annotations) > 0) { + $annotationsStr = 'annotation-' . join(' annotation-', $annotations) . ' '; + } + switch($this->getRole()) { case '': - return '
' + return ''; default: - return '' . htmlspecialchars($value, ENT_QUOTES, "UTF-8") . '' + return '' . $this->highlight(trim($value), $this->getRole(), 'xhtml') . ''; } @@ -139,4 +148,20 @@ protected function getRole(): ?string { protected function popRole(): ?string { return array_pop($this->role); } + + protected function pushAnnotations(?string $annotations): void { + $this->annotations[] = ($annotations != null ? explode(' ', $annotations) : []); + } + + protected function getAnnotations() : ?array { + $top = end($this->annotations); + if ($top === false) { + $top = []; + } + return $top; + } + + protected function popAnnotations() : ?array { + return array_pop($this->annotations); + } } diff --git a/phpdotnet/phd/Package/Generic/XHTML.php b/phpdotnet/phd/Package/Generic/XHTML.php index 35d84854..bb70624e 100644 --- a/phpdotnet/phd/Package/Generic/XHTML.php +++ b/phpdotnet/phd/Package/Generic/XHTML.php @@ -820,6 +820,8 @@ public function format_name($open, $name, $attrs) { } public function format_container_chunk_top($open, $name, $attrs, $props) { + $hasAnnotations = array_key_exists('annotations', $attrs[Reader::XMLNS_DOCBOOK]); + $this->cchunk = $this->dchunk; $this->cchunk["name"] = $name; if(isset($attrs[Reader::XMLNS_XML]["id"])) { @@ -829,12 +831,20 @@ public function format_container_chunk_top($open, $name, $attrs, $props) { } if ($open) { + if ($hasAnnotations) { + $this->pushAnnotations($attrs[Reader::XMLNS_DOCBOOK]["annotations"]); + } + $this->CURRENT_CHUNK = $id; $this->notify(Render::CHUNK, Render::OPEN); return ''; } + if ($hasAnnotations) { + $this->popAnnotations(); + } + $this->CURRENT_CHUNK = $id; $this->notify(Render::CHUNK, Render::CLOSE); $toc = ""; @@ -1714,10 +1724,17 @@ public function format_example_content($open, $name, $attrs) { return ""; } public function format_programlisting($open, $name, $attrs) { + $hasAnnotations = array_key_exists('annotations', $attrs[Reader::XMLNS_DOCBOOK]); if ($open) { $this->pushRole($attrs[Reader::XMLNS_DOCBOOK]["role"] ?? null); + if ($hasAnnotations) { + $this->pushAnnotations($attrs[Reader::XMLNS_DOCBOOK]["annotations"]); + } return ''; } + if ($hasAnnotations) { + $this->popAnnotations(); + } $this->popRole(); return "\n"; } @@ -1753,47 +1770,47 @@ public function format_constant($open, $name, $attrs, $props) } return ""; } - + if ($this->getRole() === "constant_group") { $this->popRole(); - + $value = str_replace( ["
'; } - + return '' . $value . ''; } return ""; } /** - * Creates a link to the first constant in the index + * Creates a link to the first constant in the index * that matches the pattern of a constant containing a", " "], ["", ""], strip_tags($this->cchunk["constant"], "") ); - + $link = $this->createReplaceableConstantLink(strip_tags($this->cchunk["constant"], " ")); $this->cchunk["constant"] = ""; - + if ($link === "") { return $value . ' tag * or returns an empty string if no match was found. - * + * * This works only with one set of tags in a constant * e.g. CURLE_ * or DOM_* _NODE */ private function createReplaceableConstantLink(string $constant): string { $pattern = "/" . preg_replace( - "//", - ".*", + "/ /", + ".*", str_replace( - ".", - "\.", + ".", + "\.", $this->convertConstantNameToId($constant) ) ) ."/"; - + $matchingConstantId = ""; foreach ($this->indexes as $index) { if (preg_match($pattern, $index["docbook_id"])) { @@ -1801,17 +1818,17 @@ private function createReplaceableConstantLink(string $constant): string { break; } } - + return $matchingConstantId === "" ? "" : $this->createLink($matchingConstantId); } - + private function convertConstantNameToId(string $constantName): string { $tempLinkValue = str_replace( array("\\", "_"), array("-", "-"), trim($this->normalizeFQN($constantName), "_") ); - + if (str_contains($constantName, '::')) { // class constant list($extensionAndClass, $constant) = explode("::", $tempLinkValue); @@ -1819,7 +1836,7 @@ private function convertConstantNameToId(string $constantName): string { } else { $normalizedLinkFormat = 'constant.' . $tempLinkValue; } - + return $normalizedLinkFormat; } @@ -1829,7 +1846,7 @@ public function format_constant_text($value, $tag) { } $normalizedLinkFormat = $this->convertConstantNameToId($value); - + $link = $this->createLink($normalizedLinkFormat); if ($link === null) { @@ -1844,34 +1861,34 @@ public function format_replaceable($open, $name, $attrs, $props) { } return false; } - + public function format_property_text($value, $tag) { if (! str_contains($value, '::')) { return $value; } - + $tempLinkValue = str_replace( ["\\", "_", "$"], ["-", "-", ""], trim($this->normalizeFQN($value), "_") ); - + list($extensionAndClass, $property) = explode("::", $tempLinkValue); $normalizedLinkFormat = $extensionAndClass . ".props." . trim($property, "-"); - + $link = $this->createLink($normalizedLinkFormat); - + if ($link === null || $link === "") { return $value; } - + return '' . $value . ''; } - + protected function normalizeFQN(string $fqn): string { return \ltrim(\strtolower($fqn), "\\"); } - + public function admonition_title($title, $lang) { return '' .($this->autogen($title, $lang)). ''; diff --git a/phpdotnet/phd/Package/PHP/XHTML.php b/phpdotnet/phd/Package/PHP/XHTML.php index 18585096..086ce478 100644 --- a/phpdotnet/phd/Package/PHP/XHTML.php +++ b/phpdotnet/phd/Package/PHP/XHTML.php @@ -914,6 +914,8 @@ private function isChunkedByAttributes(array $attributes): bool { } public function format_container_chunk($open, $name, $attrs, $props) { + $hasAnnotations = array_key_exists('annotations', $attrs[Reader::XMLNS_DOCBOOK]); + $this->CURRENT_CHUNK = $this->CURRENT_ID = $id = $attrs[Reader::XMLNS_XML]["id"] ?? ''; if ($this->isChunkedByAttributes($attrs)) { @@ -921,6 +923,10 @@ public function format_container_chunk($open, $name, $attrs, $props) { } if ($open) { + if ($hasAnnotations) { + $this->pushAnnotations($attrs[Reader::XMLNS_DOCBOOK]["annotations"]); + } + $this->notify(Render::CHUNK, Render::OPEN); if ($name != "reference") { $chunks = Format::getChildren($id); @@ -937,6 +943,10 @@ public function format_container_chunk($open, $name, $attrs, $props) { } return ' '; } + if ($hasAnnotations) { + $this->popAnnotations(); + } + $this->notify(Render::CHUNK, Render::CLOSE); $content = ""; @@ -957,11 +967,22 @@ public function format_container_chunk($open, $name, $attrs, $props) { } public function format_root_chunk($open, $name, $attrs) { + $hasAnnotations = array_key_exists('annotations', $attrs[Reader::XMLNS_DOCBOOK]); + $this->CURRENT_CHUNK = $this->CURRENT_ID = $id = $attrs[Reader::XMLNS_XML]["id"] ?? ''; if ($open) { + if ($hasAnnotations) { + $this->pushAnnotations($attrs[Reader::XMLNS_DOCBOOK]["annotations"]); + } + $this->notify(Render::CHUNK, Render::OPEN); return ''; } + + if ($hasAnnotations) { + $this->popAnnotations(); + } + $this->notify(Render::CHUNK, Render::CLOSE); $chunks = Format::getChildren($id); $content = '';