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__
+
+
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
+
+