From 99c70b7aaf61091e89a8c7ac45d1d69d65c32237 Mon Sep 17 00:00:00 2001 From: haszi Date: Sun, 3 Nov 2024 15:05:25 +0100 Subject: [PATCH] Add links to constants with replaceable tags (#175) Add links to constants with replaceable tags by processing them when the constant tag is being closed. Add a test. Co-authored-by: haszi --- phpdotnet/phd/Package/Generic/XHTML.php | 89 +++++++++++++++++++++-- phpdotnet/phd/Render.php | 2 +- tests/package/php/constant_links_001.phpt | 11 +++ tests/package/php/data/constant_links.xml | 9 ++- 4 files changed, 104 insertions(+), 7 deletions(-) diff --git a/phpdotnet/phd/Package/Generic/XHTML.php b/phpdotnet/phd/Package/Generic/XHTML.php index ef7abaef..0cf6e97e 100644 --- a/phpdotnet/phd/Package/Generic/XHTML.php +++ b/phpdotnet/phd/Package/Generic/XHTML.php @@ -235,7 +235,10 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML { 'refname' => 'h1', 'refnamediv' => 'div', 'releaseinfo' => 'div', - 'replaceable' => 'span', + 'replaceable' => array( + /* DEFAULT */ 'span', + 'constant' => 'format_replaceable', + ), 'revhistory' => 'format_table', 'revision' => 'format_row', 'revremark' => 'format_entry', @@ -403,6 +406,10 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML { 'ooexception' => 'format_modifier_text', 'oointerface' => 'format_modifier_text', ), + 'replaceable' => array( + /* DEFAULT */ false, + 'constant' => 'format_suppressed_text', + ), /** Those are used to retrieve the class/interface name to be able to remove it from method names */ 'classname' => [ /* DEFAULT */ false, @@ -1681,26 +1688,92 @@ public function format_screen($open, $name, $attrs) { } return ''; } - public function format_constant($open, $name, $attrs) + public function format_constant($open, $name, $attrs, $props) { if ($open) { + if (str_contains($props["innerXml"], 'pushRole("constant_group"); + $this->cchunk["constant"] = $props["innerXml"]; + } return ""; } + + if ($this->getRole() === "constant_group") { + $this->popRole(); + + $value = str_replace( + ["", ""], + ["", ""], + strip_tags($this->cchunk["constant"], "") + ); + + $link = $this->createReplaceableConstantLink(strip_tags($this->cchunk["constant"], "")); + $this->cchunk["constant"] = ""; + + if ($link === "") { + return $value . ''; + } + + return '' . $value . ''; + } return ""; } - public function format_constant_text($value, $tag) { + + /** + * Creates a link to the first constant in the index + * that matches the pattern of a constant containing a 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"])) { + $matchingConstantId = $index["docbook_id"]; + break; + } + } + + return $matchingConstantId === "" ? "" : $this->createLink($matchingConstantId); + } + + private function convertConstantNameToId(string $constantName): string { $tempLinkValue = str_replace( array("\\", "_"), array("-", "-"), - strtolower(trim($value, "_")) + strtolower(trim($constantName, "_")) ); - if (str_contains($value, '::')) { + + if (str_contains($constantName, '::')) { // class constant list($extensionAndClass, $constant) = explode("::", $tempLinkValue); $normalizedLinkFormat = $extensionAndClass . ".constants." . trim($constant, "-"); } else { $normalizedLinkFormat = 'constant.' . $tempLinkValue; } + + return $normalizedLinkFormat; + } + + public function format_constant_text($value, $tag) { + if ($this->getRole() === "constant_group") { + return ""; + } + + $normalizedLinkFormat = $this->convertConstantNameToId($value); + $link = $this->createLink($normalizedLinkFormat); if ($link === null) { @@ -1709,6 +1782,12 @@ public function format_constant_text($value, $tag) { return '' . $value . ''; } + public function format_replaceable($open, $name, $attrs, $props) { + if ($this->getRole() === "constant_group") { + return ""; + } + return false; + } public function admonition_title($title, $lang) { return '' .($this->autogen($title, $lang)). ''; diff --git a/phpdotnet/phd/Render.php b/phpdotnet/phd/Render.php index 1e536920..5e4201cd 100644 --- a/phpdotnet/phd/Render.php +++ b/phpdotnet/phd/Render.php @@ -77,7 +77,7 @@ public function execute(Reader $r) { /* {{{ */ $r->name === "type" || $r->name === "classsynopsis" || $r->name === "qandaset" || - in_array($r->name, ["methodsynopsis", "constructorsynopsis", "destructorsynopsis"], true) + in_array($r->name, ["methodsynopsis", "constructorsynopsis", "destructorsynopsis", "constant"], true) ) ) { $innerXml = $r->readInnerXml(); diff --git a/tests/package/php/constant_links_001.phpt b/tests/package/php/constant_links_001.phpt index 8b46bdd5..ee3e9280 100644 --- a/tests/package/php/constant_links_001.phpt +++ b/tests/package/php/constant_links_001.phpt @@ -27,6 +27,10 @@ $indices = [ "docbook_id" => "extension-class.constants.leading-and-trailing-undescores2", "filename" => "extensionname4.constantspage4", ], + [ + "docbook_id" => "constant.extension-namespace-definitely-exists3", + "filename" => "extensionname.constantspage", + ], ]; $format = new TestPHPChunkedXHTML($config); @@ -79,5 +83,12 @@ Content: Extension\Class::__LEADING_AND_TRAILING_UNDESCORES2__

+ +
+

4. Constant with replacable parts links to first ID in the index

+

+ Extension\Namespace\DEFINITELY_SHOULD_EXIST +

+
diff --git a/tests/package/php/data/constant_links.xml b/tests/package/php/data/constant_links.xml index eb13986b..a61fd177 100644 --- a/tests/package/php/data/constant_links.xml +++ b/tests/package/php/data/constant_links.xml @@ -1,5 +1,5 @@ - +
1. Existing constants @@ -24,5 +24,12 @@ Extension\Class::__LEADING_AND_TRAILING_UNDESCORES2__
+ +
+ 4. Constant with replacable parts links to first ID in the index + + Extension\Namespace\DEFINITELY_SHOULD_EXIST + +